Esempio n. 1
0
void
_nscd_APP_check_cred(
	void		*buf,
	pid_t		*pidp,
	char		*dc_str,
	int		log_comp,
	int		log_level)
{
	nss_pheader_t	*phdr = (nss_pheader_t *)buf;
	ucred_t		*uc = NULL;
	uid_t		ruid;
	uid_t		euid;
	pid_t		pid;
	int		errnum;
	char		*me = "_nscd_APP_check_cred";

	if (door_ucred(&uc) != 0) {
		errnum = errno;
		_NSCD_LOG(log_comp, NSCD_LOG_LEVEL_ERROR)
		(me, "door_ucred: %s\n", strerror(errno));

		NSCD_RETURN_STATUS(phdr, NSS_ERROR, errnum);
	}

	NSCD_SET_STATUS_SUCCESS(phdr);
	pid = ucred_getpid(uc);
	if (NSS_PACKED_CRED_CHECK(buf, ruid = ucred_getruid(uc),
	    euid = ucred_geteuid(uc))) {
		if (pidp != NULL) {
			if (*pidp == (pid_t)-1)
				*pidp = pid;
			else if (*pidp != pid) {
				NSCD_SET_STATUS(phdr, NSS_ERROR, EACCES);
			}
		}
	} else {
		NSCD_SET_STATUS(phdr, NSS_ERROR, EACCES);
	}

	ucred_free(uc);

	if (NSCD_STATUS_IS_NOT_OK(phdr)) {
		_NSCD_LOG(log_comp, log_level)
		(me, "%s call failed: caller pid %d (input pid = %d), ruid %d, "
		    "euid %d, header ruid %d, header euid %d\n", dc_str,
		    pid, (pidp != NULL) ? *pidp : -1, ruid, euid,
		    ((nss_pheader_t *)(buf))->p_ruid,
		    ((nss_pheader_t *)(buf))->p_euid);
	}
}
Esempio n. 2
0
static void
selfcred_fork(
	void		*buf,
	int		doorfd,
	int		cslot,
	uid_t		uid,
	gid_t		gid)
{
	int		ret;
	nscd_fork_t	f;
	nss_pheader_t	*phdr = (nss_pheader_t *)buf;
	char		*me = "selfcred_fork";

	/* if no door fd, do nothing */
	if (doorfd == -1) {
		NSCD_SET_N2N_STATUS(phdr, NSS_NSCD_PRIV, 0,
		    NSCD_SELF_CRED_NO_DOOR);
	}

	_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
	(me, "sending fork request to door %d for slot %d "
	    "(uid = %d, gid = %d)\n", doorfd, cslot, uid, gid);

	f.slot = cslot;
	f.uid = uid;
	f.gid = gid;

	ret = _nscd_doorcall_fd(doorfd, NSCD_FORK|(_whoami&NSCD_WHOAMI),
	    &f, sizeof (f), NULL, 0, phdr);

	_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
	(me, "fork request sent to door %d for slot %d (rc = %d)\n",
	    doorfd, cslot, ret);

	if (NSCD_STATUS_IS_NOT_OK(phdr)) {

		_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
		(me, "fork request sent to door %d for slot %d failed: "
		    "status = %d, errno = %s, nscd status = %d\n", doorfd,
		    cslot, NSCD_GET_STATUS(phdr),
		    strerror(NSCD_GET_ERRNO(phdr)),
		    NSCD_GET_NSCD_STATUS(phdr));

	}
}
Esempio n. 3
0
static void
send_doorfd(void **dptr, size_t *ndata, size_t *adata,
	door_desc_t *pdesc)
{
	nss_pheader_t	*phdr = (nss_pheader_t *)*dptr;
	door_arg_t	param;
	int		ret;
	int		doorfd;
	int		errnum;
	char		*me = "send_doorfd";

	initdoor(*dptr, &doorfd);
	if (NSCD_STATUS_IS_NOT_OK(phdr))
		return;

	param.rbuf = (char *)*dptr;
	param.rsize = *ndata;
	param.data_ptr = (char *)*dptr;
	param.data_size = *adata;
	param.desc_ptr = pdesc;
	param.desc_num = 1;
	ret = door_call(doorfd, &param);
	if (ret < 0) {
		errnum = errno;

		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
		(me, "door call (to fd %d) failed (%s)\n",
		    doorfd, strerror(errnum));
		(void) close(doorfd);
		NSCD_SET_STATUS(phdr, NSS_ERROR, errnum);
		return;
	}
	*adata = param.data_size;
	*ndata = param.rsize;
	*dptr = (void *)param.data_ptr;

	if (*adata == 0 || *dptr == NULL) {
		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
		(me, "no data\n");

		NSCD_SET_STATUS(phdr, NSS_ERROR, ENOTCONN);
	}

	(void) close(doorfd);
}
Esempio n. 4
0
nss_status_t
_nscd_doorcall_sendfd(int fd, int callnum, void *indata, int indlen,
	nss_pheader_t *phdr)
{
	void		*uptr;
	void		*dptr;
	void		*datap;
	size_t		ndata;
	size_t		adata;
	size_t		buflen;
	nss_pheader_t	*phdr_d;
	door_desc_t	desc;
	char		*me = "_nscd_doorcall_sendfd";

	_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
	(me, "processing door call %d (fd = %d)...\n", callnum, fd);

	/* allocate door buffer from the stack */
	NSCD_ALLOC_DOORBUF(callnum, indlen, uptr, buflen);
	dptr = uptr;
	ndata = buflen;
	adata = buflen;
	datap = NSCD_N2N_DOOR_DATA(void, dptr);
	if (indata != NULL)
		(void) memmove(datap, indata, indlen);
	desc.d_attributes = DOOR_DESCRIPTOR;
	desc.d_data.d_desc.d_descriptor = fd;

	send_doorfd(&dptr, &ndata, &adata, &desc);

	phdr_d = (nss_pheader_t *)dptr;
	if (NSCD_STATUS_IS_NOT_OK(phdr_d)) {
		if (phdr != NULL)
			*phdr = *phdr_d;

		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
		(me, "door call (%d) failed (status = %d, error = %s)\n",
		    callnum, NSCD_GET_STATUS(phdr_d),
		    strerror(NSCD_GET_ERRNO(phdr_d)));
	}

	return (NSCD_GET_STATUS(phdr_d));
}
Esempio n. 5
0
void
_nscd_proc_alt_get(
	void		*buf,
	int		*door)
{
	int		errnum;
	uid_t		set2uid;
	gid_t		set2gid;
	nss_pheader_t	*phdr = (nss_pheader_t *)buf;
	char		*me = "_nscd_proc_alt_get";
	ucred_t		*uc = NULL;
	child_t		*ch;

	_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
	(me, "getting an alternate door ...\n");

	/* make sure there is a door to talk to the forker */
	if (forking_door == -1) {
		_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_ERROR)
		(me, "no door to talk to the forker\n");

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

	/* get door client's credential information */
	if (door_ucred(&uc) != 0) {
		errnum = errno;
		_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
		(me, "door_ucred failed: %s\n", strerror(errnum));

		NSCD_RETURN_N2N_STATUS(phdr, NSS_NSCD_PRIV, errnum,
		    NSCD_DOOR_UCRED_ERROR);
	}

	/* get door client's effective uid and effective gid */
	set2uid = ucred_geteuid(uc);
	set2gid = ucred_getegid(uc);
	ucred_free(uc);
	uc = NULL;

	_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
	(me, "child uid = %d, gid = %d\n", set2uid, set2gid);

	/* is a slot available ? if not, no one to serve */
	if (child == NULL || (ch = get_cslot(set2uid, 0)) == NULL) {

		_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
		(me, "no child slot available (child array = %p, slot = %d)\n",
		    child, ch->child_slot);

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

	/* create the per user nscd if necessary */
	if (ch->child_state != CHILD_STATE_PIDKNOWN) {

		nss_pheader_t	phdr1;
		NSCD_CLEAR_STATUS(&phdr1);

		(void) mutex_lock(ch->mutex);
		if (ch->child_state == CHILD_STATE_UIDKNOWN) {

			/* ask forker to fork a new child */
			selfcred_fork(&phdr1, forking_door, ch->child_slot,
			    set2uid, set2gid);
			if (NSCD_STATUS_IS_NOT_OK(&phdr1)) {
				(void) mutex_unlock(ch->mutex);
				NSCD_COPY_STATUS(phdr, &phdr1);
				return;
			}
			ch->child_state = CHILD_STATE_FORKSENT;
		}

		_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
		(me, "waiting for door (slot = %d, uid = %d, gid = %d)\n",
		    ch->child_slot, set2uid, set2gid);

		/* wait for the per user nscd to become available */
		while (ch->child_state == CHILD_STATE_FORKSENT) {
			timestruc_t to;
			int err;
			int ttl = 5;

			to.tv_sec = ttl;
			to.tv_nsec = 0;
			_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
				(me, "cond_reltimedwait %d seconds\n", ttl);
			err = cond_reltimedwait(ch->cond, ch->mutex, &to);
			if (err == ETIME) {
				ch->child_state = CHILD_STATE_UIDKNOWN;
				_NSCD_LOG(NSCD_LOG_SELF_CRED,
				    NSCD_LOG_LEVEL_DEBUG)
				(me, "door wait timedout (slot = %d)\n",
				    ch->child_slot);
				break;
			}
		}
		(void) mutex_unlock(ch->mutex);
	}

	if (ch->child_state != CHILD_STATE_PIDKNOWN) {

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

	*door = ch->child_door;

	_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG)
	(me, "returning door %d for slot %d, uid %d, gid = %d\n",
	    *door, ch->child_slot, set2uid, set2gid);

	NSCD_RETURN_STATUS(phdr, NSS_ALTRETRY, 0);
}