]>
Commit | Line | Data |
---|---|---|
d4db08d7 CV |
1 | /* setpwd.cc: Set LSA private data password for current user. |
2 | ||
722c840b | 3 | Copyright 2008, 2014 Red Hat, Inc. |
d4db08d7 CV |
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); | |
d08afb78 | 93 | if (data.Length) |
722c840b | 94 | RtlSecureZeroMemory (data.Buffer, data.Length); |
faded04e CV |
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)) | |
d4db08d7 CV |
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__ */ |