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