fixed typo in a comment
[reactos.git] / reactos / lib / advapi32 / sec / misc.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/advapi32/sec/misc.c
5 * PURPOSE: Miscellaneous security functions
6 */
7
8 #include "advapi32.h"
9 #include <accctrl.h>
10 #include <malloc.h>
11 #include <ntsecapi.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* Interface to ntmarta.dll ***************************************************/
17
18 NTMARTA NtMartaStatic = { 0 };
19 static PNTMARTA NtMarta = NULL;
20
21 #define FindNtMartaProc(Name) \
22 NtMartaStatic.Name = (PVOID)GetProcAddress(NtMartaStatic.hDllInstance, \
23 "Acc" # Name ); \
24 if (NtMartaStatic.Name == NULL) \
25 { \
26 return GetLastError(); \
27 }
28
29 static DWORD
30 LoadAndInitializeNtMarta(VOID)
31 {
32 /* this code may be executed simultaneously by multiple threads in case they're
33 trying to initialize the interface at the same time, but that's no problem
34 because the pointers returned by GetProcAddress will be the same. However,
35 only one of the threads will change the NtMarta pointer to the NtMartaStatic
36 structure, the others threads will detect that there were other threads
37 initializing the structure faster and will release the reference to the
38 DLL */
39
40 NtMartaStatic.hDllInstance = LoadLibraryW(L"ntmarta.dll");
41 if (NtMartaStatic.hDllInstance == NULL)
42 {
43 return GetLastError();
44 }
45
46 #if 0
47 FindNtMartaProc(LookupAccountTrustee);
48 FindNtMartaProc(LookupAccountName);
49 FindNtMartaProc(LookupAccountSid);
50 FindNtMartaProc(SetEntriesInAList);
51 FindNtMartaProc(ConvertAccessToSecurityDescriptor);
52 FindNtMartaProc(ConvertSDToAccess);
53 FindNtMartaProc(ConvertAclToAccess);
54 FindNtMartaProc(GetAccessForTrustee);
55 FindNtMartaProc(GetExplicitEntries);
56 #endif
57 FindNtMartaProc(RewriteGetNamedRights);
58 FindNtMartaProc(RewriteSetNamedRights);
59 FindNtMartaProc(RewriteGetHandleRights);
60 FindNtMartaProc(RewriteSetHandleRights);
61 FindNtMartaProc(RewriteSetEntriesInAcl);
62 FindNtMartaProc(RewriteGetExplicitEntriesFromAcl);
63 FindNtMartaProc(TreeResetNamedSecurityInfo);
64 FindNtMartaProc(GetInheritanceSource);
65 FindNtMartaProc(FreeIndexArray);
66
67 return ERROR_SUCCESS;
68 }
69
70 DWORD
71 CheckNtMartaPresent(VOID)
72 {
73 DWORD ErrorCode;
74
75 if (NtMarta == NULL)
76 {
77 /* we're the first one trying to use ntmarta, initialize it and change
78 the pointer after initialization */
79 ErrorCode = LoadAndInitializeNtMarta();
80
81 if (ErrorCode == ERROR_SUCCESS)
82 {
83 /* try change the NtMarta pointer */
84 if (InterlockedCompareExchangePointer(&NtMarta,
85 &NtMartaStatic,
86 NULL) != NULL)
87 {
88 /* another thread initialized ntmarta in the meanwhile, release
89 the reference of the dll loaded. */
90 FreeLibrary(NtMartaStatic.hDllInstance);
91 }
92 }
93 #if DBG
94 else
95 {
96 DPRINT1("Failed to initialize ntmarta.dll! Error: 0x%x", ErrorCode);
97 }
98 #endif
99 }
100 else
101 {
102 /* ntmarta was already initialized */
103 ErrorCode = ERROR_SUCCESS;
104 }
105
106 return ErrorCode;
107 }
108
109 VOID UnloadNtMarta(VOID)
110 {
111 if (InterlockedExchangePointer(&NtMarta,
112 NULL) != NULL)
113 {
114 FreeLibrary(NtMartaStatic.hDllInstance);
115 }
116 }
117
118 /******************************************************************************/
119
120 /*
121 * @implemented
122 */
123 BOOL STDCALL
124 AreAllAccessesGranted(DWORD GrantedAccess,
125 DWORD DesiredAccess)
126 {
127 return((BOOL)RtlAreAllAccessesGranted(GrantedAccess,
128 DesiredAccess));
129 }
130
131
132 /*
133 * @implemented
134 */
135 BOOL STDCALL
136 AreAnyAccessesGranted(DWORD GrantedAccess,
137 DWORD DesiredAccess)
138 {
139 return((BOOL)RtlAreAnyAccessesGranted(GrantedAccess,
140 DesiredAccess));
141 }
142
143
144 /******************************************************************************
145 * GetFileSecurityA [ADVAPI32.@]
146 *
147 * Obtains Specified information about the security of a file or directory.
148 *
149 * PARAMS
150 * lpFileName [I] Name of the file to get info for
151 * RequestedInformation [I] SE_ flags from "winnt.h"
152 * pSecurityDescriptor [O] Destination for security information
153 * nLength [I] Length of pSecurityDescriptor
154 * lpnLengthNeeded [O] Destination for length of returned security information
155 *
156 * RETURNS
157 * Success: TRUE. pSecurityDescriptor contains the requested information.
158 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
159 *
160 * NOTES
161 * The information returned is constrained by the callers access rights and
162 * privileges.
163 *
164 * @implemented
165 */
166 BOOL WINAPI
167 GetFileSecurityA(LPCSTR lpFileName,
168 SECURITY_INFORMATION RequestedInformation,
169 PSECURITY_DESCRIPTOR pSecurityDescriptor,
170 DWORD nLength,
171 LPDWORD lpnLengthNeeded)
172 {
173 UNICODE_STRING FileName;
174 NTSTATUS Status;
175 BOOL bResult;
176
177 Status = RtlCreateUnicodeStringFromAsciiz(&FileName,
178 (LPSTR)lpFileName);
179 if (!NT_SUCCESS(Status))
180 {
181 SetLastError(RtlNtStatusToDosError(Status));
182 return FALSE;
183 }
184
185 bResult = GetFileSecurityW(FileName.Buffer,
186 RequestedInformation,
187 pSecurityDescriptor,
188 nLength,
189 lpnLengthNeeded);
190
191 RtlFreeUnicodeString(&FileName);
192
193 return bResult;
194 }
195
196
197 /*
198 * @implemented
199 */
200 BOOL WINAPI
201 GetFileSecurityW(LPCWSTR lpFileName,
202 SECURITY_INFORMATION RequestedInformation,
203 PSECURITY_DESCRIPTOR pSecurityDescriptor,
204 DWORD nLength,
205 LPDWORD lpnLengthNeeded)
206 {
207 OBJECT_ATTRIBUTES ObjectAttributes;
208 IO_STATUS_BLOCK StatusBlock;
209 UNICODE_STRING FileName;
210 ULONG AccessMask = 0;
211 HANDLE FileHandle;
212 NTSTATUS Status;
213
214 DPRINT("GetFileSecurityW() called\n");
215
216 if (RequestedInformation &
217 (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION))
218 {
219 AccessMask |= STANDARD_RIGHTS_READ;
220 }
221
222 if (RequestedInformation & SACL_SECURITY_INFORMATION)
223 {
224 AccessMask |= ACCESS_SYSTEM_SECURITY;
225 }
226
227 if (!RtlDosPathNameToNtPathName_U((LPWSTR)lpFileName,
228 &FileName,
229 NULL,
230 NULL))
231 {
232 DPRINT("Invalid path\n");
233 SetLastError(ERROR_INVALID_NAME);
234 return FALSE;
235 }
236
237 InitializeObjectAttributes(&ObjectAttributes,
238 &FileName,
239 OBJ_CASE_INSENSITIVE,
240 NULL,
241 NULL);
242
243 Status = NtOpenFile(&FileHandle,
244 AccessMask,
245 &ObjectAttributes,
246 &StatusBlock,
247 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
248 0);
249 if (!NT_SUCCESS(Status))
250 {
251 DPRINT("NtOpenFile() failed (Status %lx)\n", Status);
252 SetLastError(RtlNtStatusToDosError(Status));
253 return FALSE;
254 }
255
256 RtlFreeUnicodeString(&FileName);
257
258 Status = NtQuerySecurityObject(FileHandle,
259 RequestedInformation,
260 pSecurityDescriptor,
261 nLength,
262 lpnLengthNeeded);
263 NtClose(FileHandle);
264
265 if (!NT_SUCCESS(Status))
266 {
267 DPRINT("NtQuerySecurityObject() failed (Status %lx)\n", Status);
268 SetLastError(RtlNtStatusToDosError(Status));
269 return FALSE;
270 }
271
272 return TRUE;
273 }
274
275
276 /*
277 * @implemented
278 */
279 BOOL STDCALL
280 GetKernelObjectSecurity(HANDLE Handle,
281 SECURITY_INFORMATION RequestedInformation,
282 PSECURITY_DESCRIPTOR pSecurityDescriptor,
283 DWORD nLength,
284 LPDWORD lpnLengthNeeded)
285 {
286 NTSTATUS Status;
287
288 Status = NtQuerySecurityObject(Handle,
289 RequestedInformation,
290 pSecurityDescriptor,
291 nLength,
292 lpnLengthNeeded);
293 if (!NT_SUCCESS(Status))
294 {
295 SetLastError(RtlNtStatusToDosError(Status));
296 return(FALSE);
297 }
298 return(TRUE);
299 }
300
301
302 /******************************************************************************
303 * SetFileSecurityA [ADVAPI32.@]
304 * Sets the security of a file or directory
305 *
306 * @implemented
307 */
308 BOOL STDCALL
309 SetFileSecurityA (LPCSTR lpFileName,
310 SECURITY_INFORMATION SecurityInformation,
311 PSECURITY_DESCRIPTOR pSecurityDescriptor)
312 {
313 UNICODE_STRING FileName;
314 NTSTATUS Status;
315 BOOL bResult;
316
317 Status = RtlCreateUnicodeStringFromAsciiz(&FileName,
318 (LPSTR)lpFileName);
319 if (!NT_SUCCESS(Status))
320 {
321 SetLastError(RtlNtStatusToDosError(Status));
322 return FALSE;
323 }
324
325 bResult = SetFileSecurityW(FileName.Buffer,
326 SecurityInformation,
327 pSecurityDescriptor);
328
329 RtlFreeUnicodeString(&FileName);
330
331 return bResult;
332 }
333
334
335 /******************************************************************************
336 * SetFileSecurityW [ADVAPI32.@]
337 * Sets the security of a file or directory
338 *
339 * @implemented
340 */
341 BOOL STDCALL
342 SetFileSecurityW (LPCWSTR lpFileName,
343 SECURITY_INFORMATION SecurityInformation,
344 PSECURITY_DESCRIPTOR pSecurityDescriptor)
345 {
346 OBJECT_ATTRIBUTES ObjectAttributes;
347 IO_STATUS_BLOCK StatusBlock;
348 UNICODE_STRING FileName;
349 ULONG AccessMask = 0;
350 HANDLE FileHandle;
351 NTSTATUS Status;
352
353 DPRINT("SetFileSecurityW() called\n");
354
355 if (SecurityInformation &
356 (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION))
357 {
358 AccessMask |= WRITE_OWNER;
359 }
360
361 if (SecurityInformation & DACL_SECURITY_INFORMATION)
362 {
363 AccessMask |= WRITE_DAC;
364 }
365
366 if (SecurityInformation & SACL_SECURITY_INFORMATION)
367 {
368 AccessMask |= ACCESS_SYSTEM_SECURITY;
369 }
370
371 if (!RtlDosPathNameToNtPathName_U((LPWSTR)lpFileName,
372 &FileName,
373 NULL,
374 NULL))
375 {
376 DPRINT("Invalid path\n");
377 SetLastError(ERROR_INVALID_NAME);
378 return FALSE;
379 }
380
381 InitializeObjectAttributes(&ObjectAttributes,
382 &FileName,
383 OBJ_CASE_INSENSITIVE,
384 NULL,
385 NULL);
386
387 Status = NtOpenFile(&FileHandle,
388 AccessMask,
389 &ObjectAttributes,
390 &StatusBlock,
391 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
392 0);
393 if (!NT_SUCCESS(Status))
394 {
395 DPRINT("NtOpenFile() failed (Status %lx)\n", Status);
396 SetLastError(RtlNtStatusToDosError(Status));
397 return FALSE;
398 }
399
400 RtlFreeUnicodeString(&FileName);
401
402 Status = NtSetSecurityObject(FileHandle,
403 SecurityInformation,
404 pSecurityDescriptor);
405 NtClose(FileHandle);
406
407 if (!NT_SUCCESS(Status))
408 {
409 DPRINT("NtSetSecurityObject() failed (Status %lx)\n", Status);
410 SetLastError(RtlNtStatusToDosError(Status));
411 return FALSE;
412 }
413
414 return TRUE;
415 }
416
417
418 /*
419 * @implemented
420 */
421 BOOL STDCALL
422 SetKernelObjectSecurity(HANDLE Handle,
423 SECURITY_INFORMATION SecurityInformation,
424 PSECURITY_DESCRIPTOR SecurityDescriptor)
425 {
426 NTSTATUS Status;
427
428 Status = NtSetSecurityObject(Handle,
429 SecurityInformation,
430 SecurityDescriptor);
431 if (!NT_SUCCESS(Status))
432 {
433 SetLastError(RtlNtStatusToDosError(Status));
434 return FALSE;
435 }
436 return TRUE;
437 }
438
439
440 /*
441 * @implemented
442 */
443 BOOL STDCALL
444 ImpersonateLoggedOnUser(HANDLE hToken)
445 {
446 SECURITY_QUALITY_OF_SERVICE Qos;
447 OBJECT_ATTRIBUTES ObjectAttributes;
448 HANDLE NewToken;
449 TOKEN_TYPE Type;
450 ULONG ReturnLength;
451 BOOL Duplicated;
452 NTSTATUS Status;
453
454 /* Get the token type */
455 Status = NtQueryInformationToken (hToken,
456 TokenType,
457 &Type,
458 sizeof(TOKEN_TYPE),
459 &ReturnLength);
460 if (!NT_SUCCESS(Status))
461 {
462 SetLastError (RtlNtStatusToDosError (Status));
463 return FALSE;
464 }
465
466 if (Type == TokenPrimary)
467 {
468 /* Create a duplicate impersonation token */
469 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
470 Qos.ImpersonationLevel = SecurityImpersonation;
471 Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
472 Qos.EffectiveOnly = FALSE;
473
474 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
475 ObjectAttributes.RootDirectory = NULL;
476 ObjectAttributes.ObjectName = NULL;
477 ObjectAttributes.Attributes = 0;
478 ObjectAttributes.SecurityDescriptor = NULL;
479 ObjectAttributes.SecurityQualityOfService = &Qos;
480
481 Status = NtDuplicateToken (hToken,
482 TOKEN_IMPERSONATE | TOKEN_QUERY,
483 &ObjectAttributes,
484 FALSE,
485 TokenImpersonation,
486 &NewToken);
487 if (!NT_SUCCESS(Status))
488 {
489 SetLastError (RtlNtStatusToDosError (Status));
490 return FALSE;
491 }
492
493 Duplicated = TRUE;
494 }
495 else
496 {
497 /* User the original impersonation token */
498 NewToken = hToken;
499 Duplicated = FALSE;
500 }
501
502 /* Impersonate the the current thread */
503 Status = NtSetInformationThread (NtCurrentThread (),
504 ThreadImpersonationToken,
505 &NewToken,
506 sizeof(HANDLE));
507
508 if (Duplicated == TRUE)
509 {
510 NtClose (NewToken);
511 }
512
513 if (!NT_SUCCESS(Status))
514 {
515 SetLastError (RtlNtStatusToDosError (Status));
516 return FALSE;
517 }
518
519 return TRUE;
520 }
521
522
523 /*
524 * @implemented
525 */
526 BOOL STDCALL
527 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
528 {
529 NTSTATUS Status;
530
531 Status = RtlImpersonateSelf(ImpersonationLevel);
532 if (!NT_SUCCESS(Status))
533 {
534 SetLastError(RtlNtStatusToDosError(Status));
535 return FALSE;
536 }
537 return TRUE;
538 }
539
540
541 /*
542 * @implemented
543 */
544 BOOL STDCALL
545 RevertToSelf(VOID)
546 {
547 NTSTATUS Status;
548 HANDLE Token = NULL;
549
550 Status = NtSetInformationThread(NtCurrentThread(),
551 ThreadImpersonationToken,
552 &Token,
553 sizeof(HANDLE));
554 if (!NT_SUCCESS(Status))
555 {
556 SetLastError(RtlNtStatusToDosError(Status));
557 return FALSE;
558 }
559 return TRUE;
560 }
561
562
563 /******************************************************************************
564 * GetUserNameA [ADVAPI32.@]
565 *
566 * Get the current user name.
567 *
568 * PARAMS
569 * lpszName [O] Destination for the user name.
570 * lpSize [I/O] Size of lpszName.
571 *
572 *
573 * @implemented
574 */
575 BOOL WINAPI
576 GetUserNameA( LPSTR lpszName, LPDWORD lpSize )
577 {
578 UNICODE_STRING NameW;
579 ANSI_STRING NameA;
580 BOOL Ret;
581
582 /* apparently Win doesn't check whether lpSize is valid at all! */
583
584 NameW.Length = 0;
585 NameW.MaximumLength = (*lpSize) * sizeof(WCHAR);
586 NameW.Buffer = LocalAlloc(LMEM_FIXED, NameW.MaximumLength);
587 if(NameW.Buffer == NULL)
588 {
589 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
590 return FALSE;
591 }
592
593 NameA.Length = 0;
594 NameA.MaximumLength = ((*lpSize) < 0xFFFF ? (USHORT)(*lpSize) : 0xFFFF);
595 NameA.Buffer = lpszName;
596
597 Ret = GetUserNameW(NameW.Buffer,
598 lpSize);
599 if(Ret)
600 {
601 RtlUnicodeStringToAnsiString(&NameA, &NameW, FALSE);
602 NameA.Buffer[NameA.Length] = '\0';
603
604 *lpSize = NameA.Length + 1;
605 }
606
607 LocalFree(NameW.Buffer);
608
609 return Ret;
610 }
611
612 /******************************************************************************
613 * GetUserNameW [ADVAPI32.@]
614 *
615 * See GetUserNameA.
616 *
617 * @implemented
618 */
619 BOOL WINAPI
620 GetUserNameW ( LPWSTR lpszName, LPDWORD lpSize )
621 {
622 HANDLE hToken = INVALID_HANDLE_VALUE;
623 DWORD tu_len = 0;
624 char* tu_buf = NULL;
625 TOKEN_USER* token_user = NULL;
626 DWORD an_len = 0;
627 SID_NAME_USE snu = SidTypeUser;
628 WCHAR* domain_name = NULL;
629 DWORD dn_len = 0;
630
631 if ( !OpenThreadToken ( GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken ) )
632 {
633 DWORD dwLastError = GetLastError();
634 if ( dwLastError != ERROR_NO_TOKEN
635 && dwLastError != ERROR_NO_IMPERSONATION_TOKEN )
636 {
637 /* don't call SetLastError(),
638 as OpenThreadToken() ought to have set one */
639 return FALSE;
640 }
641 if ( !OpenProcessToken ( GetCurrentProcess(), TOKEN_QUERY, &hToken ) )
642 {
643 /* don't call SetLastError(),
644 as OpenProcessToken() ought to have set one */
645 return FALSE;
646 }
647 }
648 tu_buf = LocalAlloc ( LMEM_FIXED, 36 );
649 if ( !tu_buf )
650 {
651 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
652 return FALSE;
653 }
654 if ( !GetTokenInformation ( hToken, TokenUser, tu_buf, 36, &tu_len ) || tu_len > 36 )
655 {
656 LocalFree ( tu_buf );
657 tu_buf = LocalAlloc ( LMEM_FIXED, tu_len );
658 if ( !tu_buf )
659 {
660 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
661 return FALSE;
662 }
663 if ( !GetTokenInformation ( hToken, TokenUser, tu_buf, tu_len, &tu_len ) )
664 {
665 /* don't call SetLastError(),
666 as GetTokenInformation() ought to have set one */
667 LocalFree ( tu_buf );
668 CloseHandle ( hToken );
669 return FALSE;
670 }
671 }
672 token_user = (TOKEN_USER*)tu_buf;
673
674 an_len = *lpSize;
675 dn_len = 32;
676 domain_name = LocalAlloc ( LMEM_FIXED, dn_len * sizeof(WCHAR) );
677 if ( !domain_name )
678 {
679 LocalFree ( tu_buf );
680 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
681 return FALSE;
682 }
683 if ( !LookupAccountSidW ( NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu )
684 || dn_len > 32 )
685 {
686 if ( dn_len > 32 )
687 {
688 LocalFree ( domain_name );
689 domain_name = LocalAlloc ( LMEM_FIXED, dn_len * sizeof(WCHAR) );
690 if ( !domain_name )
691 {
692 LocalFree ( tu_buf );
693 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
694 return FALSE;
695 }
696 }
697 if ( !LookupAccountSidW ( NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu ) )
698 {
699 /* don't call SetLastError(),
700 as LookupAccountSid() ought to have set one */
701 LocalFree ( domain_name );
702 CloseHandle ( hToken );
703 return FALSE;
704 }
705 }
706
707 LocalFree ( domain_name );
708 LocalFree ( tu_buf );
709 CloseHandle ( hToken );
710
711 if ( an_len > *lpSize )
712 {
713 *lpSize = an_len;
714 SetLastError(ERROR_INSUFFICIENT_BUFFER);
715 return FALSE;
716 }
717
718 return TRUE;
719 }
720
721
722 /******************************************************************************
723 * LookupAccountSidA [ADVAPI32.@]
724 *
725 * @implemented
726 */
727 BOOL STDCALL
728 LookupAccountSidA (LPCSTR lpSystemName,
729 PSID lpSid,
730 LPSTR lpName,
731 LPDWORD cchName,
732 LPSTR lpReferencedDomainName,
733 LPDWORD cchReferencedDomainName,
734 PSID_NAME_USE peUse)
735 {
736 UNICODE_STRING NameW, ReferencedDomainNameW, SystemNameW;
737 DWORD szName, szReferencedDomainName;
738 BOOL Ret;
739
740 /*
741 * save the buffer sizes the caller passed to us, as they may get modified and
742 * we require the original values when converting back to ansi
743 */
744 szName = *cchName;
745 szReferencedDomainName = *cchReferencedDomainName;
746
747 /*
748 * allocate buffers for the unicode strings to receive
749 */
750
751 if(szName > 0)
752 {
753 NameW.Length = 0;
754 NameW.MaximumLength = szName * sizeof(WCHAR);
755 NameW.Buffer = (PWSTR)LocalAlloc(LMEM_FIXED, NameW.MaximumLength);
756 if(NameW.Buffer == NULL)
757 {
758 SetLastError(ERROR_OUTOFMEMORY);
759 return FALSE;
760 }
761 }
762 else
763 NameW.Buffer = NULL;
764
765 if(szReferencedDomainName > 0)
766 {
767 ReferencedDomainNameW.Length = 0;
768 ReferencedDomainNameW.MaximumLength = szReferencedDomainName * sizeof(WCHAR);
769 ReferencedDomainNameW.Buffer = (PWSTR)LocalAlloc(LMEM_FIXED, ReferencedDomainNameW.MaximumLength);
770 if(ReferencedDomainNameW.Buffer == NULL)
771 {
772 if(szName > 0)
773 {
774 LocalFree(NameW.Buffer);
775 }
776 SetLastError(ERROR_OUTOFMEMORY);
777 return FALSE;
778 }
779 }
780 else
781 ReferencedDomainNameW.Buffer = NULL;
782
783 /*
784 * convert the system name to unicode - if present
785 */
786
787 if(lpSystemName != NULL)
788 {
789 ANSI_STRING SystemNameA;
790
791 RtlInitAnsiString(&SystemNameA, lpSystemName);
792 RtlAnsiStringToUnicodeString(&SystemNameW, &SystemNameA, TRUE);
793 }
794 else
795 SystemNameW.Buffer = NULL;
796
797 /*
798 * it's time to call the unicode version
799 */
800
801 Ret = LookupAccountSidW(SystemNameW.Buffer,
802 lpSid,
803 NameW.Buffer,
804 cchName,
805 ReferencedDomainNameW.Buffer,
806 cchReferencedDomainName,
807 peUse);
808 if(Ret)
809 {
810 /*
811 * convert unicode strings back to ansi, don't forget that we can't convert
812 * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly
813 * terminate the converted string, the Rtl functions don't do that!
814 */
815 if(lpName != NULL)
816 {
817 ANSI_STRING NameA;
818
819 NameA.Length = 0;
820 NameA.MaximumLength = ((szName <= 0xFFFF) ? (USHORT)szName : 0xFFFF);
821 NameA.Buffer = lpName;
822
823 RtlUnicodeStringToAnsiString(&NameA, &NameW, FALSE);
824 NameA.Buffer[NameA.Length] = '\0';
825 }
826
827 if(lpReferencedDomainName != NULL)
828 {
829 ANSI_STRING ReferencedDomainNameA;
830
831 ReferencedDomainNameA.Length = 0;
832 ReferencedDomainNameA.MaximumLength = ((szReferencedDomainName <= 0xFFFF) ?
833 (USHORT)szReferencedDomainName : 0xFFFF);
834 ReferencedDomainNameA.Buffer = lpReferencedDomainName;
835
836 RtlUnicodeStringToAnsiString(&ReferencedDomainNameA, &ReferencedDomainNameW, FALSE);
837 ReferencedDomainNameA.Buffer[ReferencedDomainNameA.Length] = '\0';
838 }
839 }
840
841 /*
842 * free previously allocated buffers
843 */
844
845 if(SystemNameW.Buffer != NULL)
846 {
847 RtlFreeUnicodeString(&SystemNameW);
848 }
849 if(NameW.Buffer != NULL)
850 {
851 LocalFree(NameW.Buffer);
852 }
853 if(ReferencedDomainNameW.Buffer != NULL)
854 {
855 LocalFree(ReferencedDomainNameW.Buffer);
856 }
857
858 return Ret;
859 }
860
861
862 /******************************************************************************
863 * LookupAccountSidW [ADVAPI32.@]
864 *
865 * @implemented
866 */
867 BOOL WINAPI
868 LookupAccountSidW (
869 LPCWSTR pSystemName,
870 PSID pSid,
871 LPWSTR pAccountName,
872 LPDWORD pdwAccountName,
873 LPWSTR pDomainName,
874 LPDWORD pdwDomainName,
875 PSID_NAME_USE peUse )
876 {
877 LSA_UNICODE_STRING SystemName;
878 LSA_OBJECT_ATTRIBUTES ObjectAttributes;
879 LSA_HANDLE PolicyHandle = INVALID_HANDLE_VALUE;
880 NTSTATUS Status;
881 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain = NULL;
882 PLSA_TRANSLATED_NAME TranslatedName = NULL;
883 BOOL ret;
884
885 RtlInitUnicodeString ( &SystemName, pSystemName );
886 ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
887 Status = LsaOpenPolicy ( &SystemName, &ObjectAttributes, POLICY_LOOKUP_NAMES, &PolicyHandle );
888 if ( !NT_SUCCESS(Status) )
889 {
890 SetLastError ( LsaNtStatusToWinError(Status) );
891 return FALSE;
892 }
893 Status = LsaLookupSids ( PolicyHandle, 1, &pSid, &ReferencedDomain, &TranslatedName );
894
895 LsaClose ( PolicyHandle );
896
897 if ( !NT_SUCCESS(Status) || Status == STATUS_SOME_NOT_MAPPED )
898 {
899 SetLastError ( LsaNtStatusToWinError(Status) );
900 ret = FALSE;
901 }
902 else
903 {
904 ret = TRUE;
905 if ( TranslatedName )
906 {
907 DWORD dwSrcLen = TranslatedName->Name.Length / sizeof(WCHAR);
908 if ( *pdwAccountName <= dwSrcLen )
909 {
910 *pdwAccountName = dwSrcLen + 1;
911 ret = FALSE;
912 }
913 else
914 {
915 *pdwAccountName = dwSrcLen;
916 wcscpy ( pAccountName, TranslatedName->Name.Buffer );
917 }
918 if ( peUse )
919 *peUse = TranslatedName->Use;
920 }
921
922 if ( ReferencedDomain )
923 {
924 if ( ReferencedDomain->Entries > 0 )
925 {
926 DWORD dwSrcLen = ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR);
927 if ( *pdwDomainName <= dwSrcLen )
928 {
929 *pdwDomainName = dwSrcLen + 1;
930 ret = FALSE;
931 }
932 else
933 {
934 *pdwDomainName = dwSrcLen;
935 wcscpy ( pDomainName, ReferencedDomain->Domains[0].Name.Buffer );
936 }
937 }
938 }
939
940 if ( !ret )
941 SetLastError(ERROR_INSUFFICIENT_BUFFER);
942 }
943
944 if ( ReferencedDomain )
945 LsaFreeMemory ( ReferencedDomain );
946 if ( TranslatedName )
947 LsaFreeMemory ( TranslatedName );
948
949 return ret;
950 }
951
952
953
954 /******************************************************************************
955 * LookupAccountNameA [ADVAPI32.@]
956 *
957 * @unimplemented
958 */
959 BOOL STDCALL
960 LookupAccountNameA (LPCSTR SystemName,
961 LPCSTR AccountName,
962 PSID Sid,
963 LPDWORD SidLength,
964 LPSTR ReferencedDomainName,
965 LPDWORD hReferencedDomainNameLength,
966 PSID_NAME_USE SidNameUse)
967 {
968 DPRINT1("LookupAccountNameA is unimplemented\n");
969 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
970 return FALSE;
971 }
972
973
974 /******************************************************************************
975 * LookupAccountNameW [ADVAPI32.@]
976 *
977 * @unimplemented
978 */
979 BOOL STDCALL
980 LookupAccountNameW (LPCWSTR SystemName,
981 LPCWSTR AccountName,
982 PSID Sid,
983 LPDWORD SidLength,
984 LPWSTR ReferencedDomainName,
985 LPDWORD hReferencedDomainNameLength,
986 PSID_NAME_USE SidNameUse)
987 {
988 DPRINT1("LookupAccountNameW is unimplemented\n");
989 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
990 return FALSE;
991 }
992
993
994 /**********************************************************************
995 * LookupPrivilegeValueA EXPORTED
996 *
997 * @implemented
998 */
999 BOOL STDCALL
1000 LookupPrivilegeValueA (LPCSTR lpSystemName,
1001 LPCSTR lpName,
1002 PLUID lpLuid)
1003 {
1004 UNICODE_STRING SystemName;
1005 UNICODE_STRING Name;
1006 BOOL Result;
1007
1008 /* Remote system? */
1009 if (lpSystemName != NULL)
1010 {
1011 RtlCreateUnicodeStringFromAsciiz (&SystemName,
1012 (LPSTR)lpSystemName);
1013 }
1014
1015 /* Check the privilege name is not NULL */
1016 if (lpName == NULL)
1017 {
1018 SetLastError (ERROR_INVALID_PARAMETER);
1019 return FALSE;
1020 }
1021
1022 RtlCreateUnicodeStringFromAsciiz (&Name,
1023 (LPSTR)lpName);
1024
1025 Result = LookupPrivilegeValueW ((lpSystemName != NULL) ? SystemName.Buffer : NULL,
1026 Name.Buffer,
1027 lpLuid);
1028
1029 RtlFreeUnicodeString (&Name);
1030
1031 /* Remote system? */
1032 if (lpSystemName != NULL)
1033 {
1034 RtlFreeUnicodeString (&SystemName);
1035 }
1036
1037 return Result;
1038 }
1039
1040
1041 /**********************************************************************
1042 * LookupPrivilegeValueW EXPORTED
1043 *
1044 * @unimplemented
1045 */
1046 BOOL STDCALL
1047 LookupPrivilegeValueW (LPCWSTR SystemName,
1048 LPCWSTR PrivName,
1049 PLUID Luid)
1050 {
1051 static const WCHAR * const DefaultPrivNames[] =
1052 {
1053 L"SeCreateTokenPrivilege",
1054 L"SeAssignPrimaryTokenPrivilege",
1055 L"SeLockMemoryPrivilege",
1056 L"SeIncreaseQuotaPrivilege",
1057 L"SeUnsolicitedInputPrivilege",
1058 L"SeMachineAccountPrivilege",
1059 L"SeTcbPrivilege",
1060 L"SeSecurityPrivilege",
1061 L"SeTakeOwnershipPrivilege",
1062 L"SeLoadDriverPrivilege",
1063 L"SeSystemProfilePrivilege",
1064 L"SeSystemtimePrivilege",
1065 L"SeProfileSingleProcessPrivilege",
1066 L"SeIncreaseBasePriorityPrivilege",
1067 L"SeCreatePagefilePrivilege",
1068 L"SeCreatePermanentPrivilege",
1069 L"SeBackupPrivilege",
1070 L"SeRestorePrivilege",
1071 L"SeShutdownPrivilege",
1072 L"SeDebugPrivilege",
1073 L"SeAuditPrivilege",
1074 L"SeSystemEnvironmentPrivilege",
1075 L"SeChangeNotifyPrivilege",
1076 L"SeRemoteShutdownPrivilege",
1077 L"SeUndockPrivilege",
1078 L"SeSyncAgentPrivilege",
1079 L"SeEnableDelegationPrivilege",
1080 L"SeManageVolumePrivilege",
1081 L"SeImpersonatePrivilege",
1082 L"SeCreateGlobalPrivilege"
1083 };
1084 unsigned Priv;
1085
1086 if (NULL != SystemName && L'\0' != *SystemName)
1087 {
1088 DPRINT1("LookupPrivilegeValueW: not implemented for remote system\n");
1089 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1090 return FALSE;
1091 }
1092
1093 for (Priv = 0; Priv < sizeof(DefaultPrivNames) / sizeof(DefaultPrivNames[0]); Priv++)
1094 {
1095 if (0 == wcscmp(PrivName, DefaultPrivNames[Priv]))
1096 {
1097 Luid->LowPart = Priv + 1;
1098 Luid->HighPart = 0;
1099 return TRUE;
1100 }
1101 }
1102
1103 DPRINT1("LookupPrivilegeValueW: no such privilege %S\n", PrivName);
1104 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1105 return FALSE;
1106 }
1107
1108
1109 /**********************************************************************
1110 * LookupPrivilegeDisplayNameA EXPORTED
1111 *
1112 * @unimplemented
1113 */
1114 BOOL STDCALL
1115 LookupPrivilegeDisplayNameA (LPCSTR lpSystemName,
1116 LPCSTR lpName,
1117 LPSTR lpDisplayName,
1118 LPDWORD cbDisplayName,
1119 LPDWORD lpLanguageId)
1120 {
1121 DPRINT1("LookupPrivilegeDisplayNameA: stub\n");
1122 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1123 return FALSE;
1124 }
1125
1126
1127 /**********************************************************************
1128 * LookupPrivilegeDisplayNameW EXPORTED
1129 *
1130 * @unimplemented
1131 */
1132 BOOL STDCALL
1133 LookupPrivilegeDisplayNameW (LPCWSTR lpSystemName,
1134 LPCWSTR lpName,
1135 LPWSTR lpDisplayName,
1136 LPDWORD cbDisplayName,
1137 LPDWORD lpLanguageId)
1138 {
1139 DPRINT1("LookupPrivilegeDisplayNameW: stub\n");
1140 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1141 return FALSE;
1142 }
1143
1144
1145 /**********************************************************************
1146 * LookupPrivilegeNameA EXPORTED
1147 *
1148 * @unimplemented
1149 */
1150 BOOL STDCALL
1151 LookupPrivilegeNameA (LPCSTR lpSystemName,
1152 PLUID lpLuid,
1153 LPSTR lpName,
1154 LPDWORD cbName)
1155 {
1156 DPRINT1("LookupPrivilegeNameA: stub\n");
1157 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1158 return FALSE;
1159 }
1160
1161
1162 /**********************************************************************
1163 * LookupPrivilegeNameW EXPORTED
1164 *
1165 * @unimplemented
1166 */
1167 BOOL STDCALL
1168 LookupPrivilegeNameW (LPCWSTR lpSystemName,
1169 PLUID lpLuid,
1170 LPWSTR lpName,
1171 LPDWORD cbName)
1172 {
1173 DPRINT1("LookupPrivilegeNameW: stub\n");
1174 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1175 return FALSE;
1176 }
1177
1178
1179 static DWORD
1180 pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo,
1181 PSID* ppsidOwner,
1182 PSID* ppsidGroup,
1183 PACL* ppDacl,
1184 PACL* ppSacl,
1185 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
1186 {
1187 if ((SecurityInfo & (OWNER_SECURITY_INFORMATION |
1188 GROUP_SECURITY_INFORMATION |
1189 DACL_SECURITY_INFORMATION |
1190 SACL_SECURITY_INFORMATION)) &&
1191 ppSecurityDescriptor == NULL)
1192 {
1193 /* if one of the SIDs or ACLs are present, the security descriptor
1194 most not be NULL */
1195 return ERROR_INVALID_PARAMETER;
1196 }
1197 else
1198 {
1199 /* reset the pointers unless they're ignored */
1200 if ((SecurityInfo & OWNER_SECURITY_INFORMATION) &&
1201 ppsidOwner != NULL)
1202 {
1203 ppsidOwner = NULL;
1204 }
1205 if ((SecurityInfo & GROUP_SECURITY_INFORMATION) &&
1206 *ppsidGroup != NULL)
1207 {
1208 *ppsidGroup = NULL;
1209 }
1210 if ((SecurityInfo & DACL_SECURITY_INFORMATION) &&
1211 ppDacl != NULL)
1212 {
1213 *ppDacl = NULL;
1214 }
1215 if ((SecurityInfo & SACL_SECURITY_INFORMATION) &&
1216 ppSacl != NULL)
1217 {
1218 *ppSacl = NULL;
1219 }
1220
1221 if (SecurityInfo & (OWNER_SECURITY_INFORMATION |
1222 GROUP_SECURITY_INFORMATION |
1223 DACL_SECURITY_INFORMATION |
1224 SACL_SECURITY_INFORMATION))
1225 {
1226 *ppSecurityDescriptor = NULL;
1227 }
1228
1229 return ERROR_SUCCESS;
1230 }
1231 }
1232
1233
1234 static DWORD
1235 pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor,
1236 SECURITY_INFORMATION SecurityInfo,
1237 PSID psidOwner,
1238 PSID psidGroup,
1239 PACL pDacl,
1240 PACL pSacl)
1241 {
1242 /* initialize a security descriptor on the stack */
1243 if (!InitializeSecurityDescriptor(pSecurityDescriptor,
1244 SECURITY_DESCRIPTOR_REVISION))
1245 {
1246 return GetLastError();
1247 }
1248
1249 if (SecurityInfo & OWNER_SECURITY_INFORMATION)
1250 {
1251 if (RtlValidSid(psidOwner))
1252 {
1253 if (!SetSecurityDescriptorOwner(pSecurityDescriptor,
1254 psidOwner,
1255 FALSE))
1256 {
1257 return GetLastError();
1258 }
1259 }
1260 else
1261 {
1262 return ERROR_INVALID_PARAMETER;
1263 }
1264 }
1265
1266 if (SecurityInfo & GROUP_SECURITY_INFORMATION)
1267 {
1268 if (RtlValidSid(psidGroup))
1269 {
1270 if (!SetSecurityDescriptorGroup(pSecurityDescriptor,
1271 psidGroup,
1272 FALSE))
1273 {
1274 return GetLastError();
1275 }
1276 }
1277 else
1278 {
1279 return ERROR_INVALID_PARAMETER;
1280 }
1281 }
1282
1283 if (SecurityInfo & DACL_SECURITY_INFORMATION)
1284 {
1285 if (pDacl != NULL)
1286 {
1287 if (SetSecurityDescriptorDacl(pSecurityDescriptor,
1288 TRUE,
1289 pDacl,
1290 FALSE))
1291 {
1292 /* check if the DACL needs to be protected from being
1293 modified by inheritable ACEs */
1294 if (SecurityInfo & PROTECTED_DACL_SECURITY_INFORMATION)
1295 {
1296 goto ProtectDacl;
1297 }
1298 }
1299 else
1300 {
1301 return GetLastError();
1302 }
1303 }
1304 else
1305 {
1306 ProtectDacl:
1307 /* protect the DACL from being modified by inheritable ACEs */
1308 if (!SetSecurityDescriptorControl(pSecurityDescriptor,
1309 SE_DACL_PROTECTED,
1310 SE_DACL_PROTECTED))
1311 {
1312 return GetLastError();
1313 }
1314 }
1315 }
1316
1317 if (SecurityInfo & SACL_SECURITY_INFORMATION)
1318 {
1319 if (pSacl != NULL)
1320 {
1321 if (SetSecurityDescriptorSacl(pSecurityDescriptor,
1322 TRUE,
1323 pSacl,
1324 FALSE))
1325 {
1326 /* check if the SACL needs to be protected from being
1327 modified by inheritable ACEs */
1328 if (SecurityInfo & PROTECTED_SACL_SECURITY_INFORMATION)
1329 {
1330 goto ProtectSacl;
1331 }
1332 }
1333 else
1334 {
1335 return GetLastError();
1336 }
1337 }
1338 else
1339 {
1340 ProtectSacl:
1341 /* protect the SACL from being modified by inheritable ACEs */
1342 if (!SetSecurityDescriptorControl(pSecurityDescriptor,
1343 SE_SACL_PROTECTED,
1344 SE_SACL_PROTECTED))
1345 {
1346 return GetLastError();
1347 }
1348 }
1349 }
1350
1351 return ERROR_SUCCESS;
1352 }
1353
1354
1355 /**********************************************************************
1356 * GetNamedSecurityInfoW EXPORTED
1357 *
1358 * @implemented
1359 */
1360 DWORD STDCALL
1361 GetNamedSecurityInfoW(LPWSTR pObjectName,
1362 SE_OBJECT_TYPE ObjectType,
1363 SECURITY_INFORMATION SecurityInfo,
1364 PSID *ppsidOwner,
1365 PSID *ppsidGroup,
1366 PACL *ppDacl,
1367 PACL *ppSacl,
1368 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1369 {
1370 DWORD ErrorCode;
1371
1372 if (pObjectName != NULL)
1373 {
1374 ErrorCode = CheckNtMartaPresent();
1375 if (ErrorCode == ERROR_SUCCESS)
1376 {
1377 ErrorCode = pGetSecurityInfoCheck(SecurityInfo,
1378 ppsidOwner,
1379 ppsidGroup,
1380 ppDacl,
1381 ppSacl,
1382 ppSecurityDescriptor);
1383
1384 if (ErrorCode == ERROR_SUCCESS)
1385 {
1386 /* call the MARTA provider */
1387 ErrorCode = AccRewriteGetNamedRights(pObjectName,
1388 ObjectType,
1389 SecurityInfo,
1390 ppsidOwner,
1391 ppsidGroup,
1392 ppDacl,
1393 ppSacl,
1394 ppSecurityDescriptor);
1395 }
1396 }
1397 }
1398 else
1399 ErrorCode = ERROR_INVALID_PARAMETER;
1400
1401 return ErrorCode;
1402 }
1403
1404
1405 /**********************************************************************
1406 * GetNamedSecurityInfoA EXPORTED
1407 *
1408 * @implemented
1409 */
1410 DWORD STDCALL
1411 GetNamedSecurityInfoA(LPSTR pObjectName,
1412 SE_OBJECT_TYPE ObjectType,
1413 SECURITY_INFORMATION SecurityInfo,
1414 PSID *ppsidOwner,
1415 PSID *ppsidGroup,
1416 PACL *ppDacl,
1417 PACL *ppSacl,
1418 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1419 {
1420 UNICODE_STRING ObjectName;
1421 NTSTATUS Status;
1422 DWORD Ret;
1423
1424 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
1425 pObjectName);
1426 if (!NT_SUCCESS(Status))
1427 {
1428 return RtlNtStatusToDosError(Status);
1429 }
1430
1431 Ret = GetNamedSecurityInfoW(ObjectName.Buffer,
1432 ObjectType,
1433 SecurityInfo,
1434 ppsidOwner,
1435 ppsidGroup,
1436 ppDacl,
1437 ppSacl,
1438 ppSecurityDescriptor);
1439
1440 RtlFreeUnicodeString(&ObjectName);
1441
1442 return Ret;
1443 }
1444
1445
1446 /**********************************************************************
1447 * SetNamedSecurityInfoW EXPORTED
1448 *
1449 * @implemented
1450 */
1451 DWORD STDCALL
1452 SetNamedSecurityInfoW(LPWSTR pObjectName,
1453 SE_OBJECT_TYPE ObjectType,
1454 SECURITY_INFORMATION SecurityInfo,
1455 PSID psidOwner,
1456 PSID psidGroup,
1457 PACL pDacl,
1458 PACL pSacl)
1459 {
1460 DWORD ErrorCode;
1461
1462 if (pObjectName != NULL)
1463 {
1464 ErrorCode = CheckNtMartaPresent();
1465 if (ErrorCode == ERROR_SUCCESS)
1466 {
1467 SECURITY_DESCRIPTOR SecurityDescriptor;
1468
1469 ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor,
1470 SecurityInfo,
1471 psidOwner,
1472 psidGroup,
1473 pDacl,
1474 pSacl);
1475
1476 if (ErrorCode == ERROR_SUCCESS)
1477 {
1478 /* call the MARTA provider */
1479 ErrorCode = AccRewriteSetNamedRights(pObjectName,
1480 ObjectType,
1481 SecurityInfo,
1482 &SecurityDescriptor);
1483 }
1484 }
1485 }
1486 else
1487 ErrorCode = ERROR_INVALID_PARAMETER;
1488
1489 return ErrorCode;
1490 }
1491
1492
1493 /**********************************************************************
1494 * SetNamedSecurityInfoA EXPORTED
1495 *
1496 * @implemented
1497 */
1498 DWORD STDCALL
1499 SetNamedSecurityInfoA(LPSTR pObjectName,
1500 SE_OBJECT_TYPE ObjectType,
1501 SECURITY_INFORMATION SecurityInfo,
1502 PSID psidOwner,
1503 PSID psidGroup,
1504 PACL pDacl,
1505 PACL pSacl)
1506 {
1507 UNICODE_STRING ObjectName;
1508 NTSTATUS Status;
1509 DWORD Ret;
1510
1511 Status = RtlCreateUnicodeStringFromAsciiz(&ObjectName,
1512 pObjectName);
1513 if (!NT_SUCCESS(Status))
1514 {
1515 return RtlNtStatusToDosError(Status);
1516 }
1517
1518 Ret = SetNamedSecurityInfoW(ObjectName.Buffer,
1519 ObjectType,
1520 SecurityInfo,
1521 psidOwner,
1522 psidGroup,
1523 pDacl,
1524 pSacl);
1525
1526 RtlFreeUnicodeString(&ObjectName);
1527
1528 return Ret;
1529 }
1530
1531
1532 /**********************************************************************
1533 * GetSecurityInfo EXPORTED
1534 *
1535 * @implemented
1536 */
1537 DWORD STDCALL
1538 GetSecurityInfo(HANDLE handle,
1539 SE_OBJECT_TYPE ObjectType,
1540 SECURITY_INFORMATION SecurityInfo,
1541 PSID* ppsidOwner,
1542 PSID* ppsidGroup,
1543 PACL* ppDacl,
1544 PACL* ppSacl,
1545 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
1546 {
1547 DWORD ErrorCode;
1548
1549 if (handle != NULL)
1550 {
1551 ErrorCode = CheckNtMartaPresent();
1552 if (ErrorCode == ERROR_SUCCESS)
1553 {
1554 ErrorCode = pGetSecurityInfoCheck(SecurityInfo,
1555 ppsidOwner,
1556 ppsidGroup,
1557 ppDacl,
1558 ppSacl,
1559 ppSecurityDescriptor);
1560
1561 if (ErrorCode == ERROR_SUCCESS)
1562 {
1563 /* call the MARTA provider */
1564 ErrorCode = AccRewriteGetHandleRights(handle,
1565 ObjectType,
1566 SecurityInfo,
1567 ppsidOwner,
1568 ppsidGroup,
1569 ppDacl,
1570 ppSacl,
1571 ppSecurityDescriptor);
1572 }
1573 }
1574 }
1575 else
1576 ErrorCode = ERROR_INVALID_HANDLE;
1577
1578 return ErrorCode;
1579 }
1580
1581
1582 /**********************************************************************
1583 * SetSecurityInfo EXPORTED
1584 *
1585 * @implemented
1586 */
1587 DWORD
1588 WINAPI
1589 SetSecurityInfo(HANDLE handle,
1590 SE_OBJECT_TYPE ObjectType,
1591 SECURITY_INFORMATION SecurityInfo,
1592 PSID psidOwner,
1593 PSID psidGroup,
1594 PACL pDacl,
1595 PACL pSacl)
1596 {
1597 DWORD ErrorCode;
1598
1599 if (handle != NULL)
1600 {
1601 ErrorCode = CheckNtMartaPresent();
1602 if (ErrorCode == ERROR_SUCCESS)
1603 {
1604 SECURITY_DESCRIPTOR SecurityDescriptor;
1605
1606 ErrorCode = pSetSecurityInfoCheck(&SecurityDescriptor,
1607 SecurityInfo,
1608 psidOwner,
1609 psidGroup,
1610 pDacl,
1611 pSacl);
1612
1613 if (ErrorCode == ERROR_SUCCESS)
1614 {
1615 /* call the MARTA provider */
1616 ErrorCode = AccRewriteSetHandleRights(handle,
1617 ObjectType,
1618 SecurityInfo,
1619 &SecurityDescriptor);
1620 }
1621 }
1622 }
1623 else
1624 ErrorCode = ERROR_INVALID_HANDLE;
1625
1626 return ErrorCode;
1627 }
1628
1629
1630 /******************************************************************************
1631 * GetSecurityInfoExW EXPORTED
1632 */
1633 DWORD WINAPI GetSecurityInfoExA(
1634 HANDLE hObject,
1635 SE_OBJECT_TYPE ObjectType,
1636 SECURITY_INFORMATION SecurityInfo,
1637 LPCSTR lpProvider,
1638 LPCSTR lpProperty,
1639 PACTRL_ACCESSA *ppAccessList,
1640 PACTRL_AUDITA *ppAuditList,
1641 LPSTR *lppOwner,
1642 LPSTR *lppGroup
1643 )
1644 {
1645 DPRINT1("GetSecurityInfoExA stub!\n");
1646 return ERROR_BAD_PROVIDER;
1647 }
1648
1649
1650 /******************************************************************************
1651 * GetSecurityInfoExW EXPORTED
1652 */
1653 DWORD WINAPI GetSecurityInfoExW(
1654 HANDLE hObject,
1655 SE_OBJECT_TYPE ObjectType,
1656 SECURITY_INFORMATION SecurityInfo,
1657 LPCWSTR lpProvider,
1658 LPCWSTR lpProperty,
1659 PACTRL_ACCESSW *ppAccessList,
1660 PACTRL_AUDITW *ppAuditList,
1661 LPWSTR *lppOwner,
1662 LPWSTR *lppGroup
1663 )
1664 {
1665 DPRINT1("GetSecurityInfoExW stub!\n");
1666 return ERROR_BAD_PROVIDER;
1667 }
1668
1669
1670 /**********************************************************************
1671 * ImpersonateNamedPipeClient EXPORTED
1672 *
1673 * @implemented
1674 */
1675 BOOL STDCALL
1676 ImpersonateNamedPipeClient(HANDLE hNamedPipe)
1677 {
1678 IO_STATUS_BLOCK StatusBlock;
1679 NTSTATUS Status;
1680
1681 DPRINT("ImpersonateNamedPipeClient() called\n");
1682
1683 Status = NtFsControlFile(hNamedPipe,
1684 NULL,
1685 NULL,
1686 NULL,
1687 &StatusBlock,
1688 FSCTL_PIPE_IMPERSONATE,
1689 NULL,
1690 0,
1691 NULL,
1692 0);
1693 if (!NT_SUCCESS(Status))
1694 {
1695 SetLastError(RtlNtStatusToDosError(Status));
1696 return FALSE;
1697 }
1698
1699 return TRUE;
1700 }
1701
1702
1703 /*
1704 * @implemented
1705 */
1706 BOOL STDCALL
1707 CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor,
1708 PSECURITY_DESCRIPTOR CreatorDescriptor,
1709 PSECURITY_DESCRIPTOR *NewDescriptor,
1710 BOOL IsDirectoryObject,
1711 HANDLE Token,
1712 PGENERIC_MAPPING GenericMapping)
1713 {
1714 NTSTATUS Status;
1715
1716 Status = RtlNewSecurityObject(ParentDescriptor,
1717 CreatorDescriptor,
1718 NewDescriptor,
1719 IsDirectoryObject,
1720 Token,
1721 GenericMapping);
1722 if (!NT_SUCCESS(Status))
1723 {
1724 SetLastError(RtlNtStatusToDosError(Status));
1725 return FALSE;
1726 }
1727
1728 return TRUE;
1729 }
1730
1731
1732 /*
1733 * @unimplemented
1734 */
1735 BOOL STDCALL
1736 CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor,
1737 PSECURITY_DESCRIPTOR CreatorDescriptor,
1738 PSECURITY_DESCRIPTOR* NewDescriptor,
1739 GUID* ObjectType,
1740 BOOL IsContainerObject,
1741 ULONG AutoInheritFlags,
1742 HANDLE Token,
1743 PGENERIC_MAPPING GenericMapping)
1744 {
1745 DPRINT1("%s() not implemented!\n", __FUNCTION__);
1746 return FALSE;
1747 }
1748
1749
1750 /*
1751 * @unimplemented
1752 */
1753 BOOL STDCALL
1754 CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor,
1755 PSECURITY_DESCRIPTOR CreatorDescriptor,
1756 PSECURITY_DESCRIPTOR* NewDescriptor,
1757 GUID** ObjectTypes,
1758 ULONG GuidCount,
1759 BOOL IsContainerObject,
1760 ULONG AutoInheritFlags,
1761 HANDLE Token,
1762 PGENERIC_MAPPING GenericMapping)
1763 {
1764 DPRINT1("%s() not implemented!\n", __FUNCTION__);
1765 return FALSE;
1766 }
1767
1768
1769 /*
1770 * @implemented
1771 */
1772 BOOL STDCALL
1773 DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR *ObjectDescriptor)
1774 {
1775 NTSTATUS Status;
1776
1777 Status = RtlDeleteSecurityObject(ObjectDescriptor);
1778 if (!NT_SUCCESS(Status))
1779 {
1780 SetLastError(RtlNtStatusToDosError(Status));
1781 return FALSE;
1782 }
1783
1784 return TRUE;
1785 }
1786
1787
1788 /*
1789 * @implemented
1790 */
1791 BOOL STDCALL
1792 GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR ObjectDescriptor,
1793 SECURITY_INFORMATION SecurityInformation,
1794 PSECURITY_DESCRIPTOR ResultantDescriptor,
1795 DWORD DescriptorLength,
1796 PDWORD ReturnLength)
1797 {
1798 NTSTATUS Status;
1799
1800 Status = RtlQuerySecurityObject(ObjectDescriptor,
1801 SecurityInformation,
1802 ResultantDescriptor,
1803 DescriptorLength,
1804 ReturnLength);
1805 if (!NT_SUCCESS(Status))
1806 {
1807 SetLastError(RtlNtStatusToDosError(Status));
1808 return FALSE;
1809 }
1810
1811 return TRUE;
1812 }
1813
1814
1815 /*
1816 * @implemented
1817 */
1818 BOOL STDCALL
1819 SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation,
1820 PSECURITY_DESCRIPTOR ModificationDescriptor,
1821 PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
1822 PGENERIC_MAPPING GenericMapping,
1823 HANDLE Token)
1824 {
1825 NTSTATUS Status;
1826
1827 Status = RtlSetSecurityObject(SecurityInformation,
1828 ModificationDescriptor,
1829 ObjectsSecurityDescriptor,
1830 GenericMapping,
1831 Token);
1832 if (!NT_SUCCESS(Status))
1833 {
1834 SetLastError(RtlNtStatusToDosError(Status));
1835 return FALSE;
1836 }
1837
1838 return TRUE;
1839 }
1840
1841
1842 /*
1843 * @implemented
1844 */
1845 DWORD STDCALL
1846 TreeResetNamedSecurityInfoW(LPWSTR pObjectName,
1847 SE_OBJECT_TYPE ObjectType,
1848 SECURITY_INFORMATION SecurityInfo,
1849 PSID pOwner,
1850 PSID pGroup,
1851 PACL pDacl,
1852 PACL pSacl,
1853 BOOL KeepExplicit,
1854 FN_PROGRESSW fnProgress,
1855 PROG_INVOKE_SETTING ProgressInvokeSetting,
1856 PVOID Args)
1857 {
1858 DWORD ErrorCode;
1859
1860 if (pObjectName != NULL)
1861 {
1862 ErrorCode = CheckNtMartaPresent();
1863 if (ErrorCode == ERROR_SUCCESS)
1864 {
1865 switch (ObjectType)
1866 {
1867 case SE_FILE_OBJECT:
1868 case SE_REGISTRY_KEY:
1869 {
1870 /* check the SecurityInfo flags for sanity (both, the protected
1871 and unprotected dacl/sacl flag must not be passed together) */
1872 if (((SecurityInfo & DACL_SECURITY_INFORMATION) &&
1873 (SecurityInfo & (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION)) ==
1874 (PROTECTED_DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION))
1875
1876 ||
1877
1878 ((SecurityInfo & SACL_SECURITY_INFORMATION) &&
1879 (SecurityInfo & (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)) ==
1880 (PROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_SACL_SECURITY_INFORMATION)))
1881 {
1882 ErrorCode = ERROR_INVALID_PARAMETER;
1883 break;
1884 }
1885
1886 /* call the MARTA provider */
1887 ErrorCode = AccTreeResetNamedSecurityInfo(pObjectName,
1888 ObjectType,
1889 SecurityInfo,
1890 pOwner,
1891 pGroup,
1892 pDacl,
1893 pSacl,
1894 KeepExplicit,
1895 fnProgress,
1896 ProgressInvokeSetting,
1897 Args);
1898 break;
1899 }
1900
1901 default:
1902 /* object type not supported */
1903 ErrorCode = ERROR_INVALID_PARAMETER;
1904 break;
1905 }
1906 }
1907 }
1908 else
1909 ErrorCode = ERROR_INVALID_PARAMETER;
1910
1911 return ErrorCode;
1912 }
1913
1914
1915 /*
1916 * @unimplemented
1917 */
1918 DWORD STDCALL
1919 TreeResetNamedSecurityInfoA(LPSTR pObjectName,
1920 SE_OBJECT_TYPE ObjectType,
1921 SECURITY_INFORMATION SecurityInfo,
1922 PSID pOwner,
1923 PSID pGroup,
1924 PACL pDacl,
1925 PACL pSacl,
1926 BOOL KeepExplicit,
1927 FN_PROGRESSA fnProgress,
1928 PROG_INVOKE_SETTING ProgressInvokeSetting,
1929 PVOID Args)
1930 {
1931 /* That's all this function does, at least up to w2k3... Even MS was too
1932 lazy to implement it... */
1933 return ERROR_CALL_NOT_IMPLEMENTED;
1934 }
1935
1936 /* EOF */