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:
-rw-r--r--winsup/cygwin/ChangeLog30
-rw-r--r--winsup/cygwin/Makefile.in10
-rw-r--r--winsup/cygwin/cygserver.h5
-rw-r--r--winsup/cygwin/cygserver_msg.h4
-rw-r--r--winsup/cygwin/cygserver_sem.h4
-rw-r--r--winsup/cygwin/cygserver_setpwd.h53
-rw-r--r--winsup/cygwin/cygserver_shm.h4
-rw-r--r--winsup/cygwin/external.cc6
-rw-r--r--winsup/cygwin/include/cygwin/version.h3
-rw-r--r--winsup/cygwin/include/sys/cygwin.h3
-rw-r--r--winsup/cygwin/sec_auth.cc85
-rw-r--r--winsup/cygwin/security.h4
-rw-r--r--winsup/cygwin/setlsapwd.cc90
-rw-r--r--winsup/cygwin/syscalls.cc54
14 files changed, 323 insertions, 32 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 31d74eed0..ddb11d82a 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,33 @@
+2008-11-26 Corinna Vinschen <corinna@vinschen.de>
+
+ * Makefile.in (DLL_OFILES): Add setlsapwd.o.
+ * cygserver.h (CYGWIN_SERVER_VERSION_API): Bump.
+ (request_code_t): Define CYGSERVER_REQUEST_SETPWD request type.
+ * cygserver_msg.h (client_request_msg::retval): Use default value of -1
+ for retval if msglen is 0.
+ * cygserver_sem.h (client_request_sem::retval): Ditto.
+ * cygserver_shm.h (client_request_shm::retval): Ditto.
+ * cygserver_setpwd.h: New file.
+ * external.cc (cygwin_internal): Implement new CW_SET_PRIV_KEY type.
+ * sec_auth.cc (open_local_policy): Make externally available.
+ Get ACCESS_MASK as argument.
+ (create_token): Accommodate change to open_local_policy.
+ (lsaauth): Ditto.
+ (lsaprivkeyauth): New function fetching token by retrieving
+ password stored in Cygwin or Interix LSA private data area and
+ calling LogonUser with it.
+ * security.h (lsaprivkeyauth): Declare.
+ (open_local_policy): Declare.
+ * setlsapwd.cc: New file implementing setting LSA private data password
+ using LsaStorePrivateData or by calling cygserver if available.
+ * syscalls.cc (seteuid32): Add workaround to get the original token
+ when switching back to the original privileged user, even if
+ setgroups group list is still active. Add long comment to explain why.
+ Call lsaprivkeyauth first, only if that fails call lsaauth or
+ create_token.
+ * include/cygwin/version.h: Bump API minor number.
+ * include/sys/cygwin.h (cygwin_getinfo_types): Add CW_SET_PRIV_KEY.
+
2008-11-21 Corinna Vinschen <corinna@vinschen.de>
* fhandler_floppy.cc (fhandler_dev_floppy::raw_read): Drop
diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in
index d6f6bb1ce..49baebc96 100644
--- a/winsup/cygwin/Makefile.in
+++ b/winsup/cygwin/Makefile.in
@@ -141,11 +141,11 @@ DLL_OFILES:=assert.o autoload.o bsdlib.o ctype.o cxx.o cygheap.o cygthread.o \
nftw.o ntea.o passwd.o path.o pinfo.o pipe.o poll.o posix_ipc.o \
pthread.o random.o regcomp.o regerror.o regexec.o regfree.o registry.o \
resource.o rexec.o rcmd.o scandir.o sched.o sec_acl.o sec_auth.o \
- sec_helper.o security.o select.o sem.o shared.o shm.o sigfe.o signal.o \
- sigproc.o smallprint.o spawn.o strace.o strfuncs.o strptime.o strsep.o \
- strsig.o sync.o syscalls.o sysconf.o syslog.o termios.o thread.o \
- timer.o times.o tls_pbuf.o tty.o uinfo.o uname.o wait.o wincap.o \
- window.o winf.o xsique.o \
+ sec_helper.o security.o select.o sem.o setlsapwd.o shared.o shm.o \
+ sigfe.o signal.o sigproc.o smallprint.o spawn.o strace.o strfuncs.o \
+ strptime.o strsep.o strsig.o sync.o syscalls.o sysconf.o syslog.o \
+ termios.o thread.o timer.o times.o tls_pbuf.o tty.o uinfo.o uname.o \
+ wait.o wincap.o window.o winf.o xsique.o \
$(EXTRA_DLL_OFILES) $(EXTRA_OFILES) $(MALLOC_OFILES) $(MT_SAFE_OBJECTS)
GMON_OFILES:=gmon.o mcount.o profil.o
diff --git a/winsup/cygwin/cygserver.h b/winsup/cygwin/cygserver.h
index 09ab78a9f..b549ed006 100644
--- a/winsup/cygwin/cygserver.h
+++ b/winsup/cygwin/cygserver.h
@@ -1,6 +1,6 @@
/* cygserver.h
- Copyright 2001, 2002, 2003, 2004 Red Hat Inc.
+ Copyright 2001, 2002, 2003, 2004, 2008 Red Hat Inc.
Written by Egor Duda <deo@logos-m.ru>
@@ -20,7 +20,7 @@ details. */
#endif
#define CYGWIN_SERVER_VERSION_MAJOR 1
-#define CYGWIN_SERVER_VERSION_API 3
+#define CYGWIN_SERVER_VERSION_API 4
#define CYGWIN_SERVER_VERSION_MINOR 0
#define CYGWIN_SERVER_VERSION_PATCH 0
@@ -51,6 +51,7 @@ protected:
CYGSERVER_REQUEST_MSG,
CYGSERVER_REQUEST_SEM,
CYGSERVER_REQUEST_SHM,
+ CYGSERVER_REQUEST_SETPWD,
CYGSERVER_REQUEST_LAST
} request_code_t;
diff --git a/winsup/cygwin/cygserver_msg.h b/winsup/cygwin/cygserver_msg.h
index 7fbb12cab..37616bb1d 100644
--- a/winsup/cygwin/cygserver_msg.h
+++ b/winsup/cygwin/cygserver_msg.h
@@ -1,6 +1,6 @@
/* cygserver_msg.h: Single unix specification IPC interface for Cygwin.
- Copyright 2003 Red Hat, Inc.
+ Copyright 2003, 2008 Red Hat, Inc.
This file is part of Cygwin.
@@ -75,7 +75,7 @@ public:
client_request_msg (int, const void *, size_t, int); // msgsnd
#endif
- int retval () const { return _parameters.out.ret; }
+ int retval () const { return msglen () ? _parameters.out.ret : -1; }
ssize_t rcvval () const { return _parameters.out.rcv; }
};
diff --git a/winsup/cygwin/cygserver_sem.h b/winsup/cygwin/cygserver_sem.h
index 225d8f215..fdf6f8c39 100644
--- a/winsup/cygwin/cygserver_sem.h
+++ b/winsup/cygwin/cygserver_sem.h
@@ -1,6 +1,6 @@
/* cygserver_sem.h: Single unix specification IPC interface for Cygwin.
- Copyright 2003 Red Hat, Inc.
+ Copyright 2003, 2008 Red Hat, Inc.
This file is part of Cygwin.
@@ -71,7 +71,7 @@ public:
client_request_sem (int, struct sembuf *, size_t); // semop
#endif
- int retval () const { return _parameters.out.ret; }
+ int retval () const { return msglen () ? _parameters.out.ret : -1; }
};
#ifndef __INSIDE_CYGWIN__
diff --git a/winsup/cygwin/cygserver_setpwd.h b/winsup/cygwin/cygserver_setpwd.h
new file mode 100644
index 000000000..94ee2998d
--- /dev/null
+++ b/winsup/cygwin/cygserver_setpwd.h
@@ -0,0 +1,53 @@
+/* cygserver_setpwd.h: Set LSA private data password for current user.
+
+ Copyright 2008 Red Hat, Inc.
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+#ifndef __CYGSERVER_SETPWD_H__
+#define __CYGSERVER_SETPWD_H__
+
+#include <sys/types.h>
+#include "cygserver.h"
+
+#define CYGWIN_LSA_KEY_PREFIX L"L$CYGWIN_"
+
+#ifndef __INSIDE_CYGWIN__
+class transport_layer_base;
+class process_cache;
+#endif
+
+class client_request_setpwd : public client_request
+{
+ friend class client_request;
+
+private:
+ union
+ {
+ struct
+ {
+ WCHAR passwd[256];
+ } in;
+ } _parameters;
+
+#ifndef __INSIDE_CYGWIN__
+ client_request_setpwd ();
+ virtual void serve (transport_layer_base *, process_cache *);
+#endif
+
+public:
+
+#ifdef __INSIDE_CYGWIN__
+ client_request_setpwd (PUNICODE_STRING);
+#endif
+};
+
+#ifdef __INSIDE_CYGWIN__
+unsigned long setlsapwd (const char *passwd);
+#endif
+
+#endif /* __CYGSERVER_SETPWD_H__ */
diff --git a/winsup/cygwin/cygserver_shm.h b/winsup/cygwin/cygserver_shm.h
index 2948f6725..baa3e052a 100644
--- a/winsup/cygwin/cygserver_shm.h
+++ b/winsup/cygwin/cygserver_shm.h
@@ -1,6 +1,6 @@
/* cygserver_shm.h: Single unix specification IPC interface for Cygwin.
- Copyright 2003 Red Hat, Inc.
+ Copyright 2003, 2008 Red Hat, Inc.
This file is part of Cygwin.
@@ -78,7 +78,7 @@ public:
client_request_shm (proc *); // shmfork
#endif
- int retval () const { return _parameters.out.ret; }
+ int retval () const { return msglen () ? _parameters.out.ret : -1; }
void *ptrval () const { return (void *)_parameters.out.ptr; }
vm_object_t objval () const { return _parameters.out.obj; }
};
diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc
index 675d8b066..b880e07fb 100644
--- a/winsup/cygwin/external.cc
+++ b/winsup/cygwin/external.cc
@@ -25,6 +25,7 @@ details. */
#include "cygtls.h"
#include "child_info.h"
#include "environ.h"
+#include "cygserver_setpwd.h"
#include <unistd.h>
#include <stdlib.h>
#include <wchar.h>
@@ -357,6 +358,11 @@ cygwin_internal (cygwin_getinfo_types t, ...)
dos_file_warning = va_arg (arg, int);
}
break;
+ case CW_SET_PRIV_KEY:
+ {
+ const char *passwd = va_arg (arg, const char *);
+ return setlsapwd (passwd);
+ }
default:
break;
diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h
index 268f99db7..ef332ce23 100644
--- a/winsup/cygwin/include/cygwin/version.h
+++ b/winsup/cygwin/include/cygwin/version.h
@@ -335,12 +335,13 @@ details. */
186: Remove ancient V8 regexp functions. Also eliminate old crt0 interface
which provided its own user_data structure.
187: Export cfmakeraw.
+ 188: Export CW_SET_PRIV_KEY.
*/
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0
-#define CYGWIN_VERSION_API_MINOR 187
+#define CYGWIN_VERSION_API_MINOR 188
/* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible
diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h
index 1ba18597d..8c1101051 100644
--- a/winsup/cygwin/include/sys/cygwin.h
+++ b/winsup/cygwin/include/sys/cygwin.h
@@ -140,7 +140,8 @@ typedef enum
CW_DEBUG_SELF,
CW_SYNC_WINENV,
CW_CYGTLS_PADSIZE,
- CW_SET_DOS_FILE_WARNING
+ CW_SET_DOS_FILE_WARNING,
+ CW_SET_PRIV_KEY
} cygwin_getinfo_types;
#define CW_NEXTPID 0x80000000 /* or with pid to get next one */
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;
+}
diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h
index 27a2d0046..0f194bade 100644
--- a/winsup/cygwin/security.h
+++ b/winsup/cygwin/security.h
@@ -370,6 +370,8 @@ void __stdcall str2uni_cat (_UNICODE_STRING &, const char *) __attribute__ ((reg
HANDLE create_token (cygsid &usersid, user_groups &groups, struct passwd * pw);
/* LSA authentication function. */
HANDLE lsaauth (cygsid &, user_groups &, struct passwd *);
+/* LSA private key storage authentication, same as when using service logons. */
+HANDLE lsaprivkeyauth (struct passwd *pw);
/* Verify an existing token */
bool verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern = NULL);
/* Get groups of a user */
@@ -380,6 +382,8 @@ void extract_nt_dom_user (const struct passwd *pw, PWCHAR domain, PWCHAR user);
/* Get default logonserver for a domain. */
bool get_logon_server (PWCHAR domain, PWCHAR wserver, bool rediscovery);
+HANDLE open_local_policy (ACCESS_MASK access);
+
/* sec_helper.cc: Security helper functions. */
int set_privilege (HANDLE token, DWORD privilege, bool enable);
void set_cygwin_privileges (HANDLE token);
diff --git a/winsup/cygwin/setlsapwd.cc b/winsup/cygwin/setlsapwd.cc
new file mode 100644
index 000000000..34284afd3
--- /dev/null
+++ b/winsup/cygwin/setlsapwd.cc
@@ -0,0 +1,90 @@
+/* setlsapwd.cc: Set LSA private data password for current user.
+
+ Copyright 2008 Red Hat, Inc.
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+#include "winsup.h"
+#include "shared_info.h"
+#include "cygerrno.h"
+#include "path.h"
+#include "fhandler.h"
+#include "dtable.h"
+#include "cygheap.h"
+#include "security.h"
+#include "cygserver_setpwd.h"
+#include "ntdll.h"
+#include <ntsecapi.h>
+#include <stdlib.h>
+#include <wchar.h>
+
+#ifdef USE_SERVER
+/*
+ * client_request_setpwd Constructor
+ */
+
+client_request_setpwd::client_request_setpwd (PUNICODE_STRING passwd)
+ : client_request (CYGSERVER_REQUEST_SETPWD, &_parameters, sizeof (_parameters))
+{
+ memset (_parameters.in.passwd, 0, sizeof _parameters.in.passwd);
+ if (passwd->Length > 0 && passwd->Length < 256 * sizeof (WCHAR))
+ wcpncpy (_parameters.in.passwd, passwd->Buffer, 255);
+
+ msglen (sizeof (_parameters.in));
+}
+
+#endif /* USE_SERVER */
+
+unsigned long
+setlsapwd (const char *passwd)
+{
+ unsigned long ret = (unsigned long) -1;
+ HANDLE lsa = INVALID_HANDLE_VALUE;
+ WCHAR sid[128];
+ WCHAR key_name[128 + wcslen (CYGWIN_LSA_KEY_PREFIX)];
+ PWCHAR data_buf = NULL;
+ UNICODE_STRING key;
+ UNICODE_STRING data;
+
+ wcpcpy (wcpcpy (key_name, CYGWIN_LSA_KEY_PREFIX),
+ cygheap->user.get_windows_id (sid));
+ RtlInitUnicodeString (&key, key_name);
+ if (!passwd || ! *passwd
+ || sys_mbstowcs_alloc (&data_buf, HEAP_NOTHEAP, passwd))
+ {
+ NTSTATUS status = STATUS_ACCESS_DENIED;
+
+ memset (&data, 0, sizeof data);
+ if (data_buf)
+ RtlInitUnicodeString (&data, data_buf);
+ /* First try it locally. Works for admin accounts. */
+ if ((lsa = open_local_policy (POLICY_CREATE_SECRET))
+ != INVALID_HANDLE_VALUE)
+ {
+ status = LsaStorePrivateData (lsa, &key, data.Length ? &data : NULL);
+ if (NT_SUCCESS (status))
+ ret = 0;
+ LsaClose (lsa);
+ }
+ if (ret)
+#ifdef USE_SERVER
+ {
+ /* If that fails, ask cygserver. */
+ client_request_setpwd request (&data);
+ if (request.make_request () == -1 || request.error_code ())
+ set_errno (request.error_code ());
+ else
+ ret = 0;
+ }
+#else
+ __seterrno_from_nt_status (status);
+#endif
+ if (data_buf)
+ free (data_buf);
+ }
+ return ret;
+}
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 9b39f7712..4590c37a8 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -2493,7 +2493,23 @@ seteuid32 (__uid32_t uid)
cygheap->user.deimpersonate ();
/* Verify if the process token is suitable. */
- if (verify_token (hProcToken, usersid, groups))
+ /* TODO, CV 2008-11-25: The check against saved_sid is a kludge and a
+ shortcut. We must check if it's really feasible in the long run.
+ The reason to add this shortcut is this: sshd switches back to the
+ privileged user running sshd at least twice in the process of
+ authentication. It calls seteuid first, then setegid. Due to this
+ order, the setgroups group list is still active when calling seteuid
+ and verify_token treats the original token of the privileged user as
+ insufficient. This in turn results in creating a new user token for
+ the privileged user instead of using the orignal token. This can have
+ unfortunate side effects. The created token has different group
+ memberships, different user rights, and misses possible network
+ credentials.
+ Therefore we try this shortcut now. When switching back to the
+ privileged user, we probably always want a correct (aka original)
+ user token for this privileged user, not only in sshd. */
+ if ((uid == cygheap->user.saved_uid && usersid == cygheap->user.saved_sid ())
+ || verify_token (hProcToken, usersid, groups))
new_token = hProcToken;
/* Verify if the external token is suitable */
else if (cygheap->user.external_token != NO_IMPERSONATION
@@ -2514,19 +2530,35 @@ seteuid32 (__uid32_t uid)
debug_printf ("Found token %d", new_token);
- /* If no impersonation token is available, try to
- authenticate using NtCreateToken () or LSA authentication. */
+ /* If no impersonation token is available, try to authenticate using
+ LSA private data stored password, LSA authentication using our own
+ LSA module, or, as last chance, NtCreateToken. */
if (new_token == INVALID_HANDLE_VALUE)
{
- if (!(new_token = lsaauth (usersid, groups, pw_new)))
- {
- debug_printf ("lsaauth failed, try create_token.");
- new_token = create_token (usersid, groups, pw_new);
- if (new_token == INVALID_HANDLE_VALUE)
+ new_token = lsaprivkeyauth (pw_new);
+ if (new_token)
+ {
+ /* We have to verify this token since settings in /etc/group
+ might render it unusable im terms of group membership. */
+ if (!verify_token (new_token, usersid, groups))
{
- debug_printf ("create_token failed, bail out of here");
- cygheap->user.reimpersonate ();
- return -1;
+ CloseHandle (new_token);
+ new_token = NULL;
+ }
+ }
+ if (!new_token)
+ {
+ debug_printf ("lsaprivkeyauth failed, try lsaauth.");
+ if (!(new_token = lsaauth (usersid, groups, pw_new)))
+ {
+ debug_printf ("lsaauth failed, try create_token.");
+ new_token = create_token (usersid, groups, pw_new);
+ if (new_token == INVALID_HANDLE_VALUE)
+ {
+ debug_printf ("create_token failed, bail out of here");
+ cygheap->user.reimpersonate ();
+ return -1;
+ }
}
}