Beispiel #1
0
/*ARGSUSED*/
static void *
forker_monitor(
	void		*arg)
{
	pid_t		fpid;
	char		*fmri;
	char		*me = "forker_monitor";

	/* wait until forker exits */
	fpid = forker_pid;
	(void) selfcred_pulse(forking_door);

	_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
	(me, "forker (pid = %d) exited or crashed, "
	    "killing all child processes\n", fpid);

	(void) mutex_lock(&forking_lock);
	forking_door = -1;
	forker_pid = -1;
	(void) mutex_unlock(&forking_lock);

	/* forker exited/crashed, kill all the child processes */
	_nscd_kill_all_children();

	/* restart forker */
	_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
	(me, "restarting the forker ...\n");

	switch (fpid = fork1()) {
	case (pid_t)-1:
		_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
		(me, "unable to fork and start the forker ...\n");

		/* enter the maintenance mode */
		if ((fmri = getenv("SMF_FMRI")) != NULL) {
			_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
			(me, "entering maintenance mode ...\n");
			(void) smf_maintain_instance(fmri, SMF_TEMPORARY);
		}
		return ((void *)1);
		break;
	case 0:
		_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
		(me, "execv path = %s\n", execpath);

		(void) execv(execpath, execargv);
		exit(0);
		break;
	default:
		_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
		(me, "new forker's pid is %d\n", fpid);
		forker_pid = fpid;
		break;
	}

	return (NULL);
}
Beispiel #2
0
void
_nscd_proc_fork(
	void		*buf,
	int		iam)
{
	int		slot;
	int		ret;
	char		*fmri;
	pid_t		cid;
	uid_t		set2uid;
	gid_t		set2gid;
	nss_pheader_t	*phdr = (nss_pheader_t *)buf;
	char		*me = "_nscd_proc_fork";
	nscd_fork_t	*f;
	nscd_imhere_t	ih;

	_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
	(me, "%d receives fork request from %d\n", _whoami, iam);

	/* only main nscd sends fork requests */
	if (iam != NSCD_MAIN) {
		_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
		(me, "MAIN IMPOSTER CAUGHT! i am %d not NSCD_MAIN\n", iam);

		NSCD_RETURN_N2N_STATUS(phdr, NSS_NSCD_PRIV, 0,
		    NSCD_SELF_CRED_MAIN_IMPOSTER);
	}

	/* only forker handles fork requests */
	if (_whoami != NSCD_FORKER) {
		_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
		(me, "MAIN IMPOSTER CAUGHT! I AM NOT FORKER!\n");

		NSCD_RETURN_N2N_STATUS(phdr, NSS_NSCD_PRIV, 0,
		    NSCD_SELF_CRED_WRONG_NSCD);
	}

	/* fork a child for the slot assigned by the main nscd */
	f = NSCD_N2N_DOOR_DATA(nscd_fork_t, buf);
	slot = f->slot;
	/* set the uid/gid as assigned by the main nscd */
	set2uid = f->uid;
	set2gid = f->gid;

	/* ignore bad slot number */
	if (slot < 0 || slot >= max_pu_nscd) {
		_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
		(me, "bas slot number\n");

		NSCD_RETURN_N2N_STATUS(phdr, NSS_NSCD_PRIV, 0,
		    NSCD_SELF_CRED_INVALID_SLOT_NUMBER);
	}

	_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
	(me, "before fork1() ...\n");

	if ((cid = fork1()) == 0) {
		_whoami = NSCD_CHILD;

		/*
		 * remember when this child nscd starts
		 * (replace the forker start time)
		 */
		_nscd_set_start_time(1);

		/* close all except the log file */
		if (_logfd > 0) {
			int i;
			for (i = 0; i < _logfd; i++)
				(void) close(i);
			closefrom(_logfd + 1);
		} else
			closefrom(0);

		_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
		(me, "child %d\n", getpid());

		(void) setgid(set2gid);
		(void) setuid(set2uid);

		/* set up the door and server thread pool */
		if ((_doorfd = _nscd_setup_child_server(_doorfd)) == -1)
			exit(-1);

		/* tell libsldap to do self cred only */
		(void) setup_ldap_backend();

		/* notify main that child is active */
		ih.slot = slot;
		for (ret = NSS_ALTRETRY; ret == NSS_ALTRETRY; )
			ret = _nscd_doorcall_sendfd(_doorfd,
			    NSCD_IMHERE | (NSCD_CHILD & NSCD_WHOAMI),
			    &ih, sizeof (ih), NULL);

			NSCD_RETURN_STATUS_SUCCESS(phdr);
	} if (cid  == (pid_t)-1) {
		_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
		(me, "forker unable to fork ...\n");

		/* enter the maintenance mode */
		if ((fmri = getenv("SMF_FMRI")) != NULL) {
			_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
			(me, "entering maintenance mode ...\n");
			(void) smf_maintain_instance(fmri, SMF_TEMPORARY);
		}
		exit(0);
	} else {
		/*
		 * start the monitor so as to exit as early as
		 * possible if no other processes are running
		 * with the same PUN uid (i.e., this PUN is
		 * not needed any more)
		 */
		(void) init_user_proc_monitor();

		_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
		(me, "child forked:  parent pid = %d, child pid = %d\n",
		    getpid(), cid);

		NSCD_SET_STATUS_SUCCESS(phdr);
	}

	_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
	(me, "after fork\n");
}
Beispiel #3
0
/*
 * Put the smb service into maintenance mode.
 */
int
smb_smf_maintenance_mode(void)
{
	return (smf_maintain_instance(SMBD_DEFAULT_INSTANCE_FMRI, 0));
}