* 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.
This commit is contained in:
Corinna Vinschen 2002-11-20 17:10:05 +00:00
parent 3a366b12f6
commit 647b92a7d4
6 changed files with 205 additions and 234 deletions

View File

@ -1,3 +1,31 @@
2002-11-20 Pierre Humblet <pierre.humblet@ieee.org>
* 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.
2002-11-20 Steven O'Brien <steven.obrien2@ntlworld.com> 2002-11-20 Steven O'Brien <steven.obrien2@ntlworld.com>
* poll.cc (poll): ...but set POLLIN instead. * poll.cc (poll): ...but set POLLIN instead.

View File

@ -30,7 +30,7 @@ details. */
on the first call that needs information from it. */ on the first call that needs information from it. */
static struct __group32 *group_buf; /* group contents in memory */ static struct __group32 *group_buf; /* group contents in memory */
static int curr_lines; static int curr_lines = -1;
static int max_lines; static int max_lines;
/* Position in the group cache */ /* Position in the group cache */
@ -41,6 +41,7 @@ static int grp_pos = 0;
#endif #endif
static pwdgrp_check group_state; static pwdgrp_check group_state;
static char * NO_COPY null_ptr = NULL;
static int static int
parse_grp (struct __group32 &grp, char *line) parse_grp (struct __group32 &grp, char *line)
@ -62,13 +63,11 @@ parse_grp (struct __group32 &grp, char *line)
if (dp) if (dp)
{ {
*dp++ = '\0'; *dp++ = '\0';
if (!strlen (grp.gr_passwd))
grp.gr_passwd = NULL;
grp.gr_gid = strtol (dp, NULL, 10); grp.gr_gid = strtol (dp, NULL, 10);
dp = strchr (dp, ':'); dp = strchr (dp, ':');
if (dp) if (dp)
{ {
grp.gr_mem = &null_ptr;
if (*++dp) if (*++dp)
{ {
int i = 0; int i = 0;
@ -87,11 +86,9 @@ parse_grp (struct __group32 &grp, char *line)
} }
namearray[i++] = dp; namearray[i++] = dp;
namearray[i] = NULL; namearray[i] = NULL;
}
grp.gr_mem = namearray; grp.gr_mem = namearray;
} }
else }
grp.gr_mem = (char **) calloc (1, sizeof (char *));
return 1; return 1;
} }
} }
@ -134,9 +131,7 @@ pthread_mutex_t NO_COPY group_lock::mutex = (pthread_mutex_t) PTHREAD_MUTEX_INIT
/* Read in /etc/group and save contents in the group cache */ /* 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 /* This sets group_in_memory_p to 1 so functions in this file can
tell that /etc/group has been read in */ tell that /etc/group has been read in */
/* FIXME: should be static but this is called in uinfo_init outside this static void
file */
void
read_etc_group () read_etc_group ()
{ {
static pwdgrp_read gr; static pwdgrp_read gr;
@ -150,76 +145,62 @@ read_etc_group ()
if (group_state != initializing) if (group_state != initializing)
{ {
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")) if (gr.open ("/etc/group"))
{ {
char *line; char *line;
while ((line = gr.gets ()) != NULL) 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.set_last_modified (gr.get_fhandle (), gr.get_fname ());
group_state = loaded;
gr.close (); gr.close ();
debug_printf ("Read /etc/group, %d lines", curr_lines); debug_printf ("Read /etc/group, %d lines", curr_lines);
} }
else /* /etc/group doesn't exist -- create default one in memory */
/* Complete /etc/group in memory if needed */
if (!getgrgid32 (myself->gid))
{ {
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;
static char linebuf [200]; static char linebuf [200];
char group_name [UNLEN + 1] = "unknown";
char strbuf[128] = "";
if (wincap.has_security ()) if (wincap.has_security ())
{ {
HANDLE ptok; struct __group32 *gr;
cygsid tg;
DWORD siz;
if (OpenProcessToken (hMainProc, TOKEN_QUERY, &ptok)) cygheap->user.groups.pgsid.string (strbuf);
{ if ((gr = internal_getgrsid (cygheap->user.groups.pgsid)))
if (GetTokenInformation (ptok, TokenPrimaryGroup, &tg, strlcpy (group_name, gr->gr_name, sizeof (group_name));
sizeof tg, &siz) }
&& LookupAccountSidA (NULL, tg, group_name, snprintf (linebuf, sizeof (linebuf), "%s:%s:%lu:%s",
&group_name_len, domain_name, group_name, strbuf, myself->gid, cygheap->user.name ());
&domain_name_len, &acType)) debug_printf ("Completing /etc/group: %s", linebuf);
{
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); add_grp_line (linebuf);
group_state = emulated;
} }
CloseHandle (ptok); group_state = loaded;
} }
}
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");
}
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;
}
}
}
return; return;
} }
struct __group32 *
internal_getgrsid (cygsid &sid)
{
char sid_string[128];
if (curr_lines < 0 && 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 static
struct __group16 * struct __group16 *
grp32togrp16 (struct __group16 *gp16, struct __group32 *gp32) grp32togrp16 (struct __group16 *gp16, struct __group32 *gp32)
@ -246,13 +227,12 @@ getgrgid32 (__gid32_t gid)
for (int i = 0; i < curr_lines; i++) 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; default_grp = group_buf + i;
if (group_buf[i].gr_gid == gid) if (group_buf[i].gr_gid == gid)
return group_buf + i; return group_buf + i;
} }
return allow_ntsec || gid != ILLEGAL_GID ? NULL : default_grp;
return allow_ntsec ? NULL : default_grp;
} }
extern "C" struct __group16 * extern "C" struct __group16 *
@ -482,13 +462,9 @@ setgroups32 (int ngroups, const __gid32_t *grouplist)
for (int gidy = 0; gidy < gidx; gidy++) for (int gidy = 0; gidy < gidx; gidy++)
if (grouplist[gidy] == grouplist[gidx]) if (grouplist[gidy] == grouplist[gidx])
goto found; /* Duplicate */ goto found; /* Duplicate */
for (int gidy = 0; (gr = internal_getgrent (gidy)); ++gidy) if ((gr = getgrgid32 (grouplist[gidx])) &&
if (gr->gr_gid == (__gid32_t) grouplist[gidx]) gsids.addfromgr (gr))
{
if (gsids.addfromgr (gr))
goto found; goto found;
break;
}
debug_printf ("No sid found for gid %d", grouplist[gidx]); debug_printf ("No sid found for gid %d", grouplist[gidx]);
gsids.free_sids (); gsids.free_sids ();
set_errno (EINVAL); set_errno (EINVAL);

View File

@ -27,7 +27,7 @@ details. */
on the first call that needs information from it. */ on the first call that needs information from it. */
static struct passwd *passwd_buf; /* passwd contents in memory */ static struct passwd *passwd_buf; /* passwd contents in memory */
static int curr_lines; static int curr_lines = -1;
static int max_lines; static int max_lines;
static pwdgrp_check passwd_state; static pwdgrp_check passwd_state;
@ -74,7 +74,7 @@ grab_int (char **p)
} }
/* Parse /etc/passwd line into passwd structure. */ /* Parse /etc/passwd line into passwd structure. */
void static int
parse_pwd (struct passwd &res, char *buf) parse_pwd (struct passwd &res, char *buf)
{ {
/* Allocate enough room for the passwd struct and all the strings /* 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); size_t len = strlen (buf);
if (buf[--len] == '\r') if (buf[--len] == '\r')
buf[len] = '\0'; buf[len] = '\0';
if (len < 6)
return 0;
res.pw_name = grab_string (&buf); res.pw_name = grab_string (&buf);
res.pw_passwd = 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_gecos = grab_string (&buf);
res.pw_dir = grab_string (&buf); res.pw_dir = grab_string (&buf);
res.pw_shell = grab_string (&buf); res.pw_shell = grab_string (&buf);
return 1;
} }
/* Add one line from /etc/passwd into the password cache */ /* Add one line from /etc/passwd into the password cache */
@ -102,7 +105,8 @@ add_pwd_line (char *line)
max_lines += 10; max_lines += 10;
passwd_buf = (struct passwd *) realloc (passwd_buf, max_lines * sizeof (struct passwd)); 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 class passwd_lock
@ -125,10 +129,32 @@ class passwd_lock
pthread_mutex_t NO_COPY passwd_lock::mutex = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER; 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. /* 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 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. */ tell that /etc/passwd has been read in or will be emulated. */
void static void
read_etc_passwd () read_etc_passwd ()
{ {
static pwdgrp_read pr; static pwdgrp_read pr;
@ -146,97 +172,71 @@ read_etc_passwd ()
if (passwd_state != initializing) if (passwd_state != initializing)
{ {
passwd_state = initializing; passwd_state = initializing;
curr_lines = 0;
if (pr.open ("/etc/passwd")) if (pr.open ("/etc/passwd"))
{ {
char *line; char *line;
while ((line = pr.gets ()) != NULL) 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.set_last_modified (pr.get_fhandle (), pr.get_fname ());
passwd_state = loaded;
pr.close (); pr.close ();
debug_printf ("Read /etc/passwd, %d lines", curr_lines); debug_printf ("Read /etc/passwd, %d lines", curr_lines);
} }
else
{
static char linebuf[1024]; static char linebuf[1024];
char strbuf[128] = "";
BOOL searchentry = TRUE;
__uid32_t default_uid = DEFAULT_UID;
struct passwd *pw;
if (wincap.has_security ()) if (wincap.has_security ())
{ {
HANDLE ptok; cygsid tu = cygheap->user.sid ();
cygsid tu, tg; tu.string (strbuf);
DWORD siz; if (myself->uid == ILLEGAL_UID
&& (searchentry = !internal_getpwsid (tu)))
if (OpenProcessToken (hMainProc, TOKEN_QUERY, &ptok)) 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))))
{ {
if (GetTokenInformation (ptok, TokenUser, &tu, sizeof tu, snprintf (linebuf, sizeof (linebuf), "%s:*:%lu:%lu:,%s:%s:/bin/sh",
&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 (), cygheap->user.name (),
*GetSidSubAuthority (tu, myself->uid == ILLEGAL_UID ? default_uid : myself->uid,
*GetSidSubAuthorityCount(tu) - 1), myself->gid,
*GetSidSubAuthority (tg, strbuf, getenv ("HOME") ?: "/");
*GetSidSubAuthorityCount(tg) - 1), debug_printf ("Completing /etc/passwd: %s", linebuf);
tu.string (strbuf), getenv ("HOME") ?: "/");
debug_printf ("Emulating /etc/passwd: %s", linebuf);
add_pwd_line (linebuf); add_pwd_line (linebuf);
passwd_state = emulated;
} }
CloseHandle (ptok); passwd_state = loaded;
} }
}
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;
}
}
}
return; return;
} }
/* Cygwin internal */ struct passwd *
/* If this ever becomes non-reentrant, update all the getpw*_r functions */ internal_getpwsid (cygsid &sid)
static struct passwd *
search_for (__uid32_t uid, const char *name)
{ {
struct passwd *res = 0; struct passwd *pw;
struct passwd *default_pw = 0; char *ptr1, *ptr2, *endptr;
char sid_string[128] = {0,','};
if (curr_lines < 0 && passwd_state <= initializing)
read_etc_passwd ();
if (sid.string (sid_string + 2))
{
endptr = strchr (sid_string + 2, 0) - 1;
for (int i = 0; i < curr_lines; i++) for (int i = 0; i < curr_lines; i++)
{ if ((pw = passwd_buf + i)->pw_dir > pw->pw_gecos + 8)
res = passwd_buf + i; for (ptr1 = endptr, ptr2 = pw->pw_dir - 2;
if (res->pw_uid == DEFAULT_UID) *ptr1 == *ptr2; ptr2--)
default_pw = res; if (!*--ptr1)
/* on Windows NT user names are case-insensitive */ return pw;
if (name)
{
if (strcasematch (name, res->pw_name))
return res;
} }
else if (uid == (__uid32_t) res->pw_uid)
return res;
}
/* 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; return NULL;
} }
@ -399,6 +399,7 @@ setpassent ()
return 0; return 0;
} }
#if 0 /* Unused */
/* Internal function. ONLY USE THIS INTERNALLY, NEVER `getpwent'!!! */ /* Internal function. ONLY USE THIS INTERNALLY, NEVER `getpwent'!!! */
struct passwd * struct passwd *
internal_getpwent (int pos) internal_getpwent (int pos)
@ -410,6 +411,7 @@ internal_getpwent (int pos)
return passwd_buf + pos; return passwd_buf + pos;
return NULL; return NULL;
} }
#endif
extern "C" char * extern "C" char *
getpass (const char * prompt) getpass (const char * prompt)

View File

@ -118,21 +118,20 @@ BOOL
cygsid::getfrompw (const struct passwd *pw) cygsid::getfrompw (const struct passwd *pw)
{ {
char *sp = (pw && pw->pw_gecos) ? strrchr (pw->pw_gecos, ',') : NULL; 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 BOOL
cygsid::getfromgr (const struct __group32 *gr) cygsid::getfromgr (const struct __group32 *gr)
{ {
char *sp = (gr && gr->gr_passwd) ? gr->gr_passwd : NULL; char *sp = (gr && gr->gr_passwd) ? gr->gr_passwd : NULL;
return (*this = sp ?: "") != NULL; return (*this = sp) != NULL;
} }
__uid32_t __uid32_t
cygsid::get_id (BOOL search_grp, int *type) cygsid::get_id (BOOL search_grp, int *type)
{ {
/* First try to get SID from passwd or group entry */ /* First try to get SID from passwd or group entry */
cygsid sid;
__uid32_t id = ILLEGAL_UID; __uid32_t id = ILLEGAL_UID;
if (!search_grp) if (!search_grp)
@ -140,15 +139,8 @@ cygsid::get_id (BOOL search_grp, int *type)
struct passwd *pw; struct passwd *pw;
if (*this == cygheap->user.sid ()) if (*this == cygheap->user.sid ())
id = myself->uid; id = myself->uid;
else else if ((pw = internal_getpwsid (*this)))
for (int pidx = 0; (pw = internal_getpwent (pidx)); ++pidx)
{
if (sid.getfrompw (pw) && sid == psid)
{
id = pw->pw_uid; id = pw->pw_uid;
break;
}
}
if (id != ILLEGAL_UID) if (id != ILLEGAL_UID)
{ {
if (type) if (type)
@ -161,21 +153,11 @@ cygsid::get_id (BOOL search_grp, int *type)
struct __group32 *gr; struct __group32 *gr;
if (cygheap->user.groups.pgsid == psid) if (cygheap->user.groups.pgsid == psid)
id = myself->gid; id = myself->gid;
else else if ((gr = internal_getgrsid (*this)))
for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
{
if (sid.getfromgr (gr) && sid == psid)
{
id = gr->gr_gid; id = gr->gr_gid;
break; if (id != ILLEGAL_UID && type)
}
}
if (id != ILLEGAL_UID)
{
if (type)
*type = GROUP; *type = GROUP;
} }
}
return id; return id;
} }
@ -208,23 +190,16 @@ is_grp_member (__uid32_t uid, __gid32_t gid)
} }
/* Otherwise try getting info from examining passwd and group files. */ /* Otherwise try getting info from examining passwd and group files. */
for (int idx = 0; (pw = internal_getpwent (idx)); ++idx) if ((pw = getpwuid32 (uid)))
if ((__uid32_t) pw->pw_uid == uid)
{ {
/* If gid == primary group of uid, return immediately. */ /* If gid == primary group of uid, return immediately. */
if ((__gid32_t) pw->pw_gid == gid) if ((__gid32_t) pw->pw_gid == gid)
return TRUE; return TRUE;
/* Otherwise search for supplementary user list of this group. */ /* Otherwise search for supplementary user list of this group. */
for (idx = 0; (gr = internal_getgrent (idx)); ++idx) if ((gr = getgrgid32 (gid)) && gr->gr_mem)
if ((__gid32_t) gr->gr_gid == gid)
{
if (gr->gr_mem)
for (idx = 0; gr->gr_mem[idx]; ++idx) for (idx = 0; gr->gr_mem[idx]; ++idx)
if (strcasematch (cygheap->user.name (), gr->gr_mem[idx])) if (strcasematch (cygheap->user.name (), gr->gr_mem[idx]))
return TRUE; return TRUE;
return FALSE;
}
return FALSE;
} }
return FALSE; return FALSE;
} }

View File

@ -11,7 +11,8 @@ details. */
#include <accctrl.h> #include <accctrl.h>
#define DEFAULT_UID DOMAIN_USER_RID_ADMIN #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_SID_LEN 40
#define MAX_DACL_LEN(n) (sizeof (ACL) \ #define MAX_DACL_LEN(n) (sizeof (ACL) \
@ -203,11 +204,12 @@ extern BOOL allow_ntea;
extern BOOL allow_ntsec; extern BOOL allow_ntsec;
extern BOOL allow_smbntsec; extern BOOL allow_smbntsec;
/* These both functions are needed to allow walking through the passwd /* These functions are needed to allow walking through the passwd
and group lists so they are somehow security related. Besides that and group lists so they are somehow security related. Besides that
I didn't find a better place to declare them. */ I didn't find a better place to declare them. */
extern struct passwd *internal_getpwent (int);
extern struct __group32 *internal_getgrent (int); extern struct __group32 *internal_getgrent (int);
extern struct passwd *internal_getpwsid (cygsid &);
extern struct __group32 *internal_getgrsid (cygsid &);
/* File manipulation */ /* File manipulation */
int __stdcall set_process_privileges (); int __stdcall set_process_privileges ();

View File

@ -34,10 +34,11 @@ void
internal_getlogin (cygheap_user &user) internal_getlogin (cygheap_user &user)
{ {
struct passwd *pw = NULL; struct passwd *pw = NULL;
HANDLE ptok = INVALID_HANDLE_VALUE;
myself->gid = DEFAULT_GID;
if (wincap.has_security ()) if (wincap.has_security ())
{ {
HANDLE ptok = INVALID_HANDLE_VALUE;
DWORD siz; DWORD siz;
cygsid tu; cygsid tu;
DWORD ret = 0; DWORD ret = 0;
@ -60,50 +61,37 @@ internal_getlogin (cygheap_user &user)
from the Windows user name */ from the Windows user name */
if (ret) if (ret)
{ {
cygsid gsid (NO_SID); if ((pw = internal_getpwsid (tu)))
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); user.set_name (pw->pw_name);
struct __group32 *gr = getgrgid32 (pw->pw_gid); /* Set token owner to the same value as token user */
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 (!SetTokenInformation (ptok, TokenOwner, &tu, sizeof tu)) if (!SetTokenInformation (ptok, TokenOwner, &tu, sizeof tu))
debug_printf ("SetTokenInformation(TokenOwner): %E"); debug_printf ("SetTokenInformation(TokenOwner): %E");
if (gsid) }
}
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; user.groups.pgsid = gsid;
if (!SetTokenInformation (ptok, TokenPrimaryGroup, if (!SetTokenInformation (ptok, TokenPrimaryGroup,
&gsid, sizeof gsid)) &gsid, sizeof gsid))
debug_printf ("SetTokenInformation(TokenPrimaryGroup): %E"); debug_printf ("SetTokenInformation(TokenPrimaryGroup): %E");
} }
else
debug_printf ("gsid not found in augmented /etc/group");
}
} }
if (ptok != INVALID_HANDLE_VALUE) if (ptok != INVALID_HANDLE_VALUE)
CloseHandle (ptok); CloseHandle (ptok);
}
if (!pw)
pw = getpwnam (user.name ());
if (pw)
{
myself->uid = pw->pw_uid;
myself->gid = pw->pw_gid;
}
else
{
myself->uid = DEFAULT_UID;
myself->gid = DEFAULT_GID;
}
(void) cygheap->user.ontherange (CH_HOME, pw); (void) cygheap->user.ontherange (CH_HOME, pw);
return; return;