Ejemplo n.º 1
0
PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags
			      , int argc, const char **argv)
{
    const char *service=NULL, *tty=NULL;
    const char *user=NULL;
    int retval;
    unsigned setting;

    /* only interested in establishing credentials */

    setting = flags;
    if (!(setting & PAM_ESTABLISH_CRED)) {
	D(("ignoring call - not for establishing credentials"));
	return PAM_SUCCESS;            /* don't fail because of this */
    }

    /* set service name */

    if (pam_get_item(pamh, PAM_SERVICE, (const void **)&service)
	!= PAM_SUCCESS || service == NULL) {
	_log_err("cannot find the current service name");
	return PAM_ABORT;
    }

    /* set username */

    if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS || user == NULL
	|| *user == '\0') {
	_log_err("cannot determine the user's name");
	return PAM_USER_UNKNOWN;
    }

    /* set tty name */

    if (pam_get_item(pamh, PAM_TTY, (const void **)&tty) != PAM_SUCCESS
	|| tty == NULL) {
	D(("PAM_TTY not set, probing stdin"));
	tty = ttyname(STDIN_FILENO);
	if (tty == NULL) {
	    _log_err("couldn't get the tty name");
	    return PAM_ABORT;
	}
	if (pam_set_item(pamh, PAM_TTY, tty) != PAM_SUCCESS) {
	    _log_err("couldn't set tty name");
	    return PAM_ABORT;
	}
    }

    if (strncmp("/dev/",tty,5) == 0) {          /* strip leading /dev/ */
	tty += 5;
    }

    /* good, now we have the service name, the user and the terminal name */

    D(("service=%s", service));
    D(("user=%s", user));
    D(("tty=%s", tty));

#ifdef WANT_PWDB

    /* We initialize the pwdb library and check the account */
    retval = pwdb_start();                             /* initialize */
    if (retval == PWDB_SUCCESS) {
	retval = check_account(service,tty,user);      /* get groups */
	(void) pwdb_end();                                /* tidy up */
    } else {
	D(("failed to initialize pwdb; %s", pwdb_strerror(retval)));
	_log_err("unable to initialize libpwdb");
	retval = PAM_ABORT;
    }

#else /* WANT_PWDB */
    retval = check_account(service,tty,user);          /* get groups */
#endif /* WANT_PWDB */

    return retval;
}
Ejemplo n.º 2
0
NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
				const char *sent_nt_username,
				const char *domain,
				struct auth_serversupplied_info **server_info,
				const struct netr_SamInfo3 *info3)
{
	static const char zeros[16] = {0, };

	NTSTATUS nt_status = NT_STATUS_OK;
	char *found_username = NULL;
	const char *nt_domain;
	const char *nt_username;
	struct dom_sid user_sid;
	struct dom_sid group_sid;
	bool username_was_mapped;
	struct passwd *pwd;
	struct auth_serversupplied_info *result;
	TALLOC_CTX *tmp_ctx = talloc_stackframe();

	/* 
	   Here is where we should check the list of
	   trusted domains, and verify that the SID 
	   matches.
	*/

	if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
		nt_status = NT_STATUS_INVALID_PARAMETER;
		goto out;
	}

	if (!sid_compose(&group_sid, info3->base.domain_sid,
			 info3->base.primary_gid)) {
		nt_status = NT_STATUS_INVALID_PARAMETER;
		goto out;
	}

	nt_username = talloc_strdup(tmp_ctx, info3->base.account_name.string);
	if (!nt_username) {
		/* If the server didn't give us one, just use the one we sent
		 * them */
		nt_username = sent_nt_username;
	}

	nt_domain = talloc_strdup(mem_ctx, info3->base.logon_domain.string);
	if (!nt_domain) {
		/* If the server didn't give us one, just use the one we sent
		 * them */
		nt_domain = domain;
	}

	/* If getpwnam() fails try the add user script (2.2.x behavior).

	   We use the _unmapped_ username here in an attempt to provide
	   consistent username mapping behavior between kerberos and NTLM[SSP]
	   authentication in domain mode security.  I.E. Username mapping
	   should be applied to the fully qualified username
	   (e.g. DOMAIN\user) and not just the login name.  Yes this means we
	   called map_username() unnecessarily in make_user_info_map() but
	   that is how the current code is designed.  Making the change here
	   is the least disruptive place.  -- jerry */

	/* this call will try to create the user if necessary */

	nt_status = check_account(tmp_ctx,
				  nt_domain,
				  nt_username,
				  &found_username,
				  &pwd,
				  &username_was_mapped);

	if (!NT_STATUS_IS_OK(nt_status)) {
		/* Handle 'map to guest = Bad Uid */
		if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) &&
		    (lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
		    lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID) {
			DBG_NOTICE("Try to map %s to guest account",
				   nt_username);
			nt_status = make_server_info_guest(tmp_ctx, &result);
			if (NT_STATUS_IS_OK(nt_status)) {
				*server_info = talloc_move(mem_ctx, &result);
			}
		}
		goto out;
	}

	result = make_server_info(tmp_ctx);
	if (result == NULL) {
		DEBUG(4, ("make_server_info failed!\n"));
		nt_status = NT_STATUS_NO_MEMORY;
		goto out;
	}

	result->unix_name = talloc_strdup(result, found_username);

	/* copy in the info3 */
	result->info3 = copy_netr_SamInfo3(result, info3);
	if (result->info3 == NULL) {
		nt_status = NT_STATUS_NO_MEMORY;
		goto out;
	}

	/* Fill in the unix info we found on the way */

	result->utok.uid = pwd->pw_uid;
	result->utok.gid = pwd->pw_gid;

	/* ensure we are never given NULL session keys */

	if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
		result->session_key = data_blob_null;
	} else {
		result->session_key = data_blob_talloc(
			result, info3->base.key.key,
			sizeof(info3->base.key.key));
	}

	if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
		result->lm_session_key = data_blob_null;
	} else {
		result->lm_session_key = data_blob_talloc(
			result, info3->base.LMSessKey.key,
			sizeof(info3->base.LMSessKey.key));
	}

	result->nss_token |= username_was_mapped;

	result->guest = (info3->base.user_flags & NETLOGON_GUEST);

	*server_info = talloc_move(mem_ctx, &result);

	nt_status = NT_STATUS_OK;
out:
	talloc_free(tmp_ctx);

	return nt_status;
}