This is the mail archive of the
cygwin-patches@cygwin.com
mailing list for the Cygwin project.
Re: ntsec patch #4: passwd and group
- From: "Pierre A. Humblet" <Pierre dot Humblet at ieee dot org>
- To: cygwin-patches at cygwin dot com
- Date: Fri, 15 Nov 2002 09:52:52 -0500
- Subject: Re: ntsec patch #4: passwd and group
- References: <20021108171918.P21920@cygbert.vinschen.de> <3DCBEFF5.850B999E@ieee.org> <20021111145612.T10395@cygbert.vinschen.de> <3DCFC6BB.570DF472@ieee.org> <20021111174720.X10395@cygbert.vinschen.de> <3DCFE314.3B5B45AB@ieee.org> <20021111183423.A10395@cygbert.vinschen.de> <3DCFF8AE.66CBD751@ieee.org> <20021112144038.F10395@cygbert.vinschen.de> <3DD13433.D618DC4F@ieee.org> <20021112181849.K10395@cygbert.vinschen.de>
Corinna,
Here is the ntsec patch #4 diff. As discussed before, the main motivation
was to handle more robustly incomplete passwd and group files.
In the process I fixed some bugs in related code and added
getpwsid and getgrsid.
This does not try to completely address the issue of invalid pointers
after a re-read of passwd and group, that will be for later.
Note that there is a small bug fix in the getgroup32 code from
yesterday and some streamlining in is_grp_member.
Pierre
2002/11/15 Pierre Humblet <pierre.humblet@ieee.org>
* security.h: Declare getpwsid and getgrsid. Undeclare
internal_getpwent. Define DEFAULT_UID_NT. Change DEFAULT_GID.
* passwd.cc (getpwsid): Create.
(internal_getpwent): Suppress.
(read_etc_passwd): Make static. Rewrite the code for the completion
line. Reset curr_lines.
(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 reset
curr_lines. Always call add_pwd_line. Rewrite the code for the
completion line.
(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.
(getgroups32): Never close the impersonation token handle.
* 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
of /etc/passwd. Change some debug_printf.
--- security.h.orig 2002-11-12 22:07:16.000000000 -0500
+++ security.h 2002-11-12 22:15:54.000000000 -0500
@@ -11,7 +11,8 @@ details. */
#include <accctrl.h>
#define DEFAULT_UID DOMAIN_USER_RID_ADMIN
-#define DEFAULT_GID DOMAIN_ALIAS_RID_ADMINS
+#define DEFAULT_UID_NT 400 /* Non conflicting number */
+#define DEFAULT_GID 401
#define MAX_SID_LEN 40
#define MAX_DACL_LEN(n) (sizeof (ACL) \
@@ -208,6 +209,8 @@ extern BOOL allow_smbntsec;
I didn't find a better place to declare them. */
extern struct passwd *internal_getpwent (int);
extern struct __group32 *internal_getgrent (int);
+extern struct passwd *getpwsid (cygsid &, BOOL = FALSE);
+extern struct __group32 *getgrsid (cygsid &, BOOL = FALSE);
/* File manipulation */
int __stdcall set_process_privileges ();
--- passwd.cc.orig 2002-10-24 01:08:58.000000000 -0400
+++ passwd.cc 2002-11-14 21:31:22.000000000 -0500
@@ -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];
- 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;
- }
+ static char linebuf[1024];
+ char strbuf[128] = "";
+ BOOL searchentry = TRUE;
+ __uid32_t default_uid = DEFAULT_UID;
+ struct passwd *pw;
+
+ if (wincap.has_security ())
+ {
+ cygsid tu = cygheap->user.sid ();
+ tu.string (strbuf);
+ if (myself->uid == ILLEGAL_UID &&
+ (searchentry = !getpwsid (tu, TRUE)))
+ 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:*:%u:%u:,%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 *
+getpwsid (cygsid &sid, BOOL no_check)
{
- 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 (!no_check && 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)
--- grp.cc.orig 2002-11-14 17:41:00.000000000 -0500
+++ grp.cc 2002-11-14 18:18:56.000000000 -0500
@@ -41,6 +41,7 @@ static int grp_pos = 0;
#endif
static pwdgrp_check group_state;
+static char * NO_COPY null_ptr = NULL;
static int
parse_grp (struct __group32 &grp, char *line)
@@ -62,13 +63,11 @@ parse_grp (struct __group32 &grp, char *
if (dp)
{
*dp++ = '\0';
- if (!strlen (grp.gr_passwd))
- grp.gr_passwd = NULL;
-
grp.gr_gid = strtol (dp, NULL, 10);
dp = strchr (dp, ':');
if (dp)
{
+ grp.gr_mem = &null_ptr;
if (*++dp)
{
int i = 0;
@@ -87,11 +86,9 @@ parse_grp (struct __group32 &grp, char *
}
namearray[i++] = dp;
namearray[i] = NULL;
+ grp.gr_mem = namearray;
}
- grp.gr_mem = namearray;
}
- else
- grp.gr_mem = (char **) calloc (1, sizeof (char *));
return 1;
}
}
@@ -134,9 +131,7 @@ pthread_mutex_t NO_COPY group_lock::mute
/* Read in /etc/group and save contents in the group cache */
/* This sets group_in_memory_p to 1 so functions in this file can
tell that /etc/group has been read in */
-/* FIXME: should be static but this is called in uinfo_init outside this
- file */
-void
+static void
read_etc_group ()
{
static pwdgrp_read gr;
@@ -150,76 +145,74 @@ read_etc_group ()
if (group_state != initializing)
{
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);
+
+ curr_lines = 0;
if (gr.open ("/etc/group"))
{
char *line;
while ((line = gr.gets ()) != NULL)
- if (strlen (line))
- add_grp_line (line);
+ add_grp_line (line);
group_state.set_last_modified (gr.get_fhandle (), gr.get_fname ());
- group_state = loaded;
gr.close ();
debug_printf ("Read /etc/group, %d lines", curr_lines);
}
- else /* /etc/group doesn't exist -- create default one in memory */
- {
- char group_name [UNLEN + 1];
- DWORD group_name_len = UNLEN + 1;
- char domain_name [INTERNET_MAX_HOST_NAME_LENGTH + 1];
- DWORD domain_name_len = INTERNET_MAX_HOST_NAME_LENGTH + 1;
- SID_NAME_USE acType;
+
+ /* Complete /etc/group in memory if needed */
+ if (!getgrgid32 (myself->gid))
+ {
static char linebuf [200];
+ char group_name [UNLEN + 1] = "unknown";
+ char strbuf[128] = "";
if (wincap.has_security ())
- {
- HANDLE ptok;
- cygsid tg;
- DWORD siz;
-
- if (OpenProcessToken (hMainProc, TOKEN_QUERY, &ptok))
- {
- if (GetTokenInformation (ptok, TokenPrimaryGroup, &tg,
- sizeof tg, &siz)
- && LookupAccountSidA (NULL, tg, group_name,
- &group_name_len, domain_name,
- &domain_name_len, &acType))
- {
- char strbuf[100];
- snprintf (linebuf, sizeof (linebuf), "%s:%s:%lu:",
- group_name,
- tg.string (strbuf),
- *GetSidSubAuthority (tg,
- *GetSidSubAuthorityCount (tg) - 1));
- debug_printf ("Emulating /etc/group: %s", linebuf);
- add_grp_line (linebuf);
- group_state = emulated;
- }
- CloseHandle (ptok);
- }
- }
- if (group_state != emulated)
- {
- strncpy (group_name, "Administrators", sizeof (group_name));
- if (!LookupAccountSidA (NULL, well_known_admins_sid, group_name,
- &group_name_len, domain_name,
- &domain_name_len, &acType))
- {
- strcpy (group_name, "unknown");
- debug_printf ("Failed to get local admins group name. %E");
+ {
+ DWORD group_name_len = UNLEN + 1;
+ char domain_name [INTERNET_MAX_HOST_NAME_LENGTH + 1];
+ DWORD domain_name_len = INTERNET_MAX_HOST_NAME_LENGTH + 1;
+ SID_NAME_USE acType;
+ struct __group32 *gr;
+
+ cygheap->user.groups.pgsid.string (strbuf);
+ if (!(gr = getgrsid (cygheap->user.groups.pgsid)))
+ {
+ if (!LookupAccountSidA (NULL, cygheap->user.groups.pgsid,
+ group_name, &group_name_len,
+ domain_name, &domain_name_len,
+ &acType))
+ debug_printf ("Failed to get primary group name. %E");
}
- snprintf (linebuf, sizeof (linebuf), "%s::%u:", group_name,
- (unsigned) DEFAULT_GID);
- debug_printf ("Emulating /etc/group: %s", linebuf);
- add_grp_line (linebuf);
- group_state = emulated;
+ else
+ strlcpy (group_name, gr->gr_name, sizeof (group_name));
}
+ snprintf (linebuf, sizeof (linebuf), "%s:%s:%lu:%s",
+ group_name, strbuf, myself->gid, cygheap->user.name ());
+ debug_printf ("Completing /etc/group: %s", linebuf);
+ add_grp_line (linebuf);
}
+ group_state = loaded;
}
-
return;
}
+struct __group32 *
+getgrsid (cygsid &sid, BOOL no_check)
+{
+ char sid_string[128];
+
+ if (!no_check && group_state <= initializing)
+ 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))
+ return group_buf + i;
+ return NULL;
+}
+
static
struct __group16 *
grp32togrp16 (struct __group16 *gp16, struct __group32 *gp32)
@@ -246,13 +239,12 @@ getgrgid32 (__gid32_t gid)
for (int i = 0; i < curr_lines; i++)
{
- if (group_buf[i].gr_gid == DEFAULT_GID)
+ 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 ? NULL : default_grp;
+ return (!allow_ntsec && gid == ILLEGAL_GID)?default_grp:NULL;
}
extern "C" struct __group16 *
@@ -372,7 +364,8 @@ getgroups32 (int gidsetsize, __gid32_t *
++cnt;
if (gidsetsize && cnt > gidsetsize)
{
- CloseHandle (hToken);
+ if (hToken != cygheap->user.token)
+ CloseHandle (hToken);
goto error;
}
break;
@@ -481,13 +474,9 @@ setgroups32 (int ngroups, const __gid32_
for (int gidy = 0; gidy < gidx; gidy++)
if (grouplist[gidy] == grouplist[gidx])
goto found; /* Duplicate */
- for (int gidy = 0; (gr = internal_getgrent (gidy)); ++gidy)
- if (gr->gr_gid == (__gid32_t) grouplist[gidx])
- {
- if (gsids.addfromgr (gr))
- goto found;
- break;
- }
+ if ((gr = getgrgid32 (grouplist[gidx])) &&
+ gsids.addfromgr (gr))
+ goto found;
debug_printf ("No sid found for gid %d", grouplist[gidx]);
gsids.free_sids ();
set_errno (EINVAL);
--- sec_helper.cc.orig 2002-11-14 17:41:00.000000000 -0500
+++ sec_helper.cc 2002-11-14 19:18:42.000000000 -0500
@@ -118,21 +118,20 @@ BOOL
cygsid::getfrompw (const struct passwd *pw)
{
char *sp = (pw && pw->pw_gecos) ? strrchr (pw->pw_gecos, ',') : NULL;
- return (*this = sp ? sp + 1 : "") != NULL;
+ return (*this = sp ? sp + 1 : sp) != NULL;
}
BOOL
cygsid::getfromgr (const struct __group32 *gr)
{
char *sp = (gr && gr->gr_passwd) ? gr->gr_passwd : NULL;
- return (*this = sp ?: "") != NULL;
+ return (*this = sp) != NULL;
}
__uid32_t
cygsid::get_id (BOOL search_grp, int *type)
{
/* First try to get SID from passwd or group entry */
- cygsid sid;
__uid32_t id = ILLEGAL_UID;
if (!search_grp)
@@ -140,42 +139,25 @@ cygsid::get_id (BOOL search_grp, int *ty
struct passwd *pw;
if (*this == cygheap->user.sid ())
id = myself->uid;
- else
- for (int pidx = 0; (pw = internal_getpwent (pidx)); ++pidx)
- {
- if (sid.getfrompw (pw) && sid == psid)
- {
- id = pw->pw_uid;
- break;
- }
- }
+ else if ((pw = getpwsid (*this, TRUE)))
+ 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
- for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
- {
- if (sid.getfromgr (gr) && sid == psid)
- {
- id = gr->gr_gid;
- break;
- }
- }
- if (id != ILLEGAL_UID)
- {
- if (type)
- *type = GROUP;
- }
- }
+ else if ((gr = getgrsid (*this, TRUE)))
+ id = gr->gr_gid;
+ if (id != ILLEGAL_UID && type)
+ *type = GROUP;
+ }
return id;
}
@@ -208,24 +190,17 @@ is_grp_member (__uid32_t uid, __gid32_t
}
/* Otherwise try getting info from examining passwd and group files. */
- for (int idx = 0; (pw = internal_getpwent (idx)); ++idx)
- if ((__uid32_t) pw->pw_uid == 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. */
- for (idx = 0; (gr = internal_getgrent (idx)); ++idx)
- if ((__gid32_t) gr->gr_gid == gid)
- {
- if (gr->gr_mem)
- for (idx = 0; gr->gr_mem[idx]; ++idx)
- if (strcasematch (cygheap->user.name (), gr->gr_mem[idx]))
- return TRUE;
- return FALSE;
- }
- return FALSE;
- }
+ if ((pw = getpwuid32 (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)
+ for (idx = 0; gr->gr_mem[idx]; ++idx)
+ if (strcasematch (cygheap->user.name (), gr->gr_mem[idx]))
+ return TRUE;
+ }
return FALSE;
}
--- uinfo.cc.orig 2002-11-02 11:51:30.000000000 -0500
+++ uinfo.cc 2002-11-04 21:00:14.000000000 -0500
@@ -34,10 +34,11 @@ void
internal_getlogin (cygheap_user &user)
{
struct passwd *pw = NULL;
+ HANDLE ptok = INVALID_HANDLE_VALUE;
+ myself->gid = DEFAULT_GID;
if (wincap.has_security ())
{
- HANDLE ptok = INVALID_HANDLE_VALUE;
DWORD siz;
cygsid tu;
DWORD ret = 0;
@@ -58,52 +59,39 @@ internal_getlogin (cygheap_user &user)
If we have a SID, try to get the corresponding Cygwin
password entry. Set user name which can be different
from the Windows user name */
- if (ret)
- {
- cygsid gsid (NO_SID);
- cygsid psid;
-
- for (int pidx = 0; (pw = internal_getpwent (pidx)); ++pidx)
- if (psid.getfrompw (pw) && EqualSid (user.sid (), psid))
- {
- user.set_name (pw->pw_name);
- struct __group32 *gr = getgrgid32 (pw->pw_gid);
- if (gr)
- if (!gsid.getfromgr (gr))
- gsid = NO_SID;
- break;
- }
-
- /* Set token owner to the same value as token user and
- primary group to the group in /etc/passwd. */
+ if (ret)
+ {
+ if ((pw = getpwsid (tu)))
+ user.set_name (pw->pw_name);
+ /* Set token owner to the same value as token user */
if (!SetTokenInformation (ptok, TokenOwner, &tu, sizeof tu))
debug_printf ("SetTokenInformation(TokenOwner): %E");
- if (gsid)
- {
- user.groups.pgsid = gsid;
- if (!SetTokenInformation (ptok, TokenPrimaryGroup,
- &gsid, sizeof gsid))
- debug_printf ("SetTokenInformation(TokenPrimaryGroup): %E");
- }
}
- if (ptok != INVALID_HANDLE_VALUE)
- CloseHandle (ptok);
}
- if (!pw)
- pw = getpwnam (user.name ());
-
- if (pw)
+ if (!pw && !(pw = getpwnam (user.name ())))
+ debug_printf("user name not found in augmented /etc/passwd");
+ else
{
myself->uid = pw->pw_uid;
myself->gid = pw->pw_gid;
+ if (wincap.has_security ())
+ {
+ cygsid gsid;
+ if (gsid.getfromgr (getgrgid32 (pw->pw_gid)))
+ {
+ /* Set primary group to the group in /etc/passwd. */
+ user.groups.pgsid = gsid;
+ if (!SetTokenInformation (ptok, TokenPrimaryGroup,
+ &gsid, sizeof gsid))
+ debug_printf ("SetTokenInformation(TokenPrimaryGroup): %E");
+ }
+ else
+ debug_printf ("gsid not found in augmented /etc/group");
+ }
}
- else
- {
- myself->uid = DEFAULT_UID;
- myself->gid = DEFAULT_GID;
- }
-
+ if (ptok != INVALID_HANDLE_VALUE)
+ CloseHandle (ptok);
(void) cygheap->user.ontherange (CH_HOME, pw);
return;