diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2001-04-30 21:19:42 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2001-04-30 21:19:42 +0000 |
commit | 57ff940dd40a53ec03e5f2b079239b41bd9c2859 (patch) | |
tree | 4de2380c00e04343fe81f4113a9142540901c4d4 /winsup/cygwin/security.cc | |
parent | 965cecdfca617f99b5fab536e6f960201b12b2a4 (diff) | |
download | cygnal-57ff940dd40a53ec03e5f2b079239b41bd9c2859.tar.gz cygnal-57ff940dd40a53ec03e5f2b079239b41bd9c2859.tar.bz2 cygnal-57ff940dd40a53ec03e5f2b079239b41bd9c2859.zip |
* autoload.cc: Add LoadDLLinitfunc for secur32.dll.
Add LoadDLLfuncEx statements for AllocateLocallyUniqueId@4,
DuplicateTokenEx@24, LsaNtStatusToWinError@4,
LsaDeregisterLogonProcess@4, LsaFreeReturnBuffer@4,
LsaLogonUser@56, LsaLookupAuthenticationPackage@12,
LsaRegisterLogonProcess@12,
* environ.cc: Add extern declaration for `subauth_id'.
(subauth_id_init): New function for setting `subauth_id'.
(struct parse_thing): Add entry for `subauth_id'.
* fork.cc (fork_parent): Call `RevertToSelf' and
`ImpersonateLoggedOnUser' instead of `seteuid'.
* security.cc: Define global variable `subauth_id'.
(extract_nt_dom_user): New function.
(cygwin_logon_user): Call `extract_nt_dom_user' now.
(str2lsa): New static function.
(str2buf2lsa): Ditto.
(str2buf2uni): Ditto.
(subauth): Ditto.
* security.h: Add prototype for `subauth'.
* spawn.cc (spawn_guts): Use cygheap->user.token only if impersonated.
Use `cygsid' type. Remove impersonation before allowing access to
workstation/desktop to everyone. Call `RevertToSelf' and
`ImpersonateLoggedOnUser' instead of `seteuid'.
* syscalls.cc (seteuid): Rearranged to allow using subauthentication
to retrieve user tokens when needed.
Diffstat (limited to 'winsup/cygwin/security.cc')
-rw-r--r-- | winsup/cygwin/security.cc | 183 |
1 files changed, 160 insertions, 23 deletions
diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc index 9077676ac..9f5605ac0 100644 --- a/winsup/cygwin/security.cc +++ b/winsup/cygwin/security.cc @@ -24,6 +24,9 @@ details. */ #include <ctype.h> #include <wingdi.h> #include <winuser.h> +#include <wininet.h> +#include <ntsecapi.h> +#include <subauth.h> #include "cygerrno.h" #include "perprocess.h" #include "fhandler.h" @@ -56,6 +59,39 @@ cygwin_set_impersonation_token (const HANDLE hToken) } } +static void +extract_nt_dom_user (const struct passwd *pw, char *domain, char *user) +{ + char buf[INTERNET_MAX_HOST_NAME_LENGTH + UNLEN + 2]; + char *c; + + strcpy (domain, ""); + strcpy (buf, pw->pw_name); + debug_printf ("pw_gecos = %x (%s)", pw->pw_gecos, pw->pw_gecos); + if (pw->pw_gecos) + { + if ((c = strstr (pw->pw_gecos, "U-")) != NULL && + (c == pw->pw_gecos || c[-1] == ',')) + { + buf[0] = '\0'; + strncat (buf, c + 2, INTERNET_MAX_HOST_NAME_LENGTH + UNLEN + 1); + if ((c = strchr (buf, ',')) != NULL) + *c = '\0'; + } + } + if ((c = strchr (buf, '\\')) != NULL) + { + *c++ = '\0'; + strcpy (domain, buf); + strcpy (user, c); + } + else + { + strcpy (domain, ""); + strcpy (user, buf); + } +} + extern "C" HANDLE cygwin_logon_user (const struct passwd *pw, const char *password) @@ -71,32 +107,13 @@ cygwin_logon_user (const struct passwd *pw, const char *password) return INVALID_HANDLE_VALUE; } - char *c, *nt_user, *nt_domain = NULL; - char usernamebuf[256]; + char nt_domain[INTERNET_MAX_HOST_NAME_LENGTH + 1]; + char nt_user[UNLEN + 1]; HANDLE hToken; - strcpy (usernamebuf, pw->pw_name); - debug_printf ("pw_gecos = %x (%s)", pw->pw_gecos, pw->pw_gecos); - 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; - } + extract_nt_dom_user (pw, nt_domain, nt_user); debug_printf ("LogonUserA (%s, %s, %s, ...)", nt_user, nt_domain, password); - if (!LogonUserA (nt_user, nt_domain, (char *) password, + if (!LogonUserA (nt_user, *nt_domain ? nt_domain : NULL, (char *) password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken) @@ -111,6 +128,126 @@ cygwin_logon_user (const struct passwd *pw, const char *password) return hToken; } +static void +str2lsa (LSA_STRING &tgt, const char *srcstr) +{ + tgt.Length = strlen(srcstr); + tgt.MaximumLength = tgt.Length + 1; + tgt.Buffer = (PCHAR) srcstr; +} + +static void +str2buf2lsa (LSA_STRING &tgt, char *buf, const char *srcstr) +{ + tgt.Length = strlen(srcstr); + tgt.MaximumLength = tgt.Length + 1; + tgt.Buffer = (PCHAR) buf; + memcpy(buf, srcstr, tgt.MaximumLength); +} + +static void +str2buf2uni (UNICODE_STRING &tgt, WCHAR *buf, const char *srcstr) +{ + tgt.Length = strlen(srcstr) * sizeof (WCHAR); + tgt.MaximumLength = tgt.Length + sizeof(WCHAR); + tgt.Buffer = (PWCHAR) buf; + mbstowcs (buf, srcstr, tgt.MaximumLength); +} + +int subauth_id = 255; + +HANDLE +subauth (struct passwd *pw) +{ + LSA_STRING name; + HANDLE lsa_hdl; + LSA_OPERATIONAL_MODE sec_mode; + NTSTATUS ret, ret2; + ULONG package_id, size; + struct { + LSA_STRING str; + CHAR buf[16]; + } origin; + struct { + MSV1_0_LM20_LOGON auth; + WCHAR dombuf[INTERNET_MAX_HOST_NAME_LENGTH + 1]; + WCHAR usrbuf[UNLEN + 1]; + WCHAR wkstbuf[1]; + CHAR authinf1[1]; + CHAR authinf2[1]; + } subbuf; + TOKEN_SOURCE ts; + PMSV1_0_LM20_LOGON_PROFILE profile; + LUID luid; + HANDLE user_token; + QUOTA_LIMITS quota; + char nt_domain[INTERNET_MAX_HOST_NAME_LENGTH + 1]; + char nt_user[UNLEN + 1]; + + set_process_privilege(SE_TCB_NAME); + + /* Register as logon process. */ + str2lsa (name, "Cygwin"); + ret = LsaRegisterLogonProcess(&name, &lsa_hdl, &sec_mode); + if (ret != STATUS_SUCCESS) + { + debug_printf ("LsaRegisterLogonProcess: %d", ret); + set_errno (LsaNtStatusToWinError(ret)); + return INVALID_HANDLE_VALUE; + } + /* Get handle to MSV1_0 package. */ + str2lsa (name, MSV1_0_PACKAGE_NAME); + ret = LsaLookupAuthenticationPackage(lsa_hdl, &name, &package_id); + if (ret != STATUS_SUCCESS) + { + debug_printf ("LsaLookupAuthenticationPackage: %d", ret); + set_errno (LsaNtStatusToWinError(ret)); + LsaDeregisterLogonProcess(lsa_hdl); + return INVALID_HANDLE_VALUE; + } + /* Create origin. */ + str2buf2lsa (origin.str, origin.buf, "Cygwin"); + /* Create token source. */ + memcpy(ts.SourceName, "Cygwin.1", 8); + AllocateLocallyUniqueId(&ts.SourceIdentifier); + /* Get user information. */ + extract_nt_dom_user (pw, nt_domain, nt_user); + /* Fill subauth with values. */ + subbuf.auth.MessageType = MsV1_0NetworkLogon; + str2buf2uni(subbuf.auth.LogonDomainName, subbuf.dombuf, nt_domain); + str2buf2uni(subbuf.auth.UserName, subbuf.usrbuf, nt_user); + str2buf2uni(subbuf.auth.Workstation, subbuf.wkstbuf, ""); + memcpy(subbuf.auth.ChallengeToClient, "12345678", MSV1_0_CHALLENGE_LENGTH); + str2buf2lsa(subbuf.auth.CaseSensitiveChallengeResponse, subbuf.authinf1, ""); + str2buf2lsa(subbuf.auth.CaseInsensitiveChallengeResponse, subbuf.authinf2,""); + subbuf.auth.ParameterControl = 0 | (subauth_id << 24); + /* Try to logon... */ + ret = LsaLogonUser(lsa_hdl, (PLSA_STRING) &origin, Network, + package_id, &subbuf, sizeof subbuf, + NULL, &ts, (PVOID *)&profile, &size, + &luid, &user_token, "a, &ret2); + if (ret != STATUS_SUCCESS) + { + debug_printf ("LsaLogonUser: %d", ret); + set_errno (LsaNtStatusToWinError(ret)); + LsaDeregisterLogonProcess(lsa_hdl); + return INVALID_HANDLE_VALUE; + } + LsaFreeReturnBuffer(profile); + /* Convert to primary token. */ + SECURITY_ATTRIBUTES sa = { sizeof sa, NULL, TRUE }; + HANDLE primary_token; + if (!DuplicateTokenEx (user_token, TOKEN_ALL_ACCESS, &sa, + SecurityImpersonation, TokenPrimary, + &primary_token)) + { + CloseHandle (user_token); + return INVALID_HANDLE_VALUE; + } + CloseHandle (user_token); + return primary_token; +} + /* read_sd reads a security descriptor from a file. In case of error, -1 is returned and errno is set. If sd_buf is too small, 0 is returned and sd_size |