merge ROS Shell without integrated explorer part into trunk
[reactos.git] / reactos / lib / advapi32 / sec / misc.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/advapi32/sec/misc.c
6 * PURPOSE: Miscellaneous security functions
7 */
8
9 #include "advapi32.h"
10 #include <accctrl.h>
11 #include <malloc.h>
12 #include <ntsecapi.h>
13
14 #define NDEBUG
15 #include <debug.h>
16
17
18 /*
19 * @implemented
20 */
21 BOOL STDCALL
22 AreAllAccessesGranted(DWORD GrantedAccess,
23 DWORD DesiredAccess)
24 {
25 return((BOOL)RtlAreAllAccessesGranted(GrantedAccess,
26 DesiredAccess));
27 }
28
29
30 /*
31 * @implemented
32 */
33 BOOL STDCALL
34 AreAnyAccessesGranted(DWORD GrantedAccess,
35 DWORD DesiredAccess)
36 {
37 return((BOOL)RtlAreAnyAccessesGranted(GrantedAccess,
38 DesiredAccess));
39 }
40
41
42 /******************************************************************************
43 * GetFileSecurityA [ADVAPI32.@]
44 *
45 * Obtains Specified information about the security of a file or directory.
46 *
47 * PARAMS
48 * lpFileName [I] Name of the file to get info for
49 * RequestedInformation [I] SE_ flags from "winnt.h"
50 * pSecurityDescriptor [O] Destination for security information
51 * nLength [I] Length of pSecurityDescriptor
52 * lpnLengthNeeded [O] Destination for length of returned security information
53 *
54 * RETURNS
55 * Success: TRUE. pSecurityDescriptor contains the requested information.
56 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
57 *
58 * NOTES
59 * The information returned is constrained by the callers access rights and
60 * privileges.
61 *
62 * @implemented
63 */
64 BOOL WINAPI
65 GetFileSecurityA(LPCSTR lpFileName,
66 SECURITY_INFORMATION RequestedInformation,
67 PSECURITY_DESCRIPTOR pSecurityDescriptor,
68 DWORD nLength,
69 LPDWORD lpnLengthNeeded)
70 {
71 UNICODE_STRING FileName;
72 NTSTATUS Status;
73 BOOL bResult;
74
75 Status = RtlCreateUnicodeStringFromAsciiz(&FileName,
76 (LPSTR)lpFileName);
77 if (!NT_SUCCESS(Status))
78 {
79 SetLastError(RtlNtStatusToDosError(Status));
80 return FALSE;
81 }
82
83 bResult = GetFileSecurityW(FileName.Buffer,
84 RequestedInformation,
85 pSecurityDescriptor,
86 nLength,
87 lpnLengthNeeded);
88
89 RtlFreeUnicodeString(&FileName);
90
91 return bResult;
92 }
93
94
95 /*
96 * @implemented
97 */
98 BOOL WINAPI
99 GetFileSecurityW(LPCWSTR lpFileName,
100 SECURITY_INFORMATION RequestedInformation,
101 PSECURITY_DESCRIPTOR pSecurityDescriptor,
102 DWORD nLength,
103 LPDWORD lpnLengthNeeded)
104 {
105 OBJECT_ATTRIBUTES ObjectAttributes;
106 IO_STATUS_BLOCK StatusBlock;
107 UNICODE_STRING FileName;
108 ULONG AccessMask = 0;
109 HANDLE FileHandle;
110 NTSTATUS Status;
111
112 DPRINT("GetFileSecurityW() called\n");
113
114 if (RequestedInformation &
115 (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION))
116 {
117 AccessMask |= STANDARD_RIGHTS_READ;
118 }
119
120 if (RequestedInformation & SACL_SECURITY_INFORMATION)
121 {
122 AccessMask |= ACCESS_SYSTEM_SECURITY;
123 }
124
125 if (!RtlDosPathNameToNtPathName_U((LPWSTR)lpFileName,
126 &FileName,
127 NULL,
128 NULL))
129 {
130 DPRINT("Invalid path\n");
131 SetLastError(ERROR_INVALID_NAME);
132 return FALSE;
133 }
134
135 InitializeObjectAttributes(&ObjectAttributes,
136 &FileName,
137 OBJ_CASE_INSENSITIVE,
138 NULL,
139 NULL);
140
141 Status = NtOpenFile(&FileHandle,
142 AccessMask,
143 &ObjectAttributes,
144 &StatusBlock,
145 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
146 0);
147 if (!NT_SUCCESS(Status))
148 {
149 DPRINT("NtOpenFile() failed (Status %lx)\n", Status);
150 SetLastError(RtlNtStatusToDosError(Status));
151 return FALSE;
152 }
153
154 RtlFreeUnicodeString(&FileName);
155
156 Status = NtQuerySecurityObject(FileHandle,
157 RequestedInformation,
158 pSecurityDescriptor,
159 nLength,
160 lpnLengthNeeded);
161 NtClose(FileHandle);
162
163 if (!NT_SUCCESS(Status))
164 {
165 DPRINT("NtQuerySecurityObject() failed (Status %lx)\n", Status);
166 SetLastError(RtlNtStatusToDosError(Status));
167 return FALSE;
168 }
169
170 return TRUE;
171 }
172
173
174 /*
175 * @implemented
176 */
177 BOOL STDCALL
178 GetKernelObjectSecurity(HANDLE Handle,
179 SECURITY_INFORMATION RequestedInformation,
180 PSECURITY_DESCRIPTOR pSecurityDescriptor,
181 DWORD nLength,
182 LPDWORD lpnLengthNeeded)
183 {
184 NTSTATUS Status;
185
186 Status = NtQuerySecurityObject(Handle,
187 RequestedInformation,
188 pSecurityDescriptor,
189 nLength,
190 lpnLengthNeeded);
191 if (!NT_SUCCESS(Status))
192 {
193 SetLastError(RtlNtStatusToDosError(Status));
194 return(FALSE);
195 }
196 return(TRUE);
197 }
198
199
200 /******************************************************************************
201 * SetFileSecurityA [ADVAPI32.@]
202 * Sets the security of a file or directory
203 *
204 * @implemented
205 */
206 BOOL STDCALL
207 SetFileSecurityA (LPCSTR lpFileName,
208 SECURITY_INFORMATION SecurityInformation,
209 PSECURITY_DESCRIPTOR pSecurityDescriptor)
210 {
211 UNICODE_STRING FileName;
212 NTSTATUS Status;
213 BOOL bResult;
214
215 Status = RtlCreateUnicodeStringFromAsciiz(&FileName,
216 (LPSTR)lpFileName);
217 if (!NT_SUCCESS(Status))
218 {
219 SetLastError(RtlNtStatusToDosError(Status));
220 return FALSE;
221 }
222
223 bResult = SetFileSecurityW(FileName.Buffer,
224 SecurityInformation,
225 pSecurityDescriptor);
226
227 RtlFreeUnicodeString(&FileName);
228
229 return bResult;
230 }
231
232
233 /******************************************************************************
234 * SetFileSecurityW [ADVAPI32.@]
235 * Sets the security of a file or directory
236 *
237 * @implemented
238 */
239 BOOL STDCALL
240 SetFileSecurityW (LPCWSTR lpFileName,
241 SECURITY_INFORMATION SecurityInformation,
242 PSECURITY_DESCRIPTOR pSecurityDescriptor)
243 {
244 OBJECT_ATTRIBUTES ObjectAttributes;
245 IO_STATUS_BLOCK StatusBlock;
246 UNICODE_STRING FileName;
247 ULONG AccessMask = 0;
248 HANDLE FileHandle;
249 NTSTATUS Status;
250
251 DPRINT("SetFileSecurityW() called\n");
252
253 if (SecurityInformation &
254 (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION))
255 {
256 AccessMask |= WRITE_OWNER;
257 }
258
259 if (SecurityInformation & DACL_SECURITY_INFORMATION)
260 {
261 AccessMask |= WRITE_DAC;
262 }
263
264 if (SecurityInformation & SACL_SECURITY_INFORMATION)
265 {
266 AccessMask |= ACCESS_SYSTEM_SECURITY;
267 }
268
269 if (!RtlDosPathNameToNtPathName_U((LPWSTR)lpFileName,
270 &FileName,
271 NULL,
272 NULL))
273 {
274 DPRINT("Invalid path\n");
275 SetLastError(ERROR_INVALID_NAME);
276 return FALSE;
277 }
278
279 InitializeObjectAttributes(&ObjectAttributes,
280 &FileName,
281 OBJ_CASE_INSENSITIVE,
282 NULL,
283 NULL);
284
285 Status = NtOpenFile(&FileHandle,
286 AccessMask,
287 &ObjectAttributes,
288 &StatusBlock,
289 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
290 0);
291 if (!NT_SUCCESS(Status))
292 {
293 DPRINT("NtOpenFile() failed (Status %lx)\n", Status);
294 SetLastError(RtlNtStatusToDosError(Status));
295 return FALSE;
296 }
297
298 RtlFreeUnicodeString(&FileName);
299
300 Status = NtSetSecurityObject(FileHandle,
301 SecurityInformation,
302 pSecurityDescriptor);
303 NtClose(FileHandle);
304
305 if (!NT_SUCCESS(Status))
306 {
307 DPRINT("NtSetSecurityObject() failed (Status %lx)\n", Status);
308 SetLastError(RtlNtStatusToDosError(Status));
309 return FALSE;
310 }
311
312 return TRUE;
313 }
314
315
316 /*
317 * @implemented
318 */
319 BOOL STDCALL
320 SetKernelObjectSecurity(HANDLE Handle,
321 SECURITY_INFORMATION SecurityInformation,
322 PSECURITY_DESCRIPTOR SecurityDescriptor)
323 {
324 NTSTATUS Status;
325
326 Status = NtSetSecurityObject(Handle,
327 SecurityInformation,
328 SecurityDescriptor);
329 if (!NT_SUCCESS(Status))
330 {
331 SetLastError(RtlNtStatusToDosError(Status));
332 return FALSE;
333 }
334 return TRUE;
335 }
336
337
338 /*
339 * @implemented
340 */
341 BOOL STDCALL
342 ImpersonateLoggedOnUser(HANDLE hToken)
343 {
344 SECURITY_QUALITY_OF_SERVICE Qos;
345 OBJECT_ATTRIBUTES ObjectAttributes;
346 HANDLE NewToken;
347 TOKEN_TYPE Type;
348 ULONG ReturnLength;
349 BOOL Duplicated;
350 NTSTATUS Status;
351
352 /* Get the token type */
353 Status = NtQueryInformationToken (hToken,
354 TokenType,
355 &Type,
356 sizeof(TOKEN_TYPE),
357 &ReturnLength);
358 if (!NT_SUCCESS(Status))
359 {
360 SetLastError (RtlNtStatusToDosError (Status));
361 return FALSE;
362 }
363
364 if (Type == TokenPrimary)
365 {
366 /* Create a duplicate impersonation token */
367 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
368 Qos.ImpersonationLevel = SecurityImpersonation;
369 Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
370 Qos.EffectiveOnly = FALSE;
371
372 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
373 ObjectAttributes.RootDirectory = NULL;
374 ObjectAttributes.ObjectName = NULL;
375 ObjectAttributes.Attributes = 0;
376 ObjectAttributes.SecurityDescriptor = NULL;
377 ObjectAttributes.SecurityQualityOfService = &Qos;
378
379 Status = NtDuplicateToken (hToken,
380 TOKEN_IMPERSONATE | TOKEN_QUERY,
381 &ObjectAttributes,
382 FALSE,
383 TokenImpersonation,
384 &NewToken);
385 if (!NT_SUCCESS(Status))
386 {
387 SetLastError (RtlNtStatusToDosError (Status));
388 return FALSE;
389 }
390
391 Duplicated = TRUE;
392 }
393 else
394 {
395 /* User the original impersonation token */
396 NewToken = hToken;
397 Duplicated = FALSE;
398 }
399
400 /* Impersonate the the current thread */
401 Status = NtSetInformationThread (NtCurrentThread (),
402 ThreadImpersonationToken,
403 &NewToken,
404 sizeof(HANDLE));
405
406 if (Duplicated == TRUE)
407 {
408 NtClose (NewToken);
409 }
410
411 if (!NT_SUCCESS(Status))
412 {
413 SetLastError (RtlNtStatusToDosError (Status));
414 return FALSE;
415 }
416
417 return TRUE;
418 }
419
420
421 /*
422 * @implemented
423 */
424 BOOL STDCALL
425 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
426 {
427 NTSTATUS Status;
428
429 Status = RtlImpersonateSelf(ImpersonationLevel);
430 if (!NT_SUCCESS(Status))
431 {
432 SetLastError(RtlNtStatusToDosError(Status));
433 return FALSE;
434 }
435 return TRUE;
436 }
437
438
439 /*
440 * @implemented
441 */
442 BOOL STDCALL
443 RevertToSelf(VOID)
444 {
445 NTSTATUS Status;
446 HANDLE Token = NULL;
447
448 Status = NtSetInformationThread(NtCurrentThread(),
449 ThreadImpersonationToken,
450 &Token,
451 sizeof(HANDLE));
452 if (!NT_SUCCESS(Status))
453 {
454 SetLastError(RtlNtStatusToDosError(Status));
455 return FALSE;
456 }
457 return TRUE;
458 }
459
460
461 /******************************************************************************
462 * GetUserNameA [ADVAPI32.@]
463 *
464 * Get the current user name.
465 *
466 * PARAMS
467 * lpszName [O] Destination for the user name.
468 * lpSize [I/O] Size of lpszName.
469 *
470 *
471 * @implemented
472 */
473 BOOL WINAPI
474 GetUserNameA( LPSTR lpszName, LPDWORD lpSize )
475 {
476 UNICODE_STRING NameW;
477 ANSI_STRING NameA;
478 BOOL Ret;
479
480 /* apparently Win doesn't check whether lpSize is valid at all! */
481
482 NameW.Length = 0;
483 NameW.MaximumLength = (*lpSize) * sizeof(WCHAR);
484 NameW.Buffer = LocalAlloc(LMEM_FIXED, NameW.MaximumLength);
485 if(NameW.Buffer == NULL)
486 {
487 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
488 return FALSE;
489 }
490
491 NameA.Length = 0;
492 NameA.MaximumLength = ((*lpSize) < 0xFFFF ? (USHORT)(*lpSize) : 0xFFFF);
493 NameA.Buffer = lpszName;
494
495 Ret = GetUserNameW(NameW.Buffer,
496 lpSize);
497 if(Ret)
498 {
499 RtlUnicodeStringToAnsiString(&NameA, &NameW, FALSE);
500 NameA.Buffer[NameA.Length] = '\0';
501
502 *lpSize = NameA.Length + 1;
503 }
504
505 LocalFree(NameW.Buffer);
506
507 return Ret;
508 }
509
510 /******************************************************************************
511 * GetUserNameW [ADVAPI32.@]
512 *
513 * See GetUserNameA.
514 *
515 * @implemented
516 */
517 BOOL WINAPI
518 GetUserNameW ( LPWSTR lpszName, LPDWORD lpSize )
519 {
520 HANDLE hToken = INVALID_HANDLE_VALUE;
521 DWORD tu_len = 0;
522 char* tu_buf = NULL;
523 TOKEN_USER* token_user = NULL;
524 DWORD an_len = 0;
525 SID_NAME_USE snu = SidTypeUser;
526 WCHAR* domain_name = NULL;
527 DWORD dn_len = 0;
528
529 if ( !OpenThreadToken ( GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken ) )
530 {
531 DWORD dwLastError = GetLastError();
532 if ( dwLastError != ERROR_NO_TOKEN
533 && dwLastError != ERROR_NO_IMPERSONATION_TOKEN )
534 {
535 /* don't call SetLastError(),
536 as OpenThreadToken() ought to have set one */
537 return FALSE;
538 }
539 if ( !OpenProcessToken ( GetCurrentProcess(), TOKEN_QUERY, &hToken ) )
540 {
541 /* don't call SetLastError(),
542 as OpenProcessToken() ought to have set one */
543 return FALSE;
544 }
545 }
546 tu_buf = LocalAlloc ( LMEM_FIXED, 36 );
547 if ( !tu_buf )
548 {
549 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
550 return FALSE;
551 }
552 if ( !GetTokenInformation ( hToken, TokenUser, tu_buf, 36, &tu_len ) || tu_len > 36 )
553 {
554 LocalFree ( tu_buf );
555 tu_buf = LocalAlloc ( LMEM_FIXED, tu_len );
556 if ( !tu_buf )
557 {
558 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
559 return FALSE;
560 }
561 if ( !GetTokenInformation ( hToken, TokenUser, tu_buf, tu_len, &tu_len ) )
562 {
563 /* don't call SetLastError(),
564 as GetTokenInformation() ought to have set one */
565 LocalFree ( tu_buf );
566 CloseHandle ( hToken );
567 return FALSE;
568 }
569 }
570 token_user = (TOKEN_USER*)tu_buf;
571
572 an_len = *lpSize;
573 dn_len = 32;
574 domain_name = LocalAlloc ( LMEM_FIXED, dn_len * sizeof(WCHAR) );
575 if ( !domain_name )
576 {
577 LocalFree ( tu_buf );
578 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
579 return FALSE;
580 }
581 if ( !LookupAccountSidW ( NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu )
582 || dn_len > 32 )
583 {
584 if ( dn_len > 32 )
585 {
586 LocalFree ( domain_name );
587 domain_name = LocalAlloc ( LMEM_FIXED, dn_len * sizeof(WCHAR) );
588 if ( !domain_name )
589 {
590 LocalFree ( tu_buf );
591 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
592 return FALSE;
593 }
594 }
595 if ( !LookupAccountSidW ( NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu ) )
596 {
597 /* don't call SetLastError(),
598 as LookupAccountSid() ought to have set one */
599 LocalFree ( domain_name );
600 CloseHandle ( hToken );
601 return FALSE;
602 }
603 }
604
605 LocalFree ( domain_name );
606 LocalFree ( tu_buf );
607 CloseHandle ( hToken );
608
609 if ( an_len > *lpSize )
610 {
611 *lpSize = an_len;
612 SetLastError(ERROR_INSUFFICIENT_BUFFER);
613 return FALSE;
614 }
615
616 return TRUE;
617 }
618
619
620 /******************************************************************************
621 * LookupAccountSidA [ADVAPI32.@]
622 *
623 * @implemented
624 */
625 BOOL STDCALL
626 LookupAccountSidA (LPCSTR lpSystemName,
627 PSID lpSid,
628 LPSTR lpName,
629 LPDWORD cchName,
630 LPSTR lpReferencedDomainName,
631 LPDWORD cchReferencedDomainName,
632 PSID_NAME_USE peUse)
633 {
634 UNICODE_STRING NameW, ReferencedDomainNameW, SystemNameW;
635 DWORD szName, szReferencedDomainName;
636 BOOL Ret;
637
638 /*
639 * save the buffer sizes the caller passed to us, as they may get modified and
640 * we require the original values when converting back to ansi
641 */
642 szName = *cchName;
643 szReferencedDomainName = *cchReferencedDomainName;
644
645 /*
646 * allocate buffers for the unicode strings to receive
647 */
648
649 if(szName > 0)
650 {
651 NameW.Length = 0;
652 NameW.MaximumLength = szName * sizeof(WCHAR);
653 NameW.Buffer = (PWSTR)LocalAlloc(LMEM_FIXED, NameW.MaximumLength);
654 if(NameW.Buffer == NULL)
655 {
656 SetLastError(ERROR_OUTOFMEMORY);
657 return FALSE;
658 }
659 }
660 else
661 NameW.Buffer = NULL;
662
663 if(szReferencedDomainName > 0)
664 {
665 ReferencedDomainNameW.Length = 0;
666 ReferencedDomainNameW.MaximumLength = szReferencedDomainName * sizeof(WCHAR);
667 ReferencedDomainNameW.Buffer = (PWSTR)LocalAlloc(LMEM_FIXED, ReferencedDomainNameW.MaximumLength);
668 if(ReferencedDomainNameW.Buffer == NULL)
669 {
670 if(szName > 0)
671 {
672 LocalFree(NameW.Buffer);
673 }
674 SetLastError(ERROR_OUTOFMEMORY);
675 return FALSE;
676 }
677 }
678 else
679 ReferencedDomainNameW.Buffer = NULL;
680
681 /*
682 * convert the system name to unicode - if present
683 */
684
685 if(lpSystemName != NULL)
686 {
687 ANSI_STRING SystemNameA;
688
689 RtlInitAnsiString(&SystemNameA, lpSystemName);
690 RtlAnsiStringToUnicodeString(&SystemNameW, &SystemNameA, TRUE);
691 }
692 else
693 SystemNameW.Buffer = NULL;
694
695 /*
696 * it's time to call the unicode version
697 */
698
699 Ret = LookupAccountSidW(SystemNameW.Buffer,
700 lpSid,
701 NameW.Buffer,
702 cchName,
703 ReferencedDomainNameW.Buffer,
704 cchReferencedDomainName,
705 peUse);
706 if(Ret)
707 {
708 /*
709 * convert unicode strings back to ansi, don't forget that we can't convert
710 * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly
711 * terminate the converted string, the Rtl functions don't do that!
712 */
713 if(lpName != NULL)
714 {
715 ANSI_STRING NameA;
716
717 NameA.Length = 0;
718 NameA.MaximumLength = ((szName <= 0xFFFF) ? (USHORT)szName : 0xFFFF);
719 NameA.Buffer = lpName;
720
721 RtlUnicodeStringToAnsiString(&NameA, &NameW, FALSE);
722 NameA.Buffer[NameA.Length] = '\0';
723 }
724
725 if(lpReferencedDomainName != NULL)
726 {
727 ANSI_STRING ReferencedDomainNameA;
728
729 ReferencedDomainNameA.Length = 0;
730 ReferencedDomainNameA.MaximumLength = ((szReferencedDomainName <= 0xFFFF) ?
731 (USHORT)szReferencedDomainName : 0xFFFF);
732 ReferencedDomainNameA.Buffer = lpReferencedDomainName;
733
734 RtlUnicodeStringToAnsiString(&ReferencedDomainNameA, &ReferencedDomainNameW, FALSE);
735 ReferencedDomainNameA.Buffer[ReferencedDomainNameA.Length] = '\0';
736 }
737 }
738
739 /*
740 * free previously allocated buffers
741 */
742
743 if(SystemNameW.Buffer != NULL)
744 {
745 RtlFreeUnicodeString(&SystemNameW);
746 }
747 if(NameW.Buffer != NULL)
748 {
749 LocalFree(NameW.Buffer);
750 }
751 if(ReferencedDomainNameW.Buffer != NULL)
752 {
753 LocalFree(ReferencedDomainNameW.Buffer);
754 }
755
756 return Ret;
757 }
758
759
760 /******************************************************************************
761 * LookupAccountSidW [ADVAPI32.@]
762 *
763 * @implemented
764 */
765 BOOL WINAPI
766 LookupAccountSidW (
767 LPCWSTR pSystemName,
768 PSID pSid,
769 LPWSTR pAccountName,
770 LPDWORD pdwAccountName,
771 LPWSTR pDomainName,
772 LPDWORD pdwDomainName,
773 PSID_NAME_USE peUse )
774 {
775 LSA_UNICODE_STRING SystemName;
776 LSA_OBJECT_ATTRIBUTES ObjectAttributes;
777 LSA_HANDLE PolicyHandle = INVALID_HANDLE_VALUE;
778 NTSTATUS Status;
779 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain = NULL;
780 PLSA_TRANSLATED_NAME TranslatedName = NULL;
781 BOOL ret;
782
783 RtlInitUnicodeString ( &SystemName, pSystemName );
784 ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
785 Status = LsaOpenPolicy ( &SystemName, &ObjectAttributes, POLICY_LOOKUP_NAMES, &PolicyHandle );
786 if ( !NT_SUCCESS(Status) )
787 {
788 SetLastError ( LsaNtStatusToWinError(Status) );
789 return FALSE;
790 }
791 Status = LsaLookupSids ( PolicyHandle, 1, &pSid, &ReferencedDomain, &TranslatedName );
792
793 LsaClose ( PolicyHandle );
794
795 if ( !NT_SUCCESS(Status) || Status == STATUS_SOME_NOT_MAPPED )
796 {
797 SetLastError ( LsaNtStatusToWinError(Status) );
798 ret = FALSE;
799 }
800 else
801 {
802 ret = TRUE;
803 if ( TranslatedName )
804 {
805 DWORD dwSrcLen = TranslatedName->Name.Length / sizeof(WCHAR);
806 if ( *pdwAccountName <= dwSrcLen )
807 {
808 *pdwAccountName = dwSrcLen + 1;
809 ret = FALSE;
810 }
811 else
812 {
813 *pdwAccountName = dwSrcLen;
814 wcscpy ( pAccountName, TranslatedName->Name.Buffer );
815 }
816 if ( peUse )
817 *peUse = TranslatedName->Use;
818 }
819
820 if ( ReferencedDomain )
821 {
822 if ( ReferencedDomain->Entries > 0 )
823 {
824 DWORD dwSrcLen = ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR);
825 if ( *pdwDomainName <= dwSrcLen )
826 {
827 *pdwDomainName = dwSrcLen + 1;
828 ret = FALSE;
829 }
830 else
831 {
832 *pdwDomainName = dwSrcLen;
833 wcscpy ( pDomainName, ReferencedDomain->Domains[0].Name.Buffer );
834 }
835 }
836 }
837
838 if ( !ret )
839 SetLastError(ERROR_INSUFFICIENT_BUFFER);
840 }
841
842 if ( ReferencedDomain )
843 LsaFreeMemory ( ReferencedDomain );
844 if ( TranslatedName )
845 LsaFreeMemory ( TranslatedName );
846
847 return ret;
848 }
849
850
851
852 /******************************************************************************
853 * LookupAccountNameA [ADVAPI32.@]
854 *
855 * @unimplemented
856 */
857 BOOL STDCALL
858 LookupAccountNameA (LPCSTR SystemName,
859 LPCSTR AccountName,
860 PSID Sid,
861 LPDWORD SidLength,
862 LPSTR ReferencedDomainName,
863 LPDWORD hReferencedDomainNameLength,
864 PSID_NAME_USE SidNameUse)
865 {
866 DPRINT1("LookupAccountNameA is unimplemented\n");
867 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
868 return FALSE;
869 }
870
871
872 /******************************************************************************
873 * LookupAccountNameW [ADVAPI32.@]
874 *
875 * @unimplemented
876 */
877 BOOL STDCALL
878 LookupAccountNameW (LPCWSTR SystemName,
879 LPCWSTR AccountName,
880 PSID Sid,
881 LPDWORD SidLength,
882 LPWSTR ReferencedDomainName,
883 LPDWORD hReferencedDomainNameLength,
884 PSID_NAME_USE SidNameUse)
885 {
886 DPRINT1("LookupAccountNameW is unimplemented\n");
887 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
888 return FALSE;
889 }
890
891
892 /**********************************************************************
893 * LookupPrivilegeValueA EXPORTED
894 *
895 * @implemented
896 */
897 BOOL STDCALL
898 LookupPrivilegeValueA (LPCSTR lpSystemName,
899 LPCSTR lpName,
900 PLUID lpLuid)
901 {
902 UNICODE_STRING SystemName;
903 UNICODE_STRING Name;
904 BOOL Result;
905
906 /* Remote system? */
907 if (lpSystemName != NULL)
908 {
909 RtlCreateUnicodeStringFromAsciiz (&SystemName,
910 (LPSTR)lpSystemName);
911 }
912
913 /* Check the privilege name is not NULL */
914 if (lpName == NULL)
915 {
916 SetLastError (ERROR_INVALID_PARAMETER);
917 return FALSE;
918 }
919
920 RtlCreateUnicodeStringFromAsciiz (&Name,
921 (LPSTR)lpName);
922
923 Result = LookupPrivilegeValueW ((lpSystemName != NULL) ? SystemName.Buffer : NULL,
924 Name.Buffer,
925 lpLuid);
926
927 RtlFreeUnicodeString (&Name);
928
929 /* Remote system? */
930 if (lpSystemName != NULL)
931 {
932 RtlFreeUnicodeString (&SystemName);
933 }
934
935 return Result;
936 }
937
938
939 /**********************************************************************
940 * LookupPrivilegeValueW EXPORTED
941 *
942 * @unimplemented
943 */
944 BOOL STDCALL
945 LookupPrivilegeValueW (LPCWSTR SystemName,
946 LPCWSTR PrivName,
947 PLUID Luid)
948 {
949 static const WCHAR * const DefaultPrivNames[] =
950 {
951 L"SeCreateTokenPrivilege",
952 L"SeAssignPrimaryTokenPrivilege",
953 L"SeLockMemoryPrivilege",
954 L"SeIncreaseQuotaPrivilege",
955 L"SeUnsolicitedInputPrivilege",
956 L"SeMachineAccountPrivilege",
957 L"SeTcbPrivilege",
958 L"SeSecurityPrivilege",
959 L"SeTakeOwnershipPrivilege",
960 L"SeLoadDriverPrivilege",
961 L"SeSystemProfilePrivilege",
962 L"SeSystemtimePrivilege",
963 L"SeProfileSingleProcessPrivilege",
964 L"SeIncreaseBasePriorityPrivilege",
965 L"SeCreatePagefilePrivilege",
966 L"SeCreatePermanentPrivilege",
967 L"SeBackupPrivilege",
968 L"SeRestorePrivilege",
969 L"SeShutdownPrivilege",
970 L"SeDebugPrivilege",
971 L"SeAuditPrivilege",
972 L"SeSystemEnvironmentPrivilege",
973 L"SeChangeNotifyPrivilege",
974 L"SeRemoteShutdownPrivilege",
975 L"SeUndockPrivilege",
976 L"SeSyncAgentPrivilege",
977 L"SeEnableDelegationPrivilege",
978 L"SeManageVolumePrivilege",
979 L"SeImpersonatePrivilege",
980 L"SeCreateGlobalPrivilege"
981 };
982 unsigned Priv;
983
984 if (NULL != SystemName && L'\0' != *SystemName)
985 {
986 DPRINT1("LookupPrivilegeValueW: not implemented for remote system\n");
987 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
988 return FALSE;
989 }
990
991 for (Priv = 0; Priv < sizeof(DefaultPrivNames) / sizeof(DefaultPrivNames[0]); Priv++)
992 {
993 if (0 == wcscmp(PrivName, DefaultPrivNames[Priv]))
994 {
995 Luid->LowPart = Priv + 1;
996 Luid->HighPart = 0;
997 return TRUE;
998 }
999 }
1000
1001 DPRINT1("LookupPrivilegeValueW: no such privilege %S\n", PrivName);
1002 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1003 return FALSE;
1004 }
1005
1006
1007 /**********************************************************************
1008 * LookupPrivilegeDisplayNameA EXPORTED
1009 *
1010 * @unimplemented
1011 */
1012 BOOL STDCALL
1013 LookupPrivilegeDisplayNameA (LPCSTR lpSystemName,
1014 LPCSTR lpName,
1015 LPSTR lpDisplayName,
1016 LPDWORD cbDisplayName,
1017 LPDWORD lpLanguageId)
1018 {
1019 DPRINT1("LookupPrivilegeDisplayNameA: stub\n");
1020 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1021 return FALSE;
1022 }
1023
1024
1025 /**********************************************************************
1026 * LookupPrivilegeDisplayNameW EXPORTED
1027 *
1028 * @unimplemented
1029 */
1030 BOOL STDCALL
1031 LookupPrivilegeDisplayNameW (LPCWSTR lpSystemName,
1032 LPCWSTR lpName,
1033 LPWSTR lpDisplayName,
1034 LPDWORD cbDisplayName,
1035 LPDWORD lpLanguageId)
1036 {
1037 DPRINT1("LookupPrivilegeDisplayNameW: stub\n");
1038 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1039 return FALSE;
1040 }
1041
1042
1043 /**********************************************************************
1044 * LookupPrivilegeNameA EXPORTED
1045 *
1046 * @unimplemented
1047 */
1048 BOOL STDCALL
1049 LookupPrivilegeNameA (LPCSTR lpSystemName,
1050 PLUID lpLuid,
1051 LPSTR lpName,
1052 LPDWORD cbName)
1053 {
1054 DPRINT1("LookupPrivilegeNameA: stub\n");
1055 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1056 return FALSE;
1057 }
1058
1059
1060 /**********************************************************************
1061 * LookupPrivilegeNameW EXPORTED
1062 *
1063 * @unimplemented
1064 */
1065 BOOL STDCALL
1066 LookupPrivilegeNameW (LPCWSTR lpSystemName,
1067 PLUID lpLuid,
1068 LPWSTR lpName,
1069 LPDWORD cbName)
1070 {
1071 DPRINT1("LookupPrivilegeNameW: stub\n");
1072 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1073 return FALSE;
1074 }
1075
1076
1077 /**********************************************************************
1078 * GetNamedSecurityInfoW EXPORTED
1079 *
1080 * @unimplemented
1081 */
1082 DWORD STDCALL
1083 GetNamedSecurityInfoW(LPWSTR pObjectName,
1084 SE_OBJECT_TYPE ObjectType,
1085 SECURITY_INFORMATION SecurityInfo,
1086 PSID *ppsidOwner,
1087 PSID *ppsidGroup,
1088 PACL *ppDacl,
1089 PACL *ppSacl,
1090 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1091 {
1092 DPRINT1("GetNamedSecurityInfoW: stub\n");
1093 return ERROR_CALL_NOT_IMPLEMENTED;
1094 }
1095
1096
1097 /**********************************************************************
1098 * GetNamedSecurityInfoA EXPORTED
1099 *
1100 * @unimplemented
1101 */
1102 DWORD STDCALL
1103 GetNamedSecurityInfoA(LPSTR pObjectName,
1104 SE_OBJECT_TYPE ObjectType,
1105 SECURITY_INFORMATION SecurityInfo,
1106 PSID *ppsidOwner,
1107 PSID *ppsidGroup,
1108 PACL *ppDacl,
1109 PACL *ppSacl,
1110 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1111 {
1112 DPRINT1("GetNamedSecurityInfoA: stub\n");
1113 return ERROR_CALL_NOT_IMPLEMENTED;
1114 }
1115
1116
1117 /**********************************************************************
1118 * SetNamedSecurityInfoW EXPORTED
1119 *
1120 * @unimplemented
1121 */
1122 DWORD STDCALL
1123 SetNamedSecurityInfoW(LPWSTR pObjectName,
1124 SE_OBJECT_TYPE ObjectType,
1125 SECURITY_INFORMATION SecurityInfo,
1126 PSID psidOwner,
1127 PSID psidGroup,
1128 PACL pDacl,
1129 PACL pSacl)
1130 {
1131 DPRINT1("SetNamedSecurityInfoW: stub\n");
1132 return ERROR_CALL_NOT_IMPLEMENTED;
1133 }
1134
1135
1136 /**********************************************************************
1137 * SetNamedSecurityInfoA EXPORTED
1138 *
1139 * @unimplemented
1140 */
1141 DWORD STDCALL
1142 SetNamedSecurityInfoA(LPSTR pObjectName,
1143 SE_OBJECT_TYPE ObjectType,
1144 SECURITY_INFORMATION SecurityInfo,
1145 PSID psidOwner,
1146 PSID psidGroup,
1147 PACL pDacl,
1148 PACL pSacl)
1149 {
1150 DPRINT1("SetNamedSecurityInfoA: stub\n");
1151 return ERROR_CALL_NOT_IMPLEMENTED;
1152 }
1153
1154
1155 /**********************************************************************
1156 * GetSecurityInfo EXPORTED
1157 *
1158 * @unimplemented
1159 */
1160 DWORD STDCALL
1161 GetSecurityInfo(HANDLE handle,
1162 SE_OBJECT_TYPE ObjectType,
1163 SECURITY_INFORMATION SecurityInfo,
1164 PSID* ppsidOwner,
1165 PSID* ppsidGroup,
1166 PACL* ppDacl,
1167 PACL* ppSacl,
1168 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
1169 {
1170 DPRINT1("GetSecurityInfo: stub\n");
1171 return ERROR_CALL_NOT_IMPLEMENTED;
1172 }
1173
1174
1175 /**********************************************************************
1176 * SetSecurityInfo EXPORTED
1177 *
1178 * @unimplemented
1179 */
1180 DWORD
1181 WINAPI
1182 SetSecurityInfo(HANDLE handle,
1183 SE_OBJECT_TYPE ObjectType,
1184 SECURITY_INFORMATION SecurityInfo,
1185 PSID psidOwner,
1186 PSID psidGroup,
1187 PACL pDacl,
1188 PACL pSacl)
1189 {
1190 DPRINT1("SetSecurityInfo: stub\n");
1191 return ERROR_CALL_NOT_IMPLEMENTED;
1192 }
1193
1194
1195 /******************************************************************************
1196 * GetSecurityInfoExW EXPORTED
1197 */
1198 DWORD WINAPI GetSecurityInfoExA(
1199 HANDLE hObject,
1200 SE_OBJECT_TYPE ObjectType,
1201 SECURITY_INFORMATION SecurityInfo,
1202 LPCSTR lpProvider,
1203 LPCSTR lpProperty,
1204 PACTRL_ACCESSA *ppAccessList,
1205 PACTRL_AUDITA *ppAuditList,
1206 LPSTR *lppOwner,
1207 LPSTR *lppGroup
1208 )
1209 {
1210 DPRINT1("GetSecurityInfoExA stub!\n");
1211 return ERROR_BAD_PROVIDER;
1212 }
1213
1214
1215 /******************************************************************************
1216 * GetSecurityInfoExW EXPORTED
1217 */
1218 DWORD WINAPI GetSecurityInfoExW(
1219 HANDLE hObject,
1220 SE_OBJECT_TYPE ObjectType,
1221 SECURITY_INFORMATION SecurityInfo,
1222 LPCWSTR lpProvider,
1223 LPCWSTR lpProperty,
1224 PACTRL_ACCESSW *ppAccessList,
1225 PACTRL_AUDITW *ppAuditList,
1226 LPWSTR *lppOwner,
1227 LPWSTR *lppGroup
1228 )
1229 {
1230 DPRINT1("GetSecurityInfoExW stub!\n");
1231 return ERROR_BAD_PROVIDER;
1232 }
1233
1234
1235 /**********************************************************************
1236 * ImpersonateNamedPipeClient EXPORTED
1237 *
1238 * @implemented
1239 */
1240 BOOL STDCALL
1241 ImpersonateNamedPipeClient(HANDLE hNamedPipe)
1242 {
1243 IO_STATUS_BLOCK StatusBlock;
1244 NTSTATUS Status;
1245
1246 DPRINT("ImpersonateNamedPipeClient() called\n");
1247
1248 Status = NtFsControlFile(hNamedPipe,
1249 NULL,
1250 NULL,
1251 NULL,
1252 &StatusBlock,
1253 FSCTL_PIPE_IMPERSONATE,
1254 NULL,
1255 0,
1256 NULL,
1257 0);
1258 if (!NT_SUCCESS(Status))
1259 {
1260 SetLastError(RtlNtStatusToDosError(Status));
1261 return FALSE;
1262 }
1263
1264 return TRUE;
1265 }
1266
1267 /* EOF */