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