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