diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2002-11-20 17:10:05 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2002-11-20 17:10:05 +0000 |
commit | 647b92a7d420bee9244054947379f026d105def8 (patch) | |
tree | b6789b659745a0a709f4a1847036c2b0b34ff606 /winsup/cygwin/passwd.cc | |
parent | 3a366b12f692fdfa5aeb8e7c603faa917d786011 (diff) | |
download | cygnal-647b92a7d420bee9244054947379f026d105def8.tar.gz cygnal-647b92a7d420bee9244054947379f026d105def8.tar.bz2 cygnal-647b92a7d420bee9244054947379f026d105def8.zip |
* security.h: Declare internal_getpwsid and internal_getgrsid.
Undeclare internal_getpwent. Define DEFAULT_UID_NT. Change
DEFAULT_GID.
* passwd.cc (internal_getpwsid): New function.
(internal_getpwent): Suppress.
(read_etc_passwd): Make static. Rewrite the code for the completion
line. Set curr_lines to 0.
(parse_pwd): Change type to static int. Return 0 for short lines.
(add_pwd_line): Pay attention to the value of parse_pwd.
(search_for): Do not look for nor return the DEFAULT_UID.
* grp.cc (read_etc_group): Make static. Free gr_mem and set
curr_lines to 0. Always call add_pwd_line. Rewrite the code for the
completion line.
(internal_getgrsid): New function.
(parse_grp): If grp.gr_mem is empty, set it to &null_ptr.
Never NULL gr_passwd.
(getgrgid32): Only return the default if ntsec is off and the gid is
ILLEGAL_GID.
* sec_helper.cc (cygsid::get_id): Use getpwsid and getgrsid.
(cygsid_getfrompw): Clean up last line.
(cygsid_getfromgr): Ditto.
(is_grp_member): Use getpwuid32 and getgrgid32.
* uinfo.cc (internal_getlogin): Set DEFAULT_GID at start.
Use getpwsid. Move the read of /etc/group after the second access
to /etc/passwd. Change some debug_printf.
Diffstat (limited to 'winsup/cygwin/passwd.cc')
-rw-r--r-- | winsup/cygwin/passwd.cc | 154 |
1 files changed, 78 insertions, 76 deletions
diff --git a/winsup/cygwin/passwd.cc b/winsup/cygwin/passwd.cc index 462697b04..ae962822f 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; +static int curr_lines = -1; static int max_lines; static pwdgrp_check passwd_state; @@ -74,7 +74,7 @@ grab_int (char **p) } /* Parse /etc/passwd line into passwd structure. */ -void +static int parse_pwd (struct passwd &res, char *buf) { /* Allocate enough room for the passwd struct and all the strings @@ -82,6 +82,8 @@ parse_pwd (struct passwd &res, char *buf) 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); @@ -91,6 +93,7 @@ parse_pwd (struct passwd &res, char *buf) res.pw_gecos = grab_string (&buf); res.pw_dir = grab_string (&buf); res.pw_shell = grab_string (&buf); + return 1; } /* Add one line from /etc/passwd into the password cache */ @@ -102,7 +105,8 @@ add_pwd_line (char *line) max_lines += 10; passwd_buf = (struct passwd *) realloc (passwd_buf, max_lines * sizeof (struct passwd)); } - parse_pwd (passwd_buf[curr_lines++], line); + if (parse_pwd (passwd_buf[curr_lines], line)) + curr_lines++; } class passwd_lock @@ -125,10 +129,32 @@ 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. */ -void +static void read_etc_passwd () { static pwdgrp_read pr; @@ -146,97 +172,71 @@ read_etc_passwd () if (passwd_state != initializing) { passwd_state = initializing; + curr_lines = 0; if (pr.open ("/etc/passwd")) { char *line; while ((line = pr.gets ()) != NULL) - if (strlen (line)) - add_pwd_line (line); + add_pwd_line (line); passwd_state.set_last_modified (pr.get_fhandle (), pr.get_fname ()); - passwd_state = loaded; pr.close (); debug_printf ("Read /etc/passwd, %d lines", curr_lines); } - else + + static char linebuf[1024]; + char strbuf[128] = ""; + BOOL searchentry = TRUE; + __uid32_t default_uid = DEFAULT_UID; + struct passwd *pw; + + if (wincap.has_security ()) { - static char linebuf[1024]; - - if (wincap.has_security ()) - { - HANDLE ptok; - cygsid tu, tg; - DWORD siz; - - if (OpenProcessToken (hMainProc, TOKEN_QUERY, &ptok)) - { - if (GetTokenInformation (ptok, TokenUser, &tu, sizeof tu, - &siz) - && GetTokenInformation (ptok, TokenPrimaryGroup, &tg, - sizeof tg, &siz)) - { - char strbuf[100]; - snprintf (linebuf, sizeof (linebuf), - "%s::%lu:%lu:%s:%s:/bin/sh", - cygheap->user.name (), - *GetSidSubAuthority (tu, - *GetSidSubAuthorityCount(tu) - 1), - *GetSidSubAuthority (tg, - *GetSidSubAuthorityCount(tg) - 1), - tu.string (strbuf), getenv ("HOME") ?: "/"); - debug_printf ("Emulating /etc/passwd: %s", linebuf); - add_pwd_line (linebuf); - passwd_state = emulated; - } - CloseHandle (ptok); - } - } - if (passwd_state != emulated) - { - snprintf (linebuf, sizeof (linebuf), "%s::%u:%u::%s:/bin/sh", - cygheap->user.name (), (unsigned) DEFAULT_UID, - (unsigned) DEFAULT_GID, getenv ("HOME") ?: "/"); - debug_printf ("Emulating /etc/passwd: %s", linebuf); - add_pwd_line (linebuf); - passwd_state = emulated; - } + cygsid tu = cygheap->user.sid (); + tu.string (strbuf); + if (myself->uid == ILLEGAL_UID + && (searchentry = !internal_getpwsid (tu))) + default_uid = DEFAULT_UID_NT; } - + if (searchentry && + (!(pw = search_for (0, cygheap->user.name ())) || + (myself->uid != ILLEGAL_UID && + myself->uid != (__uid32_t) pw->pw_uid && + !search_for (myself->uid, NULL)))) + { + snprintf (linebuf, sizeof (linebuf), "%s:*:%lu:%lu:,%s:%s:/bin/sh", + cygheap->user.name (), + myself->uid == ILLEGAL_UID ? default_uid : myself->uid, + myself->gid, + strbuf, getenv ("HOME") ?: "/"); + debug_printf ("Completing /etc/passwd: %s", linebuf); + add_pwd_line (linebuf); + } + passwd_state = loaded; } - return; } -/* 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 * +internal_getpwsid (cygsid &sid) { - struct passwd *res = 0; - struct passwd *default_pw = 0; + struct passwd *pw; + char *ptr1, *ptr2, *endptr; + char sid_string[128] = {0,','}; - for (int i = 0; i < curr_lines; i++) + if (curr_lines < 0 && passwd_state <= initializing) + read_etc_passwd (); + + if (sid.string (sid_string + 2)) { - res = passwd_buf + i; - if (res->pw_uid == DEFAULT_UID) - default_pw = res; - /* 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; + endptr = strchr (sid_string + 2, 0) - 1; + for (int i = 0; i < curr_lines; i++) + if ((pw = passwd_buf + i)->pw_dir > pw->pw_gecos + 8) + for (ptr1 = endptr, ptr2 = pw->pw_dir - 2; + *ptr1 == *ptr2; ptr2--) + if (!*--ptr1) + return pw; } - - /* Return default passwd entry if passwd is emulated or it's a - request for the current user. */ - if (passwd_state != loaded - || (!name && uid == myself->uid) - || (name && strcasematch (name, cygheap->user.name ()))) - return default_pw; - return NULL; } @@ -399,6 +399,7 @@ setpassent () return 0; } +#if 0 /* Unused */ /* Internal function. ONLY USE THIS INTERNALLY, NEVER `getpwent'!!! */ struct passwd * internal_getpwent (int pos) @@ -410,6 +411,7 @@ internal_getpwent (int pos) return passwd_buf + pos; return NULL; } +#endif extern "C" char * getpass (const char * prompt) |