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
drop_privileges(int keep_auxgroups)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
drop_privileges(int keep_auxgroups)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
hal_set_proc_title_init(int argc,char * argv[])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
hal_set_proc_title(const char * format,...)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