Added DebugBreak.
[wine] / dlls / ntdll / sec.c
1 /*
2  *      Security functions
3  *
4  *      Copyright 1996-1998 Marcus Meissner
5  */
6
7 #include <stdlib.h>
8 #include <string.h>
9 #include <time.h>
10 #include <ctype.h>
11 #include <math.h>
12 #include "windef.h"
13 #include "winbase.h"
14 #include "winuser.h"
15 #include "wine/winestring.h"
16 #include "file.h"
17 #include "heap.h"
18 #include "winnls.h"
19 #include "debugstr.h"
20 #include "debugtools.h"
21 #include "winuser.h"
22 #include "winerror.h"
23 #include "stackframe.h"
24
25 #include "ntddk.h"
26 #include "winreg.h"
27
28 DEFAULT_DEBUG_CHANNEL(ntdll)
29
30 /*
31  *      SID FUNCTIONS
32  */
33
34 /******************************************************************************
35  *  RtlAllocateAndInitializeSid         [NTDLL.265] 
36  *
37  */
38 BOOLEAN WINAPI RtlAllocateAndInitializeSid (PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
39         DWORD nSubAuthorityCount,DWORD x3,DWORD x4,DWORD x5,DWORD x6,DWORD x7,DWORD x8,DWORD x9,DWORD x10, PSID pSid) 
40 {
41         FIXME("(%p,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p),stub!\n",
42                 pIdentifierAuthority,nSubAuthorityCount,x3,x4,x5,x6,x7,x8,x9,x10,pSid);
43         return 0;
44 }
45 /******************************************************************************
46  *  RtlEqualSid         [NTDLL.352] 
47  *
48  */
49 DWORD WINAPI RtlEqualSid(DWORD x1,DWORD x2) 
50 {       
51         FIXME("(0x%08lx,0x%08lx),stub!\n", x1,x2);
52         return TRUE;
53 }
54
55 /******************************************************************************
56  *  RtlFreeSid          [NTDLL.376] 
57  */
58 DWORD WINAPI RtlFreeSid(DWORD x1) 
59 {
60         FIXME("(0x%08lx),stub!\n", x1);
61         return TRUE;
62 }
63
64 /**************************************************************************
65  *                 RtlLengthRequiredSid                 [NTDLL.427]
66  */
67 DWORD WINAPI RtlLengthRequiredSid(DWORD nrofsubauths)
68 {
69         return sizeof(DWORD)*nrofsubauths+sizeof(SID);
70 }
71
72 /**************************************************************************
73  *                 RtlLengthSid                         [NTDLL.429]
74  */
75 DWORD WINAPI RtlLengthSid(PSID sid)
76 {
77         TRACE("sid=%p\n",sid);
78         if (!sid)
79           return FALSE; 
80         return sizeof(DWORD)*sid->SubAuthorityCount+sizeof(SID);
81 }
82
83 /**************************************************************************
84  *                 RtlInitializeSid                     [NTDLL.410]
85  */
86 DWORD WINAPI RtlInitializeSid(PSID PSID,PSID_IDENTIFIER_AUTHORITY PSIDauth,
87                               DWORD c)
88 {
89         BYTE    a = c&0xff;
90
91         if (a>=SID_MAX_SUB_AUTHORITIES)
92                 return a;
93         PSID->SubAuthorityCount = a;
94         PSID->Revision           = SID_REVISION;
95         memcpy(&(PSID->IdentifierAuthority),PSIDauth,sizeof(SID_IDENTIFIER_AUTHORITY));
96         return STATUS_SUCCESS;
97 }
98
99 /**************************************************************************
100  *                 RtlSubAuthoritySid                   [NTDLL.497]
101  */
102 LPDWORD WINAPI RtlSubAuthoritySid(PSID PSID,DWORD nr)
103 {
104         return &(PSID->SubAuthority[nr]);
105 }
106
107 /**************************************************************************
108  *                 RtlSubAuthorityCountSid              [NTDLL.496]
109  */
110
111 LPBYTE WINAPI RtlSubAuthorityCountSid(PSID PSID)
112 {
113         return ((LPBYTE)PSID)+1;
114 }
115
116 /**************************************************************************
117  *                 RtlCopySid                           [NTDLL.302]
118  */
119 DWORD WINAPI RtlCopySid(DWORD len,PSID to,PSID from)
120 {       if (!from)
121                 return 0;
122         if (len<(from->SubAuthorityCount*4+8))
123                 return STATUS_BUFFER_TOO_SMALL;
124         memmove(to,from,from->SubAuthorityCount*4+8);
125         return STATUS_SUCCESS;
126 }
127
128 /*
129  *      security descriptor functions
130  */
131
132 /**************************************************************************
133  * RtlCreateSecurityDescriptor                  [NTDLL.313]
134  *
135  * RETURNS:
136  *  0 success, 
137  *  STATUS_INVALID_OWNER, STATUS_PRIVILEGE_NOT_HELD, STATUS_NO_INHERITANCE,
138  *  STATUS_NO_MEMORY 
139  */
140 NTSTATUS WINAPI RtlCreateSecurityDescriptor(
141         PSECURITY_DESCRIPTOR lpsd,
142         DWORD rev)
143 {
144         if (rev!=SECURITY_DESCRIPTOR_REVISION)
145                 return STATUS_UNKNOWN_REVISION;
146         memset(lpsd,'\0',sizeof(*lpsd));
147         lpsd->Revision = SECURITY_DESCRIPTOR_REVISION;
148         return STATUS_SUCCESS;
149 }
150 /**************************************************************************
151  * RtlValidSecurityDescriptor                   [NTDLL.313]
152  *
153  */
154 NTSTATUS WINAPI RtlValidSecurityDescriptor(
155         PSECURITY_DESCRIPTOR SecurityDescriptor)
156 {
157         if ( ! SecurityDescriptor )
158                 return STATUS_INVALID_SECURITY_DESCR;
159         if ( SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION )
160                 return STATUS_UNKNOWN_REVISION;
161
162         return STATUS_SUCCESS;
163 }
164
165 /**************************************************************************
166  *  RtlLengthSecurityDescriptor                 [NTDLL]
167  */
168 ULONG WINAPI RtlLengthSecurityDescriptor(
169         PSECURITY_DESCRIPTOR SecurityDescriptor)
170 {
171         ULONG Size;
172         Size = SECURITY_DESCRIPTOR_MIN_LENGTH;
173         if ( SecurityDescriptor == NULL )
174                 return 0;
175
176         if ( SecurityDescriptor->Owner != NULL )
177                 Size += SecurityDescriptor->Owner->SubAuthorityCount;
178         if ( SecurityDescriptor->Group != NULL )
179                 Size += SecurityDescriptor->Group->SubAuthorityCount;
180
181
182         if ( SecurityDescriptor->Sacl != NULL )
183                 Size += SecurityDescriptor->Sacl->AclSize;
184         if ( SecurityDescriptor->Dacl != NULL )
185                 Size += SecurityDescriptor->Dacl->AclSize;
186
187         return Size;
188 }
189
190 /******************************************************************************
191  *  RtlGetDaclSecurityDescriptor                [NTDLL] 
192  *
193  */
194 NTSTATUS WINAPI RtlGetDaclSecurityDescriptor(
195         IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
196         OUT PBOOLEAN lpbDaclPresent,
197         OUT PACL *pDacl,
198         OUT PBOOLEAN lpbDaclDefaulted)
199 {
200         TRACE("(%p,%p,%p,%p)\n",
201         pSecurityDescriptor, lpbDaclPresent, *pDacl, lpbDaclDefaulted);
202
203         if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
204           return STATUS_UNKNOWN_REVISION ;
205
206         if ( (*lpbDaclPresent = (SE_DACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
207         {
208           if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
209           { *pDacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Dacl);
210           }
211           else
212           { *pDacl = pSecurityDescriptor->Dacl;
213           }
214         }
215
216         *lpbDaclDefaulted = (( SE_DACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
217         
218         return STATUS_SUCCESS;
219 }
220
221 /**************************************************************************
222  *  RtlSetDaclSecurityDescriptor                [NTDLL.483]
223  */
224 NTSTATUS WINAPI RtlSetDaclSecurityDescriptor (
225         PSECURITY_DESCRIPTOR lpsd,
226         BOOLEAN daclpresent,
227         PACL dacl,
228         BOOLEAN dacldefaulted )
229 {
230         if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
231                 return STATUS_UNKNOWN_REVISION;
232         if (lpsd->Control & SE_SELF_RELATIVE)
233                 return STATUS_INVALID_SECURITY_DESCR;
234
235         if (!daclpresent) 
236         {       lpsd->Control &= ~SE_DACL_PRESENT;
237                 return TRUE;
238         }
239
240         lpsd->Control |= SE_DACL_PRESENT;
241         lpsd->Dacl = dacl;
242
243         if (dacldefaulted)
244                 lpsd->Control |= SE_DACL_DEFAULTED;
245         else
246                 lpsd->Control &= ~SE_DACL_DEFAULTED;
247
248         return STATUS_SUCCESS;
249 }
250
251 /******************************************************************************
252  *  RtlGetSaclSecurityDescriptor                [NTDLL] 
253  *
254  */
255 NTSTATUS WINAPI RtlGetSaclSecurityDescriptor(
256         IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
257         OUT PBOOLEAN lpbSaclPresent,
258         OUT PACL *pSacl,
259         OUT PBOOLEAN lpbSaclDefaulted)
260 {
261         TRACE("(%p,%p,%p,%p)\n",
262         pSecurityDescriptor, lpbSaclPresent, *pSacl, lpbSaclDefaulted);
263
264         if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
265           return STATUS_UNKNOWN_REVISION ;
266
267         if ( (*lpbSaclPresent = (SE_SACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
268         {
269           if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
270           { *pSacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Sacl);
271           }
272           else
273           { *pSacl = pSecurityDescriptor->Sacl;
274           }
275         }
276
277         *lpbSaclDefaulted = (( SE_SACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
278         
279         return STATUS_SUCCESS;
280 }
281
282 /**************************************************************************
283  * RtlSetSaclSecurityDescriptor                 [NTDLL.488]
284  */
285 NTSTATUS WINAPI RtlSetSaclSecurityDescriptor (
286         PSECURITY_DESCRIPTOR lpsd,
287         BOOLEAN saclpresent,
288         PACL sacl,
289         BOOLEAN sacldefaulted)
290 {
291         if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
292                 return STATUS_UNKNOWN_REVISION;
293         if (lpsd->Control & SE_SELF_RELATIVE)
294                 return STATUS_INVALID_SECURITY_DESCR;
295         if (!saclpresent) {
296                 lpsd->Control &= ~SE_SACL_PRESENT;
297                 return 0;
298         }
299         lpsd->Control |= SE_SACL_PRESENT;
300         lpsd->Sacl = sacl;
301         if (sacldefaulted)
302                 lpsd->Control |= SE_SACL_DEFAULTED;
303         else
304                 lpsd->Control &= ~SE_SACL_DEFAULTED;
305         return STATUS_SUCCESS;
306 }
307
308 /**************************************************************************
309  * RtlGetOwnerSecurityDescriptor                [NTDLL.488]
310  */
311 NTSTATUS WINAPI RtlGetOwnerSecurityDescriptor(
312         PSECURITY_DESCRIPTOR SecurityDescriptor,
313         PSID *Owner,
314         PBOOLEAN OwnerDefaulted)
315 {
316         if ( !SecurityDescriptor  || !Owner || !OwnerDefaulted )
317                 return STATUS_INVALID_PARAMETER;
318
319         *Owner = SecurityDescriptor->Owner;
320         if ( *Owner != NULL )  {
321                 if ( SecurityDescriptor->Control & SE_OWNER_DEFAULTED )
322                         *OwnerDefaulted = TRUE;
323                 else
324                         *OwnerDefaulted = FALSE;
325         }
326         return STATUS_SUCCESS;
327 }
328
329 /**************************************************************************
330  *                 RtlSetOwnerSecurityDescriptor                [NTDLL.487]
331  */
332 NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(
333         PSECURITY_DESCRIPTOR lpsd,
334         PSID owner,
335         BOOLEAN ownerdefaulted)
336 {
337         if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
338                 return STATUS_UNKNOWN_REVISION;
339         if (lpsd->Control & SE_SELF_RELATIVE)
340                 return STATUS_INVALID_SECURITY_DESCR;
341
342         lpsd->Owner = owner;
343         if (ownerdefaulted)
344                 lpsd->Control |= SE_OWNER_DEFAULTED;
345         else
346                 lpsd->Control &= ~SE_OWNER_DEFAULTED;
347         return STATUS_SUCCESS;
348 }
349
350 /**************************************************************************
351  *                 RtlSetGroupSecurityDescriptor                [NTDLL.485]
352  */
353 NTSTATUS WINAPI RtlSetGroupSecurityDescriptor (
354         PSECURITY_DESCRIPTOR lpsd,
355         PSID group,
356         BOOLEAN groupdefaulted)
357 {
358         if (lpsd->Revision!=SECURITY_DESCRIPTOR_REVISION)
359                 return STATUS_UNKNOWN_REVISION;
360         if (lpsd->Control & SE_SELF_RELATIVE)
361                 return STATUS_INVALID_SECURITY_DESCR;
362
363         lpsd->Group = group;
364         if (groupdefaulted)
365                 lpsd->Control |= SE_GROUP_DEFAULTED;
366         else
367                 lpsd->Control &= ~SE_GROUP_DEFAULTED;
368         return STATUS_SUCCESS;
369 }
370 /**************************************************************************
371  *                 RtlGetGroupSecurityDescriptor                [NTDLL]
372  */
373 NTSTATUS WINAPI RtlGetGroupSecurityDescriptor(
374         PSECURITY_DESCRIPTOR SecurityDescriptor,
375         PSID *Group,
376         PBOOLEAN GroupDefaulted)
377 {
378         if ( !SecurityDescriptor || !Group || !GroupDefaulted )
379                 return STATUS_INVALID_PARAMETER;
380
381         *Group = SecurityDescriptor->Group;
382         if ( *Group != NULL )  {
383                 if ( SecurityDescriptor->Control & SE_GROUP_DEFAULTED )
384                         *GroupDefaulted = TRUE;
385                 else
386                         *GroupDefaulted = FALSE;
387         }
388         return STATUS_SUCCESS;
389
390
391 /*
392  *      access control list's
393  */
394
395 /**************************************************************************
396  *                 RtlCreateAcl                         [NTDLL.306]
397  *
398  * NOTES
399  *    This should return NTSTATUS
400  */
401 DWORD WINAPI RtlCreateAcl(PACL acl,DWORD size,DWORD rev)
402 {
403         if (rev!=ACL_REVISION)
404                 return STATUS_INVALID_PARAMETER;
405         if (size<sizeof(ACL))
406                 return STATUS_BUFFER_TOO_SMALL;
407         if (size>0xFFFF)
408                 return STATUS_INVALID_PARAMETER;
409
410         memset(acl,'\0',sizeof(ACL));
411         acl->AclRevision        = rev;
412         acl->AclSize            = size;
413         acl->AceCount           = 0;
414         return 0;
415 }
416
417 /**************************************************************************
418  *                 RtlFirstFreeAce                      [NTDLL.370]
419  * looks for the AceCount+1 ACE, and if it is still within the alloced
420  * ACL, return a pointer to it
421  */
422 BOOLEAN WINAPI RtlFirstFreeAce(
423         PACL acl,
424         PACE_HEADER *x)
425 {
426         PACE_HEADER     ace;
427         int             i;
428
429         *x = 0;
430         ace = (PACE_HEADER)(acl+1);
431         for (i=0;i<acl->AceCount;i++) {
432                 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
433                         return 0;
434                 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
435         }
436         if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
437                 return 0;
438         *x = ace;
439         return 1;
440 }
441
442 /**************************************************************************
443  *                 RtlAddAce                            [NTDLL.260]
444  */
445 NTSTATUS WINAPI RtlAddAce(
446         PACL acl,
447         DWORD rev,
448         DWORD xnrofaces,
449         PACE_HEADER acestart,
450         DWORD acelen)
451 {
452         PACE_HEADER     ace,targetace;
453         int             nrofaces;
454
455         if (acl->AclRevision != ACL_REVISION)
456                 return STATUS_INVALID_PARAMETER;
457         if (!RtlFirstFreeAce(acl,&targetace))
458                 return STATUS_INVALID_PARAMETER;
459         nrofaces=0;ace=acestart;
460         while (((DWORD)ace-(DWORD)acestart)<acelen) {
461                 nrofaces++;
462                 ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
463         }
464         if ((DWORD)targetace+acelen>(DWORD)acl+acl->AclSize) /* too much aces */
465                 return STATUS_INVALID_PARAMETER;
466         memcpy((LPBYTE)targetace,acestart,acelen);
467         acl->AceCount+=nrofaces;
468         return STATUS_SUCCESS;
469 }
470
471 /******************************************************************************
472  *  RtlAddAccessAllowedAce              [NTDLL] 
473  */
474 DWORD WINAPI RtlAddAccessAllowedAce(DWORD x1,DWORD x2,DWORD x3,DWORD x4) 
475 {
476         FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
477         return 0;
478 }
479
480 /******************************************************************************
481  *  RtlGetAce           [NTDLL] 
482  */
483 DWORD WINAPI RtlGetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce ) 
484 {
485         FIXME("(%p,%ld,%p),stub!\n",pAcl,dwAceIndex,pAce);
486         return 0;
487 }
488
489 /*
490  *      misc
491  */
492
493 /******************************************************************************
494  *  RtlAdjustPrivilege          [NTDLL] 
495  */
496 DWORD WINAPI RtlAdjustPrivilege(DWORD x1,DWORD x2,DWORD x3,DWORD x4) 
497 {
498         FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
499         return 0;
500 }
501