diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2002-07-29 12:51:52 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2002-07-29 12:51:52 +0000 |
commit | 5519d54352e7bdc6d77186cef46dbafc86946bcf (patch) | |
tree | 7b69706b4f2ed5aa997ddff5a367d757bb7afb8e /winsup/cygwin/security.cc | |
parent | eb5720f25501cd7e9b8115bb0220bef058bb5afd (diff) | |
download | cygnal-5519d54352e7bdc6d77186cef46dbafc86946bcf.tar.gz cygnal-5519d54352e7bdc6d77186cef46dbafc86946bcf.tar.bz2 cygnal-5519d54352e7bdc6d77186cef46dbafc86946bcf.zip |
* security.cc: Change some formatting.
* include/cygwin/version.h: Bump API minor version.
* cygheap.h (class cygheap_user): Add member groups.
* security.h (class cygsidlist): Add members type and maxcount,
methods position, addfromgr, alloc_sids and free_sids and
operator+= (const PSID psid). Modify contains () to call
position () and optimize add () to use maxcount.
(class user_groups): Create.
Update declarations of verify_token and create_token.
* security.cc (cygsidlist::alloc_sids): New.
(cygsidlist::free_sids): New.
(get_token_group_sidlist): Create from get_group_sidlist.
(get_initgroups_sidlist): Create from get_group_sidlist.
(get_group_sidlist): Suppress.
(get_setgroups_sidlist): Create.
(verify_token): Modify arguments. Add setgroups case.
(create_token): Modify arguments. Call get_initgroups_sidlist and
get_setgroups_sidlist as needed. Set SE_GROUP_LOGON_ID from auth_pos
outside of the loop. Rename the various group sid lists consistently.
* syscalls.cc (seteuid32): Modify to use cygheap->user.groups.
(setegid32): Call cygheap->user.groups.update_pgrp.
* grp.cc (setgroups): Create.
(setgroups32): Create.
* uinfo.cc (internal_getlogin): Initialize and update user.groups.pgsid.
* cygwin.din: Add setgroups and setgroups32.
Diffstat (limited to 'winsup/cygwin/security.cc')
-rw-r--r-- | winsup/cygwin/security.cc | 469 |
1 files changed, 276 insertions, 193 deletions
diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc index a89ff2972..d12e33359 100644 --- a/winsup/cygwin/security.cc +++ b/winsup/cygwin/security.cc @@ -47,6 +47,22 @@ BOOL allow_ntsec = true; The default is TRUE to reflect the old behaviour. */ BOOL allow_smbntsec; +cygsid * +cygsidlist::alloc_sids (int n) +{ + if (n > 0) + return (cygsid *) cmalloc (HEAP_STR, n * sizeof (cygsid)); + else + return NULL; +} + +void +cygsidlist::free_sids () +{ + if (sids) + cfree (sids); +} + extern "C" void cygwin_set_impersonation_token (const HANDLE hToken) { @@ -64,7 +80,7 @@ extract_nt_dom_user (const struct passwd *pw, char *domain, char *user) char *d, *u, *c; domain[0] = 0; - strlcpy (user, pw->pw_name, UNLEN+1); + strlcpy (user, pw->pw_name, UNLEN + 1); debug_printf ("pw_gecos = %x (%s)", pw->pw_gecos, pw->pw_gecos); if ((d = strstr (pw->pw_gecos, "U-")) != NULL && @@ -74,11 +90,11 @@ extract_nt_dom_user (const struct passwd *pw, char *domain, char *user) if ((u = strchr (d + 2, '\\')) == NULL || (c != NULL && u > c)) u = d + 1; else if (u - d <= INTERNET_MAX_HOST_NAME_LENGTH + 2) - strlcpy(domain, d + 2, u - d - 1); + strlcpy (domain, d + 2, u - d - 1); if (c == NULL) c = u + UNLEN + 1; if (c - u <= UNLEN + 1) - strlcpy(user, u + 1, c - u); + strlcpy (user, u + 1, c - u); } if (domain[0]) return; @@ -112,9 +128,9 @@ cygwin_logon_user (const struct passwd *pw, const char *password) extract_nt_dom_user (pw, nt_domain, nt_user); debug_printf ("LogonUserA (%s, %s, %s, ...)", nt_user, nt_domain, password); if (!LogonUserA (nt_user, *nt_domain ? nt_domain : NULL, (char *) password, - LOGON32_LOGON_INTERACTIVE, - LOGON32_PROVIDER_DEFAULT, - &hToken) + LOGON32_LOGON_INTERACTIVE, + LOGON32_PROVIDER_DEFAULT, + &hToken) || !SetHandleInformation (hToken, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) @@ -152,7 +168,7 @@ str2buf2uni (UNICODE_STRING &tgt, WCHAR *buf, const char *srcstr) sys_mbstowcs (buf, srcstr, tgt.MaximumLength); } -#if 0 //unused +#if 0 /* unused */ static void lsa2wchar (WCHAR *tgt, LSA_UNICODE_STRING &src, int size) { @@ -194,7 +210,7 @@ close_local_policy (LSA_HANDLE &lsa) lsa = INVALID_HANDLE_VALUE; } -#if 0 // unused +#if 0 /* unused */ static BOOL get_lsa_srv_inf (LSA_HANDLE lsa, char *logonserver, char *domain) { @@ -226,7 +242,8 @@ get_lsa_srv_inf (LSA_HANDLE lsa, char *logonserver, char *domain) not member of a domain. The name in the primary domain info is the name of the workgroup then. */ if (pdi->Sid && - (ret = NetGetDCName (NULL, primary, (LPBYTE *) &buf)) == STATUS_SUCCESS) + (ret = + NetGetDCName (NULL, primary, (LPBYTE *) &buf)) == STATUS_SUCCESS) { sys_wcstombs (name, buf, INTERNET_MAX_HOST_NAME_LENGTH + 1); strcpy (logonserver, name); @@ -271,7 +288,8 @@ get_logon_server (const char *domain, char *server, WCHAR *wserver) { sys_wcstombs (server, buf, INTERNET_MAX_HOST_NAME_LENGTH + 1); if (wserver) - for (WCHAR *ptr1 = buf; (*wserver++ = *ptr1++); ) {} + for (WCHAR *ptr1 = buf; (*wserver++ = *ptr1++);) + ; NetApiBufferFree (buf); return TRUE; } @@ -280,7 +298,8 @@ get_logon_server (const char *domain, char *server, WCHAR *wserver) } static BOOL -get_user_groups (WCHAR *wlogonserver, cygsidlist &grp_list, char *user, char *domain) +get_user_groups (WCHAR *wlogonserver, cygsidlist &grp_list, char *user, + char *domain) { char dgroup[INTERNET_MAX_HOST_NAME_LENGTH + GNLEN + 2]; WCHAR wuser[UNLEN + 1]; @@ -313,11 +332,12 @@ get_user_groups (WCHAR *wlogonserver, cygsidlist &grp_list, char *user, char *do sys_wcstombs (dgroup + len, buf[i].grui0_name, GNLEN + 1); if (!LookupAccountName (NULL, dgroup, gsid, &glen, domain, &dlen, &use)) - debug_printf ("LookupAccountName(%s): %E", dgroup); + debug_printf ("LookupAccountName(%s): %E", dgroup); else if (legal_sid_type (use)) - grp_list += gsid; - else debug_printf ("Global group %s invalid. Domain: %s Use: %d", - dgroup, domain, use); + grp_list += gsid; + else + debug_printf ("Global group %s invalid. Domain: %s Use: %d", + dgroup, domain, use); } NetApiBufferFree (buf); @@ -369,10 +389,10 @@ get_user_local_groups (cygsidlist &grp_list, PSID pusersid) char lgroup[INTERNET_MAX_HOST_NAME_LENGTH + GNLEN + 2]; const DWORD blen = sizeof ("BUILTIN\\") - 1; DWORD llen = INTERNET_MAX_HOST_NAME_LENGTH + 1; - if (!GetComputerNameA(lgroup, & llen)) + if (!GetComputerNameA (lgroup, &llen)) { - __seterrno (); - return FALSE; + __seterrno (); + return FALSE; } lgroup[llen++] = '\\'; @@ -389,11 +409,11 @@ get_user_local_groups (cygsidlist &grp_list, PSID pusersid) if (!LookupAccountName (NULL, bgroup, gsid, &glen, domain, &dlen, &use)) { if (GetLastError () != ERROR_NONE_MAPPED) - debug_printf ("LookupAccountName(%s): %E", bgroup); + debug_printf ("LookupAccountName(%s): %E", bgroup); strcpy (lgroup + llen, bgroup + blen); if (!LookupAccountName (NULL, lgroup, gsid, &glen, domain, &dlen, &use)) - debug_printf ("LookupAccountName(%s): %E", lgroup); + debug_printf ("LookupAccountName(%s): %E", lgroup); } if (!legal_sid_type (use)) debug_printf ("Rejecting local %s. use: %d", bgroup + blen, use); @@ -415,7 +435,7 @@ sid_in_token_groups (PTOKEN_GROUPS grps, cygsid &sid) return FALSE; } -#if 0 /* Unused */ +#if 0 /* Unused */ static BOOL get_user_primary_group (WCHAR *wlogonserver, const char *user, PSID pusersid, cygsid &pgrpsid) @@ -441,7 +461,8 @@ get_user_primary_group (WCHAR *wlogonserver, const char *user, } pgrpsid = pusersid; - if (IsValidSid (pgrpsid) && (count = *GetSidSubAuthorityCount (pgrpsid)) > 1) + if (IsValidSid (pgrpsid) + && (count = *GetSidSubAuthorityCount (pgrpsid)) > 1) { *GetSidSubAuthority (pgrpsid, count - 1) = buf->usri3_primary_group_id; retval = TRUE; @@ -473,57 +494,63 @@ get_unix_group_sidlist (struct passwd *pw, cygsidlist &grp_list) } } -static BOOL -get_group_sidlist (cygsidlist &grp_list, - cygsid &usersid, cygsid &pgrpsid, struct passwd *pw, - PTOKEN_GROUPS my_grps, LUID auth_luid, int &auth_pos, - BOOL *special_pgrp) +static void +get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps, + LUID auth_luid, int &auth_pos) { - char user[UNLEN + 1]; - char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1]; - WCHAR wserver[INTERNET_MAX_HOST_NAME_LENGTH + 3]; - char server[INTERNET_MAX_HOST_NAME_LENGTH + 3]; - cygsidlist sup_list; - auth_pos = -1; + if (my_grps) + { + if (sid_in_token_groups (my_grps, well_known_local_sid)) + grp_list += well_known_local_sid; + if (sid_in_token_groups (my_grps, well_known_dialup_sid)) + grp_list += well_known_dialup_sid; + if (sid_in_token_groups (my_grps, well_known_network_sid)) + grp_list += well_known_network_sid; + if (sid_in_token_groups (my_grps, well_known_batch_sid)) + grp_list += well_known_batch_sid; + if (sid_in_token_groups (my_grps, well_known_interactive_sid)) + grp_list += well_known_interactive_sid; + if (sid_in_token_groups (my_grps, well_known_service_sid)) + grp_list += well_known_service_sid; + } + else + { + grp_list += well_known_local_sid; + grp_list += well_known_interactive_sid; + } + if (auth_luid.QuadPart != 999) /* != SYSTEM_LUID */ + { + char buf[64]; + __small_sprintf (buf, "S-1-5-5-%u-%u", auth_luid.HighPart, + auth_luid.LowPart); + grp_list += buf; + auth_pos = grp_list.count - 1; + } +} +static BOOL +get_initgroups_sidlist (cygsidlist &grp_list, + PSID usersid, PSID pgrpsid, struct passwd *pw, + PTOKEN_GROUPS my_grps, LUID auth_luid, int &auth_pos, + BOOL &special_pgrp) +{ grp_list += well_known_world_sid; grp_list += well_known_authenticated_users_sid; if (usersid == well_known_system_sid) { + auth_pos = -1; grp_list += well_known_admins_sid; get_unix_group_sidlist (pw, grp_list); } else { - if (my_grps) - { - if (sid_in_token_groups (my_grps, well_known_local_sid)) - grp_list += well_known_local_sid; - if (sid_in_token_groups (my_grps, well_known_dialup_sid)) - grp_list += well_known_dialup_sid; - if (sid_in_token_groups (my_grps, well_known_network_sid)) - grp_list += well_known_network_sid; - if (sid_in_token_groups (my_grps, well_known_batch_sid)) - grp_list += well_known_batch_sid; - if (sid_in_token_groups (my_grps, well_known_interactive_sid)) - grp_list += well_known_interactive_sid; - if (sid_in_token_groups (my_grps, well_known_service_sid)) - grp_list += well_known_service_sid; - } - else - { - grp_list += well_known_local_sid; - grp_list += well_known_interactive_sid; - } - if (auth_luid.QuadPart != 999) /* != SYSTEM_LUID */ - { - char buf[64]; - __small_sprintf (buf, "S-1-5-5-%u-%u", auth_luid.HighPart, - auth_luid.LowPart); - grp_list += buf; - auth_pos = grp_list.count - 1; - } + char user[UNLEN + 1]; + char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1]; + WCHAR wserver[INTERNET_MAX_HOST_NAME_LENGTH + 3]; + char server[INTERNET_MAX_HOST_NAME_LENGTH + 3]; + + get_token_group_sidlist (grp_list, my_grps, auth_luid, auth_pos); extract_nt_dom_user (pw, domain, user); if (get_logon_server (domain, server, wserver)) get_user_groups (wserver, grp_list, user, domain); @@ -531,16 +558,26 @@ get_group_sidlist (cygsidlist &grp_list, if (!get_user_local_groups (grp_list, usersid)) return FALSE; } - /* special_pgrp true if pgrpsid is not null and not in normal groups */ - *special_pgrp = FALSE; - if (pgrpsid && !grp_list.contains (pgrpsid)) - { - *special_pgrp = TRUE; - grp_list += pgrpsid; - } + /* special_pgrp true if pgrpsid is not in normal groups */ + if ((special_pgrp = !grp_list.contains (pgrpsid))) + grp_list += pgrpsid; return TRUE; } +static void +get_setgroups_sidlist (cygsidlist &tmp_list, PTOKEN_GROUPS my_grps, + user_groups &groups, LUID auth_luid, int &auth_pos) +{ + PSID pgpsid = groups.pgsid; + tmp_list += well_known_world_sid; + tmp_list += well_known_authenticated_users_sid; + get_token_group_sidlist (tmp_list, my_grps, auth_luid, auth_pos); + for (int gidx = 0; gidx < groups.sgsids.count; gidx++) + tmp_list += groups.sgsids.sids[gidx]; + if (!groups.sgsids.contains (pgpsid)) + tmp_list += pgpsid; +} + static const char *sys_privs[] = { SE_TCB_NAME, SE_ASSIGNPRIMARYTOKEN_NAME, @@ -569,8 +606,8 @@ PTOKEN_PRIVILEGES get_system_priv_list (cygsidlist &grp_list) { LUID priv; - PTOKEN_PRIVILEGES privs = (PTOKEN_PRIVILEGES) malloc (sizeof (ULONG) + - 20 * sizeof (LUID_AND_ATTRIBUTES)); + PTOKEN_PRIVILEGES privs = (PTOKEN_PRIVILEGES) + malloc (sizeof (ULONG) + 20 * sizeof (LUID_AND_ATTRIBUTES)); if (!privs) { debug_printf ("malloc (system_privs) failed."); @@ -583,7 +620,7 @@ get_system_priv_list (cygsidlist &grp_list) { privs->Privileges[privs->PrivilegeCount].Luid = priv; privs->Privileges[privs->PrivilegeCount].Attributes = - SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT; + SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT; ++privs->PrivilegeCount; } return privs; @@ -605,8 +642,8 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list) { if (grp == -1) { - if ((ret = LsaEnumerateAccountRights (lsa, usersid, &privstrs, &cnt)) - != STATUS_SUCCESS) + if ((ret = LsaEnumerateAccountRights (lsa, usersid, &privstrs, + &cnt)) != STATUS_SUCCESS) continue; } else if ((ret = LsaEnumerateAccountRights (lsa, grp_list.sids[grp], @@ -629,8 +666,8 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list) tmp_count = privs ? privs->PrivilegeCount : 0; tmp = (PTOKEN_PRIVILEGES) - realloc (privs, sizeof (ULONG) + - (tmp_count + 1) * sizeof (LUID_AND_ATTRIBUTES)); + realloc (privs, sizeof (ULONG) + + (tmp_count + 1) * sizeof (LUID_AND_ATTRIBUTES)); if (!tmp) { if (privs) @@ -643,7 +680,7 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list) privs = tmp; privs->Privileges[privs->PrivilegeCount].Luid = priv; privs->Privileges[privs->PrivilegeCount].Attributes = - SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT; + SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT; ++privs->PrivilegeCount; next_account_right: @@ -654,8 +691,21 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list) return privs; } +/* Accept a token if + - the requested usersid matches the TokenUser and + - if setgroups has been called: + the token groups that are listed in /etc/group match the union of + the requested primary and supplementary groups in gsids. + - else the (unknown) implicitly requested supplementary groups and those + in the token are the groups associated with the usersid. We assume + they match and verify only the primary groups. + The requested primary group must appear in the token. + The primary group in the token is a group associated with the usersid, + except if the token is internal and the group is in the token SD + (see create_token). In that latter case that group must match the + requested primary group. */ BOOL -verify_token (HANDLE token, cygsid &usersid, cygsid &pgrpsid, BOOL *pintern) +verify_token (HANDLE token, cygsid &usersid, user_groups &groups, BOOL *pintern) { DWORD size; BOOL intern = FALSE; @@ -666,36 +716,39 @@ verify_token (HANDLE token, cygsid &usersid, cygsid &pgrpsid, BOOL *pintern) if (!GetTokenInformation (cygheap->user.token, TokenSource, &ts, sizeof ts, &size)) debug_printf ("GetTokenInformation(): %E"); - else *pintern = intern = !memcmp (ts.SourceName, "Cygwin.1", 8); + else + *pintern = intern = !memcmp (ts.SourceName, "Cygwin.1", 8); } /* Verify usersid */ cygsid tok_usersid = NO_SID; if (!GetTokenInformation (token, TokenUser, &tok_usersid, sizeof tok_usersid, &size)) - debug_printf ("GetTokenInformation(): %E"); - if (usersid != tok_usersid) return FALSE; + debug_printf ("GetTokenInformation(): %E"); + if (usersid != tok_usersid) + return FALSE; - /* In an internal token, if the sd group is not well_known_null_sid, - it must match pgrpsid */ - if (intern) + /* For an internal token, if setgroups was not called and if the sd group + is not well_known_null_sid, it must match pgrpsid */ + if (intern && !groups.issetgroups ()) { - char sd_buf[MAX_SID_LEN + sizeof (SECURITY_DESCRIPTOR)]; - PSID gsid = NO_SID; - if (!GetKernelObjectSecurity (token, GROUP_SECURITY_INFORMATION, + char sd_buf[MAX_SID_LEN + sizeof (SECURITY_DESCRIPTOR)]; + PSID gsid = NO_SID; + if (!GetKernelObjectSecurity (token, GROUP_SECURITY_INFORMATION, (PSECURITY_DESCRIPTOR) sd_buf, sizeof sd_buf, &size)) - debug_printf ("GetKernelObjectSecurity(): %E"); - else if (!GetSecurityDescriptorGroup ((PSECURITY_DESCRIPTOR) sd_buf, + debug_printf ("GetKernelObjectSecurity(): %E"); + else if (!GetSecurityDescriptorGroup ((PSECURITY_DESCRIPTOR) sd_buf, &gsid, (BOOL *) &size)) - debug_printf ("GetSecurityDescriptorGroup(): %E"); - if (well_known_null_sid != gsid) return pgrpsid == gsid; + debug_printf ("GetSecurityDescriptorGroup(): %E"); + if (well_known_null_sid != gsid) + return gsid == groups.pgsid; } - /* See if the pgrpsid is the tok_usersid in the token groups */ + PTOKEN_GROUPS my_grps = NULL; BOOL ret = FALSE; + char saw_buf[NGROUPS_MAX] = {}; + char *saw = saw_buf, sawpg = FALSE; - if ( pgrpsid == tok_usersid) - return TRUE; if (!GetTokenInformation (token, TokenGroups, NULL, 0, &size) && GetLastError () != ERROR_INSUFFICIENT_BUFFER) debug_printf ("GetTokenInformation(token, TokenGroups): %E\n"); @@ -703,38 +756,70 @@ verify_token (HANDLE token, cygsid &usersid, cygsid &pgrpsid, BOOL *pintern) debug_printf ("malloc (my_grps) failed."); else if (!GetTokenInformation (token, TokenGroups, my_grps, size, &size)) debug_printf ("GetTokenInformation(my_token, TokenGroups): %E\n"); - else - ret = sid_in_token_groups (my_grps, pgrpsid); + else if (!groups.issetgroups ()) /* setgroups was never called */ + { + ret = sid_in_token_groups (my_grps, groups.pgsid); + if (ret == FALSE) + ret = (groups.pgsid == tok_usersid); + } + else /* setgroups was called */ + { + struct __group32 *gr; + cygsid gsid; + if (groups.sgsids.count > (int) sizeof (saw_buf) && + !(saw = (char *) calloc (groups.sgsids.count, sizeof (char)))) + goto done; + + /* token groups found in /etc/group match the user.gsids ? */ + for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx) + if (gsid.getfromgr (gr) && sid_in_token_groups (my_grps, gsid)) + { + int pos = groups.sgsids.position (gsid); + if (pos >= 0) + saw[pos] = TRUE; + else if (groups.pgsid == gsid) + sawpg = TRUE; + else + goto done; + } + for (int gidx = 0; gidx < groups.sgsids.count; gidx++) + if (!saw[gidx]) + goto done; + if (sawpg || groups.sgsids.contains (groups.pgsid)) + ret = TRUE; + } +done: if (my_grps) free (my_grps); + if (saw != saw_buf) + free (saw); return ret; } HANDLE -create_token (cygsid &usersid, cygsid &pgrpsid, struct passwd *pw) +create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw) { NTSTATUS ret; LSA_HANDLE lsa = INVALID_HANDLE_VALUE; int old_priv_state; - cygsidlist grpsids; + cygsidlist tmp_gsids (cygsidlist_auto, 12); SECURITY_QUALITY_OF_SERVICE sqos = { sizeof sqos, SecurityImpersonation, SECURITY_STATIC_TRACKING, FALSE }; - OBJECT_ATTRIBUTES oa = - { sizeof oa, 0, 0, 0, 0, &sqos }; + OBJECT_ATTRIBUTES oa = { sizeof oa, 0, 0, 0, 0, &sqos }; PSECURITY_ATTRIBUTES psa; - BOOL special_pgrp; + BOOL special_pgrp = FALSE; char sa_buf[1024]; LUID auth_luid = SYSTEM_LUID; - LARGE_INTEGER exp = { QuadPart:0x7fffffffffffffffLL }; + LARGE_INTEGER exp = { QuadPart:0x7fffffffffffffffLL }; TOKEN_USER user; - PTOKEN_GROUPS grps = NULL; + PTOKEN_GROUPS new_tok_gsids = NULL; PTOKEN_PRIVILEGES privs = NULL; TOKEN_OWNER owner; TOKEN_PRIMARY_GROUP pgrp; - char acl_buf[MAX_DACL_LEN(5)]; + char acl_buf[MAX_DACL_LEN (5)]; TOKEN_DEFAULT_DACL dacl; TOKEN_SOURCE source; TOKEN_STATISTICS stats; @@ -746,7 +831,7 @@ create_token (cygsid &usersid, cygsid &pgrpsid, struct passwd *pw) HANDLE primary_token = INVALID_HANDLE_VALUE; HANDLE my_token = INVALID_HANDLE_VALUE; - PTOKEN_GROUPS my_grps = NULL; + PTOKEN_GROUPS my_tok_gsids = NULL; DWORD size; /* SE_CREATE_TOKEN_NAME privilege needed to call NtCreateToken. */ @@ -768,68 +853,73 @@ create_token (cygsid &usersid, cygsid &pgrpsid, struct passwd *pw) else { /* Switching user context to SYSTEM doesn't inherit the authentication - id of the user account running current process. */ + id of the user account running current process. */ if (usersid != well_known_system_sid) if (!GetTokenInformation (my_token, TokenStatistics, &stats, sizeof stats, &size)) - debug_printf ("GetTokenInformation(my_token, TokenStatistics): %E\n"); + debug_printf + ("GetTokenInformation(my_token, TokenStatistics): %E\n"); else auth_luid = stats.AuthenticationId; /* Retrieving current processes group list to be able to inherit - some important well known group sids. */ + some important well known group sids. */ if (!GetTokenInformation (my_token, TokenGroups, NULL, 0, &size) && GetLastError () != ERROR_INSUFFICIENT_BUFFER) debug_printf ("GetTokenInformation(my_token, TokenGroups): %E\n"); - else if (!(my_grps = (PTOKEN_GROUPS) malloc (size))) - debug_printf ("malloc (my_grps) failed."); - else if (!GetTokenInformation (my_token, TokenGroups, my_grps, + else if (!(my_tok_gsids = (PTOKEN_GROUPS) malloc (size))) + debug_printf ("malloc (my_tok_gsids) failed."); + else if (!GetTokenInformation (my_token, TokenGroups, my_tok_gsids, size, &size)) { debug_printf ("GetTokenInformation(my_token, TokenGroups): %E\n"); - free (my_grps); - my_grps = NULL; + free (my_tok_gsids); + my_tok_gsids = NULL; } CloseHandle (my_token); } /* Create list of groups, the user is member in. */ int auth_pos; - if (!get_group_sidlist (grpsids, usersid, pgrpsid, pw, - my_grps, auth_luid, auth_pos, &special_pgrp)) + if (new_groups.issetgroups ()) + get_setgroups_sidlist (tmp_gsids, my_tok_gsids, new_groups, auth_luid, + auth_pos); + else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid, pw, + my_tok_gsids, auth_luid, auth_pos, + special_pgrp)) goto out; /* Primary group. */ - pgrp.PrimaryGroup = pgrpsid; + pgrp.PrimaryGroup = new_groups.pgsid; /* Create a TOKEN_GROUPS list from the above retrieved list of sids. */ - char grps_buf[sizeof (ULONG) + grpsids.count * sizeof (SID_AND_ATTRIBUTES)]; - grps = (PTOKEN_GROUPS) grps_buf; - grps->GroupCount = grpsids.count; - for (DWORD i = 0; i < grps->GroupCount; ++i) + char grps_buf[sizeof (ULONG) + tmp_gsids.count * sizeof (SID_AND_ATTRIBUTES)]; + new_tok_gsids = (PTOKEN_GROUPS) grps_buf; + new_tok_gsids->GroupCount = tmp_gsids.count; + for (DWORD i = 0; i < new_tok_gsids->GroupCount; ++i) { - grps->Groups[i].Sid = grpsids.sids[i]; - grps->Groups[i].Attributes = SE_GROUP_MANDATORY | - SE_GROUP_ENABLED_BY_DEFAULT | - SE_GROUP_ENABLED; - if (auth_pos >= 0 && i == (DWORD) auth_pos) - grps->Groups[i].Attributes |= SE_GROUP_LOGON_ID; + new_tok_gsids->Groups[i].Sid = tmp_gsids.sids[i]; + new_tok_gsids->Groups[i].Attributes = SE_GROUP_MANDATORY | + SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; } + if (auth_pos >= 0) + new_tok_gsids->Groups[auth_pos].Attributes |= SE_GROUP_LOGON_ID; /* Retrieve list of privileges of that user. */ - if (!(privs = get_priv_list (lsa, usersid, grpsids))) + if (!(privs = get_priv_list (lsa, usersid, tmp_gsids))) goto out; /* Create default dacl. */ if (!sec_acl ((PACL) acl_buf, FALSE, - grpsids.contains (well_known_admins_sid)?well_known_admins_sid:usersid)) + tmp_gsids.contains (well_known_admins_sid) ? + well_known_admins_sid : usersid)) goto out; dacl.DefaultDacl = (PACL) acl_buf; /* Let's be heroic... */ ret = NtCreateToken (&token, TOKEN_ALL_ACCESS, &oa, TokenImpersonation, - &auth_luid, &exp, &user, grps, privs, &owner, &pgrp, - &dacl, &source); + &auth_luid, &exp, &user, new_tok_gsids, privs, &owner, + &pgrp, &dacl, &source); if (ret) __seterrno_from_win_error (RtlNtStatusToDosError (ret)); else if (GetLastError () == ERROR_PROC_NOT_FOUND) @@ -842,13 +932,15 @@ create_token (cygsid &usersid, cygsid &pgrpsid, struct passwd *pw) /* Set security descriptor and primary group */ psa = __sec_user (sa_buf, usersid, TRUE); if (psa->lpSecurityDescriptor && - !SetSecurityDescriptorGroup ( - (PSECURITY_DESCRIPTOR) psa->lpSecurityDescriptor, - special_pgrp ? pgrpsid : well_known_null_sid, FALSE)) - debug_printf ("SetSecurityDescriptorGroup %E"); + !SetSecurityDescriptorGroup ((PSECURITY_DESCRIPTOR) + psa->lpSecurityDescriptor, + special_pgrp ? new_groups.pgsid + : well_known_null_sid, + FALSE)) + debug_printf ("SetSecurityDescriptorGroup %E"); /* Convert to primary token. */ - if (!DuplicateTokenEx (token, MAXIMUM_ALLOWED, psa, - SecurityImpersonation, TokenPrimary, &primary_token)) + if (!DuplicateTokenEx (token, MAXIMUM_ALLOWED, psa, SecurityImpersonation, + TokenPrimary, &primary_token)) { __seterrno (); debug_printf ("DuplicateTokenEx %E"); @@ -862,8 +954,8 @@ out: CloseHandle (token); if (privs) free (privs); - if (my_grps) - free (my_grps); + if (my_tok_gsids) + free (my_tok_gsids); close_local_policy (lsa); debug_printf ("%d = create_token ()", primary_token); @@ -946,13 +1038,13 @@ subauth (struct passwd *pw) str2buf2uni (subbuf.auth.Workstation, subbuf.wkstbuf, ""); memcpy (subbuf.auth.ChallengeToClient, "12345678", MSV1_0_CHALLENGE_LENGTH); str2buf2lsa (subbuf.auth.CaseSensitiveChallengeResponse, subbuf.authinf1, ""); - str2buf2lsa (subbuf.auth.CaseInsensitiveChallengeResponse, subbuf.authinf2,""); + str2buf2lsa (subbuf.auth.CaseInsensitiveChallengeResponse,subbuf.authinf2,""); subbuf.auth.ParameterControl = 0 | (subauth_id << 24); /* Try to logon... */ ret = LsaLogonUser (lsa_hdl, (PLSA_STRING) &origin, Network, - package_id, &subbuf, sizeof subbuf, - NULL, &ts, (PVOID *)&profile, &size, - &luid, &user_token, "a, &ret2); + package_id, &subbuf, sizeof subbuf, + NULL, &ts, (PVOID *) &profile, &size, + &luid, &user_token, "a, &ret2); if (ret != STATUS_SUCCESS) { debug_printf ("LsaLogonUser: %d", ret); @@ -963,8 +1055,7 @@ subauth (struct passwd *pw) LsaFreeReturnBuffer (profile); /* Convert to primary token. */ if (!DuplicateTokenEx (user_token, TOKEN_ALL_ACCESS, &sa, - SecurityImpersonation, TokenPrimary, - &primary_token)) + SecurityImpersonation, TokenPrimary, &primary_token)) __seterrno (); out: @@ -1004,7 +1095,7 @@ read_sd (const char *file, PSECURITY_DESCRIPTOR sd_buf, LPDWORD sd_size) DWORD len = 0; const char *pfile = file; - char fbuf [PATH_MAX]; + char fbuf[PATH_MAX]; if (current_codepage == oem_cp) { DWORD fname_len = min (sizeof (fbuf) - 1, strlen (file)); @@ -1015,9 +1106,9 @@ read_sd (const char *file, PSECURITY_DESCRIPTOR sd_buf, LPDWORD sd_size) if (!GetFileSecurity (pfile, OWNER_SECURITY_INFORMATION - | GROUP_SECURITY_INFORMATION - | DACL_SECURITY_INFORMATION, - sd_buf, *sd_size, &len)) + | GROUP_SECURITY_INFORMATION + | DACL_SECURITY_INFORMATION, + sd_buf, *sd_size, &len)) { __seterrno (); return -1; @@ -1090,8 +1181,8 @@ write_sd (const char *file, PSECURITY_DESCRIPTOR sd_buf, DWORD sd_size) &bytes_written, FALSE, TRUE, &context)) { /* Samba returns ERROR_NOT_SUPPORTED. - FAT returns ERROR_INVALID_SECURITY_DESCR. - This shouldn't return as error, but better be ignored. */ + FAT returns ERROR_INVALID_SECURITY_DESCR. + This shouldn't return as error, but better be ignored. */ DWORD ret = GetLastError (); if (ret != ERROR_NOT_SUPPORTED && ret != ERROR_INVALID_SECURITY_DESCR) { @@ -1117,7 +1208,7 @@ get_nt_attribute (const char *file, int *attribute, syscall_printf ("file: %s", file); - /* Yeah, sounds too much, but I've seen SDs of 2100 bytes!*/ + /* Yeah, sounds too much, but I've seen SDs of 2100 bytes! */ DWORD sd_size = 4096; char sd_buf[4096]; PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf; @@ -1282,13 +1373,13 @@ get_file_attribute (int use_ntsec, const char *file, if (allow_ntea) { int oatt = *attribute; - res = NTReadEA (file, ".UNIXATTR", (char *) attribute, sizeof (*attribute)); + res = NTReadEA (file, ".UNIXATTR", (char *)attribute, sizeof(*attribute)); *attribute |= oatt; } else res = 0; - /* symlinks are everything for everyone!*/ + /* symlinks are everything for everyone! */ if ((*attribute & S_IFLNK) == S_IFLNK) *attribute |= S_IRWXU | S_IRWXG | S_IRWXO; @@ -1296,8 +1387,8 @@ get_file_attribute (int use_ntsec, const char *file, } static int -get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, int *attribute, - __uid32_t *uidret, __gid32_t *gidret) +get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, + int *attribute, __uid32_t *uidret, __gid32_t *gidret) { if (!wincap.has_security ()) return 0; @@ -1308,18 +1399,15 @@ get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, int *attribu PACL acl; if (ERROR_SUCCESS != GetSecurityInfo (handle, object_type, - DACL_SECURITY_INFORMATION | - GROUP_SECURITY_INFORMATION | - OWNER_SECURITY_INFORMATION, - &owner_sid, - &group_sid, - &acl, - NULL, - &psd)) - { - __seterrno (); - debug_printf ("GetSecurityInfo %E"); - return -1; + DACL_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION | + OWNER_SECURITY_INFORMATION, + &owner_sid, &group_sid, + &acl, NULL, &psd)) + { + __seterrno (); + debug_printf ("GetSecurityInfo %E"); + return -1; } __uid32_t uid = cygsid (owner_sid).get_uid (); @@ -1341,8 +1429,7 @@ get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, int *attribu if (!acl) { *attribute |= S_IRWXU | S_IRWXG | S_IRWXO; - syscall_printf ("No ACL = %x, uid %d, gid %d", - *attribute, uid, gid); + syscall_printf ("No ACL = %x, uid %d, gid %d", *attribute, uid, gid); LocalFree (psd); return 0; } @@ -1354,7 +1441,7 @@ get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, int *attribu for (DWORD i = 0; i < acl->AceCount; ++i) { - if (!GetAce (acl, i, (PVOID *) &ace)) + if (!GetAce (acl, i, (PVOID *) & ace)) continue; if (ace->Header.AceFlags & INHERIT_ONLY) continue; @@ -1372,7 +1459,7 @@ get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, int *attribu continue; } - cygsid ace_sid ((PSID) &ace->SidStart); + cygsid ace_sid ((PSID) & ace->SidStart); if (owner_sid && ace_sid == owner_sid) { if (ace->Mask & FILE_READ_DATA) @@ -1438,11 +1525,12 @@ get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, int *attribu int get_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, - int *attribute, __uid32_t *uidret, __gid32_t *gidret) + int *attribute, __uid32_t *uidret, __gid32_t *gidret) { if (allow_ntsec) { - int res = get_nt_object_attribute (handle, object_type, attribute, uidret, gidret); + int res = get_nt_object_attribute (handle, object_type, attribute, + uidret, gidret); if (attribute && (*attribute & S_IFLNK) == S_IFLNK) *attribute |= S_IRWXU | S_IRWXG | S_IRWXO; return res; @@ -1456,7 +1544,7 @@ get_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, if (!attribute) return 0; - /* symlinks are everything for everyone!*/ + /* symlinks are everything for everyone! */ if ((*attribute & S_IFLNK) == S_IFLNK) *attribute |= S_IRWXU | S_IRWXG | S_IRWXO; @@ -1475,8 +1563,7 @@ add_access_allowed_ace (PACL acl, int offset, DWORD attributes, ACCESS_ALLOWED_ACE *ace; if (GetAce (acl, offset, (PVOID *) &ace)) ace->Header.AceFlags |= inherit; - len_add += sizeof (ACCESS_DENIED_ACE) - sizeof (DWORD) - + GetLengthSid (sid); + len_add += sizeof (ACCESS_DENIED_ACE) - sizeof (DWORD) + GetLengthSid (sid); return TRUE; } @@ -1492,8 +1579,7 @@ add_access_denied_ace (PACL acl, int offset, DWORD attributes, ACCESS_DENIED_ACE *ace; if (GetAce (acl, offset, (PVOID *) &ace)) ace->Header.AceFlags |= inherit; - len_add += sizeof (ACCESS_DENIED_ACE) - sizeof (DWORD) - + GetLengthSid (sid); + len_add += sizeof (ACCESS_DENIED_ACE) - sizeof (DWORD) + GetLengthSid (sid); return TRUE; } @@ -1614,8 +1700,7 @@ alloc_sd (__uid32_t uid, __gid32_t gid, int attribute, if (attribute & S_IXGRP) group_allow |= FILE_GENERIC_EXECUTE; if ((attribute & (S_IFDIR | S_IWGRP | S_IXGRP)) - == (S_IFDIR | S_IWGRP | S_IXGRP) - && !(attribute & S_ISVTX)) + == (S_IFDIR | S_IWGRP | S_IXGRP) && !(attribute & S_ISVTX)) group_allow |= FILE_DELETE_CHILD; /* Construct allow attribute for everyone. */ @@ -1658,30 +1743,30 @@ alloc_sd (__uid32_t uid, __gid32_t gid, int attribute, /* Construct appropriate inherit attribute. */ DWORD inherit = (attribute & S_IFDIR) ? SUB_CONTAINERS_AND_OBJECTS_INHERIT - : NO_INHERITANCE; + : NO_INHERITANCE; /* Set deny ACE for owner. */ if (owner_deny && !add_access_denied_ace (acl, ace_off++, owner_deny, - owner_sid, acl_len, inherit)) + owner_sid, acl_len, inherit)) return NULL; /* Set allow ACE for owner. */ if (!add_access_allowed_ace (acl, ace_off++, owner_allow, - owner_sid, acl_len, inherit)) + owner_sid, acl_len, inherit)) return NULL; /* Set deny ACE for group. */ if (group_deny && !add_access_denied_ace (acl, ace_off++, group_deny, - group_sid, acl_len, inherit)) + group_sid, acl_len, inherit)) return NULL; /* Set allow ACE for group. */ if (!add_access_allowed_ace (acl, ace_off++, group_allow, - group_sid, acl_len, inherit)) + group_sid, acl_len, inherit)) return NULL; /* Set allow ACE for everyone. */ if (!add_access_allowed_ace (acl, ace_off++, other_allow, - well_known_world_sid, acl_len, inherit)) + well_known_world_sid, acl_len, inherit)) return NULL; /* Set null ACE for special bits. */ if (null_allow @@ -1764,15 +1849,15 @@ void set_security_attribute (int attribute, PSECURITY_ATTRIBUTES psa, void *sd_buf, DWORD sd_buf_size) { - /* symlinks are anything for everyone!*/ + /* symlinks are anything for everyone! */ if ((attribute & S_IFLNK) == S_IFLNK) attribute |= S_IRWXU | S_IRWXG | S_IRWXO; psa->lpSecurityDescriptor = sd_buf; - InitializeSecurityDescriptor ((PSECURITY_DESCRIPTOR)sd_buf, + InitializeSecurityDescriptor ((PSECURITY_DESCRIPTOR) sd_buf, SECURITY_DESCRIPTOR_REVISION); - psa->lpSecurityDescriptor = alloc_sd (geteuid32 (), getegid32 (), - attribute, (PSECURITY_DESCRIPTOR)sd_buf, + psa->lpSecurityDescriptor = alloc_sd (geteuid32 (), getegid32 (), attribute, + (PSECURITY_DESCRIPTOR) sd_buf, &sd_buf_size); } @@ -1803,8 +1888,7 @@ set_nt_attribute (const char *file, __uid32_t uid, __gid32_t gid, int set_file_attribute (int use_ntsec, const char *file, - __uid32_t uid, __gid32_t gid, - int attribute) + __uid32_t uid, __gid32_t gid, int attribute) { int ret = 0; @@ -1825,6 +1909,5 @@ int set_file_attribute (int use_ntsec, const char *file, int attribute) { return set_file_attribute (use_ntsec, file, - myself->uid, myself->gid, - attribute); + myself->uid, myself->gid, attribute); } |