12912Sartem /*************************************************************************** 22912Sartem * 32912Sartem * util_helper.c - HAL utilities for helper (as e.g. prober/addons) et al. 42912Sartem * 52912Sartem * Copyright (C) 2006 David Zeuthen, <david@fubar.dk> 62912Sartem * 72912Sartem * Licensed under the Academic Free License version 2.1 82912Sartem * 92912Sartem * This program is free software; you can redistribute it and/or modify 102912Sartem * it under the terms of the GNU General Public License as published by 112912Sartem * the Free Software Foundation; either version 2 of the License, or 122912Sartem * (at your option) any later version. 132912Sartem * 142912Sartem * This program is distributed in the hope that it will be useful, 152912Sartem * but WITHOUT ANY WARRANTY; without even the implied warranty of 162912Sartem * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 172912Sartem * GNU General Public License for more details. 182912Sartem * 192912Sartem * You should have received a copy of the GNU General Public License 202912Sartem * along with this program; if not, write to the Free Software 212912Sartem * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 222912Sartem * 232912Sartem **************************************************************************/ 242912Sartem 252912Sartem #ifdef HAVE_CONFIG_H 262912Sartem # include <config.h> 272912Sartem #endif 282912Sartem 292912Sartem #include <grp.h> 302912Sartem #include <stdarg.h> 312912Sartem #include <stdlib.h> 322912Sartem #include <string.h> 332912Sartem #include <sys/time.h> 342912Sartem #include <time.h> 352912Sartem #include <pwd.h> 362912Sartem #include <unistd.h> 372912Sartem 382912Sartem #include "logger.h" 392912Sartem 402912Sartem #include "util_helper.h" 412912Sartem 422912Sartem #ifdef __linux__ 432912Sartem extern char **environ; 442912Sartem #endif 452912Sartem 462912Sartem static char **argv_buffer = NULL; 472912Sartem static size_t argv_size = 0; 482912Sartem 492912Sartem #ifdef sun 502912Sartem #include <priv.h> 512912Sartem void 52*11649SJerry.Gilliam@Sun.COM drop_privileges(int keep_auxgroups) 532912Sartem { 54*11649SJerry.Gilliam@Sun.COM priv_set_t *pPrivSet; 552912Sartem 562912Sartem /* 572912Sartem * Start with the 'basic' privilege set and then remove any 582912Sartem * of the 'basic' privileges that will not be needed. 592912Sartem */ 60*11649SJerry.Gilliam@Sun.COM if ((pPrivSet = priv_allocset()) == NULL) { 612912Sartem return; 622912Sartem } 632912Sartem 64*11649SJerry.Gilliam@Sun.COM /* 65*11649SJerry.Gilliam@Sun.COM * Establish the basic set of privileges. 66*11649SJerry.Gilliam@Sun.COM * Note: fork/exec required for libdevinfo devlink 67*11649SJerry.Gilliam@Sun.COM * interfaces are included in the basic set. 68*11649SJerry.Gilliam@Sun.COM */ 69*11649SJerry.Gilliam@Sun.COM priv_basicset(pPrivSet); 70*11649SJerry.Gilliam@Sun.COM 712912Sartem /* Clear privileges we will not need from the 'basic' set */ 722912Sartem (void) priv_delset(pPrivSet, PRIV_FILE_LINK_ANY); 732912Sartem (void) priv_delset(pPrivSet, PRIV_PROC_INFO); 742912Sartem (void) priv_delset(pPrivSet, PRIV_PROC_SESSION); 752912Sartem 762912Sartem /* for sysevent need to be root and have this privilege */ 772912Sartem (void) priv_addset(pPrivSet, PRIV_SYS_CONFIG); 782912Sartem 7911394SFei.Feng@Sun.COM /* need proc_audit privilege */ 8011394SFei.Feng@Sun.COM (void) priv_addset(pPrivSet, PRIV_PROC_AUDIT); 8111394SFei.Feng@Sun.COM 822912Sartem /* Set the permitted privilege set. */ 83*11649SJerry.Gilliam@Sun.COM (void) setppriv(PRIV_SET, PRIV_PERMITTED, pPrivSet); 842912Sartem 85*11649SJerry.Gilliam@Sun.COM /* Set the limit privilege set. */ 86*11649SJerry.Gilliam@Sun.COM (void) setppriv(PRIV_SET, PRIV_LIMIT, pPrivSet); 872912Sartem 88*11649SJerry.Gilliam@Sun.COM priv_freeset(pPrivSet); 892912Sartem } 902912Sartem #else /* !sun */ 912912Sartem 922912Sartem /** Drop root privileges: Set the running user id to HAL_USER and 932912Sartem * group to HAL_GROUP, and optionally retain auxiliary groups of HAL_USER. 942912Sartem */ 952912Sartem void 962912Sartem drop_privileges (int keep_auxgroups) 972912Sartem { 982912Sartem struct passwd *pw = NULL; 992912Sartem struct group *gr = NULL; 1002912Sartem 1012912Sartem /* determine user id */ 1022912Sartem pw = getpwnam (HAL_USER); 1032912Sartem if (!pw) { 1042912Sartem HAL_DEBUG (("drop_privileges: user " HAL_USER " does not exist")); 1052912Sartem exit (-1); 1062912Sartem } 1072912Sartem 1082912Sartem /* determine primary group id */ 1092912Sartem gr = getgrnam (HAL_GROUP); 1102912Sartem if (!gr) { 1112912Sartem HAL_DEBUG (("drop_privileges: group " HAL_GROUP " does not exist")); 1122912Sartem exit (-1); 1132912Sartem } 1142912Sartem 1152912Sartem if (keep_auxgroups) { 1162912Sartem if (initgroups (HAL_USER, gr->gr_gid)) { 1172912Sartem HAL_DEBUG(("drop_privileges: could not initialize groups")); 1182912Sartem exit (-1); 1192912Sartem } 1202912Sartem } 1212912Sartem 1222912Sartem if (setgid (gr->gr_gid)) { 1232912Sartem HAL_DEBUG (("drop_privileges: could not set group id")); 1242912Sartem exit (-1); 1252912Sartem } 1262912Sartem 1272912Sartem if (setuid (pw->pw_uid)) { 1282912Sartem HAL_DEBUG (("drop_privileges: could not set user id")); 1292912Sartem exit (-1); 1302912Sartem } 1312912Sartem } 1322912Sartem #endif /* !sun */ 1332912Sartem 1342912Sartem void 1352912Sartem hal_set_proc_title_init (int argc, char *argv[]) 1362912Sartem { 1372912Sartem #ifdef __linux__ 1382912Sartem unsigned int i; 1392912Sartem char **new_environ, *endptr; 1402912Sartem 1412912Sartem /* This code is really really ugly. We make some memory layout 1422912Sartem * assumptions and reuse the environment array as memory to store 1432912Sartem * our process title in */ 1442912Sartem 1452912Sartem for (i = 0; environ[i] != NULL; i++) 1462912Sartem ; 1472912Sartem 1482912Sartem endptr = i ? environ[i-1] + strlen (environ[i-1]) : argv[argc-1] + strlen (argv[argc-1]); 1492912Sartem 1502912Sartem argv_buffer = argv; 1512912Sartem argv_size = endptr - argv_buffer[0]; 1522912Sartem 1532912Sartem /* Make a copy of environ */ 1542912Sartem 1552912Sartem new_environ = malloc (sizeof(char*) * (i + 1)); 1562912Sartem for (i = 0; environ[i] != NULL; i++) 1572912Sartem new_environ[i] = strdup (environ[i]); 1582912Sartem new_environ[i] = NULL; 1592912Sartem 1602912Sartem environ = new_environ; 1612912Sartem #endif 1622912Sartem } 1632912Sartem 1642912Sartem /* this code borrowed from avahi-daemon's setproctitle.c (LGPL v2) */ 1652912Sartem void 1662912Sartem hal_set_proc_title (const char *format, ...) 1672912Sartem { 1682912Sartem #ifdef __linux__ 1692912Sartem size_t len; 1702912Sartem va_list ap; 1712912Sartem 1722912Sartem if (argv_buffer == NULL) 1732912Sartem goto out; 1742912Sartem 1752912Sartem va_start (ap, format); 1762912Sartem vsnprintf (argv_buffer[0], argv_size, format, ap); 1772912Sartem va_end (ap); 1782912Sartem 1792912Sartem len = strlen (argv_buffer[0]); 1802912Sartem 1812912Sartem memset (argv_buffer[0] + len, 0, argv_size - len); 1822912Sartem argv_buffer[1] = NULL; 1832912Sartem out: 1842912Sartem ; 1852912Sartem #endif 1862912Sartem } 1872912Sartem 188