/*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); }
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"); }
/* * Put the smb service into maintenance mode. */ int smb_smf_maintenance_mode(void) { return (smf_maintain_instance(SMBD_DEFAULT_INSTANCE_FMRI, 0)); }