- NDK 0.98, now with versionned headers. Too many changes to list, see the TinyKRNL...
[reactos.git] / reactos / dll / win32 / advapi32 / sec / ac.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/advapi32/sec/ac.c
6 * PURPOSE: ACL/ACE functions
7 */
8
9 #include <advapi32.h>
10
11 #define NDEBUG
12 #include <debug.h>
13
14 /* --- ACL --- */
15
16 /*
17 * @implemented
18 */
19 BOOL
20 STDCALL
21 GetAclInformation (
22 PACL pAcl,
23 LPVOID pAclInformation,
24 DWORD nAclInformationLength,
25 ACL_INFORMATION_CLASS dwAclInformationClass
26 )
27 {
28 NTSTATUS Status;
29
30 Status = RtlQueryInformationAcl (pAcl,
31 pAclInformation,
32 nAclInformationLength,
33 dwAclInformationClass);
34 if (!NT_SUCCESS(Status))
35 {
36 SetLastError (RtlNtStatusToDosError (Status));
37 return FALSE;
38 }
39
40 return TRUE;
41 }
42
43
44 /*
45 * @implemented
46 */
47 BOOL
48 STDCALL
49 InitializeAcl (
50 PACL pAcl,
51 DWORD nAclLength,
52 DWORD dwAclRevision
53 )
54 {
55 NTSTATUS Status;
56
57 Status = RtlCreateAcl (pAcl,
58 nAclLength,
59 dwAclRevision);
60 if (!NT_SUCCESS(Status))
61 {
62 SetLastError (RtlNtStatusToDosError (Status));
63 return FALSE;
64 }
65
66 return TRUE;
67 }
68
69
70 /*
71 * @implemented
72 */
73 BOOL
74 STDCALL
75 IsValidAcl (
76 PACL pAcl
77 )
78 {
79 return RtlValidAcl (pAcl);
80 }
81
82
83 /*
84 * @implemented
85 */
86 BOOL
87 STDCALL
88 SetAclInformation (
89 PACL pAcl,
90 LPVOID pAclInformation,
91 DWORD nAclInformationLength,
92 ACL_INFORMATION_CLASS dwAclInformationClass
93 )
94 {
95 NTSTATUS Status;
96
97 Status = RtlSetInformationAcl (pAcl,
98 pAclInformation,
99 nAclInformationLength,
100 dwAclInformationClass);
101 if (!NT_SUCCESS(Status))
102 {
103 SetLastError (RtlNtStatusToDosError (Status));
104 return FALSE;
105 }
106
107 return TRUE;
108 }
109
110
111 /* --- ACE --- */
112
113 /*
114 * @implemented
115 */
116 BOOL
117 STDCALL
118 AddAccessAllowedAce (
119 PACL pAcl,
120 DWORD dwAceRevision,
121 DWORD AccessMask,
122 PSID pSid
123 )
124 {
125 NTSTATUS Status;
126
127 Status = RtlAddAccessAllowedAce (pAcl,
128 dwAceRevision,
129 AccessMask,
130 pSid);
131 if (!NT_SUCCESS(Status))
132 {
133 SetLastError (RtlNtStatusToDosError (Status));
134 return FALSE;
135 }
136
137 return TRUE;
138 }
139
140
141 /*
142 * @implemented
143 */
144 BOOL STDCALL
145 AddAccessAllowedAceEx(PACL pAcl,
146 DWORD dwAceRevision,
147 DWORD AceFlags,
148 DWORD AccessMask,
149 PSID pSid)
150 {
151 NTSTATUS Status;
152
153 Status = RtlAddAccessAllowedAceEx(pAcl,
154 dwAceRevision,
155 AceFlags,
156 AccessMask,
157 pSid);
158 if (!NT_SUCCESS(Status))
159 {
160 SetLastError(RtlNtStatusToDosError(Status));
161 return FALSE;
162 }
163
164 return TRUE;
165 }
166
167
168 /*
169 * @implemented
170 */
171 BOOL
172 STDCALL
173 AddAccessAllowedObjectAce(
174 PACL pAcl,
175 DWORD dwAceRevision,
176 DWORD AceFlags,
177 DWORD AccessMask,
178 GUID* ObjectTypeGuid,
179 GUID* InheritedObjectTypeGuid,
180 PSID pSid)
181 {
182 NTSTATUS Status;
183
184 Status = RtlAddAccessAllowedObjectAce(pAcl,
185 dwAceRevision,
186 AceFlags,
187 AccessMask,
188 ObjectTypeGuid,
189 InheritedObjectTypeGuid,
190 pSid);
191 if (!NT_SUCCESS(Status))
192 {
193 SetLastError(RtlNtStatusToDosError(Status));
194 return FALSE;
195 }
196
197 return TRUE;
198 }
199
200
201 /*
202 * @implemented
203 */
204 BOOL
205 STDCALL
206 AddAccessDeniedAce (
207 PACL pAcl,
208 DWORD dwAceRevision,
209 DWORD AccessMask,
210 PSID pSid
211 )
212 {
213 NTSTATUS Status;
214
215 Status = RtlAddAccessDeniedAce (pAcl,
216 dwAceRevision,
217 AccessMask,
218 pSid);
219 if (!NT_SUCCESS(Status))
220 {
221 SetLastError (RtlNtStatusToDosError (Status));
222 return FALSE;
223 }
224
225 return TRUE;
226 }
227
228
229 /*
230 * @implemented
231 */
232 BOOL STDCALL
233 AddAccessDeniedAceEx(PACL pAcl,
234 DWORD dwAceRevision,
235 DWORD AceFlags,
236 DWORD AccessMask,
237 PSID pSid)
238 {
239 NTSTATUS Status;
240
241 Status = RtlAddAccessDeniedAceEx(pAcl,
242 dwAceRevision,
243 AceFlags,
244 AccessMask,
245 pSid);
246 if (!NT_SUCCESS(Status))
247 {
248 SetLastError(RtlNtStatusToDosError(Status));
249 return FALSE;
250 }
251
252 return TRUE;
253 }
254
255
256 /*
257 * @implemented
258 */
259 BOOL
260 STDCALL
261 AddAccessDeniedObjectAce(
262 PACL pAcl,
263 DWORD dwAceRevision,
264 DWORD AceFlags,
265 DWORD AccessMask,
266 GUID* ObjectTypeGuid,
267 GUID* InheritedObjectTypeGuid,
268 PSID pSid)
269 {
270 NTSTATUS Status;
271
272 Status = RtlAddAccessDeniedObjectAce(pAcl,
273 dwAceRevision,
274 AceFlags,
275 AccessMask,
276 ObjectTypeGuid,
277 InheritedObjectTypeGuid,
278 pSid);
279 if (!NT_SUCCESS(Status))
280 {
281 SetLastError(RtlNtStatusToDosError(Status));
282 return FALSE;
283 }
284
285 return TRUE;
286 }
287
288
289 /*
290 * @implemented
291 */
292 BOOL
293 STDCALL
294 AddAce (
295 PACL pAcl,
296 DWORD dwAceRevision,
297 DWORD dwStartingAceIndex,
298 LPVOID pAceList,
299 DWORD nAceListLength
300 )
301 {
302 NTSTATUS Status;
303
304 Status = RtlAddAce (pAcl,
305 dwAceRevision,
306 dwStartingAceIndex,
307 pAceList,
308 nAceListLength);
309 if (!NT_SUCCESS(Status))
310 {
311 SetLastError (RtlNtStatusToDosError (Status));
312 return FALSE;
313 }
314
315 return TRUE;
316 }
317
318
319 /*
320 * @implemented
321 */
322 BOOL
323 STDCALL
324 AddAuditAccessAce (
325 PACL pAcl,
326 DWORD dwAceRevision,
327 DWORD dwAccessMask,
328 PSID pSid,
329 BOOL bAuditSuccess,
330 BOOL bAuditFailure
331 )
332 {
333 NTSTATUS Status;
334
335 Status = RtlAddAuditAccessAce (pAcl,
336 dwAceRevision,
337 dwAccessMask,
338 pSid,
339 bAuditSuccess,
340 bAuditFailure);
341 if (!NT_SUCCESS(Status))
342 {
343 SetLastError (RtlNtStatusToDosError (Status));
344 return FALSE;
345 }
346
347 return TRUE;
348 }
349
350
351 /*
352 * @implemented
353 */
354 BOOL STDCALL
355 AddAuditAccessAceEx(PACL pAcl,
356 DWORD dwAceRevision,
357 DWORD AceFlags,
358 DWORD dwAccessMask,
359 PSID pSid,
360 BOOL bAuditSuccess,
361 BOOL bAuditFailure)
362 {
363 NTSTATUS Status;
364
365 Status = RtlAddAuditAccessAceEx(pAcl,
366 dwAceRevision,
367 AceFlags,
368 dwAccessMask,
369 pSid,
370 bAuditSuccess,
371 bAuditFailure);
372 if (!NT_SUCCESS(Status))
373 {
374 SetLastError(RtlNtStatusToDosError(Status));
375 return FALSE;
376 }
377
378 return TRUE;
379 }
380
381
382 /*
383 * @implemented
384 */
385 BOOL
386 STDCALL
387 AddAuditAccessObjectAce(
388 PACL pAcl,
389 DWORD dwAceRevision,
390 DWORD AceFlags,
391 DWORD AccessMask,
392 GUID* ObjectTypeGuid,
393 GUID* InheritedObjectTypeGuid,
394 PSID pSid,
395 BOOL bAuditSuccess,
396 BOOL bAuditFailure)
397 {
398 NTSTATUS Status;
399
400 Status = RtlAddAuditAccessObjectAce(pAcl,
401 dwAceRevision,
402 AceFlags,
403 AccessMask,
404 ObjectTypeGuid,
405 InheritedObjectTypeGuid,
406 pSid,
407 bAuditSuccess,
408 bAuditFailure);
409 if (!NT_SUCCESS(Status))
410 {
411 SetLastError(RtlNtStatusToDosError(Status));
412 return FALSE;
413 }
414
415 return TRUE;
416 }
417
418
419 /*
420 * @implemented
421 */
422 BOOL
423 STDCALL
424 DeleteAce (
425 PACL pAcl,
426 DWORD dwAceIndex
427 )
428 {
429 NTSTATUS Status;
430
431 Status = RtlDeleteAce (pAcl,
432 dwAceIndex);
433 if (!NT_SUCCESS(Status))
434 {
435 SetLastError (RtlNtStatusToDosError (Status));
436 return FALSE;
437 }
438
439 return TRUE;
440 }
441
442
443 /*
444 * @implemented
445 */
446 BOOL
447 STDCALL
448 FindFirstFreeAce (
449 PACL pAcl,
450 LPVOID * pAce
451 )
452 {
453 return RtlFirstFreeAce (pAcl,
454 (PACE*)pAce);
455 }
456
457
458 /*
459 * @implemented
460 */
461 BOOL
462 STDCALL
463 GetAce (
464 PACL pAcl,
465 DWORD dwAceIndex,
466 LPVOID * pAce
467 )
468 {
469 NTSTATUS Status;
470
471 Status = RtlGetAce (pAcl,
472 dwAceIndex,
473 pAce);
474 if (!NT_SUCCESS(Status))
475 {
476 SetLastError (RtlNtStatusToDosError (Status));
477 return FALSE;
478 }
479
480 return TRUE;
481 }
482
483
484 /*
485 * @implemented
486 */
487 DWORD
488 STDCALL
489 GetInheritanceSourceW (
490 LPWSTR pObjectName,
491 SE_OBJECT_TYPE ObjectType,
492 SECURITY_INFORMATION SecurityInfo,
493 BOOL Container,
494 GUID** pObjectClassGuids OPTIONAL,
495 DWORD GuidCount,
496 PACL pAcl,
497 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL,
498 PGENERIC_MAPPING pGenericMapping,
499 PINHERITED_FROMW pInheritArray
500 )
501 {
502 DWORD ErrorCode;
503
504 ErrorCode = CheckNtMartaPresent();
505 if (ErrorCode == ERROR_SUCCESS)
506 {
507 /* call the MARTA provider */
508 ErrorCode = AccGetInheritanceSource(pObjectName,
509 ObjectType,
510 SecurityInfo,
511 Container,
512 pObjectClassGuids,
513 GuidCount,
514 pAcl,
515 pfnArray,
516 pGenericMapping,
517 pInheritArray);
518 }
519
520 return ErrorCode;
521 }
522
523
524 /*
525 * @unimplemented
526 */
527 DWORD
528 STDCALL
529 GetInheritanceSourceA (
530 LPSTR pObjectName,
531 SE_OBJECT_TYPE ObjectType,
532 SECURITY_INFORMATION SecurityInfo,
533 BOOL Container,
534 GUID** pObjectClassGuids OPTIONAL,
535 DWORD GuidCount,
536 PACL pAcl,
537 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL,
538 PGENERIC_MAPPING pGenericMapping,
539 PINHERITED_FROM pInheritArray
540 )
541 {
542 /* That's all this function does, at least up to w2k3... Even MS was too
543 lazy to implement it... */
544 return ERROR_CALL_NOT_IMPLEMENTED;
545 }
546
547
548 /*
549 * @implemented
550 */
551 DWORD
552 STDCALL
553 FreeInheritedFromArray (
554 PINHERITED_FROMW pInheritArray,
555 USHORT AceCnt,
556 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL
557 )
558 {
559 DWORD ErrorCode;
560
561 ErrorCode = CheckNtMartaPresent();
562 if (ErrorCode == ERROR_SUCCESS)
563 {
564 /* call the MARTA provider */
565 ErrorCode = AccFreeIndexArray(pInheritArray,
566 AceCnt,
567 pfnArray);
568 }
569
570 return ErrorCode;
571 }
572
573
574 /*
575 * @implemented
576 */
577 DWORD
578 STDCALL
579 SetEntriesInAclW(
580 ULONG cCountOfExplicitEntries,
581 PEXPLICIT_ACCESS_W pListOfExplicitEntries,
582 PACL OldAcl,
583 PACL* NewAcl)
584 {
585 DWORD ErrorCode;
586
587 ErrorCode = CheckNtMartaPresent();
588 if (ErrorCode == ERROR_SUCCESS)
589 {
590 /* call the MARTA provider */
591 ErrorCode = AccRewriteSetEntriesInAcl(cCountOfExplicitEntries,
592 pListOfExplicitEntries,
593 OldAcl,
594 NewAcl);
595 }
596
597 return ErrorCode;
598 }
599
600
601 static DWORD
602 InternalTrusteeAToW(IN PTRUSTEE_A pTrusteeA,
603 OUT PTRUSTEE_W *pTrusteeW)
604 {
605 TRUSTEE_FORM TrusteeForm;
606 INT BufferSize = 0;
607 PSTR lpStr;
608 DWORD ErrorCode = ERROR_SUCCESS;
609
610 ASSERT(sizeof(TRUSTEE_W) == sizeof(TRUSTEE_A));
611
612 TrusteeForm = GetTrusteeForm(pTrusteeA);
613 switch (TrusteeForm)
614 {
615 case TRUSTEE_IS_NAME:
616 {
617 /* directly copy the array, this works as the size of the EXPLICIT_ACCESS_A
618 structure matches the size of the EXPLICIT_ACCESS_W version */
619 lpStr = GetTrusteeName(pTrusteeA);
620 if (lpStr != NULL)
621 BufferSize = strlen(lpStr) + 1;
622
623 *pTrusteeW = RtlAllocateHeap(RtlGetProcessHeap(),
624 0,
625 sizeof(TRUSTEE_W) + (BufferSize * sizeof(WCHAR)));
626 if (*pTrusteeW != NULL)
627 {
628 RtlCopyMemory(*pTrusteeW,
629 pTrusteeA,
630 FIELD_OFFSET(TRUSTEE_A,
631 ptstrName));
632
633 if (lpStr != NULL)
634 {
635 (*pTrusteeW)->ptstrName = (PWSTR)((*pTrusteeW) + 1);
636
637 /* convert the trustee's name */
638 if (MultiByteToWideChar(CP_ACP,
639 0,
640 lpStr,
641 -1,
642 (*pTrusteeW)->ptstrName,
643 BufferSize) == 0)
644 {
645 goto ConvertErr;
646 }
647 }
648 else
649 {
650 RtlFreeHeap(RtlGetProcessHeap(),
651 0,
652 *pTrusteeW);
653 goto NothingToConvert;
654 }
655 }
656 else
657 ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
658 break;
659 }
660
661 case TRUSTEE_IS_OBJECTS_AND_NAME:
662 {
663 POBJECTS_AND_NAME_A oanA = (POBJECTS_AND_NAME_A)GetTrusteeNameA(pTrusteeA);
664 POBJECTS_AND_NAME_W oan;
665 PWSTR StrBuf;
666
667 /* calculate the size needed */
668 if ((oanA->ObjectsPresent & ACE_INHERITED_OBJECT_TYPE_PRESENT) &&
669 oanA->InheritedObjectTypeName != NULL)
670 {
671 BufferSize = strlen(oanA->InheritedObjectTypeName) + 1;
672 }
673 if (oanA->ptstrName != NULL)
674 {
675 BufferSize += strlen(oanA->ptstrName) + 1;
676 }
677
678 *pTrusteeW = RtlAllocateHeap(RtlGetProcessHeap(),
679 0,
680 sizeof(TRUSTEE_W) + sizeof(OBJECTS_AND_NAME_W) +
681 (BufferSize * sizeof(WCHAR)));
682
683 if (*pTrusteeW != NULL)
684 {
685 oan = (POBJECTS_AND_NAME_W)((*pTrusteeW) + 1);
686 StrBuf = (PWSTR)(oan + 1);
687
688 /* copy over the parts of the TRUSTEE structure that don't need
689 to be touched */
690 RtlCopyMemory(*pTrusteeW,
691 pTrusteeA,
692 FIELD_OFFSET(TRUSTEE_A,
693 ptstrName));
694
695 (*pTrusteeW)->ptstrName = (LPWSTR)oan;
696
697 /* convert the OBJECTS_AND_NAME_A structure */
698 oan->ObjectsPresent = oanA->ObjectsPresent;
699 oan->ObjectType = oanA->ObjectType;
700
701 if ((oanA->ObjectsPresent & ACE_INHERITED_OBJECT_TYPE_PRESENT) &&
702 oanA->InheritedObjectTypeName != NULL)
703 {
704 /* convert inherited object type name */
705 BufferSize = strlen(oanA->InheritedObjectTypeName) + 1;
706
707 if (MultiByteToWideChar(CP_ACP,
708 0,
709 oanA->InheritedObjectTypeName,
710 -1,
711 StrBuf,
712 BufferSize) == 0)
713 {
714 goto ConvertErr;
715 }
716 oan->InheritedObjectTypeName = StrBuf;
717
718 StrBuf += BufferSize;
719 }
720 else
721 oan->InheritedObjectTypeName = NULL;
722
723 if (oanA->ptstrName != NULL)
724 {
725 /* convert the trustee name */
726 BufferSize = strlen(oanA->ptstrName) + 1;
727
728 if (MultiByteToWideChar(CP_ACP,
729 0,
730 oanA->ptstrName,
731 -1,
732 StrBuf,
733 BufferSize) == 0)
734 {
735 ConvertErr:
736 ErrorCode = GetLastError();
737
738 /* cleanup */
739 RtlFreeHeap(RtlGetProcessHeap(),
740 0,
741 *pTrusteeW);
742
743 return ErrorCode;
744 }
745 oan->ptstrName = StrBuf;
746 }
747 else
748 oan->ptstrName = NULL;
749 }
750 else
751 ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
752 break;
753 }
754
755 default:
756 {
757 NothingToConvert:
758 /* no need to convert anything to unicode */
759 *pTrusteeW = (PTRUSTEE_W)pTrusteeA;
760 break;
761 }
762 }
763
764 return ErrorCode;
765 }
766
767
768 static __inline VOID
769 InternalFreeConvertedTrustee(IN PTRUSTEE_W pTrusteeW,
770 IN PTRUSTEE_A pTrusteeA)
771 {
772 if ((PVOID)pTrusteeW != (PVOID)pTrusteeA)
773 {
774 RtlFreeHeap(RtlGetProcessHeap(),
775 0,
776 pTrusteeW);
777 }
778 }
779
780
781 static DWORD
782 InternalExplicitAccessAToW(IN ULONG cCountOfExplicitEntries,
783 IN PEXPLICIT_ACCESS_A pListOfExplicitEntriesA,
784 OUT PEXPLICIT_ACCESS_W *pListOfExplicitEntriesW)
785 {
786 TRUSTEE_FORM TrusteeForm;
787 SIZE_T Size;
788 ULONG i;
789 ULONG ObjectsAndNameCount = 0;
790 PEXPLICIT_ACCESS_W peaw = NULL;
791 DWORD ErrorCode = ERROR_SUCCESS;
792 LPSTR lpStr;
793
794 /* NOTE: This code assumes that the size of the TRUSTEE_A and TRUSTEE_W structure matches! */
795 ASSERT(sizeof(TRUSTEE_A) == sizeof(TRUSTEE_W));
796
797 if (cCountOfExplicitEntries != 0)
798 {
799 /* calculate the size needed */
800 Size = cCountOfExplicitEntries * sizeof(EXPLICIT_ACCESS_W);
801 for (i = 0; i != cCountOfExplicitEntries; i++)
802 {
803 TrusteeForm = GetTrusteeForm(&pListOfExplicitEntriesA[i].Trustee);
804
805 switch (TrusteeForm)
806 {
807 case TRUSTEE_IS_NAME:
808 {
809 lpStr = GetTrusteeNameA(&pListOfExplicitEntriesA[i].Trustee);
810 if (lpStr != NULL)
811 Size += (strlen(lpStr) + 1) * sizeof(WCHAR);
812 break;
813 }
814
815 case TRUSTEE_IS_OBJECTS_AND_NAME:
816 {
817 POBJECTS_AND_NAME_A oan = (POBJECTS_AND_NAME_A)GetTrusteeNameA(&pListOfExplicitEntriesA[i].Trustee);
818
819 if ((oan->ObjectsPresent & ACE_INHERITED_OBJECT_TYPE_PRESENT) &&
820 oan->InheritedObjectTypeName != NULL)
821 {
822 Size += (strlen(oan->InheritedObjectTypeName) + 1) * sizeof(WCHAR);
823 }
824
825 if (oan->ptstrName != NULL)
826 Size += (strlen(oan->ptstrName) + 1) * sizeof(WCHAR);
827
828 ObjectsAndNameCount++;
829 break;
830 }
831
832 default:
833 break;
834 }
835 }
836
837 /* allocate the array */
838 peaw = RtlAllocateHeap(RtlGetProcessHeap(),
839 0,
840 Size);
841 if (peaw != NULL)
842 {
843 INT BufferSize;
844 POBJECTS_AND_NAME_W oan = (POBJECTS_AND_NAME_W)(peaw + cCountOfExplicitEntries);
845 LPWSTR StrBuf = (LPWSTR)(oan + ObjectsAndNameCount);
846
847 /* convert the array to unicode */
848 for (i = 0; i != cCountOfExplicitEntries; i++)
849 {
850 peaw[i].grfAccessPermissions = pListOfExplicitEntriesA[i].grfAccessPermissions;
851 peaw[i].grfAccessMode = pListOfExplicitEntriesA[i].grfAccessMode;
852 peaw[i].grfInheritance = pListOfExplicitEntriesA[i].grfInheritance;
853
854 /* convert or copy the TRUSTEE structure */
855 TrusteeForm = GetTrusteeForm(&pListOfExplicitEntriesA[i].Trustee);
856 switch (TrusteeForm)
857 {
858 case TRUSTEE_IS_NAME:
859 {
860 lpStr = GetTrusteeNameA(&pListOfExplicitEntriesA[i].Trustee);
861 if (lpStr != NULL)
862 {
863 /* convert the trustee name */
864 BufferSize = strlen(lpStr) + 1;
865
866 if (MultiByteToWideChar(CP_ACP,
867 0,
868 lpStr,
869 -1,
870 StrBuf,
871 BufferSize) == 0)
872 {
873 goto ConvertErr;
874 }
875 peaw[i].Trustee.ptstrName = StrBuf;
876
877 StrBuf += BufferSize;
878 }
879 else
880 goto RawTrusteeCopy;
881
882 break;
883 }
884
885 case TRUSTEE_IS_OBJECTS_AND_NAME:
886 {
887 POBJECTS_AND_NAME_A oanA = (POBJECTS_AND_NAME_A)GetTrusteeNameA(&pListOfExplicitEntriesA[i].Trustee);
888
889 /* copy over the parts of the TRUSTEE structure that don't need
890 to be touched */
891 RtlCopyMemory(&peaw[i].Trustee,
892 &pListOfExplicitEntriesA[i].Trustee,
893 FIELD_OFFSET(TRUSTEE_A,
894 ptstrName));
895
896 peaw[i].Trustee.ptstrName = (LPWSTR)oan;
897
898 /* convert the OBJECTS_AND_NAME_A structure */
899 oan->ObjectsPresent = oanA->ObjectsPresent;
900 oan->ObjectType = oanA->ObjectType;
901
902 if ((oanA->ObjectsPresent & ACE_INHERITED_OBJECT_TYPE_PRESENT) &&
903 oanA->InheritedObjectTypeName != NULL)
904 {
905 /* convert inherited object type name */
906 BufferSize = strlen(oanA->InheritedObjectTypeName) + 1;
907
908 if (MultiByteToWideChar(CP_ACP,
909 0,
910 oanA->InheritedObjectTypeName,
911 -1,
912 StrBuf,
913 BufferSize) == 0)
914 {
915 goto ConvertErr;
916 }
917 oan->InheritedObjectTypeName = StrBuf;
918
919 StrBuf += BufferSize;
920 }
921 else
922 oan->InheritedObjectTypeName = NULL;
923
924 if (oanA->ptstrName != NULL)
925 {
926 /* convert the trustee name */
927 BufferSize = strlen(oanA->ptstrName) + 1;
928
929 if (MultiByteToWideChar(CP_ACP,
930 0,
931 oanA->ptstrName,
932 -1,
933 StrBuf,
934 BufferSize) == 0)
935 {
936 ConvertErr:
937 ErrorCode = GetLastError();
938
939 /* cleanup */
940 RtlFreeHeap(RtlGetProcessHeap(),
941 0,
942 peaw);
943
944 return ErrorCode;
945 }
946 oan->ptstrName = StrBuf;
947
948 StrBuf += BufferSize;
949 }
950 else
951 oan->ptstrName = NULL;
952
953 /* move on to the next OBJECTS_AND_NAME_A structure */
954 oan++;
955 break;
956 }
957
958 default:
959 {
960 RawTrusteeCopy:
961 /* just copy over the TRUSTEE structure, they don't contain any
962 ansi/unicode specific data */
963 RtlCopyMemory(&peaw[i].Trustee,
964 &pListOfExplicitEntriesA[i].Trustee,
965 sizeof(TRUSTEE_A));
966 break;
967 }
968 }
969 }
970
971 ASSERT(ErrorCode == ERROR_SUCCESS);
972 *pListOfExplicitEntriesW = peaw;
973 }
974 else
975 ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
976 }
977
978 return ErrorCode;
979 }
980
981
982 /*
983 * @implemented
984 */
985 DWORD
986 STDCALL
987 SetEntriesInAclA(
988 ULONG cCountOfExplicitEntries,
989 PEXPLICIT_ACCESS_A pListOfExplicitEntries,
990 PACL OldAcl,
991 PACL* NewAcl)
992 {
993 PEXPLICIT_ACCESS_W ListOfExplicitEntriesW = NULL;
994 DWORD ErrorCode;
995
996 ErrorCode = InternalExplicitAccessAToW(cCountOfExplicitEntries,
997 pListOfExplicitEntries,
998 &ListOfExplicitEntriesW);
999
1000 if (ErrorCode == ERROR_SUCCESS)
1001 {
1002 ErrorCode = SetEntriesInAclW(cCountOfExplicitEntries,
1003 ListOfExplicitEntriesW,
1004 OldAcl,
1005 NewAcl);
1006
1007 /* free the allocated array */
1008 RtlFreeHeap(RtlGetProcessHeap(),
1009 0,
1010 ListOfExplicitEntriesW);
1011 }
1012
1013 return ErrorCode;
1014 }
1015
1016
1017 /*
1018 * @implemented
1019 */
1020 DWORD
1021 STDCALL
1022 GetExplicitEntriesFromAclW(
1023 PACL pacl,
1024 PULONG pcCountOfExplicitEntries,
1025 PEXPLICIT_ACCESS_W* pListOfExplicitEntries
1026 )
1027 {
1028 DWORD ErrorCode;
1029
1030 ErrorCode = CheckNtMartaPresent();
1031 if (ErrorCode == ERROR_SUCCESS)
1032 {
1033 /* call the MARTA provider */
1034 ErrorCode = AccRewriteGetExplicitEntriesFromAcl(pacl,
1035 pcCountOfExplicitEntries,
1036 pListOfExplicitEntries);
1037 }
1038
1039 return ErrorCode;
1040 }
1041
1042
1043 /*
1044 * @unimplemented
1045 */
1046 DWORD
1047 STDCALL
1048 GetEffectiveRightsFromAclW(IN PACL pacl,
1049 IN PTRUSTEE_W pTrustee,
1050 OUT PACCESS_MASK pAccessRights)
1051 {
1052 DPRINT1("%s() not implemented!\n", __FUNCTION__);
1053 return ERROR_CALL_NOT_IMPLEMENTED;
1054 }
1055
1056
1057 /*
1058 * @implemented
1059 */
1060 DWORD
1061 STDCALL
1062 GetEffectiveRightsFromAclA(IN PACL pacl,
1063 IN PTRUSTEE_A pTrustee,
1064 OUT PACCESS_MASK pAccessRights)
1065 {
1066 PTRUSTEE_W pTrusteeW = NULL;
1067 DWORD ErrorCode;
1068
1069 ErrorCode = InternalTrusteeAToW(pTrustee,
1070 &pTrusteeW);
1071 if (ErrorCode == ERROR_SUCCESS)
1072 {
1073 ErrorCode = GetEffectiveRightsFromAclW(pacl,
1074 pTrusteeW,
1075 pAccessRights);
1076
1077 InternalFreeConvertedTrustee(pTrusteeW,
1078 pTrustee);
1079 }
1080 else
1081 ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
1082
1083 return ErrorCode;
1084 }
1085
1086
1087 /*
1088 * @unimplemented
1089 */
1090 DWORD
1091 STDCALL
1092 GetAuditedPermissionsFromAclW(IN PACL pacl,
1093 IN PTRUSTEE_W pTrustee,
1094 OUT PACCESS_MASK pSuccessfulAuditedRights,
1095 OUT PACCESS_MASK pFailedAuditRights)
1096 {
1097 DPRINT1("%s() not implemented!\n", __FUNCTION__);
1098 return ERROR_CALL_NOT_IMPLEMENTED;
1099 }
1100
1101
1102 /*
1103 * @implemented
1104 */
1105 DWORD
1106 STDCALL
1107 GetAuditedPermissionsFromAclA(IN PACL pacl,
1108 IN PTRUSTEE_A pTrustee,
1109 OUT PACCESS_MASK pSuccessfulAuditedRights,
1110 OUT PACCESS_MASK pFailedAuditRights)
1111 {
1112 PTRUSTEE_W pTrusteeW = NULL;
1113 DWORD ErrorCode;
1114
1115 ErrorCode = InternalTrusteeAToW(pTrustee,
1116 &pTrusteeW);
1117 if (ErrorCode == ERROR_SUCCESS)
1118 {
1119 ErrorCode = GetAuditedPermissionsFromAclW(pacl,
1120 pTrusteeW,
1121 pSuccessfulAuditedRights,
1122 pFailedAuditRights);
1123
1124 InternalFreeConvertedTrustee(pTrusteeW,
1125 pTrustee);
1126 }
1127 else
1128 ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
1129
1130 return ErrorCode;
1131 }
1132
1133 /* EOF */