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 522912Sartem drop_privileges (int keep_auxgroups) 532912Sartem { 542912Sartem priv_set_t *pPrivSet = NULL; 552912Sartem priv_set_t *lPrivSet = NULL; 562912Sartem 572912Sartem /* 582912Sartem * Start with the 'basic' privilege set and then remove any 592912Sartem * of the 'basic' privileges that will not be needed. 602912Sartem */ 612912Sartem if ((pPrivSet = priv_str_to_set("basic", ",", NULL)) == NULL) { 622912Sartem return; 632912Sartem } 642912Sartem 652912Sartem /* Clear privileges we will not need from the 'basic' set */ 662912Sartem (void) priv_delset(pPrivSet, PRIV_FILE_LINK_ANY); 672912Sartem (void) priv_delset(pPrivSet, PRIV_PROC_INFO); 682912Sartem (void) priv_delset(pPrivSet, PRIV_PROC_SESSION); 692912Sartem 702912Sartem /* for sysevent need to be root and have this privilege */ 712912Sartem (void) priv_addset(pPrivSet, PRIV_SYS_CONFIG); 722912Sartem 73*11394SFei.Feng@Sun.COM /* need proc_audit privilege */ 74*11394SFei.Feng@Sun.COM (void) priv_addset(pPrivSet, PRIV_PROC_AUDIT); 75*11394SFei.Feng@Sun.COM 762912Sartem /* Set the permitted privilege set. */ 772912Sartem if (setppriv(PRIV_SET, PRIV_PERMITTED, pPrivSet) != 0) { 782912Sartem return; 792912Sartem } 802912Sartem 812912Sartem /* Clear the limit set. */ 822912Sartem if ((lPrivSet = priv_allocset()) == NULL) { 832912Sartem return; 842912Sartem } 852912Sartem 862912Sartem priv_emptyset(lPrivSet); 872912Sartem 882912Sartem if (setppriv(PRIV_SET, PRIV_LIMIT, lPrivSet) != 0) { 892912Sartem return; 902912Sartem } 912912Sartem 922912Sartem priv_freeset(lPrivSet); 932912Sartem } 942912Sartem #else /* !sun */ 952912Sartem 962912Sartem /** Drop root privileges: Set the running user id to HAL_USER and 972912Sartem * group to HAL_GROUP, and optionally retain auxiliary groups of HAL_USER. 982912Sartem */ 992912Sartem void 1002912Sartem drop_privileges (int keep_auxgroups) 1012912Sartem { 1022912Sartem struct passwd *pw = NULL; 1032912Sartem struct group *gr = NULL; 1042912Sartem 1052912Sartem /* determine user id */ 1062912Sartem pw = getpwnam (HAL_USER); 1072912Sartem if (!pw) { 1082912Sartem HAL_DEBUG (("drop_privileges: user " HAL_USER " does not exist")); 1092912Sartem exit (-1); 1102912Sartem } 1112912Sartem 1122912Sartem /* determine primary group id */ 1132912Sartem gr = getgrnam (HAL_GROUP); 1142912Sartem if (!gr) { 1152912Sartem HAL_DEBUG (("drop_privileges: group " HAL_GROUP " does not exist")); 1162912Sartem exit (-1); 1172912Sartem } 1182912Sartem 1192912Sartem if (keep_auxgroups) { 1202912Sartem if (initgroups (HAL_USER, gr->gr_gid)) { 1212912Sartem HAL_DEBUG(("drop_privileges: could not initialize groups")); 1222912Sartem exit (-1); 1232912Sartem } 1242912Sartem } 1252912Sartem 1262912Sartem if (setgid (gr->gr_gid)) { 1272912Sartem HAL_DEBUG (("drop_privileges: could not set group id")); 1282912Sartem exit (-1); 1292912Sartem } 1302912Sartem 1312912Sartem if (setuid (pw->pw_uid)) { 1322912Sartem HAL_DEBUG (("drop_privileges: could not set user id")); 1332912Sartem exit (-1); 1342912Sartem } 1352912Sartem } 1362912Sartem #endif /* !sun */ 1372912Sartem 1382912Sartem void 1392912Sartem hal_set_proc_title_init (int argc, char *argv[]) 1402912Sartem { 1412912Sartem #ifdef __linux__ 1422912Sartem unsigned int i; 1432912Sartem char **new_environ, *endptr; 1442912Sartem 1452912Sartem /* This code is really really ugly. We make some memory layout 1462912Sartem * assumptions and reuse the environment array as memory to store 1472912Sartem * our process title in */ 1482912Sartem 1492912Sartem for (i = 0; environ[i] != NULL; i++) 1502912Sartem ; 1512912Sartem 1522912Sartem endptr = i ? environ[i-1] + strlen (environ[i-1]) : argv[argc-1] + strlen (argv[argc-1]); 1532912Sartem 1542912Sartem argv_buffer = argv; 1552912Sartem argv_size = endptr - argv_buffer[0]; 1562912Sartem 1572912Sartem /* Make a copy of environ */ 1582912Sartem 1592912Sartem new_environ = malloc (sizeof(char*) * (i + 1)); 1602912Sartem for (i = 0; environ[i] != NULL; i++) 1612912Sartem new_environ[i] = strdup (environ[i]); 1622912Sartem new_environ[i] = NULL; 1632912Sartem 1642912Sartem environ = new_environ; 1652912Sartem #endif 1662912Sartem } 1672912Sartem 1682912Sartem /* this code borrowed from avahi-daemon's setproctitle.c (LGPL v2) */ 1692912Sartem void 1702912Sartem hal_set_proc_title (const char *format, ...) 1712912Sartem { 1722912Sartem #ifdef __linux__ 1732912Sartem size_t len; 1742912Sartem va_list ap; 1752912Sartem 1762912Sartem if (argv_buffer == NULL) 1772912Sartem goto out; 1782912Sartem 1792912Sartem va_start (ap, format); 1802912Sartem vsnprintf (argv_buffer[0], argv_size, format, ap); 1812912Sartem va_end (ap); 1822912Sartem 1832912Sartem len = strlen (argv_buffer[0]); 1842912Sartem 1852912Sartem memset (argv_buffer[0] + len, 0, argv_size - len); 1862912Sartem argv_buffer[1] = NULL; 1872912Sartem out: 1882912Sartem ; 1892912Sartem #endif 1902912Sartem } 1912912Sartem 192