Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/advapi32/lsa.c
4387 views
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 "sddl.h"
33
#include "advapi32_misc.h"
34
35
#include "wine/debug.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 LPCSTR debugstr_us( const UNICODE_STRING *us )
48
{
49
if (!us) return "(null)";
50
return debugstr_wn(us->Buffer, us->Length / sizeof(WCHAR));
51
}
52
53
static void dumpLsaAttributes(const LSA_OBJECT_ATTRIBUTES *oa)
54
{
55
if (oa)
56
{
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);
62
}
63
}
64
65
static const char *debugstr_InformationClass( POLICY_INFORMATION_CLASS class )
66
{
67
static const char * const names[] =
68
{
69
NULL,
70
"PolicyAuditLogInformation",
71
"PolicyAuditEventsInformation",
72
"PolicyPrimaryDomainInformation",
73
"PolicyPdAccountInformation",
74
"PolicyAccountDomainInformation",
75
"PolicyLsaServerRoleInformation",
76
"PolicyReplicaSourceInformation",
77
"PolicyDefaultQuotaInformation",
78
"PolicyModificationInformation",
79
"PolicyAuditFullSetInformation",
80
"PolicyAuditFullQueryInformation",
81
"PolicyDnsDomainInformation",
82
"PolicyDnsDomainInformationInt",
83
"PolicyLocalAccountDomainInformation",
84
"PolicyMachineAccountInformation",
85
"PolicyMachineAccountInformation2",
86
};
87
88
if (class < ARRAY_SIZE(names) && names[class]) return names[class];
89
return wine_dbg_sprintf( "%u", class );
90
}
91
92
static void* ADVAPI_GetDomainName(unsigned sz, unsigned ofs)
93
{
94
HKEY key;
95
LONG ret;
96
BYTE* ptr = NULL;
97
UNICODE_STRING* ustr;
98
99
ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Services\\VxD\\VNETSUP", 0, KEY_READ, &key);
100
if (ret == ERROR_SUCCESS)
101
{
102
DWORD size = 0;
103
ret = RegQueryValueExW(key, L"Workgroup", NULL, NULL, NULL, &size);
104
if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
105
{
106
ptr = calloc(1, sz + size);
107
if (!ptr) return NULL;
108
ustr = (UNICODE_STRING*)(ptr + ofs);
109
ustr->MaximumLength = size;
110
ustr->Buffer = (WCHAR*)(ptr + sz);
111
ret = RegQueryValueExW(key, L"Workgroup", NULL, NULL, (LPBYTE)ustr->Buffer, &size);
112
if (ret != ERROR_SUCCESS)
113
{
114
free(ptr);
115
ptr = NULL;
116
}
117
else ustr->Length = size - sizeof(WCHAR);
118
}
119
RegCloseKey(key);
120
}
121
if (!ptr)
122
{
123
ptr = calloc(1, sz + sizeof(L"DOMAIN"));
124
if (!ptr) return NULL;
125
ustr = (UNICODE_STRING*)(ptr + ofs);
126
ustr->MaximumLength = sizeof(L"DOMAIN");
127
ustr->Buffer = (WCHAR*)(ptr + sz);
128
ustr->Length = sizeof(L"DOMAIN") - sizeof(WCHAR);
129
memcpy(ustr->Buffer, L"DOMAIN", sizeof(L"DOMAIN"));
130
}
131
return ptr;
132
}
133
134
/******************************************************************************
135
* LsaGetUserName [ADVAPI32.@]
136
*
137
*/
138
NTSTATUS WINAPI LsaGetUserName(PUNICODE_STRING *user_name, PUNICODE_STRING *domain_name)
139
{
140
UNICODE_STRING *user;
141
DWORD user_size;
142
143
user_size = 0;
144
if (GetUserNameW(NULL, &user_size) || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
145
return STATUS_UNSUCCESSFUL;
146
147
user = malloc(sizeof(*user) + user_size * sizeof(WCHAR));
148
if (!user) return STATUS_NO_MEMORY;
149
150
user->Buffer = (WCHAR *)(user + 1);
151
user->MaximumLength = user_size * sizeof(WCHAR);
152
user->Length = user->MaximumLength - sizeof(WCHAR);
153
if (!GetUserNameW(user->Buffer, &user_size))
154
{
155
free(user);
156
return STATUS_UNSUCCESSFUL;
157
}
158
159
if (domain_name)
160
{
161
UNICODE_STRING *domain;
162
WCHAR computer[MAX_COMPUTERNAME_LENGTH + 1];
163
DWORD domain_size;
164
165
domain_size = ARRAY_SIZE(computer);
166
if (!GetComputerNameW(computer, &domain_size))
167
{
168
free(user);
169
return STATUS_UNSUCCESSFUL;
170
}
171
172
domain = malloc(sizeof(*domain) + (domain_size + 1) * sizeof(WCHAR));
173
if (!domain)
174
{
175
free(user);
176
return STATUS_NO_MEMORY;
177
}
178
179
domain->Buffer = (WCHAR *)(domain + 1);
180
domain->Length = domain_size * sizeof(WCHAR);
181
domain->MaximumLength = domain->Length + sizeof(WCHAR);
182
wcscpy(domain->Buffer, computer);
183
184
*domain_name = domain;
185
}
186
187
*user_name = user;
188
189
return STATUS_SUCCESS;
190
}
191
192
/******************************************************************************
193
* LsaAddAccountRights [ADVAPI32.@]
194
*
195
*/
196
NTSTATUS WINAPI LsaAddAccountRights(
197
LSA_HANDLE policy,
198
PSID sid,
199
PLSA_UNICODE_STRING rights,
200
ULONG count)
201
{
202
FIXME("(%p,%p,%p,0x%08lx) stub\n", policy, sid, rights, count);
203
return STATUS_SUCCESS;
204
}
205
206
/******************************************************************************
207
* LsaClose [ADVAPI32.@]
208
*
209
* Closes a handle to a Policy or TrustedDomain.
210
*
211
* PARAMS
212
* ObjectHandle [I] Handle to a Policy or TrustedDomain.
213
*
214
* RETURNS
215
* Success: STATUS_SUCCESS.
216
* Failure: NTSTATUS code.
217
*/
218
NTSTATUS WINAPI LsaClose(IN LSA_HANDLE ObjectHandle)
219
{
220
WARN("(%p) stub\n", ObjectHandle);
221
return STATUS_SUCCESS;
222
}
223
224
/******************************************************************************
225
* LsaCreateTrustedDomainEx [ADVAPI32.@]
226
*
227
*/
228
NTSTATUS WINAPI LsaCreateTrustedDomainEx(
229
LSA_HANDLE policy,
230
PTRUSTED_DOMAIN_INFORMATION_EX domain_info,
231
PTRUSTED_DOMAIN_AUTH_INFORMATION auth_info,
232
ACCESS_MASK access,
233
PLSA_HANDLE domain)
234
{
235
FIXME("(%p,%p,%p,0x%08lx,%p) stub\n", policy, domain_info, auth_info,
236
access, domain);
237
return STATUS_SUCCESS;
238
}
239
240
/******************************************************************************
241
* LsaDeleteTrustedDomain [ADVAPI32.@]
242
*
243
*/
244
NTSTATUS WINAPI LsaDeleteTrustedDomain(LSA_HANDLE policy, PSID sid)
245
{
246
FIXME("(%p,%p) stub\n", policy, sid);
247
return STATUS_SUCCESS;
248
}
249
250
/******************************************************************************
251
* LsaEnumerateAccountRights [ADVAPI32.@]
252
*
253
*/
254
NTSTATUS WINAPI LsaEnumerateAccountRights(
255
LSA_HANDLE policy,
256
PSID sid,
257
PLSA_UNICODE_STRING *rights,
258
PULONG count)
259
{
260
FIXME("(%p,%p,%p,%p) stub\n", policy, sid, rights, count);
261
*rights = 0;
262
*count = 0;
263
return STATUS_OBJECT_NAME_NOT_FOUND;
264
}
265
266
/******************************************************************************
267
* LsaEnumerateAccounts [ADVAPI32.@]
268
*
269
*/
270
NTSTATUS WINAPI LsaEnumerateAccounts(
271
LSA_HANDLE policy,
272
PLSA_ENUMERATION_HANDLE context,
273
PVOID *buffer,
274
ULONG maxlen,
275
PULONG count)
276
{
277
FIXME("(%p,%p,%p,%ld,%p) stub\n", policy, context, buffer, maxlen, count);
278
if (count) *count = 0;
279
return STATUS_NO_MORE_ENTRIES;
280
}
281
282
/******************************************************************************
283
* LsaEnumerateAccountsWithUserRight [ADVAPI32.@]
284
*
285
*/
286
NTSTATUS WINAPI LsaEnumerateAccountsWithUserRight(
287
LSA_HANDLE policy,
288
PLSA_UNICODE_STRING rights,
289
PVOID *buffer,
290
PULONG count)
291
{
292
FIXME("(%p,%p,%p,%p) stub\n", policy, rights, buffer, count);
293
return STATUS_NO_MORE_ENTRIES;
294
}
295
296
/******************************************************************************
297
* LsaEnumerateTrustedDomains [ADVAPI32.@]
298
*
299
* Returns the names and SIDs of trusted domains.
300
*
301
* PARAMS
302
* PolicyHandle [I] Handle to a Policy object.
303
* EnumerationContext [I] Pointer to an enumeration handle.
304
* Buffer [O] Contains the names and SIDs of trusted domains.
305
* PreferredMaximumLength[I] Preferred maximum size in bytes of Buffer.
306
* CountReturned [O] Number of elements in Buffer.
307
*
308
* RETURNS
309
* Success: STATUS_SUCCESS,
310
* STATUS_MORE_ENTRIES,
311
* STATUS_NO_MORE_ENTRIES
312
* Failure: NTSTATUS code.
313
*
314
* NOTES
315
* LsaEnumerateTrustedDomains can be called multiple times to enumerate
316
* all trusted domains.
317
*/
318
NTSTATUS WINAPI LsaEnumerateTrustedDomains(
319
IN LSA_HANDLE PolicyHandle,
320
IN PLSA_ENUMERATION_HANDLE EnumerationContext,
321
OUT PVOID* Buffer,
322
IN ULONG PreferredMaximumLength,
323
OUT PULONG CountReturned)
324
{
325
FIXME("(%p,%p,%p,0x%08lx,%p) stub\n", PolicyHandle, EnumerationContext,
326
Buffer, PreferredMaximumLength, CountReturned);
327
328
if (CountReturned) *CountReturned = 0;
329
return STATUS_SUCCESS;
330
}
331
332
/******************************************************************************
333
* LsaEnumerateTrustedDomainsEx [ADVAPI32.@]
334
*
335
*/
336
NTSTATUS WINAPI LsaEnumerateTrustedDomainsEx(
337
LSA_HANDLE policy,
338
PLSA_ENUMERATION_HANDLE context,
339
PVOID *buffer,
340
ULONG length,
341
PULONG count)
342
{
343
FIXME("(%p,%p,%p,0x%08lx,%p) stub\n", policy, context, buffer, length, count);
344
345
if (count) *count = 0;
346
return STATUS_SUCCESS;
347
}
348
349
/******************************************************************************
350
* LsaFreeMemory [ADVAPI32.@]
351
*
352
* Frees memory allocated by a LSA function.
353
*
354
* PARAMS
355
* Buffer [I] Memory buffer to free.
356
*
357
* RETURNS
358
* Success: STATUS_SUCCESS.
359
* Failure: NTSTATUS code.
360
*/
361
NTSTATUS WINAPI LsaFreeMemory(IN PVOID Buffer)
362
{
363
TRACE("(%p)\n", Buffer);
364
365
free(Buffer);
366
return STATUS_SUCCESS;
367
}
368
369
/******************************************************************************
370
* LsaLookupNames [ADVAPI32.@]
371
*
372
* Returns the SIDs of an array of user, group, or local group names.
373
*
374
* PARAMS
375
* PolicyHandle [I] Handle to a Policy object.
376
* Count [I] Number of names in Names.
377
* Names [I] Array of names to lookup.
378
* ReferencedDomains [O] Array of domains where the names were found.
379
* Sids [O] Array of SIDs corresponding to Names.
380
*
381
* RETURNS
382
* Success: STATUS_SUCCESS,
383
* STATUS_SOME_NOT_MAPPED
384
* Failure: STATUS_NONE_MAPPED or NTSTATUS code.
385
*/
386
NTSTATUS WINAPI LsaLookupNames(
387
IN LSA_HANDLE PolicyHandle,
388
IN ULONG Count,
389
IN PLSA_UNICODE_STRING Names,
390
OUT PLSA_REFERENCED_DOMAIN_LIST* ReferencedDomains,
391
OUT PLSA_TRANSLATED_SID* Sids)
392
{
393
FIXME("(%p,0x%08lx,%p,%p,%p) stub\n", PolicyHandle, Count, Names,
394
ReferencedDomains, Sids);
395
396
return STATUS_NONE_MAPPED;
397
}
398
399
static BOOL lookup_name( LSA_UNICODE_STRING *name, SID *sid, DWORD *sid_size, WCHAR *domain,
400
DWORD *domain_size, SID_NAME_USE *use, BOOL *handled )
401
{
402
BOOL ret;
403
404
ret = lookup_local_wellknown_name( name, sid, sid_size, domain, domain_size, use, handled );
405
if (!*handled)
406
ret = lookup_local_user_name( name, sid, sid_size, domain, domain_size, use, handled );
407
408
return ret;
409
}
410
411
/* Adds domain info to referenced domain list.
412
Domain list is stored as plain buffer, layout is:
413
414
LSA_REFERENCED_DOMAIN_LIST,
415
LSA_TRUST_INFORMATION array,
416
domain data array of
417
{
418
domain name data (WCHAR buffer),
419
SID data
420
}
421
422
Parameters:
423
list [I] referenced list pointer
424
domain [I] domain name string
425
data [IO] pointer to domain data array
426
*/
427
static LONG lsa_reflist_add_domain(LSA_REFERENCED_DOMAIN_LIST *list, LSA_UNICODE_STRING *domain, char **data)
428
{
429
ULONG sid_size = 0,domain_size = 0;
430
BOOL handled = FALSE;
431
SID_NAME_USE use;
432
LONG i;
433
434
for (i = 0; i < list->Entries; i++)
435
{
436
/* try to reuse index */
437
if ((list->Domains[i].Name.Length == domain->Length) &&
438
(!wcsnicmp(list->Domains[i].Name.Buffer, domain->Buffer, (domain->Length / sizeof(WCHAR)))))
439
{
440
return i;
441
}
442
}
443
444
/* no matching domain found, store name */
445
list->Domains[list->Entries].Name.Length = domain->Length;
446
list->Domains[list->Entries].Name.MaximumLength = domain->MaximumLength;
447
list->Domains[list->Entries].Name.Buffer = (WCHAR*)*data;
448
memcpy(list->Domains[list->Entries].Name.Buffer, domain->Buffer, domain->MaximumLength);
449
*data += domain->MaximumLength;
450
451
/* get and store SID data */
452
list->Domains[list->Entries].Sid = *data;
453
lookup_name(domain, NULL, &sid_size, NULL, &domain_size, &use, &handled);
454
domain_size = 0;
455
lookup_name(domain, list->Domains[list->Entries].Sid, &sid_size, NULL, &domain_size, &use, &handled);
456
*data += sid_size;
457
458
return list->Entries++;
459
}
460
461
/******************************************************************************
462
* LsaLookupNames2 [ADVAPI32.@]
463
*
464
*/
465
NTSTATUS WINAPI LsaLookupNames2( LSA_HANDLE policy, ULONG flags, ULONG count,
466
PLSA_UNICODE_STRING names, PLSA_REFERENCED_DOMAIN_LIST *domains,
467
PLSA_TRANSLATED_SID2 *sids )
468
{
469
ULONG i, sid_size_total = 0, domain_size_max = 0, size, domainname_size_total = 0;
470
ULONG sid_size, domain_size, mapped;
471
LSA_UNICODE_STRING domain;
472
BOOL handled = FALSE;
473
char *domain_data;
474
SID_NAME_USE use;
475
SID *sid;
476
477
TRACE("(%p,0x%08lx,0x%08lx,%p,%p,%p)\n", policy, flags, count, names, domains, sids);
478
479
mapped = 0;
480
for (i = 0; i < count; i++)
481
{
482
handled = FALSE;
483
sid_size = domain_size = 0;
484
lookup_name( &names[i], NULL, &sid_size, NULL, &domain_size, &use, &handled );
485
if (handled)
486
{
487
sid_size_total += sid_size;
488
domainname_size_total += domain_size;
489
if (domain_size)
490
{
491
if (domain_size > domain_size_max)
492
domain_size_max = domain_size;
493
}
494
mapped++;
495
}
496
}
497
TRACE("mapped %lu out of %lu\n", mapped, count);
498
499
size = sizeof(LSA_TRANSLATED_SID2) * count + sid_size_total;
500
if (!(*sids = malloc(size))) return STATUS_NO_MEMORY;
501
502
sid = (SID *)(*sids + count);
503
504
/* use maximum domain count */
505
if (!(*domains = malloc(sizeof(LSA_REFERENCED_DOMAIN_LIST) + sizeof(LSA_TRUST_INFORMATION) * count +
506
sid_size_total + domainname_size_total * sizeof(WCHAR))))
507
{
508
free(*sids);
509
return STATUS_NO_MEMORY;
510
}
511
(*domains)->Entries = 0;
512
(*domains)->Domains = (LSA_TRUST_INFORMATION*)((char*)*domains + sizeof(LSA_REFERENCED_DOMAIN_LIST));
513
domain_data = (char*)(*domains)->Domains + sizeof(LSA_TRUST_INFORMATION)*count;
514
515
domain.Buffer = malloc(domain_size_max * sizeof(WCHAR));
516
for (i = 0; i < count; i++)
517
{
518
domain.Length = domain_size_max*sizeof(WCHAR);
519
domain.MaximumLength = domain_size_max*sizeof(WCHAR);
520
521
(*sids)[i].Use = SidTypeUnknown;
522
(*sids)[i].DomainIndex = -1;
523
(*sids)[i].Flags = 0;
524
525
handled = FALSE;
526
sid_size = sid_size_total;
527
domain_size = domain_size_max;
528
lookup_name( &names[i], sid, &sid_size, domain.Buffer, &domain_size, &use, &handled );
529
if (handled)
530
{
531
(*sids)[i].Sid = sid;
532
(*sids)[i].Use = use;
533
534
sid = (SID *)((char *)sid + sid_size);
535
sid_size_total -= sid_size;
536
if (domain_size)
537
{
538
domain.Length = domain_size * sizeof(WCHAR);
539
domain.MaximumLength = (domain_size + 1) * sizeof(WCHAR);
540
(*sids)[i].DomainIndex = lsa_reflist_add_domain(*domains, &domain, &domain_data);
541
}
542
}
543
}
544
free(domain.Buffer);
545
546
if (mapped == count) return STATUS_SUCCESS;
547
if (mapped > 0 && mapped < count) return STATUS_SOME_NOT_MAPPED;
548
return STATUS_NONE_MAPPED;
549
}
550
551
/******************************************************************************
552
* LsaLookupSids [ADVAPI32.@]
553
*
554
* Looks up the names that correspond to an array of SIDs.
555
*
556
* PARAMS
557
* PolicyHandle [I] Handle to a Policy object.
558
* Count [I] Number of SIDs in the Sids array.
559
* Sids [I] Array of SIDs to lookup.
560
* ReferencedDomains [O] Array of domains where the sids were found.
561
* Names [O] Array of names corresponding to Sids.
562
*
563
* RETURNS
564
* Success: STATUS_SUCCESS,
565
* STATUS_SOME_NOT_MAPPED
566
* Failure: STATUS_NONE_MAPPED or NTSTATUS code.
567
*/
568
NTSTATUS WINAPI LsaLookupSids(
569
LSA_HANDLE PolicyHandle,
570
ULONG Count,
571
PSID *Sids,
572
LSA_REFERENCED_DOMAIN_LIST **ReferencedDomains,
573
LSA_TRANSLATED_NAME **Names)
574
{
575
ULONG i, mapped, name_fullsize, domain_fullsize;
576
ULONG name_size, domain_size;
577
LSA_UNICODE_STRING domain;
578
WCHAR *name_buffer;
579
char *domain_data;
580
SID_NAME_USE use;
581
WCHAR *strsid;
582
583
TRACE("(%p, %lu, %p, %p, %p)\n", PolicyHandle, Count, Sids, ReferencedDomains, Names);
584
585
/* this length does not include actual string length yet */
586
name_fullsize = sizeof(LSA_TRANSLATED_NAME) * Count;
587
if (!(*Names = malloc(name_fullsize))) return STATUS_NO_MEMORY;
588
/* maximum count of stored domain infos is Count, allocate it like that cause really needed
589
count could only be computed after sid data is retrieved */
590
domain_fullsize = sizeof(LSA_REFERENCED_DOMAIN_LIST) + sizeof(LSA_TRUST_INFORMATION)*Count;
591
if (!(*ReferencedDomains = malloc(domain_fullsize)))
592
{
593
free(*Names);
594
return STATUS_NO_MEMORY;
595
}
596
(*ReferencedDomains)->Entries = 0;
597
(*ReferencedDomains)->Domains = (LSA_TRUST_INFORMATION*)((char*)*ReferencedDomains + sizeof(LSA_REFERENCED_DOMAIN_LIST));
598
599
/* Get full names data length and full length needed to store domain name and SID */
600
for (i = 0; i < Count; i++)
601
{
602
(*Names)[i].Use = SidTypeUnknown;
603
(*Names)[i].DomainIndex = -1;
604
RtlInitUnicodeStringEx(&(*Names)[i].Name, NULL);
605
606
memset(&(*ReferencedDomains)->Domains[i], 0, sizeof(LSA_TRUST_INFORMATION));
607
608
name_size = domain_size = 0;
609
if (!LookupAccountSidW(NULL, Sids[i], NULL, &name_size, NULL, &domain_size, &use) &&
610
GetLastError() == ERROR_INSUFFICIENT_BUFFER)
611
{
612
if (name_size)
613
{
614
(*Names)[i].Name.Length = (name_size - 1) * sizeof(WCHAR);
615
(*Names)[i].Name.MaximumLength = name_size * sizeof(WCHAR);
616
}
617
else
618
{
619
(*Names)[i].Name.Length = 0;
620
(*Names)[i].Name.MaximumLength = sizeof(WCHAR);
621
}
622
623
name_fullsize += (*Names)[i].Name.MaximumLength;
624
625
/* This potentially allocates more than needed, cause different names will reuse same domain index.
626
Also it's not possible to store domain name length right here for the same reason. */
627
if (domain_size)
628
{
629
ULONG sid_size = 0;
630
BOOL handled = FALSE;
631
WCHAR *name;
632
633
domain_fullsize += domain_size * sizeof(WCHAR);
634
635
/* get domain SID size too */
636
name = malloc(domain_size * sizeof(WCHAR));
637
*name = 0;
638
LookupAccountSidW(NULL, Sids[i], NULL, &name_size, name, &domain_size, &use);
639
640
domain.Buffer = name;
641
domain.Length = domain_size * sizeof(WCHAR);
642
domain.MaximumLength = domain_size * sizeof(WCHAR);
643
644
lookup_name(&domain, NULL, &sid_size, NULL, &domain_size, &use, &handled);
645
domain_fullsize += sid_size;
646
647
free(name);
648
}
649
else
650
{
651
/* If we don't have a domain name, use a zero-length entry rather than a null value. */
652
domain_fullsize += sizeof(WCHAR);
653
domain.Length = 0;
654
domain.MaximumLength = sizeof(WCHAR);
655
}
656
}
657
else if (ConvertSidToStringSidW(Sids[i], &strsid))
658
{
659
(*Names)[i].Name.Length = lstrlenW(strsid) * sizeof(WCHAR);
660
(*Names)[i].Name.MaximumLength = (lstrlenW(strsid) + 1) * sizeof(WCHAR);
661
name_fullsize += (lstrlenW(strsid) + 1) * sizeof(WCHAR);
662
663
LocalFree(strsid);
664
}
665
}
666
667
/* now we have full length needed for both */
668
*Names = realloc(*Names, name_fullsize);
669
name_buffer = (WCHAR*)((char*)*Names + sizeof(LSA_TRANSLATED_NAME)*Count);
670
671
*ReferencedDomains = realloc(*ReferencedDomains, domain_fullsize);
672
/* fix pointer after reallocation */
673
(*ReferencedDomains)->Domains = (LSA_TRUST_INFORMATION*)((char*)*ReferencedDomains + sizeof(LSA_REFERENCED_DOMAIN_LIST));
674
domain_data = (char*)(*ReferencedDomains)->Domains + sizeof(LSA_TRUST_INFORMATION)*Count;
675
676
mapped = 0;
677
for (i = 0; i < Count; i++)
678
{
679
name_size = domain_size = 0;
680
681
(*Names)[i].Name.Buffer = name_buffer;
682
683
if (!LookupAccountSidW(NULL, Sids[i], NULL, &name_size, NULL, &domain_size, &use) &&
684
GetLastError() == ERROR_INSUFFICIENT_BUFFER)
685
{
686
mapped++;
687
688
if (domain_size)
689
{
690
domain.Length = (domain_size - 1) * sizeof(WCHAR);
691
domain.MaximumLength = domain_size * sizeof(WCHAR);
692
}
693
else
694
{
695
/* Use a zero-length buffer */
696
domain.Length = 0;
697
domain.MaximumLength = sizeof(WCHAR);
698
}
699
700
domain.Buffer = malloc(domain.MaximumLength);
701
702
LookupAccountSidW(NULL, Sids[i], (*Names)[i].Name.Buffer, &name_size, domain.Buffer, &domain_size, &use);
703
(*Names)[i].Use = use;
704
705
(*Names)[i].DomainIndex = lsa_reflist_add_domain(*ReferencedDomains, &domain, &domain_data);
706
free(domain.Buffer);
707
}
708
else if (ConvertSidToStringSidW(Sids[i], &strsid))
709
{
710
lstrcpyW((*Names)[i].Name.Buffer, strsid);
711
LocalFree(strsid);
712
}
713
714
name_buffer += lstrlenW(name_buffer) + 1;
715
}
716
TRACE("mapped %lu out of %lu\n", mapped, Count);
717
718
if (mapped == Count) return STATUS_SUCCESS;
719
if (mapped) return STATUS_SOME_NOT_MAPPED;
720
return STATUS_NONE_MAPPED;
721
}
722
723
/******************************************************************************
724
* LsaNtStatusToWinError [ADVAPI32.@]
725
*
726
* Converts an LSA NTSTATUS code to a Windows error code.
727
*
728
* PARAMS
729
* Status [I] NTSTATUS code.
730
*
731
* RETURNS
732
* Success: Corresponding Windows error code.
733
* Failure: ERROR_MR_MID_NOT_FOUND.
734
*/
735
ULONG WINAPI LsaNtStatusToWinError(NTSTATUS Status)
736
{
737
return RtlNtStatusToDosError(Status);
738
}
739
740
/******************************************************************************
741
* LsaOpenPolicy [ADVAPI32.@]
742
*
743
* Opens a handle to the Policy object on a local or remote system.
744
*
745
* PARAMS
746
* SystemName [I] Name of the target system.
747
* ObjectAttributes [I] Connection attributes.
748
* DesiredAccess [I] Requested access rights.
749
* PolicyHandle [I/O] Handle to the Policy object.
750
*
751
* RETURNS
752
* Success: STATUS_SUCCESS.
753
* Failure: NTSTATUS code.
754
*
755
* NOTES
756
* Set SystemName to NULL to open the local Policy object.
757
*/
758
NTSTATUS WINAPI LsaOpenPolicy(
759
IN PLSA_UNICODE_STRING SystemName,
760
IN PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
761
IN ACCESS_MASK DesiredAccess,
762
IN OUT PLSA_HANDLE PolicyHandle)
763
{
764
WARN("(%s,%p,0x%08lx,%p) stub\n",
765
SystemName?debugstr_w(SystemName->Buffer):"(null)",
766
ObjectAttributes, DesiredAccess, PolicyHandle);
767
768
ADVAPI_ForceLocalComputer(SystemName ? SystemName->Buffer : NULL,
769
STATUS_ACCESS_VIOLATION);
770
dumpLsaAttributes(ObjectAttributes);
771
772
if(PolicyHandle) *PolicyHandle = (LSA_HANDLE)0xcafe;
773
return STATUS_SUCCESS;
774
}
775
776
/******************************************************************************
777
* LsaOpenTrustedDomainByName [ADVAPI32.@]
778
*
779
*/
780
NTSTATUS WINAPI LsaOpenTrustedDomainByName(
781
LSA_HANDLE policy,
782
PLSA_UNICODE_STRING name,
783
ACCESS_MASK access,
784
PLSA_HANDLE handle)
785
{
786
FIXME("(%p,%p,0x%08lx,%p) stub\n", policy, name, access, handle);
787
return STATUS_OBJECT_NAME_NOT_FOUND;
788
}
789
790
/******************************************************************************
791
* LsaQueryInformationPolicy [ADVAPI32.@]
792
*
793
* Returns information about a Policy object.
794
*
795
* PARAMS
796
* PolicyHandle [I] Handle to a Policy object.
797
* InformationClass [I] Type of information to retrieve.
798
* Buffer [O] Pointer to the requested information.
799
*
800
* RETURNS
801
* Success: STATUS_SUCCESS.
802
* Failure: NTSTATUS code.
803
*/
804
NTSTATUS WINAPI LsaQueryInformationPolicy(
805
IN LSA_HANDLE PolicyHandle,
806
IN POLICY_INFORMATION_CLASS InformationClass,
807
OUT PVOID *Buffer)
808
{
809
TRACE("(%p,%s,%p)\n", PolicyHandle, debugstr_InformationClass(InformationClass), Buffer);
810
811
if(!Buffer) return STATUS_INVALID_PARAMETER;
812
switch (InformationClass)
813
{
814
case PolicyAuditEventsInformation: /* 2 */
815
{
816
PPOLICY_AUDIT_EVENTS_INFO p = calloc(1, sizeof(POLICY_AUDIT_EVENTS_INFO));
817
p->AuditingMode = FALSE; /* no auditing */
818
*Buffer = p;
819
}
820
break;
821
case PolicyPrimaryDomainInformation: /* 3 */
822
{
823
/* Only the domain name is valid for the local computer.
824
* All other fields are zero.
825
*/
826
PPOLICY_PRIMARY_DOMAIN_INFO pinfo;
827
828
pinfo = ADVAPI_GetDomainName(sizeof(*pinfo), offsetof(POLICY_PRIMARY_DOMAIN_INFO, Name));
829
830
TRACE("setting domain to %s\n", debugstr_w(pinfo->Name.Buffer));
831
832
*Buffer = pinfo;
833
}
834
break;
835
case PolicyAccountDomainInformation: /* 5 */
836
{
837
struct di
838
{
839
POLICY_ACCOUNT_DOMAIN_INFO info;
840
SID sid;
841
DWORD padding[3];
842
WCHAR domain[MAX_COMPUTERNAME_LENGTH + 1];
843
};
844
845
DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
846
struct di * xdi = calloc(1, sizeof(*xdi));
847
848
xdi->info.DomainName.MaximumLength = dwSize * sizeof(WCHAR);
849
xdi->info.DomainName.Buffer = xdi->domain;
850
if (GetComputerNameW(xdi->info.DomainName.Buffer, &dwSize))
851
xdi->info.DomainName.Length = dwSize * sizeof(WCHAR);
852
853
TRACE("setting name to %s\n", debugstr_w(xdi->info.DomainName.Buffer));
854
855
xdi->info.DomainSid = &xdi->sid;
856
857
if (!ADVAPI_GetComputerSid(&xdi->sid))
858
{
859
free(xdi);
860
861
WARN("Computer SID not found\n");
862
863
return STATUS_UNSUCCESSFUL;
864
}
865
866
TRACE("setting SID to %s\n", debugstr_sid(&xdi->sid));
867
868
*Buffer = xdi;
869
}
870
break;
871
case PolicyDnsDomainInformation: /* 12 (0xc) */
872
{
873
struct
874
{
875
POLICY_DNS_DOMAIN_INFO info;
876
struct
877
{
878
SID sid;
879
DWORD sid_subauthority[3];
880
} domain_sid;
881
WCHAR domain_name[256];
882
WCHAR dns_domain_name[256];
883
WCHAR dns_forest_name[256];
884
} *xdi;
885
struct
886
{
887
SID sid;
888
DWORD sid_subauthority[3];
889
} computer_sid;
890
DWORD dwSize;
891
892
xdi = calloc(1, sizeof(*xdi));
893
if (!xdi) return STATUS_NO_MEMORY;
894
895
dwSize = 256;
896
if (GetComputerNameExW(ComputerNamePhysicalDnsDomain, xdi->domain_name, &dwSize))
897
{
898
WCHAR *dot;
899
900
dot = wcsrchr(xdi->domain_name, '.');
901
if (dot) *dot = 0;
902
wcsupr(xdi->domain_name);
903
xdi->info.Name.Buffer = xdi->domain_name;
904
xdi->info.Name.Length = lstrlenW(xdi->domain_name) * sizeof(WCHAR);
905
xdi->info.Name.MaximumLength = xdi->info.Name.Length + sizeof(WCHAR);
906
TRACE("setting Name to %s\n", debugstr_w(xdi->info.Name.Buffer));
907
}
908
909
dwSize = 256;
910
if (GetComputerNameExW(ComputerNameDnsDomain, xdi->dns_domain_name, &dwSize))
911
{
912
xdi->info.DnsDomainName.Buffer = xdi->dns_domain_name;
913
xdi->info.DnsDomainName.Length = dwSize * sizeof(WCHAR);
914
xdi->info.DnsDomainName.MaximumLength = (dwSize + 1) * sizeof(WCHAR);
915
TRACE("setting DnsDomainName to %s\n", debugstr_w(xdi->info.DnsDomainName.Buffer));
916
917
xdi->info.DnsForestName.Buffer = xdi->dns_domain_name;
918
xdi->info.DnsForestName.Length = dwSize * sizeof(WCHAR);
919
xdi->info.DnsForestName.MaximumLength = (dwSize + 1) * sizeof(WCHAR);
920
TRACE("setting DnsForestName to %s\n", debugstr_w(xdi->info.DnsForestName.Buffer));
921
}
922
923
dwSize = sizeof(xdi->domain_sid);
924
if (ADVAPI_GetComputerSid(&computer_sid.sid) && GetWindowsAccountDomainSid(&computer_sid.sid, &xdi->domain_sid.sid, &dwSize))
925
{
926
xdi->info.Sid = &xdi->domain_sid.sid;
927
TRACE("setting SID to %s\n", debugstr_sid(&xdi->domain_sid.sid));
928
}
929
930
*Buffer = xdi;
931
}
932
break;
933
case PolicyAuditLogInformation:
934
case PolicyPdAccountInformation:
935
case PolicyLsaServerRoleInformation:
936
case PolicyReplicaSourceInformation:
937
case PolicyDefaultQuotaInformation:
938
case PolicyModificationInformation:
939
case PolicyAuditFullSetInformation:
940
case PolicyAuditFullQueryInformation:
941
{
942
FIXME("category %d not implemented\n", InformationClass);
943
return STATUS_UNSUCCESSFUL;
944
}
945
}
946
return STATUS_SUCCESS;
947
}
948
949
/******************************************************************************
950
* LsaQueryTrustedDomainInfo [ADVAPI32.@]
951
*
952
*/
953
NTSTATUS WINAPI LsaQueryTrustedDomainInfo(
954
LSA_HANDLE policy,
955
PSID sid,
956
TRUSTED_INFORMATION_CLASS class,
957
PVOID *buffer)
958
{
959
FIXME("(%p,%p,%d,%p) stub\n", policy, sid, class, buffer);
960
return STATUS_OBJECT_NAME_NOT_FOUND;
961
}
962
963
/******************************************************************************
964
* LsaQueryTrustedDomainInfoByName [ADVAPI32.@]
965
*
966
*/
967
NTSTATUS WINAPI LsaQueryTrustedDomainInfoByName(
968
LSA_HANDLE policy,
969
PLSA_UNICODE_STRING name,
970
TRUSTED_INFORMATION_CLASS class,
971
PVOID *buffer)
972
{
973
FIXME("(%p,%p,%d,%p) stub\n", policy, name, class, buffer);
974
return STATUS_OBJECT_NAME_NOT_FOUND;
975
}
976
977
/******************************************************************************
978
* LsaRegisterPolicyChangeNotification [ADVAPI32.@]
979
*
980
*/
981
NTSTATUS WINAPI LsaRegisterPolicyChangeNotification(
982
POLICY_NOTIFICATION_INFORMATION_CLASS class,
983
HANDLE event)
984
{
985
FIXME("(%d,%p) stub\n", class, event);
986
return STATUS_UNSUCCESSFUL;
987
}
988
989
/******************************************************************************
990
* LsaRemoveAccountRights [ADVAPI32.@]
991
*
992
*/
993
NTSTATUS WINAPI LsaRemoveAccountRights(
994
LSA_HANDLE policy,
995
PSID sid,
996
BOOLEAN all,
997
PLSA_UNICODE_STRING rights,
998
ULONG count)
999
{
1000
FIXME("(%p,%p,%d,%p,0x%08lx) stub\n", policy, sid, all, rights, count);
1001
return STATUS_SUCCESS;
1002
}
1003
1004
/******************************************************************************
1005
* LsaRetrievePrivateData [ADVAPI32.@]
1006
*
1007
* Retrieves data stored by LsaStorePrivateData.
1008
*
1009
* PARAMS
1010
* PolicyHandle [I] Handle to a Policy object.
1011
* KeyName [I] Name of the key where the data is stored.
1012
* PrivateData [O] Pointer to the private data.
1013
*
1014
* RETURNS
1015
* Success: STATUS_SUCCESS.
1016
* Failure: STATUS_OBJECT_NAME_NOT_FOUND or NTSTATUS code.
1017
*/
1018
NTSTATUS WINAPI LsaRetrievePrivateData(
1019
IN LSA_HANDLE PolicyHandle,
1020
IN PLSA_UNICODE_STRING KeyName,
1021
OUT PLSA_UNICODE_STRING* PrivateData)
1022
{
1023
FIXME("(%p,%p,%p) stub\n", PolicyHandle, KeyName, PrivateData);
1024
return STATUS_OBJECT_NAME_NOT_FOUND;
1025
}
1026
1027
/******************************************************************************
1028
* LsaSetInformationPolicy [ADVAPI32.@]
1029
*
1030
* Modifies information in a Policy object.
1031
*
1032
* PARAMS
1033
* PolicyHandle [I] Handle to a Policy object.
1034
* InformationClass [I] Type of information to set.
1035
* Buffer [I] Pointer to the information to set.
1036
*
1037
* RETURNS
1038
* Success: STATUS_SUCCESS.
1039
* Failure: NTSTATUS code.
1040
*/
1041
NTSTATUS WINAPI LsaSetInformationPolicy(
1042
IN LSA_HANDLE PolicyHandle,
1043
IN POLICY_INFORMATION_CLASS InformationClass,
1044
IN PVOID Buffer)
1045
{
1046
FIXME("(%p,%s,%p) stub\n", PolicyHandle, debugstr_InformationClass(InformationClass), Buffer);
1047
1048
return STATUS_UNSUCCESSFUL;
1049
}
1050
1051
/******************************************************************************
1052
* LsaSetSecret [ADVAPI32.@]
1053
*
1054
* Set old and new values on a secret handle
1055
*
1056
* PARAMS
1057
* SecretHandle [I] Handle to a secret object.
1058
* EncryptedCurrentValue [I] Pointer to encrypted new value, can be NULL
1059
* EncryptedOldValue [I] Pointer to encrypted old value, can be NULL
1060
*
1061
* RETURNS
1062
* Success: STATUS_SUCCESS
1063
* Failure: NTSTATUS code.
1064
*/
1065
NTSTATUS WINAPI LsaSetSecret(
1066
IN LSA_HANDLE SecretHandle,
1067
IN PLSA_UNICODE_STRING EncryptedCurrentValue,
1068
IN PLSA_UNICODE_STRING EncryptedOldValue)
1069
{
1070
FIXME("(%p,%p,%p) stub\n", SecretHandle, EncryptedCurrentValue,
1071
EncryptedOldValue);
1072
return STATUS_SUCCESS;
1073
}
1074
1075
/******************************************************************************
1076
* LsaSetTrustedDomainInfoByName [ADVAPI32.@]
1077
*
1078
*/
1079
NTSTATUS WINAPI LsaSetTrustedDomainInfoByName(
1080
LSA_HANDLE policy,
1081
PLSA_UNICODE_STRING name,
1082
TRUSTED_INFORMATION_CLASS class,
1083
PVOID buffer)
1084
{
1085
FIXME("(%p,%p,%d,%p) stub\n", policy, name, class, buffer);
1086
return STATUS_SUCCESS;
1087
}
1088
1089
/******************************************************************************
1090
* LsaSetTrustedDomainInformation [ADVAPI32.@]
1091
*
1092
*/
1093
NTSTATUS WINAPI LsaSetTrustedDomainInformation(
1094
LSA_HANDLE policy,
1095
PSID sid,
1096
TRUSTED_INFORMATION_CLASS class,
1097
PVOID buffer)
1098
{
1099
FIXME("(%p,%p,%d,%p) stub\n", policy, sid, class, buffer);
1100
return STATUS_SUCCESS;
1101
}
1102
1103
/******************************************************************************
1104
* LsaStorePrivateData [ADVAPI32.@]
1105
*
1106
* Stores or deletes a Policy object's data under the specified reg key.
1107
*
1108
* PARAMS
1109
* PolicyHandle [I] Handle to a Policy object.
1110
* KeyName [I] Name of the key where the data will be stored.
1111
* PrivateData [O] Pointer to the private data.
1112
*
1113
* RETURNS
1114
* Success: STATUS_SUCCESS.
1115
* Failure: STATUS_OBJECT_NAME_NOT_FOUND or NTSTATUS code.
1116
*/
1117
NTSTATUS WINAPI LsaStorePrivateData(
1118
IN LSA_HANDLE PolicyHandle,
1119
IN PLSA_UNICODE_STRING KeyName,
1120
IN PLSA_UNICODE_STRING PrivateData)
1121
{
1122
FIXME("(%p,%p,%p) stub\n", PolicyHandle, KeyName, PrivateData);
1123
return STATUS_OBJECT_NAME_NOT_FOUND;
1124
}
1125
1126
/******************************************************************************
1127
* LsaUnregisterPolicyChangeNotification [ADVAPI32.@]
1128
*
1129
*/
1130
NTSTATUS WINAPI LsaUnregisterPolicyChangeNotification(
1131
POLICY_NOTIFICATION_INFORMATION_CLASS class,
1132
HANDLE event)
1133
{
1134
FIXME("(%d,%p) stub\n", class, event);
1135
return STATUS_SUCCESS;
1136
}
1137
1138
/******************************************************************************
1139
* LsaLookupPrivilegeName [ADVAPI32.@]
1140
*
1141
*/
1142
NTSTATUS WINAPI LsaLookupPrivilegeName(LSA_HANDLE handle, LUID *luid, LSA_UNICODE_STRING **name)
1143
{
1144
const WCHAR *privnameW;
1145
DWORD length;
1146
WCHAR *strW;
1147
1148
TRACE("(%p,%p,%p)\n", handle, luid, name);
1149
1150
if (!luid || !handle)
1151
return STATUS_INVALID_PARAMETER;
1152
1153
*name = NULL;
1154
1155
if (!(privnameW = get_wellknown_privilege_name(luid)))
1156
return STATUS_NO_SUCH_PRIVILEGE;
1157
1158
length = lstrlenW(privnameW);
1159
*name = malloc(sizeof(**name) + (length + 1) * sizeof(WCHAR));
1160
if (!*name)
1161
return STATUS_NO_MEMORY;
1162
1163
strW = (WCHAR *)(*name + 1);
1164
memcpy(strW, privnameW, length * sizeof(WCHAR));
1165
strW[length] = 0;
1166
RtlInitUnicodeString(*name, strW);
1167
1168
return STATUS_SUCCESS;
1169
}
1170
1171
/******************************************************************************
1172
* LsaLookupPrivilegeDisplayName [ADVAPI32.@]
1173
*
1174
*/
1175
NTSTATUS WINAPI LsaLookupPrivilegeDisplayName(LSA_HANDLE handle, LSA_UNICODE_STRING *name,
1176
LSA_UNICODE_STRING **display_name, SHORT *language)
1177
{
1178
FIXME("(%p, %s, %p, %p)\n", handle, debugstr_us(name), display_name, language);
1179
1180
return STATUS_NO_SUCH_PRIVILEGE;
1181
}
1182
1183
/******************************************************************************
1184
* AuditQuerySystemPolicy [ADVAPI32.@]
1185
*
1186
*/
1187
BOOLEAN WINAPI AuditQuerySystemPolicy(const GUID* guids, ULONG count, AUDIT_POLICY_INFORMATION** policy)
1188
{
1189
1190
FIXME("(%p, %ld, %p)\n", guids, count, policy);
1191
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1192
return FALSE;
1193
}
1194
1195