implemented GetUserNameA()
[reactos.git] / reactos / lib / advapi32 / sec / misc.c
1 /* $Id: misc.c,v 1.34 2004/12/14 22:11:16 weiden Exp $
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 VOID STDCALL
342 MapGenericMask(PDWORD AccessMask,
343 PGENERIC_MAPPING GenericMapping)
344 {
345 RtlMapGenericMask(AccessMask,
346 GenericMapping);
347 }
348
349
350 /*
351 * @implemented
352 */
353 BOOL STDCALL
354 ImpersonateLoggedOnUser(HANDLE hToken)
355 {
356 SECURITY_QUALITY_OF_SERVICE Qos;
357 OBJECT_ATTRIBUTES ObjectAttributes;
358 HANDLE NewToken;
359 TOKEN_TYPE Type;
360 ULONG ReturnLength;
361 BOOL Duplicated;
362 NTSTATUS Status;
363
364 /* Get the token type */
365 Status = NtQueryInformationToken (hToken,
366 TokenType,
367 &Type,
368 sizeof(TOKEN_TYPE),
369 &ReturnLength);
370 if (!NT_SUCCESS(Status))
371 {
372 SetLastError (RtlNtStatusToDosError (Status));
373 return FALSE;
374 }
375
376 if (Type == TokenPrimary)
377 {
378 /* Create a duplicate impersonation token */
379 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
380 Qos.ImpersonationLevel = SecurityImpersonation;
381 Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
382 Qos.EffectiveOnly = FALSE;
383
384 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
385 ObjectAttributes.RootDirectory = NULL;
386 ObjectAttributes.ObjectName = NULL;
387 ObjectAttributes.Attributes = 0;
388 ObjectAttributes.SecurityDescriptor = NULL;
389 ObjectAttributes.SecurityQualityOfService = &Qos;
390
391 Status = NtDuplicateToken (hToken,
392 TOKEN_IMPERSONATE | TOKEN_QUERY,
393 &ObjectAttributes,
394 FALSE,
395 TokenImpersonation,
396 &NewToken);
397 if (!NT_SUCCESS(Status))
398 {
399 SetLastError (RtlNtStatusToDosError (Status));
400 return FALSE;
401 }
402
403 Duplicated = TRUE;
404 }
405 else
406 {
407 /* User the original impersonation token */
408 NewToken = hToken;
409 Duplicated = FALSE;
410 }
411
412 /* Impersonate the the current thread */
413 Status = NtSetInformationThread (NtCurrentThread (),
414 ThreadImpersonationToken,
415 &NewToken,
416 sizeof(HANDLE));
417
418 if (Duplicated == TRUE)
419 {
420 NtClose (NewToken);
421 }
422
423 if (!NT_SUCCESS(Status))
424 {
425 SetLastError (RtlNtStatusToDosError (Status));
426 return FALSE;
427 }
428
429 return TRUE;
430 }
431
432
433 /*
434 * @implemented
435 */
436 BOOL STDCALL
437 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
438 {
439 NTSTATUS Status;
440
441 Status = RtlImpersonateSelf(ImpersonationLevel);
442 if (!NT_SUCCESS(Status))
443 {
444 SetLastError(RtlNtStatusToDosError(Status));
445 return FALSE;
446 }
447 return TRUE;
448 }
449
450
451 /*
452 * @implemented
453 */
454 BOOL STDCALL
455 RevertToSelf(VOID)
456 {
457 NTSTATUS Status;
458 HANDLE Token = NULL;
459
460 Status = NtSetInformationThread(NtCurrentThread(),
461 ThreadImpersonationToken,
462 &Token,
463 sizeof(HANDLE));
464 if (!NT_SUCCESS(Status))
465 {
466 SetLastError(RtlNtStatusToDosError(Status));
467 return FALSE;
468 }
469 return TRUE;
470 }
471
472
473 /******************************************************************************
474 * GetUserNameA [ADVAPI32.@]
475 *
476 * Get the current user name.
477 *
478 * PARAMS
479 * lpszName [O] Destination for the user name.
480 * lpSize [I/O] Size of lpszName.
481 *
482 *
483 * @implemented
484 */
485 BOOL WINAPI
486 GetUserNameA( LPSTR lpszName, LPDWORD lpSize )
487 {
488 UNICODE_STRING NameW;
489 ANSI_STRING NameA;
490 BOOL Ret;
491
492 /* apparently Win doesn't check whether lpSize is valid at all! */
493
494 NameW.Length = 0;
495 NameW.MaximumLength = (*lpSize) * sizeof(WCHAR);
496 NameW.Buffer = LocalAlloc(LMEM_FIXED, NameW.MaximumLength);
497 if(NameW.Buffer == NULL)
498 {
499 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
500 return FALSE;
501 }
502
503 NameA.Length = 0;
504 NameA.MaximumLength = ((*lpSize) < 0xFFFF ? (USHORT)(*lpSize) : 0xFFFF);
505 NameA.Buffer = lpszName;
506
507 Ret = GetUserNameW(NameW.Buffer,
508 lpSize);
509 if(Ret)
510 {
511 RtlUnicodeStringToAnsiString(&NameA, &NameW, FALSE);
512 NameA.Buffer[NameA.Length] = '\0';
513
514 *lpSize = NameA.Length + 1;
515 }
516
517 LocalFree(NameW.Buffer);
518
519 return Ret;
520 }
521
522 /******************************************************************************
523 * GetUserNameW [ADVAPI32.@]
524 *
525 * See GetUserNameA.
526 *
527 * @implemented
528 */
529 BOOL WINAPI
530 GetUserNameW ( LPWSTR lpszName, LPDWORD lpSize )
531 {
532 HANDLE hToken = INVALID_HANDLE_VALUE;
533 DWORD tu_len = 0;
534 char* tu_buf = NULL;
535 TOKEN_USER* token_user = NULL;
536 DWORD an_len = 0;
537 SID_NAME_USE snu = SidTypeUser;
538 WCHAR* domain_name = NULL;
539 DWORD dn_len = 0;
540
541 if ( !OpenThreadToken ( GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken ) )
542 {
543 DWORD dwLastError = GetLastError();
544 if ( dwLastError != ERROR_NO_TOKEN
545 && dwLastError != ERROR_NO_IMPERSONATION_TOKEN )
546 {
547 /* don't call SetLastError(),
548 as OpenThreadToken() ought to have set one */
549 return FALSE;
550 }
551 if ( !OpenProcessToken ( GetCurrentProcess(), TOKEN_QUERY, &hToken ) )
552 {
553 /* don't call SetLastError(),
554 as OpenProcessToken() ought to have set one */
555 return FALSE;
556 }
557 }
558 tu_buf = LocalAlloc ( LMEM_FIXED, 36 );
559 if ( !tu_buf )
560 {
561 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
562 return FALSE;
563 }
564 if ( !GetTokenInformation ( hToken, TokenUser, tu_buf, 36, &tu_len ) || tu_len > 36 )
565 {
566 LocalFree ( tu_buf );
567 tu_buf = LocalAlloc ( LMEM_FIXED, tu_len );
568 if ( !tu_buf )
569 {
570 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
571 return FALSE;
572 }
573 if ( !GetTokenInformation ( hToken, TokenUser, tu_buf, tu_len, &tu_len ) )
574 {
575 /* don't call SetLastError(),
576 as GetTokenInformation() ought to have set one */
577 LocalFree ( tu_buf );
578 CloseHandle ( hToken );
579 return FALSE;
580 }
581 }
582 token_user = (TOKEN_USER*)tu_buf;
583
584 an_len = *lpSize;
585 dn_len = 32;
586 domain_name = LocalAlloc ( LMEM_FIXED, dn_len * sizeof(WCHAR) );
587 if ( !domain_name )
588 {
589 LocalFree ( tu_buf );
590 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
591 return FALSE;
592 }
593 if ( !LookupAccountSidW ( NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu )
594 || dn_len > 32 )
595 {
596 if ( dn_len > 32 )
597 {
598 LocalFree ( domain_name );
599 domain_name = LocalAlloc ( LMEM_FIXED, dn_len * sizeof(WCHAR) );
600 if ( !domain_name )
601 {
602 LocalFree ( tu_buf );
603 SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
604 return FALSE;
605 }
606 }
607 if ( !LookupAccountSidW ( NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu ) )
608 {
609 /* don't call SetLastError(),
610 as LookupAccountSid() ought to have set one */
611 LocalFree ( domain_name );
612 CloseHandle ( hToken );
613 return FALSE;
614 }
615 }
616
617 LocalFree ( domain_name );
618 LocalFree ( tu_buf );
619 CloseHandle ( hToken );
620
621 if ( an_len > *lpSize )
622 {
623 *lpSize = an_len;
624 SetLastError(ERROR_INSUFFICIENT_BUFFER);
625 return FALSE;
626 }
627
628 return TRUE;
629 }
630
631
632 /******************************************************************************
633 * LookupAccountSidA [ADVAPI32.@]
634 *
635 * @implemented
636 */
637 BOOL STDCALL
638 LookupAccountSidA (LPCSTR lpSystemName,
639 PSID lpSid,
640 LPSTR lpName,
641 LPDWORD cchName,
642 LPSTR lpReferencedDomainName,
643 LPDWORD cchReferencedDomainName,
644 PSID_NAME_USE peUse)
645 {
646 UNICODE_STRING NameW, ReferencedDomainNameW, SystemNameW;
647 DWORD szName, szReferencedDomainName;
648 BOOL Ret;
649
650 /*
651 * save the buffer sizes the caller passed to us, as they may get modified and
652 * we require the original values when converting back to ansi
653 */
654 szName = *cchName;
655 szReferencedDomainName = *cchReferencedDomainName;
656
657 /*
658 * allocate buffers for the unicode strings to receive
659 */
660
661 if(szName > 0)
662 {
663 NameW.Length = 0;
664 NameW.MaximumLength = szName * sizeof(WCHAR);
665 NameW.Buffer = (PWSTR)LocalAlloc(LMEM_FIXED, NameW.MaximumLength);
666 if(NameW.Buffer == NULL)
667 {
668 SetLastError(ERROR_OUTOFMEMORY);
669 return FALSE;
670 }
671 }
672 else
673 NameW.Buffer = NULL;
674
675 if(szReferencedDomainName > 0)
676 {
677 ReferencedDomainNameW.Length = 0;
678 ReferencedDomainNameW.MaximumLength = szReferencedDomainName * sizeof(WCHAR);
679 ReferencedDomainNameW.Buffer = (PWSTR)LocalAlloc(LMEM_FIXED, ReferencedDomainNameW.MaximumLength);
680 if(ReferencedDomainNameW.Buffer == NULL)
681 {
682 if(szName > 0)
683 {
684 LocalFree(NameW.Buffer);
685 }
686 SetLastError(ERROR_OUTOFMEMORY);
687 return FALSE;
688 }
689 }
690 else
691 ReferencedDomainNameW.Buffer = NULL;
692
693 /*
694 * convert the system name to unicode - if present
695 */
696
697 if(lpSystemName != NULL)
698 {
699 ANSI_STRING SystemNameA;
700
701 RtlInitAnsiString(&SystemNameA, lpSystemName);
702 RtlAnsiStringToUnicodeString(&SystemNameW, &SystemNameA, TRUE);
703 }
704 else
705 SystemNameW.Buffer = NULL;
706
707 /*
708 * it's time to call the unicode version
709 */
710
711 Ret = LookupAccountSidW(SystemNameW.Buffer,
712 lpSid,
713 NameW.Buffer,
714 cchName,
715 ReferencedDomainNameW.Buffer,
716 cchReferencedDomainName,
717 peUse);
718 if(Ret)
719 {
720 /*
721 * convert unicode strings back to ansi, don't forget that we can't convert
722 * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly
723 * terminate the converted string, the Rtl functions don't do that!
724 */
725 if(lpName != NULL)
726 {
727 ANSI_STRING NameA;
728
729 NameA.Length = 0;
730 NameA.MaximumLength = ((szName <= 0xFFFF) ? (USHORT)szName : 0xFFFF);
731 NameA.Buffer = lpName;
732
733 RtlUnicodeStringToAnsiString(&NameA, &NameW, FALSE);
734 NameA.Buffer[NameA.Length] = '\0';
735 }
736
737 if(lpReferencedDomainName != NULL)
738 {
739 ANSI_STRING ReferencedDomainNameA;
740
741 ReferencedDomainNameA.Length = 0;
742 ReferencedDomainNameA.MaximumLength = ((szReferencedDomainName <= 0xFFFF) ?
743 (USHORT)szReferencedDomainName : 0xFFFF);
744 ReferencedDomainNameA.Buffer = lpReferencedDomainName;
745
746 RtlUnicodeStringToAnsiString(&ReferencedDomainNameA, &ReferencedDomainNameW, FALSE);
747 ReferencedDomainNameA.Buffer[ReferencedDomainNameA.Length] = '\0';
748 }
749 }
750
751 /*
752 * free previously allocated buffers
753 */
754
755 if(SystemNameW.Buffer != NULL)
756 {
757 RtlFreeUnicodeString(&SystemNameW);
758 }
759 if(NameW.Buffer != NULL)
760 {
761 LocalFree(NameW.Buffer);
762 }
763 if(ReferencedDomainNameW.Buffer != NULL)
764 {
765 LocalFree(ReferencedDomainNameW.Buffer);
766 }
767
768 return Ret;
769 }
770
771
772 /******************************************************************************
773 * LookupAccountSidW [ADVAPI32.@]
774 *
775 * @implemented
776 */
777 BOOL WINAPI
778 LookupAccountSidW (
779 LPCWSTR pSystemName,
780 PSID pSid,
781 LPWSTR pAccountName,
782 LPDWORD pdwAccountName,
783 LPWSTR pDomainName,
784 LPDWORD pdwDomainName,
785 PSID_NAME_USE peUse )
786 {
787 LSA_UNICODE_STRING SystemName;
788 LSA_OBJECT_ATTRIBUTES ObjectAttributes;
789 LSA_HANDLE PolicyHandle = INVALID_HANDLE_VALUE;
790 NTSTATUS Status;
791 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain = NULL;
792 PLSA_TRANSLATED_NAME TranslatedName = NULL;
793 BOOL ret;
794
795 RtlInitUnicodeString ( &SystemName, pSystemName );
796 ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
797 Status = LsaOpenPolicy ( &SystemName, &ObjectAttributes, POLICY_LOOKUP_NAMES, &PolicyHandle );
798 if ( !NT_SUCCESS(Status) )
799 {
800 SetLastError ( LsaNtStatusToWinError(Status) );
801 return FALSE;
802 }
803 Status = LsaLookupSids ( PolicyHandle, 1, &pSid, &ReferencedDomain, &TranslatedName );
804
805 LsaClose ( PolicyHandle );
806
807 if ( !NT_SUCCESS(Status) || Status == STATUS_SOME_NOT_MAPPED )
808 {
809 SetLastError ( LsaNtStatusToWinError(Status) );
810 ret = FALSE;
811 }
812 else
813 {
814 ret = TRUE;
815 if ( TranslatedName )
816 {
817 DWORD dwSrcLen = TranslatedName->Name.Length / sizeof(WCHAR);
818 if ( *pdwAccountName <= dwSrcLen )
819 {
820 *pdwAccountName = dwSrcLen + 1;
821 ret = FALSE;
822 }
823 else
824 {
825 *pdwAccountName = dwSrcLen;
826 wcscpy ( pAccountName, TranslatedName->Name.Buffer );
827 }
828 if ( peUse )
829 *peUse = TranslatedName->Use;
830 }
831
832 if ( ReferencedDomain )
833 {
834 if ( ReferencedDomain->Entries > 0 )
835 {
836 DWORD dwSrcLen = ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR);
837 if ( *pdwDomainName <= dwSrcLen )
838 {
839 *pdwDomainName = dwSrcLen + 1;
840 ret = FALSE;
841 }
842 else
843 {
844 *pdwDomainName = dwSrcLen;
845 wcscpy ( pDomainName, ReferencedDomain->Domains[0].Name.Buffer );
846 }
847 }
848 }
849
850 if ( !ret )
851 SetLastError(ERROR_INSUFFICIENT_BUFFER);
852 }
853
854 if ( ReferencedDomain )
855 LsaFreeMemory ( ReferencedDomain );
856 if ( TranslatedName )
857 LsaFreeMemory ( TranslatedName );
858
859 return ret;
860 }
861
862
863
864 /******************************************************************************
865 * LookupAccountNameA [ADVAPI32.@]
866 *
867 * @unimplemented
868 */
869 BOOL STDCALL
870 LookupAccountNameA (LPCSTR SystemName,
871 LPCSTR AccountName,
872 PSID Sid,
873 LPDWORD SidLength,
874 LPSTR ReferencedDomainName,
875 LPDWORD hReferencedDomainNameLength,
876 PSID_NAME_USE SidNameUse)
877 {
878 DPRINT1("LookupAccountNameA is unimplemented\n");
879 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
880 return FALSE;
881 }
882
883
884 /******************************************************************************
885 * LookupAccountNameW [ADVAPI32.@]
886 *
887 * @unimplemented
888 */
889 BOOL STDCALL
890 LookupAccountNameW (LPCWSTR SystemName,
891 LPCWSTR AccountName,
892 PSID Sid,
893 LPDWORD SidLength,
894 LPWSTR ReferencedDomainName,
895 LPDWORD hReferencedDomainNameLength,
896 PSID_NAME_USE SidNameUse)
897 {
898 DPRINT1("LookupAccountNameW is unimplemented\n");
899 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
900 return FALSE;
901 }
902
903
904 /**********************************************************************
905 * LookupPrivilegeValueA EXPORTED
906 *
907 * @implemented
908 */
909 BOOL STDCALL
910 LookupPrivilegeValueA (LPCSTR lpSystemName,
911 LPCSTR lpName,
912 PLUID lpLuid)
913 {
914 UNICODE_STRING SystemName;
915 UNICODE_STRING Name;
916 BOOL Result;
917
918 /* Remote system? */
919 if (lpSystemName != NULL)
920 {
921 RtlCreateUnicodeStringFromAsciiz (&SystemName,
922 (LPSTR)lpSystemName);
923 }
924
925 /* Check the privilege name is not NULL */
926 if (lpName == NULL)
927 {
928 SetLastError (ERROR_INVALID_PARAMETER);
929 return FALSE;
930 }
931
932 RtlCreateUnicodeStringFromAsciiz (&Name,
933 (LPSTR)lpName);
934
935 Result = LookupPrivilegeValueW ((lpSystemName != NULL) ? SystemName.Buffer : NULL,
936 Name.Buffer,
937 lpLuid);
938
939 RtlFreeUnicodeString (&Name);
940
941 /* Remote system? */
942 if (lpSystemName != NULL)
943 {
944 RtlFreeUnicodeString (&SystemName);
945 }
946
947 return Result;
948 }
949
950
951 /**********************************************************************
952 * LookupPrivilegeValueW EXPORTED
953 *
954 * @unimplemented
955 */
956 BOOL STDCALL
957 LookupPrivilegeValueW (LPCWSTR SystemName,
958 LPCWSTR PrivName,
959 PLUID Luid)
960 {
961 static const WCHAR * const DefaultPrivNames[] =
962 {
963 L"SeCreateTokenPrivilege",
964 L"SeAssignPrimaryTokenPrivilege",
965 L"SeLockMemoryPrivilege",
966 L"SeIncreaseQuotaPrivilege",
967 L"SeUnsolicitedInputPrivilege",
968 L"SeMachineAccountPrivilege",
969 L"SeTcbPrivilege",
970 L"SeSecurityPrivilege",
971 L"SeTakeOwnershipPrivilege",
972 L"SeLoadDriverPrivilege",
973 L"SeSystemProfilePrivilege",
974 L"SeSystemtimePrivilege",
975 L"SeProfileSingleProcessPrivilege",
976 L"SeIncreaseBasePriorityPrivilege",
977 L"SeCreatePagefilePrivilege",
978 L"SeCreatePermanentPrivilege",
979 L"SeBackupPrivilege",
980 L"SeRestorePrivilege",
981 L"SeShutdownPrivilege",
982 L"SeDebugPrivilege",
983 L"SeAuditPrivilege",
984 L"SeSystemEnvironmentPrivilege",
985 L"SeChangeNotifyPrivilege",
986 L"SeRemoteShutdownPrivilege",
987 L"SeUndockPrivilege",
988 L"SeSyncAgentPrivilege",
989 L"SeEnableDelegationPrivilege",
990 L"SeManageVolumePrivilege",
991 L"SeImpersonatePrivilege",
992 L"SeCreateGlobalPrivilege"
993 };
994 unsigned Priv;
995
996 if (NULL != SystemName && L'\0' != *SystemName)
997 {
998 DPRINT1("LookupPrivilegeValueW: not implemented for remote system\n");
999 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1000 return FALSE;
1001 }
1002
1003 for (Priv = 0; Priv < sizeof(DefaultPrivNames) / sizeof(DefaultPrivNames[0]); Priv++)
1004 {
1005 if (0 == wcscmp(PrivName, DefaultPrivNames[Priv]))
1006 {
1007 Luid->LowPart = Priv + 1;
1008 Luid->HighPart = 0;
1009 return TRUE;
1010 }
1011 }
1012
1013 DPRINT1("LookupPrivilegeValueW: no such privilege %S\n", PrivName);
1014 SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1015 return FALSE;
1016 }
1017
1018
1019 /**********************************************************************
1020 * LookupPrivilegeDisplayNameA EXPORTED
1021 *
1022 * @unimplemented
1023 */
1024 BOOL STDCALL
1025 LookupPrivilegeDisplayNameA (LPCSTR lpSystemName,
1026 LPCSTR lpName,
1027 LPSTR lpDisplayName,
1028 LPDWORD cbDisplayName,
1029 LPDWORD lpLanguageId)
1030 {
1031 DPRINT1("LookupPrivilegeDisplayNameA: stub\n");
1032 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1033 return FALSE;
1034 }
1035
1036
1037 /**********************************************************************
1038 * LookupPrivilegeDisplayNameW EXPORTED
1039 *
1040 * @unimplemented
1041 */
1042 BOOL STDCALL
1043 LookupPrivilegeDisplayNameW (LPCWSTR lpSystemName,
1044 LPCWSTR lpName,
1045 LPWSTR lpDisplayName,
1046 LPDWORD cbDisplayName,
1047 LPDWORD lpLanguageId)
1048 {
1049 DPRINT1("LookupPrivilegeDisplayNameW: stub\n");
1050 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1051 return FALSE;
1052 }
1053
1054
1055 /**********************************************************************
1056 * LookupPrivilegeNameA EXPORTED
1057 *
1058 * @unimplemented
1059 */
1060 BOOL STDCALL
1061 LookupPrivilegeNameA (LPCSTR lpSystemName,
1062 PLUID lpLuid,
1063 LPSTR lpName,
1064 LPDWORD cbName)
1065 {
1066 DPRINT1("LookupPrivilegeNameA: stub\n");
1067 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1068 return FALSE;
1069 }
1070
1071
1072 /**********************************************************************
1073 * LookupPrivilegeNameW EXPORTED
1074 *
1075 * @unimplemented
1076 */
1077 BOOL STDCALL
1078 LookupPrivilegeNameW (LPCWSTR lpSystemName,
1079 PLUID lpLuid,
1080 LPWSTR lpName,
1081 LPDWORD cbName)
1082 {
1083 DPRINT1("LookupPrivilegeNameW: stub\n");
1084 SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
1085 return FALSE;
1086 }
1087
1088
1089 /**********************************************************************
1090 * GetNamedSecurityInfoW EXPORTED
1091 *
1092 * @unimplemented
1093 */
1094 DWORD STDCALL
1095 GetNamedSecurityInfoW(LPWSTR pObjectName,
1096 SE_OBJECT_TYPE ObjectType,
1097 SECURITY_INFORMATION SecurityInfo,
1098 PSID *ppsidOwner,
1099 PSID *ppsidGroup,
1100 PACL *ppDacl,
1101 PACL *ppSacl,
1102 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1103 {
1104 DPRINT1("GetNamedSecurityInfoW: stub\n");
1105 return ERROR_CALL_NOT_IMPLEMENTED;
1106 }
1107
1108
1109 /**********************************************************************
1110 * GetNamedSecurityInfoA EXPORTED
1111 *
1112 * @unimplemented
1113 */
1114 DWORD STDCALL
1115 GetNamedSecurityInfoA(LPSTR pObjectName,
1116 SE_OBJECT_TYPE ObjectType,
1117 SECURITY_INFORMATION SecurityInfo,
1118 PSID *ppsidOwner,
1119 PSID *ppsidGroup,
1120 PACL *ppDacl,
1121 PACL *ppSacl,
1122 PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
1123 {
1124 DPRINT1("GetNamedSecurityInfoA: stub\n");
1125 return ERROR_CALL_NOT_IMPLEMENTED;
1126 }
1127
1128
1129 /**********************************************************************
1130 * SetNamedSecurityInfoW EXPORTED
1131 *
1132 * @unimplemented
1133 */
1134 DWORD STDCALL
1135 SetNamedSecurityInfoW(LPWSTR pObjectName,
1136 SE_OBJECT_TYPE ObjectType,
1137 SECURITY_INFORMATION SecurityInfo,
1138 PSID psidOwner,
1139 PSID psidGroup,
1140 PACL pDacl,
1141 PACL pSacl)
1142 {
1143 DPRINT1("SetNamedSecurityInfoW: stub\n");
1144 return ERROR_CALL_NOT_IMPLEMENTED;
1145 }
1146
1147
1148 /**********************************************************************
1149 * SetNamedSecurityInfoA EXPORTED
1150 *
1151 * @unimplemented
1152 */
1153 DWORD STDCALL
1154 SetNamedSecurityInfoA(LPSTR pObjectName,
1155 SE_OBJECT_TYPE ObjectType,
1156 SECURITY_INFORMATION SecurityInfo,
1157 PSID psidOwner,
1158 PSID psidGroup,
1159 PACL pDacl,
1160 PACL pSacl)
1161 {
1162 DPRINT1("SetNamedSecurityInfoA: stub\n");
1163 return ERROR_CALL_NOT_IMPLEMENTED;
1164 }
1165
1166
1167 /**********************************************************************
1168 * GetSecurityInfo EXPORTED
1169 *
1170 * @unimplemented
1171 */
1172 DWORD STDCALL
1173 GetSecurityInfo(HANDLE handle,
1174 SE_OBJECT_TYPE ObjectType,
1175 SECURITY_INFORMATION SecurityInfo,
1176 PSID* ppsidOwner,
1177 PSID* ppsidGroup,
1178 PACL* ppDacl,
1179 PACL* ppSacl,
1180 PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
1181 {
1182 DPRINT1("GetSecurityInfo: stub\n");
1183 return ERROR_CALL_NOT_IMPLEMENTED;
1184 }
1185
1186
1187 /**********************************************************************
1188 * SetSecurityInfo EXPORTED
1189 *
1190 * @unimplemented
1191 */
1192 DWORD
1193 WINAPI
1194 SetSecurityInfo(HANDLE handle,
1195 SE_OBJECT_TYPE ObjectType,
1196 SECURITY_INFORMATION SecurityInfo,
1197 PSID psidOwner,
1198 PSID psidGroup,
1199 PACL pDacl,
1200 PACL pSacl)
1201 {
1202 DPRINT1("SetSecurityInfo: stub\n");
1203 return ERROR_CALL_NOT_IMPLEMENTED;
1204 }
1205
1206
1207 /******************************************************************************
1208 * GetSecurityInfoExW EXPORTED
1209 */
1210 DWORD WINAPI GetSecurityInfoExA(
1211 HANDLE hObject,
1212 SE_OBJECT_TYPE ObjectType,
1213 SECURITY_INFORMATION SecurityInfo,
1214 LPCSTR lpProvider,
1215 LPCSTR lpProperty,
1216 PACTRL_ACCESSA *ppAccessList,
1217 PACTRL_AUDITA *ppAuditList,
1218 LPSTR *lppOwner,
1219 LPSTR *lppGroup
1220 )
1221 {
1222 DPRINT1("GetSecurityInfoExA stub!\n");
1223 return ERROR_BAD_PROVIDER;
1224 }
1225
1226
1227 /******************************************************************************
1228 * GetSecurityInfoExW EXPORTED
1229 */
1230 DWORD WINAPI GetSecurityInfoExW(
1231 HANDLE hObject,
1232 SE_OBJECT_TYPE ObjectType,
1233 SECURITY_INFORMATION SecurityInfo,
1234 LPCWSTR lpProvider,
1235 LPCWSTR lpProperty,
1236 PACTRL_ACCESSW *ppAccessList,
1237 PACTRL_AUDITW *ppAuditList,
1238 LPWSTR *lppOwner,
1239 LPWSTR *lppGroup
1240 )
1241 {
1242 DPRINT1("GetSecurityInfoExW stub!\n");
1243 return ERROR_BAD_PROVIDER;
1244 }
1245
1246
1247 /**********************************************************************
1248 * ImpersonateNamedPipeClient EXPORTED
1249 *
1250 * @implemented
1251 */
1252 BOOL STDCALL
1253 ImpersonateNamedPipeClient(HANDLE hNamedPipe)
1254 {
1255 IO_STATUS_BLOCK StatusBlock;
1256 NTSTATUS Status;
1257
1258 DPRINT("ImpersonateNamedPipeClient() called\n");
1259
1260 Status = NtFsControlFile(hNamedPipe,
1261 NULL,
1262 NULL,
1263 NULL,
1264 &StatusBlock,
1265 FSCTL_PIPE_IMPERSONATE,
1266 NULL,
1267 0,
1268 NULL,
1269 0);
1270 if (!NT_SUCCESS(Status))
1271 {
1272 SetLastError(RtlNtStatusToDosError(Status));
1273 return FALSE;
1274 }
1275
1276 return TRUE;
1277 }
1278
1279 /* EOF */