/* * Copyright (C), 2000-2007 by the monit project group. * All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #ifdef HAVE_STDIO_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_ERRNO_H #include #endif #ifdef HAVE_PWD_H #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #ifdef HAVE_SYS_PARAM_H #include #endif #ifdef HAVE_FCNTL_H #include #endif #include "monitor.h" #ifndef MAXPATHLEN #define MAXPATHLEN STRLEN #endif /* Private prototypes */ static void set_sandbox(void); static void set_environment(void); /** * Setup this program for safer exec, and set required runtime * "environment" variables. * * @author Jan-Henrik Haukeland, * * @version \$Id: env.c,v 1.37 2007/07/25 12:54:28 hauk Exp $ * * @file */ /* ------------------------------------------------------------------ Public */ /** * Initialize the program environment */ void init_env() { /* Setup for safe(r) exec */ set_sandbox(); /* Setup program environment */ set_environment(); } /* ----------------------------------------------------------------- Private */ /** * DESCRIPTION * This code was originally posted by Wietse Venema, years ago, in * a discussion on news on how to create safe suid wrappers. For * those interested in NNTP archeology, here's the post: * * Article 5648 of comp.security.unix: * From: wietse@wzv.win.tue.nl (Wietse Venema) * Newsgroups: comp.security.unix * Subject: Re: [8lgm]-Advisory-7.UNIX.passwd.11-May-1994 * Date: 18 May 1994 07:52:05 +0200 * Organization: Eindhoven University of Technology, The Netherlands * Lines: 68 * * milton@picard.med.miami.edu (H. Milton Johnson) writes: * >OK, I admit it, I'm a totally incompetent sysadmin because I am not * >sure I could write a bullet-proof setuid wrapper. However, if one of * >the competent sysadmins subscribing to this group could post or point * >the way to an example of a bullet- proof setuid wrapper, I'm sure that * >I could use it as a template to address this/future/other problems. * * Ok, here is a first stab. Perhaps we can make this into a combined * effort and get rid of the problem once and for all. * * Wietse * * [code - see the function below, only marginally changed to suit monit] * * @author Wietse Venema * */ static void set_sandbox(void) { int i; struct stat st; extern char **environ; char *path = "PATH=/bin:/usr/bin:/sbin:/usr/sbin"; /* * Purge the environment. Then make sure PATH is set; some shells default * to a path with '.' first. You may have to putenv() other stuff, too, * but be careful with importing too much. */ environ[0]= 0; if(putenv(path)) { LogError("%s: cannot set the PATH variable -- %s\n", prog, STRERROR); exit(1); } /* * Require that file descriptors 0,1,2 are open. Mysterious things * can happen if that is not the case. */ for(i= 0; i < 3; i++) { if(fstat(i, &st) == -1 && open("/dev/null", O_RDWR) != i) { LogError("Cannot open /dev/null -- %s\n", STRERROR); exit(1); } } Util_closeFds(); } /** * Get and set required runtime "environment" variables. */ static void set_environment(void) { struct passwd *pw; /* Get password struct */ if ( ! (pw= getpwuid(geteuid())) ) { LogError("%s: You don't exist. Go away.\n", prog); exit(1); } Run.Env.home= xstrdup(pw->pw_dir); Run.Env.user= xstrdup(pw->pw_name); /* Get CWD */ Run.Env.cwd= xcalloc(sizeof(char), MAXPATHLEN+1); if ( ! (getcwd(Run.Env.cwd, MAXPATHLEN)) ) { LogError("%s: Cannot read current directory -- %s\n", prog, STRERROR); exit(1); } /* * Save and clear the file creation mask */ Run.umask= umask(0); }