]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - windows/winsecur.c
Remove some unused variables.
[PuTTY.git] / windows / winsecur.c
1 /*
2  * winsecur.c: implementation of winsecur.h.
3  */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7
8 #include "putty.h"
9
10 #if !defined NO_SECURITY
11
12 #define WINSECUR_GLOBAL
13 #include "winsecur.h"
14
15 /* Initialised once, then kept around to reuse forever */
16 static PSID worldsid, networksid, usersid;
17
18
19 int got_advapi(void)
20 {
21     static int attempted = FALSE;
22     static int successful;
23     static HMODULE advapi;
24
25     if (!attempted) {
26         attempted = TRUE;
27         advapi = load_system32_dll("advapi32.dll");
28         successful = advapi &&
29             GET_WINDOWS_FUNCTION(advapi, GetSecurityInfo) &&
30             GET_WINDOWS_FUNCTION(advapi, SetSecurityInfo) &&
31             GET_WINDOWS_FUNCTION(advapi, OpenProcessToken) &&
32             GET_WINDOWS_FUNCTION(advapi, GetTokenInformation) &&
33             GET_WINDOWS_FUNCTION(advapi, InitializeSecurityDescriptor) &&
34             GET_WINDOWS_FUNCTION(advapi, SetSecurityDescriptorOwner) &&
35             GET_WINDOWS_FUNCTION(advapi, SetEntriesInAclA);
36     }
37     return successful;
38 }
39
40 PSID get_user_sid(void)
41 {
42     HANDLE proc = NULL, tok = NULL;
43     TOKEN_USER *user = NULL;
44     DWORD toklen, sidlen;
45     PSID sid = NULL, ret = NULL;
46
47     if (!got_advapi())
48         goto cleanup;
49
50     if ((proc = OpenProcess(MAXIMUM_ALLOWED, FALSE,
51                             GetCurrentProcessId())) == NULL)
52         goto cleanup;
53
54     if (!p_OpenProcessToken(proc, TOKEN_QUERY, &tok))
55         goto cleanup;
56
57     if (!p_GetTokenInformation(tok, TokenUser, NULL, 0, &toklen) &&
58         GetLastError() != ERROR_INSUFFICIENT_BUFFER)
59         goto cleanup;
60
61     if ((user = (TOKEN_USER *)LocalAlloc(LPTR, toklen)) == NULL)
62         goto cleanup;
63
64     if (!p_GetTokenInformation(tok, TokenUser, user, toklen, &toklen))
65         goto cleanup;
66
67     sidlen = GetLengthSid(user->User.Sid);
68
69     sid = (PSID)smalloc(sidlen);
70
71     if (!CopySid(sidlen, sid, user->User.Sid))
72         goto cleanup;
73
74     /* Success. Move sid into the return value slot, and null it out
75      * to stop the cleanup code freeing it. */
76     ret = sid;
77     sid = NULL;
78
79   cleanup:
80     if (proc != NULL)
81         CloseHandle(proc);
82     if (tok != NULL)
83         CloseHandle(tok);
84     if (user != NULL)
85         LocalFree(user);
86     if (sid != NULL)
87         sfree(sid);
88
89     return ret;
90 }
91
92 int getsids(char *error)
93 {
94     SID_IDENTIFIER_AUTHORITY world_auth = SECURITY_WORLD_SID_AUTHORITY;
95     SID_IDENTIFIER_AUTHORITY nt_auth = SECURITY_NT_AUTHORITY;
96     int ret;
97
98     error=NULL;
99
100     if (!usersid) {
101         if ((usersid = get_user_sid()) == NULL) {
102             error = dupprintf("unable to construct SID for current user: %s",
103                                win_strerror(GetLastError()));
104             goto cleanup;
105         }
106     }
107
108     if (!worldsid) {
109         if (!AllocateAndInitializeSid(&world_auth, 1, SECURITY_WORLD_RID,
110                                       0, 0, 0, 0, 0, 0, 0, &worldsid)) {
111             error = dupprintf("unable to construct SID for world: %s",
112                                win_strerror(GetLastError()));
113             goto cleanup;
114         }
115     }
116
117     if (!networksid) {
118         if (!AllocateAndInitializeSid(&nt_auth, 1, SECURITY_NETWORK_RID,
119                                       0, 0, 0, 0, 0, 0, 0, &networksid)) {
120             error = dupprintf("unable to construct SID for "
121                                "local same-user access only: %s",
122                                win_strerror(GetLastError()));
123             goto cleanup;
124         }
125     }
126
127     ret=TRUE;
128
129  cleanup:
130     if (ret) {
131       sfree(error);
132       error = NULL;
133     }
134     return ret;
135 }
136   
137
138 int make_private_security_descriptor(DWORD permissions,
139                                      PSECURITY_DESCRIPTOR *psd,
140                                      PACL *acl,
141                                      char **error)
142 {
143     EXPLICIT_ACCESS ea[3];
144     int acl_err;
145     int ret = FALSE;
146
147
148     *psd = NULL;
149     *acl = NULL;
150     *error = NULL;
151
152     if (!getsids(*error))
153       goto cleanup;
154
155     memset(ea, 0, sizeof(ea));
156     ea[0].grfAccessPermissions = permissions;
157     ea[0].grfAccessMode = REVOKE_ACCESS;
158     ea[0].grfInheritance = NO_INHERITANCE;
159     ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
160     ea[0].Trustee.ptstrName = (LPTSTR)worldsid;
161     ea[1].grfAccessPermissions = permissions;
162     ea[1].grfAccessMode = GRANT_ACCESS;
163     ea[1].grfInheritance = NO_INHERITANCE;
164     ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
165     ea[1].Trustee.ptstrName = (LPTSTR)usersid;
166     ea[2].grfAccessPermissions = permissions;
167     ea[2].grfAccessMode = REVOKE_ACCESS;
168     ea[2].grfInheritance = NO_INHERITANCE;
169     ea[2].Trustee.TrusteeForm = TRUSTEE_IS_SID;
170     ea[2].Trustee.ptstrName = (LPTSTR)networksid;
171
172     acl_err = p_SetEntriesInAclA(3, ea, NULL, acl);
173     if (acl_err != ERROR_SUCCESS || *acl == NULL) {
174         *error = dupprintf("unable to construct ACL: %s",
175                            win_strerror(acl_err));
176         goto cleanup;
177     }
178
179     *psd = (PSECURITY_DESCRIPTOR)
180         LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
181     if (!*psd) {
182         *error = dupprintf("unable to allocate security descriptor: %s",
183                            win_strerror(GetLastError()));
184         goto cleanup;
185     }
186
187     if (!InitializeSecurityDescriptor(*psd, SECURITY_DESCRIPTOR_REVISION)) {
188         *error = dupprintf("unable to initialise security descriptor: %s",
189                            win_strerror(GetLastError()));
190         goto cleanup;
191     }
192
193     if (!SetSecurityDescriptorOwner(*psd, usersid, FALSE)) {
194         *error = dupprintf("unable to set owner in security descriptor: %s",
195                            win_strerror(GetLastError()));
196         goto cleanup;
197     }
198
199     if (!SetSecurityDescriptorDacl(*psd, TRUE, *acl, FALSE)) {
200         *error = dupprintf("unable to set DACL in security descriptor: %s",
201                            win_strerror(GetLastError()));
202         goto cleanup;
203     }
204
205     ret = TRUE;
206
207   cleanup:
208     if (!ret) {
209         if (*psd) {
210             LocalFree(*psd);
211             *psd = NULL;
212         }
213         if (*acl) {
214             LocalFree(*acl);
215             *acl = NULL;
216         }
217     } else {
218         sfree(*error);
219         *error = NULL;
220     }
221     return ret;
222 }
223
224 int setprocessacl(char *error)
225 {
226     EXPLICIT_ACCESS ea[2];
227     int acl_err;
228     int ret=FALSE;
229     PACL acl = NULL;
230
231     static const nastyace=WRITE_DAC | WRITE_OWNER |
232         PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD |
233         PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION |
234         PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION |
235         PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE |
236         PROCESS_SUSPEND_RESUME;
237
238     if (!getsids(error))
239         goto cleanup;
240
241     memset(ea, 0, sizeof(ea));
242
243     /* Everyone: deny */
244     ea[0].grfAccessPermissions = nastyace;
245     ea[0].grfAccessMode = DENY_ACCESS;
246     ea[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
247     ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
248     ea[0].Trustee.ptstrName = (LPTSTR)worldsid;
249
250     /* User: user ace */
251     ea[1].grfAccessPermissions = ~nastyace & 0x1fff;
252     ea[1].grfAccessMode = GRANT_ACCESS;
253     ea[1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
254     ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
255     ea[1].Trustee.ptstrName = (LPTSTR)usersid;
256
257     acl_err = p_SetEntriesInAclA(2, ea, NULL, &acl);
258
259     if (acl_err != ERROR_SUCCESS || acl == NULL) {
260         error = dupprintf("unable to construct ACL: %s",
261                           win_strerror(acl_err));
262         goto cleanup;
263     }
264
265     if (ERROR_SUCCESS != p_SetSecurityInfo
266         (GetCurrentProcess(), SE_KERNEL_OBJECT,
267          OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
268          usersid, NULL, acl, NULL)) {
269         error=dupprintf("Unable to set process ACL: %s",
270                         win_strerror(GetLastError()));
271         goto cleanup;
272     }
273                       
274
275     ret=TRUE;
276     
277   cleanup:
278     if (!ret) {
279         if (acl) {
280             LocalFree(acl);
281             acl = NULL;
282         }
283     }
284     return ret;
285 }  
286 #endif /* !defined NO_SECURITY */