OSDN Git Service

* transport_pipes.cc: Include ntdef.h to accommodate cygerrno.h.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygserver / setpwd.cc
1 /* setpwd.cc: Set LSA private data password for current user.
2
3    Copyright 2008 Red Hat, Inc.
4
5 This file is part of Cygwin.
6
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
9 details. */
10
11 #ifdef __OUTSIDE_CYGWIN__
12 #include "woutsup.h"
13
14 #include <errno.h>
15 #include <pthread.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <time.h>
20 #include <wchar.h>
21
22 #include <ntsecapi.h>
23 #include <ntdef.h>
24 #include "ntdll.h"
25
26 #include "cygserver.h"
27 #include "process.h"
28 #include "transport.h"
29
30 #include "cygserver_setpwd.h"
31
32 client_request_setpwd::client_request_setpwd ()
33   : client_request (CYGSERVER_REQUEST_SETPWD,
34                     &_parameters, sizeof (_parameters))
35
36 }
37
38 void
39 client_request_setpwd::serve (transport_layer_base *const conn,
40                               process_cache *const cache)
41 {
42   HANDLE tok;
43   PTOKEN_USER user;
44   WCHAR sidbuf[128], key_name [128 + wcslen (CYGWIN_LSA_KEY_PREFIX)];
45   UNICODE_STRING sid, key, data;
46
47   syscall_printf ("Request to set private data");
48   if (msglen () != sizeof (_parameters.in))
49     {
50       syscall_printf ("bad request body length: expecting %lu bytes, got %lu",
51                       sizeof (_parameters), msglen ());
52       error_code (EINVAL);
53       msglen (0);
54       return;
55     }
56   msglen (0);
57   if (!conn->impersonate_client ())
58     {
59       error_code (EACCES);
60       return;
61     }
62   if (!OpenThreadToken (GetCurrentThread (), TOKEN_READ, TRUE, &tok))
63     {
64       conn->revert_to_self ();
65       error_code (EACCES);
66       return;
67     }
68   /* Get uid from user SID in token. */
69   user = (PTOKEN_USER) get_token_info (tok, TokenUser);
70   CloseHandle (tok);
71   conn->revert_to_self ();
72   if (!user)
73     {
74       error_code (EACCES);
75       return;
76     }
77   LSA_OBJECT_ATTRIBUTES oa = { 0, 0, 0, 0, 0, 0 };
78   HANDLE lsa;
79   NTSTATUS status = LsaOpenPolicy (NULL, &oa, POLICY_CREATE_SECRET, &lsa);
80   if (!NT_SUCCESS (status))
81     {
82       error_code (LsaNtStatusToWinError (status));
83       return;
84     }
85   RtlInitEmptyUnicodeString (&sid, sidbuf, sizeof sidbuf);
86   RtlConvertSidToUnicodeString (&sid, user->User.Sid, FALSE);
87   free (user);
88   RtlInitEmptyUnicodeString (&key, key_name, sizeof key_name);
89   RtlAppendUnicodeToString (&key, CYGWIN_LSA_KEY_PREFIX);
90   RtlAppendUnicodeStringToString (&key, &sid);
91   RtlInitUnicodeString (&data, _parameters.in.passwd);
92   status = LsaStorePrivateData (lsa, &key, data.Length ? &data : NULL);
93   if (data.Length)
94     memset (data.Buffer, 0, data.Length);
95   /* Success or we're trying to remove a password entry which doesn't exist. */
96   if (NT_SUCCESS (status)
97       || (data.Length == 0 && status == STATUS_OBJECT_NAME_NOT_FOUND))
98     error_code (0);
99   else
100     error_code (LsaNtStatusToWinError (status));
101   syscall_printf ("Request to set private data returns error %d", error_code ());
102   LsaClose (lsa);
103 }
104 #endif /* __OUTSIDE_CYGWIN__ */