3462a33f13b368a1385520ac235e853dc0f5821b
[reactos.git] / reactos / dll / advapi32 / sec / sid.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * WINE COPYRIGHT:
5 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
6 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
7 *
8 * PROJECT: ReactOS system libraries
9 * FILE: lib/advapi32/sec/sid.c
10 * PURPOSE: Security ID functions
11 */
12
13 #include <advapi32.h>
14 #include <wine/debug.h>
15 #include <wine/unicode.h>
16
17 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
18
19
20 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
21 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
22 PACL pAcl, LPDWORD cBytes);
23 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
24 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
25 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
26 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
27
28 typedef struct _ACEFLAG
29 {
30 LPCWSTR wstr;
31 DWORD value;
32 } ACEFLAG, *LPACEFLAG;
33
34 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
35
36 /*
37 * ACE access rights
38 */
39 static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
40 static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
41 static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
42 static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
43 static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
44 static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
45 static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
46 static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
47
48 /*
49 * ACE types
50 */
51 static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
52 static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
53 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
54 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
55 static const WCHAR SDDL_AUDIT[] = {'A','U',0};
56 static const WCHAR SDDL_ALARM[] = {'A','L',0};
57 static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
58 static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
59
60 /*
61 * ACE flags
62 */
63 static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
64 static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
65 static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
66 static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
67 static const WCHAR SDDL_INHERITED[] = {'I','D',0};
68 static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
69 static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
70
71 /* set last error code from NT status and get the proper boolean return value */
72 /* used for functions that are a simple wrapper around the corresponding ntdll API */
73 static __inline BOOL set_ntstatus( NTSTATUS status )
74 {
75 if (status) SetLastError( RtlNtStatusToDosError( status ));
76 return !status;
77 }
78
79 #define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
80
81
82 /* some helper functions - taken from winehq cvs 20050916 */
83 /******************************************************************************
84 * ComputeStringSidSize
85 */
86 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
87 {
88 int ctok = 0;
89 DWORD size = sizeof(SID);
90
91 while (*StringSid)
92 {
93 if (*StringSid == '-')
94 ctok++;
95 StringSid++;
96 }
97
98 if (ctok > 3)
99 size += (ctok - 3) * sizeof(DWORD);
100
101 return size;
102 }
103
104 /******************************************************************************
105 * ParseAceStringType
106 */
107 ACEFLAG AceType[] =
108 {
109 { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
110 { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
111 { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
112 { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
113 /*
114 { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
115 { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
116 { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
117 { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
118 */
119 { NULL, 0 },
120 };
121
122 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
123 {
124 UINT len = 0;
125 LPCWSTR szAcl = *StringAcl;
126 LPACEFLAG lpaf = AceType;
127
128 while (lpaf->wstr &&
129 (len = strlenW(lpaf->wstr)) &&
130 strncmpW(lpaf->wstr, szAcl, len))
131 lpaf++;
132
133 if (!lpaf->wstr)
134 return 0;
135
136 *StringAcl += len;
137 return lpaf->value;
138 }
139
140
141 /******************************************************************************
142 * ParseAceStringFlags
143 */
144 ACEFLAG AceFlags[] =
145 {
146 { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
147 { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
148 { SDDL_INHERITED, INHERITED_ACE },
149 { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
150 { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
151 { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
152 { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
153 { NULL, 0 },
154 };
155
156 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
157 {
158 UINT len = 0;
159 BYTE flags = 0;
160 LPCWSTR szAcl = *StringAcl;
161
162 while (*szAcl != ';')
163 {
164 LPACEFLAG lpaf = AceFlags;
165
166 while (lpaf->wstr &&
167 (len = strlenW(lpaf->wstr)) &&
168 strncmpW(lpaf->wstr, szAcl, len))
169 lpaf++;
170
171 if (!lpaf->wstr)
172 return 0;
173
174 flags |= lpaf->value;
175 szAcl += len;
176 }
177
178 *StringAcl = szAcl;
179 return flags;
180 }
181
182
183 /******************************************************************************
184 * ParseAceStringRights
185 */
186 ACEFLAG AceRights[] =
187 {
188 { SDDL_GENERIC_ALL, GENERIC_ALL },
189 { SDDL_GENERIC_READ, GENERIC_READ },
190 { SDDL_GENERIC_WRITE, GENERIC_WRITE },
191 { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
192 { SDDL_READ_CONTROL, READ_CONTROL },
193 { SDDL_STANDARD_DELETE, DELETE },
194 { SDDL_WRITE_DAC, WRITE_DAC },
195 { SDDL_WRITE_OWNER, WRITE_OWNER },
196 { NULL, 0 },
197 };
198
199 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
200 {
201 UINT len = 0;
202 DWORD rights = 0;
203 LPCWSTR szAcl = *StringAcl;
204
205 if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
206 {
207 LPCWSTR p = szAcl;
208
209 while (*p && *p != ';')
210 p++;
211
212 if (p - szAcl <= 8)
213 {
214 rights = strtoulW(szAcl, NULL, 16);
215 *StringAcl = p;
216 }
217 else
218 WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
219 }
220 else
221 {
222 while (*szAcl != ';')
223 {
224 LPACEFLAG lpaf = AceRights;
225
226 while (lpaf->wstr &&
227 (len = strlenW(lpaf->wstr)) &&
228 strncmpW(lpaf->wstr, szAcl, len))
229 {
230 lpaf++;
231 }
232
233 if (!lpaf->wstr)
234 return 0;
235
236 rights |= lpaf->value;
237 szAcl += len;
238 }
239 }
240
241 *StringAcl = szAcl;
242 return rights;
243 }
244
245 /******************************************************************************
246 * ParseStringAclToAcl
247 *
248 * dacl_flags(string_ace1)(string_ace2)... (string_acen)
249 */
250 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
251 PACL pAcl, LPDWORD cBytes)
252 {
253 DWORD val;
254 DWORD sidlen;
255 DWORD length = sizeof(ACL);
256 PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
257
258 TRACE("%s\n", debugstr_w(StringAcl));
259
260 if (!StringAcl)
261 return FALSE;
262
263 if (pAcl) /* pAce is only useful if we're setting values */
264 pAce = (PACCESS_ALLOWED_ACE) ((LPBYTE)pAcl + sizeof(PACL));
265
266 /* Parse ACL flags */
267 *lpdwFlags = ParseAclStringFlags(&StringAcl);
268
269 /* Parse ACE */
270 while (*StringAcl == '(')
271 {
272 StringAcl++;
273
274 /* Parse ACE type */
275 val = ParseAceStringType(&StringAcl);
276 if (pAce)
277 pAce->Header.AceType = (BYTE) val;
278 if (*StringAcl != ';')
279 goto lerr;
280 StringAcl++;
281
282 /* Parse ACE flags */
283 val = ParseAceStringFlags(&StringAcl);
284 if (pAce)
285 pAce->Header.AceFlags = (BYTE) val;
286 if (*StringAcl != ';')
287 goto lerr;
288 StringAcl++;
289
290 /* Parse ACE rights */
291 val = ParseAceStringRights(&StringAcl);
292 if (pAce)
293 pAce->Mask = val;
294 if (*StringAcl != ';')
295 goto lerr;
296 StringAcl++;
297
298 /* Parse ACE object guid */
299 if (*StringAcl != ';')
300 {
301 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
302 goto lerr;
303 }
304 StringAcl++;
305
306 /* Parse ACE inherit object guid */
307 if (*StringAcl != ';')
308 {
309 FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
310 goto lerr;
311 }
312 StringAcl++;
313
314 /* Parse ACE account sid */
315 if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
316 {
317 while (*StringAcl && *StringAcl != ')')
318 StringAcl++;
319 }
320
321 if (*StringAcl != ')')
322 goto lerr;
323 StringAcl++;
324
325 length += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
326 }
327
328 *cBytes = length;
329 return TRUE;
330
331 lerr:
332 WARN("Invalid ACE string format\n");
333 return FALSE;
334 }
335
336 /******************************************************************************
337 * ParseStringSecurityDescriptorToSecurityDescriptor
338 */
339 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
340 LPCWSTR StringSecurityDescriptor,
341 SECURITY_DESCRIPTOR* SecurityDescriptor,
342 LPDWORD cBytes)
343 {
344 BOOL bret = FALSE;
345 WCHAR toktype;
346 WCHAR tok[MAX_PATH];
347 LPCWSTR lptoken;
348 LPBYTE lpNext = NULL;
349 DWORD len;
350
351 *cBytes = 0;
352
353 if (SecurityDescriptor)
354 lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
355
356 while (*StringSecurityDescriptor)
357 {
358 toktype = *StringSecurityDescriptor;
359
360 /* Expect char identifier followed by ':' */
361 StringSecurityDescriptor++;
362 if (*StringSecurityDescriptor != ':')
363 {
364 SetLastError(ERROR_INVALID_PARAMETER);
365 goto lend;
366 }
367 StringSecurityDescriptor++;
368
369 /* Extract token */
370 lptoken = StringSecurityDescriptor;
371 while (*lptoken && *lptoken != ':')
372 lptoken++;
373
374 if (*lptoken)
375 lptoken--;
376
377 len = lptoken - StringSecurityDescriptor;
378 memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
379 tok[len] = 0;
380
381 switch (toktype)
382 {
383 case 'O':
384 {
385 DWORD bytes;
386
387 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
388 goto lend;
389
390 if (SecurityDescriptor)
391 {
392 SecurityDescriptor->Owner = (PSID) ((DWORD) lpNext -
393 (DWORD) SecurityDescriptor);
394 lpNext += bytes; /* Advance to next token */
395 }
396
397 *cBytes += bytes;
398
399 break;
400 }
401
402 case 'G':
403 {
404 DWORD bytes;
405
406 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
407 goto lend;
408
409 if (SecurityDescriptor)
410 {
411 SecurityDescriptor->Group = (PSID) ((DWORD) lpNext -
412 (DWORD) SecurityDescriptor);
413 lpNext += bytes; /* Advance to next token */
414 }
415
416 *cBytes += bytes;
417
418 break;
419 }
420
421 case 'D':
422 {
423 DWORD flags;
424 DWORD bytes;
425
426 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
427 goto lend;
428
429 if (SecurityDescriptor)
430 {
431 SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
432 SecurityDescriptor->Dacl = (PACL) ((DWORD) lpNext -
433 (DWORD) SecurityDescriptor);
434 lpNext += bytes; /* Advance to next token */
435 }
436
437 *cBytes += bytes;
438
439 break;
440 }
441
442 case 'S':
443 {
444 DWORD flags;
445 DWORD bytes;
446
447 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
448 goto lend;
449
450 if (SecurityDescriptor)
451 {
452 SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
453 SecurityDescriptor->Sacl = (PACL) ((DWORD) lpNext -
454 (DWORD) SecurityDescriptor);
455 lpNext += bytes; /* Advance to next token */
456 }
457
458 *cBytes += bytes;
459
460 break;
461 }
462
463 default:
464 FIXME("Unknown token\n");
465 SetLastError(ERROR_INVALID_PARAMETER);
466 goto lend;
467 }
468
469 StringSecurityDescriptor = lptoken;
470 }
471
472 bret = TRUE;
473
474 lend:
475 return bret;
476 }
477
478 /******************************************************************************
479 * ParseAclStringFlags
480 */
481 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
482 {
483 DWORD flags = 0;
484 LPCWSTR szAcl = *StringAcl;
485
486 while (*szAcl != '(')
487 {
488 if (*szAcl == 'P')
489 {
490 flags |= SE_DACL_PROTECTED;
491 }
492 else if (*szAcl == 'A')
493 {
494 szAcl++;
495 if (*szAcl == 'R')
496 flags |= SE_DACL_AUTO_INHERIT_REQ;
497 else if (*szAcl == 'I')
498 flags |= SE_DACL_AUTO_INHERITED;
499 }
500 szAcl++;
501 }
502
503 *StringAcl = szAcl;
504 return flags;
505 }
506
507 /******************************************************************************
508 * ParseStringSidToSid
509 */
510 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
511 {
512 BOOL bret = FALSE;
513 SID* pisid=pSid;
514
515 TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
516 if (!StringSid)
517 {
518 SetLastError(ERROR_INVALID_PARAMETER);
519 TRACE("StringSid is NULL, returning FALSE\n");
520 return FALSE;
521 }
522
523 *cBytes = ComputeStringSidSize(StringSid);
524 if (!pisid) /* Simply compute the size */
525 {
526 TRACE("only size requested, returning TRUE\n");
527 return TRUE;
528 }
529
530 if (*StringSid != 'S' || *StringSid != '-') /* S-R-I-S-S */
531 {
532 DWORD i = 0, identAuth;
533 DWORD csubauth = ((*cBytes - sizeof(SID)) / sizeof(DWORD)) + 1;
534
535 StringSid += 2; /* Advance to Revision */
536 pisid->Revision = atoiW(StringSid);
537
538 if (pisid->Revision != SDDL_REVISION)
539 {
540 TRACE("Revision %d is unknown\n", pisid->Revision);
541 goto lend; /* ERROR_INVALID_SID */
542 }
543 if (csubauth == 0)
544 {
545 TRACE("SubAuthorityCount is 0\n");
546 goto lend; /* ERROR_INVALID_SID */
547 }
548
549 pisid->SubAuthorityCount = csubauth;
550
551 /* Advance to identifier authority */
552 while (*StringSid && *StringSid != '-')
553 StringSid++;
554 if (*StringSid == '-')
555 StringSid++;
556
557 /* MS' implementation can't handle values greater than 2^32 - 1, so
558 * we don't either; assume most significant bytes are always 0
559 */
560 pisid->IdentifierAuthority.Value[0] = 0;
561 pisid->IdentifierAuthority.Value[1] = 0;
562 identAuth = atoiW(StringSid);
563 pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
564 pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
565 pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
566 pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
567
568 /* Advance to first sub authority */
569 while (*StringSid && *StringSid != '-')
570 StringSid++;
571 if (*StringSid == '-')
572 StringSid++;
573
574 while (*StringSid)
575 {
576 while (*StringSid && *StringSid != '-')
577 StringSid++;
578
579 pisid->SubAuthority[i++] = atoiW(StringSid);
580 }
581
582 if (i != pisid->SubAuthorityCount)
583 goto lend; /* ERROR_INVALID_SID */
584
585 bret = TRUE;
586 }
587 else /* String constant format - Only available in winxp and above */
588 {
589 pisid->Revision = SDDL_REVISION;
590 pisid->SubAuthorityCount = 1;
591
592 FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
593
594 /* TODO: Lookup string of well-known SIDs in table */
595 pisid->IdentifierAuthority.Value[5] = 0;
596 pisid->SubAuthority[0] = 0;
597
598 bret = TRUE;
599 }
600
601 lend:
602 if (!bret)
603 SetLastError(ERROR_INVALID_SID);
604
605 TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
606 return bret;
607 }
608
609 /* Exported functions */
610
611 /*
612 * @implemented
613 */
614 BOOL STDCALL
615 AllocateLocallyUniqueId(PLUID Luid)
616 {
617 NTSTATUS Status;
618
619 Status = NtAllocateLocallyUniqueId (Luid);
620 if (!NT_SUCCESS (Status))
621 {
622 SetLastError (RtlNtStatusToDosError (Status));
623 return FALSE;
624 }
625
626 return TRUE;
627 }
628
629
630 /*
631 * @implemented
632 */
633 BOOL STDCALL
634 AllocateAndInitializeSid (PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
635 BYTE nSubAuthorityCount,
636 DWORD dwSubAuthority0,
637 DWORD dwSubAuthority1,
638 DWORD dwSubAuthority2,
639 DWORD dwSubAuthority3,
640 DWORD dwSubAuthority4,
641 DWORD dwSubAuthority5,
642 DWORD dwSubAuthority6,
643 DWORD dwSubAuthority7,
644 PSID *pSid)
645 {
646 NTSTATUS Status;
647
648 Status = RtlAllocateAndInitializeSid (pIdentifierAuthority,
649 nSubAuthorityCount,
650 dwSubAuthority0,
651 dwSubAuthority1,
652 dwSubAuthority2,
653 dwSubAuthority3,
654 dwSubAuthority4,
655 dwSubAuthority5,
656 dwSubAuthority6,
657 dwSubAuthority7,
658 pSid);
659 if (!NT_SUCCESS (Status))
660 {
661 SetLastError (RtlNtStatusToDosError (Status));
662 return FALSE;
663 }
664
665 return TRUE;
666 }
667
668
669 /*
670 * @implemented
671 */
672 BOOL STDCALL
673 CopySid (DWORD nDestinationSidLength,
674 PSID pDestinationSid,
675 PSID pSourceSid)
676 {
677 NTSTATUS Status;
678
679 Status = RtlCopySid (nDestinationSidLength,
680 pDestinationSid,
681 pSourceSid);
682 if (!NT_SUCCESS (Status))
683 {
684 SetLastError (RtlNtStatusToDosError (Status));
685 return FALSE;
686 }
687
688 return TRUE;
689 }
690 /* Winehq cvs 20050916 */
691 /******************************************************************************
692 * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
693 * @implemented
694 */
695 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
696 LPCWSTR StringSecurityDescriptor,
697 DWORD StringSDRevision,
698 PSECURITY_DESCRIPTOR* SecurityDescriptor,
699 PULONG SecurityDescriptorSize)
700 {
701 DWORD cBytes;
702 SECURITY_DESCRIPTOR* psd;
703 BOOL bret = FALSE;
704
705 TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
706
707 if (GetVersion() & 0x80000000)
708 {
709 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
710 goto lend;
711 }
712 else if (StringSDRevision != SID_REVISION)
713 {
714 SetLastError(ERROR_UNKNOWN_REVISION);
715 goto lend;
716 }
717
718 /* Compute security descriptor length */
719 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
720 NULL, &cBytes))
721 goto lend;
722
723 psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
724 GMEM_ZEROINIT, cBytes);
725
726 psd->Revision = SID_REVISION;
727 psd->Control |= SE_SELF_RELATIVE;
728
729 if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
730 psd, &cBytes))
731 {
732 LocalFree(psd);
733 goto lend;
734 }
735
736 if (SecurityDescriptorSize)
737 *SecurityDescriptorSize = cBytes;
738
739 bret = TRUE;
740
741 lend:
742 TRACE(" ret=%d\n", bret);
743 return bret;
744 }
745
746 /* Winehq cvs 20050916 */
747 /******************************************************************************
748 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
749 * @implemented
750 */
751 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
752 LPCSTR StringSecurityDescriptor,
753 DWORD StringSDRevision,
754 PSECURITY_DESCRIPTOR* SecurityDescriptor,
755 PULONG SecurityDescriptorSize)
756 {
757 UINT len;
758 BOOL ret = FALSE;
759 LPWSTR StringSecurityDescriptorW;
760
761 len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
762 StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
763
764 if (StringSecurityDescriptorW)
765 {
766 MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
767
768 ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
769 StringSDRevision, SecurityDescriptor,
770 SecurityDescriptorSize);
771 HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
772 }
773
774 return ret;
775 }
776
777 /*
778 * @implemented
779 */
780 BOOL STDCALL
781 EqualPrefixSid (PSID pSid1,
782 PSID pSid2)
783 {
784 return RtlEqualPrefixSid (pSid1, pSid2);
785 }
786
787
788 /*
789 * @implemented
790 */
791 BOOL STDCALL
792 EqualSid (PSID pSid1,
793 PSID pSid2)
794 {
795 return RtlEqualSid (pSid1, pSid2);
796 }
797
798
799 /*
800 * @implemented
801 *
802 * RETURNS
803 * Docs says this function does NOT return a value
804 * even thou it's defined to return a PVOID...
805 */
806 PVOID STDCALL
807 FreeSid (PSID pSid)
808 {
809 return RtlFreeSid (pSid);
810 }
811
812
813 /*
814 * @implemented
815 */
816 DWORD STDCALL
817 GetLengthSid (PSID pSid)
818 {
819 return (DWORD)RtlLengthSid (pSid);
820 }
821
822
823 /*
824 * @implemented
825 */
826 PSID_IDENTIFIER_AUTHORITY STDCALL
827 GetSidIdentifierAuthority (PSID pSid)
828 {
829 return RtlIdentifierAuthoritySid (pSid);
830 }
831
832
833 /*
834 * @implemented
835 */
836 DWORD STDCALL
837 GetSidLengthRequired (UCHAR nSubAuthorityCount)
838 {
839 return (DWORD)RtlLengthRequiredSid (nSubAuthorityCount);
840 }
841
842
843 /*
844 * @implemented
845 */
846 PDWORD STDCALL
847 GetSidSubAuthority (PSID pSid,
848 DWORD nSubAuthority)
849 {
850 return (PDWORD)RtlSubAuthoritySid (pSid, nSubAuthority);
851 }
852
853
854 /*
855 * @implemented
856 */
857 PUCHAR STDCALL
858 GetSidSubAuthorityCount (PSID pSid)
859 {
860 return RtlSubAuthorityCountSid (pSid);
861 }
862
863
864 /*
865 * @implemented
866 */
867 BOOL STDCALL
868 InitializeSid (PSID Sid,
869 PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
870 BYTE nSubAuthorityCount)
871 {
872 NTSTATUS Status;
873
874 Status = RtlInitializeSid (Sid,
875 pIdentifierAuthority,
876 nSubAuthorityCount);
877 if (!NT_SUCCESS (Status))
878 {
879 SetLastError (RtlNtStatusToDosError (Status));
880 return FALSE;
881 }
882
883 return TRUE;
884 }
885
886
887 /*
888 * @implemented
889 */
890 BOOL STDCALL
891 IsValidSid (PSID pSid)
892 {
893 return (BOOL)RtlValidSid (pSid);
894 }
895
896 /*
897 * @implemented
898 */
899 BOOL STDCALL
900 ConvertSidToStringSidW(PSID Sid, LPWSTR *StringSid)
901 {
902 NTSTATUS Status;
903 UNICODE_STRING UnicodeString;
904 WCHAR FixedBuffer[64];
905
906 if (! RtlValidSid(Sid))
907 {
908 SetLastError(ERROR_INVALID_SID);
909 return FALSE;
910 }
911
912 UnicodeString.Length = 0;
913 UnicodeString.MaximumLength = sizeof(FixedBuffer);
914 UnicodeString.Buffer = FixedBuffer;
915 Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, FALSE);
916 if (STATUS_BUFFER_TOO_SMALL == Status)
917 {
918 Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, TRUE);
919 }
920 if (! NT_SUCCESS(Status))
921 {
922 SetLastError(RtlNtStatusToDosError(Status));
923 return FALSE;
924 }
925
926 *StringSid = LocalAlloc(LMEM_FIXED, UnicodeString.Length + sizeof(WCHAR));
927 if (NULL == *StringSid)
928 {
929 if (UnicodeString.Buffer != FixedBuffer)
930 {
931 RtlFreeUnicodeString(&UnicodeString);
932 }
933 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
934 return FALSE;
935 }
936
937 MoveMemory(*StringSid, UnicodeString.Buffer, UnicodeString.Length);
938 ZeroMemory((PCHAR) *StringSid + UnicodeString.Length, sizeof(WCHAR));
939 if (UnicodeString.Buffer != FixedBuffer)
940 {
941 RtlFreeUnicodeString(&UnicodeString);
942 }
943
944 return TRUE;
945 }
946
947
948 /*
949 * @implemented
950 */
951 BOOL STDCALL
952 ConvertSidToStringSidA(PSID Sid, LPSTR *StringSid)
953 {
954 LPWSTR StringSidW;
955 int Len;
956
957 if (! ConvertSidToStringSidW(Sid, &StringSidW))
958 {
959 return FALSE;
960 }
961
962 Len = WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, NULL, 0, NULL, NULL);
963 if (Len <= 0)
964 {
965 LocalFree(StringSidW);
966 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
967 return FALSE;
968 }
969 *StringSid = LocalAlloc(LMEM_FIXED, Len);
970 if (NULL == *StringSid)
971 {
972 LocalFree(StringSidW);
973 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
974 return FALSE;
975 }
976
977 if (! WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, *StringSid, Len, NULL, NULL))
978 {
979 LocalFree(StringSid);
980 LocalFree(StringSidW);
981 return FALSE;
982 }
983
984 LocalFree(StringSidW);
985
986 return TRUE;
987 }
988
989
990 /*
991 * @unimplemented
992 */
993 BOOL STDCALL
994 EqualDomainSid(IN PSID pSid1,
995 IN PSID pSid2,
996 OUT BOOL* pfEqual)
997 {
998 FIXME("%s() not implemented!\n", __FUNCTION__);
999 return FALSE;
1000 }
1001
1002
1003 /*
1004 * @unimplemented
1005 */
1006 BOOL STDCALL
1007 GetWindowsAccountDomainSid(IN PSID pSid,
1008 OUT PSID ppDomainSid,
1009 IN OUT DWORD* cbSid)
1010 {
1011 FIXME("%s() not implemented!\n", __FUNCTION__);
1012 return FALSE;
1013 }
1014
1015
1016 /*
1017 * @unimplemented
1018 */
1019 BOOL STDCALL
1020 CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType,
1021 IN PSID DomainSid OPTIONAL,
1022 OUT PSID pSid,
1023 IN OUT DWORD* cbSid)
1024 {
1025 FIXME("unimplemented!\n", __FUNCTION__);
1026 return FALSE;
1027 }
1028
1029
1030 /*
1031 * @unimplemented
1032 */
1033 BOOL STDCALL
1034 IsWellKnownSid(IN PSID pSid,
1035 IN WELL_KNOWN_SID_TYPE WellKnownSidType)
1036 {
1037 FIXME("unimplemented!\n", __FUNCTION__);
1038 return FALSE;
1039 }
1040
1041
1042 /*
1043 * @implemented
1044 */
1045 BOOL STDCALL
1046 ConvertStringSidToSidA(
1047 IN LPCSTR StringSid,
1048 OUT PSID* sid)
1049 {
1050 BOOL bRetVal = FALSE;
1051
1052 if (!StringSid || !sid)
1053 SetLastError(ERROR_INVALID_PARAMETER);
1054 else
1055 {
1056 UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
1057 LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1058 MultiByteToWideChar(CP_ACP, 0, StringSid, - 1, wStringSid, len);
1059 bRetVal = ConvertStringSidToSidW(wStringSid, sid);
1060 HeapFree(GetProcessHeap(), 0, wStringSid);
1061 }
1062 return bRetVal;
1063 }
1064
1065 /*
1066 * @unimplemented
1067 */
1068 BOOL STDCALL
1069 ConvertStringSidToSidW(
1070 IN LPCWSTR StringSid,
1071 OUT PSID* sid)
1072 {
1073 FIXME("unimplemented!\n", __FUNCTION__);
1074 return FALSE;
1075 }
1076
1077
1078 /* EOF */