diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2001-04-25 09:43:25 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2001-04-25 09:43:25 +0000 |
commit | d551169a9fa38d2499840f409e0ca90992d6881a (patch) | |
tree | 7597dd538a99f270fd0285082a090c35a6876d2c /winsup/cygwin/grp.cc | |
parent | 3a6e96682d6ee6f127882eef92e3041de8aca4af (diff) | |
download | newlib-d551169a9fa38d2499840f409e0ca90992d6881a.zip newlib-d551169a9fa38d2499840f409e0ca90992d6881a.tar.gz newlib-d551169a9fa38d2499840f409e0ca90992d6881a.tar.bz2 |
* autoload.cc: Add LoadDLLfunc statements for SetTokenInformation@16.
* cygheap.cc: Include security.h.
* grp.cc (internal_getgrent): New function.
(getgroups): Rearranged using `internal_getgrent' and the new
`cygsid' class.
* passwd.cc (internal_getpwent): New function.
* sec_acl.cc: Use new `cygsid' class throughout.
(acl_access): Use `internal_getgrent' instead of `getgrent'.
* sec_helper.cc: Use new `cygsid' class throughout.
(get_id_from_sid): Use `internal_getgrent' instead of `getgrent'.
Use `internal_getpwent' instead of `getpwent'.
* security.cc: Use new `cygsid' class throughout.
* security.h: Move `MAX_SID_LEN' from winsup.h to here.
Add extern declarations for `internal_getgrent' and `internal_getpwent'.
(class cygsid): New class.
* shared.cc (sec_user): Use new `cygsid' class.
* syscalls.cc (seteuid): Try to set owner to user and primary group to
current group in impersonation token before performing impersonation.
(setegid): Try to set primary group in process token to the new group
if ntsec is on.
* uinfo.cc (internal_getlogin): Use new `cygsid' class.
Try to set owner to user and primary group to current group in process
token if the process has been started from a non cygwin process.
(uinfo_init): Set primary group only if the process has been started
from a non cygwin process.
* winsup.h: Move define for `MAX_SID_LEN' to security.h.
Diffstat (limited to 'winsup/cygwin/grp.cc')
-rw-r--r-- | winsup/cygwin/grp.cc | 95 |
1 files changed, 56 insertions, 39 deletions
diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc index 9b068f7..2cd8b5e 100644 --- a/winsup/cygwin/grp.cc +++ b/winsup/cygwin/grp.cc @@ -258,69 +258,86 @@ setgrent () grp_pos = 0; } +/* Internal function. ONLY USE THIS INTERNALLY, NEVER `getgrent'!!! */ +struct group * +internal_getgrent (int pos) +{ + if (group_state <= initializing) + read_etc_group(); + + if (pos < curr_lines) + return group_buf + pos; + return NULL; +} + int getgroups (int gidsetsize, gid_t *grouplist, gid_t gid, const char *username) { HANDLE hToken = NULL; - char buf[4096]; DWORD size; int cnt = 0; + struct group *gr; if (group_state <= initializing) read_etc_group(); if (allow_ntsec && - OpenProcessToken (hMainProc, TOKEN_QUERY, &hToken) && - GetTokenInformation (hToken, TokenGroups, buf, 4096, &size)) + OpenProcessToken (hMainProc, TOKEN_QUERY, &hToken)) { - TOKEN_GROUPS *groups = (TOKEN_GROUPS *) buf; - char ssid[MAX_SID_LEN]; - PSID sid = (PSID) ssid; - - for (DWORD pg = 0; pg < groups->GroupCount; ++pg) + if (GetTokenInformation (hToken, TokenGroups, NULL, 0, &size) + || GetLastError () == ERROR_INSUFFICIENT_BUFFER) { - struct group *gr; - while ((gr = getgrent ()) != NULL) + char buf[size]; + TOKEN_GROUPS *groups = (TOKEN_GROUPS *) buf; + + if (GetTokenInformation (hToken, TokenGroups, buf, size, &size)) { - if (get_gr_sid (sid, gr) && - EqualSid (sid, groups->Groups[pg].Sid)) - { - if (cnt < gidsetsize) - grouplist[cnt] = gr->gr_gid; - ++cnt; - if (gidsetsize && cnt > gidsetsize) - goto error; - break; - } + cygsid sid; + + for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx) + if (get_gr_sid (sid, gr)) + for (DWORD pg = 0; pg < groups->GroupCount; ++pg) + if (sid == groups->Groups[pg].Sid) + { + if (cnt < gidsetsize) + grouplist[cnt] = gr->gr_gid; + ++cnt; + if (gidsetsize && cnt > gidsetsize) + { + CloseHandle (hToken); + goto error; + } + break; + } } - endgrent (); } + else + debug_printf ("%d = GetTokenInformation(NULL) %E", size); CloseHandle (hToken); - return cnt; + if (cnt) + return cnt; } - else - { - for (int i = 0; i < curr_lines; ++i) - if (gid == group_buf[i].gr_gid) + + for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx) + if (gid == gr->gr_gid) + { + if (cnt < gidsetsize) + grouplist[cnt] = gr->gr_gid; + ++cnt; + if (gidsetsize && cnt > gidsetsize) + goto error; + } + else if (gr->gr_mem) + for (int gi = 0; gr->gr_mem[gi]; ++gi) + if (strcasematch (username, gr->gr_mem[gi])) { if (cnt < gidsetsize) - grouplist[cnt] = group_buf[i].gr_gid; + grouplist[cnt] = gr->gr_gid; ++cnt; if (gidsetsize && cnt > gidsetsize) goto error; } - else if (group_buf[i].gr_mem) - for (int gi = 0; group_buf[i].gr_mem[gi]; ++gi) - if (strcasematch (username, group_buf[i].gr_mem[gi])) - { - if (cnt < gidsetsize) - grouplist[cnt] = group_buf[i].gr_gid; - ++cnt; - if (gidsetsize && cnt > gidsetsize) - goto error; - } - return cnt; - } + return cnt; error: set_errno (EINVAL); |