+2008-11-26 Corinna Vinschen <corinna@vinschen.de>
+
+ * Makefile.in (OBJS): Add setpwd.o.
+ * README: Explain new service to store passwords in the LSA registry
+ area.
+ * bsd_helper.cc (get_token_info): Make externally available.
+ * bsd_helper.h (get_token_info): Declare.
+ * client.cc (client_request::handle_request): Add case for
+ CYGSERVER_REQUEST_SETPWD request.
+ * setpwd.cc: New file implementing the CYGSERVER_REQUEST_SETPWD
+ request.
+
2008-10-30 Christopher Faylor <me+cygwin@cgf.cx>
* Makefile.in: Use -static-libgcc when creating cygserver.exe.
#define copyin(a,b,c) win_copyin((td),(a),(b),(c))
#define copyout(a,b,c) win_copyout((td),(a),(b),(c))
+void *get_token_info (HANDLE, TOKEN_INFORMATION_CLASS);
int ipcperm (struct thread *, struct ipc_perm *, unsigned int);
int suser (struct thread *);
bool adjust_identity_info (struct proc *p);
--- /dev/null
+/* setpwd.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. */
+
+#ifdef __OUTSIDE_CYGWIN__
+#include "woutsup.h"
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <wchar.h>
+
+#include <ntsecapi.h>
+#include <ntdef.h>
+#include "ntdll.h"
+
+#include "cygserver.h"
+#include "process.h"
+#include "transport.h"
+
+#include "cygserver_setpwd.h"
+
+client_request_setpwd::client_request_setpwd ()
+ : client_request (CYGSERVER_REQUEST_SETPWD,
+ &_parameters, sizeof (_parameters))
+{
+}
+
+void
+client_request_setpwd::serve (transport_layer_base *const conn,
+ process_cache *const cache)
+{
+ HANDLE tok;
+ PTOKEN_USER user;
+ WCHAR sidbuf[128], key_name [128 + wcslen (CYGWIN_LSA_KEY_PREFIX)];
+ UNICODE_STRING sid, key, data;
+
+ syscall_printf ("Request to set private data");
+ if (msglen () != sizeof (_parameters.in))
+ {
+ syscall_printf ("bad request body length: expecting %lu bytes, got %lu",
+ sizeof (_parameters), msglen ());
+ error_code (EINVAL);
+ msglen (0);
+ return;
+ }
+ msglen (0);
+ if (!conn->impersonate_client ())
+ {
+ error_code (EACCES);
+ return;
+ }
+ if (!OpenThreadToken (GetCurrentThread (), TOKEN_READ, TRUE, &tok))
+ {
+ conn->revert_to_self ();
+ error_code (EACCES);
+ return;
+ }
+ /* Get uid from user SID in token. */
+ user = (PTOKEN_USER) get_token_info (tok, TokenUser);
+ CloseHandle (tok);
+ conn->revert_to_self ();
+ if (!user)
+ {
+ error_code (EACCES);
+ return;
+ }
+ LSA_OBJECT_ATTRIBUTES oa = { 0, 0, 0, 0, 0, 0 };
+ HANDLE lsa;
+ NTSTATUS status = LsaOpenPolicy (NULL, &oa, POLICY_CREATE_SECRET, &lsa);
+ if (!NT_SUCCESS (status))
+ {
+ error_code (LsaNtStatusToWinError (status));
+ return;
+ }
+ RtlInitEmptyUnicodeString (&sid, sidbuf, sizeof sidbuf);
+ RtlConvertSidToUnicodeString (&sid, user->User.Sid, FALSE);
+ free (user);
+ RtlInitEmptyUnicodeString (&key, key_name, sizeof key_name);
+ RtlAppendUnicodeToString (&key, CYGWIN_LSA_KEY_PREFIX);
+ RtlAppendUnicodeStringToString (&key, &sid);
+ RtlInitUnicodeString (&data, _parameters.in.passwd);
+ status = LsaStorePrivateData (lsa, &key, data.Length ? &data : NULL);
+ if (NT_SUCCESS (status))
+ error_code (0);
+ else
+ error_code (LsaNtStatusToWinError (status));
+ syscall_printf ("Request to set private data returns error %d", error_code ());
+ LsaClose (lsa);
+}
+#endif /* __OUTSIDE_CYGWIN__ */