source: filezilla/trunk/fuentes/src/putty/windows/winsecur.c @ 3185

Last change on this file since 3185 was 3185, checked in by jrpelegrina, 2 years ago

Update new version: 3.15.02

File size: 8.0 KB
Line 
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 */
16static PSID worldsid, networksid, usersid;
17
18
19int 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
40PSID 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
92int 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
138int make_private_security_descriptor(DWORD permissions,
139                                     PSECURITY_DESCRIPTOR *psd,
140                                     PACL *acl,
141                                     char **error)
142{
143    SID_IDENTIFIER_AUTHORITY world_auth = SECURITY_WORLD_SID_AUTHORITY;
144    SID_IDENTIFIER_AUTHORITY nt_auth = SECURITY_NT_AUTHORITY;
145    EXPLICIT_ACCESS ea[3];
146    int acl_err;
147    int ret = FALSE;
148
149
150    *psd = NULL;
151    *acl = NULL;
152    *error = NULL;
153
154    if (!getsids(*error))
155      goto cleanup;
156
157    memset(ea, 0, sizeof(ea));
158    ea[0].grfAccessPermissions = permissions;
159    ea[0].grfAccessMode = REVOKE_ACCESS;
160    ea[0].grfInheritance = NO_INHERITANCE;
161    ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
162    ea[0].Trustee.ptstrName = (LPTSTR)worldsid;
163    ea[1].grfAccessPermissions = permissions;
164    ea[1].grfAccessMode = GRANT_ACCESS;
165    ea[1].grfInheritance = NO_INHERITANCE;
166    ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
167    ea[1].Trustee.ptstrName = (LPTSTR)usersid;
168    ea[2].grfAccessPermissions = permissions;
169    ea[2].grfAccessMode = REVOKE_ACCESS;
170    ea[2].grfInheritance = NO_INHERITANCE;
171    ea[2].Trustee.TrusteeForm = TRUSTEE_IS_SID;
172    ea[2].Trustee.ptstrName = (LPTSTR)networksid;
173
174    acl_err = p_SetEntriesInAclA(3, ea, NULL, acl);
175    if (acl_err != ERROR_SUCCESS || *acl == NULL) {
176        *error = dupprintf("unable to construct ACL: %s",
177                           win_strerror(acl_err));
178        goto cleanup;
179    }
180
181    *psd = (PSECURITY_DESCRIPTOR)
182        LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
183    if (!*psd) {
184        *error = dupprintf("unable to allocate security descriptor: %s",
185                           win_strerror(GetLastError()));
186        goto cleanup;
187    }
188
189    if (!InitializeSecurityDescriptor(*psd, SECURITY_DESCRIPTOR_REVISION)) {
190        *error = dupprintf("unable to initialise security descriptor: %s",
191                           win_strerror(GetLastError()));
192        goto cleanup;
193    }
194
195    if (!SetSecurityDescriptorOwner(*psd, usersid, FALSE)) {
196        *error = dupprintf("unable to set owner in security descriptor: %s",
197                           win_strerror(GetLastError()));
198        goto cleanup;
199    }
200
201    if (!SetSecurityDescriptorDacl(*psd, TRUE, *acl, FALSE)) {
202        *error = dupprintf("unable to set DACL in security descriptor: %s",
203                           win_strerror(GetLastError()));
204        goto cleanup;
205    }
206
207    ret = TRUE;
208
209  cleanup:
210    if (!ret) {
211        if (*psd) {
212            LocalFree(*psd);
213            *psd = NULL;
214        }
215        if (*acl) {
216            LocalFree(*acl);
217            *acl = NULL;
218        }
219    } else {
220        sfree(*error);
221        *error = NULL;
222    }
223    return ret;
224}
225
226int setprocessacl(char *error)
227{
228    SID_IDENTIFIER_AUTHORITY world_auth = SECURITY_WORLD_SID_AUTHORITY;
229    SID_IDENTIFIER_AUTHORITY nt_auth = SECURITY_NT_AUTHORITY;
230    EXPLICIT_ACCESS ea[2];
231    int acl_err;
232    int ret=FALSE;
233    PACL acl = NULL;
234
235    static const nastyace=WRITE_DAC | WRITE_OWNER |
236        PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD |
237        PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION |
238        PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION |
239        PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE |
240        PROCESS_SUSPEND_RESUME;
241
242    if (!getsids(error))
243        goto cleanup;
244
245    memset(ea, 0, sizeof(ea));
246
247    /* Everyone: deny */
248    ea[0].grfAccessPermissions = nastyace;
249    ea[0].grfAccessMode = DENY_ACCESS;
250    ea[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
251    ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
252    ea[0].Trustee.ptstrName = (LPTSTR)worldsid;
253
254    /* User: user ace */
255    ea[1].grfAccessPermissions = ~nastyace & 0x1fff;
256    ea[1].grfAccessMode = GRANT_ACCESS;
257    ea[1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
258    ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
259    ea[1].Trustee.ptstrName = (LPTSTR)usersid;
260
261    acl_err = p_SetEntriesInAclA(2, ea, NULL, &acl);
262
263    if (acl_err != ERROR_SUCCESS || acl == NULL) {
264        error = dupprintf("unable to construct ACL: %s",
265                          win_strerror(acl_err));
266        goto cleanup;
267    }
268
269    if (ERROR_SUCCESS != p_SetSecurityInfo
270        (GetCurrentProcess(), SE_KERNEL_OBJECT,
271         OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
272         usersid, NULL, acl, NULL)) {
273        error=dupprintf("Unable to set process ACL: %s",
274                        win_strerror(GetLastError()));
275        goto cleanup;
276    }
277                     
278
279    ret=TRUE;
280   
281  cleanup:
282    if (!ret) {
283        if (acl) {
284            LocalFree(acl);
285            acl = NULL;
286        }
287    }
288    return ret;
289} 
290#endif /* !defined NO_SECURITY */
Note: See TracBrowser for help on using the repository browser.