Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/sec_auth.cc')
-rw-r--r--winsup/cygwin/sec_auth.cc85
1 files changed, 79 insertions, 6 deletions
diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc
index 3f7a082b2..138131744 100644
--- a/winsup/cygwin/sec_auth.cc
+++ b/winsup/cygwin/sec_auth.cc
@@ -27,6 +27,7 @@ details. */
#include <iptypes.h>
#include "pwdgrp.h"
#include "cyglsa.h"
+#include "cygserver_setpwd.h"
#include <cygwin/version.h>
extern "C" void
@@ -150,13 +151,13 @@ str2uni_cat (UNICODE_STRING &tgt, const char *srcstr)
tgt.Length = tgt.MaximumLength = 0;
}
-static LSA_HANDLE
-open_local_policy ()
+HANDLE
+open_local_policy (ACCESS_MASK access)
{
LSA_OBJECT_ATTRIBUTES oa = { 0, 0, 0, 0, 0, 0 };
- LSA_HANDLE lsa = INVALID_HANDLE_VALUE;
+ HANDLE lsa = INVALID_HANDLE_VALUE;
- NTSTATUS ret = LsaOpenPolicy (NULL, &oa, POLICY_EXECUTE, &lsa);
+ NTSTATUS ret = LsaOpenPolicy (NULL, &oa, access, &lsa);
if (ret != STATUS_SUCCESS)
__seterrno_from_win_error (LsaNtStatusToWinError (ret));
return lsa;
@@ -785,7 +786,7 @@ create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw)
push_self_privilege (SE_CREATE_TOKEN_PRIVILEGE, true);
/* Open policy object. */
- if ((lsa = open_local_policy ()) == INVALID_HANDLE_VALUE)
+ if ((lsa = open_local_policy (POLICY_EXECUTE)) == INVALID_HANDLE_VALUE)
goto out;
/* User, owner, primary group. */
@@ -963,7 +964,7 @@ lsaauth (cygsid &usersid, user_groups &new_groups, struct passwd *pw)
}
/* Open policy object. */
- if ((lsa = open_local_policy ()) == INVALID_HANDLE_VALUE)
+ if ((lsa = open_local_policy (POLICY_EXECUTE)) == INVALID_HANDLE_VALUE)
goto out;
/* Create origin. */
@@ -1172,3 +1173,75 @@ out:
debug_printf ("%p = lsaauth ()", user_token);
return user_token;
}
+
+#define SFU_LSA_KEY_SUFFIX L"_microsoft_sfu_utility"
+
+HANDLE
+lsaprivkeyauth (struct passwd *pw)
+{
+ NTSTATUS status;
+ HANDLE lsa = INVALID_HANDLE_VALUE;
+ HANDLE token = NULL;
+ WCHAR sid[256];
+ WCHAR domain[MAX_DOMAIN_NAME_LEN + 1];
+ WCHAR user[UNLEN + 1];
+ WCHAR key_name[MAX_DOMAIN_NAME_LEN + UNLEN + wcslen (SFU_LSA_KEY_SUFFIX) + 2];
+ UNICODE_STRING key;
+ PUNICODE_STRING data;
+ cygsid psid;
+
+ push_self_privilege (SE_TCB_PRIVILEGE, true);
+
+ /* Open policy object. */
+ if ((lsa = open_local_policy (POLICY_GET_PRIVATE_INFORMATION))
+ == INVALID_HANDLE_VALUE)
+ goto out;
+
+ /* Needed for Interix key and LogonUser. */
+ extract_nt_dom_user (pw, domain, user);
+
+ /* First test for a Cygwin entry. */
+ if (psid.getfrompw (pw) && psid.string (sid))
+ {
+ wcpcpy (wcpcpy (key_name, CYGWIN_LSA_KEY_PREFIX), sid);
+ RtlInitUnicodeString (&key, key_name);
+ status = LsaRetrievePrivateData (lsa, &key, &data);
+ if (!NT_SUCCESS (status))
+ {
+ /* No Cygwin key, try Interix key. */
+ if (!*domain)
+ goto out;
+ __small_swprintf (key_name, L"%W_%W%W",
+ domain, user, SFU_LSA_KEY_SUFFIX);
+ RtlInitUnicodeString (&key, key_name);
+ status = LsaRetrievePrivateData (lsa, &key, &data);
+ if (!NT_SUCCESS (status))
+ goto out;
+ }
+ }
+
+ /* The key is not 0-terminated. */
+ PWCHAR passwd = (PWCHAR) alloca (data->Length + sizeof (WCHAR));
+ *wcpncpy (passwd, data->Buffer, data->Length / sizeof (WCHAR)) = L'\0';
+ LsaFreeMemory (data);
+ debug_printf ("Try logon for %W\\%W", domain, user);
+ if (!LogonUserW (user, domain, passwd, LOGON32_LOGON_INTERACTIVE,
+ LOGON32_PROVIDER_DEFAULT, &token))
+ {
+ __seterrno ();
+ token = NULL;
+ }
+ else if (!SetHandleInformation (token,
+ HANDLE_FLAG_INHERIT,
+ HANDLE_FLAG_INHERIT))
+ {
+ __seterrno ();
+ CloseHandle (token);
+ token = NULL;
+ }
+
+out:
+ close_local_policy (lsa);
+ pop_self_privilege ();
+ return token;
+}