xref: /onnv-gate/usr/src/cmd/hal/hald/util_helper.c (revision 11649:3eb4beedba47)
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