* 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:
parent
3a366b12f6
commit
647b92a7d4
|
@ -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.
|
||||||
|
|
|
@ -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 */
|
||||||
char group_name [UNLEN + 1];
|
if (!getgrgid32 (myself->gid))
|
||||||
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,
|
|
||||||
&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");
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
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;
|
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))
|
||||||
{
|
goto found;
|
||||||
if (gsids.addfromgr (gr))
|
|
||||||
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);
|
||||||
|
|
|
@ -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];
|
||||||
|
char strbuf[128] = "";
|
||||||
|
BOOL searchentry = TRUE;
|
||||||
|
__uid32_t default_uid = DEFAULT_UID;
|
||||||
|
struct passwd *pw;
|
||||||
|
|
||||||
|
if (wincap.has_security ())
|
||||||
{
|
{
|
||||||
static char linebuf[1024];
|
cygsid tu = cygheap->user.sid ();
|
||||||
|
tu.string (strbuf);
|
||||||
if (wincap.has_security ())
|
if (myself->uid == ILLEGAL_UID
|
||||||
{
|
&& (searchentry = !internal_getpwsid (tu)))
|
||||||
HANDLE ptok;
|
default_uid = DEFAULT_UID_NT;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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;
|
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,','};
|
||||||
|
|
||||||
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;
|
endptr = strchr (sid_string + 2, 0) - 1;
|
||||||
if (res->pw_uid == DEFAULT_UID)
|
for (int i = 0; i < curr_lines; i++)
|
||||||
default_pw = res;
|
if ((pw = passwd_buf + i)->pw_dir > pw->pw_gecos + 8)
|
||||||
/* on Windows NT user names are case-insensitive */
|
for (ptr1 = endptr, ptr2 = pw->pw_dir - 2;
|
||||||
if (name)
|
*ptr1 == *ptr2; ptr2--)
|
||||||
{
|
if (!*--ptr1)
|
||||||
if (strcasematch (name, res->pw_name))
|
return pw;
|
||||||
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)
|
||||||
|
|
|
@ -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,42 +139,25 @@ 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)
|
id = pw->pw_uid;
|
||||||
{
|
|
||||||
if (sid.getfrompw (pw) && sid == psid)
|
|
||||||
{
|
|
||||||
id = pw->pw_uid;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (id != ILLEGAL_UID)
|
if (id != ILLEGAL_UID)
|
||||||
{
|
{
|
||||||
if (type)
|
if (type)
|
||||||
*type = USER;
|
*type = USER;
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (search_grp || type)
|
if (search_grp || 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)
|
id = gr->gr_gid;
|
||||||
{
|
if (id != ILLEGAL_UID && type)
|
||||||
if (sid.getfromgr (gr) && sid == psid)
|
*type = GROUP;
|
||||||
{
|
}
|
||||||
id = gr->gr_gid;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (id != ILLEGAL_UID)
|
|
||||||
{
|
|
||||||
if (type)
|
|
||||||
*type = GROUP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,24 +190,17 @@ 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. */
|
if ((gr = getgrgid32 (gid)) && gr->gr_mem)
|
||||||
for (idx = 0; (gr = internal_getgrent (idx)); ++idx)
|
for (idx = 0; gr->gr_mem[idx]; ++idx)
|
||||||
if ((__gid32_t) gr->gr_gid == gid)
|
if (strcasematch (cygheap->user.name (), gr->gr_mem[idx]))
|
||||||
{
|
return TRUE;
|
||||||
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;
|
|
||||||
}
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 ();
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -58,52 +59,39 @@ internal_getlogin (cygheap_user &user)
|
||||||
If we have a SID, try to get the corresponding Cygwin
|
If we have a SID, try to get the corresponding Cygwin
|
||||||
password entry. Set user name which can be different
|
password entry. Set user name which can be different
|
||||||
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;
|
user.set_name (pw->pw_name);
|
||||||
|
/* Set token owner to the same value as token user */
|
||||||
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 (!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
|
||||||
if (ptok != INVALID_HANDLE_VALUE)
|
debug_printf ("gsid not found in augmented /etc/group");
|
||||||
CloseHandle (ptok);
|
}
|
||||||
}
|
}
|
||||||
|
if (ptok != INVALID_HANDLE_VALUE)
|
||||||
if (!pw)
|
CloseHandle (ptok);
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue