118c2aff7Sartem /*************************************************************************** 218c2aff7Sartem * 318c2aff7Sartem * util_helper.c - HAL utilities for helper (as e.g. prober/addons) et al. 418c2aff7Sartem * 518c2aff7Sartem * Copyright (C) 2006 David Zeuthen, <david@fubar.dk> 618c2aff7Sartem * 718c2aff7Sartem * Licensed under the Academic Free License version 2.1 818c2aff7Sartem * 918c2aff7Sartem * This program is free software; you can redistribute it and/or modify 1018c2aff7Sartem * it under the terms of the GNU General Public License as published by 1118c2aff7Sartem * the Free Software Foundation; either version 2 of the License, or 1218c2aff7Sartem * (at your option) any later version. 1318c2aff7Sartem * 1418c2aff7Sartem * This program is distributed in the hope that it will be useful, 1518c2aff7Sartem * but WITHOUT ANY WARRANTY; without even the implied warranty of 1618c2aff7Sartem * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1718c2aff7Sartem * GNU General Public License for more details. 1818c2aff7Sartem * 1918c2aff7Sartem * You should have received a copy of the GNU General Public License 2018c2aff7Sartem * along with this program; if not, write to the Free Software 2118c2aff7Sartem * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 2218c2aff7Sartem * 2318c2aff7Sartem **************************************************************************/ 2418c2aff7Sartem 2518c2aff7Sartem #ifdef HAVE_CONFIG_H 2618c2aff7Sartem # include <config.h> 2718c2aff7Sartem #endif 2818c2aff7Sartem 2918c2aff7Sartem #include <grp.h> 3018c2aff7Sartem #include <stdarg.h> 3118c2aff7Sartem #include <stdlib.h> 3218c2aff7Sartem #include <string.h> 3318c2aff7Sartem #include <sys/time.h> 3418c2aff7Sartem #include <time.h> 3518c2aff7Sartem #include <pwd.h> 3618c2aff7Sartem #include <unistd.h> 3718c2aff7Sartem 3818c2aff7Sartem #include "logger.h" 3918c2aff7Sartem 4018c2aff7Sartem #include "util_helper.h" 4118c2aff7Sartem 4218c2aff7Sartem #ifdef __linux__ 4318c2aff7Sartem extern char **environ; 4418c2aff7Sartem #endif 4518c2aff7Sartem 4618c2aff7Sartem static char **argv_buffer = NULL; 4718c2aff7Sartem static size_t argv_size = 0; 4818c2aff7Sartem 4918c2aff7Sartem #ifdef sun 5018c2aff7Sartem #include <priv.h> 5118c2aff7Sartem void 5218c2aff7Sartem drop_privileges(int keep_auxgroups) 5318c2aff7Sartem { 54*f5f5f433SJerry Gilliam priv_set_t *pPrivSet; 5518c2aff7Sartem 5618c2aff7Sartem /* 5718c2aff7Sartem * Start with the 'basic' privilege set and then remove any 5818c2aff7Sartem * of the 'basic' privileges that will not be needed. 5918c2aff7Sartem */ 60*f5f5f433SJerry Gilliam if ((pPrivSet = priv_allocset()) == NULL) { 6118c2aff7Sartem return; 6218c2aff7Sartem } 6318c2aff7Sartem 64*f5f5f433SJerry Gilliam /* 65*f5f5f433SJerry Gilliam * Establish the basic set of privileges. 66*f5f5f433SJerry Gilliam * Note: fork/exec required for libdevinfo devlink 67*f5f5f433SJerry Gilliam * interfaces are included in the basic set. 68*f5f5f433SJerry Gilliam */ 69*f5f5f433SJerry Gilliam priv_basicset(pPrivSet); 70*f5f5f433SJerry Gilliam 7118c2aff7Sartem /* Clear privileges we will not need from the 'basic' set */ 7218c2aff7Sartem (void) priv_delset(pPrivSet, PRIV_FILE_LINK_ANY); 7318c2aff7Sartem (void) priv_delset(pPrivSet, PRIV_PROC_INFO); 7418c2aff7Sartem (void) priv_delset(pPrivSet, PRIV_PROC_SESSION); 7518c2aff7Sartem 7618c2aff7Sartem /* for sysevent need to be root and have this privilege */ 7718c2aff7Sartem (void) priv_addset(pPrivSet, PRIV_SYS_CONFIG); 7818c2aff7Sartem 7973a8c195Sfei feng - Sun Microsystems - Beijing China /* need proc_audit privilege */ 8073a8c195Sfei feng - Sun Microsystems - Beijing China (void) priv_addset(pPrivSet, PRIV_PROC_AUDIT); 8173a8c195Sfei feng - Sun Microsystems - Beijing China 8218c2aff7Sartem /* Set the permitted privilege set. */ 83*f5f5f433SJerry Gilliam (void) setppriv(PRIV_SET, PRIV_PERMITTED, pPrivSet); 8418c2aff7Sartem 85*f5f5f433SJerry Gilliam /* Set the limit privilege set. */ 86*f5f5f433SJerry Gilliam (void) setppriv(PRIV_SET, PRIV_LIMIT, pPrivSet); 8718c2aff7Sartem 88*f5f5f433SJerry Gilliam priv_freeset(pPrivSet); 8918c2aff7Sartem } 9018c2aff7Sartem #else /* !sun */ 9118c2aff7Sartem 9218c2aff7Sartem /** Drop root privileges: Set the running user id to HAL_USER and 9318c2aff7Sartem * group to HAL_GROUP, and optionally retain auxiliary groups of HAL_USER. 9418c2aff7Sartem */ 9518c2aff7Sartem void 9618c2aff7Sartem drop_privileges (int keep_auxgroups) 9718c2aff7Sartem { 9818c2aff7Sartem struct passwd *pw = NULL; 9918c2aff7Sartem struct group *gr = NULL; 10018c2aff7Sartem 10118c2aff7Sartem /* determine user id */ 10218c2aff7Sartem pw = getpwnam (HAL_USER); 10318c2aff7Sartem if (!pw) { 10418c2aff7Sartem HAL_DEBUG (("drop_privileges: user " HAL_USER " does not exist")); 10518c2aff7Sartem exit (-1); 10618c2aff7Sartem } 10718c2aff7Sartem 10818c2aff7Sartem /* determine primary group id */ 10918c2aff7Sartem gr = getgrnam (HAL_GROUP); 11018c2aff7Sartem if (!gr) { 11118c2aff7Sartem HAL_DEBUG (("drop_privileges: group " HAL_GROUP " does not exist")); 11218c2aff7Sartem exit (-1); 11318c2aff7Sartem } 11418c2aff7Sartem 11518c2aff7Sartem if (keep_auxgroups) { 11618c2aff7Sartem if (initgroups (HAL_USER, gr->gr_gid)) { 11718c2aff7Sartem HAL_DEBUG(("drop_privileges: could not initialize groups")); 11818c2aff7Sartem exit (-1); 11918c2aff7Sartem } 12018c2aff7Sartem } 12118c2aff7Sartem 12218c2aff7Sartem if (setgid (gr->gr_gid)) { 12318c2aff7Sartem HAL_DEBUG (("drop_privileges: could not set group id")); 12418c2aff7Sartem exit (-1); 12518c2aff7Sartem } 12618c2aff7Sartem 12718c2aff7Sartem if (setuid (pw->pw_uid)) { 12818c2aff7Sartem HAL_DEBUG (("drop_privileges: could not set user id")); 12918c2aff7Sartem exit (-1); 13018c2aff7Sartem } 13118c2aff7Sartem } 13218c2aff7Sartem #endif /* !sun */ 13318c2aff7Sartem 13418c2aff7Sartem void 13518c2aff7Sartem hal_set_proc_title_init (int argc, char *argv[]) 13618c2aff7Sartem { 13718c2aff7Sartem #ifdef __linux__ 13818c2aff7Sartem unsigned int i; 13918c2aff7Sartem char **new_environ, *endptr; 14018c2aff7Sartem 14118c2aff7Sartem /* This code is really really ugly. We make some memory layout 14218c2aff7Sartem * assumptions and reuse the environment array as memory to store 14318c2aff7Sartem * our process title in */ 14418c2aff7Sartem 14518c2aff7Sartem for (i = 0; environ[i] != NULL; i++) 14618c2aff7Sartem ; 14718c2aff7Sartem 14818c2aff7Sartem endptr = i ? environ[i-1] + strlen (environ[i-1]) : argv[argc-1] + strlen (argv[argc-1]); 14918c2aff7Sartem 15018c2aff7Sartem argv_buffer = argv; 15118c2aff7Sartem argv_size = endptr - argv_buffer[0]; 15218c2aff7Sartem 15318c2aff7Sartem /* Make a copy of environ */ 15418c2aff7Sartem 15518c2aff7Sartem new_environ = malloc (sizeof(char*) * (i + 1)); 15618c2aff7Sartem for (i = 0; environ[i] != NULL; i++) 15718c2aff7Sartem new_environ[i] = strdup (environ[i]); 15818c2aff7Sartem new_environ[i] = NULL; 15918c2aff7Sartem 16018c2aff7Sartem environ = new_environ; 16118c2aff7Sartem #endif 16218c2aff7Sartem } 16318c2aff7Sartem 16418c2aff7Sartem /* this code borrowed from avahi-daemon's setproctitle.c (LGPL v2) */ 16518c2aff7Sartem void 16618c2aff7Sartem hal_set_proc_title (const char *format, ...) 16718c2aff7Sartem { 16818c2aff7Sartem #ifdef __linux__ 16918c2aff7Sartem size_t len; 17018c2aff7Sartem va_list ap; 17118c2aff7Sartem 17218c2aff7Sartem if (argv_buffer == NULL) 17318c2aff7Sartem goto out; 17418c2aff7Sartem 17518c2aff7Sartem va_start (ap, format); 17618c2aff7Sartem vsnprintf (argv_buffer[0], argv_size, format, ap); 17718c2aff7Sartem va_end (ap); 17818c2aff7Sartem 17918c2aff7Sartem len = strlen (argv_buffer[0]); 18018c2aff7Sartem 18118c2aff7Sartem memset (argv_buffer[0] + len, 0, argv_size - len); 18218c2aff7Sartem argv_buffer[1] = NULL; 18318c2aff7Sartem out: 18418c2aff7Sartem ; 18518c2aff7Sartem #endif 18618c2aff7Sartem } 18718c2aff7Sartem 188