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