kernel32/tests/pipe: Enable compilation with long types.
[wine.git] / dlls / advapi32 / lsa.c
blobb63519c0299cee62312f76fa3e70c8b8bc3a43f0
1 /*
2 * Implementation of the Local Security Authority API
4 * Copyright 1999 Juergen Schmied
5 * Copyright 2002 Andriy Palamarchuk
6 * Copyright 2004 Mike McCormack
7 * Copyright 2005 Hans Leidekker
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include <stdarg.h>
26 #include "ntstatus.h"
27 #define WIN32_NO_STATUS
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winreg.h"
31 #include "winternl.h"
32 #include "sddl.h"
33 #include "advapi32_misc.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
39 #define ADVAPI_ForceLocalComputer(ServerName, FailureCode) \
40 if (!ADVAPI_IsLocalComputer(ServerName)) \
41 { \
42 FIXME("Action Implemented for local computer only. " \
43 "Requested for server %s\n", debugstr_w(ServerName)); \
44 return FailureCode; \
47 static LPCSTR debugstr_us( const UNICODE_STRING *us )
49 if (!us) return "(null)";
50 return debugstr_wn(us->Buffer, us->Length / sizeof(WCHAR));
53 static void dumpLsaAttributes(const LSA_OBJECT_ATTRIBUTES *oa)
55 if (oa)
57 TRACE("\n\tlength=%lu, rootdir=%p, objectname=%s\n\tattr=0x%08lx, sid=%s qos=%p\n",
58 oa->Length, oa->RootDirectory,
59 oa->ObjectName?debugstr_w(oa->ObjectName->Buffer):"null",
60 oa->Attributes, debugstr_sid(oa->SecurityDescriptor),
61 oa->SecurityQualityOfService);
65 static void* ADVAPI_GetDomainName(unsigned sz, unsigned ofs)
67 HKEY key;
68 LONG ret;
69 BYTE* ptr = NULL;
70 UNICODE_STRING* ustr;
72 ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Services\\VxD\\VNETSUP", 0, KEY_READ, &key);
73 if (ret == ERROR_SUCCESS)
75 DWORD size = 0;
76 ret = RegQueryValueExW(key, L"Workgroup", NULL, NULL, NULL, &size);
77 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
79 ptr = heap_alloc_zero(sz + size);
80 if (!ptr) return NULL;
81 ustr = (UNICODE_STRING*)(ptr + ofs);
82 ustr->MaximumLength = size;
83 ustr->Buffer = (WCHAR*)(ptr + sz);
84 ret = RegQueryValueExW(key, L"Workgroup", NULL, NULL, (LPBYTE)ustr->Buffer, &size);
85 if (ret != ERROR_SUCCESS)
87 heap_free(ptr);
88 ptr = NULL;
90 else ustr->Length = size - sizeof(WCHAR);
92 RegCloseKey(key);
94 if (!ptr)
96 ptr = heap_alloc_zero(sz + sizeof(L"DOMAIN"));
97 if (!ptr) return NULL;
98 ustr = (UNICODE_STRING*)(ptr + ofs);
99 ustr->MaximumLength = sizeof(L"DOMAIN");
100 ustr->Buffer = (WCHAR*)(ptr + sz);
101 ustr->Length = sizeof(L"DOMAIN") - sizeof(WCHAR);
102 memcpy(ustr->Buffer, L"DOMAIN", sizeof(L"DOMAIN"));
104 return ptr;
107 /******************************************************************************
108 * LsaGetUserName [ADVAPI32.@]
111 NTSTATUS WINAPI LsaGetUserName(PUNICODE_STRING *user_name, PUNICODE_STRING *domain_name)
113 UNICODE_STRING *user;
114 DWORD user_size;
116 user_size = 0;
117 if (GetUserNameW(NULL, &user_size) || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
118 return STATUS_UNSUCCESSFUL;
120 user = heap_alloc(sizeof(*user) + user_size * sizeof(WCHAR));
121 if (!user) return STATUS_NO_MEMORY;
123 user->Buffer = (WCHAR *)(user + 1);
124 user->MaximumLength = user_size * sizeof(WCHAR);
125 user->Length = user->MaximumLength - sizeof(WCHAR);
126 if (!GetUserNameW(user->Buffer, &user_size))
128 heap_free(user);
129 return STATUS_UNSUCCESSFUL;
132 if (domain_name)
134 UNICODE_STRING *domain;
135 WCHAR computer[MAX_COMPUTERNAME_LENGTH + 1];
136 DWORD domain_size;
138 domain_size = ARRAY_SIZE(computer);
139 if (!GetComputerNameW(computer, &domain_size))
141 heap_free(user);
142 return STATUS_UNSUCCESSFUL;
145 domain = heap_alloc(sizeof(*domain) + (domain_size + 1) * sizeof(WCHAR));
146 if (!domain)
148 heap_free(user);
149 return STATUS_NO_MEMORY;
152 domain->Buffer = (WCHAR *)(domain + 1);
153 domain->Length = domain_size * sizeof(WCHAR);
154 domain->MaximumLength = domain->Length + sizeof(WCHAR);
155 wcscpy(domain->Buffer, computer);
157 *domain_name = domain;
160 *user_name = user;
162 return STATUS_SUCCESS;
165 /******************************************************************************
166 * LsaAddAccountRights [ADVAPI32.@]
169 NTSTATUS WINAPI LsaAddAccountRights(
170 LSA_HANDLE policy,
171 PSID sid,
172 PLSA_UNICODE_STRING rights,
173 ULONG count)
175 FIXME("(%p,%p,%p,0x%08lx) stub\n", policy, sid, rights, count);
176 return STATUS_SUCCESS;
179 /******************************************************************************
180 * LsaClose [ADVAPI32.@]
182 * Closes a handle to a Policy or TrustedDomain.
184 * PARAMS
185 * ObjectHandle [I] Handle to a Policy or TrustedDomain.
187 * RETURNS
188 * Success: STATUS_SUCCESS.
189 * Failure: NTSTATUS code.
191 NTSTATUS WINAPI LsaClose(IN LSA_HANDLE ObjectHandle)
193 WARN("(%p) stub\n", ObjectHandle);
194 return STATUS_SUCCESS;
197 /******************************************************************************
198 * LsaCreateTrustedDomainEx [ADVAPI32.@]
201 NTSTATUS WINAPI LsaCreateTrustedDomainEx(
202 LSA_HANDLE policy,
203 PTRUSTED_DOMAIN_INFORMATION_EX domain_info,
204 PTRUSTED_DOMAIN_AUTH_INFORMATION auth_info,
205 ACCESS_MASK access,
206 PLSA_HANDLE domain)
208 FIXME("(%p,%p,%p,0x%08lx,%p) stub\n", policy, domain_info, auth_info,
209 access, domain);
210 return STATUS_SUCCESS;
213 /******************************************************************************
214 * LsaDeleteTrustedDomain [ADVAPI32.@]
217 NTSTATUS WINAPI LsaDeleteTrustedDomain(LSA_HANDLE policy, PSID sid)
219 FIXME("(%p,%p) stub\n", policy, sid);
220 return STATUS_SUCCESS;
223 /******************************************************************************
224 * LsaEnumerateAccountRights [ADVAPI32.@]
227 NTSTATUS WINAPI LsaEnumerateAccountRights(
228 LSA_HANDLE policy,
229 PSID sid,
230 PLSA_UNICODE_STRING *rights,
231 PULONG count)
233 FIXME("(%p,%p,%p,%p) stub\n", policy, sid, rights, count);
234 *rights = 0;
235 *count = 0;
236 return STATUS_OBJECT_NAME_NOT_FOUND;
239 /******************************************************************************
240 * LsaEnumerateAccounts [ADVAPI32.@]
243 NTSTATUS WINAPI LsaEnumerateAccounts(
244 LSA_HANDLE policy,
245 PLSA_ENUMERATION_HANDLE context,
246 PVOID *buffer,
247 ULONG maxlen,
248 PULONG count)
250 FIXME("(%p,%p,%p,%ld,%p) stub\n", policy, context, buffer, maxlen, count);
251 if (count) *count = 0;
252 return STATUS_NO_MORE_ENTRIES;
255 /******************************************************************************
256 * LsaEnumerateAccountsWithUserRight [ADVAPI32.@]
259 NTSTATUS WINAPI LsaEnumerateAccountsWithUserRight(
260 LSA_HANDLE policy,
261 PLSA_UNICODE_STRING rights,
262 PVOID *buffer,
263 PULONG count)
265 FIXME("(%p,%p,%p,%p) stub\n", policy, rights, buffer, count);
266 return STATUS_NO_MORE_ENTRIES;
269 /******************************************************************************
270 * LsaEnumerateTrustedDomains [ADVAPI32.@]
272 * Returns the names and SIDs of trusted domains.
274 * PARAMS
275 * PolicyHandle [I] Handle to a Policy object.
276 * EnumerationContext [I] Pointer to an enumeration handle.
277 * Buffer [O] Contains the names and SIDs of trusted domains.
278 * PreferredMaximumLength[I] Preferred maximum size in bytes of Buffer.
279 * CountReturned [O] Number of elements in Buffer.
281 * RETURNS
282 * Success: STATUS_SUCCESS,
283 * STATUS_MORE_ENTRIES,
284 * STATUS_NO_MORE_ENTRIES
285 * Failure: NTSTATUS code.
287 * NOTES
288 * LsaEnumerateTrustedDomains can be called multiple times to enumerate
289 * all trusted domains.
291 NTSTATUS WINAPI LsaEnumerateTrustedDomains(
292 IN LSA_HANDLE PolicyHandle,
293 IN PLSA_ENUMERATION_HANDLE EnumerationContext,
294 OUT PVOID* Buffer,
295 IN ULONG PreferredMaximumLength,
296 OUT PULONG CountReturned)
298 FIXME("(%p,%p,%p,0x%08lx,%p) stub\n", PolicyHandle, EnumerationContext,
299 Buffer, PreferredMaximumLength, CountReturned);
301 if (CountReturned) *CountReturned = 0;
302 return STATUS_SUCCESS;
305 /******************************************************************************
306 * LsaEnumerateTrustedDomainsEx [ADVAPI32.@]
309 NTSTATUS WINAPI LsaEnumerateTrustedDomainsEx(
310 LSA_HANDLE policy,
311 PLSA_ENUMERATION_HANDLE context,
312 PVOID *buffer,
313 ULONG length,
314 PULONG count)
316 FIXME("(%p,%p,%p,0x%08lx,%p) stub\n", policy, context, buffer, length, count);
318 if (count) *count = 0;
319 return STATUS_SUCCESS;
322 /******************************************************************************
323 * LsaFreeMemory [ADVAPI32.@]
325 * Frees memory allocated by a LSA function.
327 * PARAMS
328 * Buffer [I] Memory buffer to free.
330 * RETURNS
331 * Success: STATUS_SUCCESS.
332 * Failure: NTSTATUS code.
334 NTSTATUS WINAPI LsaFreeMemory(IN PVOID Buffer)
336 TRACE("(%p)\n", Buffer);
338 heap_free(Buffer);
339 return STATUS_SUCCESS;
342 /******************************************************************************
343 * LsaLookupNames [ADVAPI32.@]
345 * Returns the SIDs of an array of user, group, or local group names.
347 * PARAMS
348 * PolicyHandle [I] Handle to a Policy object.
349 * Count [I] Number of names in Names.
350 * Names [I] Array of names to lookup.
351 * ReferencedDomains [O] Array of domains where the names were found.
352 * Sids [O] Array of SIDs corresponding to Names.
354 * RETURNS
355 * Success: STATUS_SUCCESS,
356 * STATUS_SOME_NOT_MAPPED
357 * Failure: STATUS_NONE_MAPPED or NTSTATUS code.
359 NTSTATUS WINAPI LsaLookupNames(
360 IN LSA_HANDLE PolicyHandle,
361 IN ULONG Count,
362 IN PLSA_UNICODE_STRING Names,
363 OUT PLSA_REFERENCED_DOMAIN_LIST* ReferencedDomains,
364 OUT PLSA_TRANSLATED_SID* Sids)
366 FIXME("(%p,0x%08lx,%p,%p,%p) stub\n", PolicyHandle, Count, Names,
367 ReferencedDomains, Sids);
369 return STATUS_NONE_MAPPED;
372 static BOOL lookup_name( LSA_UNICODE_STRING *name, SID *sid, DWORD *sid_size, WCHAR *domain,
373 DWORD *domain_size, SID_NAME_USE *use, BOOL *handled )
375 BOOL ret;
377 ret = lookup_local_wellknown_name( name, sid, sid_size, domain, domain_size, use, handled );
378 if (!*handled)
379 ret = lookup_local_user_name( name, sid, sid_size, domain, domain_size, use, handled );
381 return ret;
384 /* Adds domain info to referenced domain list.
385 Domain list is stored as plain buffer, layout is:
387 LSA_REFERENCED_DOMAIN_LIST,
388 LSA_TRUST_INFORMATION array,
389 domain data array of
391 domain name data (WCHAR buffer),
392 SID data
395 Parameters:
396 list [I] referenced list pointer
397 domain [I] domain name string
398 data [IO] pointer to domain data array
400 static LONG lsa_reflist_add_domain(LSA_REFERENCED_DOMAIN_LIST *list, LSA_UNICODE_STRING *domain, char **data)
402 ULONG sid_size = 0,domain_size = 0;
403 BOOL handled = FALSE;
404 SID_NAME_USE use;
405 LONG i;
407 for (i = 0; i < list->Entries; i++)
409 /* try to reuse index */
410 if ((list->Domains[i].Name.Length == domain->Length) &&
411 (!wcsnicmp(list->Domains[i].Name.Buffer, domain->Buffer, (domain->Length / sizeof(WCHAR)))))
413 return i;
417 /* no matching domain found, store name */
418 list->Domains[list->Entries].Name.Length = domain->Length;
419 list->Domains[list->Entries].Name.MaximumLength = domain->MaximumLength;
420 list->Domains[list->Entries].Name.Buffer = (WCHAR*)*data;
421 memcpy(list->Domains[list->Entries].Name.Buffer, domain->Buffer, domain->MaximumLength);
422 *data += domain->MaximumLength;
424 /* get and store SID data */
425 list->Domains[list->Entries].Sid = *data;
426 lookup_name(domain, NULL, &sid_size, NULL, &domain_size, &use, &handled);
427 domain_size = 0;
428 lookup_name(domain, list->Domains[list->Entries].Sid, &sid_size, NULL, &domain_size, &use, &handled);
429 *data += sid_size;
431 return list->Entries++;
434 /******************************************************************************
435 * LsaLookupNames2 [ADVAPI32.@]
438 NTSTATUS WINAPI LsaLookupNames2( LSA_HANDLE policy, ULONG flags, ULONG count,
439 PLSA_UNICODE_STRING names, PLSA_REFERENCED_DOMAIN_LIST *domains,
440 PLSA_TRANSLATED_SID2 *sids )
442 ULONG i, sid_size_total = 0, domain_size_max = 0, size, domainname_size_total = 0;
443 ULONG sid_size, domain_size, mapped;
444 LSA_UNICODE_STRING domain;
445 BOOL handled = FALSE;
446 char *domain_data;
447 SID_NAME_USE use;
448 SID *sid;
450 TRACE("(%p,0x%08lx,0x%08lx,%p,%p,%p)\n", policy, flags, count, names, domains, sids);
452 mapped = 0;
453 for (i = 0; i < count; i++)
455 handled = FALSE;
456 sid_size = domain_size = 0;
457 lookup_name( &names[i], NULL, &sid_size, NULL, &domain_size, &use, &handled );
458 if (handled)
460 sid_size_total += sid_size;
461 domainname_size_total += domain_size;
462 if (domain_size)
464 if (domain_size > domain_size_max)
465 domain_size_max = domain_size;
467 mapped++;
470 TRACE("mapped %lu out of %lu\n", mapped, count);
472 size = sizeof(LSA_TRANSLATED_SID2) * count + sid_size_total;
473 if (!(*sids = heap_alloc(size))) return STATUS_NO_MEMORY;
475 sid = (SID *)(*sids + count);
477 /* use maximum domain count */
478 if (!(*domains = heap_alloc(sizeof(LSA_REFERENCED_DOMAIN_LIST) + sizeof(LSA_TRUST_INFORMATION)*count +
479 sid_size_total + domainname_size_total*sizeof(WCHAR))))
481 heap_free(*sids);
482 return STATUS_NO_MEMORY;
484 (*domains)->Entries = 0;
485 (*domains)->Domains = (LSA_TRUST_INFORMATION*)((char*)*domains + sizeof(LSA_REFERENCED_DOMAIN_LIST));
486 domain_data = (char*)(*domains)->Domains + sizeof(LSA_TRUST_INFORMATION)*count;
488 domain.Buffer = heap_alloc(domain_size_max*sizeof(WCHAR));
489 for (i = 0; i < count; i++)
491 domain.Length = domain_size_max*sizeof(WCHAR);
492 domain.MaximumLength = domain_size_max*sizeof(WCHAR);
494 (*sids)[i].Use = SidTypeUnknown;
495 (*sids)[i].DomainIndex = -1;
496 (*sids)[i].Flags = 0;
498 handled = FALSE;
499 sid_size = sid_size_total;
500 domain_size = domain_size_max;
501 lookup_name( &names[i], sid, &sid_size, domain.Buffer, &domain_size, &use, &handled );
502 if (handled)
504 (*sids)[i].Sid = sid;
505 (*sids)[i].Use = use;
507 sid = (SID *)((char *)sid + sid_size);
508 sid_size_total -= sid_size;
509 if (domain_size)
511 domain.Length = domain_size * sizeof(WCHAR);
512 domain.MaximumLength = (domain_size + 1) * sizeof(WCHAR);
513 (*sids)[i].DomainIndex = lsa_reflist_add_domain(*domains, &domain, &domain_data);
517 heap_free(domain.Buffer);
519 if (mapped == count) return STATUS_SUCCESS;
520 if (mapped > 0 && mapped < count) return STATUS_SOME_NOT_MAPPED;
521 return STATUS_NONE_MAPPED;
524 /******************************************************************************
525 * LsaLookupSids [ADVAPI32.@]
527 * Looks up the names that correspond to an array of SIDs.
529 * PARAMS
530 * PolicyHandle [I] Handle to a Policy object.
531 * Count [I] Number of SIDs in the Sids array.
532 * Sids [I] Array of SIDs to lookup.
533 * ReferencedDomains [O] Array of domains where the sids were found.
534 * Names [O] Array of names corresponding to Sids.
536 * RETURNS
537 * Success: STATUS_SUCCESS,
538 * STATUS_SOME_NOT_MAPPED
539 * Failure: STATUS_NONE_MAPPED or NTSTATUS code.
541 NTSTATUS WINAPI LsaLookupSids(
542 LSA_HANDLE PolicyHandle,
543 ULONG Count,
544 PSID *Sids,
545 LSA_REFERENCED_DOMAIN_LIST **ReferencedDomains,
546 LSA_TRANSLATED_NAME **Names)
548 ULONG i, mapped, name_fullsize, domain_fullsize;
549 ULONG name_size, domain_size;
550 LSA_UNICODE_STRING domain;
551 WCHAR *name_buffer;
552 char *domain_data;
553 SID_NAME_USE use;
554 WCHAR *strsid;
556 TRACE("(%p, %lu, %p, %p, %p)\n", PolicyHandle, Count, Sids, ReferencedDomains, Names);
558 /* this length does not include actual string length yet */
559 name_fullsize = sizeof(LSA_TRANSLATED_NAME) * Count;
560 if (!(*Names = heap_alloc(name_fullsize))) return STATUS_NO_MEMORY;
561 /* maximum count of stored domain infos is Count, allocate it like that cause really needed
562 count could only be computed after sid data is retrieved */
563 domain_fullsize = sizeof(LSA_REFERENCED_DOMAIN_LIST) + sizeof(LSA_TRUST_INFORMATION)*Count;
564 if (!(*ReferencedDomains = heap_alloc(domain_fullsize)))
566 heap_free(*Names);
567 return STATUS_NO_MEMORY;
569 (*ReferencedDomains)->Entries = 0;
570 (*ReferencedDomains)->Domains = (LSA_TRUST_INFORMATION*)((char*)*ReferencedDomains + sizeof(LSA_REFERENCED_DOMAIN_LIST));
572 /* Get full names data length and full length needed to store domain name and SID */
573 for (i = 0; i < Count; i++)
575 (*Names)[i].Use = SidTypeUnknown;
576 (*Names)[i].DomainIndex = -1;
577 RtlInitUnicodeStringEx(&(*Names)[i].Name, NULL);
579 memset(&(*ReferencedDomains)->Domains[i], 0, sizeof(LSA_TRUST_INFORMATION));
581 name_size = domain_size = 0;
582 if (!LookupAccountSidW(NULL, Sids[i], NULL, &name_size, NULL, &domain_size, &use) &&
583 GetLastError() == ERROR_INSUFFICIENT_BUFFER)
585 if (name_size)
587 (*Names)[i].Name.Length = (name_size - 1) * sizeof(WCHAR);
588 (*Names)[i].Name.MaximumLength = name_size * sizeof(WCHAR);
590 else
592 (*Names)[i].Name.Length = 0;
593 (*Names)[i].Name.MaximumLength = sizeof(WCHAR);
596 name_fullsize += (*Names)[i].Name.MaximumLength;
598 /* This potentially allocates more than needed, cause different names will reuse same domain index.
599 Also it's not possible to store domain name length right here for the same reason. */
600 if (domain_size)
602 ULONG sid_size = 0;
603 BOOL handled = FALSE;
604 WCHAR *name;
606 domain_fullsize += domain_size * sizeof(WCHAR);
608 /* get domain SID size too */
609 name = heap_alloc(domain_size * sizeof(WCHAR));
610 *name = 0;
611 LookupAccountSidW(NULL, Sids[i], NULL, &name_size, name, &domain_size, &use);
613 domain.Buffer = name;
614 domain.Length = domain_size * sizeof(WCHAR);
615 domain.MaximumLength = domain_size * sizeof(WCHAR);
617 lookup_name(&domain, NULL, &sid_size, NULL, &domain_size, &use, &handled);
618 domain_fullsize += sid_size;
620 heap_free(name);
622 else
624 /* If we don't have a domain name, use a zero-length entry rather than a null value. */
625 domain_fullsize += sizeof(WCHAR);
626 domain.Length = 0;
627 domain.MaximumLength = sizeof(WCHAR);
630 else if (ConvertSidToStringSidW(Sids[i], &strsid))
632 (*Names)[i].Name.Length = lstrlenW(strsid) * sizeof(WCHAR);
633 (*Names)[i].Name.MaximumLength = (lstrlenW(strsid) + 1) * sizeof(WCHAR);
634 name_fullsize += (lstrlenW(strsid) + 1) * sizeof(WCHAR);
636 LocalFree(strsid);
640 /* now we have full length needed for both */
641 *Names = heap_realloc(*Names, name_fullsize);
642 name_buffer = (WCHAR*)((char*)*Names + sizeof(LSA_TRANSLATED_NAME)*Count);
644 *ReferencedDomains = heap_realloc(*ReferencedDomains, domain_fullsize);
645 /* fix pointer after reallocation */
646 (*ReferencedDomains)->Domains = (LSA_TRUST_INFORMATION*)((char*)*ReferencedDomains + sizeof(LSA_REFERENCED_DOMAIN_LIST));
647 domain_data = (char*)(*ReferencedDomains)->Domains + sizeof(LSA_TRUST_INFORMATION)*Count;
649 mapped = 0;
650 for (i = 0; i < Count; i++)
652 name_size = domain_size = 0;
654 (*Names)[i].Name.Buffer = name_buffer;
656 if (!LookupAccountSidW(NULL, Sids[i], NULL, &name_size, NULL, &domain_size, &use) &&
657 GetLastError() == ERROR_INSUFFICIENT_BUFFER)
659 mapped++;
661 if (domain_size)
663 domain.Length = (domain_size - 1) * sizeof(WCHAR);
664 domain.MaximumLength = domain_size * sizeof(WCHAR);
666 else
668 /* Use a zero-length buffer */
669 domain.Length = 0;
670 domain.MaximumLength = sizeof(WCHAR);
673 domain.Buffer = heap_alloc(domain.MaximumLength);
675 LookupAccountSidW(NULL, Sids[i], (*Names)[i].Name.Buffer, &name_size, domain.Buffer, &domain_size, &use);
676 (*Names)[i].Use = use;
678 (*Names)[i].DomainIndex = lsa_reflist_add_domain(*ReferencedDomains, &domain, &domain_data);
679 heap_free(domain.Buffer);
681 else if (ConvertSidToStringSidW(Sids[i], &strsid))
683 lstrcpyW((*Names)[i].Name.Buffer, strsid);
684 LocalFree(strsid);
687 name_buffer += lstrlenW(name_buffer) + 1;
689 TRACE("mapped %lu out of %lu\n", mapped, Count);
691 if (mapped == Count) return STATUS_SUCCESS;
692 if (mapped) return STATUS_SOME_NOT_MAPPED;
693 return STATUS_NONE_MAPPED;
696 /******************************************************************************
697 * LsaNtStatusToWinError [ADVAPI32.@]
699 * Converts an LSA NTSTATUS code to a Windows error code.
701 * PARAMS
702 * Status [I] NTSTATUS code.
704 * RETURNS
705 * Success: Corresponding Windows error code.
706 * Failure: ERROR_MR_MID_NOT_FOUND.
708 ULONG WINAPI LsaNtStatusToWinError(NTSTATUS Status)
710 return RtlNtStatusToDosError(Status);
713 /******************************************************************************
714 * LsaOpenPolicy [ADVAPI32.@]
716 * Opens a handle to the Policy object on a local or remote system.
718 * PARAMS
719 * SystemName [I] Name of the target system.
720 * ObjectAttributes [I] Connection attributes.
721 * DesiredAccess [I] Requested access rights.
722 * PolicyHandle [I/O] Handle to the Policy object.
724 * RETURNS
725 * Success: STATUS_SUCCESS.
726 * Failure: NTSTATUS code.
728 * NOTES
729 * Set SystemName to NULL to open the local Policy object.
731 NTSTATUS WINAPI LsaOpenPolicy(
732 IN PLSA_UNICODE_STRING SystemName,
733 IN PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
734 IN ACCESS_MASK DesiredAccess,
735 IN OUT PLSA_HANDLE PolicyHandle)
737 WARN("(%s,%p,0x%08lx,%p) stub\n",
738 SystemName?debugstr_w(SystemName->Buffer):"(null)",
739 ObjectAttributes, DesiredAccess, PolicyHandle);
741 ADVAPI_ForceLocalComputer(SystemName ? SystemName->Buffer : NULL,
742 STATUS_ACCESS_VIOLATION);
743 dumpLsaAttributes(ObjectAttributes);
745 if(PolicyHandle) *PolicyHandle = (LSA_HANDLE)0xcafe;
746 return STATUS_SUCCESS;
749 /******************************************************************************
750 * LsaOpenTrustedDomainByName [ADVAPI32.@]
753 NTSTATUS WINAPI LsaOpenTrustedDomainByName(
754 LSA_HANDLE policy,
755 PLSA_UNICODE_STRING name,
756 ACCESS_MASK access,
757 PLSA_HANDLE handle)
759 FIXME("(%p,%p,0x%08lx,%p) stub\n", policy, name, access, handle);
760 return STATUS_OBJECT_NAME_NOT_FOUND;
763 /******************************************************************************
764 * LsaQueryInformationPolicy [ADVAPI32.@]
766 * Returns information about a Policy object.
768 * PARAMS
769 * PolicyHandle [I] Handle to a Policy object.
770 * InformationClass [I] Type of information to retrieve.
771 * Buffer [O] Pointer to the requested information.
773 * RETURNS
774 * Success: STATUS_SUCCESS.
775 * Failure: NTSTATUS code.
777 NTSTATUS WINAPI LsaQueryInformationPolicy(
778 IN LSA_HANDLE PolicyHandle,
779 IN POLICY_INFORMATION_CLASS InformationClass,
780 OUT PVOID *Buffer)
782 TRACE("(%p,0x%08x,%p)\n", PolicyHandle, InformationClass, Buffer);
784 if(!Buffer) return STATUS_INVALID_PARAMETER;
785 switch (InformationClass)
787 case PolicyAuditEventsInformation: /* 2 */
789 PPOLICY_AUDIT_EVENTS_INFO p = heap_alloc_zero(sizeof(POLICY_AUDIT_EVENTS_INFO));
790 p->AuditingMode = FALSE; /* no auditing */
791 *Buffer = p;
793 break;
794 case PolicyPrimaryDomainInformation: /* 3 */
796 /* Only the domain name is valid for the local computer.
797 * All other fields are zero.
799 PPOLICY_PRIMARY_DOMAIN_INFO pinfo;
801 pinfo = ADVAPI_GetDomainName(sizeof(*pinfo), offsetof(POLICY_PRIMARY_DOMAIN_INFO, Name));
803 TRACE("setting domain to %s\n", debugstr_w(pinfo->Name.Buffer));
805 *Buffer = pinfo;
807 break;
808 case PolicyAccountDomainInformation: /* 5 */
810 struct di
812 POLICY_ACCOUNT_DOMAIN_INFO info;
813 SID sid;
814 DWORD padding[3];
815 WCHAR domain[MAX_COMPUTERNAME_LENGTH + 1];
818 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
819 struct di * xdi = heap_alloc_zero(sizeof(*xdi));
821 xdi->info.DomainName.MaximumLength = dwSize * sizeof(WCHAR);
822 xdi->info.DomainName.Buffer = xdi->domain;
823 if (GetComputerNameW(xdi->info.DomainName.Buffer, &dwSize))
824 xdi->info.DomainName.Length = dwSize * sizeof(WCHAR);
826 TRACE("setting name to %s\n", debugstr_w(xdi->info.DomainName.Buffer));
828 xdi->info.DomainSid = &xdi->sid;
830 if (!ADVAPI_GetComputerSid(&xdi->sid))
832 heap_free(xdi);
834 WARN("Computer SID not found\n");
836 return STATUS_UNSUCCESSFUL;
839 TRACE("setting SID to %s\n", debugstr_sid(&xdi->sid));
841 *Buffer = xdi;
843 break;
844 case PolicyDnsDomainInformation: /* 12 (0xc) */
846 struct
848 POLICY_DNS_DOMAIN_INFO info;
849 struct
851 SID sid;
852 DWORD sid_subauthority[3];
853 } domain_sid;
854 WCHAR domain_name[256];
855 WCHAR dns_domain_name[256];
856 WCHAR dns_forest_name[256];
857 } *xdi;
858 struct
860 SID sid;
861 DWORD sid_subauthority[3];
862 } computer_sid;
863 DWORD dwSize;
865 xdi = heap_alloc_zero(sizeof(*xdi));
866 if (!xdi) return STATUS_NO_MEMORY;
868 dwSize = 256;
869 if (GetComputerNameExW(ComputerNamePhysicalDnsDomain, xdi->domain_name, &dwSize))
871 WCHAR *dot;
873 dot = wcsrchr(xdi->domain_name, '.');
874 if (dot) *dot = 0;
875 wcsupr(xdi->domain_name);
876 xdi->info.Name.Buffer = xdi->domain_name;
877 xdi->info.Name.Length = lstrlenW(xdi->domain_name) * sizeof(WCHAR);
878 xdi->info.Name.MaximumLength = xdi->info.Name.Length + sizeof(WCHAR);
879 TRACE("setting Name to %s\n", debugstr_w(xdi->info.Name.Buffer));
882 dwSize = 256;
883 if (GetComputerNameExW(ComputerNameDnsDomain, xdi->dns_domain_name, &dwSize))
885 xdi->info.DnsDomainName.Buffer = xdi->dns_domain_name;
886 xdi->info.DnsDomainName.Length = dwSize * sizeof(WCHAR);
887 xdi->info.DnsDomainName.MaximumLength = (dwSize + 1) * sizeof(WCHAR);
888 TRACE("setting DnsDomainName to %s\n", debugstr_w(xdi->info.DnsDomainName.Buffer));
890 xdi->info.DnsForestName.Buffer = xdi->dns_domain_name;
891 xdi->info.DnsForestName.Length = dwSize * sizeof(WCHAR);
892 xdi->info.DnsForestName.MaximumLength = (dwSize + 1) * sizeof(WCHAR);
893 TRACE("setting DnsForestName to %s\n", debugstr_w(xdi->info.DnsForestName.Buffer));
896 dwSize = sizeof(xdi->domain_sid);
897 if (ADVAPI_GetComputerSid(&computer_sid.sid) && GetWindowsAccountDomainSid(&computer_sid.sid, &xdi->domain_sid.sid, &dwSize))
899 xdi->info.Sid = &xdi->domain_sid.sid;
900 TRACE("setting SID to %s\n", debugstr_sid(&xdi->domain_sid.sid));
903 *Buffer = xdi;
905 break;
906 case PolicyAuditLogInformation:
907 case PolicyPdAccountInformation:
908 case PolicyLsaServerRoleInformation:
909 case PolicyReplicaSourceInformation:
910 case PolicyDefaultQuotaInformation:
911 case PolicyModificationInformation:
912 case PolicyAuditFullSetInformation:
913 case PolicyAuditFullQueryInformation:
915 FIXME("category %d not implemented\n", InformationClass);
916 return STATUS_UNSUCCESSFUL;
919 return STATUS_SUCCESS;
922 /******************************************************************************
923 * LsaQueryTrustedDomainInfo [ADVAPI32.@]
926 NTSTATUS WINAPI LsaQueryTrustedDomainInfo(
927 LSA_HANDLE policy,
928 PSID sid,
929 TRUSTED_INFORMATION_CLASS class,
930 PVOID *buffer)
932 FIXME("(%p,%p,%d,%p) stub\n", policy, sid, class, buffer);
933 return STATUS_OBJECT_NAME_NOT_FOUND;
936 /******************************************************************************
937 * LsaQueryTrustedDomainInfoByName [ADVAPI32.@]
940 NTSTATUS WINAPI LsaQueryTrustedDomainInfoByName(
941 LSA_HANDLE policy,
942 PLSA_UNICODE_STRING name,
943 TRUSTED_INFORMATION_CLASS class,
944 PVOID *buffer)
946 FIXME("(%p,%p,%d,%p) stub\n", policy, name, class, buffer);
947 return STATUS_OBJECT_NAME_NOT_FOUND;
950 /******************************************************************************
951 * LsaRegisterPolicyChangeNotification [ADVAPI32.@]
954 NTSTATUS WINAPI LsaRegisterPolicyChangeNotification(
955 POLICY_NOTIFICATION_INFORMATION_CLASS class,
956 HANDLE event)
958 FIXME("(%d,%p) stub\n", class, event);
959 return STATUS_UNSUCCESSFUL;
962 /******************************************************************************
963 * LsaRemoveAccountRights [ADVAPI32.@]
966 NTSTATUS WINAPI LsaRemoveAccountRights(
967 LSA_HANDLE policy,
968 PSID sid,
969 BOOLEAN all,
970 PLSA_UNICODE_STRING rights,
971 ULONG count)
973 FIXME("(%p,%p,%d,%p,0x%08lx) stub\n", policy, sid, all, rights, count);
974 return STATUS_SUCCESS;
977 /******************************************************************************
978 * LsaRetrievePrivateData [ADVAPI32.@]
980 * Retrieves data stored by LsaStorePrivateData.
982 * PARAMS
983 * PolicyHandle [I] Handle to a Policy object.
984 * KeyName [I] Name of the key where the data is stored.
985 * PrivateData [O] Pointer to the private data.
987 * RETURNS
988 * Success: STATUS_SUCCESS.
989 * Failure: STATUS_OBJECT_NAME_NOT_FOUND or NTSTATUS code.
991 NTSTATUS WINAPI LsaRetrievePrivateData(
992 IN LSA_HANDLE PolicyHandle,
993 IN PLSA_UNICODE_STRING KeyName,
994 OUT PLSA_UNICODE_STRING* PrivateData)
996 FIXME("(%p,%p,%p) stub\n", PolicyHandle, KeyName, PrivateData);
997 return STATUS_OBJECT_NAME_NOT_FOUND;
1000 /******************************************************************************
1001 * LsaSetInformationPolicy [ADVAPI32.@]
1003 * Modifies information in a Policy object.
1005 * PARAMS
1006 * PolicyHandle [I] Handle to a Policy object.
1007 * InformationClass [I] Type of information to set.
1008 * Buffer [I] Pointer to the information to set.
1010 * RETURNS
1011 * Success: STATUS_SUCCESS.
1012 * Failure: NTSTATUS code.
1014 NTSTATUS WINAPI LsaSetInformationPolicy(
1015 IN LSA_HANDLE PolicyHandle,
1016 IN POLICY_INFORMATION_CLASS InformationClass,
1017 IN PVOID Buffer)
1019 FIXME("(%p,0x%08x,%p) stub\n", PolicyHandle, InformationClass, Buffer);
1021 return STATUS_UNSUCCESSFUL;
1024 /******************************************************************************
1025 * LsaSetSecret [ADVAPI32.@]
1027 * Set old and new values on a secret handle
1029 * PARAMS
1030 * SecretHandle [I] Handle to a secret object.
1031 * EncryptedCurrentValue [I] Pointer to encrypted new value, can be NULL
1032 * EncryptedOldValue [I] Pointer to encrypted old value, can be NULL
1034 * RETURNS
1035 * Success: STATUS_SUCCESS
1036 * Failure: NTSTATUS code.
1038 NTSTATUS WINAPI LsaSetSecret(
1039 IN LSA_HANDLE SecretHandle,
1040 IN PLSA_UNICODE_STRING EncryptedCurrentValue,
1041 IN PLSA_UNICODE_STRING EncryptedOldValue)
1043 FIXME("(%p,%p,%p) stub\n", SecretHandle, EncryptedCurrentValue,
1044 EncryptedOldValue);
1045 return STATUS_SUCCESS;
1048 /******************************************************************************
1049 * LsaSetTrustedDomainInfoByName [ADVAPI32.@]
1052 NTSTATUS WINAPI LsaSetTrustedDomainInfoByName(
1053 LSA_HANDLE policy,
1054 PLSA_UNICODE_STRING name,
1055 TRUSTED_INFORMATION_CLASS class,
1056 PVOID buffer)
1058 FIXME("(%p,%p,%d,%p) stub\n", policy, name, class, buffer);
1059 return STATUS_SUCCESS;
1062 /******************************************************************************
1063 * LsaSetTrustedDomainInformation [ADVAPI32.@]
1066 NTSTATUS WINAPI LsaSetTrustedDomainInformation(
1067 LSA_HANDLE policy,
1068 PSID sid,
1069 TRUSTED_INFORMATION_CLASS class,
1070 PVOID buffer)
1072 FIXME("(%p,%p,%d,%p) stub\n", policy, sid, class, buffer);
1073 return STATUS_SUCCESS;
1076 /******************************************************************************
1077 * LsaStorePrivateData [ADVAPI32.@]
1079 * Stores or deletes a Policy object's data under the specified reg key.
1081 * PARAMS
1082 * PolicyHandle [I] Handle to a Policy object.
1083 * KeyName [I] Name of the key where the data will be stored.
1084 * PrivateData [O] Pointer to the private data.
1086 * RETURNS
1087 * Success: STATUS_SUCCESS.
1088 * Failure: STATUS_OBJECT_NAME_NOT_FOUND or NTSTATUS code.
1090 NTSTATUS WINAPI LsaStorePrivateData(
1091 IN LSA_HANDLE PolicyHandle,
1092 IN PLSA_UNICODE_STRING KeyName,
1093 IN PLSA_UNICODE_STRING PrivateData)
1095 FIXME("(%p,%p,%p) stub\n", PolicyHandle, KeyName, PrivateData);
1096 return STATUS_OBJECT_NAME_NOT_FOUND;
1099 /******************************************************************************
1100 * LsaUnregisterPolicyChangeNotification [ADVAPI32.@]
1103 NTSTATUS WINAPI LsaUnregisterPolicyChangeNotification(
1104 POLICY_NOTIFICATION_INFORMATION_CLASS class,
1105 HANDLE event)
1107 FIXME("(%d,%p) stub\n", class, event);
1108 return STATUS_SUCCESS;
1111 /******************************************************************************
1112 * LsaLookupPrivilegeName [ADVAPI32.@]
1115 NTSTATUS WINAPI LsaLookupPrivilegeName(LSA_HANDLE handle, LUID *luid, LSA_UNICODE_STRING **name)
1117 const WCHAR *privnameW;
1118 DWORD length;
1119 WCHAR *strW;
1121 TRACE("(%p,%p,%p)\n", handle, luid, name);
1123 if (!luid || !handle)
1124 return STATUS_INVALID_PARAMETER;
1126 *name = NULL;
1128 if (!(privnameW = get_wellknown_privilege_name(luid)))
1129 return STATUS_NO_SUCH_PRIVILEGE;
1131 length = lstrlenW(privnameW);
1132 *name = heap_alloc(sizeof(**name) + (length + 1) * sizeof(WCHAR));
1133 if (!*name)
1134 return STATUS_NO_MEMORY;
1136 strW = (WCHAR *)(*name + 1);
1137 memcpy(strW, privnameW, length * sizeof(WCHAR));
1138 strW[length] = 0;
1139 RtlInitUnicodeString(*name, strW);
1141 return STATUS_SUCCESS;
1144 /******************************************************************************
1145 * LsaLookupPrivilegeDisplayName [ADVAPI32.@]
1148 NTSTATUS WINAPI LsaLookupPrivilegeDisplayName(LSA_HANDLE handle, LSA_UNICODE_STRING *name,
1149 LSA_UNICODE_STRING **display_name, SHORT *language)
1151 FIXME("(%p, %s, %p, %p)\n", handle, debugstr_us(name), display_name, language);
1153 return STATUS_NO_SUCH_PRIVILEGE;
1156 /******************************************************************************
1157 * AuditQuerySystemPolicy [ADVAPI32.@]
1160 BOOLEAN WINAPI AuditQuerySystemPolicy(const GUID* guids, ULONG count, AUDIT_POLICY_INFORMATION** policy)
1163 FIXME("(%p, %ld, %p)\n", guids, count, policy);
1164 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1165 return FALSE;