Пример #1
0
/*
 * Get a password entry by uid and allocate space for it.
 */
struct passwd *
sudo_getpwuid(uid_t uid)
{
    struct cache_item key, *item;
    struct rbnode *node;
    debug_decl(sudo_getpwuid, SUDO_DEBUG_NSS)

    key.k.uid = uid;
    if ((node = rbfind(pwcache_byuid, &key)) != NULL) {
	item = (struct cache_item *) node->data;
	goto done;
    }
    /*
     * Cache passwd db entry if it exists or a negative response if not.
     */
#ifdef HAVE_SETAUTHDB
    aix_setauthdb(IDtouser(uid));
#endif
    item = sudo_make_pwitem(uid, NULL);
    if (item == NULL) {
	item = ecalloc(1, sizeof(*item));
	item->refcnt = 1;
	item->k.uid = uid;
	/* item->d.pw = NULL; */
    }
    if (rbinsert(pwcache_byuid, item) != NULL)
	fatalx(_("unable to cache uid %u, already exists"),
	    (unsigned int) uid);
#ifdef HAVE_SETAUTHDB
    aix_restoreauthdb();
#endif
done:
    item->refcnt++;
    debug_return_ptr(item->d.pw);
}
Пример #2
0
/*
 * Do authentication via AIX's authenticate routine.  We loop until the
 * reenter parameter is 0, but normally authenticate is called only once.
 *
 * Note: this function returns 1 on success, whereas AIX's authenticate()
 * returns 0.
 */
int
sys_auth_passwd(Authctxt *ctxt, const char *password)
{
	char *authmsg = NULL, *msg = NULL, *name = ctxt->pw->pw_name;
	int authsuccess = 0, expired, reenter, result;

	do {
		result = authenticate((char *)name, (char *)password, &reenter,
		    &authmsg);
		aix_remove_embedded_newlines(authmsg);	
		debug3("AIX/authenticate result %d, authmsg %.100s", result,
		    authmsg);
	} while (reenter);

	if (!aix_valid_authentications(name))
		result = -1;

	if (result == 0) {
		authsuccess = 1;

		/*
		 * Record successful login.  We don't have a pty yet, so just
		 * label the line as "ssh"
		 */
		aix_setauthdb(name);

		/*
		 * Check if the user's password is expired.
		 */
		expired = passwdexpired(name, &msg);
		if (msg && *msg) {
			buffer_append(ctxt->loginmsg, msg, strlen(msg));
			aix_remove_embedded_newlines(msg);
		}
		debug3("AIX/passwdexpired returned %d msg %.100s", expired, msg);

		switch (expired) {
		case 0: /* password not expired */
			break;
		case 1: /* expired, password change required */
			ctxt->force_pwchange = 1;
			break;
		default: /* user can't change(2) or other error (-1) */
			logit("Password can't be changed for user %s: %.100s",
			    name, msg);
			if (msg)
				xfree(msg);
			authsuccess = 0;
		}

		aix_restoreauthdb();
	}

	if (authmsg != NULL)
		xfree(authmsg);

	return authsuccess;
}
Пример #3
0
/*
 * record_failed_login: generic "login failed" interface function
 */
void
record_failed_login(const char *user, const char *ttyname)
{
	char *hostname = get_canonical_hostname(options.use_dns);

	if (geteuid() != 0)
		return;

	aix_setauthdb(user);
#  ifdef AIX_LOGINFAILED_4ARG
	loginfailed((char *)user, hostname, (char *)ttyname, AUDIT_FAIL_AUTH);
#  else
	loginfailed((char *)user, hostname, (char *)ttyname);
#  endif
}
Пример #4
0
/*
 * record_failed_login: generic "login failed" interface function
 */
void
record_failed_login(const char *user, const char *hostname, const char *ttyname)
{
	if (geteuid() != 0)
		return;

	aix_setauthdb(user);
#   ifdef AIX_LOGINFAILED_4ARG
	loginfailed((char *)user, (char *)hostname, (char *)ttyname,
	    AUDIT_FAIL_AUTH);
#   else
	loginfailed((char *)user, (char *)hostname, (char *)ttyname);
#   endif
	aix_restoreauthdb();
}
Пример #5
0
int
sys_auth_record_login(const char *user, const char *host, const char *ttynm)
{
	char *msg;
	int success = 0;

	aix_setauthdb(user);
	if (loginsuccess((char *)user, host, ttynm, &msg) == 0) {
		success = 1;
		if (msg != NULL) {
			debug("AIX/loginsuccess: msg %s", __func__, msg);
			buffer_append(&loginmsg, msg, strlen(msg));
			xfree(msg);
		}
	}
	aix_restoreauthdb();
	return (success);
}
Пример #6
0
int
sys_auth_record_login(const char *user, const char *host, const char *ttynm,
    Buffer *loginmsg)
{
	char *msg = NULL;
	int success = 0;

	aix_setauthdb(user);
	if (loginsuccess((char *)user, (char *)host, (char *)ttynm, &msg) == 0) {
		success = 1;
		if (msg != NULL) {
			debug("AIX/loginsuccess: msg %s", msg);
			if (lastlogin_msg == NULL)
				lastlogin_msg = msg;
		}
	}
	aix_restoreauthdb();
	return (success);
}
Пример #7
0
int
sys_auth_record_login(const char *user, const char *host, const char *ttynm,
    Buffer *loginmsg)
{
	char *msg = NULL;
	static int msg_done = 0;
	int success = 0;

	aix_setauthdb(user);
	if (loginsuccess((char *)user, (char *)host, (char *)ttynm, &msg) == 0) {
		success = 1;
		if (msg != NULL && loginmsg != NULL && !msg_done) {
			debug("AIX/loginsuccess: msg %s", msg);
			buffer_append(loginmsg, msg, strlen(msg));
			xfree(msg);
			msg_done = 1;
		}
	}
	aix_restoreauthdb();
	return (success);
}
Пример #8
0
/*
 * Get a password entry by name and allocate space for it.
 */
struct passwd *
sudo_getpwnam(const char *name)
{
    struct cache_item key, *item;
    struct rbnode *node;
    size_t len;
    debug_decl(sudo_getpwnam, SUDO_DEBUG_NSS)

    key.k.name = (char *) name;
    if ((node = rbfind(pwcache_byname, &key)) != NULL) {
	item = (struct cache_item *) node->data;
	goto done;
    }
    /*
     * Cache passwd db entry if it exists or a negative response if not.
     */
#ifdef HAVE_SETAUTHDB
    aix_setauthdb((char *) name);
#endif
    if ((key.d.pw = getpwnam(name)) != NULL) {
	item = make_pwitem(key.d.pw, name);
	if (rbinsert(pwcache_byname, item) != NULL)
	    errorx(1, _("unable to cache user %s, already exists"), name);
    } else {
	len = strlen(name) + 1;
	item = ecalloc(1, sizeof(*item) + len);
	item->refcnt = 1;
	item->k.name = (char *) item + sizeof(*item);
	memcpy(item->k.name, name, len);
	/* item->d.pw = NULL; */
	if (rbinsert(pwcache_byname, item) != NULL)
	    errorx(1, _("unable to cache user %s, already exists"), name);
    }
#ifdef HAVE_SETAUTHDB
    aix_restoreauthdb();
#endif
done:
    item->refcnt++;
    debug_return_ptr(item->d.pw);
}
/*
 * BSD-compatible getgrouplist(3) using getgrset(3)
 */
int
getgrouplist(const char *name, gid_t basegid, gid_t *groups, int *ngroupsp)
{
    char *cp, *grset = NULL;
    int i, ngroups = 1;
    int grpsize = *ngroupsp;
    int rval = -1;
    gid_t gid;

    /* We support BSD semantics where the first element is the base gid */
    if (grpsize <= 0)
	return -1;
    groups[0] = basegid;

#ifdef HAVE_SETAUTHDB
    aix_setauthdb((char *) name);
#endif
    if ((grset = getgrset(name)) != NULL) {
	const char *errstr;
	for (cp = strtok(grset, ","); cp != NULL; cp = strtok(NULL, ",")) {
	    gid = atoid(cp, NULL, NULL, &errstr);
	    if (errstr == NULL && gid != basegid) {
		if (ngroups == grpsize)
		    goto done;
		groups[ngroups++] = gid;
	    }
	}
    }
    rval = 0;

done:
    free(grset);
#ifdef HAVE_SETAUTHDB
    aix_restoreauthdb();
#endif
    *ngroupsp = ngroups;

    return rval;
}
Пример #10
0
/*
 * Get a password entry by uid and allocate space for it.
 * Fills in pw_passwd from shadow file if necessary.
 */
struct passwd *
sudo_getpwuid(uid_t uid)
{
    struct cache_item key, *item;
    struct rbnode *node;

    key.k.uid = uid;
    if ((node = rbfind(pwcache_byuid, &key)) != NULL) {
	item = (struct cache_item *) node->data;
	goto done;
    }
    /*
     * Cache passwd db entry if it exists or a negative response if not.
     */
#ifdef HAVE_SETAUTHDB
    aix_setauthdb(IDtouser(uid));
#endif
    if ((key.d.pw = getpwuid(uid)) != NULL) {
	item = make_pwitem(key.d.pw, NULL);
	if (rbinsert(pwcache_byuid, item) != NULL)
	    errorx(1, "unable to cache uid %u (%s), already exists",
		(unsigned int) uid, item->d.pw->pw_name);
    } else {
	item = emalloc(sizeof(*item));
	item->refcnt = 1;
	item->k.uid = uid;
	item->d.pw = NULL;
	if (rbinsert(pwcache_byuid, item) != NULL)
	    errorx(1, "unable to cache uid %u, already exists",
		(unsigned int) uid);
    }
#ifdef HAVE_SETAUTHDB
    aix_restoreauthdb();
#endif
done:
    item->refcnt++;
    return item->d.pw;
}
Пример #11
0
/* Reset user_groups based on passwd entry. */
static void
reset_groups(struct passwd *pw)
{
#if defined(HAVE_INITGROUPS) && defined(HAVE_GETGROUPS)
    if (pw != sudo_user.pw) {
# ifdef HAVE_SETAUTHDB
	aix_setauthdb(pw->pw_name);
# endif
	if (initgroups(pw->pw_name, pw->pw_gid) == -1)
	    log_error(USE_ERRNO|MSG_ONLY, "can't reset group vector");
	efree(user_groups);
	user_groups = NULL;
	if ((user_ngroups = getgroups(0, NULL)) > 0) {
	    user_groups = emalloc2(user_ngroups, sizeof(GETGROUPS_T));
	    if (getgroups(user_ngroups, user_groups) < 0)
		log_error(USE_ERRNO|MSG_ONLY, "can't get group vector");
	}
# ifdef HAVE_SETAUTHDB
	aix_restoreauthdb();
# endif
    }
#endif
}
Пример #12
0
struct passwd *
getpwnamallow(const char *user)
{
#ifdef HAVE_LOGIN_CAP
	extern login_cap_t *lc;
#ifdef BSD_AUTH
	auth_session_t *as;
#endif
#endif
	struct passwd *pw;

	parse_server_match_config(&options, user,
	    get_canonical_hostname(options.use_dns), get_remote_ipaddr());

#if defined(_AIX) && defined(HAVE_SETAUTHDB)
	aix_setauthdb(user);
#endif

	pw = getpwnam(user);

#if defined(_AIX) && defined(HAVE_SETAUTHDB)
	aix_restoreauthdb();
#endif
#ifdef HAVE_CYGWIN
	/*
	 * Windows usernames are case-insensitive.  To avoid later problems
	 * when trying to match the username, the user is only allowed to
	 * login if the username is given in the same case as stored in the
	 * user database.
	 */
	if (pw != NULL && strcmp(user, pw->pw_name) != 0) {
		logit("Login name %.100s does not match stored username %.100s",
		    user, pw->pw_name);
		pw = NULL;
	}
#endif
	if (pw == NULL) {
		logit("Invalid user %.100s from %.100s",
		    user, get_remote_ipaddr());
#ifdef CUSTOM_FAILED_LOGIN
		record_failed_login(user,
		    get_canonical_hostname(options.use_dns), "ssh");
#endif
#ifdef SSH_AUDIT_EVENTS
		audit_event(SSH_INVALID_USER);
#endif /* SSH_AUDIT_EVENTS */
		return (NULL);
	}
	if (!allowed_user(pw))
		return (NULL);
#ifdef HAVE_LOGIN_CAP
	if ((lc = login_getclass(pw->pw_class)) == NULL) {
		debug("unable to get login class: %s", user);
		return (NULL);
	}
#ifdef BSD_AUTH
	if ((as = auth_open()) == NULL || auth_setpwd(as, pw) != 0 ||
	    auth_approval(as, lc, pw->pw_name, "ssh") <= 0) {
		debug("Approval failure for %s", user);
		pw = NULL;
	}
	if (as != NULL)
		auth_close(as);
#endif
#endif
	if (pw != NULL)
		return (pwcopy(pw));
	return (NULL);
}
Пример #13
0
int
user_in_group(struct passwd *pw, const char *group)
{
#ifdef HAVE_MBR_CHECK_MEMBERSHIP
    uuid_t gu, uu;
    int ismember;
#else
    char **gr_mem;
    int i;
#endif
    struct group *grp;
    int retval = FALSE;

#ifdef HAVE_SETAUTHDB
    aix_setauthdb(pw->pw_name);
#endif
    grp = sudo_getgrnam(group);
#ifdef HAVE_SETAUTHDB
    aix_restoreauthdb();
#endif
    if (grp == NULL)
	goto done;

    /* check against user's primary (passwd file) gid */
    if (grp->gr_gid == pw->pw_gid) {
	retval = TRUE;
	goto done;
    }

#ifdef HAVE_MBR_CHECK_MEMBERSHIP
    /* If we are matching the invoking user use the stashed uuid. */
    if (strcmp(pw->pw_name, user_name) == 0) {
	if (mbr_gid_to_uuid(grp->gr_gid, gu) == 0 &&
	    mbr_check_membership(user_uuid, gu, &ismember) == 0 && ismember) {
	    retval = TRUE;
	    goto done;
	}
    } else {
	if (mbr_uid_to_uuid(pw->pw_uid, uu) == 0 &&
	    mbr_gid_to_uuid(grp->gr_gid, gu) == 0 &&
	    mbr_check_membership(uu, gu, &ismember) == 0 && ismember) {
	    retval = TRUE;
	    goto done;
	}
    }
#else /* HAVE_MBR_CHECK_MEMBERSHIP */
# ifdef HAVE_GETGROUPS
    /*
     * If we are matching the invoking or list user and that user has a
     * supplementary group vector, check it.
     */
    if (user_ngroups > 0 &&
	strcmp(pw->pw_name, list_pw ? list_pw->pw_name : user_name) == 0) {
	for (i = 0; i < user_ngroups; i++) {
	    if (grp->gr_gid == user_groups[i]) {
		retval = TRUE;
		goto done;
	    }
	}
    } else
# endif /* HAVE_GETGROUPS */
    {
	if (grp != NULL && grp->gr_mem != NULL) {
	    for (gr_mem = grp->gr_mem; *gr_mem; gr_mem++) {
		if (strcmp(*gr_mem, pw->pw_name) == 0) {
		    retval = TRUE;
		    goto done;
		}
	    }
	}
    }
#endif /* HAVE_MBR_CHECK_MEMBERSHIP */

done:
    if (grp != NULL)
	gr_delref(grp);
    return retval;
}
Пример #14
0
/*
 * Tries to authenticate the user using password.  Returns true if
 * authentication succeeds.
 */
int
auth_password(Authctxt *authctxt, const char *password)
{
	struct passwd * pw = authctxt->pw;
	int ok = authctxt->valid;

	/* deny if no user. */
	if (pw == NULL)
		return 0;
#ifndef HAVE_CYGWIN
	if (pw && pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)
		ok = 0;
#endif
	if (*password == '\0' && options.permit_empty_passwd == 0)
		return 0;

#if defined(HAVE_OSF_SIA)
	return auth_sia_password(authctxt, password) && ok;
#else
# ifdef KRB5
	if (options.kerberos_authentication == 1) {
		int ret = auth_krb5_password(authctxt, password);
		if (ret == 1 || ret == 0)
			return ret && ok;
		/* Fall back to ordinary passwd authentication. */
	}
# endif
# ifdef HAVE_CYGWIN
	if (is_winnt) {
		HANDLE hToken = cygwin_logon_user(pw, password);

		if (hToken == INVALID_HANDLE_VALUE)
			return 0;
		cygwin_set_impersonation_token(hToken);
		return ok;
	}
# endif
# ifdef WITH_AIXAUTHENTICATE
	{
		char *authmsg = NULL;
		int reenter = 1;
		int authsuccess = 0;

		if (authenticate(pw->pw_name, password, &reenter,
		    &authmsg) == 0 && ok) {
			char *msg;
			char *host = 
			    (char *)get_canonical_hostname(options.use_dns);

			authsuccess = 1;
			aix_remove_embedded_newlines(authmsg);	

			debug3("AIX/authenticate succeeded for user %s: %.100s",
				pw->pw_name, authmsg);

	        	/* No pty yet, so just label the line as "ssh" */
			aix_setauthdb(authctxt->user);
	        	if (loginsuccess(authctxt->user, host, "ssh", 
			    &msg) == 0) {
				if (msg != NULL) {
					debug("%s: msg %s", __func__, msg);
					buffer_append(&loginmsg, msg, 
					    strlen(msg));
					xfree(msg);
				}
			}
		} else {
			debug3("AIX/authenticate failed for user %s: %.100s",
			    pw->pw_name, authmsg);
		}

		if (authmsg != NULL)
			xfree(authmsg);

		return authsuccess;
	}
# endif
# ifdef BSD_AUTH
	if (auth_userokay(pw->pw_name, authctxt->style, "auth-ssh",
	    (char *)password) == 0)
		return 0;
	else
		return ok;
# else
	{
	/* Just use the supplied fake password if authctxt is invalid */
	char *pw_password = authctxt->valid ? shadow_pw(pw) : pw->pw_passwd;

	/* Check for users with no password. */
	if (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0)
		return ok;
	else {
		/* Encrypt the candidate password using the proper salt. */
		char *encrypted_password = xcrypt(password,
		    (pw_password[0] && pw_password[1]) ? pw_password : "******");

		/*
		 * Authentication is accepted if the encrypted passwords
		 * are identical.
		 */
		return (strcmp(encrypted_password, pw_password) == 0) && ok;
	}

	}
# endif
#endif /* !HAVE_OSF_SIA */
}