/*
 * If domain discovery is running, wait for it to finish.
 */
int
smb_ddiscover_wait(void)
{
	timestruc_t to;
	int rc = 0;

	(void) mutex_lock(&smb_dclocator.sdl_mtx);

	if (smb_dclocator.sdl_locate) {
		to.tv_sec = SMB_DCLOCATOR_TIMEOUT;
		to.tv_nsec = 0;
		rc = cond_reltimedwait(&smb_dclocator.sdl_cv,
		    &smb_dclocator.sdl_mtx, &to);
	}

	(void) mutex_unlock(&smb_dclocator.sdl_mtx);

	return (rc);
}
Exemple #2
0
void
smb_netbios_sleep(time_t seconds)
{
	timestruc_t reltimeout;

	(void) mutex_lock(&nbtd.nbs_mtx);

	if (nbtd.nbs_state == NETBIOS_STATE_RUNNING) {
		if (seconds == 0)
			seconds  = 1;
		reltimeout.tv_sec = seconds;
		reltimeout.tv_nsec = 0;

		(void) cond_reltimedwait(&nbtd.nbs_cv,
		    &nbtd.nbs_mtx, &reltimeout);
	}

	(void) mutex_unlock(&nbtd.nbs_mtx);
}
Exemple #3
0
/*
 * Waits for ch_wait seconds if cache is in UPDATING state.
 * Upon wake up returns true if cache is ready to be used,
 * otherwise it returns false.
 */
static boolean_t
smb_cache_wait(smb_cache_t *chandle)
{
	timestruc_t to;
	int err;

	if (chandle->ch_wait == 0)
		return (B_TRUE);

	to.tv_sec = chandle->ch_wait;
	to.tv_nsec = 0;
	while (chandle->ch_state == SMB_CACHE_STATE_REFRESHING) {
		err = cond_reltimedwait(&chandle->ch_cv,
		    &chandle->ch_mtx, &to);
		if (err == ETIME)
			break;
	}

	return (chandle->ch_state == SMB_CACHE_STATE_READY);
}
/*
 * This is the entry point for discovering a domain controller for the
 * specified domain.
 *
 * The actual work of discovering a DC is handled by DC locator thread.
 * All we do here is signal the request and wait for a DC or a timeout.
 *
 * Input parameters:
 *  domain - domain to be discovered (can either be NetBIOS or DNS domain)
 *  dc - preferred DC. If the preferred DC is set to empty string, it
 *       will attempt to discover any DC in the specified domain.
 *
 * Output parameter:
 *  dp - on success, dp will be filled with the discovered DC and domain
 *       information.
 * Returns B_TRUE if the DC/domain info is available.
 */
boolean_t
smb_locate_dc(char *domain, char *dc, smb_domainex_t *dp)
{
	int rc;
	timestruc_t to;
	smb_domainex_t domain_info;

	if (domain == NULL || *domain == '\0')
		return (B_FALSE);

	(void) mutex_lock(&smb_dclocator.sdl_mtx);

	if (!smb_dclocator.sdl_locate) {
		smb_dclocator.sdl_locate = B_TRUE;
		(void) strlcpy(smb_dclocator.sdl_domain, domain,
		    SMB_PI_MAX_DOMAIN);
		(void) strlcpy(smb_dclocator.sdl_dc, dc, MAXHOSTNAMELEN);
		(void) cond_broadcast(&smb_dclocator.sdl_cv);
	}

	while (smb_dclocator.sdl_locate) {
		to.tv_sec = SMB_DCLOCATOR_TIMEOUT;
		to.tv_nsec = 0;
		rc = cond_reltimedwait(&smb_dclocator.sdl_cv,
		    &smb_dclocator.sdl_mtx, &to);

		if (rc == ETIME)
			break;
	}

	if (dp == NULL)
		dp = &domain_info;
	rc = smb_domain_getinfo(dp);

	(void) mutex_unlock(&smb_dclocator.sdl_mtx);

	return (rc);
}
Exemple #5
0
/*
 *  all clients connected to a console must disconnect before
 *  removing a console.
 */
static void
cleanup_cons(vntsd_cons_t *consp)
{
	vntsd_group_t	*groupp;
	timestruc_t	to;

	assert(consp);
	D1(stderr, "t@%d vntsd_disconn_clients@%d\n", thr_self(),
	    consp->cons_no);

	groupp = consp->group;
	assert(groupp);


	(void) mutex_lock(&consp->lock);

	/* wait for all clients disconnect from the console */
	while (consp->clientpq != NULL) {
		consp->status |= VNTSD_CONS_SIG_WAIT;

		/* signal client to disconnect the console */
		(void) vntsd_que_walk(consp->clientpq,
		    (el_func_t)vntsd_notify_client_cons_del);

		(void) thr_kill(consp->wr_tid, SIGUSR1);
		to.tv_sec = VNTSD_CV_WAIT_DELTIME;
		to.tv_nsec = 0;

		/* wait for clients to disconnect  */
		(void) cond_reltimedwait(&consp->cvp, &consp->lock, &to);
	}

	(void) mutex_unlock(&consp->lock);

	free_cons(consp);
}
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);
}
Exemple #7
0
/* clean up a group */
void
vntsd_clean_group(vntsd_group_t *groupp)
{

	timestruc_t	to;

	D1(stderr, "t@%d clean_group() group=%s tcp=%lld\n", thr_self(),
	    groupp->group_name, groupp->tcp_port);

	(void) mutex_lock(&groupp->lock);

	/* prevent from reentry */
	if (groupp->status & VNTSD_GROUP_CLEANUP) {
		(void) mutex_unlock(&groupp->lock);
		return;
	}
	groupp->status |= VNTSD_GROUP_CLEANUP;
	vntsd_free_que(&groupp->conspq, (clean_func_t)cleanup_cons);
	(void) mutex_unlock(&groupp->lock);

	/* walk through no cons client queue */
	while (groupp->no_cons_clientpq != NULL) {
		groupp->status |= VNTSD_GROUP_SIG_WAIT;
		(void) vntsd_que_walk(groupp->no_cons_clientpq,
		    (el_func_t)vntsd_notify_client_cons_del);
		to.tv_sec = VNTSD_CV_WAIT_DELTIME;
		to.tv_nsec = 0;
		(void) cond_reltimedwait(&groupp->cvp, &groupp->lock, &to);
	}

	if (groupp->listen_tid == thr_self()) {
		/* listen thread is exiting */
		(void) mutex_lock(&(groupp->vntsd->lock));
		(void) vntsd_que_rm(&groupp->vntsd->grouppq, groupp);
		(void) mutex_unlock(&groupp->vntsd->lock);

		(void) cond_destroy(&groupp->cvp);
		(void) mutex_unlock(&groupp->lock);
		(void) mutex_destroy(&groupp->lock);
		free(groupp);
		return;
	}

	/* signal listen thread to exit  */
	groupp->status |= VNTSD_GROUP_SIG_WAIT;

	while (groupp->status & VNTSD_GROUP_SIG_WAIT) {
		(void) thr_kill(groupp->listen_tid, SIGUSR1);
		to.tv_sec = VNTSD_CV_WAIT_DELTIME;
		to.tv_nsec = 0;
		/* wait listen thread to exit  */
		(void) cond_reltimedwait(&groupp->cvp, &groupp->lock, &to);
	}

	(void) mutex_unlock(&groupp->lock);
	(void) thr_join(groupp->listen_tid, NULL, NULL);
	/* free group */
	(void) cond_destroy(&groupp->cvp);
	(void) mutex_destroy(&groupp->lock);
	free(groupp);
}
Exemple #8
0
domodify( char *dn, LDAPMod **pmods, int newentry )
#endif	/* SOLARIS_LDAP_CMD */
{
    int			i, j, notascii, op;
    struct berval	*bvp;

    if ( pmods == NULL ) {
	fprintf( stderr, gettext("%s: no attributes to change or add (entry %s)\n"),
		ldaptool_progname, dn );
	return( LDAP_PARAM_ERROR );
    }

    if ( ldaptool_verbose ) {
	for ( i = 0; pmods[ i ] != NULL; ++i ) {
	    op = pmods[ i ]->mod_op & ~LDAP_MOD_BVALUES;
	    printf( gettext("%s %s:\n"), op == LDAP_MOD_REPLACE ?
		    gettext("replace") : op == LDAP_MOD_ADD ?
		    gettext("add") : gettext("delete"), pmods[ i ]->mod_type );
	    if ( pmods[ i ]->mod_bvalues != NULL ) {
		for ( j = 0; pmods[ i ]->mod_bvalues[ j ] != NULL; ++j ) {
		    bvp = pmods[ i ]->mod_bvalues[ j ];
		    notascii = 0;
		    if ( !display_binary_values ) {
			notascii = !ldaptool_berval_is_ascii( bvp );
		    }
		    if ( notascii ) {
			printf( gettext("\tNOT ASCII (%ld bytes)\n"), bvp->bv_len );
		    } else {
			printf( "\t%s\n", bvp->bv_val );
		    }
		}
	    }
	}
    }

    if ( !ldapmodify_quiet) {
	if ( newentry ) {
	    printf( gettext("%sadding new entry %s\n"),
		ldaptool_not ? "!" : "", dn );
	} else {
	    printf( gettext("%smodifying entry %s\n"),
		ldaptool_not ? "!" : "", dn );
	}
    }

    if ( !ldaptool_not ) {
	if ( newentry ) {
	unsigned int	sleep_interval = 2; /* seconds */

#ifdef SOLARIS_LDAP_CMD
	    /* Backward compatibility with old Solaris command */
	    unsigned int nb = 0;
	    timestruc_t to; 
	    while ((i = ldaptool_add_ext_s( ld, dn, pmods,
			ldaptool_request_ctrls, NULL, "ldap_add" ))
			!= LDAP_SUCCESS) {
		if (i == LDAP_BUSY) {		
			if ( sleep_interval > 3600 ) {
				printf(gettext("ldap_add: Unable to complete "
						"request.  Server is too "
						"busy servicing other "
						"requests\n"));
				break;
			}
			if ( !ldapmodify_quiet ) {
				printf(gettext("ldap_add: LDAP_BUSY returned "
						"by server.  Will retry "
						"operation in %d seconds\n"),
						sleep_interval);
			}
			sleep( sleep_interval );
			sleep_interval *= 2;
		} else if (i == LDAP_NO_SUCH_OBJECT) {
			/*
			 * Wait for the parent entry to be created by
			 * another thread. Do not retry more than the
			 * number of threads.
			 */
			++nb;
			if (nb >= nbthreads)
				break;
			mutex_lock(&wait_mutex); 
			to.tv_sec = 5; 
			to.tv_nsec = 0; 
			if (cond_reltimedwait(&wait_cond, &wait_mutex, &to)
				== ETIME) {
					nb = nbthreads; /* last chance */ 
			} 
			mutex_unlock(&wait_mutex); 
		} else {
			break;
		}
	    }
	    cond_broadcast(&wait_cond);
#else
	    while ((i = ldaptool_add_ext_s( ld, dn, pmods,
			ldaptool_request_ctrls, NULL, "ldap_add" ))
			== LDAP_BUSY) {
		if ( sleep_interval > 3600 ) {
			printf("ldap_add: Unable to complete request. ");
			printf("Server is too ");
			printf("busy servicing other requests\n");
			break;
		}
		if ( !ldapmodify_quiet ) {
			printf("ldap_add: LDAP_BUSY returned by server. ");
			printf("Will retry operation ");
			printf("in %d seconds\n", sleep_interval); 
		}
		sleep( sleep_interval );
		sleep_interval *= 2;
	    }
#endif	/* SOLARIS_LDAP_CMD */
	} else {
	    i = ldaptool_modify_ext_s( ld, dn, pmods, ldaptool_request_ctrls,
		    NULL, "ldap_modify" );
	}
	if ( i == LDAP_SUCCESS && ldaptool_verbose ) {
	    printf( gettext("modify complete\n") );
	}
    } else {
	i = LDAP_SUCCESS;
    }

    if ( !ldapmodify_quiet) {
	putchar( '\n' );
    }

    return( i );
}