Mercurial > trustbridge > nss-cmake-static
comparison nspr/pr/src/md/windows/ntsec.c @ 0:1e5118fa0cb1
This is NSS with a Cmake Buildsyste
To compile a static NSS library for Windows we've used the
Chromium-NSS fork and added a Cmake buildsystem to compile
it statically for Windows. See README.chromium for chromium
changes and README.trustbridge for our modifications.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 28 Jul 2014 10:47:06 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e5118fa0cb1 |
---|---|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | |
2 /* This Source Code Form is subject to the terms of the Mozilla Public | |
3 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
5 | |
6 #include "primpl.h" | |
7 | |
8 /* | |
9 * ntsec.c | |
10 * | |
11 * Implement the POSIX-style mode bits (access permissions) for | |
12 * files and other securable objects in Windows NT using Windows | |
13 * NT's security descriptors with appropriate discretionary | |
14 * access-control lists. | |
15 */ | |
16 | |
17 /* | |
18 * The security identifiers (SIDs) for owner, primary group, | |
19 * and the Everyone (World) group. | |
20 * | |
21 * These SIDs are looked up during NSPR initialization and | |
22 * saved in this global structure (see _PR_NT_InitSids) so | |
23 * that _PR_NT_MakeSecurityDescriptorACL doesn't need to | |
24 * look them up every time. | |
25 */ | |
26 static struct { | |
27 PSID owner; | |
28 PSID group; | |
29 PSID everyone; | |
30 } _pr_nt_sids; | |
31 | |
32 /* | |
33 * Initialize the SIDs for owner, primary group, and the Everyone | |
34 * group in the _pr_nt_sids structure. | |
35 * | |
36 * This function needs to be called by NSPR initialization. | |
37 */ | |
38 void _PR_NT_InitSids(void) | |
39 { | |
40 #ifdef WINCE /* not supported */ | |
41 return; | |
42 #else | |
43 SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; | |
44 HANDLE hToken = NULL; /* initialized to an arbitrary value to | |
45 * silence a Purify UMR warning */ | |
46 PSID infoBuffer[1024/sizeof(PSID)]; /* defined as an array of PSIDs | |
47 * to force proper alignment */ | |
48 PTOKEN_OWNER pTokenOwner = (PTOKEN_OWNER) infoBuffer; | |
49 PTOKEN_PRIMARY_GROUP pTokenPrimaryGroup | |
50 = (PTOKEN_PRIMARY_GROUP) infoBuffer; | |
51 DWORD dwLength; | |
52 BOOL rv; | |
53 | |
54 /* | |
55 * Look up and make a copy of the owner and primary group | |
56 * SIDs in the access token of the calling process. | |
57 */ | |
58 rv = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken); | |
59 if (rv == 0) { | |
60 /* | |
61 * On non-NT systems, this function is not implemented | |
62 * (error code ERROR_CALL_NOT_IMPLEMENTED), and neither are | |
63 * the other security functions. There is no point in | |
64 * going further. | |
65 * | |
66 * A process with insufficient access permissions may fail | |
67 * with the error code ERROR_ACCESS_DENIED. | |
68 */ | |
69 PR_LOG(_pr_io_lm, PR_LOG_DEBUG, | |
70 ("_PR_NT_InitSids: OpenProcessToken() failed. Error: %d", | |
71 GetLastError())); | |
72 return; | |
73 } | |
74 | |
75 rv = GetTokenInformation(hToken, TokenOwner, infoBuffer, | |
76 sizeof(infoBuffer), &dwLength); | |
77 PR_ASSERT(rv != 0); | |
78 dwLength = GetLengthSid(pTokenOwner->Owner); | |
79 _pr_nt_sids.owner = (PSID) PR_Malloc(dwLength); | |
80 PR_ASSERT(_pr_nt_sids.owner != NULL); | |
81 rv = CopySid(dwLength, _pr_nt_sids.owner, pTokenOwner->Owner); | |
82 PR_ASSERT(rv != 0); | |
83 | |
84 rv = GetTokenInformation(hToken, TokenPrimaryGroup, infoBuffer, | |
85 sizeof(infoBuffer), &dwLength); | |
86 PR_ASSERT(rv != 0); | |
87 dwLength = GetLengthSid(pTokenPrimaryGroup->PrimaryGroup); | |
88 _pr_nt_sids.group = (PSID) PR_Malloc(dwLength); | |
89 PR_ASSERT(_pr_nt_sids.group != NULL); | |
90 rv = CopySid(dwLength, _pr_nt_sids.group, | |
91 pTokenPrimaryGroup->PrimaryGroup); | |
92 PR_ASSERT(rv != 0); | |
93 | |
94 rv = CloseHandle(hToken); | |
95 PR_ASSERT(rv != 0); | |
96 | |
97 /* Create a well-known SID for the Everyone group. */ | |
98 rv = AllocateAndInitializeSid(&SIDAuthWorld, 1, | |
99 SECURITY_WORLD_RID, | |
100 0, 0, 0, 0, 0, 0, 0, | |
101 &_pr_nt_sids.everyone); | |
102 PR_ASSERT(rv != 0); | |
103 #endif | |
104 } | |
105 | |
106 /* | |
107 * Free the SIDs for owner, primary group, and the Everyone group | |
108 * in the _pr_nt_sids structure. | |
109 * | |
110 * This function needs to be called by NSPR cleanup. | |
111 */ | |
112 void | |
113 _PR_NT_FreeSids(void) | |
114 { | |
115 #ifdef WINCE | |
116 return; | |
117 #else | |
118 if (_pr_nt_sids.owner) { | |
119 PR_Free(_pr_nt_sids.owner); | |
120 } | |
121 if (_pr_nt_sids.group) { | |
122 PR_Free(_pr_nt_sids.group); | |
123 } | |
124 if (_pr_nt_sids.everyone) { | |
125 FreeSid(_pr_nt_sids.everyone); | |
126 } | |
127 #endif | |
128 } | |
129 | |
130 /* | |
131 * Construct a security descriptor whose discretionary access-control | |
132 * list implements the specified mode bits. The SIDs for owner, group, | |
133 * and everyone are obtained from the global _pr_nt_sids structure. | |
134 * Both the security descriptor and access-control list are returned | |
135 * and should be freed by a _PR_NT_FreeSecurityDescriptorACL call. | |
136 * | |
137 * The accessTable array maps NSPR's read, write, and execute access | |
138 * rights to the corresponding NT access rights for the securable | |
139 * object. | |
140 */ | |
141 PRStatus | |
142 _PR_NT_MakeSecurityDescriptorACL( | |
143 PRIntn mode, | |
144 DWORD accessTable[], | |
145 PSECURITY_DESCRIPTOR *resultSD, | |
146 PACL *resultACL) | |
147 { | |
148 #ifdef WINCE | |
149 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); | |
150 return PR_FAILURE; | |
151 #else | |
152 PSECURITY_DESCRIPTOR pSD = NULL; | |
153 PACL pACL = NULL; | |
154 DWORD cbACL; /* size of ACL */ | |
155 DWORD accessMask; | |
156 | |
157 if (_pr_nt_sids.owner == NULL) { | |
158 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); | |
159 return PR_FAILURE; | |
160 } | |
161 | |
162 pSD = (PSECURITY_DESCRIPTOR) PR_Malloc(SECURITY_DESCRIPTOR_MIN_LENGTH); | |
163 if (pSD == NULL) { | |
164 _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); | |
165 goto failed; | |
166 } | |
167 if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) { | |
168 _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); | |
169 goto failed; | |
170 } | |
171 if (!SetSecurityDescriptorOwner(pSD, _pr_nt_sids.owner, FALSE)) { | |
172 _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); | |
173 goto failed; | |
174 } | |
175 if (!SetSecurityDescriptorGroup(pSD, _pr_nt_sids.group, FALSE)) { | |
176 _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); | |
177 goto failed; | |
178 } | |
179 | |
180 /* | |
181 * Construct a discretionary access-control list with three | |
182 * access-control entries, one each for owner, primary group, | |
183 * and Everyone. | |
184 */ | |
185 | |
186 cbACL = sizeof(ACL) | |
187 + 3 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) | |
188 + GetLengthSid(_pr_nt_sids.owner) | |
189 + GetLengthSid(_pr_nt_sids.group) | |
190 + GetLengthSid(_pr_nt_sids.everyone); | |
191 pACL = (PACL) PR_Malloc(cbACL); | |
192 if (pACL == NULL) { | |
193 _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); | |
194 goto failed; | |
195 } | |
196 if (!InitializeAcl(pACL, cbACL, ACL_REVISION)) { | |
197 _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); | |
198 goto failed; | |
199 } | |
200 accessMask = 0; | |
201 if (mode & 00400) accessMask |= accessTable[0]; | |
202 if (mode & 00200) accessMask |= accessTable[1]; | |
203 if (mode & 00100) accessMask |= accessTable[2]; | |
204 if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask, | |
205 _pr_nt_sids.owner)) { | |
206 _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); | |
207 goto failed; | |
208 } | |
209 accessMask = 0; | |
210 if (mode & 00040) accessMask |= accessTable[0]; | |
211 if (mode & 00020) accessMask |= accessTable[1]; | |
212 if (mode & 00010) accessMask |= accessTable[2]; | |
213 if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask, | |
214 _pr_nt_sids.group)) { | |
215 _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); | |
216 goto failed; | |
217 } | |
218 accessMask = 0; | |
219 if (mode & 00004) accessMask |= accessTable[0]; | |
220 if (mode & 00002) accessMask |= accessTable[1]; | |
221 if (mode & 00001) accessMask |= accessTable[2]; | |
222 if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask, | |
223 _pr_nt_sids.everyone)) { | |
224 _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); | |
225 goto failed; | |
226 } | |
227 | |
228 if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) { | |
229 _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); | |
230 goto failed; | |
231 } | |
232 | |
233 *resultSD = pSD; | |
234 *resultACL = pACL; | |
235 return PR_SUCCESS; | |
236 | |
237 failed: | |
238 if (pSD) { | |
239 PR_Free(pSD); | |
240 } | |
241 if (pACL) { | |
242 PR_Free(pACL); | |
243 } | |
244 return PR_FAILURE; | |
245 #endif | |
246 } | |
247 | |
248 /* | |
249 * Free the specified security descriptor and access-control list | |
250 * previously created by _PR_NT_MakeSecurityDescriptorACL. | |
251 */ | |
252 void | |
253 _PR_NT_FreeSecurityDescriptorACL(PSECURITY_DESCRIPTOR pSD, PACL pACL) | |
254 { | |
255 if (pSD) { | |
256 PR_Free(pSD); | |
257 } | |
258 if (pACL) { | |
259 PR_Free(pACL); | |
260 } | |
261 } |