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