Index: security.h =================================================================== RCS file: /cvs/src/src/winsup/cygwin/security.h,v retrieving revision 1.36 diff -u -p -r1.36 security.h --- security.h 14 Dec 2002 17:23:42 -0000 1.36 +++ security.h 29 Jan 2003 04:10:11 -0000 @@ -11,8 +11,8 @@ details. */ #include #define DEFAULT_UID DOMAIN_USER_RID_ADMIN -#define DEFAULT_UID_NT 400 /* Non conflicting number */ -#define DEFAULT_GID 401 +#define UNKNOWN_UID 400 /* Non conflicting number */ +#define UNKNOWN_GID 401 #define MAX_SID_LEN 40 #define MAX_DACL_LEN(n) (sizeof (ACL) \ @@ -20,8 +20,40 @@ details. */ #define NO_SID ((PSID)NULL) -class cygsid { +class cygpsid { +protected: PSID psid; +public: + cygpsid () {} + cygpsid (PSID nsid) { psid = nsid; } + operator const PSID () { return psid; } + const PSID operator= (PSID nsid) { return psid = nsid;} + __uid32_t get_id (BOOL search_grp, int *type = NULL); + int get_uid () { return get_id (FALSE); } + int get_gid () { return get_id (TRUE); } + + char *string (char *nsidstr) const; + + bool operator== (const PSID nsid) const + { + if (!psid || !nsid) + return nsid == psid; + return EqualSid (psid, nsid); + } + bool operator!= (const PSID nsid) const + { return !(*this == nsid); } + bool operator== (const char *nsidstr) const; + bool operator!= (const char *nsidstr) const + { return !(*this == nsidstr); } + + void debug_print (const char *prefix = NULL) const + { + char buf[256]; + debug_printf ("%s %s", prefix ?: "", string (buf) ?: "NULL"); + } +}; + +class cygsid : public cygpsid { char sbuf[MAX_SID_LEN]; const PSID getfromstr (const char *nsidstr); @@ -50,7 +82,7 @@ public: inline const PSID operator= (const char *nsidstr) { return getfromstr (nsidstr); } - inline cygsid () : psid ((PSID) sbuf) {} + inline cygsid () : cygpsid ((PSID) sbuf) {} inline cygsid (const PSID nsid) { *this = nsid; } inline cygsid (const char *nstrsid) { *this = nstrsid; } @@ -58,34 +90,6 @@ public: BOOL getfrompw (const struct passwd *pw); BOOL getfromgr (const struct __group32 *gr); - - __uid32_t get_id (BOOL search_grp, int *type = NULL); - inline int get_uid () { return get_id (FALSE); } - inline int get_gid () { return get_id (TRUE); } - - char *string (char *nsidstr) const; - - inline BOOL operator== (const PSID nsid) const - { - if (!psid || !nsid) - return nsid == psid; - return EqualSid (psid, nsid); - } - inline BOOL operator== (const char *nsidstr) const - { - cygsid nsid (nsidstr); - return *this == nsid; - } - inline BOOL operator!= (const PSID nsid) const - { return !(*this == nsid); } - inline BOOL operator!= (const char *nsidstr) const - { return !(*this == nsidstr); } - - void debug_print (const char *prefix = NULL) const - { - char buf[256]; - debug_printf ("%s %s", prefix ?: "", string (buf) ?: "NULL"); - } }; typedef enum { cygsidlist_empty, cygsidlist_alloc, cygsidlist_auto } cygsidlist_type; @@ -171,8 +175,11 @@ public: } void clear_supp () { - sgsids.free_sids (); - ischanged = TRUE; + if (issetgroups ()) + { + sgsids.free_sids (); + ischanged = TRUE; + } } void update_pgrp (const PSID sid) { @@ -222,6 +229,8 @@ BOOL __stdcall add_access_denied_ace (PA void set_security_attribute (int attribute, PSECURITY_ATTRIBUTES psa, void *sd_buf, DWORD sd_buf_size); +bool get_sids_info (cygpsid, cygpsid, __uid32_t * , __gid32_t *); + /* Try a subauthentication. */ HANDLE subauth (struct passwd *pw); /* Try creating a token directly. */ @@ -236,7 +245,7 @@ BOOL get_logon_server (const char * doma /* sec_helper.cc: Security helper functions. */ BOOL __stdcall is_grp_member (__uid32_t uid, __gid32_t gid); -int set_process_privilege (const char *privilege, BOOL enable = TRUE); +int set_process_privilege (const char *privilege, bool enable = true, bool check_thread = false); /* shared.cc: */ /* Retrieve a security descriptor that allows all access */ Index: sec_helper.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/sec_helper.cc,v retrieving revision 1.32 diff -u -p -r1.32 sec_helper.cc --- sec_helper.cc 26 Jan 2003 06:42:40 -0000 1.32 +++ sec_helper.cc 29 Jan 2003 04:12:45 -0000 @@ -39,7 +39,7 @@ SECURITY_ATTRIBUTES NO_COPY sec_none_nih SECURITY_ATTRIBUTES NO_COPY sec_all; SECURITY_ATTRIBUTES NO_COPY sec_all_nih; -SID_IDENTIFIER_AUTHORITY sid_auth[] = { +SID_IDENTIFIER_AUTHORITY NO_COPY sid_auth[] = { {SECURITY_NULL_SID_AUTHORITY}, {SECURITY_WORLD_SID_AUTHORITY}, {SECURITY_LOCAL_SID_AUTHORITY}, @@ -62,6 +62,63 @@ cygsid well_known_authenticated_users_si cygsid well_known_system_sid; cygsid well_known_admins_sid; +bool +cygpsid::operator== (const char *nsidstr) const +{ + cygsid nsid (nsidstr); + return psid == nsid; +} + +__uid32_t +cygpsid::get_id (BOOL search_grp, int *type) +{ + /* First try to get SID from group, then passwd */ + __uid32_t id = ILLEGAL_UID; + + if (search_grp) + { + struct __group32 *gr; + if (cygheap->user.groups.pgsid == psid) + id = myself->gid; + else if ((gr = internal_getgrsid (*this))) + id = gr->gr_gid; + if (id != ILLEGAL_UID) + { + if (type) + *type = GROUP; + return id; + } + } + if (!search_grp || type) + { + struct passwd *pw; + if (*this == cygheap->user.sid ()) + id = myself->uid; + else if ((pw = internal_getpwsid (*this))) + id = pw->pw_uid; + if (id != ILLEGAL_UID && type) + *type = USER; + } + return id; +} + + +char * +cygpsid::string (char *nsidstr) const +{ + char *t; + DWORD i; + + if (!psid || !nsidstr) + return NULL; + strcpy (nsidstr, "S-1-"); + t = nsidstr + sizeof ("S-1-") - 1; + t += __small_sprintf (t, "%u", GetSidIdentifierAuthority (psid)->Value[5]); + for (i = 0; i < *GetSidSubAuthorityCount (psid); ++i) + t += __small_sprintf (t, "-%lu", *GetSidSubAuthority (psid, i)); + return nsidstr; +} + void cygsid::init () { @@ -80,25 +137,6 @@ cygsid::init () well_known_admins_sid = "S-1-5-32-544"; } -char * -cygsid::string (char *nsidstr) const -{ - char t[32]; - DWORD i; - - if (!psid || !nsidstr) - return NULL; - strcpy (nsidstr, "S-1-"); - __small_sprintf (t, "%u", GetSidIdentifierAuthority (psid)->Value[5]); - strcat (nsidstr, t); - for (i = 0; i < *GetSidSubAuthorityCount (psid); ++i) - { - __small_sprintf (t, "-%lu", *GetSidSubAuthority (psid, i)); - strcat (nsidstr, t); - } - return nsidstr; -} - PSID cygsid::get_sid (DWORD s, DWORD cnt, DWORD *r) { @@ -148,37 +186,42 @@ cygsid::getfromgr (const struct __group3 return (*this = sp) != NULL; } -__uid32_t -cygsid::get_id (BOOL search_grp, int *type) +bool +get_sids_info (cygpsid owner_sid, cygpsid group_sid, __uid32_t * uidret, __gid32_t * gidret) { - /* First try to get SID from passwd or group entry */ - __uid32_t id = ILLEGAL_UID; - - if (!search_grp) - { - struct passwd *pw; - if (*this == cygheap->user.sid ()) - id = myself->uid; - else if ((pw = internal_getpwsid (*this))) - id = pw->pw_uid; - if (id != ILLEGAL_UID) - { - if (type) - *type = USER; - return id; - } - } - if (search_grp || type) - { - struct __group32 *gr; - if (cygheap->user.groups.pgsid == psid) - id = myself->gid; - else if ((gr = internal_getgrsid (*this))) - id = gr->gr_gid; - if (id != ILLEGAL_UID && type) - *type = GROUP; + struct passwd *pw; + struct __group32 *gr = NULL; + BOOL ret = FALSE; + + if (group_sid == cygheap->user.groups.pgsid) + *gidret = myself->gid; + else if ((gr = internal_getgrsid (group_sid))) + *gidret = gr->gr_gid; + else + *gidret = ILLEGAL_GID; + + if (owner_sid == cygheap->user.sid ()) + { + *uidret = myself->uid; + if (*gidret == myself->gid) + ret = TRUE; + else + ret = (internal_getgroups (0, NULL, &group_sid) > 0); + } + else if ((pw = internal_getpwsid (owner_sid))) + { + *uidret = pw->pw_uid; + if (*gidret == ILLEGAL_GID + || (!gr && !(gr = internal_getgrsid (group_sid)))) + return FALSE; + for (int idx = 0; gr->gr_mem[idx]; ++idx) + if ((ret = strcasematch (pw->pw_name, gr->gr_mem[idx]))) + break; } - return id; + else + *uidret = ILLEGAL_UID; + + return ret; } BOOL @@ -294,7 +337,7 @@ got_it: #endif //unused int -set_process_privilege (const char *privilege, BOOL enable) +set_process_privilege (const char *privilege, bool enable, bool check_thread) { HANDLE hToken = NULL; LUID restore_priv; @@ -302,8 +345,11 @@ set_process_privilege (const char *privi int ret = -1; DWORD size; - if (!OpenProcessToken (hMainProc, TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, - &hToken)) + if ((check_thread && cygheap->user.issetuid () + && !OpenThreadToken (GetCurrentThread (), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, + 0, &hToken)) + || !OpenProcessToken (hMainProc, TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, + &hToken)) { __seterrno (); goto out; @@ -329,7 +375,6 @@ set_process_privilege (const char *privi be enabled. GetLastError () returns an correct error code, though. */ if (enable && GetLastError () == ERROR_NOT_ALL_ASSIGNED) { - debug_printf ("Privilege %s couldn't be assigned", privilege); __seterrno (); goto out; } Index: security.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/security.cc,v retrieving revision 1.132 diff -u -p -r1.132 security.cc --- security.cc 26 Jan 2003 06:42:40 -0000 1.132 +++ security.cc 29 Jan 2003 04:16:56 -0000 @@ -90,13 +90,11 @@ extract_nt_dom_user (const struct passwd if ((d = strstr (pw->pw_gecos, "U-")) != NULL && (d == pw->pw_gecos || d[-1] == ',')) { - c = strchr (d + 2, ','); - if ((u = strchr (d + 2, '\\')) == NULL || (c != NULL && u > c)) + c = strechr (d + 2, ','); + if ((u = strechr (d + 2, '\\')) >= c) u = d + 1; else if (u - d <= INTERNET_MAX_HOST_NAME_LENGTH + 2) 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); } @@ -329,7 +327,7 @@ get_user_groups (WCHAR *wlogonserver, cy for (DWORD i = 0; i < cnt; ++i) { cygsid gsid; - DWORD glen = sizeof (gsid); + DWORD glen = MAX_SID_LEN; char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1]; DWORD dlen = sizeof (domain); SID_NAME_USE use = SidTypeInvalid; @@ -407,7 +405,7 @@ get_user_local_groups (cygsidlist &grp_l if (is_group_member (buf[i].lgrpi0_name, pusersid, grp_list)) { cygsid gsid; - DWORD glen = sizeof (gsid); + DWORD glen = MAX_SID_LEN; char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1]; DWORD dlen = sizeof (domain); @@ -1230,7 +1228,7 @@ get_attribute_from_acl (int * attribute, continue; } - cygsid ace_sid ((PSID) &ace->SidStart); + cygpsid ace_sid ((PSID) &ace->SidStart); if (ace_sid == well_known_world_sid) { if (ace->Mask & FILE_READ_DATA) @@ -1317,13 +1315,13 @@ get_nt_attribute (const char *file, int return -1; } - PSID owner_sid; - PSID group_sid; + cygpsid owner_sid; + cygpsid group_sid; BOOL dummy; - if (!GetSecurityDescriptorOwner (psd, &owner_sid, &dummy)) + if (!GetSecurityDescriptorOwner (psd, (void **) &owner_sid, &dummy)) debug_printf ("GetSecurityDescriptorOwner %E"); - if (!GetSecurityDescriptorGroup (psd, &group_sid, &dummy)) + if (!GetSecurityDescriptorGroup (psd, (void **) &group_sid, &dummy)) debug_printf ("GetSecurityDescriptorGroup %E"); PACL acl; @@ -1336,8 +1334,9 @@ get_nt_attribute (const char *file, int return -1; } - __uid32_t uid = cygsid (owner_sid).get_uid (); - __gid32_t gid = cygsid (group_sid).get_gid (); + __uid32_t uid; + __gid32_t gid; + BOOL grp_member = get_sids_info (owner_sid, group_sid, &uid, &gid); if (uidret) *uidret = uid; if (gidret) @@ -1349,8 +1348,6 @@ get_nt_attribute (const char *file, int return 0; } - BOOL grp_member = is_grp_member (uid, gid); - if (!acl_exists || !acl) { *attribute |= S_IRWXU | S_IRWXG | S_IRWXO; @@ -1420,15 +1417,15 @@ get_nt_object_attribute (HANDLE handle, return 0; PSECURITY_DESCRIPTOR psd = NULL; - PSID owner_sid; - PSID group_sid; + cygpsid owner_sid; + cygpsid group_sid; PACL acl; if (ERROR_SUCCESS != GetSecurityInfo (handle, object_type, DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION, - &owner_sid, &group_sid, + (void **) &owner_sid, (void **) &group_sid, &acl, NULL, &psd)) { __seterrno (); @@ -1436,8 +1433,10 @@ get_nt_object_attribute (HANDLE handle, return -1; } - __uid32_t uid = cygsid (owner_sid).get_uid (); - __gid32_t gid = cygsid (group_sid).get_gid (); + __uid32_t uid; + __gid32_t gid; + BOOL grp_member = get_sids_info (owner_sid, group_sid, &uid, &gid); + if (uidret) *uidret = uid; if (gidret) @@ -1450,8 +1449,6 @@ get_nt_object_attribute (HANDLE handle, return 0; } - BOOL grp_member = is_grp_member (uid, gid); - if (!acl) { *attribute |= S_IRWXU | S_IRWXG | S_IRWXO; @@ -1565,7 +1562,7 @@ alloc_sd (__uid32_t uid, __gid32_t gid, /* Must have SE_RESTORE_NAME privilege to change owner */ if (cur_owner_sid && owner_sid != cur_owner_sid - && set_process_privilege (SE_RESTORE_NAME) < 0 ) + && set_process_privilege (SE_RESTORE_NAME, true, true) < 0 ) return NULL; /* Get SID of new group. */ @@ -1738,7 +1735,8 @@ alloc_sd (__uid32_t uid, __gid32_t gid, for (DWORD i = 0; i < oacl->AceCount; ++i) if (GetAce (oacl, i, (PVOID *) &ace)) { - cygsid ace_sid ((PSID) &ace->SidStart); + cygpsid ace_sid ((PSID) &ace->SidStart); + /* Check for related ACEs. */ if (ace_sid == well_known_null_sid) continue; Index: autoload.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/autoload.cc,v retrieving revision 1.59 diff -u -p -r1.59 autoload.cc --- autoload.cc 15 Jan 2003 10:21:23 -0000 1.59 +++ autoload.cc 29 Jan 2003 04:17:16 -0000 @@ -352,6 +352,7 @@ LoadDLLfunc (LsaOpenPolicy, 16, advapi32 LoadDLLfunc (LsaQueryInformationPolicy, 12, advapi32) LoadDLLfunc (MakeSelfRelativeSD, 12, advapi32) LoadDLLfunc (OpenProcessToken, 12, advapi32) +LoadDLLfunc (OpenThreadToken, 16, advapi32) LoadDLLfunc (RegCloseKey, 4, advapi32) LoadDLLfunc (RegCreateKeyExA, 36, advapi32) LoadDLLfunc (RegDeleteKeyA, 8, advapi32) Index: pwdgrp.h =================================================================== RCS file: /cvs/src/src/winsup/cygwin/pwdgrp.h,v retrieving revision 1.18 diff -u -p -r1.18 pwdgrp.h --- pwdgrp.h 27 Jan 2003 00:16:01 -0000 1.18 +++ pwdgrp.h 29 Jan 2003 04:17:39 -0000 @@ -12,14 +12,14 @@ details. */ /* These functions are needed to allow searching and walking through the passwd and group lists */ -extern struct passwd *internal_getpwsid (cygsid &); +extern struct passwd *internal_getpwsid (cygpsid &); extern struct passwd *internal_getpwnam (const char *, bool = FALSE); extern struct passwd *internal_getpwuid (__uid32_t, bool = FALSE); -extern struct __group32 *internal_getgrsid (cygsid &); +extern struct __group32 *internal_getgrsid (cygpsid &); extern struct __group32 *internal_getgrgid (__gid32_t gid, bool = FALSE); extern struct __group32 *internal_getgrnam (const char *, bool = FALSE); extern struct __group32 *internal_getgrent (int); -int internal_getgroups (int, __gid32_t *, cygsid * = NULL); +int internal_getgroups (int, __gid32_t *, cygpsid * = NULL); #include "sync.h" class pwdgrp Index: passwd.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/passwd.cc,v retrieving revision 1.66 diff -u -p -r1.66 passwd.cc --- passwd.cc 27 Jan 2003 17:00:17 -0000 1.66 +++ passwd.cc 29 Jan 2003 04:18:05 -0000 @@ -85,7 +85,7 @@ pwdgrp::read_passwd () (void) cygheap->user.ontherange (CH_HOME, NULL); snprintf (linebuf, sizeof (linebuf), "%s:*:%lu:%lu:,%s:%s:/bin/sh", cygheap->user.name (), - myself->uid == ILLEGAL_UID ? DEFAULT_UID_NT : myself->uid, + myself->uid == ILLEGAL_UID ? UNKNOWN_UID : myself->uid, myself->gid, strbuf, getenv ("HOME") ?: ""); debug_printf ("Completing /etc/passwd: %s", linebuf); @@ -95,7 +95,7 @@ pwdgrp::read_passwd () } struct passwd * -internal_getpwsid (cygsid &sid) +internal_getpwsid (cygpsid &sid) { struct passwd *pw; char *ptr1, *ptr2, *endptr; Index: grp.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/grp.cc,v retrieving revision 1.73 diff -u -p -r1.73 grp.cc --- grp.cc 27 Jan 2003 00:16:01 -0000 1.73 +++ grp.cc 29 Jan 2003 04:18:23 -0000 @@ -107,7 +107,7 @@ pwdgrp::read_group () } struct __group32 * -internal_getgrsid (cygsid &sid) +internal_getgrsid (cygpsid &sid) { char sid_string[128]; @@ -231,7 +231,7 @@ internal_getgrent (int pos) } int -internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygsid * srchsid) +internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid) { HANDLE hToken = NULL; DWORD size; Index: uinfo.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/uinfo.cc,v retrieving revision 1.110 diff -u -p -r1.110 uinfo.cc --- uinfo.cc 27 Jan 2003 00:31:30 -0000 1.110 +++ uinfo.cc 29 Jan 2003 04:18:48 -0000 @@ -37,7 +37,7 @@ internal_getlogin (cygheap_user &user) struct passwd *pw = NULL; HANDLE ptok = INVALID_HANDLE_VALUE; - myself->gid = DEFAULT_GID; + myself->gid = UNKNOWN_GID; if (wincap.has_security ()) { DWORD siz;