4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-21 00:07:36 +08:00

* cygwin.din: Define symbols for `cygwin_logon_user' and

`cygwin_set_impersonation_token'.
        * dcrt0.cc (dll_crt0_1): Eliminate superfluous conditional
        statements.
        Add load statements for `ImpersonateLoggedOnUser', `LogonUserA'
        and `RevertToSelf'.
        * fork.cc (fork): Care for correct impersonation of parent
        and child process.
        * security.cc (cygwin_set_impersonation_token): New function.
        (cygwin_logon_user): Ditto.
        shared.h (class pinfo): New members `orig_uid', `orig_gid',
        `real_uid' nad `real_gid'.
        spawn.cc (spawn_guts): Care for impersonation when starting
        child process in a different user context.
        * syscalls.cc (setgid): Call `setegid' now. Set real_gid.
        (setuid): Call `seteuid' now. Set real_uid.
        (seteuid): Functionality moved from setuid to here. Care for
        correct impersonation.
        (setegid): Functionality moved from setgid to here.
        * uinfo.cc (uinfo_init): Initialization of additional pinfo
        members.
        (getuid): Return real uid.
        (getgid): Return real gid.
        (geteuid): Return effective uid.
        (getegid): Return effective gid.
        include/sys/cygwin.h: Add prototypes for `cygwin_logon_user' and
        `cygwin_set_impersonation_token'.
        include/cygwin/version.h: Bumb API minor version to 22.
This commit is contained in:
Corinna Vinschen 2000-06-16 19:36:07 +00:00
parent 3875d9e652
commit 64b3062937
11 changed files with 261 additions and 64 deletions

View File

@ -1,3 +1,34 @@
Thu Jun 16 20:55:00 2000 Corinna Vinschen <corinna@vinschen.de>
* cygwin.din: Define symbols for `cygwin_logon_user' and
`cygwin_set_impersonation_token'.
* dcrt0.cc (dll_crt0_1): Eliminate superfluous conditional
statements.
Add load statements for `ImpersonateLoggedOnUser', `LogonUserA'
and `RevertToSelf'.
* fork.cc (fork): Care for correct impersonation of parent
and child process.
* security.cc (cygwin_set_impersonation_token): New function.
(cygwin_logon_user): Ditto.
shared.h (class pinfo): New members `orig_uid', `orig_gid',
`real_uid' nad `real_gid'.
spawn.cc (spawn_guts): Care for impersonation when starting
child process in a different user context.
* syscalls.cc (setgid): Call `setegid' now. Set real_gid.
(setuid): Call `seteuid' now. Set real_uid.
(seteuid): Functionality moved from setuid to here. Care for
correct impersonation.
(setegid): Functionality moved from setgid to here.
* uinfo.cc (uinfo_init): Initialization of additional pinfo
members.
(getuid): Return real uid.
(getgid): Return real gid.
(geteuid): Return effective uid.
(getegid): Return effective gid.
include/sys/cygwin.h: Add prototypes for `cygwin_logon_user' and
`cygwin_set_impersonation_token'.
include/cygwin/version.h: Bumb API minor version to 22.
Thu Jun 15 18:12:36 2000 Christopher Faylor <cgf@cygnus.com> Thu Jun 15 18:12:36 2000 Christopher Faylor <cgf@cygnus.com>
* path.cc (chdir): Don't set cache to offending chdir. Change comment * path.cc (chdir): Don't set cache to offending chdir. Change comment

View File

@ -988,6 +988,8 @@ cygwin32_posix_to_win32_path_list = cygwin_posix_to_win32_path_list
cygwin32_split_path = cygwin_split_path cygwin32_split_path = cygwin_split_path
cygwin_winpid_to_pid cygwin_winpid_to_pid
cygwin32_winpid_to_pid = cygwin_winpid_to_pid cygwin32_winpid_to_pid = cygwin_winpid_to_pid
cygwin_logon_user
cygwin_set_impersonation_token
realpath realpath
reent_data DATA reent_data DATA
getenv getenv

View File

@ -763,10 +763,9 @@ dll_crt0_1 ()
/* Flush signals and ensure that signal thread is up and running. Can't /* Flush signals and ensure that signal thread is up and running. Can't
do this for noncygwin case since the signal thread is blocked due to do this for noncygwin case since the signal thread is blocked due to
LoadLibrary serialization. */ LoadLibrary serialization. */
if (!dynamically_loaded) sig_send (NULL, __SIGFLUSH); /* also initializes uid, gid */
sig_send (NULL, __SIGFLUSH); /* also initializes uid, gid */
if (user_data->main && !dynamically_loaded) if (user_data->main)
exit (user_data->main (argc, argv, *user_data->envptr)); exit (user_data->main (argc, argv, *user_data->envptr));
} }
@ -1157,10 +1156,12 @@ LoadDLLfunc (GetSidSubAuthority, 8, advapi32)
LoadDLLfunc (GetSidSubAuthorityCount, 4, advapi32) LoadDLLfunc (GetSidSubAuthorityCount, 4, advapi32)
LoadDLLfunc (GetTokenInformation, 20, advapi32) LoadDLLfunc (GetTokenInformation, 20, advapi32)
LoadDLLfunc (GetUserNameA, 8, advapi32) LoadDLLfunc (GetUserNameA, 8, advapi32)
LoadDLLfunc (ImpersonateLoggedOnUser, 4, advapi32)
LoadDLLfunc (InitializeAcl, 12, advapi32) LoadDLLfunc (InitializeAcl, 12, advapi32)
LoadDLLfunc (InitializeSecurityDescriptor, 8, advapi32) LoadDLLfunc (InitializeSecurityDescriptor, 8, advapi32)
LoadDLLfunc (InitializeSid, 12, advapi32) LoadDLLfunc (InitializeSid, 12, advapi32)
LoadDLLfunc (IsValidSid, 4, advapi32) LoadDLLfunc (IsValidSid, 4, advapi32)
LoadDLLfunc (LogonUserA, 24, advapi32)
LoadDLLfunc (LookupAccountNameA, 28, advapi32) LoadDLLfunc (LookupAccountNameA, 28, advapi32)
LoadDLLfunc (LookupAccountSidA, 28, advapi32) LoadDLLfunc (LookupAccountSidA, 28, advapi32)
LoadDLLfunc (LookupPrivilegeValueA, 12, advapi32) LoadDLLfunc (LookupPrivilegeValueA, 12, advapi32)
@ -1175,6 +1176,7 @@ LoadDLLfunc (RegQueryValueExA, 24, advapi32)
LoadDLLfunc (RegSetValueExA, 24, advapi32) LoadDLLfunc (RegSetValueExA, 24, advapi32)
LoadDLLfunc (RegisterEventSourceA, 8, advapi32) LoadDLLfunc (RegisterEventSourceA, 8, advapi32)
LoadDLLfunc (ReportEventA, 36, advapi32) LoadDLLfunc (ReportEventA, 36, advapi32)
LoadDLLfunc (RevertToSelf, 0, advapi32)
LoadDLLfunc (SetKernelObjectSecurity, 12, advapi32) LoadDLLfunc (SetKernelObjectSecurity, 12, advapi32)
LoadDLLfunc (SetSecurityDescriptorDacl, 16, advapi32) LoadDLLfunc (SetSecurityDescriptorDacl, 16, advapi32)
LoadDLLfunc (SetSecurityDescriptorGroup, 12, advapi32) LoadDLLfunc (SetSecurityDescriptorGroup, 12, advapi32)

View File

@ -363,10 +363,16 @@ fork ()
goto cleanup; goto cleanup;
} }
/* Remove impersonation */
uid_t uid = geteuid();
if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
seteuid (myself->orig_uid);
char sa_buf[1024];
rc = CreateProcessA (myself->progname, /* image to run */ rc = CreateProcessA (myself->progname, /* image to run */
myself->progname, /* what we send in arg0 */ myself->progname, /* what we send in arg0 */
&sec_none_nih, /* process security attrs */ allow_ntsec ? sec_user (sa_buf) : &sec_none_nih,
&sec_none_nih, /* thread security attrs */ allow_ntsec ? sec_user (sa_buf) : &sec_none_nih,
TRUE, /* inherit handles from parent */ TRUE, /* inherit handles from parent */
c_flags, c_flags,
NULL, /* environment filled in later */ NULL, /* environment filled in later */
@ -384,9 +390,16 @@ fork ()
ForceCloseHandle(subproc_ready); ForceCloseHandle(subproc_ready);
ForceCloseHandle(forker_finished); ForceCloseHandle(forker_finished);
subproc_ready = forker_finished = NULL; subproc_ready = forker_finished = NULL;
/* Restore impersonation */
if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
seteuid (uid);
return -1; return -1;
} }
/* Restore impersonation */
if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
seteuid (uid);
ProtectHandle (pi.hThread); ProtectHandle (pi.hThread);
/* Protect the handle but name it similarly to the way it will /* Protect the handle but name it similarly to the way it will
be called in subproc handling. */ be called in subproc handling. */
@ -410,6 +423,12 @@ fork ()
memcpy (child->sidbuf, myself->sidbuf, 40); memcpy (child->sidbuf, myself->sidbuf, 40);
memcpy (child->logsrv, myself->logsrv, 256); memcpy (child->logsrv, myself->logsrv, 256);
memcpy (child->domain, myself->domain, MAX_COMPUTERNAME_LENGTH+1); memcpy (child->domain, myself->domain, MAX_COMPUTERNAME_LENGTH+1);
child->token = myself->token;
child->impersonated = myself->impersonated;
child->orig_uid = myself->orig_uid;
child->orig_gid = myself->orig_gid;
child->real_uid = myself->real_uid;
child->real_gid = myself->real_gid;
set_child_mmap_ptr (child); set_child_mmap_ptr (child);
/* Wait for subproc to initialize itself. */ /* Wait for subproc to initialize itself. */
@ -494,6 +513,17 @@ fork ()
debug_printf ("self %p, pid %d, ppid %d", debug_printf ("self %p, pid %d, ppid %d",
myself, x, myself ? myself->ppid : -1); myself, x, myself ? myself->ppid : -1);
/* Restore the inheritance state as in parent
Don't call setuid here! The flags are already set. */
if (myself->impersonated)
{
debug_printf ("Impersonation of child, token: %d", myself->token);
if (myself->token == INVALID_HANDLE_VALUE)
RevertToSelf (); // probably not needed
else if (!ImpersonateLoggedOnUser (myself->token))
system_printf ("Impersonate for forked child failed: %E");
}
sync_with_parent ("after longjmp.", TRUE); sync_with_parent ("after longjmp.", TRUE);
ProtectHandle (hParent); ProtectHandle (hParent);

View File

@ -106,10 +106,15 @@ details. */
19: Export fchown, lchown, lacl 19: Export fchown, lchown, lacl
20: regsub, inet_network 20: regsub, inet_network
21: incompatible change to stdio cr/lf and buffering 21: incompatible change to stdio cr/lf and buffering
22: Export cygwin_logon_user, cygwin_set_impersonation_token.
geteuid, getegid return effective uid/gid.
getuid, getgid return real uid/gid.
seteuid, setegid set only effective uid/gid.
setuid, setgid set effective and real uid/gid.
*/ */
#define CYGWIN_VERSION_API_MAJOR 0 #define CYGWIN_VERSION_API_MAJOR 0
#define CYGWIN_VERSION_API_MINOR 21 #define CYGWIN_VERSION_API_MINOR 22
/* There is also a compatibity version number associated with the /* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible shared memory regions. It is incremented when incompatible

View File

@ -31,6 +31,9 @@ extern int cygwin_conv_to_full_posix_path (const char *, char *);
extern int cygwin_posix_path_list_p (const char *); extern int cygwin_posix_path_list_p (const char *);
extern void cygwin_split_path (const char *, char *, char *); extern void cygwin_split_path (const char *, char *, char *);
extern HANDLE cygwin_logon_user (const struct passwd *, const char *);
extern void cygwin_set_impersonation_token (const HANDLE);
#ifdef _GNU_H_WINDOWS32_BASE #ifdef _GNU_H_WINDOWS32_BASE
/* included if <windows.h> is included */ /* included if <windows.h> is included */
extern int cygwin32_attach_handle_to_fd (char *, int, HANDLE, int, int); extern int cygwin32_attach_handle_to_fd (char *, int, HANDLE, int, int);

View File

@ -374,6 +374,73 @@ got_it:
return TRUE; return TRUE;
} }
extern "C"
void
cygwin_set_impersonation_token (const HANDLE hToken)
{
debug_printf ("set_impersonation_token (%d)", hToken);
if (myself->token != hToken)
{
if (myself->token != INVALID_HANDLE_VALUE)
CloseHandle (myself->token);
myself->token = hToken;
myself->impersonated = FALSE;
}
}
extern "C"
HANDLE
cygwin_logon_user (const struct passwd *pw, const char *password)
{
if (os_being_run != winNT)
{
set_errno (ENOSYS);
return INVALID_HANDLE_VALUE;
}
if (!pw)
{
set_errno (EINVAL);
return INVALID_HANDLE_VALUE;
}
char *c, *nt_user, *nt_domain = NULL;
char usernamebuf[256];
HANDLE hToken;
strcpy (usernamebuf, pw->pw_name);
if (pw->pw_gecos)
{
if ((c = strstr (pw->pw_gecos, "U-")) != NULL &&
(c == pw->pw_gecos || c[-1] == ','))
{
usernamebuf[0] = '\0';
strncat (usernamebuf, c + 2, 255);
if ((c = strchr (usernamebuf, ',')) != NULL)
*c = '\0';
}
}
nt_user = usernamebuf;
if ((c = strchr (nt_user, '\\')) != NULL)
{
nt_domain = nt_user;
*c = '\0';
nt_user = c + 1;
}
if (! LogonUserA (nt_user, nt_domain, (char *) password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
&hToken)
|| !SetHandleInformation (hToken,
HANDLE_FLAG_INHERIT,
HANDLE_FLAG_INHERIT))
{
__seterrno ();
return INVALID_HANDLE_VALUE;
}
debug_printf ("%d = logon_user(%s,...)", hToken, pw->pw_name);
return hToken;
}
/* read_sd reads a security descriptor from a file. /* read_sd reads a security descriptor from a file.
In case of error, -1 is returned and errno is set. In case of error, -1 is returned and errno is set.
If sd_buf is too small, 0 is returned and sd_size If sd_buf is too small, 0 is returned and sd_size

View File

@ -93,6 +93,15 @@ class pinfo
char logsrv[256]; /* Logon server, may be fully qualified DNS name */ char logsrv[256]; /* Logon server, may be fully qualified DNS name */
char domain[MAX_COMPUTERNAME_LENGTH+1]; /* Logon domain of the user */ char domain[MAX_COMPUTERNAME_LENGTH+1]; /* Logon domain of the user */
/* token is needed if sexec should be called. It can be set by a call
to `set_impersonation_token()'. */
HANDLE token;
BOOL impersonated;
uid_t orig_uid; /* Remains intact also after impersonation */
uid_t orig_gid; /* Ditto */
uid_t real_uid; /* Remains intact on seteuid, replaced by setuid */
gid_t real_gid; /* Ditto */
/* Non-zero if process was stopped by a signal. */ /* Non-zero if process was stopped by a signal. */
char stopsig; char stopsig;

View File

@ -503,6 +503,9 @@ skip_arg_parsing:
/* Preallocated buffer for `sec_user' call */ /* Preallocated buffer for `sec_user' call */
char sa_buf[1024]; char sa_buf[1024];
if (!hToken && myself->token != INVALID_HANDLE_VALUE)
hToken = myself->token;
if (hToken) if (hToken)
{ {
/* allow the child to interact with our window station/desktop */ /* allow the child to interact with our window station/desktop */
@ -535,6 +538,11 @@ skip_arg_parsing:
else else
system_printf ("GetTokenInformation: %E"); system_printf ("GetTokenInformation: %E");
/* Remove impersonation */
uid_t uid = geteuid();
if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
seteuid (myself->orig_uid);
rc = CreateProcessAsUser (hToken, rc = CreateProcessAsUser (hToken,
real_path, /* image name - with full path */ real_path, /* image name - with full path */
one_line.buf, /* what was passed to exec */ one_line.buf, /* what was passed to exec */
@ -550,6 +558,9 @@ skip_arg_parsing:
0, /* use current drive/directory */ 0, /* use current drive/directory */
&si, &si,
&pi); &pi);
/* Restore impersonation */
if (myself->impersonated && myself->token != INVALID_HANDLE_VALUE)
seteuid (uid);
} }
else else
rc = CreateProcessA (real_path, /* image name - with full path */ rc = CreateProcessA (real_path, /* image name - with full path */

View File

@ -1796,6 +1796,92 @@ mknod ()
extern "C" extern "C"
int int
setgid (gid_t gid) setgid (gid_t gid)
{
int ret = setegid (gid);
if (!ret)
myself->real_gid = myself->gid;
return ret;
}
/* setuid: POSIX 4.2.2.1 */
extern "C"
int
setuid (uid_t uid)
{
int ret = seteuid (uid);
if (!ret)
myself->real_uid = myself->uid;
debug_printf ("real: %d, effective: %d", myself->real_uid, myself->uid);
return ret;
}
extern char *internal_getlogin (struct pinfo *pi);
/* seteuid: standards? */
extern "C"
int
seteuid (uid_t uid)
{
if (os_being_run == winNT)
{
if (uid != (uid_t) -1)
{
struct passwd *pw_new = getpwuid (uid);
if (!pw_new)
{
set_errno (EINVAL);
return -1;
}
if (uid != myself->uid)
if (uid == myself->orig_uid)
{
debug_printf ("RevertToSelf() (uid == orig_uid, token=%d)",
myself->token);
RevertToSelf();
if (myself->token != INVALID_HANDLE_VALUE)
myself->impersonated = FALSE;
}
else if (!myself->impersonated)
{
debug_printf ("Impersonate(uid == %d)", uid);
RevertToSelf();
if (myself->token != INVALID_HANDLE_VALUE)
if (!ImpersonateLoggedOnUser (myself->token))
system_printf ("Impersonate(%d) in set(e)uid failed: %E",
myself->token);
else
myself->impersonated = TRUE;
}
struct pinfo pi;
pi.psid = (PSID) pi.sidbuf;
struct passwd *pw_cur = getpwnam (internal_getlogin (&pi));
if (pw_cur != pw_new)
{
debug_printf ("Diffs!!! token: %d, cur: %d, new: %d, orig: %d",
myself->token, pw_cur->pw_uid,
pw_new->pw_uid, myself->orig_uid);
set_errno (EPERM);
return -1;
}
myself->uid = uid;
strcpy (myself->username, pi.username);
CopySid (40, myself->psid, pi.psid);
strcpy (myself->logsrv, pi.logsrv);
strcpy (myself->domain, pi.domain);
}
}
else
set_errno (ENOSYS);
debug_printf ("real: %d, effective: %d", myself->real_uid, myself->uid);
return 0;
}
/* setegid: from System V. */
extern "C"
int
setegid (gid_t gid)
{ {
if (os_being_run == winNT) if (os_being_run == winNT)
{ {
@ -1814,60 +1900,6 @@ setgid (gid_t gid)
return 0; return 0;
} }
extern char *internal_getlogin (struct pinfo *pi);
/* setuid: POSIX 4.2.2.1 */
extern "C"
int
setuid (uid_t uid)
{
if (os_being_run == winNT)
{
if (uid != (uid_t) -1)
{
struct passwd *pw_new = getpwuid (uid);
if (!pw_new)
{
set_errno (EINVAL);
return -1;
}
struct pinfo pi;
pi.psid = (PSID) pi.sidbuf;
struct passwd *pw_cur = getpwnam (internal_getlogin (&pi));
if (pw_cur != pw_new)
{
set_errno (EPERM);
return -1;
}
myself->uid = uid;
strcpy (myself->username, pi.username);
CopySid (40, myself->psid, pi.psid);
strcpy (myself->logsrv, pi.logsrv);
strcpy (myself->domain, pi.domain);
}
}
else
set_errno (ENOSYS);
return 0;
}
/* seteuid: standards? */
extern "C"
int
seteuid (uid_t uid)
{
return setuid (uid);
}
/* setegid: from System V. */
extern "C"
int
setegid (gid_t gid)
{
return setgid (gid);
}
/* chroot: privileged Unix system call. */ /* chroot: privileged Unix system call. */
extern "C" extern "C"
int int

View File

@ -126,6 +126,11 @@ uinfo_init ()
myself->uid = DEFAULT_UID; myself->uid = DEFAULT_UID;
myself->gid = DEFAULT_GID; myself->gid = DEFAULT_GID;
} }
/* Set to non impersonated value. */
myself->token = INVALID_HANDLE_VALUE;
myself->impersonated = TRUE;
myself->orig_uid = myself->real_uid = myself->uid;
myself->orig_gid = myself->real_gid = myself->gid;
} }
extern "C" char * extern "C" char *
@ -143,25 +148,25 @@ getlogin (void)
extern "C" uid_t extern "C" uid_t
getuid (void) getuid (void)
{ {
return myself->uid; return myself->real_uid;
} }
extern "C" gid_t extern "C" gid_t
getgid (void) getgid (void)
{ {
return myself->gid; return myself->real_gid;
} }
extern "C" uid_t extern "C" uid_t
geteuid (void) geteuid (void)
{ {
return getuid (); return myself->uid;
} }
extern "C" gid_t extern "C" gid_t
getegid (void) getegid (void)
{ {
return getgid (); return myself->gid;
} }
/* Not quite right - cuserid can change, getlogin can't */ /* Not quite right - cuserid can change, getlogin can't */