xref: /illumos-gate/usr/src/cmd/hal/hald/util_helper.c (revision 55fea89d)
118c2aff7Sartem /***************************************************************************
218c2aff7Sartem  *
3*55fea89dSDan Cross  * util_helper.c - HAL utilities for helper (as e.g. prober/addons) et al.
418c2aff7Sartem  *
518c2aff7Sartem  * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
618c2aff7Sartem  *
718c2aff7Sartem  * Licensed under the Academic Free License version 2.1
818c2aff7Sartem  *
918c2aff7Sartem  * This program is free software; you can redistribute it and/or modify
1018c2aff7Sartem  * it under the terms of the GNU General Public License as published by
1118c2aff7Sartem  * the Free Software Foundation; either version 2 of the License, or
1218c2aff7Sartem  * (at your option) any later version.
1318c2aff7Sartem  *
1418c2aff7Sartem  * This program is distributed in the hope that it will be useful,
1518c2aff7Sartem  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1618c2aff7Sartem  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1718c2aff7Sartem  * GNU General Public License for more details.
1818c2aff7Sartem  *
1918c2aff7Sartem  * You should have received a copy of the GNU General Public License
2018c2aff7Sartem  * along with this program; if not, write to the Free Software
2118c2aff7Sartem  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
2218c2aff7Sartem  *
2318c2aff7Sartem  **************************************************************************/
2418c2aff7Sartem 
2518c2aff7Sartem #ifdef HAVE_CONFIG_H
2618c2aff7Sartem #  include <config.h>
2718c2aff7Sartem #endif
2818c2aff7Sartem 
2918c2aff7Sartem #include <grp.h>
3018c2aff7Sartem #include <stdarg.h>
3118c2aff7Sartem #include <stdlib.h>
3218c2aff7Sartem #include <string.h>
3318c2aff7Sartem #include <sys/time.h>
3418c2aff7Sartem #include <time.h>
3518c2aff7Sartem #include <pwd.h>
3618c2aff7Sartem #include <unistd.h>
3718c2aff7Sartem 
3818c2aff7Sartem #include "logger.h"
3918c2aff7Sartem 
4018c2aff7Sartem #include "util_helper.h"
4118c2aff7Sartem 
4218c2aff7Sartem #ifdef __linux__
4318c2aff7Sartem extern char **environ;
4418c2aff7Sartem #endif
4518c2aff7Sartem 
4618c2aff7Sartem static char **argv_buffer = NULL;
4718c2aff7Sartem static size_t argv_size = 0;
4818c2aff7Sartem 
4918c2aff7Sartem #ifdef sun
5018c2aff7Sartem #include <priv.h>
5118c2aff7Sartem void
drop_privileges(int keep_auxgroups)52f5f5f433SJerry Gilliam drop_privileges(int keep_auxgroups)
5318c2aff7Sartem {
54f5f5f433SJerry Gilliam 	priv_set_t *pPrivSet;
5518c2aff7Sartem 
5618c2aff7Sartem 	/*
5718c2aff7Sartem 	 * Start with the 'basic' privilege set and then remove any
5818c2aff7Sartem 	 * of the 'basic' privileges that will not be needed.
5918c2aff7Sartem 	 */
60f5f5f433SJerry Gilliam 	if ((pPrivSet = priv_allocset()) == NULL) {
6118c2aff7Sartem 		return;
6218c2aff7Sartem 	}
6318c2aff7Sartem 
64f5f5f433SJerry Gilliam 	/*
65f5f5f433SJerry Gilliam 	 * Establish the basic set of privileges.
66f5f5f433SJerry Gilliam 	 * Note: fork/exec required for libdevinfo devlink
67f5f5f433SJerry Gilliam 	 * interfaces are included in the basic set.
68f5f5f433SJerry Gilliam 	 */
69f5f5f433SJerry Gilliam 	priv_basicset(pPrivSet);
70f5f5f433SJerry Gilliam 
7118c2aff7Sartem 	/* Clear privileges we will not need from the 'basic' set */
7218c2aff7Sartem 	(void) priv_delset(pPrivSet, PRIV_FILE_LINK_ANY);
7318c2aff7Sartem 	(void) priv_delset(pPrivSet, PRIV_PROC_INFO);
7418c2aff7Sartem 	(void) priv_delset(pPrivSet, PRIV_PROC_SESSION);
7518c2aff7Sartem 
7618c2aff7Sartem 	/* for sysevent need to be root and have this privilege */
7718c2aff7Sartem 	(void) priv_addset(pPrivSet, PRIV_SYS_CONFIG);
7818c2aff7Sartem 
7973a8c195Sfei feng - Sun Microsystems - Beijing China 	/* need proc_audit privilege */
8073a8c195Sfei feng - Sun Microsystems - Beijing China 	(void) priv_addset(pPrivSet, PRIV_PROC_AUDIT);
8173a8c195Sfei feng - Sun Microsystems - Beijing China 
8218c2aff7Sartem 	/* Set the permitted privilege set. */
83f5f5f433SJerry Gilliam 	(void) setppriv(PRIV_SET, PRIV_PERMITTED, pPrivSet);
8418c2aff7Sartem 
85f5f5f433SJerry Gilliam 	/* Set the limit privilege set. */
86f5f5f433SJerry Gilliam 	(void) setppriv(PRIV_SET, PRIV_LIMIT, pPrivSet);
8718c2aff7Sartem 
88f5f5f433SJerry Gilliam 	priv_freeset(pPrivSet);
8918c2aff7Sartem }
9018c2aff7Sartem #else /* !sun */
9118c2aff7Sartem 
9218c2aff7Sartem /** Drop root privileges: Set the running user id to HAL_USER and
9318c2aff7Sartem  *  group to HAL_GROUP, and optionally retain auxiliary groups of HAL_USER.
9418c2aff7Sartem  */
9518c2aff7Sartem void
drop_privileges(int keep_auxgroups)9618c2aff7Sartem drop_privileges (int keep_auxgroups)
9718c2aff7Sartem {
9818c2aff7Sartem 	struct passwd *pw = NULL;
9918c2aff7Sartem 	struct group *gr = NULL;
10018c2aff7Sartem 
10118c2aff7Sartem 	/* determine user id */
10218c2aff7Sartem 	pw = getpwnam (HAL_USER);
10318c2aff7Sartem 	if (!pw)  {
10418c2aff7Sartem 		HAL_DEBUG (("drop_privileges: user " HAL_USER " does not exist"));
10518c2aff7Sartem 		exit (-1);
10618c2aff7Sartem 	}
10718c2aff7Sartem 
10818c2aff7Sartem 	/* determine primary group id */
10918c2aff7Sartem 	gr = getgrnam (HAL_GROUP);
11018c2aff7Sartem 	if (!gr) {
11118c2aff7Sartem 		HAL_DEBUG (("drop_privileges: group " HAL_GROUP " does not exist"));
11218c2aff7Sartem 		exit (-1);
11318c2aff7Sartem 	}
11418c2aff7Sartem 
11518c2aff7Sartem 	if (keep_auxgroups) {
11618c2aff7Sartem 		if (initgroups (HAL_USER, gr->gr_gid)) {
11718c2aff7Sartem 			HAL_DEBUG(("drop_privileges: could not initialize groups"));
11818c2aff7Sartem 			exit (-1);
11918c2aff7Sartem 		}
12018c2aff7Sartem 	}
12118c2aff7Sartem 
12218c2aff7Sartem 	if (setgid (gr->gr_gid)) {
12318c2aff7Sartem 		HAL_DEBUG (("drop_privileges: could not set group id"));
12418c2aff7Sartem 		exit (-1);
12518c2aff7Sartem 	}
12618c2aff7Sartem 
12718c2aff7Sartem 	if (setuid (pw->pw_uid)) {
12818c2aff7Sartem 		HAL_DEBUG (("drop_privileges: could not set user id"));
12918c2aff7Sartem 		exit (-1);
13018c2aff7Sartem 	}
13118c2aff7Sartem }
13218c2aff7Sartem #endif /* !sun */
13318c2aff7Sartem 
13418c2aff7Sartem void
hal_set_proc_title_init(int argc,char * argv[])13518c2aff7Sartem hal_set_proc_title_init (int argc, char *argv[])
13618c2aff7Sartem {
13718c2aff7Sartem #ifdef __linux__
13818c2aff7Sartem 	unsigned int i;
13918c2aff7Sartem 	char **new_environ, *endptr;
14018c2aff7Sartem 
14118c2aff7Sartem 	/* This code is really really ugly. We make some memory layout
14218c2aff7Sartem 	 * assumptions and reuse the environment array as memory to store
14318c2aff7Sartem 	 * our process title in */
144*55fea89dSDan Cross 
14518c2aff7Sartem 	for (i = 0; environ[i] != NULL; i++)
14618c2aff7Sartem 		;
147*55fea89dSDan Cross 
14818c2aff7Sartem 	endptr = i ? environ[i-1] + strlen (environ[i-1]) : argv[argc-1] + strlen (argv[argc-1]);
149*55fea89dSDan Cross 
15018c2aff7Sartem 	argv_buffer = argv;
15118c2aff7Sartem 	argv_size = endptr - argv_buffer[0];
152*55fea89dSDan Cross 
15318c2aff7Sartem 	/* Make a copy of environ */
154*55fea89dSDan Cross 
15518c2aff7Sartem 	new_environ = malloc (sizeof(char*) * (i + 1));
15618c2aff7Sartem 	for (i = 0; environ[i] != NULL; i++)
15718c2aff7Sartem 		new_environ[i] = strdup (environ[i]);
15818c2aff7Sartem 	new_environ[i] = NULL;
159*55fea89dSDan Cross 
16018c2aff7Sartem 	environ = new_environ;
16118c2aff7Sartem #endif
16218c2aff7Sartem }
16318c2aff7Sartem 
16418c2aff7Sartem /* this code borrowed from avahi-daemon's setproctitle.c (LGPL v2) */
16518c2aff7Sartem void
hal_set_proc_title(const char * format,...)16618c2aff7Sartem hal_set_proc_title (const char *format, ...)
16718c2aff7Sartem {
16818c2aff7Sartem #ifdef __linux__
16918c2aff7Sartem 	size_t len;
17018c2aff7Sartem 	va_list ap;
17118c2aff7Sartem 
17218c2aff7Sartem 	if (argv_buffer == NULL)
17318c2aff7Sartem 		goto out;
174*55fea89dSDan Cross 
17518c2aff7Sartem 	va_start (ap, format);
17618c2aff7Sartem 	vsnprintf (argv_buffer[0], argv_size, format, ap);
17718c2aff7Sartem 	va_end (ap);
178*55fea89dSDan Cross 
17918c2aff7Sartem 	len = strlen (argv_buffer[0]);
180*55fea89dSDan Cross 
18118c2aff7Sartem 	memset (argv_buffer[0] + len, 0, argv_size - len);
18218c2aff7Sartem 	argv_buffer[1] = NULL;
18318c2aff7Sartem out:
18418c2aff7Sartem 	;
18518c2aff7Sartem #endif
18618c2aff7Sartem }
18718c2aff7Sartem 
188