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