vcomp: Better stub for omp_get_max_threads.
[wine] / dlls / advapi32 / lsa.c
1 /*
2  * Implementation of the Local Security Authority API
3  *
4  * Copyright 1999 Juergen Schmied
5  * Copyright 2002 Andriy Palamarchuk
6  * Copyright 2004 Mike McCormack
7  * Copyright 2005 Hans Leidekker
8  *
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.
13  *
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.
18  *
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
22  */
23
24 #include <stdarg.h>
25
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 "advapi32_misc.h"
33
34 #include "wine/debug.h"
35 #include "wine/unicode.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
38
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; \
45 }
46
47 static void dumpLsaAttributes(const LSA_OBJECT_ATTRIBUTES *oa)
48 {
49     if (oa)
50     {
51         TRACE("\n\tlength=%u, rootdir=%p, objectname=%s\n\tattr=0x%08x, sid=%s qos=%p\n",
52               oa->Length, oa->RootDirectory,
53               oa->ObjectName?debugstr_w(oa->ObjectName->Buffer):"null",
54               oa->Attributes, debugstr_sid(oa->SecurityDescriptor),
55               oa->SecurityQualityOfService);
56     }
57 }
58
59 static void* ADVAPI_GetDomainName(unsigned sz, unsigned ofs)
60 {
61     HKEY key;
62     LONG ret;
63     BYTE* ptr = NULL;
64     UNICODE_STRING* ustr;
65
66     static const WCHAR wVNETSUP[] = {
67         'S','y','s','t','e','m','\\',
68         'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
69         'S','e','r','v','i','c','e','s','\\',
70         'V','x','D','\\','V','N','E','T','S','U','P','\0'};
71
72     ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wVNETSUP, 0, KEY_READ, &key);
73     if (ret == ERROR_SUCCESS)
74     {
75         DWORD size = 0;
76         static const WCHAR wg[] = { 'W','o','r','k','g','r','o','u','p',0 };
77
78         ret = RegQueryValueExW(key, wg, NULL, NULL, NULL, &size);
79         if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
80         {
81             ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz + size);
82             if (!ptr) return NULL;
83             ustr = (UNICODE_STRING*)(ptr + ofs);
84             ustr->MaximumLength = size;
85             ustr->Buffer = (WCHAR*)(ptr + sz);
86             ret = RegQueryValueExW(key, wg, NULL, NULL, (LPBYTE)ustr->Buffer, &size);
87             if (ret != ERROR_SUCCESS)
88             {
89                 HeapFree(GetProcessHeap(), 0, ptr);
90                 ptr = NULL;
91             }   
92             else ustr->Length = size - sizeof(WCHAR);
93         }
94         RegCloseKey(key);
95     }
96     if (!ptr)
97     {
98         static const WCHAR wDomain[] = {'D','O','M','A','I','N','\0'};
99         ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
100                         sz + sizeof(wDomain));
101         if (!ptr) return NULL;
102         ustr = (UNICODE_STRING*)(ptr + ofs);
103         ustr->MaximumLength = sizeof(wDomain);
104         ustr->Buffer = (WCHAR*)(ptr + sz);
105         ustr->Length = sizeof(wDomain) - sizeof(WCHAR);
106         memcpy(ustr->Buffer, wDomain, sizeof(wDomain));
107     }
108     return ptr;
109 }
110
111 /******************************************************************************
112  * LsaAddAccountRights [ADVAPI32.@]
113  *
114  */
115 NTSTATUS WINAPI LsaAddAccountRights(
116     LSA_HANDLE policy,
117     PSID sid,
118     PLSA_UNICODE_STRING rights,
119     ULONG count)
120 {
121     FIXME("(%p,%p,%p,0x%08x) stub\n", policy, sid, rights, count);
122     return STATUS_OBJECT_NAME_NOT_FOUND;
123 }
124
125 /******************************************************************************
126  * LsaClose [ADVAPI32.@]
127  *
128  * Closes a handle to a Policy or TrustedDomain.
129  *
130  * PARAMS
131  *  ObjectHandle [I] Handle to a Policy or TrustedDomain.
132  *
133  * RETURNS
134  *  Success: STATUS_SUCCESS.
135  *  Failure: NTSTATUS code.
136  */
137 NTSTATUS WINAPI LsaClose(IN LSA_HANDLE ObjectHandle)
138 {
139     FIXME("(%p) stub\n", ObjectHandle);
140     return STATUS_SUCCESS;
141 }
142
143 /******************************************************************************
144  * LsaCreateTrustedDomainEx [ADVAPI32.@]
145  *
146  */
147 NTSTATUS WINAPI LsaCreateTrustedDomainEx(
148     LSA_HANDLE policy,
149     PTRUSTED_DOMAIN_INFORMATION_EX domain_info,
150     PTRUSTED_DOMAIN_AUTH_INFORMATION auth_info,
151     ACCESS_MASK access,
152     PLSA_HANDLE domain)
153 {
154     FIXME("(%p,%p,%p,0x%08x,%p) stub\n", policy, domain_info, auth_info,
155           access, domain);
156     return STATUS_SUCCESS;
157 }
158
159 /******************************************************************************
160  * LsaDeleteTrustedDomain [ADVAPI32.@]
161  *
162  */
163 NTSTATUS WINAPI LsaDeleteTrustedDomain(LSA_HANDLE policy, PSID sid)
164 {
165     FIXME("(%p,%p) stub\n", policy, sid);
166     return STATUS_SUCCESS;
167 }
168
169 /******************************************************************************
170  * LsaEnumerateAccountRights [ADVAPI32.@]
171  *
172  */
173 NTSTATUS WINAPI LsaEnumerateAccountRights(
174     LSA_HANDLE policy,
175     PSID sid,
176     PLSA_UNICODE_STRING *rights,
177     PULONG count)
178 {
179     FIXME("(%p,%p,%p,%p) stub\n", policy, sid, rights, count);
180     *rights = 0;
181     *count = 0;
182     return STATUS_OBJECT_NAME_NOT_FOUND;
183 }
184
185 /******************************************************************************
186  * LsaEnumerateAccountsWithUserRight [ADVAPI32.@]
187  *
188  */
189 NTSTATUS WINAPI LsaEnumerateAccountsWithUserRight(
190     LSA_HANDLE policy,
191     PLSA_UNICODE_STRING rights,
192     PVOID *buffer,
193     PULONG count)
194 {
195     FIXME("(%p,%p,%p,%p) stub\n", policy, rights, buffer, count);
196     return STATUS_NO_MORE_ENTRIES;
197 }
198
199 /******************************************************************************
200  * LsaEnumerateTrustedDomains [ADVAPI32.@]
201  *
202  * Returns the names and SIDs of trusted domains.
203  *
204  * PARAMS
205  *  PolicyHandle          [I] Handle to a Policy object.
206  *  EnumerationContext    [I] Pointer to an enumeration handle.
207  *  Buffer                [O] Contains the names and SIDs of trusted domains.
208  *  PreferredMaximumLength[I] Preferred maximum size in bytes of Buffer.
209  *  CountReturned         [O] Number of elements in Buffer.
210  *
211  * RETURNS
212  *  Success: STATUS_SUCCESS,
213  *           STATUS_MORE_ENTRIES,
214  *           STATUS_NO_MORE_ENTRIES
215  *  Failure: NTSTATUS code.
216  *
217  * NOTES
218  *  LsaEnumerateTrustedDomains can be called multiple times to enumerate
219  *  all trusted domains.
220  */
221 NTSTATUS WINAPI LsaEnumerateTrustedDomains(
222     IN LSA_HANDLE PolicyHandle,
223     IN PLSA_ENUMERATION_HANDLE EnumerationContext,
224     OUT PVOID* Buffer,
225     IN ULONG PreferredMaximumLength,
226     OUT PULONG CountReturned)
227 {
228     FIXME("(%p,%p,%p,0x%08x,%p) stub\n", PolicyHandle, EnumerationContext,
229           Buffer, PreferredMaximumLength, CountReturned);
230
231     if (CountReturned) *CountReturned = 0;
232     return STATUS_SUCCESS;
233 }
234
235 /******************************************************************************
236  * LsaEnumerateTrustedDomainsEx [ADVAPI32.@]
237  *
238  */
239 NTSTATUS WINAPI LsaEnumerateTrustedDomainsEx(
240     LSA_HANDLE policy,
241     PLSA_ENUMERATION_HANDLE context,
242     PVOID *buffer,
243     ULONG length,
244     PULONG count)
245 {
246     FIXME("(%p,%p,%p,0x%08x,%p) stub\n", policy, context, buffer, length, count);
247
248     if (count) *count = 0;
249     return STATUS_SUCCESS;
250 }
251
252 /******************************************************************************
253  * LsaFreeMemory [ADVAPI32.@]
254  *
255  * Frees memory allocated by a LSA function.
256  *
257  * PARAMS
258  *  Buffer [I] Memory buffer to free.
259  *
260  * RETURNS
261  *  Success: STATUS_SUCCESS.
262  *  Failure: NTSTATUS code.
263  */
264 NTSTATUS WINAPI LsaFreeMemory(IN PVOID Buffer)
265 {
266     TRACE("(%p)\n", Buffer);
267
268     HeapFree(GetProcessHeap(), 0, Buffer);
269     return STATUS_SUCCESS;
270 }
271
272 /******************************************************************************
273  * LsaLookupNames [ADVAPI32.@]
274  *
275  * Returns the SIDs of an array of user, group, or local group names.
276  *
277  * PARAMS
278  *  PolicyHandle      [I] Handle to a Policy object.
279  *  Count             [I] Number of names in Names.
280  *  Names             [I] Array of names to lookup.
281  *  ReferencedDomains [O] Array of domains where the names were found.
282  *  Sids              [O] Array of SIDs corresponding to Names.
283  *
284  * RETURNS
285  *  Success: STATUS_SUCCESS,
286  *           STATUS_SOME_NOT_MAPPED
287  *  Failure: STATUS_NONE_MAPPED or NTSTATUS code.
288  */
289 NTSTATUS WINAPI LsaLookupNames(
290     IN LSA_HANDLE PolicyHandle,
291     IN ULONG Count,
292     IN PLSA_UNICODE_STRING Names,
293     OUT PLSA_REFERENCED_DOMAIN_LIST* ReferencedDomains,
294     OUT PLSA_TRANSLATED_SID* Sids)
295 {
296     FIXME("(%p,0x%08x,%p,%p,%p) stub\n", PolicyHandle, Count, Names,
297           ReferencedDomains, Sids);
298
299     return STATUS_NONE_MAPPED;
300 }
301
302 static BOOL lookup_name( LSA_UNICODE_STRING *name, SID *sid, DWORD *sid_size, WCHAR *domain,
303                          DWORD *domain_size, SID_NAME_USE *use, BOOL *handled )
304 {
305     BOOL ret;
306
307     ret = lookup_local_wellknown_name( name, sid, sid_size, domain, domain_size, use, handled );
308     if (!*handled)
309         ret = lookup_local_user_name( name, sid, sid_size, domain, domain_size, use, handled );
310
311     return ret;
312 }
313
314 static INT build_domain(PLSA_REFERENCED_DOMAIN_LIST currentList, PLSA_UNICODE_STRING domain)
315 {
316     ULONG count;
317     ULONG sid_size = 0,domain_size = 0;
318     BOOL handled = FALSE;
319     SID_NAME_USE use;
320
321     for (count = 0; count < currentList->Entries; count ++)
322     {
323         if ((currentList->Domains[count].Name.Length == domain->Length) &&
324             (strncmpiW(currentList->Domains[count].Name.Buffer,domain->Buffer,(domain->Length / sizeof(WCHAR))) == 0))
325         {
326             HeapFree(GetProcessHeap(),0,domain->Buffer);
327             return count;
328         }
329     }
330
331     if (currentList->Entries > 0)
332         currentList->Domains = HeapReAlloc(GetProcessHeap(),0,currentList->Domains, (currentList->Entries + 1) * sizeof(LSA_TRUST_INFORMATION));
333     else
334         currentList->Domains = HeapAlloc(GetProcessHeap(),0,sizeof(LSA_TRUST_INFORMATION));
335
336     currentList->Domains[currentList->Entries].Name = *domain;
337
338     lookup_name( domain, NULL, &sid_size, NULL, &domain_size, &use, &handled );
339     domain_size = 0;
340     currentList->Domains[currentList->Entries].Sid = HeapAlloc(GetProcessHeap(),0,sid_size);
341     lookup_name( domain, currentList->Domains[currentList->Entries].Sid, &sid_size, NULL, &domain_size, &use, &handled );
342
343     currentList->Entries++;
344     return currentList->Entries-1;
345 }
346
347 /******************************************************************************
348  * LsaLookupNames2 [ADVAPI32.@]
349  *
350  */
351 NTSTATUS WINAPI LsaLookupNames2( LSA_HANDLE policy, ULONG flags, ULONG count,
352                                  PLSA_UNICODE_STRING names, PLSA_REFERENCED_DOMAIN_LIST *domains,
353                                  PLSA_TRANSLATED_SID2 *sids )
354 {
355     ULONG i, sid_size_total = 0, domain_size_max = 0, size;
356     ULONG sid_size, domain_size, mapped;
357     BOOL handled = FALSE;
358     SID_NAME_USE use;
359     SID *sid;
360
361     TRACE("(%p,0x%08x,0x%08x,%p,%p,%p)\n", policy, flags, count, names, domains, sids);
362
363     mapped = 0;
364     for (i = 0; i < count; i++)
365     {
366         handled = FALSE;
367         sid_size = domain_size = 0;
368         lookup_name( &names[i], NULL, &sid_size, NULL, &domain_size, &use, &handled );
369         if (handled)
370         {
371             sid_size_total += sid_size;
372             if (domain_size)
373             {
374                 if (domain_size > domain_size_max)
375                     domain_size_max = domain_size;
376             }
377             mapped++;
378         }
379     }
380     TRACE("mapped %u out of %u\n", mapped, count);
381
382     size = sizeof(LSA_TRANSLATED_SID2) * count + sid_size_total;
383     if (!(*sids = HeapAlloc( GetProcessHeap(), 0, size) )) return STATUS_NO_MEMORY;
384
385     sid = (SID *)(*sids + count);
386
387     if (!(*domains = HeapAlloc( GetProcessHeap(), 0, sizeof(LSA_REFERENCED_DOMAIN_LIST) )))
388     {
389         HeapFree( GetProcessHeap(), 0, *sids );
390         return STATUS_NO_MEMORY;
391     }
392     (*domains)->Entries = 0;
393     (*domains)->Domains = NULL;
394
395     for (i = 0; i < count; i++)
396     {
397         LSA_UNICODE_STRING domain;
398
399         domain.Length = domain_size_max*sizeof(WCHAR);
400         domain.MaximumLength = domain_size_max*sizeof(WCHAR);
401         domain.Buffer = HeapAlloc(GetProcessHeap(),0,domain.Length);
402
403         (*sids)[i].Use = SidTypeUnknown;
404         (*sids)[i].DomainIndex = -1;
405         (*sids)[i].Flags = 0;
406
407         handled = FALSE;
408         sid_size = sid_size_total;
409         domain_size = domain_size_max;
410         lookup_name( &names[i], sid, &sid_size, domain.Buffer, &domain_size, &use, &handled );
411         if (handled)
412         {
413             (*sids)[i].Sid = sid;
414             (*sids)[i].Use = use;
415
416             sid = (SID *)((char *)sid + sid_size);
417             sid_size_total -= sid_size;
418             if (domain_size)
419             {
420                 domain.Length = domain_size * sizeof(WCHAR);
421                 (*sids)[i].DomainIndex = build_domain(*domains, &domain);
422             }
423             else
424                 HeapFree(GetProcessHeap(),0,domain.Buffer);
425         }
426         else
427             HeapFree(GetProcessHeap(),0,domain.Buffer);
428     }
429
430     if (mapped == count) return STATUS_SUCCESS;
431     if (mapped > 0 && mapped < count) return STATUS_SOME_NOT_MAPPED;
432     return STATUS_NONE_MAPPED;
433 }
434
435 /******************************************************************************
436  * LsaLookupSids [ADVAPI32.@]
437  *
438  * Looks up the names that correspond to an array of SIDs.
439  *
440  * PARAMS
441  *  PolicyHandle      [I] Handle to a Policy object.
442  *  Count             [I] Number of SIDs in the Sids array.
443  *  Sids              [I] Array of SIDs to lookup.
444  *  ReferencedDomains [O] Array of domains where the sids were found.
445  *  Names             [O] Array of names corresponding to Sids.
446  *
447  * RETURNS
448  *  Success: STATUS_SUCCESS,
449  *           STATUS_SOME_NOT_MAPPED
450  *  Failure: STATUS_NONE_MAPPED or NTSTATUS code.
451  */
452 NTSTATUS WINAPI LsaLookupSids(
453     IN LSA_HANDLE PolicyHandle,
454     IN ULONG Count,
455     IN PSID *Sids,
456     OUT PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains,
457     OUT PLSA_TRANSLATED_NAME *Names )
458 {
459     ULONG i, mapped, size;
460     ULONG name_size, domain_size;
461     SID_NAME_USE use;
462
463     TRACE("(%p,%u,%p,%p,%p) stub\n", PolicyHandle, Count, Sids,
464           ReferencedDomains, Names);
465
466     size = sizeof(LSA_TRANSLATED_NAME) * Count;
467     if (!(*Names = HeapAlloc( GetProcessHeap(), 0, size) )) return STATUS_NO_MEMORY;
468     if (!(*ReferencedDomains = HeapAlloc( GetProcessHeap(), 0, sizeof(LSA_REFERENCED_DOMAIN_LIST)) ))
469     {
470         HeapFree( GetProcessHeap(), 0, *Names);
471         return STATUS_NO_MEMORY;
472     }
473     (*ReferencedDomains)->Entries = 0;
474     (*ReferencedDomains)->Domains = NULL;
475
476     mapped = 0;
477     for (i = 0; i < Count; i++)
478     {
479         name_size = domain_size = 0;
480         (*Names)[i].Use = SidTypeUnknown;
481         (*Names)[i].DomainIndex = -1;
482         (*Names)[i].Name.Length = 0;
483         (*Names)[i].Name.MaximumLength = 0;
484         (*Names)[i].Name.Buffer = NULL;
485
486         if (!LookupAccountSidW(NULL, Sids[i], NULL, &name_size, NULL, &domain_size, &use) &&
487             GetLastError() == ERROR_INSUFFICIENT_BUFFER)
488         {
489             LSA_UNICODE_STRING domain;
490
491             mapped++;
492
493             if (domain_size)
494             {
495                 domain.Length = (domain_size - 1) * sizeof(WCHAR);
496                 domain.MaximumLength = domain_size*sizeof(WCHAR);
497                 domain.Buffer = HeapAlloc(GetProcessHeap(),0,domain.MaximumLength);
498             }
499             else
500             {
501                 domain.Length = 0;
502                 domain.MaximumLength = 0;
503                 domain.Buffer = NULL;
504             }
505
506             (*Names)[i].Name.Length = (name_size - 1) * sizeof(WCHAR);
507             (*Names)[i].Name.MaximumLength = name_size * sizeof(WCHAR);
508             (*Names)[i].Name.Buffer = HeapAlloc(GetProcessHeap(), 0, name_size * sizeof(WCHAR));
509             LookupAccountSidW(NULL, Sids[i], (*Names)[i].Name.Buffer, &name_size, domain.Buffer, &domain_size, &use);
510             (*Names)[i].Use = use;
511
512             if (domain_size)
513                 (*Names)[i].DomainIndex = build_domain(*ReferencedDomains, &domain);
514         }
515     }
516     TRACE("mapped %u out of %u\n",mapped,Count);
517
518     if (mapped == Count) return STATUS_SUCCESS;
519     if (mapped) return STATUS_SOME_NOT_MAPPED;
520     return STATUS_NONE_MAPPED;
521 }
522
523 /******************************************************************************
524  * LsaNtStatusToWinError [ADVAPI32.@]
525  *
526  * Converts an LSA NTSTATUS code to a Windows error code.
527  *
528  * PARAMS
529  *  Status [I] NTSTATUS code.
530  *
531  * RETURNS
532  *  Success: Corresponding Windows error code.
533  *  Failure: ERROR_MR_MID_NOT_FOUND.
534  */
535 ULONG WINAPI LsaNtStatusToWinError(NTSTATUS Status)
536 {
537     return RtlNtStatusToDosError(Status);
538 }
539
540 /******************************************************************************
541  * LsaOpenPolicy [ADVAPI32.@]
542  *
543  * Opens a handle to the Policy object on a local or remote system.
544  *
545  * PARAMS
546  *  SystemName       [I] Name of the target system.
547  *  ObjectAttributes [I] Connection attributes.
548  *  DesiredAccess    [I] Requested access rights.
549  *  PolicyHandle     [I/O] Handle to the Policy object.
550  *
551  * RETURNS
552  *  Success: STATUS_SUCCESS.
553  *  Failure: NTSTATUS code.
554  *
555  * NOTES
556  *  Set SystemName to NULL to open the local Policy object.
557  */
558 NTSTATUS WINAPI LsaOpenPolicy(
559     IN PLSA_UNICODE_STRING SystemName,
560     IN PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
561     IN ACCESS_MASK DesiredAccess,
562     IN OUT PLSA_HANDLE PolicyHandle)
563 {
564     FIXME("(%s,%p,0x%08x,%p) stub\n",
565           SystemName?debugstr_w(SystemName->Buffer):"(null)",
566           ObjectAttributes, DesiredAccess, PolicyHandle);
567
568     ADVAPI_ForceLocalComputer(SystemName ? SystemName->Buffer : NULL,
569                               STATUS_ACCESS_VIOLATION);
570     dumpLsaAttributes(ObjectAttributes);
571
572     if(PolicyHandle) *PolicyHandle = (LSA_HANDLE)0xcafe;
573     return STATUS_SUCCESS;
574 }
575
576 /******************************************************************************
577  * LsaOpenTrustedDomainByName [ADVAPI32.@]
578  *
579  */
580 NTSTATUS WINAPI LsaOpenTrustedDomainByName(
581     LSA_HANDLE policy,
582     PLSA_UNICODE_STRING name,
583     ACCESS_MASK access,
584     PLSA_HANDLE handle)
585 {
586     FIXME("(%p,%p,0x%08x,%p) stub\n", policy, name, access, handle);
587     return STATUS_OBJECT_NAME_NOT_FOUND;
588 }
589
590 /******************************************************************************
591  * LsaQueryInformationPolicy [ADVAPI32.@]
592  *
593  * Returns information about a Policy object.
594  *
595  * PARAMS
596  *  PolicyHandle     [I] Handle to a Policy object.
597  *  InformationClass [I] Type of information to retrieve.
598  *  Buffer           [O] Pointer to the requested information.
599  *
600  * RETURNS
601  *  Success: STATUS_SUCCESS.
602  *  Failure: NTSTATUS code.
603  */
604 NTSTATUS WINAPI LsaQueryInformationPolicy(
605     IN LSA_HANDLE PolicyHandle,
606     IN POLICY_INFORMATION_CLASS InformationClass,
607     OUT PVOID *Buffer)
608 {
609     TRACE("(%p,0x%08x,%p)\n", PolicyHandle, InformationClass, Buffer);
610
611     if(!Buffer) return STATUS_INVALID_PARAMETER;
612     switch (InformationClass)
613     {
614         case PolicyAuditEventsInformation: /* 2 */
615         {
616             PPOLICY_AUDIT_EVENTS_INFO p = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
617                                                     sizeof(POLICY_AUDIT_EVENTS_INFO));
618             p->AuditingMode = FALSE; /* no auditing */
619             *Buffer = p;
620         }
621         break;
622         case PolicyPrimaryDomainInformation: /* 3 */
623         {
624             /* Only the domain name is valid for the local computer.
625              * All other fields are zero.
626              */
627             PPOLICY_PRIMARY_DOMAIN_INFO pinfo;
628
629             pinfo = ADVAPI_GetDomainName(sizeof(*pinfo), offsetof(POLICY_PRIMARY_DOMAIN_INFO, Name));
630
631             TRACE("setting domain to %s\n", debugstr_w(pinfo->Name.Buffer));
632
633             *Buffer = pinfo;
634         }
635         break;
636         case PolicyAccountDomainInformation: /* 5 */
637         {
638             struct di
639             {
640                 POLICY_ACCOUNT_DOMAIN_INFO info;
641                 SID sid;
642                 DWORD padding[3];
643                 WCHAR domain[MAX_COMPUTERNAME_LENGTH + 1];
644             };
645
646             DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
647             struct di * xdi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*xdi));
648
649             xdi->info.DomainName.MaximumLength = dwSize * sizeof(WCHAR);
650             xdi->info.DomainName.Buffer = xdi->domain;
651             if (GetComputerNameW(xdi->info.DomainName.Buffer, &dwSize))
652                 xdi->info.DomainName.Length = dwSize * sizeof(WCHAR);
653
654             TRACE("setting name to %s\n", debugstr_w(xdi->info.DomainName.Buffer));
655
656             xdi->info.DomainSid = &xdi->sid;
657
658             if (!ADVAPI_GetComputerSid(&xdi->sid))
659             {
660                 HeapFree(GetProcessHeap(), 0, xdi);
661
662                 WARN("Computer SID not found\n");
663
664                 return STATUS_UNSUCCESSFUL;
665             }
666
667             TRACE("setting SID to %s\n", debugstr_sid(&xdi->sid));
668
669             *Buffer = xdi;
670         }
671         break;
672         case  PolicyDnsDomainInformation:       /* 12 (0xc) */
673         {
674             /* Only the domain name is valid for the local computer.
675              * All other fields are zero.
676              */
677             PPOLICY_DNS_DOMAIN_INFO pinfo;
678
679             pinfo = ADVAPI_GetDomainName(sizeof(*pinfo), offsetof(POLICY_DNS_DOMAIN_INFO, Name));
680
681             TRACE("setting domain to %s\n", debugstr_w(pinfo->Name.Buffer));
682
683             *Buffer = pinfo;
684         }
685         break;
686         case  PolicyAuditLogInformation:
687         case  PolicyPdAccountInformation:
688         case  PolicyLsaServerRoleInformation:
689         case  PolicyReplicaSourceInformation:
690         case  PolicyDefaultQuotaInformation:
691         case  PolicyModificationInformation:
692         case  PolicyAuditFullSetInformation:
693         case  PolicyAuditFullQueryInformation:
694         {
695             FIXME("category %d not implemented\n", InformationClass);
696             return STATUS_UNSUCCESSFUL;
697         }
698     }
699     return STATUS_SUCCESS;
700 }
701
702 /******************************************************************************
703  * LsaQueryTrustedDomainInfo [ADVAPI32.@]
704  *
705  */
706 NTSTATUS WINAPI LsaQueryTrustedDomainInfo(
707     LSA_HANDLE policy,
708     PSID sid,
709     TRUSTED_INFORMATION_CLASS class,
710     PVOID *buffer)
711 {
712     FIXME("(%p,%p,%d,%p) stub\n", policy, sid, class, buffer);
713     return STATUS_OBJECT_NAME_NOT_FOUND;
714 }
715
716 /******************************************************************************
717  * LsaQueryTrustedDomainInfoByName [ADVAPI32.@]
718  *
719  */
720 NTSTATUS WINAPI LsaQueryTrustedDomainInfoByName(
721     LSA_HANDLE policy,
722     PLSA_UNICODE_STRING name,
723     TRUSTED_INFORMATION_CLASS class,
724     PVOID *buffer)
725 {
726     FIXME("(%p,%p,%d,%p) stub\n", policy, name, class, buffer);
727     return STATUS_OBJECT_NAME_NOT_FOUND;
728 }
729
730 /******************************************************************************
731  * LsaRegisterPolicyChangeNotification [ADVAPI32.@]
732  *
733  */
734 NTSTATUS WINAPI LsaRegisterPolicyChangeNotification(
735     POLICY_NOTIFICATION_INFORMATION_CLASS class,
736     HANDLE event)
737 {
738     FIXME("(%d,%p) stub\n", class, event);
739     return STATUS_UNSUCCESSFUL;
740 }
741
742 /******************************************************************************
743  * LsaRemoveAccountRights [ADVAPI32.@]
744  *
745  */
746 NTSTATUS WINAPI LsaRemoveAccountRights(
747     LSA_HANDLE policy,
748     PSID sid,
749     BOOLEAN all,
750     PLSA_UNICODE_STRING rights,
751     ULONG count)
752 {
753     FIXME("(%p,%p,%d,%p,0x%08x) stub\n", policy, sid, all, rights, count);
754     return STATUS_SUCCESS;
755 }
756
757 /******************************************************************************
758  * LsaRetrievePrivateData [ADVAPI32.@]
759  *
760  * Retrieves data stored by LsaStorePrivateData.
761  *
762  * PARAMS
763  *  PolicyHandle [I] Handle to a Policy object.
764  *  KeyName      [I] Name of the key where the data is stored.
765  *  PrivateData  [O] Pointer to the private data.
766  *
767  * RETURNS
768  *  Success: STATUS_SUCCESS.
769  *  Failure: STATUS_OBJECT_NAME_NOT_FOUND or NTSTATUS code.
770  */
771 NTSTATUS WINAPI LsaRetrievePrivateData(
772     IN LSA_HANDLE PolicyHandle,
773     IN PLSA_UNICODE_STRING KeyName,
774     OUT PLSA_UNICODE_STRING* PrivateData)
775 {
776     FIXME("(%p,%p,%p) stub\n", PolicyHandle, KeyName, PrivateData);
777     return STATUS_OBJECT_NAME_NOT_FOUND;
778 }
779
780 /******************************************************************************
781  * LsaSetInformationPolicy [ADVAPI32.@]
782  *
783  * Modifies information in a Policy object.
784  *
785  * PARAMS
786  *  PolicyHandle     [I] Handle to a Policy object.
787  *  InformationClass [I] Type of information to set.
788  *  Buffer           [I] Pointer to the information to set.
789  *
790  * RETURNS
791  *  Success: STATUS_SUCCESS.
792  *  Failure: NTSTATUS code.
793  */
794 NTSTATUS WINAPI LsaSetInformationPolicy(
795     IN LSA_HANDLE PolicyHandle,
796     IN POLICY_INFORMATION_CLASS InformationClass,
797     IN PVOID Buffer)
798 {
799     FIXME("(%p,0x%08x,%p) stub\n", PolicyHandle, InformationClass, Buffer);
800
801     return STATUS_UNSUCCESSFUL;
802 }
803
804 /******************************************************************************
805  * LsaSetSecret [ADVAPI32.@]
806  *
807  * Set old and new values on a secret handle
808  *
809  * PARAMS
810  *  SecretHandle          [I] Handle to a secret object.
811  *  EncryptedCurrentValue [I] Pointer to encrypted new value, can be NULL
812  *  EncryptedOldValue     [I] Pointer to encrypted old value, can be NULL
813  *
814  * RETURNS
815  *  Success: STATUS_SUCCESS
816  *  Failure: NTSTATUS code.
817  */
818 NTSTATUS WINAPI LsaSetSecret(
819     IN LSA_HANDLE SecretHandle,
820     IN PLSA_UNICODE_STRING EncryptedCurrentValue,
821     IN PLSA_UNICODE_STRING EncryptedOldValue)
822 {
823     FIXME("(%p,%p,%p) stub\n", SecretHandle, EncryptedCurrentValue,
824             EncryptedOldValue);
825     return STATUS_SUCCESS;
826 }
827
828 /******************************************************************************
829  * LsaSetTrustedDomainInfoByName [ADVAPI32.@]
830  *
831  */
832 NTSTATUS WINAPI LsaSetTrustedDomainInfoByName(
833     LSA_HANDLE policy,
834     PLSA_UNICODE_STRING name,
835     TRUSTED_INFORMATION_CLASS class,
836     PVOID buffer)
837 {
838     FIXME("(%p,%p,%d,%p) stub\n", policy, name, class, buffer);
839     return STATUS_SUCCESS;
840 }
841
842 /******************************************************************************
843  * LsaSetTrustedDomainInformation [ADVAPI32.@]
844  *
845  */
846 NTSTATUS WINAPI LsaSetTrustedDomainInformation(
847     LSA_HANDLE policy,
848     PSID sid,
849     TRUSTED_INFORMATION_CLASS class,
850     PVOID buffer)
851 {
852     FIXME("(%p,%p,%d,%p) stub\n", policy, sid, class, buffer);
853     return STATUS_SUCCESS;
854 }
855
856 /******************************************************************************
857  * LsaStorePrivateData [ADVAPI32.@]
858  *
859  * Stores or deletes a Policy object's data under the specified reg key.
860  *
861  * PARAMS
862  *  PolicyHandle [I] Handle to a Policy object.
863  *  KeyName      [I] Name of the key where the data will be stored.
864  *  PrivateData  [O] Pointer to the private data.
865  *
866  * RETURNS
867  *  Success: STATUS_SUCCESS.
868  *  Failure: STATUS_OBJECT_NAME_NOT_FOUND or NTSTATUS code.
869  */
870 NTSTATUS WINAPI LsaStorePrivateData(
871     IN LSA_HANDLE PolicyHandle,
872     IN PLSA_UNICODE_STRING KeyName,
873     IN PLSA_UNICODE_STRING PrivateData)
874 {
875     FIXME("(%p,%p,%p) stub\n", PolicyHandle, KeyName, PrivateData);
876     return STATUS_OBJECT_NAME_NOT_FOUND;
877 }
878
879 /******************************************************************************
880  * LsaUnregisterPolicyChangeNotification [ADVAPI32.@]
881  *
882  */
883 NTSTATUS WINAPI LsaUnregisterPolicyChangeNotification(
884     POLICY_NOTIFICATION_INFORMATION_CLASS class,
885     HANDLE event)
886 {
887     FIXME("(%d,%p) stub\n", class, event);
888     return STATUS_SUCCESS;
889 }