Fix CreateProcessA to implement correct actions on ambiguous command
[wine/multimedia.git] / dlls / ntdll / sec.c
blob9414b9f2632679b9fbc24ae34d83500abaadf8f4
1 /*
2 * Security functions
4 * Copyright 1996-1998 Marcus Meissner
5 */
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 "debug.h"
21 #include "winuser.h"
22 #include "winerror.h"
23 #include "stackframe.h"
25 #include "ntddk.h"
26 #include "winreg.h"
28 DEFAULT_DEBUG_CHANNEL(ntdll)
31 * SID FUNCTIONS
34 /******************************************************************************
35 * RtlAllocateAndInitializeSid [NTDLL.265]
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)
41 FIXME(ntdll,"(%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;
45 /******************************************************************************
46 * RtlEqualSid [NTDLL.352]
49 DWORD WINAPI RtlEqualSid(DWORD x1,DWORD x2)
51 FIXME(ntdll,"(0x%08lx,0x%08lx),stub!\n", x1,x2);
52 return TRUE;
55 /******************************************************************************
56 * RtlFreeSid [NTDLL.376]
58 DWORD WINAPI RtlFreeSid(DWORD x1)
60 FIXME(ntdll,"(0x%08lx),stub!\n", x1);
61 return TRUE;
64 /**************************************************************************
65 * RtlLengthRequiredSid [NTDLL.427]
67 DWORD WINAPI RtlLengthRequiredSid(DWORD nrofsubauths)
69 return sizeof(DWORD)*nrofsubauths+sizeof(SID);
72 /**************************************************************************
73 * RtlLengthSid [NTDLL.429]
75 DWORD WINAPI RtlLengthSid(PSID sid)
77 TRACE(ntdll,"sid=%p\n",sid);
78 if (!sid)
79 return FALSE;
80 return sizeof(DWORD)*sid->SubAuthorityCount+sizeof(SID);
83 /**************************************************************************
84 * RtlInitializeSid [NTDLL.410]
86 DWORD WINAPI RtlInitializeSid(PSID PSID,PSID_IDENTIFIER_AUTHORITY PSIDauth,
87 DWORD c)
89 BYTE a = c&0xff;
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;
99 /**************************************************************************
100 * RtlSubAuthoritySid [NTDLL.497]
102 LPDWORD WINAPI RtlSubAuthoritySid(PSID PSID,DWORD nr)
104 return &(PSID->SubAuthority[nr]);
107 /**************************************************************************
108 * RtlSubAuthorityCountSid [NTDLL.496]
111 LPBYTE WINAPI RtlSubAuthorityCountSid(PSID PSID)
113 return ((LPBYTE)PSID)+1;
116 /**************************************************************************
117 * RtlCopySid [NTDLL.302]
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;
129 * security descriptor functions
132 /**************************************************************************
133 * RtlCreateSecurityDescriptor [NTDLL.313]
135 * RETURNS:
136 * 0 success,
137 * STATUS_INVALID_OWNER, STATUS_PRIVILEGE_NOT_HELD, STATUS_NO_INHERITANCE,
138 * STATUS_NO_MEMORY
140 NTSTATUS WINAPI RtlCreateSecurityDescriptor(
141 PSECURITY_DESCRIPTOR lpsd,
142 DWORD rev)
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;
150 /**************************************************************************
151 * RtlValidSecurityDescriptor [NTDLL.313]
154 NTSTATUS WINAPI RtlValidSecurityDescriptor(
155 PSECURITY_DESCRIPTOR SecurityDescriptor)
157 if ( ! SecurityDescriptor )
158 return STATUS_INVALID_SECURITY_DESCR;
159 if ( SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION )
160 return STATUS_UNKNOWN_REVISION;
162 return STATUS_SUCCESS;
165 /**************************************************************************
166 * RtlLengthSecurityDescriptor [NTDLL]
168 ULONG WINAPI RtlLengthSecurityDescriptor(
169 PSECURITY_DESCRIPTOR SecurityDescriptor)
171 ULONG Size;
172 Size = SECURITY_DESCRIPTOR_MIN_LENGTH;
173 if ( SecurityDescriptor == NULL )
174 return 0;
176 if ( SecurityDescriptor->Owner != NULL )
177 Size += SecurityDescriptor->Owner->SubAuthorityCount;
178 if ( SecurityDescriptor->Group != NULL )
179 Size += SecurityDescriptor->Group->SubAuthorityCount;
182 if ( SecurityDescriptor->Sacl != NULL )
183 Size += SecurityDescriptor->Sacl->AclSize;
184 if ( SecurityDescriptor->Dacl != NULL )
185 Size += SecurityDescriptor->Dacl->AclSize;
187 return Size;
190 /******************************************************************************
191 * RtlGetDaclSecurityDescriptor [NTDLL]
194 NTSTATUS WINAPI RtlGetDaclSecurityDescriptor(
195 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
196 OUT PBOOLEAN lpbDaclPresent,
197 OUT PACL *pDacl,
198 OUT PBOOLEAN lpbDaclDefaulted)
200 TRACE(ntdll,"(%p,%p,%p,%p)\n",
201 pSecurityDescriptor, lpbDaclPresent, *pDacl, lpbDaclDefaulted);
203 if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
204 return STATUS_UNKNOWN_REVISION ;
206 if ( (*lpbDaclPresent = (SE_DACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
208 if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
209 { *pDacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Dacl);
211 else
212 { *pDacl = pSecurityDescriptor->Dacl;
216 *lpbDaclDefaulted = (( SE_DACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
218 return STATUS_SUCCESS;
221 /**************************************************************************
222 * RtlSetDaclSecurityDescriptor [NTDLL.483]
224 NTSTATUS WINAPI RtlSetDaclSecurityDescriptor (
225 PSECURITY_DESCRIPTOR lpsd,
226 BOOLEAN daclpresent,
227 PACL dacl,
228 BOOLEAN dacldefaulted )
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;
235 if (!daclpresent)
236 { lpsd->Control &= ~SE_DACL_PRESENT;
237 return TRUE;
240 lpsd->Control |= SE_DACL_PRESENT;
241 lpsd->Dacl = dacl;
243 if (dacldefaulted)
244 lpsd->Control |= SE_DACL_DEFAULTED;
245 else
246 lpsd->Control &= ~SE_DACL_DEFAULTED;
248 return STATUS_SUCCESS;
251 /******************************************************************************
252 * RtlGetSaclSecurityDescriptor [NTDLL]
255 NTSTATUS WINAPI RtlGetSaclSecurityDescriptor(
256 IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
257 OUT PBOOLEAN lpbSaclPresent,
258 OUT PACL *pSacl,
259 OUT PBOOLEAN lpbSaclDefaulted)
261 TRACE(ntdll,"(%p,%p,%p,%p)\n",
262 pSecurityDescriptor, lpbSaclPresent, *pSacl, lpbSaclDefaulted);
264 if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
265 return STATUS_UNKNOWN_REVISION ;
267 if ( (*lpbSaclPresent = (SE_SACL_PRESENT & pSecurityDescriptor->Control) ? 1 : 0) )
269 if ( SE_SELF_RELATIVE & pSecurityDescriptor->Control)
270 { *pSacl = (PACL) ((LPBYTE)pSecurityDescriptor + (DWORD)pSecurityDescriptor->Sacl);
272 else
273 { *pSacl = pSecurityDescriptor->Sacl;
277 *lpbSaclDefaulted = (( SE_SACL_DEFAULTED & pSecurityDescriptor->Control ) ? 1 : 0);
279 return STATUS_SUCCESS;
282 /**************************************************************************
283 * RtlSetSaclSecurityDescriptor [NTDLL.488]
285 NTSTATUS WINAPI RtlSetSaclSecurityDescriptor (
286 PSECURITY_DESCRIPTOR lpsd,
287 BOOLEAN saclpresent,
288 PACL sacl,
289 BOOLEAN sacldefaulted)
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;
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;
308 /**************************************************************************
309 * RtlGetOwnerSecurityDescriptor [NTDLL.488]
311 NTSTATUS WINAPI RtlGetOwnerSecurityDescriptor(
312 PSECURITY_DESCRIPTOR SecurityDescriptor,
313 PSID *Owner,
314 PBOOLEAN OwnerDefaulted)
316 if ( !SecurityDescriptor || !Owner || !OwnerDefaulted )
317 return STATUS_INVALID_PARAMETER;
319 *Owner = SecurityDescriptor->Owner;
320 if ( *Owner != NULL ) {
321 if ( SecurityDescriptor->Control & SE_OWNER_DEFAULTED )
322 *OwnerDefaulted = TRUE;
323 else
324 *OwnerDefaulted = FALSE;
326 return STATUS_SUCCESS;
329 /**************************************************************************
330 * RtlSetOwnerSecurityDescriptor [NTDLL.487]
332 NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(
333 PSECURITY_DESCRIPTOR lpsd,
334 PSID owner,
335 BOOLEAN ownerdefaulted)
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;
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;
350 /**************************************************************************
351 * RtlSetGroupSecurityDescriptor [NTDLL.485]
353 NTSTATUS WINAPI RtlSetGroupSecurityDescriptor (
354 PSECURITY_DESCRIPTOR lpsd,
355 PSID group,
356 BOOLEAN groupdefaulted)
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;
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;
370 /**************************************************************************
371 * RtlGetGroupSecurityDescriptor [NTDLL]
373 NTSTATUS WINAPI RtlGetGroupSecurityDescriptor(
374 PSECURITY_DESCRIPTOR SecurityDescriptor,
375 PSID *Group,
376 PBOOLEAN GroupDefaulted)
378 if ( !SecurityDescriptor || !Group || !GroupDefaulted )
379 return STATUS_INVALID_PARAMETER;
381 *Group = SecurityDescriptor->Group;
382 if ( *Group != NULL ) {
383 if ( SecurityDescriptor->Control & SE_GROUP_DEFAULTED )
384 *GroupDefaulted = TRUE;
385 else
386 *GroupDefaulted = FALSE;
388 return STATUS_SUCCESS;
392 * access control list's
395 /**************************************************************************
396 * RtlCreateAcl [NTDLL.306]
398 * NOTES
399 * This should return NTSTATUS
401 DWORD WINAPI RtlCreateAcl(PACL acl,DWORD size,DWORD rev)
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;
410 memset(acl,'\0',sizeof(ACL));
411 acl->AclRevision = rev;
412 acl->AclSize = size;
413 acl->AceCount = 0;
414 return 0;
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
422 BOOLEAN WINAPI RtlFirstFreeAce(
423 PACL acl,
424 PACE_HEADER *x)
426 PACE_HEADER ace;
427 int i;
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);
436 if ((DWORD)ace>=(((DWORD)acl)+acl->AclSize))
437 return 0;
438 *x = ace;
439 return 1;
442 /**************************************************************************
443 * RtlAddAce [NTDLL.260]
445 NTSTATUS WINAPI RtlAddAce(
446 PACL acl,
447 DWORD rev,
448 DWORD xnrofaces,
449 PACE_HEADER acestart,
450 DWORD acelen)
452 PACE_HEADER ace,targetace;
453 int nrofaces;
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);
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;
471 /******************************************************************************
472 * RtlAddAccessAllowedAce [NTDLL]
474 DWORD WINAPI RtlAddAccessAllowedAce(DWORD x1,DWORD x2,DWORD x3,DWORD x4)
476 FIXME(ntdll,"(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
477 return 0;
480 /******************************************************************************
481 * RtlGetAce [NTDLL]
483 DWORD WINAPI RtlGetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
485 FIXME(ntdll,"(%p,%ld,%p),stub!\n",pAcl,dwAceIndex,pAce);
486 return 0;
490 * misc
493 /******************************************************************************
494 * RtlAdjustPrivilege [NTDLL]
496 DWORD WINAPI RtlAdjustPrivilege(DWORD x1,DWORD x2,DWORD x3,DWORD x4)
498 FIXME(ntdll,"(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4);
499 return 0;