From d6ffc075889f79a600ed2ef0998a7b969d4b51db Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 10 Dec 2002 12:43:49 +0000 Subject: 2002-12-10 Pierre Humblet * pwdgrp.h (pwdgrp_check::pwdgrp_state): Replace by pwdgrp_check::isinitializing (). (pwdgrp_check::isinitializing): Create. * passwd.cc (grab_int): Change type to unsigned, use strtoul and set the pointer content to 0 if the field is invalid. (parse_pwd): Move validity test after getting pw_gid. (read_etc_passwd): Replace "passwd_state <= " by passwd_state::isinitializing (). (internal_getpwuid): Ditto. (internal_getpwnam): Ditto. (getpwent): Ditto. (getpass): Ditto. * grp.cc (parse_grp): Use strtoul for gr_gid and verify the validity. (read_etc_group): Replace "group_state <= " by group_state::isinitializing (). (internal_getgrgid): Ditto. (getgrent32): Ditto. (internal_getgrent): Ditto. 2002-12-10 Pierre Humblet * security.h: Move declarations of internal_getgrent, internal_getpwsid and internal_getgrsid to pwdgrp.h. * pwdgrp.h: Declare internal_getpwsid, internal_getpwnam, internal_getpwuid, internal_getgrsid, internal_getgrgid, internal_getgrnam, internal_getgrent and internal_getgroups. Delete "emulated" from enum pwdgrp_state. (pwdgrp_check::isuninitialized): Create. (pwdgrp_check::pwdgrp_state): Change state to initializing rather than to uninitialized. (pwdgrp_read::gets): Remove trailing CRs. * passwd.cc (grab_string): Don't look for NLs. (grab_int): Ditto. (parse_pwd): Don't look for CRs. Return 0 if entry is too short. (search_for): Delete. (read_etc_passwd): Simplify tests to actually read the file. Set state to loaded before making internal_getpwXX calls. Replace search_for calls by equivalent internal_pwgetXX calls. (internal_getpwsid): Use passwd_state.isuninitialized to decide to call read_etc_passwd. (internal_getpwuid): Create. (internal_getpwnam): Create. (getpwuid32): Simply call internal_getpwuid. (getpwuid_r32): Call internal_getpwuid. (getpwnam): Simply call internal_getpwnam. (getpwnam_r): Call internal_getpwnam. * grp.cc (parse_grp): Don't look for CRs. Adjust blank space. (add_grp_line): Adjust blank space. (class group_lock): Ditto. (read_etc_group): Simplify tests to actually read the file. Set state to loaded before making internal_getgrXX calls. Replace getgrXX calls by equivalent internal calls. (internal_getgrsid): Use group_state.isuninitialized to decide to call read_etc_group. (internal_getgrgid): Create. (internal_getgrnam): Create. (getgroups32): Simply call internal_getgrgid. (getgrnam32): Simply call internal_getgrnam. (internal_getgrent): Call group_state.isuninitialized. (internal_getgroups): Create from the former getgroups32, using two of the four arguments. Set gid to myself->gid and username to cygheap->user.name (). (getgroups32): Simply call internal_getgroup. (getgroups): Call internal_getgroup instead of getgroups32. (setgroups32): Call internal versions of get{pw,gr}XX. * sec_helper.cc: Include pwdgrp.h. (is_grp_member): Call internal versions of get{pw,gr}XX. * security.cc: Include pwdgrp.h. (alloc_sd): Call internal versions of get{pw,gr}XX. * syscalls.cc: Include pwdgrp.h. (seteuid32): Call internal versions of get{pw,gr}XX. (setegid32): Ditto. * uinfo.cc: Include pwdgrp.h. (internal_getlogin): Call internal versions of get{pw,gr}XX. (cygheap_user::ontherange): Ditto. * sec_acl.cc: Include pwdgrp.h. (setacl): Call internal versions of get{pw,gr}XX. (acl_access): Ditto and simplify logic. (aclfromtext): Ditto. --- winsup/cygwin/ChangeLog | 82 +++++++++++++++++++++++++++ winsup/cygwin/grp.cc | 124 +++++++++++++++++++++-------------------- winsup/cygwin/passwd.cc | 133 ++++++++++++++++---------------------------- winsup/cygwin/pwdgrp.h | 48 +++++++++++----- winsup/cygwin/sec_acl.cc | 27 ++++----- winsup/cygwin/sec_helper.cc | 11 ++-- winsup/cygwin/security.cc | 5 +- winsup/cygwin/security.h | 7 --- winsup/cygwin/syscalls.cc | 5 +- winsup/cygwin/uinfo.cc | 11 ++-- 10 files changed, 258 insertions(+), 195 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index e131977a4..be9113c98 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,85 @@ +2002-12-10 Pierre Humblet + + * pwdgrp.h (pwdgrp_check::pwdgrp_state): Replace by + pwdgrp_check::isinitializing (). + (pwdgrp_check::isinitializing): Create. + * passwd.cc (grab_int): Change type to unsigned, use strtoul and + set the pointer content to 0 if the field is invalid. + (parse_pwd): Move validity test after getting pw_gid. + (read_etc_passwd): Replace "passwd_state <= " by + passwd_state::isinitializing (). + (internal_getpwuid): Ditto. + (internal_getpwnam): Ditto. + (getpwent): Ditto. + (getpass): Ditto. + * grp.cc (parse_grp): Use strtoul for gr_gid and verify the validity. + (read_etc_group): Replace "group_state <= " by + group_state::isinitializing (). + (internal_getgrgid): Ditto. + (getgrent32): Ditto. + (internal_getgrent): Ditto. + +2002-12-10 Pierre Humblet + + * security.h: Move declarations of internal_getgrent, + internal_getpwsid and internal_getgrsid to pwdgrp.h. + * pwdgrp.h: Declare internal_getpwsid, internal_getpwnam, + internal_getpwuid, internal_getgrsid, internal_getgrgid, + internal_getgrnam, internal_getgrent and internal_getgroups. + Delete "emulated" from enum pwdgrp_state. + (pwdgrp_check::isuninitialized): Create. + (pwdgrp_check::pwdgrp_state): Change state to initializing + rather than to uninitialized. + (pwdgrp_read::gets): Remove trailing CRs. + * passwd.cc (grab_string): Don't look for NLs. + (grab_int): Ditto. + (parse_pwd): Don't look for CRs. Return 0 if entry is too short. + (search_for): Delete. + (read_etc_passwd): Simplify tests to actually read the file. + Set state to loaded before making internal_getpwXX calls. + Replace search_for calls by equivalent internal_pwgetXX calls. + (internal_getpwsid): Use passwd_state.isuninitialized to decide + to call read_etc_passwd. + (internal_getpwuid): Create. + (internal_getpwnam): Create. + (getpwuid32): Simply call internal_getpwuid. + (getpwuid_r32): Call internal_getpwuid. + (getpwnam): Simply call internal_getpwnam. + (getpwnam_r): Call internal_getpwnam. + * grp.cc (parse_grp): Don't look for CRs. Adjust blank space. + (add_grp_line): Adjust blank space. + (class group_lock): Ditto. + (read_etc_group): Simplify tests to actually read the file. + Set state to loaded before making internal_getgrXX calls. + Replace getgrXX calls by equivalent internal calls. + (internal_getgrsid): Use group_state.isuninitialized to decide + to call read_etc_group. + (internal_getgrgid): Create. + (internal_getgrnam): Create. + (getgroups32): Simply call internal_getgrgid. + (getgrnam32): Simply call internal_getgrnam. + (internal_getgrent): Call group_state.isuninitialized. + (internal_getgroups): Create from the former getgroups32, using + two of the four arguments. Set gid to myself->gid and username + to cygheap->user.name (). + (getgroups32): Simply call internal_getgroup. + (getgroups): Call internal_getgroup instead of getgroups32. + (setgroups32): Call internal versions of get{pw,gr}XX. + * sec_helper.cc: Include pwdgrp.h. + (is_grp_member): Call internal versions of get{pw,gr}XX. + * security.cc: Include pwdgrp.h. + (alloc_sd): Call internal versions of get{pw,gr}XX. + * syscalls.cc: Include pwdgrp.h. + (seteuid32): Call internal versions of get{pw,gr}XX. + (setegid32): Ditto. + * uinfo.cc: Include pwdgrp.h. + (internal_getlogin): Call internal versions of get{pw,gr}XX. + (cygheap_user::ontherange): Ditto. + * sec_acl.cc: Include pwdgrp.h. + (setacl): Call internal versions of get{pw,gr}XX. + (acl_access): Ditto and simplify logic. + (aclfromtext): Ditto. + 2002-12-09 2002-12-02 Egor Duda * lib/pseudo-reloc.c: New file. diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc index b52d9dc89..51ccd066c 100644 --- a/winsup/cygwin/grp.cc +++ b/winsup/cygwin/grp.cc @@ -30,7 +30,7 @@ details. */ on the first call that needs information from it. */ static struct __group32 *group_buf; /* group contents in memory */ -static int curr_lines = -1; +static int curr_lines; static int max_lines; /* Position in the group cache */ @@ -46,10 +46,6 @@ static char * NO_COPY null_ptr = NULL; static int parse_grp (struct __group32 &grp, char *line) { - int len = strlen (line); - if (line[--len] == '\r') - line[len] = '\0'; - char *dp = strchr (line, ':'); if (!dp) @@ -63,9 +59,8 @@ parse_grp (struct __group32 &grp, char *line) if (dp) { *dp++ = '\0'; - grp.gr_gid = strtol (dp, NULL, 10); - dp = strchr (dp, ':'); - if (dp) + grp.gr_gid = strtoul (line = dp, &dp, 10); + if (dp != line && *dp == ':') { grp.gr_mem = &null_ptr; if (*++dp) @@ -100,10 +95,10 @@ static void add_grp_line (char *line) { if (curr_lines == max_lines) - { + { max_lines += 10; group_buf = (struct __group32 *) realloc (group_buf, max_lines * sizeof (struct __group32)); - } + } if (parse_grp (group_buf[curr_lines], line)) curr_lines++; } @@ -114,15 +109,15 @@ class group_lock static NO_COPY pthread_mutex_t mutex; public: group_lock (bool doit) - { - if (armed = doit) - pthread_mutex_lock (&mutex); - } + { + if (armed = doit) + pthread_mutex_lock (&mutex); + } ~group_lock () - { - if (armed) - pthread_mutex_unlock (&mutex); - } + { + if (armed) + pthread_mutex_unlock (&mutex); + } }; pthread_mutex_t NO_COPY group_lock::mutex = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER; @@ -139,12 +134,8 @@ read_etc_group () group_lock here (cygwin_finished_initializing); /* if we got blocked by the mutex, then etc_group may have been processed */ - if (group_state != uninitialized) - return; - - if (group_state != initializing) + if (group_state.isinitializing ()) { - group_state = initializing; for (int i = 0; i < curr_lines; i++) if ((group_buf + i)->gr_mem != &null_ptr) free ((group_buf + i)->gr_mem); @@ -160,9 +151,10 @@ read_etc_group () gr.close (); debug_printf ("Read /etc/group, %d lines", curr_lines); } + group_state = loaded; /* Complete /etc/group in memory if needed */ - if (!getgrgid32 (myself->gid)) + if (!internal_getgrgid (myself->gid)) { static char linebuf [200]; char group_name [UNLEN + 1] = "unknown"; @@ -181,7 +173,6 @@ read_etc_group () debug_printf ("Completing /etc/group: %s", linebuf); add_grp_line (linebuf); } - group_state = loaded; } return; } @@ -191,16 +182,50 @@ internal_getgrsid (cygsid &sid) { char sid_string[128]; - if (curr_lines < 0 && group_state <= initializing) + if (group_state.isuninitialized ()) read_etc_group (); if (sid.string (sid_string)) for (int i = 0; i < curr_lines; i++) - if (!strcmp (sid_string, (group_buf + i)->gr_passwd)) + if (!strcmp (sid_string, group_buf[i].gr_passwd)) return group_buf + i; return NULL; } +struct __group32 * +internal_getgrgid (__gid32_t gid, BOOL check) +{ + struct __group32 * default_grp = NULL; + + if (group_state.isuninitialized () + || (check && group_state.isinitializing ())) + read_etc_group (); + + for (int i = 0; i < curr_lines; i++) + { + if (group_buf[i].gr_gid == myself->gid) + default_grp = group_buf + i; + if (group_buf[i].gr_gid == gid) + return group_buf + i; + } + return allow_ntsec || gid != ILLEGAL_GID ? NULL : default_grp; +} + +struct __group32 * +internal_getgrnam (const char *name, BOOL check) +{ + if (group_state.isuninitialized () + || (check && group_state.isinitializing ())) + read_etc_group (); + + for (int i = 0; i < curr_lines; i++) + if (strcasematch (group_buf[i].gr_name, name)) + return group_buf + i; + + /* Didn't find requested group */ + return NULL; +} + static struct __group16 * grp32togrp16 (struct __group16 *gp16, struct __group32 *gp32) @@ -221,18 +246,7 @@ grp32togrp16 (struct __group16 *gp16, struct __group32 *gp32) extern "C" struct __group32 * getgrgid32 (__gid32_t gid) { - struct __group32 * default_grp = NULL; - if (group_state <= initializing) - read_etc_group (); - - for (int i = 0; i < curr_lines; i++) - { - if (group_buf[i].gr_gid == myself->gid) - default_grp = group_buf + i; - if (group_buf[i].gr_gid == gid) - return group_buf + i; - } - return allow_ntsec || gid != ILLEGAL_GID ? NULL : default_grp; + return internal_getgrgid (gid, TRUE); } extern "C" struct __group16 * @@ -246,15 +260,7 @@ getgrgid (__gid16_t gid) extern "C" struct __group32 * getgrnam32 (const char *name) { - if (group_state <= initializing) - read_etc_group (); - - for (int i = 0; i < curr_lines; i++) - if (strcasematch (group_buf[i].gr_name, name)) - return group_buf + i; - - /* Didn't find requested group */ - return NULL; + return internal_getgrnam (name, TRUE); } extern "C" struct __group16 * @@ -274,7 +280,7 @@ endgrent () extern "C" struct __group32 * getgrent32 () { - if (group_state <= initializing) + if (group_state.isinitializing ()) read_etc_group (); if (grp_pos < curr_lines) @@ -301,7 +307,7 @@ setgrent () struct __group32 * internal_getgrent (int pos) { - if (group_state <= initializing) + if (group_state.isuninitialized ()) read_etc_group (); if (pos < curr_lines) @@ -310,16 +316,14 @@ internal_getgrent (int pos) } int -getgroups32 (int gidsetsize, __gid32_t *grouplist, __gid32_t gid, - const char *username) +internal_getgroups (int gidsetsize, __gid32_t *grouplist) { HANDLE hToken = NULL; DWORD size; int cnt = 0; struct __group32 *gr; - - if (group_state <= initializing) - read_etc_group (); + __gid32_t gid; + const char *username; if (allow_ntsec) { @@ -368,6 +372,8 @@ getgroups32 (int gidsetsize, __gid32_t *grouplist, __gid32_t gid, return cnt; } + gid = myself->gid; + username = cygheap->user.name (); for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx) if (gid == gr->gr_gid) { @@ -397,8 +403,7 @@ error: extern "C" int getgroups32 (int gidsetsize, __gid32_t *grouplist) { - return getgroups32 (gidsetsize, grouplist, myself->gid, - cygheap->user.name ()); + return internal_getgroups (gidsetsize, grouplist); } extern "C" int @@ -414,8 +419,7 @@ getgroups (int gidsetsize, __gid16_t *grouplist) if (gidsetsize > 0 && grouplist) grouplist32 = (__gid32_t *) alloca (gidsetsize * sizeof (__gid32_t)); - int ret = getgroups32 (gidsetsize, grouplist32, myself->gid, - cygheap->user.name ()); + int ret = internal_getgroups (gidsetsize, grouplist32); if (gidsetsize > 0 && grouplist) for (int i = 0; i < ret; ++ i) @@ -462,7 +466,7 @@ setgroups32 (int ngroups, const __gid32_t *grouplist) for (int gidy = 0; gidy < gidx; gidy++) if (grouplist[gidy] == grouplist[gidx]) goto found; /* Duplicate */ - if ((gr = getgrgid32 (grouplist[gidx])) && + if ((gr = internal_getgrgid (grouplist[gidx])) && gsids.addfromgr (gr)) goto found; debug_printf ("No sid found for gid %d", grouplist[gidx]); diff --git a/winsup/cygwin/passwd.cc b/winsup/cygwin/passwd.cc index 3677f8d13..c3bb7a115 100644 --- a/winsup/cygwin/passwd.cc +++ b/winsup/cygwin/passwd.cc @@ -27,7 +27,7 @@ details. */ on the first call that needs information from it. */ static struct passwd *passwd_buf; /* passwd contents in memory */ -static int curr_lines = -1; +static int curr_lines; static int max_lines; static pwdgrp_check passwd_state; @@ -47,7 +47,7 @@ grab_string (char **p) char *src = *p; char *res = src; - while (*src && *src != ':' && *src != '\n') + while (*src && *src != ':') src++; if (*src == ':') @@ -60,16 +60,12 @@ grab_string (char **p) } /* same, for ints */ -static int +static unsigned int grab_int (char **p) { char *src = *p; - int val = strtol (src, NULL, 10); - while (*src && *src != ':' && *src != '\n') - src++; - if (*src == ':') - src++; - *p = src; + unsigned int val = strtoul (src, p, 10); + *p = (*p == src || **p != ':') ? almost_null : *p + 1; return val; } @@ -79,16 +75,12 @@ parse_pwd (struct passwd &res, char *buf) { /* Allocate enough room for the passwd struct and all the strings in it in one go */ - size_t len = strlen (buf); - if (buf[--len] == '\r') - buf[len] = '\0'; - if (len < 6) - return 0; - res.pw_name = grab_string (&buf); res.pw_passwd = grab_string (&buf); res.pw_uid = grab_int (&buf); res.pw_gid = grab_int (&buf); + if (!*buf) + return 0; res.pw_comment = 0; res.pw_gecos = grab_string (&buf); res.pw_dir = grab_string (&buf); @@ -129,28 +121,6 @@ class passwd_lock pthread_mutex_t NO_COPY passwd_lock::mutex = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER; -/* Cygwin internal */ -/* If this ever becomes non-reentrant, update all the getpw*_r functions */ -static struct passwd * -search_for (__uid32_t uid, const char *name) -{ - struct passwd *res = 0; - - for (int i = 0; i < curr_lines; i++) - { - res = passwd_buf + i; - /* on Windows NT user names are case-insensitive */ - if (name) - { - if (strcasematch (name, res->pw_name)) - return res; - } - else if (uid == (__uid32_t) res->pw_uid) - return res; - } - return NULL; -} - /* Read in /etc/passwd and save contents in the password cache. This sets passwd_state to loaded or emulated so functions in this file can tell that /etc/passwd has been read in or will be emulated. */ @@ -166,12 +136,8 @@ read_etc_passwd () passwd_lock here (cygwin_finished_initializing); /* if we got blocked by the mutex, then etc_passwd may have been processed */ - if (passwd_state != uninitialized) - return; - - if (passwd_state != initializing) + if (passwd_state.isinitializing ()) { - passwd_state = initializing; curr_lines = 0; if (pr.open ("/etc/passwd")) { @@ -183,6 +149,7 @@ read_etc_passwd () pr.close (); debug_printf ("Read /etc/passwd, %d lines", curr_lines); } + passwd_state = loaded; static char linebuf[1024]; char strbuf[128] = ""; @@ -199,12 +166,12 @@ read_etc_passwd () default_uid = DEFAULT_UID_NT; } else if (myself->uid == ILLEGAL_UID) - searchentry = !search_for (DEFAULT_UID, NULL); + searchentry = !internal_getpwuid (DEFAULT_UID); if (searchentry && - (!(pw = search_for (0, cygheap->user.name ())) || + (!(pw = internal_getpwnam (cygheap->user.name ())) || (myself->uid != ILLEGAL_UID && myself->uid != (__uid32_t) pw->pw_uid && - !search_for (myself->uid, NULL)))) + !internal_getpwuid (myself->uid)))) { snprintf (linebuf, sizeof (linebuf), "%s:*:%lu:%lu:,%s:%s:/bin/sh", cygheap->user.name (), @@ -214,7 +181,6 @@ read_etc_passwd () debug_printf ("Completing /etc/passwd: %s", linebuf); add_pwd_line (linebuf); } - passwd_state = loaded; } return; } @@ -226,7 +192,7 @@ internal_getpwsid (cygsid &sid) char *ptr1, *ptr2, *endptr; char sid_string[128] = {0,','}; - if (curr_lines < 0 && passwd_state <= initializing) + if (passwd_state.isuninitialized ()) read_etc_passwd (); if (sid.string (sid_string + 2)) @@ -242,15 +208,40 @@ internal_getpwsid (cygsid &sid) return NULL; } -extern "C" struct passwd * -getpwuid32 (__uid32_t uid) +struct passwd * +internal_getpwuid (__uid32_t uid, BOOL check) { - if (passwd_state <= initializing) + if (passwd_state.isuninitialized () + || (check && passwd_state.isinitializing ())) read_etc_passwd (); - pthread_testcancel (); + for (int i = 0; i < curr_lines; i++) + if (uid == (__uid32_t) passwd_buf[i].pw_uid) + return passwd_buf + i; + return NULL; +} + +struct passwd * +internal_getpwnam (const char *name, BOOL check) +{ + if (passwd_state.isuninitialized () + || (check && passwd_state.isinitializing ())) + read_etc_passwd (); - return search_for (uid, 0); + for (int i = 0; i < curr_lines; i++) + /* on Windows NT user names are case-insensitive */ + if (strcasematch (name, passwd_buf[i].pw_name)) + return passwd_buf + i; + return NULL; +} + + +extern "C" struct passwd * +getpwuid32 (__uid32_t uid) +{ + struct passwd *temppw = internal_getpwuid (uid, TRUE); + pthread_testcancel (); + return temppw; } extern "C" struct passwd * @@ -267,13 +258,8 @@ getpwuid_r32 (__uid32_t uid, struct passwd *pwd, char *buffer, size_t bufsize, s if (!pwd || !buffer) return ERANGE; - if (passwd_state <= initializing) - read_etc_passwd (); - + struct passwd *temppw = internal_getpwuid (uid, TRUE); pthread_testcancel (); - - struct passwd *temppw = search_for (uid, 0); - if (!temppw) return 0; @@ -310,12 +296,9 @@ getpwuid_r (__uid16_t uid, struct passwd *pwd, char *buffer, size_t bufsize, str extern "C" struct passwd * getpwnam (const char *name) { - if (passwd_state <= initializing) - read_etc_passwd (); - + struct passwd *temppw = internal_getpwnam (name, TRUE); pthread_testcancel (); - - return search_for (0, name); + return temppw; } @@ -331,13 +314,9 @@ getpwnam_r (const char *nam, struct passwd *pwd, char *buffer, size_t bufsize, s if (!pwd || !buffer || !nam) return ERANGE; - if (passwd_state <= initializing) - read_etc_passwd (); - + struct passwd *temppw = internal_getpwnam (nam, TRUE); pthread_testcancel (); - struct passwd *temppw = search_for (0, nam); - if (!temppw) return 0; @@ -368,7 +347,7 @@ getpwnam_r (const char *nam, struct passwd *pwd, char *buffer, size_t bufsize, s extern "C" struct passwd * getpwent (void) { - if (passwd_state <= initializing) + if (passwd_state.isinitializing ()) read_etc_passwd (); if (pw_pos < curr_lines) @@ -401,20 +380,6 @@ setpassent () return 0; } -#if 0 /* Unused */ -/* Internal function. ONLY USE THIS INTERNALLY, NEVER `getpwent'!!! */ -struct passwd * -internal_getpwent (int pos) -{ - if (passwd_state <= initializing) - read_etc_passwd (); - - if (pos < curr_lines) - return passwd_buf + pos; - return NULL; -} -#endif - extern "C" char * getpass (const char * prompt) { @@ -425,7 +390,7 @@ getpass (const char * prompt) #endif struct termios ti, newti; - if (passwd_state <= initializing) + if (passwd_state.isinitializing ()) read_etc_passwd (); cygheap_fdget fhstdin (0); diff --git a/winsup/cygwin/pwdgrp.h b/winsup/cygwin/pwdgrp.h index 75de89fbe..6be1b32f7 100644 --- a/winsup/cygwin/pwdgrp.h +++ b/winsup/cygwin/pwdgrp.h @@ -10,10 +10,20 @@ This software is a copyrighted work licensed under the terms of the Cygwin license. Please consult the file "CYGWIN_LICENSE" for 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_getpwnam (const char *, BOOL = FALSE); +extern struct passwd *internal_getpwuid (__uid32_t, BOOL = FALSE); +extern struct __group32 *internal_getgrsid (cygsid &); +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 *); + enum pwdgrp_state { uninitialized = 0, initializing, - emulated, loaded }; @@ -24,26 +34,34 @@ class pwdgrp_check { public: pwdgrp_check () : state (uninitialized) {} - operator pwdgrp_state () + BOOL isinitializing () { - if (state != uninitialized && file_w32[0] && cygheap->etc_changed ()) - { - HANDLE h; - WIN32_FIND_DATA data; - - if ((h = FindFirstFile (file_w32, &data)) != INVALID_HANDLE_VALUE) + if (state <= initializing) + state = initializing; + else if (cygheap->etc_changed ()) + { + if (!file_w32[0]) + state = initializing; + else { - if (CompareFileTime (&data.ftLastWriteTime, &last_modified) > 0) - state = uninitialized; - FindClose (h); + HANDLE h; + WIN32_FIND_DATA data; + + if ((h = FindFirstFile (file_w32, &data)) != INVALID_HANDLE_VALUE) + { + if (CompareFileTime (&data.ftLastWriteTime, &last_modified) > 0) + state = initializing; + FindClose (h); + } } } - return state; + return state == initializing; } void operator = (pwdgrp_state nstate) { state = nstate; } + BOOL isuninitialized () const { return state == uninitialized; } void set_last_modified (HANDLE fh, const char *name) { if (!file_w32[0]) @@ -101,7 +119,11 @@ public: lptr = eptr; eptr = strchr (lptr, '\n'); if (eptr) - *eptr++ = '\0'; + { + if (eptr > lptr && *(eptr - 1) == '\r') + *(eptr - 1) = 0; + *eptr++ = '\0'; + } return lptr; } inline HANDLE get_fhandle () { return fh; } diff --git a/winsup/cygwin/sec_acl.cc b/winsup/cygwin/sec_acl.cc index 51ac03526..a928002c5 100644 --- a/winsup/cygwin/sec_acl.cc +++ b/winsup/cygwin/sec_acl.cc @@ -30,6 +30,7 @@ details. */ #include "dtable.h" #include "pinfo.h" #include "cygheap.h" +#include "pwdgrp.h" extern "C" int aclsort (int nentries, int, __aclent16_t *aclbufp); extern "C" int acl (const char *path, int cmd, int nentries, __aclent16_t *aclbufp); @@ -158,7 +159,7 @@ setacl (const char *file, int nentries, __aclent16_t *aclbufp) break; case USER: case DEF_USER: - if (!(pw = getpwuid32 (aclbufp[i].a_id)) + if (!(pw = internal_getpwuid (aclbufp[i].a_id)) || !sid.getfrompw (pw) || !add_access_allowed_ace (acl, ace_off++, allow, sid, acl_len, inheritance)) @@ -172,7 +173,7 @@ setacl (const char *file, int nentries, __aclent16_t *aclbufp) break; case GROUP: case DEF_GROUP: - if (!(gr = getgrgid32 (aclbufp[i].a_id)) + if (!(gr = internal_getgrgid (aclbufp[i].a_id)) || !sid.getfromgr (gr) || !add_access_allowed_ace (acl, ace_off++, allow, sid, acl_len, inheritance)) @@ -419,21 +420,15 @@ acl_access (const char *path, int flags) * Take SID from passwd, search SID in group, check is_grp_member. */ cygsid owner; - cygsid group; struct passwd *pw; struct __group32 *gr = NULL; - if ((pw = getpwuid32 (acls[i].a_id)) != NULL - && owner.getfrompw (pw)) - { - for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx) - if (group.getfromgr (gr) - && owner == group - && is_grp_member (myself->uid, gr->gr_gid)) - break; - } - if (!gr) - continue; + if ((pw = internal_getpwuid (acls[i].a_id)) != NULL + && owner.getfrompw (pw) + && (gr = internal_getgrsid (owner)) + && is_grp_member (myself->uid, gr->gr_gid)) + break; + continue; } break; case GROUP_OBJ: @@ -958,7 +953,7 @@ aclfromtext (char *acltextp, int *) c += 5; if (isalpha (*c)) { - struct passwd *pw = getpwnam (c); + struct passwd *pw = internal_getpwnam (c); if (!pw) { set_errno (EINVAL); @@ -986,7 +981,7 @@ aclfromtext (char *acltextp, int *) c += 5; if (isalpha (*c)) { - struct __group32 *gr = getgrnam32 (c); + struct __group32 *gr = internal_getgrnam (c); if (!gr) { set_errno (EINVAL); diff --git a/winsup/cygwin/sec_helper.cc b/winsup/cygwin/sec_helper.cc index 125b9b00d..0a5c5803d 100644 --- a/winsup/cygwin/sec_helper.cc +++ b/winsup/cygwin/sec_helper.cc @@ -31,6 +31,7 @@ details. */ #include "dtable.h" #include "pinfo.h" #include "cygheap.h" +#include "pwdgrp.h" /* General purpose security attribute objects for global use. */ SECURITY_ATTRIBUTES NO_COPY sec_none; @@ -164,7 +165,6 @@ cygsid::get_id (BOOL search_grp, int *type) BOOL is_grp_member (__uid32_t uid, __gid32_t gid) { - extern int getgroups32 (int, __gid32_t *, __gid32_t, const char *); struct passwd *pw; struct __group32 *gr; int idx; @@ -176,12 +176,11 @@ is_grp_member (__uid32_t uid, __gid32_t gid) /* If gid == primary group of current user, return immediately. */ if (gid == myself->gid) return TRUE; - /* Calling getgroups32 only makes sense when reading the access token. */ + /* Calling getgroups only makes sense when reading the access token. */ if (allow_ntsec) { __gid32_t grps[NGROUPS_MAX]; - int cnt = getgroups32 (NGROUPS_MAX, grps, myself->gid, - cygheap->user.name ()); + int cnt = internal_getgroups (NGROUPS_MAX, grps); for (idx = 0; idx < cnt; ++idx) if (grps[idx] == gid) return TRUE; @@ -190,13 +189,13 @@ is_grp_member (__uid32_t uid, __gid32_t gid) } /* Otherwise try getting info from examining passwd and group files. */ - if ((pw = getpwuid32 (uid))) + if ((pw = internal_getpwuid (uid))) { /* If gid == primary group of uid, return immediately. */ if ((__gid32_t) pw->pw_gid == gid) return TRUE; /* Otherwise search for supplementary user list of this group. */ - if ((gr = getgrgid32 (gid)) && gr->gr_mem) + if ((gr = internal_getgrgid (gid))) for (idx = 0; gr->gr_mem[idx]; ++idx) if (strcasematch (cygheap->user.name (), gr->gr_mem[idx])) return TRUE; diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc index 37e2e66d9..784d75527 100644 --- a/winsup/cygwin/security.cc +++ b/winsup/cygwin/security.cc @@ -39,6 +39,7 @@ details. */ #include #include "ntdll.h" #include "lm.h" +#include "pwdgrp.h" extern BOOL allow_ntea; BOOL allow_ntsec; @@ -1550,7 +1551,7 @@ alloc_sd (__uid32_t uid, __gid32_t gid, int attribute, owner_sid = cygheap->user.sid (); else if (uid == ILLEGAL_UID) owner_sid = cur_owner_sid; - else if (!owner_sid.getfrompw (getpwuid32 (uid))) + else if (!owner_sid.getfrompw (internal_getpwuid (uid))) { set_errno (EINVAL); return NULL; @@ -1564,7 +1565,7 @@ alloc_sd (__uid32_t uid, __gid32_t gid, int attribute, group_sid = cygheap->user.groups.pgsid; else if (gid == ILLEGAL_GID) group_sid = cur_group_sid; - else if (!group_sid.getfromgr (getgrgid32 (gid))) + else if (!group_sid.getfromgr (internal_getgrgid (gid))) { set_errno (EINVAL); return NULL; diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index 2952d8ece..7c95ce8aa 100644 --- a/winsup/cygwin/security.h +++ b/winsup/cygwin/security.h @@ -204,13 +204,6 @@ extern BOOL allow_ntea; extern BOOL allow_ntsec; extern BOOL allow_smbntsec; -/* These functions are needed to allow walking through the passwd - and group lists so they are somehow security related. Besides that - I didn't find a better place to declare them. */ -extern struct __group32 *internal_getgrent (int); -extern struct passwd *internal_getpwsid (cygsid &); -extern struct __group32 *internal_getgrsid (cygsid &); - /* File manipulation */ int __stdcall set_process_privileges (); int __stdcall get_file_attribute (int, const char *, int *, diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index eff73942a..8c0561e79 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -45,6 +45,7 @@ details. */ #define NEED_VFORK #include #include "perthread.h" +#include "pwdgrp.h" #undef _close #undef _lseek @@ -1970,7 +1971,7 @@ seteuid32 (__uid32_t uid) struct passwd * pw_new; PSID origpsid, psid2 = NO_SID; - pw_new = getpwuid32 (uid); + pw_new = internal_getpwuid (uid); if (!usersid.getfrompw (pw_new)) { set_errno (EINVAL); @@ -2146,7 +2147,7 @@ setegid32 (__gid32_t gid) cygsid gsid; HANDLE ptok; - struct __group32 * gr = getgrgid32 (gid); + struct __group32 * gr = internal_getgrgid (gid); if (!gr || gr->gr_gid != gid || !gsid.getfromgr (gr)) { set_errno (EINVAL); diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index 8c853ac2a..a2a46a03f 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -29,6 +29,7 @@ details. */ #include "registry.h" #include "child_info.h" #include "environ.h" +#include "pwdgrp.h" void internal_getlogin (cygheap_user &user) @@ -68,8 +69,8 @@ internal_getlogin (cygheap_user &user) } } - if (!pw && !(pw = getpwnam (user.name ())) - && !(pw = getpwuid32 (DEFAULT_UID))) + if (!pw && !(pw = internal_getpwnam (user.name ())) + && !(pw = internal_getpwuid (DEFAULT_UID))) debug_printf("user not found in augmented /etc/passwd"); else { @@ -79,7 +80,7 @@ internal_getlogin (cygheap_user &user) if (wincap.has_security ()) { cygsid gsid; - if (gsid.getfromgr (getgrgid32 (pw->pw_gid))) + if (gsid.getfromgr (internal_getgrgid (pw->pw_gid))) { /* Set primary group to the group in /etc/passwd. */ user.groups.pgsid = gsid; @@ -214,7 +215,7 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw) else { if (!pw) - pw = getpwnam (name ()); + pw = internal_getpwnam (name ()); if (pw && pw->pw_dir && *pw->pw_dir) { debug_printf ("Set HOME (from /etc/passwd) to %s", pw->pw_dir); @@ -238,7 +239,7 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw) if (what != CH_HOME && homepath == NULL && newhomepath == NULL) { if (!pw) - pw = getpwnam (name ()); + pw = internal_getpwnam (name ()); if (pw && pw->pw_dir && *pw->pw_dir) cygwin_conv_to_full_win32_path (pw->pw_dir, homepath_env_buf); else -- cgit v1.2.3