rsaenh: Fix the case when CPGetHashParam should return the size of the HASHVAL.
[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 "ntsecapi.h"
33
34 #include "wine/debug.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
37
38 #define ADVAPI_ForceLocalComputer(ServerName, FailureCode) \
39     if (!ADVAPI_IsLocalComputer(ServerName)) \
40 { \
41         FIXME("Action Implemented for local computer only. " \
42               "Requested for server %s\n", debugstr_w(ServerName)); \
43         return FailureCode; \
44 }
45
46 static void dumpLsaAttributes(PLSA_OBJECT_ATTRIBUTES oa)
47 {
48     if (oa)
49     {
50         TRACE("\n\tlength=%lu, rootdir=%p, objectname=%s\n\tattr=0x%08lx, sid=%p qos=%p\n",
51               oa->Length, oa->RootDirectory,
52               oa->ObjectName?debugstr_w(oa->ObjectName->Buffer):"null",
53               oa->Attributes, oa->SecurityDescriptor, oa->SecurityQualityOfService);
54     }
55 }
56
57 /************************************************************
58  * ADVAPI_IsLocalComputer
59  *
60  * Checks whether the server name indicates local machine.
61  */
62 static BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
63 {
64     DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
65     BOOL Result;
66     LPWSTR buf;
67
68     if (!ServerName || !ServerName[0])
69         return TRUE;
70
71     buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
72     Result = GetComputerNameW(buf,  &dwSize);
73     if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
74         ServerName += 2;
75     Result = Result && !lstrcmpW(ServerName, buf);
76     HeapFree(GetProcessHeap(), 0, buf);
77
78     return Result;
79 }
80
81 /******************************************************************************
82  * LsaAddAccountRights [ADVAPI32.@]
83  *
84  */
85 NTSTATUS WINAPI LsaAddAccountRights(
86     LSA_HANDLE policy,
87     PSID sid,
88     PLSA_UNICODE_STRING rights,
89     ULONG count)
90 {
91     FIXME("(%p,%p,%p,0x%08lx) stub\n", policy, sid, rights, count);
92     return STATUS_OBJECT_NAME_NOT_FOUND;
93 }
94
95 /******************************************************************************
96  * LsaClose [ADVAPI32.@]
97  *
98  * Closes a handle to a Policy or TrustedDomain.
99  *
100  * PARAMS
101  *  ObjectHandle [I] Handle to a Policy or TrustedDomain.
102  *
103  * RETURNS
104  *  Success: STATUS_SUCCESS.
105  *  Failure: NTSTATUS code.
106  */
107 NTSTATUS WINAPI LsaClose(IN LSA_HANDLE ObjectHandle)
108 {
109     FIXME("(%p) stub\n", ObjectHandle);
110     return STATUS_SUCCESS;
111 }
112
113 /******************************************************************************
114  * LsaCreateTrustedDomainEx [ADVAPI32.@]
115  *
116  */
117 NTSTATUS WINAPI LsaCreateTrustedDomainEx(
118     LSA_HANDLE policy,
119     PTRUSTED_DOMAIN_INFORMATION_EX domain_info,
120     PTRUSTED_DOMAIN_AUTH_INFORMATION auth_info,
121     ACCESS_MASK access,
122     PLSA_HANDLE domain)
123 {
124     FIXME("(%p,%p,%p,0x%08lx,%p) stub\n", policy, domain_info, auth_info,
125           access, domain);
126     return STATUS_SUCCESS;
127 }
128
129 /******************************************************************************
130  * LsaDeleteTrustedDomain [ADVAPI32.@]
131  *
132  */
133 NTSTATUS WINAPI LsaDeleteTrustedDomain(LSA_HANDLE policy, PSID sid)
134 {
135     FIXME("(%p,%p) stub\n", policy, sid);
136     return STATUS_SUCCESS;
137 }
138
139 /******************************************************************************
140  * LsaEnumerateAccountRights [ADVAPI32.@]
141  *
142  */
143 NTSTATUS WINAPI LsaEnumerateAccountRights(
144     LSA_HANDLE policy,
145     PSID sid,
146     PLSA_UNICODE_STRING *rights,
147     PULONG count)
148 {
149     FIXME("(%p,%p,%p,%p) stub\n", policy, sid, rights, count);
150     return STATUS_OBJECT_NAME_NOT_FOUND;
151 }
152
153 /******************************************************************************
154  * LsaEnumerateAccountsWithUserRight [ADVAPI32.@]
155  *
156  */
157 NTSTATUS WINAPI LsaEnumerateAccountsWithUserRight(
158     LSA_HANDLE policy,
159     PLSA_UNICODE_STRING rights,
160     PVOID *buffer,
161     PULONG count)
162 {
163     FIXME("(%p,%p,%p,%p) stub\n", policy, rights, buffer, count);
164     return STATUS_NO_MORE_ENTRIES;
165 }
166
167 /******************************************************************************
168  * LsaEnumerateTrustedDomains [ADVAPI32.@]
169  *
170  * Returns the names and SIDs of trusted domains.
171  *
172  * PARAMS
173  *  PolicyHandle          [I] Handle to a Policy object.
174  *  EnumerationContext    [I] Pointer to an enumeration handle.
175  *  Buffer                [O] Contains the names and SIDs of trusted domains.
176  *  PreferredMaximumLength[I] Preferred maximum size in bytes of Buffer.
177  *  CountReturned         [O] Number of elements in Buffer.
178  *
179  * RETURNS
180  *  Success: STATUS_SUCCESS,
181  *           STATUS_MORE_ENTRIES,
182  *           STATUS_NO_MORE_ENTRIES
183  *  Failure: NTSTATUS code.
184  *
185  * NOTES
186  *  LsaEnumerateTrustedDomains can be called multiple times to enumerate
187  *  all trusted domains.
188  */
189 NTSTATUS WINAPI LsaEnumerateTrustedDomains(
190     IN LSA_HANDLE PolicyHandle,
191     IN PLSA_ENUMERATION_HANDLE EnumerationContext,
192     OUT PVOID* Buffer,
193     IN ULONG PreferredMaximumLength,
194     OUT PULONG CountReturned)
195 {
196     FIXME("(%p,%p,%p,0x%08lx,%p) stub\n", PolicyHandle, EnumerationContext,
197           Buffer, PreferredMaximumLength, CountReturned);
198
199     if (CountReturned) *CountReturned = 0;
200     return STATUS_SUCCESS;
201 }
202
203 /******************************************************************************
204  * LsaEnumerateTrustedDomainsEx [ADVAPI32.@]
205  *
206  */
207 NTSTATUS WINAPI LsaEnumerateTrustedDomainsEx(
208     LSA_HANDLE policy,
209     PLSA_ENUMERATION_HANDLE context,
210     PVOID *buffer,
211     ULONG length,
212     PULONG count)
213 {
214     FIXME("(%p,%p,%p,0x%08lx,%p) stub\n", policy, context, buffer, length, count);
215
216     if (count) *count = 0;
217     return STATUS_SUCCESS;
218 }
219
220 /******************************************************************************
221  * LsaFreeMemory [ADVAPI32.@]
222  *
223  * Frees memory allocated by a LSA function.
224  *
225  * PARAMS
226  *  Buffer [I] Memory buffer to free.
227  *
228  * RETURNS
229  *  Success: STATUS_SUCCESS.
230  *  Failure: NTSTATUS code.
231  */
232 NTSTATUS WINAPI LsaFreeMemory(IN PVOID Buffer)
233 {
234     TRACE("(%p)\n", Buffer);
235     return HeapFree(GetProcessHeap(), 0, Buffer);
236 }
237
238 /******************************************************************************
239  * LsaLookupNames [ADVAPI32.@]
240  *
241  * Returns the SIDs of an array of user, group, or local group names.
242  *
243  * PARAMS
244  *  PolicyHandle      [I] Handle to a Policy object.
245  *  Count             [I] Number of names in Names.
246  *  Names             [I] Array of names to lookup.
247  *  ReferencedDomains [O] Array of domains where the names were found.
248  *  Sids              [O] Array of SIDs corresponding to Names.
249  *
250  * RETURNS
251  *  Success: STATUS_SUCCESS,
252  *           STATUS_SOME_NOT_MAPPED
253  *  Failure: STATUS_NONE_MAPPED or NTSTATUS code.
254  */
255 NTSTATUS WINAPI LsaLookupNames(
256     IN LSA_HANDLE PolicyHandle,
257     IN ULONG Count,
258     IN PLSA_UNICODE_STRING Names,
259     OUT PLSA_REFERENCED_DOMAIN_LIST* ReferencedDomains,
260     OUT PLSA_TRANSLATED_SID* Sids)
261 {
262     FIXME("(%p,0x%08lx,%p,%p,%p) stub\n", PolicyHandle, Count, Names,
263           ReferencedDomains, Sids);
264
265     return STATUS_NONE_MAPPED;
266 }
267
268 /******************************************************************************
269  * LsaLookupNames2 [ADVAPI32.@]
270  *
271  */
272 NTSTATUS WINAPI LsaLookupNames2(
273     LSA_HANDLE policy,
274     ULONG flags,
275     ULONG count,
276     PLSA_UNICODE_STRING names,
277     PLSA_REFERENCED_DOMAIN_LIST *domains,
278     PLSA_TRANSLATED_SID2 *sids)
279 {
280     FIXME("(%p,0x%08lx,0x%08lx,%p,%p,%p) stub\n", policy, flags, count, names, domains, sids);
281     return STATUS_NONE_MAPPED;
282 }
283
284 /******************************************************************************
285  * LsaLookupSids [ADVAPI32.@]
286  *
287  * Looks up the names that correspond to an array of SIDs.
288  *
289  * PARAMS
290  *  PolicyHandle      [I] Handle to a Policy object.
291  *  Count             [I] Number of SIDs in the Sids array.
292  *  Sids              [I] Array of SIDs to lookup.
293  *  ReferencedDomains [O] Array of domains where the sids were found.
294  *  Names             [O] Array of names corresponding to Sids.
295  *
296  * RETURNS
297  *  Success: STATUS_SUCCESS,
298  *           STATUS_SOME_NOT_MAPPED
299  *  Failure: STATUS_NONE_MAPPED or NTSTATUS code.
300  */
301 NTSTATUS WINAPI LsaLookupSids(
302     IN LSA_HANDLE PolicyHandle,
303     IN ULONG Count,
304     IN PSID *Sids,
305     OUT PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains,
306     OUT PLSA_TRANSLATED_NAME *Names )
307 {
308     FIXME("(%p,%lu,%p,%p,%p) stub\n", PolicyHandle, Count, Sids,
309           ReferencedDomains, Names);
310
311     return STATUS_NONE_MAPPED;
312 }
313
314 /******************************************************************************
315  * LsaNtStatusToWinError [ADVAPI32.@]
316  *
317  * Converts an LSA NTSTATUS code to a Windows error code.
318  *
319  * PARAMS
320  *  Status [I] NTSTATUS code.
321  *
322  * RETURNS
323  *  Success: Corresponding Windows error code.
324  *  Failure: ERROR_MR_MID_NOT_FOUND.
325  */
326 ULONG WINAPI LsaNtStatusToWinError(NTSTATUS Status)
327 {
328     return RtlNtStatusToDosError(Status);
329 }
330
331 /******************************************************************************
332  * LsaOpenPolicy [ADVAPI32.@]
333  *
334  * Opens a handle to the Policy object on a local or remote system.
335  *
336  * PARAMS
337  *  SystemName       [I] Name of the target system.
338  *  ObjectAttributes [I] Connection attributes.
339  *  DesiredAccess    [I] Requested access rights.
340  *  PolicyHandle     [I/O] Handle to the Policy object.
341  *
342  * RETURNS
343  *  Success: STATUS_SUCCESS.
344  *  Failure: NTSTATUS code.
345  *
346  * NOTES
347  *  Set SystemName to NULL to open the local Policy object.
348  */
349 NTSTATUS WINAPI LsaOpenPolicy(
350     IN PLSA_UNICODE_STRING SystemName,
351     IN PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
352     IN ACCESS_MASK DesiredAccess,
353     IN OUT PLSA_HANDLE PolicyHandle)
354 {
355     FIXME("(%s,%p,0x%08lx,%p) stub\n",
356           SystemName?debugstr_w(SystemName->Buffer):"(null)",
357           ObjectAttributes, DesiredAccess, PolicyHandle);
358
359     ADVAPI_ForceLocalComputer(SystemName ? SystemName->Buffer : NULL,
360                               STATUS_ACCESS_VIOLATION);
361     dumpLsaAttributes(ObjectAttributes);
362
363     if(PolicyHandle) *PolicyHandle = (LSA_HANDLE)0xcafe;
364     return STATUS_SUCCESS;
365 }
366
367 /******************************************************************************
368  * LsaOpenTrustedDomainByName [ADVAPI32.@]
369  *
370  */
371 NTSTATUS WINAPI LsaOpenTrustedDomainByName(
372     LSA_HANDLE policy,
373     PLSA_UNICODE_STRING name,
374     ACCESS_MASK access,
375     PLSA_HANDLE handle)
376 {
377     FIXME("(%p,%p,0x%08lx,%p) stub\n", policy, name, access, handle);
378     return STATUS_OBJECT_NAME_NOT_FOUND;
379 }
380
381 /******************************************************************************
382  * LsaQueryInformationPolicy [ADVAPI32.@]
383  *
384  * Returns information about a Policy object.
385  *
386  * PARAMS
387  *  PolicyHandle     [I] Handle to a Policy object.
388  *  InformationClass [I] Type of information to retrieve.
389  *  Buffer           [O] Pointer to the requested information.
390  *
391  * RETURNS
392  *  Success: STATUS_SUCCESS.
393  *  Failure: NTSTATUS code.
394  */
395 NTSTATUS WINAPI LsaQueryInformationPolicy(
396     IN LSA_HANDLE PolicyHandle,
397     IN POLICY_INFORMATION_CLASS InformationClass,
398     OUT PVOID *Buffer)
399 {
400     FIXME("(%p,0x%08x,%p) stub\n", PolicyHandle, InformationClass, Buffer);
401
402     if(!Buffer) return STATUS_INVALID_PARAMETER;
403     switch (InformationClass)
404     {
405         case PolicyAuditEventsInformation: /* 2 */
406         {
407             PPOLICY_AUDIT_EVENTS_INFO p = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
408                                                     sizeof(POLICY_AUDIT_EVENTS_INFO));
409             p->AuditingMode = FALSE; /* no auditing */
410             *Buffer = p;
411         }
412         break;
413         case PolicyPrimaryDomainInformation: /* 3 */
414         case PolicyAccountDomainInformation: /* 5 */
415         {
416             struct di
417             {
418                 POLICY_PRIMARY_DOMAIN_INFO ppdi;
419                 SID sid;
420             };
421
422             SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
423
424             struct di * xdi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*xdi));
425             HKEY key;
426             BOOL useDefault = TRUE;
427             LONG ret;
428
429             if ((ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
430                  "System\\CurrentControlSet\\Services\\VxD\\VNETSUP", 0,
431                  KEY_READ, &key)) == ERROR_SUCCESS)
432             {
433                 DWORD size = 0;
434                 static const WCHAR wg[] = { 'W','o','r','k','g','r','o','u','p',0 };
435
436                 ret = RegQueryValueExW(key, wg, NULL, NULL, NULL, &size);
437                 if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
438                 {
439                     xdi->ppdi.Name.Buffer = HeapAlloc(GetProcessHeap(),
440                                                       HEAP_ZERO_MEMORY, size);
441
442                     if ((ret = RegQueryValueExW(key, wg, NULL, NULL,
443                          (LPBYTE)xdi->ppdi.Name.Buffer, &size)) == ERROR_SUCCESS)
444                     {
445                         xdi->ppdi.Name.Length = (USHORT)size;
446                         useDefault = FALSE;
447                     }
448                     else
449                     {
450                         HeapFree(GetProcessHeap(), 0, xdi->ppdi.Name.Buffer);
451                         xdi->ppdi.Name.Buffer = NULL;
452                     }
453                 }
454                 RegCloseKey(key);
455             }
456             if (useDefault)
457                 RtlCreateUnicodeStringFromAsciiz(&(xdi->ppdi.Name), "DOMAIN");
458
459             TRACE("setting domain to %s\n", debugstr_w(xdi->ppdi.Name.Buffer));
460
461             xdi->ppdi.Sid = &(xdi->sid);
462             xdi->sid.Revision = SID_REVISION;
463             xdi->sid.SubAuthorityCount = 1;
464             xdi->sid.IdentifierAuthority = localSidAuthority;
465             xdi->sid.SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
466             *Buffer = xdi;
467         }
468         break;
469         case  PolicyAuditLogInformation:
470         case  PolicyPdAccountInformation:
471         case  PolicyLsaServerRoleInformation:
472         case  PolicyReplicaSourceInformation:
473         case  PolicyDefaultQuotaInformation:
474         case  PolicyModificationInformation:
475         case  PolicyAuditFullSetInformation:
476         case  PolicyAuditFullQueryInformation:
477         case  PolicyDnsDomainInformation:
478         {
479             FIXME("category not implemented\n");
480             return STATUS_UNSUCCESSFUL;
481         }
482     }
483     return STATUS_SUCCESS;
484 }
485
486 /******************************************************************************
487  * LsaQueryTrustedDomainInfo [ADVAPI32.@]
488  *
489  */
490 NTSTATUS WINAPI LsaQueryTrustedDomainInfo(
491     LSA_HANDLE policy,
492     PSID sid,
493     TRUSTED_INFORMATION_CLASS class,
494     PVOID *buffer)
495 {
496     FIXME("(%p,%p,%d,%p) stub\n", policy, sid, class, buffer);
497     return STATUS_OBJECT_NAME_NOT_FOUND;
498 }
499
500 /******************************************************************************
501  * LsaQueryTrustedDomainInfoByName [ADVAPI32.@]
502  *
503  */
504 NTSTATUS WINAPI LsaQueryTrustedDomainInfoByName(
505     LSA_HANDLE policy,
506     PLSA_UNICODE_STRING name,
507     TRUSTED_INFORMATION_CLASS class,
508     PVOID *buffer)
509 {
510     FIXME("(%p,%p,%d,%p) stub\n", policy, name, class, buffer);
511     return STATUS_OBJECT_NAME_NOT_FOUND;
512 }
513
514 /******************************************************************************
515  * LsaRegisterPolicyChangeNotification [ADVAPI32.@]
516  *
517  */
518 NTSTATUS WINAPI LsaRegisterPolicyChangeNotification(
519     POLICY_NOTIFICATION_INFORMATION_CLASS class,
520     HANDLE event)
521 {
522     FIXME("(%d,%p) stub\n", class, event);
523     return STATUS_UNSUCCESSFUL;
524 }
525
526 /******************************************************************************
527  * LsaRemoveAccountRights [ADVAPI32.@]
528  *
529  */
530 NTSTATUS WINAPI LsaRemoveAccountRights(
531     LSA_HANDLE policy,
532     PSID sid,
533     BOOLEAN all,
534     PLSA_UNICODE_STRING rights,
535     ULONG count)
536 {
537     FIXME("(%p,%p,%d,%p,0x%08lx) stub\n", policy, sid, all, rights, count);
538     return STATUS_SUCCESS;
539 }
540
541 /******************************************************************************
542  * LsaRetrievePrivateData [ADVAPI32.@]
543  *
544  * Retrieves data stored by LsaStorePrivateData.
545  *
546  * PARAMS
547  *  PolicyHandle [I] Handle to a Policy object.
548  *  KeyName      [I] Name of the key where the data is stored.
549  *  PrivateData  [O] Pointer to the private data.
550  *
551  * RETURNS
552  *  Success: STATUS_SUCCESS.
553  *  Failure: STATUS_OBJECT_NAME_NOT_FOUND or NTSTATUS code.
554  */
555 NTSTATUS WINAPI LsaRetrievePrivateData(
556     IN LSA_HANDLE PolicyHandle,
557     IN PLSA_UNICODE_STRING KeyName,
558     OUT PLSA_UNICODE_STRING* PrivateData)
559 {
560     FIXME("(%p,%p,%p) stub\n", PolicyHandle, KeyName, PrivateData);
561     return STATUS_OBJECT_NAME_NOT_FOUND;
562 }
563
564 /******************************************************************************
565  * LsaSetInformationPolicy [ADVAPI32.@]
566  *
567  * Modifies information in a Policy object.
568  *
569  * PARAMS
570  *  PolicyHandle     [I] Handle to a Policy object.
571  *  InformationClass [I] Type of information to set.
572  *  Buffer           [I] Pointer to the information to set.
573  *
574  * RETURNS
575  *  Success: STATUS_SUCCESS.
576  *  Failure: NTSTATUS code.
577  */
578 NTSTATUS WINAPI LsaSetInformationPolicy(
579     IN LSA_HANDLE PolicyHandle,
580     IN POLICY_INFORMATION_CLASS InformationClass,
581     IN PVOID Buffer)
582 {
583     FIXME("(%p,0x%08x,%p) stub\n", PolicyHandle, InformationClass, Buffer);
584
585     return STATUS_UNSUCCESSFUL;
586 }
587
588 /******************************************************************************
589  * LsaSetTrustedDomainInfoByName [ADVAPI32.@]
590  *
591  */
592 NTSTATUS WINAPI LsaSetTrustedDomainInfoByName(
593     LSA_HANDLE policy,
594     PLSA_UNICODE_STRING name,
595     TRUSTED_INFORMATION_CLASS class,
596     PVOID buffer)
597 {
598     FIXME("(%p,%p,%d,%p) stub\n", policy, name, class, buffer);
599     return STATUS_SUCCESS;
600 }
601
602 /******************************************************************************
603  * LsaSetTrustedDomainInformation [ADVAPI32.@]
604  *
605  */
606 NTSTATUS WINAPI LsaSetTrustedDomainInformation(
607     LSA_HANDLE policy,
608     PSID sid,
609     TRUSTED_INFORMATION_CLASS class,
610     PVOID buffer)
611 {
612     FIXME("(%p,%p,%d,%p) stub\n", policy, sid, class, buffer);
613     return STATUS_SUCCESS;
614 }
615
616 /******************************************************************************
617  * LsaStorePrivateData [ADVAPI32.@]
618  *
619  * Stores or deletes a Policy object's data under the specified reg key.
620  *
621  * PARAMS
622  *  PolicyHandle [I] Handle to a Policy object.
623  *  KeyName      [I] Name of the key where the data will be stored.
624  *  PrivateData  [O] Pointer to the private data.
625  *
626  * RETURNS
627  *  Success: STATUS_SUCCESS.
628  *  Failure: STATUS_OBJECT_NAME_NOT_FOUND or NTSTATUS code.
629  */
630 NTSTATUS WINAPI LsaStorePrivateData(
631     IN LSA_HANDLE PolicyHandle,
632     IN PLSA_UNICODE_STRING KeyName,
633     IN PLSA_UNICODE_STRING PrivateData)
634 {
635     FIXME("(%p,%p,%p) stub\n", PolicyHandle, KeyName, PrivateData);
636     return STATUS_OBJECT_NAME_NOT_FOUND;
637 }
638
639 /******************************************************************************
640  * LsaUnregisterPolicyChangeNotification [ADVAPI32.@]
641  *
642  */
643 NTSTATUS WINAPI LsaUnregisterPolicyChangeNotification(
644     POLICY_NOTIFICATION_INFORMATION_CLASS class,
645     HANDLE event)
646 {
647     FIXME("(%d,%p) stub\n", class, event);
648     return STATUS_SUCCESS;
649 }