Cygwin: seteuid: work with password-less user switch as well

The previous patch failed with password-less auth because in
that case the return code from get_server_groups wasn't tested.
Fix that.  Also make sure that get_server_groups does not
check if the account is disabled or locked out when just fetching
the group list for initgroups or getgrouplist.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2019-01-24 21:19:40 +01:00
parent 2c12a2c32a
commit 02373d8bec
3 changed files with 39 additions and 21 deletions

View File

@ -738,7 +738,7 @@ get_groups (const char *user, gid_t gid, cygsidlist &gsids)
struct group *grp = internal_getgrgid (gid, &cldap); struct group *grp = internal_getgrgid (gid, &cldap);
cygsid usersid, grpsid; cygsid usersid, grpsid;
if (usersid.getfrompw (pw)) if (usersid.getfrompw (pw))
get_server_groups (gsids, usersid); get_server_groups (gsids, usersid, NO_CHK_DISABLED);
if (gid != ILLEGAL_GID && grpsid.getfromgr (grp)) if (gid != ILLEGAL_GID && grpsid.getfromgr (grp))
gsids += grpsid; gsids += grpsid;
cygheap->user.reimpersonate (); cygheap->user.reimpersonate ();

View File

@ -523,7 +523,8 @@ get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps)
} }
bool bool
get_server_groups (cygsidlist &grp_list, PSID usersid) get_server_groups (cygsidlist &grp_list, PSID usersid,
acct_disabled_chk_t check_account_disabled)
{ {
WCHAR user[UNLEN + 1]; WCHAR user[UNLEN + 1];
WCHAR domain[MAX_DOMAIN_NAME_LEN + 1]; WCHAR domain[MAX_DOMAIN_NAME_LEN + 1];
@ -553,20 +554,23 @@ get_server_groups (cygsidlist &grp_list, PSID usersid)
&& sid_sub_auth (usersid, 0) == SECURITY_NT_NON_UNIQUE && sid_sub_auth (usersid, 0) == SECURITY_NT_NON_UNIQUE
&& get_logon_server (domain, server, DS_IS_FLAT_NAME)) && get_logon_server (domain, server, DS_IS_FLAT_NAME))
{ {
NET_API_STATUS napi_stat; if (check_account_disabled == CHK_DISABLED)
USER_INFO_1 *ui1;
bool allow_user = false;
napi_stat = NetUserGetInfo (server, user, 1, (LPBYTE *) &ui1);
if (napi_stat == NERR_Success)
allow_user = !(ui1->usri1_flags & (UF_ACCOUNTDISABLE | UF_LOCKOUT));
if (ui1)
NetApiBufferFree (ui1);
if (!allow_user)
{ {
debug_printf ("User denied: %W\\%W", domain, user); NET_API_STATUS napi_stat;
set_errno (EACCES); USER_INFO_1 *ui1;
return false; bool allow_user = false;
napi_stat = NetUserGetInfo (server, user, 1, (LPBYTE *) &ui1);
if (napi_stat == NERR_Success)
allow_user = !(ui1->usri1_flags & (UF_ACCOUNTDISABLE | UF_LOCKOUT));
if (ui1)
NetApiBufferFree (ui1);
if (!allow_user)
{
debug_printf ("User denied: %W\\%W", domain, user);
set_errno (EACCES);
return false;
}
} }
get_user_groups (server, grp_list, user, domain); get_user_groups (server, grp_list, user, domain);
get_user_local_groups (server, domain, grp_list, user); get_user_local_groups (server, domain, grp_list, user);
@ -582,7 +586,7 @@ get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid,
grp_list *= well_known_authenticated_users_sid; grp_list *= well_known_authenticated_users_sid;
if (well_known_system_sid != usersid) if (well_known_system_sid != usersid)
get_token_group_sidlist (grp_list, my_grps); get_token_group_sidlist (grp_list, my_grps);
if (!get_server_groups (grp_list, usersid)) if (!get_server_groups (grp_list, usersid, CHK_DISABLED))
return false; return false;
/* special_pgrp true if pgrpsid is not in normal groups */ /* special_pgrp true if pgrpsid is not in normal groups */
@ -590,17 +594,19 @@ get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid,
return true; return true;
} }
static void static bool
get_setgroups_sidlist (cygsidlist &tmp_list, PSID usersid, get_setgroups_sidlist (cygsidlist &tmp_list, PSID usersid,
PTOKEN_GROUPS my_grps, user_groups &groups) PTOKEN_GROUPS my_grps, user_groups &groups)
{ {
tmp_list *= well_known_world_sid; tmp_list *= well_known_world_sid;
tmp_list *= well_known_authenticated_users_sid; tmp_list *= well_known_authenticated_users_sid;
get_token_group_sidlist (tmp_list, my_grps); get_token_group_sidlist (tmp_list, my_grps);
get_server_groups (tmp_list, usersid); if (!get_server_groups (tmp_list, usersid, CHK_DISABLED))
return false;
for (int gidx = 0; gidx < groups.sgsids.count (); gidx++) for (int gidx = 0; gidx < groups.sgsids.count (); gidx++)
tmp_list += groups.sgsids.sids[gidx]; tmp_list += groups.sgsids.sids[gidx];
tmp_list += groups.pgsid; tmp_list += groups.pgsid;
return true;
} }
/* Fixed size TOKEN_PRIVILEGES list to reflect privileges given to the /* Fixed size TOKEN_PRIVILEGES list to reflect privileges given to the
@ -953,7 +959,10 @@ create_token (cygsid &usersid, user_groups &new_groups)
/* Create list of groups, the user is member in. */ /* Create list of groups, the user is member in. */
if (new_groups.issetgroups ()) if (new_groups.issetgroups ())
get_setgroups_sidlist (tmp_gsids, usersid, my_tok_gsids, new_groups); {
if (!get_setgroups_sidlist (tmp_gsids, usersid, my_tok_gsids, new_groups))
goto out;
}
else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid, else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid,
my_tok_gsids)) my_tok_gsids))
goto out; goto out;
@ -1089,7 +1098,10 @@ lsaauth (cygsid &usersid, user_groups &new_groups)
/* Create list of groups, the user is member in. */ /* Create list of groups, the user is member in. */
if (new_groups.issetgroups ()) if (new_groups.issetgroups ())
get_setgroups_sidlist (tmp_gsids, usersid, NULL, new_groups); {
if (!get_setgroups_sidlist (tmp_gsids, usersid, NULL, new_groups))
goto out;
}
else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid, else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid,
NULL)) NULL))
goto out; goto out;

View File

@ -482,7 +482,13 @@ HANDLE lsaprivkeyauth (struct passwd *pw);
/* Verify an existing token */ /* Verify an existing token */
bool verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern = NULL); bool verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern = NULL);
/* Get groups of a user */ /* Get groups of a user */
bool get_server_groups (cygsidlist &grp_list, PSID usersid); enum acct_disabled_chk_t {
NO_CHK_DISABLED = 0,
CHK_DISABLED = 1
};
bool get_server_groups (cygsidlist &grp_list, PSID usersid,
acct_disabled_chk_t check_account_disabled);
/* Extract U-domain\user field from passwd entry. */ /* Extract U-domain\user field from passwd entry. */
void extract_nt_dom_user (const struct passwd *pw, PWCHAR domain, PWCHAR user); void extract_nt_dom_user (const struct passwd *pw, PWCHAR domain, PWCHAR user);