1*2912Sartem /*************************************************************************** 2*2912Sartem * 3*2912Sartem * util_helper.c - HAL utilities for helper (as e.g. prober/addons) et al. 4*2912Sartem * 5*2912Sartem * Copyright (C) 2006 David Zeuthen, <david@fubar.dk> 6*2912Sartem * 7*2912Sartem * Licensed under the Academic Free License version 2.1 8*2912Sartem * 9*2912Sartem * This program is free software; you can redistribute it and/or modify 10*2912Sartem * it under the terms of the GNU General Public License as published by 11*2912Sartem * the Free Software Foundation; either version 2 of the License, or 12*2912Sartem * (at your option) any later version. 13*2912Sartem * 14*2912Sartem * This program is distributed in the hope that it will be useful, 15*2912Sartem * but WITHOUT ANY WARRANTY; without even the implied warranty of 16*2912Sartem * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17*2912Sartem * GNU General Public License for more details. 18*2912Sartem * 19*2912Sartem * You should have received a copy of the GNU General Public License 20*2912Sartem * along with this program; if not, write to the Free Software 21*2912Sartem * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22*2912Sartem * 23*2912Sartem **************************************************************************/ 24*2912Sartem 25*2912Sartem #ifdef HAVE_CONFIG_H 26*2912Sartem # include <config.h> 27*2912Sartem #endif 28*2912Sartem 29*2912Sartem #include <grp.h> 30*2912Sartem #include <stdarg.h> 31*2912Sartem #include <stdlib.h> 32*2912Sartem #include <string.h> 33*2912Sartem #include <sys/time.h> 34*2912Sartem #include <time.h> 35*2912Sartem #include <pwd.h> 36*2912Sartem #include <unistd.h> 37*2912Sartem 38*2912Sartem #include "logger.h" 39*2912Sartem 40*2912Sartem #include "util_helper.h" 41*2912Sartem 42*2912Sartem #ifdef __linux__ 43*2912Sartem extern char **environ; 44*2912Sartem #endif 45*2912Sartem 46*2912Sartem static char **argv_buffer = NULL; 47*2912Sartem static size_t argv_size = 0; 48*2912Sartem 49*2912Sartem #ifdef sun 50*2912Sartem #include <priv.h> 51*2912Sartem void 52*2912Sartem drop_privileges (int keep_auxgroups) 53*2912Sartem { 54*2912Sartem priv_set_t *pPrivSet = NULL; 55*2912Sartem priv_set_t *lPrivSet = NULL; 56*2912Sartem 57*2912Sartem /* 58*2912Sartem * Start with the 'basic' privilege set and then remove any 59*2912Sartem * of the 'basic' privileges that will not be needed. 60*2912Sartem */ 61*2912Sartem if ((pPrivSet = priv_str_to_set("basic", ",", NULL)) == NULL) { 62*2912Sartem return; 63*2912Sartem } 64*2912Sartem 65*2912Sartem /* Clear privileges we will not need from the 'basic' set */ 66*2912Sartem (void) priv_delset(pPrivSet, PRIV_FILE_LINK_ANY); 67*2912Sartem (void) priv_delset(pPrivSet, PRIV_PROC_INFO); 68*2912Sartem (void) priv_delset(pPrivSet, PRIV_PROC_SESSION); 69*2912Sartem 70*2912Sartem /* for sysevent need to be root and have this privilege */ 71*2912Sartem (void) priv_addset(pPrivSet, PRIV_SYS_CONFIG); 72*2912Sartem 73*2912Sartem /* Set the permitted privilege set. */ 74*2912Sartem if (setppriv(PRIV_SET, PRIV_PERMITTED, pPrivSet) != 0) { 75*2912Sartem return; 76*2912Sartem } 77*2912Sartem 78*2912Sartem /* Clear the limit set. */ 79*2912Sartem if ((lPrivSet = priv_allocset()) == NULL) { 80*2912Sartem return; 81*2912Sartem } 82*2912Sartem 83*2912Sartem priv_emptyset(lPrivSet); 84*2912Sartem 85*2912Sartem if (setppriv(PRIV_SET, PRIV_LIMIT, lPrivSet) != 0) { 86*2912Sartem return; 87*2912Sartem } 88*2912Sartem 89*2912Sartem priv_freeset(lPrivSet); 90*2912Sartem } 91*2912Sartem #else /* !sun */ 92*2912Sartem 93*2912Sartem /** Drop root privileges: Set the running user id to HAL_USER and 94*2912Sartem * group to HAL_GROUP, and optionally retain auxiliary groups of HAL_USER. 95*2912Sartem */ 96*2912Sartem void 97*2912Sartem drop_privileges (int keep_auxgroups) 98*2912Sartem { 99*2912Sartem struct passwd *pw = NULL; 100*2912Sartem struct group *gr = NULL; 101*2912Sartem 102*2912Sartem /* determine user id */ 103*2912Sartem pw = getpwnam (HAL_USER); 104*2912Sartem if (!pw) { 105*2912Sartem HAL_DEBUG (("drop_privileges: user " HAL_USER " does not exist")); 106*2912Sartem exit (-1); 107*2912Sartem } 108*2912Sartem 109*2912Sartem /* determine primary group id */ 110*2912Sartem gr = getgrnam (HAL_GROUP); 111*2912Sartem if (!gr) { 112*2912Sartem HAL_DEBUG (("drop_privileges: group " HAL_GROUP " does not exist")); 113*2912Sartem exit (-1); 114*2912Sartem } 115*2912Sartem 116*2912Sartem if (keep_auxgroups) { 117*2912Sartem if (initgroups (HAL_USER, gr->gr_gid)) { 118*2912Sartem HAL_DEBUG(("drop_privileges: could not initialize groups")); 119*2912Sartem exit (-1); 120*2912Sartem } 121*2912Sartem } 122*2912Sartem 123*2912Sartem if (setgid (gr->gr_gid)) { 124*2912Sartem HAL_DEBUG (("drop_privileges: could not set group id")); 125*2912Sartem exit (-1); 126*2912Sartem } 127*2912Sartem 128*2912Sartem if (setuid (pw->pw_uid)) { 129*2912Sartem HAL_DEBUG (("drop_privileges: could not set user id")); 130*2912Sartem exit (-1); 131*2912Sartem } 132*2912Sartem } 133*2912Sartem #endif /* !sun */ 134*2912Sartem 135*2912Sartem void 136*2912Sartem hal_set_proc_title_init (int argc, char *argv[]) 137*2912Sartem { 138*2912Sartem #ifdef __linux__ 139*2912Sartem unsigned int i; 140*2912Sartem char **new_environ, *endptr; 141*2912Sartem 142*2912Sartem /* This code is really really ugly. We make some memory layout 143*2912Sartem * assumptions and reuse the environment array as memory to store 144*2912Sartem * our process title in */ 145*2912Sartem 146*2912Sartem for (i = 0; environ[i] != NULL; i++) 147*2912Sartem ; 148*2912Sartem 149*2912Sartem endptr = i ? environ[i-1] + strlen (environ[i-1]) : argv[argc-1] + strlen (argv[argc-1]); 150*2912Sartem 151*2912Sartem argv_buffer = argv; 152*2912Sartem argv_size = endptr - argv_buffer[0]; 153*2912Sartem 154*2912Sartem /* Make a copy of environ */ 155*2912Sartem 156*2912Sartem new_environ = malloc (sizeof(char*) * (i + 1)); 157*2912Sartem for (i = 0; environ[i] != NULL; i++) 158*2912Sartem new_environ[i] = strdup (environ[i]); 159*2912Sartem new_environ[i] = NULL; 160*2912Sartem 161*2912Sartem environ = new_environ; 162*2912Sartem #endif 163*2912Sartem } 164*2912Sartem 165*2912Sartem /* this code borrowed from avahi-daemon's setproctitle.c (LGPL v2) */ 166*2912Sartem void 167*2912Sartem hal_set_proc_title (const char *format, ...) 168*2912Sartem { 169*2912Sartem #ifdef __linux__ 170*2912Sartem size_t len; 171*2912Sartem va_list ap; 172*2912Sartem 173*2912Sartem if (argv_buffer == NULL) 174*2912Sartem goto out; 175*2912Sartem 176*2912Sartem va_start (ap, format); 177*2912Sartem vsnprintf (argv_buffer[0], argv_size, format, ap); 178*2912Sartem va_end (ap); 179*2912Sartem 180*2912Sartem len = strlen (argv_buffer[0]); 181*2912Sartem 182*2912Sartem memset (argv_buffer[0] + len, 0, argv_size - len); 183*2912Sartem argv_buffer[1] = NULL; 184*2912Sartem out: 185*2912Sartem ; 186*2912Sartem #endif 187*2912Sartem } 188*2912Sartem 189