nscd_selfcred.c revision 0dfdd7f38ea07ffc9a4b245c94185c923f4bb0a3
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * CDDL HEADER START
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * The contents of this file are subject to the terms of the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Common Development and Distribution License (the "License").
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * You may not use this file except in compliance with the License.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * See the License for the specific language governing permissions
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * and limitations under the License.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * When distributing Covered Code, include this CDDL HEADER in each
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * If applicable, add the following below this CDDL HEADER, with the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * fields enclosed by brackets "[]" replaced with your own identifying
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * information: Portions Copyright [yyyy] [name of copyright owner]
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * CDDL HEADER END
0dfdd7f38ea07ffc9a4b245c94185c923f4bb0a3michen * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Use is subject to license terms.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#pragma ident "%Z%%M% %I% %E% SMI"
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic char *execpath;
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic char **execargv;
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void *get_smf_prop(const char *var, char type, void *def_val);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/* current self-cred configuration data being used */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * clild state
cb5caa98562cf06753163f558cbcfe30b8f4673adjltypedef enum {
cb5caa98562cf06753163f558cbcfe30b8f4673adjltypedef struct _child {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/* nscd door id */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/* nscd id: main, forker, or child */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/* forker nscd pid */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (i = 0; i < max_pu_nscd; i++)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (-1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (-1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (-1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl child = (child_t **)calloc(max_pu_nscd, sizeof (child_t *));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (-1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "looking for uid %d (slot used = %d)\n", uid, used_slot);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* first find the slot with a matching uid */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (i = 0; i <= used_slot; i++) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* if no need to allocate a new slot, return NULL */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* no open slot ? get a new one */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* if no slot available, allocate more */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* got last one ? reset tail */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* have open slot ? add to and reset tail */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* no open slot ? make one */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* return if the slot has been returned by another thread */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* check one more time */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "kill request sent to door %d (rc = %d)\n", fd, ret);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (i = 0; i <= used_slot; i++) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ret = _nscd_doorcall_fd(fd, NSCD_PULSE |(_whoami & NSCD_WHOAMI),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*ARGSUSED*/
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* wait until forker exits */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl(me, "forker (pid = %d) exited or crashed, killing all child processes\n",
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* forker exited/crashed, kill all the child processes */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* restart forker */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* enter the maintenance mode */
ec2f0988b97ce539b7f3c03014df2120212b5f6eraf return ((void *)1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* wait until child exits */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* return the slot used by the child */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl switch (iam) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * I'm main, or uid from door is not correct,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * this must be an imposter
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * I'm forker, or uid from door is not correct,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * this must be an imposter
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* only main needs to know the forker */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* monitor the forker nscd */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* child nscd can only talk to the main nscd */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* get the main nscd assigned slot number */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* Bad slot number */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl dp->d_data.d_desc.d_descriptor, dp->d_data.d_desc.d_id);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * let waiters know that the child is ready to
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* monitor the child nscd */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* only main nscd sends pulse */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "MAIN IMPOSTER CAUGHT! i am %d not NSCD_MAIN\n", iam);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* forker doesn't return stats, it just pauses */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*CONSTCOND*/
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* remember the current activity sequence number */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl while (!done) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* allow per_user_nscd_ttl seconds of inactivity */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* no activity in the specified seconds, exit and disconnect */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "no activity in the last %d seconds, exit\n", pu_nscd_ttl);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "%d receives fork request from %d\n", _whoami, iam);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* only main nscd sends fork requests */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* only forker handles fork requests */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* fork a child for the slot assigned by the main nscd */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* set the uid/gid as assigned by the main nscd */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* ignore bad slot number */
e37190e5b4531a897e4191a30b8f41678b582e25michen * remember when this child nscd starts
e37190e5b4531a897e4191a30b8f41678b582e25michen * (replace the forker start time)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* close all except the log file */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (i = 0; i < _logfd; i++)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) close(i);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* set up the door and server thread pool */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((_doorfd = _nscd_setup_child_server(_doorfd)) == -1)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* tell libsldap to do self cred only */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* notify main that child is active */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* enter the maintenance mode */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * start the monitor so as to exit as early as
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * possible if no other processes are running
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * with the same PUN uid (i.e., this PUN is
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * not needed any more)
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* if no door fd, do nothing */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ret = _nscd_doorcall_fd(doorfd, NSCD_FORK|(_whoami&NSCD_WHOAMI),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "fork request sent to door %d for slot %d (rc = %d)\n",
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "fork request sent to door %d for slot %d failed: "
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cslot, NSCD_GET_STATUS(phdr), strerror(NSCD_GET_ERRNO(phdr)),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* make sure there is a door to talk to the forker */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* get door client's credential information */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* get door client's effective uid and effective gid */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* is a slot available ? if not, no one to serve */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (child == NULL || (ch = get_cslot(set2uid, 0)) == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "no child slot available (child array = %p, slot = %d)\n",
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* create the per user nscd if necessary */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* ask forker to fork a new child */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "waiting for door (slot = %d, uid = %d, gid = %d)\n",
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* wait for the per user nscd to become available */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "returning door %d for slot %d, uid %d, gid = %d\n",
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic char **
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int c = 4;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int i = 0, j, k = 0, n = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (k == 0)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl for (j = 0; j < n; j++)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* if self cred is not configured, do nothing */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* save pathname and generate the new argv for the forker */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* start the forker nscd */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* main nscd */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* remember process id of the forker */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* set NOFILE to unlimited */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* enable child nscd management */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* no handle to close, it's OK */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl static int checked = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl static int is_on = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl static int (*ldap_func)();
0dfdd7f38ea07ffc9a4b245c94185c923f4bb0a3michen return (0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * also check the ldap backend to see if
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * the configuration there is good for
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * doing self credentialing
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) get_ldap_funcs(ldap_sc_func, (void **)&ldap_func);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl static void (*ldap_func)();
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*ARGSUSED*/
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* get door client's credential information */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* get door client's effective uid */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* is the per-user nscd running ? if not, no one to serve */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "self cred config: enabled = %d\n", pu_nscd_enabled);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/* ARGSUSED */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_cfg_global_selfcred_t *sc_cfg = &nscd_selfcred_cfg_g;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * At init time, the whole group of config params are received.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * At update time, group or individual parameter value could
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * be received.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (_nscd_cfg_flag_is_set(dflag, NSCD_CFG_DFLAG_GROUP)) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * individual config parameter
cb5caa98562cf06753163f558cbcfe30b8f4673adjl off = offsetof(nscd_cfg_global_selfcred_t, enable_selfcred);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl off = offsetof(nscd_cfg_global_selfcred_t, max_per_user_nscd);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl off = offsetof(nscd_cfg_global_selfcred_t, per_user_nscd_ttl);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/* ARGSUSED */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/* ARGSUSED */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (uid == 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) snprintf(pname, sizeof (pname), "/proc/%s/psinfo", pid_name);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* Process may have exited */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Get the info structure for the process and close quickly.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (0);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (1);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: check_user_process
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*ARGSUSED*/
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*CONSTCOND*/
cb5caa98562cf06753163f558cbcfe30b8f4673adjl while (1) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * search the /proc directory and look at each process
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* for each active process */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * if no process running as the PUN uid found, exit
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * to kill this PUN
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (found == 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* NOTREACHED */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*LINTED E_FUNC_HAS_NO_RETURN_STMT*/
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * start a thread to make sure there is at least a process
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * running as the PUN user. If not, terminate this PUN.
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl switch (type) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl switch (type) {