[NETAPI32]
[reactos.git] / reactos / dll / win32 / netapi32 / user.c
1 /*
2 * Copyright 2002 Andriy Palamarchuk
3 *
4 * netapi32 user functions
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 /*
22 * TODO:
23 * Implement NetUserGetGroups
24 * Implement NetUserSetGroups
25 * NetUserGetLocalGroups does not support LG_INCLUDE_INDIRECT yet.
26 * Add missing information levels.
27 * ...
28 */
29
30 #include "netapi32.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
33
34
35 typedef struct _ENUM_CONTEXT
36 {
37 SAM_HANDLE ServerHandle;
38 SAM_HANDLE BuiltinDomainHandle;
39 SAM_HANDLE AccountDomainHandle;
40
41 SAM_ENUMERATE_HANDLE EnumerationContext;
42 PSAM_RID_ENUMERATION Buffer;
43 ULONG Count;
44 ULONG Index;
45 BOOLEAN BuiltinDone;
46
47 } ENUM_CONTEXT, *PENUM_CONTEXT;
48
49
50 static
51 ULONG
52 GetAccountFlags(ULONG AccountControl)
53 {
54 ULONG Flags = UF_SCRIPT;
55
56 if (AccountControl & USER_ACCOUNT_DISABLED)
57 Flags |= UF_ACCOUNTDISABLE;
58
59 if (AccountControl & USER_HOME_DIRECTORY_REQUIRED)
60 Flags |= UF_HOMEDIR_REQUIRED;
61
62 if (AccountControl & USER_PASSWORD_NOT_REQUIRED)
63 Flags |= UF_PASSWD_NOTREQD;
64
65 // UF_PASSWD_CANT_CHANGE
66
67 if (AccountControl & USER_ACCOUNT_AUTO_LOCKED)
68 Flags |= UF_LOCKOUT;
69
70 if (AccountControl & USER_DONT_EXPIRE_PASSWORD)
71 Flags |= UF_DONT_EXPIRE_PASSWD;
72
73 /*
74 if (AccountControl & USER_ENCRYPTED_TEXT_PASSWORD_ALLOWED)
75 Flags |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED;
76
77 if (AccountControl & USER_SMARTCARD_REQUIRED)
78 Flags |= UF_SMARTCARD_REQUIRED;
79
80 if (AccountControl & USER_TRUSTED_FOR_DELEGATION)
81 Flags |= UF_TRUSTED_FOR_DELEGATION;
82
83 if (AccountControl & USER_NOT_DELEGATED)
84 Flags |= UF_NOT_DELEGATED;
85
86 if (AccountControl & USER_USE_DES_KEY_ONLY)
87 Flags |= UF_USE_DES_KEY_ONLY;
88
89 if (AccountControl & USER_DONT_REQUIRE_PREAUTH)
90 Flags |= UF_DONT_REQUIRE_PREAUTH;
91
92 if (AccountControl & USER_PASSWORD_EXPIRED)
93 Flags |= UF_PASSWORD_EXPIRED;
94 */
95
96 /* Set account type flags */
97 if (AccountControl & USER_TEMP_DUPLICATE_ACCOUNT)
98 Flags |= UF_TEMP_DUPLICATE_ACCOUNT;
99 else if (AccountControl & USER_NORMAL_ACCOUNT)
100 Flags |= UF_NORMAL_ACCOUNT;
101 else if (AccountControl & USER_INTERDOMAIN_TRUST_ACCOUNT)
102 Flags |= UF_INTERDOMAIN_TRUST_ACCOUNT;
103 else if (AccountControl & USER_WORKSTATION_TRUST_ACCOUNT)
104 Flags |= UF_WORKSTATION_TRUST_ACCOUNT;
105 else if (AccountControl & USER_SERVER_TRUST_ACCOUNT)
106 Flags |= UF_SERVER_TRUST_ACCOUNT;
107
108 return Flags;
109 }
110
111
112 static
113 ULONG
114 GetAccountControl(ULONG Flags)
115 {
116 ULONG AccountControl = 0;
117
118 if (Flags & UF_ACCOUNTDISABLE)
119 AccountControl |= USER_ACCOUNT_DISABLED;
120
121 if (Flags & UF_HOMEDIR_REQUIRED)
122 AccountControl |= USER_HOME_DIRECTORY_REQUIRED;
123
124 if (Flags & UF_PASSWD_NOTREQD)
125 AccountControl |= USER_PASSWORD_NOT_REQUIRED;
126
127 if (Flags & UF_LOCKOUT)
128 AccountControl |= USER_ACCOUNT_AUTO_LOCKED;
129
130 if (Flags & UF_DONT_EXPIRE_PASSWD)
131 AccountControl |= USER_DONT_EXPIRE_PASSWORD;
132
133 /* Set account type flags */
134 if (Flags & UF_TEMP_DUPLICATE_ACCOUNT)
135 AccountControl |= USER_TEMP_DUPLICATE_ACCOUNT;
136 else if (Flags & UF_NORMAL_ACCOUNT)
137 AccountControl |= USER_NORMAL_ACCOUNT;
138 else if (Flags & UF_INTERDOMAIN_TRUST_ACCOUNT)
139 AccountControl |= USER_INTERDOMAIN_TRUST_ACCOUNT;
140 else if (Flags & UF_WORKSTATION_TRUST_ACCOUNT)
141 AccountControl |= USER_WORKSTATION_TRUST_ACCOUNT;
142 else if (Flags & UF_SERVER_TRUST_ACCOUNT)
143 AccountControl |= USER_SERVER_TRUST_ACCOUNT;
144
145 return AccountControl;
146 }
147
148
149 static
150 DWORD
151 GetPasswordAge(IN PLARGE_INTEGER PasswordLastSet)
152 {
153 LARGE_INTEGER SystemTime;
154 ULONG SystemSecondsSince1970;
155 ULONG PasswordSecondsSince1970;
156 NTSTATUS Status;
157
158 Status = NtQuerySystemTime(&SystemTime);
159 if (!NT_SUCCESS(Status))
160 return 0;
161
162 RtlTimeToSecondsSince1970(&SystemTime, &SystemSecondsSince1970);
163 RtlTimeToSecondsSince1970(PasswordLastSet, &PasswordSecondsSince1970);
164
165 return SystemSecondsSince1970 - PasswordSecondsSince1970;
166 }
167
168
169 static
170 NET_API_STATUS
171 BuildUserInfoBuffer(PUSER_ALL_INFORMATION UserInfo,
172 DWORD level,
173 ULONG RelativeId,
174 LPVOID *Buffer)
175 {
176 UNICODE_STRING LogonServer = RTL_CONSTANT_STRING(L"\\\\*");
177 LPVOID LocalBuffer = NULL;
178 PUSER_INFO_0 UserInfo0;
179 PUSER_INFO_1 UserInfo1;
180 PUSER_INFO_2 UserInfo2;
181 PUSER_INFO_3 UserInfo3;
182 PUSER_INFO_4 UserInfo4;
183 PUSER_INFO_10 UserInfo10;
184 PUSER_INFO_11 UserInfo11;
185 PUSER_INFO_20 UserInfo20;
186 PUSER_INFO_23 UserInfo23;
187 LPWSTR Ptr;
188 ULONG Size = 0;
189 NET_API_STATUS ApiStatus = NERR_Success;
190
191 *Buffer = NULL;
192
193 switch (level)
194 {
195 case 0:
196 Size = sizeof(USER_INFO_0) +
197 UserInfo->UserName.Length + sizeof(WCHAR);
198 break;
199
200 case 1:
201 Size = sizeof(USER_INFO_1) +
202 UserInfo->UserName.Length + sizeof(WCHAR);
203
204 if (UserInfo->HomeDirectory.Length > 0)
205 Size += UserInfo->HomeDirectory.Length + sizeof(WCHAR);
206
207 if (UserInfo->AdminComment.Length > 0)
208 Size += UserInfo->AdminComment.Length + sizeof(WCHAR);
209
210 if (UserInfo->ScriptPath.Length > 0)
211 Size += UserInfo->ScriptPath.Length + sizeof(WCHAR);
212 break;
213
214 case 2:
215 Size = sizeof(USER_INFO_2) +
216 UserInfo->UserName.Length + sizeof(WCHAR);
217
218 if (UserInfo->HomeDirectory.Length > 0)
219 Size += UserInfo->HomeDirectory.Length + sizeof(WCHAR);
220
221 if (UserInfo->AdminComment.Length > 0)
222 Size += UserInfo->AdminComment.Length + sizeof(WCHAR);
223
224 if (UserInfo->ScriptPath.Length > 0)
225 Size += UserInfo->ScriptPath.Length + sizeof(WCHAR);
226
227 if (UserInfo->FullName.Length > 0)
228 Size += UserInfo->FullName.Length + sizeof(WCHAR);
229
230 if (UserInfo->UserComment.Length > 0)
231 Size += UserInfo->UserComment.Length + sizeof(WCHAR);
232
233 if (UserInfo->Parameters.Length > 0)
234 Size += UserInfo->Parameters.Length + sizeof(WCHAR);
235
236 if (UserInfo->WorkStations.Length > 0)
237 Size += UserInfo->WorkStations.Length + sizeof(WCHAR);
238
239 if (UserInfo->LogonHours.UnitsPerWeek > 0)
240 Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8;
241
242 if (LogonServer.Length > 0)
243 Size += LogonServer.Length + sizeof(WCHAR);
244 break;
245
246 case 3:
247 Size = sizeof(USER_INFO_3) +
248 UserInfo->UserName.Length + sizeof(WCHAR);
249
250 if (UserInfo->HomeDirectory.Length > 0)
251 Size += UserInfo->HomeDirectory.Length + sizeof(WCHAR);
252
253 if (UserInfo->AdminComment.Length > 0)
254 Size += UserInfo->AdminComment.Length + sizeof(WCHAR);
255
256 if (UserInfo->ScriptPath.Length > 0)
257 Size += UserInfo->ScriptPath.Length + sizeof(WCHAR);
258
259 if (UserInfo->FullName.Length > 0)
260 Size += UserInfo->FullName.Length + sizeof(WCHAR);
261
262 if (UserInfo->UserComment.Length > 0)
263 Size += UserInfo->UserComment.Length + sizeof(WCHAR);
264
265 if (UserInfo->Parameters.Length > 0)
266 Size += UserInfo->Parameters.Length + sizeof(WCHAR);
267
268 if (UserInfo->WorkStations.Length > 0)
269 Size += UserInfo->WorkStations.Length + sizeof(WCHAR);
270
271 if (UserInfo->LogonHours.UnitsPerWeek > 0)
272 Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8;
273
274 if (LogonServer.Length > 0)
275 Size += LogonServer.Length + sizeof(WCHAR);
276
277 if (UserInfo->ProfilePath.Length > 0)
278 Size += UserInfo->ProfilePath.Length + sizeof(WCHAR);
279
280 if (UserInfo->HomeDirectoryDrive.Length > 0)
281 Size += UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR);
282 break;
283
284 case 4:
285 Size = sizeof(USER_INFO_4) +
286 UserInfo->UserName.Length + sizeof(WCHAR);
287
288 if (UserInfo->HomeDirectory.Length > 0)
289 Size += UserInfo->HomeDirectory.Length + sizeof(WCHAR);
290
291 if (UserInfo->AdminComment.Length > 0)
292 Size += UserInfo->AdminComment.Length + sizeof(WCHAR);
293
294 if (UserInfo->ScriptPath.Length > 0)
295 Size += UserInfo->ScriptPath.Length + sizeof(WCHAR);
296
297 if (UserInfo->FullName.Length > 0)
298 Size += UserInfo->FullName.Length + sizeof(WCHAR);
299
300 if (UserInfo->UserComment.Length > 0)
301 Size += UserInfo->UserComment.Length + sizeof(WCHAR);
302
303 if (UserInfo->Parameters.Length > 0)
304 Size += UserInfo->Parameters.Length + sizeof(WCHAR);
305
306 if (UserInfo->WorkStations.Length > 0)
307 Size += UserInfo->WorkStations.Length + sizeof(WCHAR);
308
309 if (UserInfo->LogonHours.UnitsPerWeek > 0)
310 Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8;
311
312 if (LogonServer.Length > 0)
313 Size += LogonServer.Length + sizeof(WCHAR);
314
315 /* FIXME: usri4_user_sid */
316
317 if (UserInfo->ProfilePath.Length > 0)
318 Size += UserInfo->ProfilePath.Length + sizeof(WCHAR);
319
320 if (UserInfo->HomeDirectoryDrive.Length > 0)
321 Size += UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR);
322 break;
323
324 case 10:
325 Size = sizeof(USER_INFO_10) +
326 UserInfo->UserName.Length + sizeof(WCHAR);
327
328 if (UserInfo->AdminComment.Length > 0)
329 Size += UserInfo->AdminComment.Length + sizeof(WCHAR);
330
331 if (UserInfo->UserComment.Length > 0)
332 Size += UserInfo->UserComment.Length + sizeof(WCHAR);
333
334 if (UserInfo->FullName.Length > 0)
335 Size += UserInfo->FullName.Length + sizeof(WCHAR);
336 break;
337
338 case 11:
339 Size = sizeof(USER_INFO_11) +
340 UserInfo->UserName.Length + sizeof(WCHAR);
341
342 if (UserInfo->AdminComment.Length > 0)
343 Size += UserInfo->AdminComment.Length + sizeof(WCHAR);
344
345 if (UserInfo->UserComment.Length > 0)
346 Size += UserInfo->UserComment.Length + sizeof(WCHAR);
347
348 if (UserInfo->FullName.Length > 0)
349 Size += UserInfo->FullName.Length + sizeof(WCHAR);
350
351 if (UserInfo->HomeDirectory.Length > 0)
352 Size += UserInfo->HomeDirectory.Length + sizeof(WCHAR);
353
354 if (UserInfo->Parameters.Length > 0)
355 Size += UserInfo->Parameters.Length + sizeof(WCHAR);
356
357 if (LogonServer.Length > 0)
358 Size += LogonServer.Length + sizeof(WCHAR);
359
360 if (UserInfo->WorkStations.Length > 0)
361 Size += UserInfo->WorkStations.Length + sizeof(WCHAR);
362
363 if (UserInfo->LogonHours.UnitsPerWeek > 0)
364 Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8;
365 break;
366
367 case 20:
368 Size = sizeof(USER_INFO_20) +
369 UserInfo->UserName.Length + sizeof(WCHAR);
370
371 if (UserInfo->FullName.Length > 0)
372 Size += UserInfo->FullName.Length + sizeof(WCHAR);
373
374 if (UserInfo->AdminComment.Length > 0)
375 Size += UserInfo->AdminComment.Length + sizeof(WCHAR);
376 break;
377
378 case 23:
379 Size = sizeof(USER_INFO_23) +
380 UserInfo->UserName.Length + sizeof(WCHAR);
381
382 if (UserInfo->FullName.Length > 0)
383 Size += UserInfo->FullName.Length + sizeof(WCHAR);
384
385 if (UserInfo->AdminComment.Length > 0)
386 Size += UserInfo->AdminComment.Length + sizeof(WCHAR);
387
388 /* FIXME: usri23_user_sid */
389 break;
390
391 default:
392 ApiStatus = ERROR_INVALID_LEVEL;
393 goto done;
394 }
395
396 ApiStatus = NetApiBufferAllocate(Size, &LocalBuffer);
397 if (ApiStatus != NERR_Success)
398 goto done;
399
400 ZeroMemory(LocalBuffer, Size);
401
402 switch (level)
403 {
404 case 0:
405 UserInfo0 = (PUSER_INFO_0)LocalBuffer;
406
407 Ptr = (LPWSTR)((ULONG_PTR)UserInfo0 + sizeof(USER_INFO_0));
408 UserInfo0->usri0_name = Ptr;
409
410 memcpy(UserInfo0->usri0_name,
411 UserInfo->UserName.Buffer,
412 UserInfo->UserName.Length);
413 UserInfo0->usri0_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
414 break;
415
416 case 1:
417 UserInfo1 = (PUSER_INFO_1)LocalBuffer;
418
419 Ptr = (LPWSTR)((ULONG_PTR)UserInfo1 + sizeof(USER_INFO_1));
420
421 UserInfo1->usri1_name = Ptr;
422
423 memcpy(UserInfo1->usri1_name,
424 UserInfo->UserName.Buffer,
425 UserInfo->UserName.Length);
426 UserInfo1->usri1_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
427
428 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
429
430 UserInfo1->usri1_password = NULL;
431
432 UserInfo1->usri1_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
433
434 /* FIXME: UserInfo1->usri1_priv */
435
436 if (UserInfo->HomeDirectory.Length > 0)
437 {
438 UserInfo1->usri1_home_dir = Ptr;
439
440 memcpy(UserInfo1->usri1_home_dir,
441 UserInfo->HomeDirectory.Buffer,
442 UserInfo->HomeDirectory.Length);
443 UserInfo1->usri1_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
444
445 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
446 }
447
448 if (UserInfo->AdminComment.Length > 0)
449 {
450 UserInfo1->usri1_comment = Ptr;
451
452 memcpy(UserInfo1->usri1_comment,
453 UserInfo->AdminComment.Buffer,
454 UserInfo->AdminComment.Length);
455 UserInfo1->usri1_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
456
457 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
458 }
459
460 UserInfo1->usri1_flags = GetAccountFlags(UserInfo->UserAccountControl);
461
462 if (UserInfo->ScriptPath.Length > 0)
463 {
464 UserInfo1->usri1_script_path = Ptr;
465
466 memcpy(UserInfo1->usri1_script_path,
467 UserInfo->ScriptPath.Buffer,
468 UserInfo->ScriptPath.Length);
469 UserInfo1->usri1_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
470 }
471 break;
472
473 case 2:
474 UserInfo2 = (PUSER_INFO_2)LocalBuffer;
475
476 Ptr = (LPWSTR)((ULONG_PTR)UserInfo2 + sizeof(USER_INFO_2));
477
478 UserInfo2->usri2_name = Ptr;
479
480 memcpy(UserInfo2->usri2_name,
481 UserInfo->UserName.Buffer,
482 UserInfo->UserName.Length);
483 UserInfo2->usri2_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
484
485 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
486
487 UserInfo2->usri2_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
488
489 /* FIXME: usri2_priv */
490
491 if (UserInfo->HomeDirectory.Length > 0)
492 {
493 UserInfo2->usri2_home_dir = Ptr;
494
495 memcpy(UserInfo2->usri2_home_dir,
496 UserInfo->HomeDirectory.Buffer,
497 UserInfo->HomeDirectory.Length);
498 UserInfo2->usri2_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
499
500 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
501 }
502
503 if (UserInfo->AdminComment.Length > 0)
504 {
505 UserInfo2->usri2_comment = Ptr;
506
507 memcpy(UserInfo2->usri2_comment,
508 UserInfo->AdminComment.Buffer,
509 UserInfo->AdminComment.Length);
510 UserInfo2->usri2_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
511
512 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
513 }
514
515 UserInfo2->usri2_flags = GetAccountFlags(UserInfo->UserAccountControl);
516
517 if (UserInfo->ScriptPath.Length > 0)
518 {
519 UserInfo2->usri2_script_path = Ptr;
520
521 memcpy(UserInfo2->usri2_script_path,
522 UserInfo->ScriptPath.Buffer,
523 UserInfo->ScriptPath.Length);
524 UserInfo2->usri2_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
525
526 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR));
527 }
528
529 /* FIXME: usri2_auth_flags */
530
531 if (UserInfo->FullName.Length > 0)
532 {
533 UserInfo2->usri2_full_name = Ptr;
534
535 memcpy(UserInfo2->usri2_full_name,
536 UserInfo->FullName.Buffer,
537 UserInfo->FullName.Length);
538 UserInfo2->usri2_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
539
540 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
541 }
542
543 if (UserInfo->UserComment.Length > 0)
544 {
545 UserInfo2->usri2_usr_comment = Ptr;
546
547 memcpy(UserInfo2->usri2_usr_comment,
548 UserInfo->UserComment.Buffer,
549 UserInfo->UserComment.Length);
550 UserInfo2->usri2_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
551
552 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
553 }
554
555 if (UserInfo->Parameters.Length > 0)
556 {
557 UserInfo2->usri2_parms = Ptr;
558
559 memcpy(UserInfo2->usri2_parms,
560 UserInfo->Parameters.Buffer,
561 UserInfo->Parameters.Length);
562 UserInfo2->usri2_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL;
563
564 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
565 }
566
567 if (UserInfo->WorkStations.Length > 0)
568 {
569 UserInfo2->usri2_workstations = Ptr;
570
571 memcpy(UserInfo2->usri2_workstations,
572 UserInfo->WorkStations.Buffer,
573 UserInfo->WorkStations.Length);
574 UserInfo2->usri2_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL;
575
576 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
577 }
578
579 RtlTimeToSecondsSince1970(&UserInfo->LastLogon,
580 &UserInfo2->usri2_last_logon);
581
582 RtlTimeToSecondsSince1970(&UserInfo->LastLogoff,
583 &UserInfo2->usri2_last_logoff);
584
585 RtlTimeToSecondsSince1970(&UserInfo->AccountExpires,
586 &UserInfo2->usri2_acct_expires);
587
588 UserInfo2->usri2_max_storage = USER_MAXSTORAGE_UNLIMITED;
589 UserInfo2->usri2_units_per_week = UserInfo->LogonHours.UnitsPerWeek;
590
591 if (UserInfo->LogonHours.UnitsPerWeek > 0)
592 {
593 UserInfo2->usri2_logon_hours = (PVOID)Ptr;
594
595 memcpy(UserInfo2->usri2_logon_hours,
596 UserInfo->LogonHours.LogonHours,
597 (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
598
599 Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
600 }
601
602 UserInfo2->usri2_bad_pw_count = UserInfo->BadPasswordCount;
603 UserInfo2->usri2_num_logons = UserInfo->LogonCount;
604
605 if (LogonServer.Length > 0)
606 {
607 UserInfo2->usri2_logon_server = Ptr;
608
609 memcpy(UserInfo2->usri2_logon_server,
610 LogonServer.Buffer,
611 LogonServer.Length);
612 UserInfo2->usri2_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL;
613
614 Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
615 }
616
617 UserInfo2->usri2_country_code = UserInfo->CountryCode;
618 UserInfo2->usri2_code_page = UserInfo->CodePage;
619 break;
620
621 case 3:
622 UserInfo3 = (PUSER_INFO_3)LocalBuffer;
623
624 Ptr = (LPWSTR)((ULONG_PTR)UserInfo3 + sizeof(USER_INFO_3));
625
626 UserInfo3->usri3_name = Ptr;
627
628 memcpy(UserInfo3->usri3_name,
629 UserInfo->UserName.Buffer,
630 UserInfo->UserName.Length);
631 UserInfo3->usri3_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
632
633 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
634
635 UserInfo3->usri3_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
636
637 /* FIXME: usri3_priv */
638
639 if (UserInfo->HomeDirectory.Length > 0)
640 {
641 UserInfo3->usri3_home_dir = Ptr;
642
643 memcpy(UserInfo3->usri3_home_dir,
644 UserInfo->HomeDirectory.Buffer,
645 UserInfo->HomeDirectory.Length);
646 UserInfo3->usri3_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
647
648 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
649 }
650
651 if (UserInfo->AdminComment.Length > 0)
652 {
653 UserInfo3->usri3_comment = Ptr;
654
655 memcpy(UserInfo3->usri3_comment,
656 UserInfo->AdminComment.Buffer,
657 UserInfo->AdminComment.Length);
658 UserInfo3->usri3_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
659
660 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
661 }
662
663 UserInfo3->usri3_flags = GetAccountFlags(UserInfo->UserAccountControl);
664
665 if (UserInfo->ScriptPath.Length > 0)
666 {
667 UserInfo3->usri3_script_path = Ptr;
668
669 memcpy(UserInfo3->usri3_script_path,
670 UserInfo->ScriptPath.Buffer,
671 UserInfo->ScriptPath.Length);
672 UserInfo3->usri3_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
673
674 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR));
675 }
676
677 /* FIXME: usri3_auth_flags */
678
679 if (UserInfo->FullName.Length > 0)
680 {
681 UserInfo3->usri3_full_name = Ptr;
682
683 memcpy(UserInfo3->usri3_full_name,
684 UserInfo->FullName.Buffer,
685 UserInfo->FullName.Length);
686 UserInfo3->usri3_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
687
688 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
689 }
690
691 if (UserInfo->UserComment.Length > 0)
692 {
693 UserInfo3->usri3_usr_comment = Ptr;
694
695 memcpy(UserInfo3->usri3_usr_comment,
696 UserInfo->UserComment.Buffer,
697 UserInfo->UserComment.Length);
698 UserInfo3->usri3_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
699
700 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
701 }
702
703 if (UserInfo->Parameters.Length > 0)
704 {
705 UserInfo3->usri3_parms = Ptr;
706
707 memcpy(UserInfo3->usri3_parms,
708 UserInfo->Parameters.Buffer,
709 UserInfo->Parameters.Length);
710 UserInfo3->usri3_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL;
711
712 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
713 }
714
715 if (UserInfo->WorkStations.Length > 0)
716 {
717 UserInfo3->usri3_workstations = Ptr;
718
719 memcpy(UserInfo3->usri3_workstations,
720 UserInfo->WorkStations.Buffer,
721 UserInfo->WorkStations.Length);
722 UserInfo3->usri3_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL;
723
724 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
725 }
726
727 RtlTimeToSecondsSince1970(&UserInfo->LastLogon,
728 &UserInfo3->usri3_last_logon);
729
730 RtlTimeToSecondsSince1970(&UserInfo->LastLogoff,
731 &UserInfo3->usri3_last_logoff);
732
733 RtlTimeToSecondsSince1970(&UserInfo->AccountExpires,
734 &UserInfo3->usri3_acct_expires);
735
736 UserInfo3->usri3_max_storage = USER_MAXSTORAGE_UNLIMITED;
737 UserInfo3->usri3_units_per_week = UserInfo->LogonHours.UnitsPerWeek;
738
739 if (UserInfo->LogonHours.UnitsPerWeek > 0)
740 {
741 UserInfo3->usri3_logon_hours = (PVOID)Ptr;
742
743 memcpy(UserInfo3->usri3_logon_hours,
744 UserInfo->LogonHours.LogonHours,
745 (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
746
747 Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
748 }
749
750 UserInfo3->usri3_bad_pw_count = UserInfo->BadPasswordCount;
751 UserInfo3->usri3_num_logons = UserInfo->LogonCount;
752
753 if (LogonServer.Length > 0)
754 {
755 UserInfo3->usri3_logon_server = Ptr;
756
757 memcpy(UserInfo3->usri3_logon_server,
758 LogonServer.Buffer,
759 LogonServer.Length);
760 UserInfo3->usri3_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL;
761
762 Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
763 }
764
765 UserInfo3->usri3_country_code = UserInfo->CountryCode;
766 UserInfo3->usri3_code_page = UserInfo->CodePage;
767 UserInfo3->usri3_user_id = RelativeId;
768 UserInfo3->usri3_primary_group_id = UserInfo->PrimaryGroupId;
769
770 if (UserInfo->ProfilePath.Length > 0)
771 {
772 UserInfo3->usri3_profile = Ptr;
773
774 memcpy(UserInfo3->usri3_profile,
775 UserInfo->ProfilePath.Buffer,
776 UserInfo->ProfilePath.Length);
777 UserInfo3->usri3_profile[UserInfo->ProfilePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
778
779 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ProfilePath.Length + sizeof(WCHAR));
780 }
781
782 if (UserInfo->HomeDirectoryDrive.Length > 0)
783 {
784 UserInfo3->usri3_home_dir_drive = Ptr;
785
786 memcpy(UserInfo3->usri3_home_dir_drive,
787 UserInfo->HomeDirectoryDrive.Buffer,
788 UserInfo->HomeDirectoryDrive.Length);
789 UserInfo3->usri3_home_dir_drive[UserInfo->HomeDirectoryDrive.Length / sizeof(WCHAR)] = UNICODE_NULL;
790
791 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR));
792 }
793
794 UserInfo3->usri3_password_expired = (UserInfo->UserAccountControl & USER_PASSWORD_EXPIRED);
795 break;
796
797 case 4:
798 UserInfo4 = (PUSER_INFO_4)LocalBuffer;
799
800 Ptr = (LPWSTR)((ULONG_PTR)UserInfo4 + sizeof(USER_INFO_4));
801
802 UserInfo4->usri4_name = Ptr;
803
804 memcpy(UserInfo4->usri4_name,
805 UserInfo->UserName.Buffer,
806 UserInfo->UserName.Length);
807 UserInfo4->usri4_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
808
809 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
810
811 UserInfo4->usri4_password = NULL;
812 UserInfo4->usri4_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
813
814 /* FIXME: usri4_priv */
815
816 if (UserInfo->HomeDirectory.Length > 0)
817 {
818 UserInfo4->usri4_home_dir = Ptr;
819
820 memcpy(UserInfo4->usri4_home_dir,
821 UserInfo->HomeDirectory.Buffer,
822 UserInfo->HomeDirectory.Length);
823 UserInfo4->usri4_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
824
825 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
826 }
827
828 if (UserInfo->AdminComment.Length > 0)
829 {
830 UserInfo4->usri4_comment = Ptr;
831
832 memcpy(UserInfo4->usri4_comment,
833 UserInfo->AdminComment.Buffer,
834 UserInfo->AdminComment.Length);
835 UserInfo4->usri4_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
836
837 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
838 }
839
840 UserInfo4->usri4_flags = GetAccountFlags(UserInfo->UserAccountControl);
841
842 if (UserInfo->ScriptPath.Length > 0)
843 {
844 UserInfo4->usri4_script_path = Ptr;
845
846 memcpy(UserInfo4->usri4_script_path,
847 UserInfo->ScriptPath.Buffer,
848 UserInfo->ScriptPath.Length);
849 UserInfo4->usri4_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
850
851 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR));
852 }
853
854 /* FIXME: usri4_auth_flags */
855
856 if (UserInfo->FullName.Length > 0)
857 {
858 UserInfo4->usri4_full_name = Ptr;
859
860 memcpy(UserInfo4->usri4_full_name,
861 UserInfo->FullName.Buffer,
862 UserInfo->FullName.Length);
863 UserInfo4->usri4_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
864
865 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
866 }
867
868 if (UserInfo->UserComment.Length > 0)
869 {
870 UserInfo4->usri4_usr_comment = Ptr;
871
872 memcpy(UserInfo4->usri4_usr_comment,
873 UserInfo->UserComment.Buffer,
874 UserInfo->UserComment.Length);
875 UserInfo4->usri4_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
876
877 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
878 }
879
880 if (UserInfo->Parameters.Length > 0)
881 {
882 UserInfo4->usri4_parms = Ptr;
883
884 memcpy(UserInfo4->usri4_parms,
885 UserInfo->Parameters.Buffer,
886 UserInfo->Parameters.Length);
887 UserInfo4->usri4_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL;
888
889 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
890 }
891
892 if (UserInfo->WorkStations.Length > 0)
893 {
894 UserInfo4->usri4_workstations = Ptr;
895
896 memcpy(UserInfo4->usri4_workstations,
897 UserInfo->WorkStations.Buffer,
898 UserInfo->WorkStations.Length);
899 UserInfo4->usri4_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL;
900
901 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
902 }
903
904 RtlTimeToSecondsSince1970(&UserInfo->LastLogon,
905 &UserInfo4->usri4_last_logon);
906
907 RtlTimeToSecondsSince1970(&UserInfo->LastLogoff,
908 &UserInfo4->usri4_last_logoff);
909
910 RtlTimeToSecondsSince1970(&UserInfo->AccountExpires,
911 &UserInfo4->usri4_acct_expires);
912
913 UserInfo4->usri4_max_storage = USER_MAXSTORAGE_UNLIMITED;
914 UserInfo4->usri4_units_per_week = UserInfo->LogonHours.UnitsPerWeek;
915
916 if (UserInfo->LogonHours.UnitsPerWeek > 0)
917 {
918 UserInfo4->usri4_logon_hours = (PVOID)Ptr;
919
920 memcpy(UserInfo4->usri4_logon_hours,
921 UserInfo->LogonHours.LogonHours,
922 (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
923
924 Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
925 }
926
927 UserInfo4->usri4_bad_pw_count = UserInfo->BadPasswordCount;
928 UserInfo4->usri4_num_logons = UserInfo->LogonCount;
929
930 if (LogonServer.Length > 0)
931 {
932 UserInfo4->usri4_logon_server = Ptr;
933
934 memcpy(UserInfo4->usri4_logon_server,
935 LogonServer.Buffer,
936 LogonServer.Length);
937 UserInfo4->usri4_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL;
938
939 Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
940 }
941
942 UserInfo4->usri4_country_code = UserInfo->CountryCode;
943 UserInfo4->usri4_code_page = UserInfo->CodePage;
944
945 /* FIXME: usri4_user_sid */
946
947 UserInfo4->usri4_primary_group_id = UserInfo->PrimaryGroupId;
948
949 if (UserInfo->ProfilePath.Length > 0)
950 {
951 UserInfo4->usri4_profile = Ptr;
952
953 memcpy(UserInfo4->usri4_profile,
954 UserInfo->ProfilePath.Buffer,
955 UserInfo->ProfilePath.Length);
956 UserInfo4->usri4_profile[UserInfo->ProfilePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
957
958 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ProfilePath.Length + sizeof(WCHAR));
959 }
960
961 if (UserInfo->HomeDirectoryDrive.Length > 0)
962 {
963 UserInfo4->usri4_home_dir_drive = Ptr;
964
965 memcpy(UserInfo4->usri4_home_dir_drive,
966 UserInfo->HomeDirectoryDrive.Buffer,
967 UserInfo->HomeDirectoryDrive.Length);
968 UserInfo4->usri4_home_dir_drive[UserInfo->HomeDirectoryDrive.Length / sizeof(WCHAR)] = UNICODE_NULL;
969
970 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR));
971 }
972
973 UserInfo4->usri4_password_expired = (UserInfo->UserAccountControl & USER_PASSWORD_EXPIRED);
974 break;
975
976 case 10:
977 UserInfo10 = (PUSER_INFO_10)LocalBuffer;
978
979 Ptr = (LPWSTR)((ULONG_PTR)UserInfo10 + sizeof(USER_INFO_10));
980
981 UserInfo10->usri10_name = Ptr;
982
983 memcpy(UserInfo10->usri10_name,
984 UserInfo->UserName.Buffer,
985 UserInfo->UserName.Length);
986 UserInfo10->usri10_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
987
988 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
989
990 if (UserInfo->AdminComment.Length > 0)
991 {
992 UserInfo10->usri10_comment = Ptr;
993
994 memcpy(UserInfo10->usri10_comment,
995 UserInfo->AdminComment.Buffer,
996 UserInfo->AdminComment.Length);
997 UserInfo10->usri10_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
998
999 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
1000 }
1001
1002 if (UserInfo->UserComment.Length > 0)
1003 {
1004 UserInfo10->usri10_usr_comment = Ptr;
1005
1006 memcpy(UserInfo10->usri10_usr_comment,
1007 UserInfo->UserComment.Buffer,
1008 UserInfo->UserComment.Length);
1009 UserInfo10->usri10_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1010
1011 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
1012 }
1013
1014 if (UserInfo->FullName.Length > 0)
1015 {
1016 UserInfo10->usri10_full_name = Ptr;
1017
1018 memcpy(UserInfo10->usri10_full_name,
1019 UserInfo->FullName.Buffer,
1020 UserInfo->FullName.Length);
1021 UserInfo10->usri10_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1022
1023 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
1024 }
1025 break;
1026
1027 case 11:
1028 UserInfo11 = (PUSER_INFO_11)LocalBuffer;
1029
1030 Ptr = (LPWSTR)((ULONG_PTR)UserInfo11 + sizeof(USER_INFO_11));
1031
1032 UserInfo11->usri11_name = Ptr;
1033
1034 memcpy(UserInfo11->usri11_name,
1035 UserInfo->UserName.Buffer,
1036 UserInfo->UserName.Length);
1037 UserInfo11->usri11_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1038
1039 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
1040
1041 if (UserInfo->AdminComment.Length > 0)
1042 {
1043 UserInfo11->usri11_comment = Ptr;
1044
1045 memcpy(UserInfo11->usri11_comment,
1046 UserInfo->AdminComment.Buffer,
1047 UserInfo->AdminComment.Length);
1048 UserInfo11->usri11_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1049
1050 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
1051 }
1052
1053 if (UserInfo->UserComment.Length > 0)
1054 {
1055 UserInfo11->usri11_usr_comment = Ptr;
1056
1057 memcpy(UserInfo11->usri11_usr_comment,
1058 UserInfo->UserComment.Buffer,
1059 UserInfo->UserComment.Length);
1060 UserInfo11->usri11_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1061
1062 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
1063 }
1064
1065 if (UserInfo->FullName.Length > 0)
1066 {
1067 UserInfo11->usri11_full_name = Ptr;
1068
1069 memcpy(UserInfo11->usri11_full_name,
1070 UserInfo->FullName.Buffer,
1071 UserInfo->FullName.Length);
1072 UserInfo11->usri11_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1073
1074 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
1075 }
1076
1077 /* FIXME: usri11_priv */
1078 /* FIXME: usri11_auth_flags */
1079
1080 UserInfo11->usri11_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
1081
1082 if (UserInfo->HomeDirectory.Length > 0)
1083 {
1084 UserInfo11->usri11_home_dir = Ptr;
1085
1086 memcpy(UserInfo11->usri11_home_dir,
1087 UserInfo->HomeDirectory.Buffer,
1088 UserInfo->HomeDirectory.Length);
1089 UserInfo11->usri11_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
1090
1091 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
1092 }
1093
1094 if (UserInfo->Parameters.Length > 0)
1095 {
1096 UserInfo11->usri11_parms = Ptr;
1097
1098 memcpy(UserInfo11->usri11_parms,
1099 UserInfo->Parameters.Buffer,
1100 UserInfo->Parameters.Length);
1101 UserInfo11->usri11_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL;
1102
1103 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
1104 }
1105
1106 RtlTimeToSecondsSince1970(&UserInfo->LastLogon,
1107 &UserInfo11->usri11_last_logon);
1108
1109 RtlTimeToSecondsSince1970(&UserInfo->LastLogoff,
1110 &UserInfo11->usri11_last_logoff);
1111
1112 UserInfo11->usri11_bad_pw_count = UserInfo->BadPasswordCount;
1113 UserInfo11->usri11_num_logons = UserInfo->LogonCount;
1114
1115 if (LogonServer.Length > 0)
1116 {
1117 UserInfo11->usri11_logon_server = Ptr;
1118
1119 memcpy(UserInfo11->usri11_logon_server,
1120 LogonServer.Buffer,
1121 LogonServer.Length);
1122 UserInfo11->usri11_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL;
1123
1124 Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
1125 }
1126
1127 UserInfo11->usri11_country_code = UserInfo->CountryCode;
1128
1129 if (UserInfo->WorkStations.Length > 0)
1130 {
1131 UserInfo11->usri11_workstations = Ptr;
1132
1133 memcpy(UserInfo11->usri11_workstations,
1134 UserInfo->WorkStations.Buffer,
1135 UserInfo->WorkStations.Length);
1136 UserInfo11->usri11_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL;
1137
1138 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
1139 }
1140
1141 UserInfo11->usri11_max_storage = USER_MAXSTORAGE_UNLIMITED;
1142 UserInfo11->usri11_units_per_week = UserInfo->LogonHours.UnitsPerWeek;
1143
1144 if (UserInfo->LogonHours.UnitsPerWeek > 0)
1145 {
1146 UserInfo11->usri11_logon_hours = (PVOID)Ptr;
1147
1148 memcpy(UserInfo11->usri11_logon_hours,
1149 UserInfo->LogonHours.LogonHours,
1150 (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
1151
1152 Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8);
1153 }
1154
1155 UserInfo11->usri11_code_page = UserInfo->CodePage;
1156 break;
1157
1158 case 20:
1159 UserInfo20 = (PUSER_INFO_20)LocalBuffer;
1160
1161 Ptr = (LPWSTR)((ULONG_PTR)UserInfo20 + sizeof(USER_INFO_20));
1162
1163 UserInfo20->usri20_name = Ptr;
1164
1165 memcpy(UserInfo20->usri20_name,
1166 UserInfo->UserName.Buffer,
1167 UserInfo->UserName.Length);
1168 UserInfo20->usri20_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1169
1170 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
1171
1172 if (UserInfo->FullName.Length > 0)
1173 {
1174 UserInfo20->usri20_full_name = Ptr;
1175
1176 memcpy(UserInfo20->usri20_full_name,
1177 UserInfo->FullName.Buffer,
1178 UserInfo->FullName.Length);
1179 UserInfo20->usri20_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1180
1181 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
1182 }
1183
1184 if (UserInfo->AdminComment.Length > 0)
1185 {
1186 UserInfo20->usri20_comment = Ptr;
1187
1188 memcpy(UserInfo20->usri20_comment,
1189 UserInfo->AdminComment.Buffer,
1190 UserInfo->AdminComment.Length);
1191 UserInfo20->usri20_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1192
1193 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
1194 }
1195
1196 UserInfo20->usri20_flags = GetAccountFlags(UserInfo->UserAccountControl);
1197
1198 UserInfo20->usri20_user_id = RelativeId;
1199 break;
1200
1201 case 23:
1202 UserInfo23 = (PUSER_INFO_23)LocalBuffer;
1203
1204 Ptr = (LPWSTR)((ULONG_PTR)UserInfo23 + sizeof(USER_INFO_23));
1205
1206 UserInfo23->usri23_name = Ptr;
1207
1208 memcpy(UserInfo23->usri23_name,
1209 UserInfo->UserName.Buffer,
1210 UserInfo->UserName.Length);
1211 UserInfo23->usri23_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1212
1213 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
1214
1215 if (UserInfo->FullName.Length > 0)
1216 {
1217 UserInfo23->usri23_full_name = Ptr;
1218
1219 memcpy(UserInfo23->usri23_full_name,
1220 UserInfo->FullName.Buffer,
1221 UserInfo->FullName.Length);
1222 UserInfo23->usri23_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1223
1224 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
1225 }
1226
1227 if (UserInfo->AdminComment.Length > 0)
1228 {
1229 UserInfo23->usri23_comment = Ptr;
1230
1231 memcpy(UserInfo23->usri23_comment,
1232 UserInfo->AdminComment.Buffer,
1233 UserInfo->AdminComment.Length);
1234 UserInfo23->usri23_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
1235
1236 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
1237 }
1238
1239 UserInfo23->usri23_flags = GetAccountFlags(UserInfo->UserAccountControl);
1240
1241 /* FIXME: usri23_user_sid */
1242 break;
1243 }
1244
1245 done:
1246 if (ApiStatus == NERR_Success)
1247 {
1248 *Buffer = LocalBuffer;
1249 }
1250 else
1251 {
1252 if (LocalBuffer != NULL)
1253 NetApiBufferFree(LocalBuffer);
1254 }
1255
1256 return ApiStatus;
1257 }
1258
1259
1260 static
1261 VOID
1262 FreeUserInfo(PUSER_ALL_INFORMATION UserInfo)
1263 {
1264 if (UserInfo->UserName.Buffer != NULL)
1265 SamFreeMemory(UserInfo->UserName.Buffer);
1266
1267 if (UserInfo->FullName.Buffer != NULL)
1268 SamFreeMemory(UserInfo->FullName.Buffer);
1269
1270 if (UserInfo->HomeDirectory.Buffer != NULL)
1271 SamFreeMemory(UserInfo->HomeDirectory.Buffer);
1272
1273 if (UserInfo->HomeDirectoryDrive.Buffer != NULL)
1274 SamFreeMemory(UserInfo->HomeDirectoryDrive.Buffer);
1275
1276 if (UserInfo->ScriptPath.Buffer != NULL)
1277 SamFreeMemory(UserInfo->ScriptPath.Buffer);
1278
1279 if (UserInfo->ProfilePath.Buffer != NULL)
1280 SamFreeMemory(UserInfo->ProfilePath.Buffer);
1281
1282 if (UserInfo->AdminComment.Buffer != NULL)
1283 SamFreeMemory(UserInfo->AdminComment.Buffer);
1284
1285 if (UserInfo->WorkStations.Buffer != NULL)
1286 SamFreeMemory(UserInfo->WorkStations.Buffer);
1287
1288 if (UserInfo->UserComment.Buffer != NULL)
1289 SamFreeMemory(UserInfo->UserComment.Buffer);
1290
1291 if (UserInfo->Parameters.Buffer != NULL)
1292 SamFreeMemory(UserInfo->Parameters.Buffer);
1293
1294 if (UserInfo->PrivateData.Buffer != NULL)
1295 SamFreeMemory(UserInfo->PrivateData.Buffer);
1296
1297 if (UserInfo->LogonHours.LogonHours != NULL)
1298 SamFreeMemory(UserInfo->LogonHours.LogonHours);
1299
1300 SamFreeMemory(UserInfo);
1301 }
1302
1303
1304 static
1305 NET_API_STATUS
1306 SetUserInfo(SAM_HANDLE UserHandle,
1307 LPBYTE UserInfo,
1308 DWORD Level)
1309 {
1310 USER_ALL_INFORMATION UserAllInfo;
1311 PUSER_INFO_0 UserInfo0;
1312 PUSER_INFO_1 UserInfo1;
1313 PUSER_INFO_2 UserInfo2;
1314 PUSER_INFO_3 UserInfo3;
1315 PUSER_INFO_4 UserInfo4;
1316 PUSER_INFO_1003 UserInfo1003;
1317 PUSER_INFO_1006 UserInfo1006;
1318 PUSER_INFO_1007 UserInfo1007;
1319 PUSER_INFO_1008 UserInfo1008;
1320 PUSER_INFO_1009 UserInfo1009;
1321 PUSER_INFO_1011 UserInfo1011;
1322 PUSER_INFO_1012 UserInfo1012;
1323 PUSER_INFO_1013 UserInfo1013;
1324 PUSER_INFO_1014 UserInfo1014;
1325 PUSER_INFO_1017 UserInfo1017;
1326 PUSER_INFO_1024 UserInfo1024;
1327 PUSER_INFO_1025 UserInfo1025;
1328 PUSER_INFO_1051 UserInfo1051;
1329 PUSER_INFO_1052 UserInfo1052;
1330 PUSER_INFO_1053 UserInfo1053;
1331 NET_API_STATUS ApiStatus = NERR_Success;
1332 NTSTATUS Status = STATUS_SUCCESS;
1333
1334 ZeroMemory(&UserAllInfo, sizeof(USER_ALL_INFORMATION));
1335
1336 switch (Level)
1337 {
1338 case 0:
1339 UserInfo0 = (PUSER_INFO_0)UserInfo;
1340
1341 RtlInitUnicodeString(&UserAllInfo.UserName,
1342 UserInfo0->usri0_name);
1343
1344 UserAllInfo.WhichFields |= USER_ALL_USERNAME;
1345 break;
1346
1347 case 1:
1348 UserInfo1 = (PUSER_INFO_1)UserInfo;
1349
1350 // usri1_name ignored
1351
1352 if (UserInfo1->usri1_password != NULL)
1353 {
1354 RtlInitUnicodeString(&UserAllInfo.NtPassword,
1355 UserInfo1->usri1_password);
1356 UserAllInfo.NtPasswordPresent = TRUE;
1357 UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
1358 }
1359
1360 // usri1_password_age ignored
1361
1362 // UserInfo1->usri1_priv
1363
1364 if (UserInfo1->usri1_home_dir != NULL)
1365 {
1366 RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1367 UserInfo1->usri1_home_dir);
1368 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1369 }
1370
1371 if (UserInfo1->usri1_comment != NULL)
1372 {
1373 RtlInitUnicodeString(&UserAllInfo.AdminComment,
1374 UserInfo1->usri1_comment);
1375 UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1376 }
1377
1378 UserAllInfo.UserAccountControl = GetAccountControl(UserInfo1->usri1_flags);
1379 UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
1380
1381 if (UserInfo1->usri1_script_path != NULL)
1382 {
1383 RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1384 UserInfo1->usri1_script_path);
1385 UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1386 }
1387 break;
1388
1389 case 2:
1390 UserInfo2 = (PUSER_INFO_2)UserInfo;
1391
1392 // usri2_name ignored
1393
1394 if (UserInfo2->usri2_password != NULL)
1395 {
1396 RtlInitUnicodeString(&UserAllInfo.NtPassword,
1397 UserInfo2->usri2_password);
1398 UserAllInfo.NtPasswordPresent = TRUE;
1399 UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
1400 }
1401
1402 // usri2_password_age ignored
1403
1404 // UserInfo2->usri2_priv;
1405
1406 if (UserInfo2->usri2_home_dir != NULL)
1407 {
1408 RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1409 UserInfo2->usri2_home_dir);
1410 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1411 }
1412
1413 if (UserInfo2->usri2_comment != NULL)
1414 {
1415 RtlInitUnicodeString(&UserAllInfo.AdminComment,
1416 UserInfo2->usri2_comment);
1417 UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1418 }
1419
1420 UserAllInfo.UserAccountControl = GetAccountControl(UserInfo2->usri2_flags);
1421 UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
1422
1423 if (UserInfo2->usri2_script_path != NULL)
1424 {
1425 RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1426 UserInfo2->usri2_script_path);
1427 UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1428 }
1429
1430 // UserInfo2->usri2_auth_flags;
1431
1432 if (UserInfo2->usri2_full_name != NULL)
1433 {
1434 RtlInitUnicodeString(&UserAllInfo.FullName,
1435 UserInfo2->usri2_full_name);
1436 UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
1437 }
1438
1439 if (UserInfo2->usri2_usr_comment != NULL)
1440 {
1441 RtlInitUnicodeString(&UserAllInfo.UserComment,
1442 UserInfo2->usri2_usr_comment);
1443 UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
1444 }
1445
1446 if (UserInfo2->usri2_parms != NULL)
1447 {
1448 RtlInitUnicodeString(&UserAllInfo.Parameters,
1449 UserInfo2->usri2_parms);
1450 UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
1451 }
1452
1453 if (UserInfo2->usri2_workstations != NULL)
1454 {
1455 RtlInitUnicodeString(&UserAllInfo.WorkStations,
1456 UserInfo2->usri2_workstations);
1457 UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
1458 }
1459
1460 // usri2_last_logon ignored
1461 // usri2_last_logoff ignored
1462
1463 if (UserInfo2->usri2_acct_expires == TIMEQ_FOREVER)
1464 {
1465 UserAllInfo.AccountExpires.LowPart = 0;
1466 UserAllInfo.AccountExpires.HighPart = 0;
1467 }
1468 else
1469 {
1470 RtlSecondsSince1970ToTime(UserInfo2->usri2_acct_expires,
1471 &UserAllInfo.AccountExpires);
1472 }
1473 UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
1474
1475 // UserInfo2->usri2_max_storage;
1476 // UserInfo2->usri2_units_per_week;
1477 // UserInfo2->usri2_logon_hours;
1478
1479 // usri2_bad_pw_count ignored
1480 // usri2_num_logons ignored
1481 // usri2_logon_server ignored
1482
1483 UserAllInfo.CountryCode = UserInfo2->usri2_country_code;
1484 UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
1485
1486 UserAllInfo.CodePage = UserInfo2->usri2_code_page;
1487 UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
1488 break;
1489
1490 case 3:
1491 UserInfo3 = (PUSER_INFO_3)UserInfo;
1492
1493 // usri3_name ignored
1494
1495 if (UserInfo3->usri3_password != NULL)
1496 {
1497 RtlInitUnicodeString(&UserAllInfo.NtPassword,
1498 UserInfo3->usri3_password);
1499 UserAllInfo.NtPasswordPresent = TRUE;
1500 UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
1501 }
1502
1503 // usri3_password_age ignored
1504
1505 // UserInfo3->usri3_priv;
1506
1507 if (UserInfo3->usri3_home_dir != NULL)
1508 {
1509 RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1510 UserInfo3->usri3_home_dir);
1511 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1512 }
1513
1514 if (UserInfo3->usri3_comment != NULL)
1515 {
1516 RtlInitUnicodeString(&UserAllInfo.AdminComment,
1517 UserInfo3->usri3_comment);
1518 UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1519 }
1520
1521 UserAllInfo.UserAccountControl = GetAccountControl(UserInfo3->usri3_flags);
1522 UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
1523
1524 if (UserInfo3->usri3_script_path != NULL)
1525 {
1526 RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1527 UserInfo3->usri3_script_path);
1528 UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1529 }
1530
1531 // UserInfo3->usri3_auth_flags;
1532
1533 if (UserInfo3->usri3_full_name != NULL)
1534 {
1535 RtlInitUnicodeString(&UserAllInfo.FullName,
1536 UserInfo3->usri3_full_name);
1537 UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
1538 }
1539
1540 if (UserInfo3->usri3_usr_comment != NULL)
1541 {
1542 RtlInitUnicodeString(&UserAllInfo.UserComment,
1543 UserInfo3->usri3_usr_comment);
1544 UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
1545 }
1546
1547 if (UserInfo3->usri3_parms != NULL)
1548 {
1549 RtlInitUnicodeString(&UserAllInfo.Parameters,
1550 UserInfo3->usri3_parms);
1551 UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
1552 }
1553
1554 if (UserInfo3->usri3_workstations != NULL)
1555 {
1556 RtlInitUnicodeString(&UserAllInfo.WorkStations,
1557 UserInfo3->usri3_workstations);
1558 UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
1559 }
1560
1561 // usri3_last_logon ignored
1562 // usri3_last_logoff ignored
1563
1564 if (UserInfo3->usri3_acct_expires == TIMEQ_FOREVER)
1565 {
1566 UserAllInfo.AccountExpires.LowPart = 0;
1567 UserAllInfo.AccountExpires.HighPart = 0;
1568 }
1569 else
1570 {
1571 RtlSecondsSince1970ToTime(UserInfo3->usri3_acct_expires,
1572 &UserAllInfo.AccountExpires);
1573 }
1574 UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
1575
1576 // UserInfo3->usri3_max_storage;
1577 // UserInfo3->usri3_units_per_week;
1578 // UserInfo3->usri3_logon_hours;
1579
1580 // usri3_bad_pw_count ignored
1581 // usri3_num_logons ignored
1582 // usri3_logon_server ignored
1583
1584 UserAllInfo.CountryCode = UserInfo3->usri3_country_code;
1585 UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
1586
1587 UserAllInfo.CodePage = UserInfo3->usri3_code_page;
1588 UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
1589
1590 // usri3_user_id ignored
1591
1592 UserAllInfo.PrimaryGroupId = UserInfo3->usri3_primary_group_id;
1593 UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID;
1594
1595 if (UserInfo3->usri3_profile != NULL)
1596 {
1597 RtlInitUnicodeString(&UserAllInfo.ProfilePath,
1598 UserInfo3->usri3_profile);
1599 UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH;
1600 }
1601
1602 if (UserInfo3->usri3_home_dir_drive != NULL)
1603 {
1604 RtlInitUnicodeString(&UserAllInfo.HomeDirectoryDrive,
1605 UserInfo3->usri3_home_dir_drive);
1606 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORYDRIVE;
1607 }
1608
1609 UserAllInfo.PasswordExpired = (UserInfo3->usri3_password_expired != 0);
1610 UserAllInfo.WhichFields |= USER_ALL_PASSWORDEXPIRED;
1611 break;
1612
1613 case 4:
1614 UserInfo4 = (PUSER_INFO_4)UserInfo;
1615
1616 // usri4_name ignored
1617
1618 if (UserInfo4->usri4_password != NULL)
1619 {
1620 RtlInitUnicodeString(&UserAllInfo.NtPassword,
1621 UserInfo4->usri4_password);
1622 UserAllInfo.NtPasswordPresent = TRUE;
1623 UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
1624 }
1625
1626 // usri4_password_age ignored
1627
1628 // UserInfo3->usri4_priv;
1629
1630 if (UserInfo4->usri4_home_dir != NULL)
1631 {
1632 RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1633 UserInfo4->usri4_home_dir);
1634 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1635 }
1636
1637 if (UserInfo4->usri4_comment != NULL)
1638 {
1639 RtlInitUnicodeString(&UserAllInfo.AdminComment,
1640 UserInfo4->usri4_comment);
1641 UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1642 }
1643
1644 UserAllInfo.UserAccountControl = GetAccountControl(UserInfo4->usri4_flags);
1645 UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
1646
1647 if (UserInfo4->usri4_script_path != NULL)
1648 {
1649 RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1650 UserInfo4->usri4_script_path);
1651 UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1652 }
1653
1654 // UserInfo4->usri4_auth_flags;
1655
1656 if (UserInfo4->usri4_full_name != NULL)
1657 {
1658 RtlInitUnicodeString(&UserAllInfo.FullName,
1659 UserInfo4->usri4_full_name);
1660 UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
1661 }
1662
1663 if (UserInfo4->usri4_usr_comment != NULL)
1664 {
1665 RtlInitUnicodeString(&UserAllInfo.UserComment,
1666 UserInfo4->usri4_usr_comment);
1667 UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
1668 }
1669
1670 if (UserInfo4->usri4_parms != NULL)
1671 {
1672 RtlInitUnicodeString(&UserAllInfo.Parameters,
1673 UserInfo4->usri4_parms);
1674 UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
1675 }
1676
1677 if (UserInfo4->usri4_workstations != NULL)
1678 {
1679 RtlInitUnicodeString(&UserAllInfo.WorkStations,
1680 UserInfo4->usri4_workstations);
1681 UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
1682 }
1683
1684 // usri4_last_logon ignored
1685 // usri4_last_logoff ignored
1686
1687 if (UserInfo4->usri4_acct_expires == TIMEQ_FOREVER)
1688 {
1689 UserAllInfo.AccountExpires.LowPart = 0;
1690 UserAllInfo.AccountExpires.HighPart = 0;
1691 }
1692 else
1693 {
1694 RtlSecondsSince1970ToTime(UserInfo4->usri4_acct_expires,
1695 &UserAllInfo.AccountExpires);
1696 }
1697 UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
1698
1699 // UserInfo3->usri4_max_storage;
1700 // UserInfo3->usri4_units_per_week;
1701 // UserInfo3->usri4_logon_hours;
1702
1703 // usri4_bad_pw_count ignored
1704 // usri4_num_logons ignored
1705 // usri4_logon_server ignored
1706
1707 UserAllInfo.CountryCode = UserInfo4->usri4_country_code;
1708 UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
1709
1710 UserAllInfo.CodePage = UserInfo4->usri4_code_page;
1711 UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
1712
1713 // usri4_user_sid ignored
1714
1715 UserAllInfo.PrimaryGroupId = UserInfo4->usri4_primary_group_id;
1716 UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID;
1717
1718 if (UserInfo4->usri4_profile != NULL)
1719 {
1720 RtlInitUnicodeString(&UserAllInfo.ProfilePath,
1721 UserInfo4->usri4_profile);
1722 UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH;
1723 }
1724
1725 if (UserInfo4->usri4_home_dir_drive != NULL)
1726 {
1727 RtlInitUnicodeString(&UserAllInfo.HomeDirectoryDrive,
1728 UserInfo4->usri4_home_dir_drive);
1729 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORYDRIVE;
1730 }
1731
1732 UserAllInfo.PasswordExpired = (UserInfo4->usri4_password_expired != 0);
1733 UserAllInfo.WhichFields |= USER_ALL_PASSWORDEXPIRED;
1734 break;
1735
1736 // case 21:
1737 // case 22:
1738
1739 case 1003:
1740 UserInfo1003 = (PUSER_INFO_1003)UserInfo;
1741
1742 if (UserInfo1003->usri1003_password != NULL)
1743 {
1744 RtlInitUnicodeString(&UserAllInfo.NtPassword,
1745 UserInfo1003->usri1003_password);
1746 UserAllInfo.NtPasswordPresent = TRUE;
1747 UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
1748 }
1749 break;
1750
1751 // case 1005:
1752
1753 case 1006:
1754 UserInfo1006 = (PUSER_INFO_1006)UserInfo;
1755
1756 if (UserInfo1006->usri1006_home_dir != NULL)
1757 {
1758 RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1759 UserInfo1006->usri1006_home_dir);
1760 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1761 }
1762 break;
1763
1764 case 1007:
1765 UserInfo1007 = (PUSER_INFO_1007)UserInfo;
1766
1767 if (UserInfo1007->usri1007_comment != NULL)
1768 {
1769 RtlInitUnicodeString(&UserAllInfo.AdminComment,
1770 UserInfo1007->usri1007_comment);
1771 UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1772 }
1773 break;
1774
1775 case 1008:
1776 UserInfo1008 = (PUSER_INFO_1008)UserInfo;
1777 UserAllInfo.UserAccountControl = GetAccountControl(UserInfo1008->usri1008_flags);
1778 UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
1779 break;
1780
1781 case 1009:
1782 UserInfo1009 = (PUSER_INFO_1009)UserInfo;
1783
1784 if (UserInfo1009->usri1009_script_path != NULL)
1785 {
1786 RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1787 UserInfo1009->usri1009_script_path);
1788 UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1789 }
1790 break;
1791
1792 // case 1010:
1793
1794 case 1011:
1795 UserInfo1011 = (PUSER_INFO_1011)UserInfo;
1796
1797 if (UserInfo1011->usri1011_full_name != NULL)
1798 {
1799 RtlInitUnicodeString(&UserAllInfo.FullName,
1800 UserInfo1011->usri1011_full_name);
1801 UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
1802 }
1803 break;
1804
1805 case 1012:
1806 UserInfo1012 = (PUSER_INFO_1012)UserInfo;
1807
1808 if (UserInfo1012->usri1012_usr_comment != NULL)
1809 {
1810 RtlInitUnicodeString(&UserAllInfo.UserComment,
1811 UserInfo1012->usri1012_usr_comment);
1812 UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
1813 }
1814 break;
1815
1816 case 1013:
1817 UserInfo1013 = (PUSER_INFO_1013)UserInfo;
1818
1819 if (UserInfo1013->usri1013_parms != NULL)
1820 {
1821 RtlInitUnicodeString(&UserAllInfo.Parameters,
1822 UserInfo1013->usri1013_parms);
1823 UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
1824 }
1825 break;
1826
1827 case 1014:
1828 UserInfo1014 = (PUSER_INFO_1014)UserInfo;
1829
1830 if (UserInfo1014->usri1014_workstations != NULL)
1831 {
1832 RtlInitUnicodeString(&UserAllInfo.WorkStations,
1833 UserInfo1014->usri1014_workstations);
1834 UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
1835 }
1836 break;
1837
1838 case 1017:
1839 UserInfo1017 = (PUSER_INFO_1017)UserInfo;
1840
1841 if (UserInfo1017->usri1017_acct_expires == TIMEQ_FOREVER)
1842 {
1843 UserAllInfo.AccountExpires.LowPart = 0;
1844 UserAllInfo.AccountExpires.HighPart = 0;
1845 }
1846 else
1847 {
1848 RtlSecondsSince1970ToTime(UserInfo1017->usri1017_acct_expires,
1849 &UserAllInfo.AccountExpires);
1850 }
1851 UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
1852 break;
1853
1854 // case 1018:
1855 // case 1020:
1856
1857 case 1024:
1858 UserInfo1024 = (PUSER_INFO_1024)UserInfo;
1859
1860 UserAllInfo.CountryCode = UserInfo1024->usri1024_country_code;
1861 UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
1862 break;
1863
1864 case 1025:
1865 UserInfo1025 = (PUSER_INFO_1025)UserInfo;
1866
1867 UserAllInfo.CodePage = UserInfo1025->usri1025_code_page;
1868 UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
1869 break;
1870
1871 case 1051:
1872 UserInfo1051 = (PUSER_INFO_1051)UserInfo;
1873
1874 UserAllInfo.PrimaryGroupId = UserInfo1051->usri1051_primary_group_id;
1875 UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID;
1876 break;
1877
1878 case 1052:
1879 UserInfo1052 = (PUSER_INFO_1052)UserInfo;
1880
1881 if (UserInfo1052->usri1052_profile != NULL)
1882 {
1883 RtlInitUnicodeString(&UserAllInfo.ProfilePath,
1884 UserInfo1052->usri1052_profile);
1885 UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH;
1886 }
1887 break;
1888
1889 case 1053:
1890 UserInfo1053 = (PUSER_INFO_1053)UserInfo;
1891
1892 if (UserInfo1053->usri1053_home_dir_drive != NULL)
1893 {
1894 RtlInitUnicodeString(&UserAllInfo.HomeDirectoryDrive,
1895 UserInfo1053->usri1053_home_dir_drive);
1896 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORYDRIVE;
1897 }
1898 break;
1899
1900 default:
1901 ERR("Unsupported level %lu!\n", Level);
1902 return ERROR_INVALID_PARAMETER;
1903 }
1904
1905 Status = SamSetInformationUser(UserHandle,
1906 UserAllInformation,
1907 &UserAllInfo);
1908 if (!NT_SUCCESS(Status))
1909 {
1910 ERR("SamSetInformationUser failed (Status %08lx)\n", Status);
1911 ApiStatus = NetpNtStatusToApiStatus(Status);
1912 goto done;
1913 }
1914
1915 done:
1916 return ApiStatus;
1917 }
1918
1919
1920 static
1921 NET_API_STATUS
1922 OpenUserByName(SAM_HANDLE DomainHandle,
1923 PUNICODE_STRING UserName,
1924 ULONG DesiredAccess,
1925 PSAM_HANDLE UserHandle)
1926 {
1927 PULONG RelativeIds = NULL;
1928 PSID_NAME_USE Use = NULL;
1929 NET_API_STATUS ApiStatus = NERR_Success;
1930 NTSTATUS Status = STATUS_SUCCESS;
1931
1932 /* Get the RID for the given user name */
1933 Status = SamLookupNamesInDomain(DomainHandle,
1934 1,
1935 UserName,
1936 &RelativeIds,
1937 &Use);
1938 if (!NT_SUCCESS(Status))
1939 {
1940 ERR("SamLookupNamesInDomain failed (Status %08lx)\n", Status);
1941 return NetpNtStatusToApiStatus(Status);
1942 }
1943
1944 /* Fail, if it is not an alias account */
1945 if (Use[0] != SidTypeUser)
1946 {
1947 ERR("Object is not a user!\n");
1948 ApiStatus = NERR_GroupNotFound;
1949 goto done;
1950 }
1951
1952 /* Open the alias account */
1953 Status = SamOpenUser(DomainHandle,
1954 DesiredAccess,
1955 RelativeIds[0],
1956 UserHandle);
1957 if (!NT_SUCCESS(Status))
1958 {
1959 ERR("SamOpenUser failed (Status %08lx)\n", Status);
1960 ApiStatus = NetpNtStatusToApiStatus(Status);
1961 goto done;
1962 }
1963
1964 done:
1965 if (RelativeIds != NULL)
1966 SamFreeMemory(RelativeIds);
1967
1968 if (Use != NULL)
1969 SamFreeMemory(Use);
1970
1971 return ApiStatus;
1972 }
1973
1974
1975 /************************************************************
1976 * NetUserAdd (NETAPI32.@)
1977 */
1978 NET_API_STATUS
1979 WINAPI
1980 NetUserAdd(LPCWSTR servername,
1981 DWORD level,
1982 LPBYTE bufptr,
1983 LPDWORD parm_err)
1984 {
1985 UNICODE_STRING ServerName;
1986 UNICODE_STRING UserName;
1987 SAM_HANDLE ServerHandle = NULL;
1988 SAM_HANDLE DomainHandle = NULL;
1989 SAM_HANDLE UserHandle = NULL;
1990 ULONG GrantedAccess;
1991 ULONG RelativeId;
1992 NET_API_STATUS ApiStatus = NERR_Success;
1993 NTSTATUS Status = STATUS_SUCCESS;
1994
1995 TRACE("(%s, %d, %p, %p)\n", debugstr_w(servername), level, bufptr, parm_err);
1996
1997 /* Check the info level */
1998 switch (level)
1999 {
2000 case 1:
2001 case 2:
2002 case 3:
2003 case 4:
2004 break;
2005
2006 default:
2007 return ERROR_INVALID_LEVEL;
2008 }
2009
2010 if (servername != NULL)
2011 RtlInitUnicodeString(&ServerName, servername);
2012
2013 /* Connect to the SAM Server */
2014 Status = SamConnect((servername != NULL) ? &ServerName : NULL,
2015 &ServerHandle,
2016 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
2017 NULL);
2018 if (!NT_SUCCESS(Status))
2019 {
2020 ERR("SamConnect failed (Status %08lx)\n", Status);
2021 ApiStatus = NetpNtStatusToApiStatus(Status);
2022 goto done;
2023 }
2024
2025 /* Open the Account Domain */
2026 Status = OpenAccountDomain(ServerHandle,
2027 (servername != NULL) ? &ServerName : NULL,
2028 DOMAIN_CREATE_USER | DOMAIN_LOOKUP,
2029 &DomainHandle);
2030 if (!NT_SUCCESS(Status))
2031 {
2032 ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
2033 ApiStatus = NetpNtStatusToApiStatus(Status);
2034 goto done;
2035 }
2036
2037 /* Initialize the user name string */
2038 RtlInitUnicodeString(&UserName,
2039 ((PUSER_INFO_1)bufptr)->usri1_name);
2040
2041 /* Create the user account */
2042 Status = SamCreateUser2InDomain(DomainHandle,
2043 &UserName,
2044 USER_NORMAL_ACCOUNT,
2045 USER_ALL_ACCESS | DELETE | WRITE_DAC,
2046 &UserHandle,
2047 &GrantedAccess,
2048 &RelativeId);
2049 if (!NT_SUCCESS(Status))
2050 {
2051 ERR("SamCreateUser2InDomain failed (Status %08lx)\n", Status);
2052 ApiStatus = NetpNtStatusToApiStatus(Status);
2053 goto done;
2054 }
2055
2056 /* Set user information */
2057 ApiStatus = SetUserInfo(UserHandle,
2058 bufptr,
2059 level);
2060 if (ApiStatus != NERR_Success)
2061 {
2062 ERR("SetUserInfo failed (Status %lu)\n", ApiStatus);
2063 goto done;
2064 }
2065
2066 done:
2067 if (UserHandle != NULL)
2068 SamCloseHandle(UserHandle);
2069
2070 if (DomainHandle != NULL)
2071 SamCloseHandle(DomainHandle);
2072
2073 if (ServerHandle != NULL)
2074 SamCloseHandle(ServerHandle);
2075
2076 return ApiStatus;
2077 }
2078
2079
2080 /******************************************************************************
2081 * NetUserChangePassword (NETAPI32.@)
2082 * PARAMS
2083 * domainname [I] Optional. Domain on which the user resides or the logon
2084 * domain of the current user if NULL.
2085 * username [I] Optional. Username to change the password for or the name
2086 * of the current user if NULL.
2087 * oldpassword [I] The user's current password.
2088 * newpassword [I] The password that the user will be changed to using.
2089 *
2090 * RETURNS
2091 * Success: NERR_Success.
2092 * Failure: NERR_* failure code or win error code.
2093 *
2094 */
2095 NET_API_STATUS
2096 WINAPI
2097 NetUserChangePassword(LPCWSTR domainname,
2098 LPCWSTR username,
2099 LPCWSTR oldpassword,
2100 LPCWSTR newpassword)
2101 {
2102 PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer = NULL;
2103 PMSV1_0_CHANGEPASSWORD_RESPONSE ResponseBuffer = NULL;
2104 ULONG RequestBufferSize;
2105 ULONG ResponseBufferSize = 0;
2106 LPWSTR Ptr;
2107 ANSI_STRING PackageName;
2108 ULONG AuthenticationPackage = 0;
2109 HANDLE LsaHandle = NULL;
2110 NET_API_STATUS ApiStatus = NERR_Success;
2111 NTSTATUS Status = STATUS_SUCCESS;
2112 NTSTATUS ProtocolStatus;
2113
2114 TRACE("(%s, %s, ..., ...)\n", debugstr_w(domainname), debugstr_w(username));
2115
2116 /* FIXME: handle null domain or user name */
2117
2118 /* Check the parameters */
2119 if ((oldpassword == NULL) ||
2120 (newpassword == NULL))
2121 return ERROR_INVALID_PARAMETER;
2122
2123 /* Connect to the LSA server */
2124 Status = LsaConnectUntrusted(&LsaHandle);
2125 if (!NT_SUCCESS(Status))
2126 return NetpNtStatusToApiStatus(Status);
2127
2128 /* Get the authentication package ID */
2129 RtlInitAnsiString(&PackageName,
2130 MSV1_0_PACKAGE_NAME);
2131
2132 Status = LsaLookupAuthenticationPackage(LsaHandle,
2133 &PackageName,
2134 &AuthenticationPackage);
2135 if (!NT_SUCCESS(Status))
2136 {
2137 ApiStatus = NetpNtStatusToApiStatus(Status);
2138 goto done;
2139 }
2140
2141 /* Calculate the request buffer size */
2142 RequestBufferSize = sizeof(MSV1_0_CHANGEPASSWORD_REQUEST) +
2143 ((wcslen(domainname) + 1) * sizeof(WCHAR)) +
2144 ((wcslen(username) + 1) * sizeof(WCHAR)) +
2145 ((wcslen(oldpassword) + 1) * sizeof(WCHAR)) +
2146 ((wcslen(newpassword) + 1) * sizeof(WCHAR));
2147
2148 /* Allocate the request buffer */
2149 ApiStatus = NetApiBufferAllocate(RequestBufferSize,
2150 (PVOID*)&RequestBuffer);
2151 if (ApiStatus != NERR_Success)
2152 goto done;
2153
2154 /* Initialize the request buffer */
2155 RequestBuffer->MessageType = MsV1_0ChangePassword;
2156 RequestBuffer->Impersonating = TRUE;
2157
2158 Ptr = (LPWSTR)((ULONG_PTR)RequestBuffer + sizeof(MSV1_0_CHANGEPASSWORD_REQUEST));
2159
2160 /* Pack the domain name */
2161 RequestBuffer->DomainName.Length = wcslen(domainname) * sizeof(WCHAR);
2162 RequestBuffer->DomainName.MaximumLength = RequestBuffer->DomainName.Length + sizeof(WCHAR);
2163 RequestBuffer->DomainName.Buffer = Ptr;
2164
2165 RtlCopyMemory(RequestBuffer->DomainName.Buffer,
2166 domainname,
2167 RequestBuffer->DomainName.MaximumLength);
2168
2169 Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->DomainName.MaximumLength);
2170
2171 /* Pack the user name */
2172 RequestBuffer->AccountName.Length = wcslen(username) * sizeof(WCHAR);
2173 RequestBuffer->AccountName.MaximumLength = RequestBuffer->AccountName.Length + sizeof(WCHAR);
2174 RequestBuffer->AccountName.Buffer = Ptr;
2175
2176 RtlCopyMemory(RequestBuffer->AccountName.Buffer,
2177 username,
2178 RequestBuffer->AccountName.MaximumLength);
2179
2180 Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->AccountName.MaximumLength);
2181
2182 /* Pack the old password */
2183 RequestBuffer->OldPassword.Length = wcslen(oldpassword) * sizeof(WCHAR);
2184 RequestBuffer->OldPassword.MaximumLength = RequestBuffer->OldPassword.Length + sizeof(WCHAR);
2185 RequestBuffer->OldPassword.Buffer = Ptr;
2186
2187 RtlCopyMemory(RequestBuffer->OldPassword.Buffer,
2188 oldpassword,
2189 RequestBuffer->OldPassword.MaximumLength);
2190
2191 Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->OldPassword.MaximumLength);
2192
2193 /* Pack the new password */
2194 RequestBuffer->NewPassword.Length = wcslen(newpassword) * sizeof(WCHAR);
2195 RequestBuffer->NewPassword.MaximumLength = RequestBuffer->NewPassword.Length + sizeof(WCHAR);
2196 RequestBuffer->NewPassword.Buffer = Ptr;
2197
2198 RtlCopyMemory(RequestBuffer->NewPassword.Buffer,
2199 newpassword,
2200 RequestBuffer->NewPassword.MaximumLength);
2201
2202 /* Call the authentication package */
2203 Status = LsaCallAuthenticationPackage(LsaHandle,
2204 AuthenticationPackage,
2205 RequestBuffer,
2206 RequestBufferSize,
2207 (PVOID*)&ResponseBuffer,
2208 &ResponseBufferSize,
2209 &ProtocolStatus);
2210 if (!NT_SUCCESS(Status))
2211 {
2212 ApiStatus = NetpNtStatusToApiStatus(Status);
2213 goto done;
2214 }
2215
2216 if (!NT_SUCCESS(ProtocolStatus))
2217 {
2218 ApiStatus = NetpNtStatusToApiStatus(ProtocolStatus);
2219 goto done;
2220 }
2221
2222 done:
2223 if (RequestBuffer != NULL)
2224 NetApiBufferFree(RequestBuffer);
2225
2226 if (ResponseBuffer != NULL)
2227 LsaFreeReturnBuffer(ResponseBuffer);
2228
2229 if (LsaHandle != NULL)
2230 NtClose(LsaHandle);
2231
2232 return ApiStatus;
2233 }
2234
2235
2236 /************************************************************
2237 * NetUserDel (NETAPI32.@)
2238 */
2239 NET_API_STATUS
2240 WINAPI
2241 NetUserDel(LPCWSTR servername,
2242 LPCWSTR username)
2243 {
2244 UNICODE_STRING ServerName;
2245 UNICODE_STRING UserName;
2246 SAM_HANDLE ServerHandle = NULL;
2247 SAM_HANDLE DomainHandle = NULL;
2248 SAM_HANDLE UserHandle = NULL;
2249 NET_API_STATUS ApiStatus = NERR_Success;
2250 NTSTATUS Status = STATUS_SUCCESS;
2251
2252 TRACE("(%s, %s)\n", debugstr_w(servername), debugstr_w(username));
2253
2254 if (servername != NULL)
2255 RtlInitUnicodeString(&ServerName, servername);
2256
2257 RtlInitUnicodeString(&UserName, username);
2258
2259 /* Connect to the SAM Server */
2260 Status = SamConnect((servername != NULL) ? &ServerName : NULL,
2261 &ServerHandle,
2262 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
2263 NULL);
2264 if (!NT_SUCCESS(Status))
2265 {
2266 ERR("SamConnect failed (Status %08lx)\n", Status);
2267 ApiStatus = NetpNtStatusToApiStatus(Status);
2268 goto done;
2269 }
2270
2271 /* Open the Builtin Domain */
2272 Status = OpenBuiltinDomain(ServerHandle,
2273 DOMAIN_LOOKUP,
2274 &DomainHandle);
2275 if (!NT_SUCCESS(Status))
2276 {
2277 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status);
2278 ApiStatus = NetpNtStatusToApiStatus(Status);
2279 goto done;
2280 }
2281
2282 /* Open the user account in the builtin domain */
2283 ApiStatus = OpenUserByName(DomainHandle,
2284 &UserName,
2285 DELETE,
2286 &UserHandle);
2287 if (ApiStatus != NERR_Success && ApiStatus != ERROR_NONE_MAPPED)
2288 {
2289 TRACE("OpenUserByName failed (ApiStatus %lu)\n", ApiStatus);
2290 goto done;
2291 }
2292
2293 if (UserHandle == NULL)
2294 {
2295 if (DomainHandle != NULL)
2296 {
2297 SamCloseHandle(DomainHandle);
2298 DomainHandle = NULL;
2299 }
2300
2301 /* Open the Acount Domain */
2302 Status = OpenAccountDomain(ServerHandle,
2303 (servername != NULL) ? &ServerName : NULL,
2304 DOMAIN_LOOKUP,
2305 &DomainHandle);
2306 if (!NT_SUCCESS(Status))
2307 {
2308 ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
2309 ApiStatus = NetpNtStatusToApiStatus(Status);
2310 goto done;
2311 }
2312
2313 /* Open the user account in the account domain */
2314 ApiStatus = OpenUserByName(DomainHandle,
2315 &UserName,
2316 DELETE,
2317 &UserHandle);
2318 if (ApiStatus != NERR_Success)
2319 {
2320 ERR("OpenUserByName failed (ApiStatus %lu)\n", ApiStatus);
2321 if (ApiStatus == ERROR_NONE_MAPPED)
2322 ApiStatus = NERR_GroupNotFound;
2323 goto done;
2324 }
2325 }
2326
2327 /* Delete the user */
2328 Status = SamDeleteUser(UserHandle);
2329 if (!NT_SUCCESS(Status))
2330 {
2331 ERR("SamDeleteUser failed (Status %08lx)\n", Status);
2332 ApiStatus = NetpNtStatusToApiStatus(Status);
2333 goto done;
2334 }
2335
2336 done:
2337 if (UserHandle != NULL)
2338 SamCloseHandle(UserHandle);
2339
2340 if (DomainHandle != NULL)
2341 SamCloseHandle(DomainHandle);
2342
2343 if (ServerHandle != NULL)
2344 SamCloseHandle(ServerHandle);
2345
2346 return ApiStatus;
2347 }
2348
2349
2350 /************************************************************
2351 * NetUserEnum (NETAPI32.@)
2352 */
2353 NET_API_STATUS
2354 WINAPI
2355 NetUserEnum(LPCWSTR servername,
2356 DWORD level,
2357 DWORD filter,
2358 LPBYTE* bufptr,
2359 DWORD prefmaxlen,
2360 LPDWORD entriesread,
2361 LPDWORD totalentries,
2362 LPDWORD resume_handle)
2363 {
2364 UNICODE_STRING ServerName;
2365 PSAM_RID_ENUMERATION CurrentUser;
2366 PENUM_CONTEXT EnumContext = NULL;
2367 LPVOID Buffer = NULL;
2368 ULONG i;
2369 SAM_HANDLE UserHandle = NULL;
2370 PUSER_ALL_INFORMATION UserInfo = NULL;
2371
2372 NET_API_STATUS ApiStatus = NERR_Success;
2373 NTSTATUS Status = STATUS_SUCCESS;
2374
2375 TRACE("(%s %d 0x%d %p %d %p %p %p)\n", debugstr_w(servername), level,
2376 filter, bufptr, prefmaxlen, entriesread, totalentries, resume_handle);
2377
2378 *entriesread = 0;
2379 *totalentries = 0;
2380 *bufptr = NULL;
2381
2382 if (servername != NULL)
2383 RtlInitUnicodeString(&ServerName, servername);
2384
2385 if (resume_handle != NULL && *resume_handle != 0)
2386 {
2387 EnumContext = (PENUM_CONTEXT)*resume_handle;
2388 }
2389 else
2390 {
2391 ApiStatus = NetApiBufferAllocate(sizeof(ENUM_CONTEXT), (PVOID*)&EnumContext);
2392 if (ApiStatus != NERR_Success)
2393 goto done;
2394
2395 EnumContext->EnumerationContext = 0;
2396 EnumContext->Buffer = NULL;
2397 EnumContext->Count = 0;
2398 EnumContext->Index = 0;
2399 EnumContext->BuiltinDone = FALSE;
2400
2401 Status = SamConnect((servername != NULL) ? &ServerName : NULL,
2402 &EnumContext->ServerHandle,
2403 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
2404 NULL);
2405 if (!NT_SUCCESS(Status))
2406 {
2407 ERR("SamConnect failed (Status %08lx)\n", Status);
2408 ApiStatus = NetpNtStatusToApiStatus(Status);
2409 goto done;
2410 }
2411
2412 Status = OpenAccountDomain(EnumContext->ServerHandle,
2413 (servername != NULL) ? &ServerName : NULL,
2414 DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
2415 &EnumContext->AccountDomainHandle);
2416 if (!NT_SUCCESS(Status))
2417 {
2418 ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
2419 ApiStatus = NetpNtStatusToApiStatus(Status);
2420 goto done;
2421 }
2422
2423 Status = OpenBuiltinDomain(EnumContext->ServerHandle,
2424 DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
2425 &EnumContext->BuiltinDomainHandle);
2426 if (!NT_SUCCESS(Status))
2427 {
2428 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status);
2429 ApiStatus = NetpNtStatusToApiStatus(Status);
2430 goto done;
2431 }
2432 }
2433
2434 // while (TRUE)
2435 // {
2436 TRACE("EnumContext->Index: %lu\n", EnumContext->Index);
2437 TRACE("EnumContext->Count: %lu\n", EnumContext->Count);
2438
2439 if (EnumContext->Index >= EnumContext->Count)
2440 {
2441 // if (EnumContext->BuiltinDone == TRUE)
2442 // {
2443 // ApiStatus = NERR_Success;
2444 // goto done;
2445 // }
2446
2447 TRACE("Calling SamEnumerateUsersInDomain\n");
2448 Status = SamEnumerateUsersInDomain(EnumContext->AccountDomainHandle, //BuiltinDomainHandle,
2449 &EnumContext->EnumerationContext,
2450 0,
2451 (PVOID *)&EnumContext->Buffer,
2452 prefmaxlen,
2453 &EnumContext->Count);
2454
2455 TRACE("SamEnumerateUsersInDomain returned (Status %08lx)\n", Status);
2456 if (!NT_SUCCESS(Status))
2457 {
2458 ERR("SamEnumerateUsersInDomain failed (Status %08lx)\n", Status);
2459 ApiStatus = NetpNtStatusToApiStatus(Status);
2460 goto done;
2461 }
2462
2463 if (Status == STATUS_MORE_ENTRIES)
2464 {
2465 ApiStatus = NERR_BufTooSmall;
2466 goto done;
2467 }
2468 else
2469 {
2470 EnumContext->BuiltinDone = TRUE;
2471 }
2472 }
2473
2474 TRACE("EnumContext: %lu\n", EnumContext);
2475 TRACE("EnumContext->Count: %lu\n", EnumContext->Count);
2476 TRACE("EnumContext->Buffer: %p\n", EnumContext->Buffer);
2477
2478 /* Get a pointer to the current user */
2479 CurrentUser = &EnumContext->Buffer[EnumContext->Index];
2480
2481 TRACE("RID: %lu\n", CurrentUser->RelativeId);
2482
2483 Status = SamOpenUser(EnumContext->AccountDomainHandle, //BuiltinDomainHandle,
2484 USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT,
2485 CurrentUser->RelativeId,
2486 &UserHandle);
2487 if (!NT_SUCCESS(Status))
2488 {
2489 ERR("SamOpenUser failed (Status %08lx)\n", Status);
2490 ApiStatus = NetpNtStatusToApiStatus(Status);
2491 goto done;
2492 }
2493
2494 Status = SamQueryInformationUser(UserHandle,
2495 UserAllInformation,
2496 (PVOID *)&UserInfo);
2497 if (!NT_SUCCESS(Status))
2498 {
2499 ERR("SamQueryInformationUser failed (Status %08lx)\n", Status);
2500 ApiStatus = NetpNtStatusToApiStatus(Status);
2501 goto done;
2502 }
2503
2504 SamCloseHandle(UserHandle);
2505 UserHandle = NULL;
2506
2507 ApiStatus = BuildUserInfoBuffer(UserInfo,
2508 level,
2509 CurrentUser->RelativeId,
2510 &Buffer);
2511 if (ApiStatus != NERR_Success)
2512 {
2513 ERR("BuildUserInfoBuffer failed (ApiStatus %lu)\n", ApiStatus);
2514 goto done;
2515 }
2516
2517 if (UserInfo != NULL)
2518 {
2519 FreeUserInfo(UserInfo);
2520 UserInfo = NULL;
2521 }
2522
2523 EnumContext->Index++;
2524
2525 (*entriesread)++;
2526 // }
2527
2528 done:
2529 if (ApiStatus == NERR_Success && EnumContext->Index < EnumContext->Count)
2530 ApiStatus = ERROR_MORE_DATA;
2531
2532 if (EnumContext != NULL)
2533 *totalentries = EnumContext->Count;
2534
2535 if (resume_handle == NULL || ApiStatus != ERROR_MORE_DATA)
2536 {
2537 if (EnumContext != NULL)
2538 {
2539 if (EnumContext->BuiltinDomainHandle != NULL)
2540 SamCloseHandle(EnumContext->BuiltinDomainHandle);
2541
2542 if (EnumContext->AccountDomainHandle != NULL)
2543 SamCloseHandle(EnumContext->AccountDomainHandle);
2544
2545 if (EnumContext->ServerHandle != NULL)
2546 SamCloseHandle(EnumContext->ServerHandle);
2547
2548 if (EnumContext->Buffer != NULL)
2549 {
2550 for (i = 0; i < EnumContext->Count; i++)
2551 {
2552 SamFreeMemory(EnumContext->Buffer[i].Name.Buffer);
2553 }
2554
2555 SamFreeMemory(EnumContext->Buffer);
2556 }
2557
2558 NetApiBufferFree(EnumContext);
2559 EnumContext = NULL;
2560 }
2561 }
2562
2563 if (UserHandle != NULL)
2564 SamCloseHandle(UserHandle);
2565
2566 if (UserInfo != NULL)
2567 FreeUserInfo(UserInfo);
2568
2569 if (resume_handle != NULL)
2570 *resume_handle = (DWORD_PTR)EnumContext;
2571
2572 *bufptr = (LPBYTE)Buffer;
2573
2574 TRACE("return %lu\n", ApiStatus);
2575
2576 return ApiStatus;
2577 }
2578
2579
2580 /************************************************************
2581 * NetUserGetGroups (NETAPI32.@)
2582 */
2583 NET_API_STATUS
2584 WINAPI
2585 NetUserGetGroups(LPCWSTR servername,
2586 LPCWSTR username,
2587 DWORD level,
2588 LPBYTE *bufptr,
2589 DWORD prefixmaxlen,
2590 LPDWORD entriesread,
2591 LPDWORD totalentries)
2592 {
2593 FIXME("%s %s %d %p %d %p %p stub\n", debugstr_w(servername),
2594 debugstr_w(username), level, bufptr, prefixmaxlen, entriesread,
2595 totalentries);
2596
2597 *bufptr = NULL;
2598 *entriesread = 0;
2599 *totalentries = 0;
2600
2601 return ERROR_INVALID_LEVEL;
2602 }
2603
2604
2605 /************************************************************
2606 * NetUserGetInfo (NETAPI32.@)
2607 */
2608 NET_API_STATUS
2609 WINAPI
2610 NetUserGetInfo(LPCWSTR servername,
2611 LPCWSTR username,
2612 DWORD level,
2613 LPBYTE* bufptr)
2614 {
2615 UNICODE_STRING ServerName;
2616 UNICODE_STRING UserName;
2617 SAM_HANDLE ServerHandle = NULL;
2618 SAM_HANDLE AccountDomainHandle = NULL;
2619 SAM_HANDLE UserHandle = NULL;
2620 PULONG RelativeIds = NULL;
2621 PSID_NAME_USE Use = NULL;
2622 PUSER_ALL_INFORMATION UserInfo = NULL;
2623 LPVOID Buffer = NULL;
2624 NET_API_STATUS ApiStatus = NERR_Success;
2625 NTSTATUS Status = STATUS_SUCCESS;
2626
2627 TRACE("(%s, %s, %d, %p)\n", debugstr_w(servername),
2628 debugstr_w(username), level, bufptr);
2629
2630 if (servername != NULL)
2631 RtlInitUnicodeString(&ServerName, servername);
2632
2633 RtlInitUnicodeString(&UserName, username);
2634
2635 /* Connect to the SAM Server */
2636 Status = SamConnect((servername != NULL) ? &ServerName : NULL,
2637 &ServerHandle,
2638 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
2639 NULL);
2640 if (!NT_SUCCESS(Status))
2641 {
2642 ERR("SamConnect failed (Status %08lx)\n", Status);
2643 ApiStatus = NetpNtStatusToApiStatus(Status);
2644 goto done;
2645 }
2646
2647 /* Open the Account Domain */
2648 Status = OpenAccountDomain(ServerHandle,
2649 (servername != NULL) ? &ServerName : NULL,
2650 DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
2651 &AccountDomainHandle);
2652 if (!NT_SUCCESS(Status))
2653 {
2654 ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
2655 ApiStatus = NetpNtStatusToApiStatus(Status);
2656 goto done;
2657 }
2658
2659 /* Get the RID for the given user name */
2660 Status = SamLookupNamesInDomain(AccountDomainHandle,
2661 1,
2662 &UserName,
2663 &RelativeIds,
2664 &Use);
2665 if (!NT_SUCCESS(Status))
2666 {
2667 ERR("SamOpenDomain failed (Status %08lx)\n", Status);
2668 ApiStatus = NetpNtStatusToApiStatus(Status);
2669 goto done;
2670 }
2671
2672 /* Check if the account is a user account */
2673 if (Use[0] != SidTypeUser)
2674 {
2675 ERR("No user found!\n");
2676 ApiStatus = NERR_UserNotFound;
2677 goto done;
2678 }
2679
2680 TRACE("RID: %lu\n", RelativeIds[0]);
2681
2682 /* Open the user object */
2683 Status = SamOpenUser(AccountDomainHandle,
2684 USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT,
2685 RelativeIds[0],
2686 &UserHandle);
2687 if (!NT_SUCCESS(Status))
2688 {
2689 ERR("SamOpenUser failed (Status %08lx)\n", Status);
2690 ApiStatus = NetpNtStatusToApiStatus(Status);
2691 goto done;
2692 }
2693
2694 Status = SamQueryInformationUser(UserHandle,
2695 UserAllInformation,
2696 (PVOID *)&UserInfo);
2697 if (!NT_SUCCESS(Status))
2698 {
2699 ERR("SamQueryInformationUser failed (Status %08lx)\n", Status);
2700 ApiStatus = NetpNtStatusToApiStatus(Status);
2701 goto done;
2702 }
2703
2704 ApiStatus = BuildUserInfoBuffer(UserInfo,
2705 level,
2706 RelativeIds[0],
2707 &Buffer);
2708 if (ApiStatus != NERR_Success)
2709 {
2710 ERR("BuildUserInfoBuffer failed (ApiStatus %08lu)\n", ApiStatus);
2711 goto done;
2712 }
2713
2714 done:
2715 if (UserInfo != NULL)
2716 FreeUserInfo(UserInfo);
2717
2718 if (UserHandle != NULL)
2719 SamCloseHandle(UserHandle);
2720
2721 if (RelativeIds != NULL)
2722 SamFreeMemory(RelativeIds);
2723
2724 if (Use != NULL)
2725 SamFreeMemory(Use);
2726
2727 if (AccountDomainHandle != NULL)
2728 SamCloseHandle(AccountDomainHandle);
2729
2730 if (ServerHandle != NULL)
2731 SamCloseHandle(ServerHandle);
2732
2733 *bufptr = (LPBYTE)Buffer;
2734
2735 return ApiStatus;
2736 }
2737
2738
2739 /************************************************************
2740 * NetUserGetLocalGroups (NETAPI32.@)
2741 */
2742 NET_API_STATUS
2743 WINAPI
2744 NetUserGetLocalGroups(LPCWSTR servername,
2745 LPCWSTR username,
2746 DWORD level,
2747 DWORD flags,
2748 LPBYTE* bufptr,
2749 DWORD prefmaxlen,
2750 LPDWORD entriesread,
2751 LPDWORD totalentries)
2752 {
2753 UNICODE_STRING ServerName;
2754 UNICODE_STRING UserName;
2755 SAM_HANDLE ServerHandle = NULL;
2756 SAM_HANDLE BuiltinDomainHandle = NULL;
2757 SAM_HANDLE AccountDomainHandle = NULL;
2758 PSID AccountDomainSid = NULL;
2759 PSID UserSid = NULL;
2760 PULONG RelativeIds = NULL;
2761 PSID_NAME_USE Use = NULL;
2762 ULONG BuiltinMemberCount = 0;
2763 ULONG AccountMemberCount = 0;
2764 PULONG BuiltinAliases = NULL;
2765 PULONG AccountAliases = NULL;
2766 PUNICODE_STRING BuiltinNames = NULL;
2767 PUNICODE_STRING AccountNames = NULL;
2768 PLOCALGROUP_USERS_INFO_0 Buffer = NULL;
2769 ULONG Size;
2770 ULONG Count = 0;
2771 ULONG Index;
2772 ULONG i;
2773 LPWSTR StrPtr;
2774 NET_API_STATUS ApiStatus = NERR_Success;
2775 NTSTATUS Status = STATUS_SUCCESS;
2776
2777 TRACE("(%s, %s, %d, %08x, %p %d, %p, %p) stub!\n",
2778 debugstr_w(servername), debugstr_w(username), level, flags, bufptr,
2779 prefmaxlen, entriesread, totalentries);
2780
2781 if (level != 0)
2782 return ERROR_INVALID_LEVEL;
2783
2784 if (flags & ~LG_INCLUDE_INDIRECT)
2785 return ERROR_INVALID_PARAMETER;
2786
2787 if (flags & LG_INCLUDE_INDIRECT)
2788 {
2789 WARN("The flag LG_INCLUDE_INDIRECT is not supported yet!\n");
2790 }
2791
2792 if (servername != NULL)
2793 RtlInitUnicodeString(&ServerName, servername);
2794
2795 RtlInitUnicodeString(&UserName, username);
2796
2797 /* Connect to the SAM Server */
2798 Status = SamConnect((servername != NULL) ? &ServerName : NULL,
2799 &ServerHandle,
2800 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
2801 NULL);
2802 if (!NT_SUCCESS(Status))
2803 {
2804 ERR("SamConnect failed (Status %08lx)\n", Status);
2805 ApiStatus = NetpNtStatusToApiStatus(Status);
2806 goto done;
2807 }
2808
2809 /* Open the Builtin Domain */
2810 Status = OpenBuiltinDomain(ServerHandle,
2811 DOMAIN_LOOKUP | DOMAIN_GET_ALIAS_MEMBERSHIP,
2812 &BuiltinDomainHandle);
2813 if (!NT_SUCCESS(Status))
2814 {
2815 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status);
2816 ApiStatus = NetpNtStatusToApiStatus(Status);
2817 goto done;
2818 }
2819
2820 /* Get the Account Domain SID */
2821 Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL,
2822 &AccountDomainSid);
2823 if (!NT_SUCCESS(Status))
2824 {
2825 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
2826 ApiStatus = NetpNtStatusToApiStatus(Status);
2827 goto done;
2828 }
2829
2830 /* Open the Account Domain */
2831 Status = SamOpenDomain(ServerHandle,
2832 DOMAIN_LOOKUP | DOMAIN_GET_ALIAS_MEMBERSHIP,
2833 AccountDomainSid,
2834 &AccountDomainHandle);
2835 if (!NT_SUCCESS(Status))
2836 {
2837 ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
2838 ApiStatus = NetpNtStatusToApiStatus(Status);
2839 goto done;
2840 }
2841
2842 /* Get the RID for the given user name */
2843 Status = SamLookupNamesInDomain(AccountDomainHandle,
2844 1,
2845 &UserName,
2846 &RelativeIds,
2847 &Use);
2848 if (!NT_SUCCESS(Status))
2849 {
2850 ERR("SamLookupNamesInDomain failed (Status %08lx)\n", Status);
2851 ApiStatus = NetpNtStatusToApiStatus(Status);
2852 goto done;
2853 }
2854
2855 /* Fail, if it is not a user account */
2856 if (Use[0] != SidTypeUser)
2857 {
2858 ERR("Account is not a User!\n");
2859 ApiStatus = NERR_UserNotFound;
2860 goto done;
2861 }
2862
2863 /* Build the User SID from the Account Domain SID and the users RID */
2864 ApiStatus = BuildSidFromSidAndRid(AccountDomainSid,
2865 RelativeIds[0],
2866 &UserSid);
2867 if (ApiStatus != NERR_Success)
2868 {
2869 ERR("BuildSidFromSidAndRid failed!\n");
2870 goto done;
2871 }
2872
2873 /* Get alias memberships in the Builtin Domain */
2874 Status = SamGetAliasMembership(BuiltinDomainHandle,
2875 1,
2876 &UserSid,
2877 &BuiltinMemberCount,
2878 &BuiltinAliases);
2879 if (!NT_SUCCESS(Status))
2880 {
2881 ERR("SamGetAliasMembership failed (Status %08lx)\n", Status);
2882 ApiStatus = NetpNtStatusToApiStatus(Status);
2883 goto done;
2884 }
2885
2886 if (BuiltinMemberCount > 0)
2887 {
2888 /* Get the Names of the builtin alias members */
2889 Status = SamLookupIdsInDomain(BuiltinDomainHandle,
2890 BuiltinMemberCount,
2891 BuiltinAliases,
2892 &BuiltinNames,
2893 NULL);
2894 if (!NT_SUCCESS(Status))
2895 {
2896 ERR("SamLookupIdsInDomain failed (Status %08lx)\n", Status);
2897 ApiStatus = NetpNtStatusToApiStatus(Status);
2898 goto done;
2899 }
2900 }
2901
2902 /* Get alias memberships in the Account Domain */
2903 Status = SamGetAliasMembership(AccountDomainHandle,
2904 1,
2905 &UserSid,
2906 &AccountMemberCount,
2907 &AccountAliases);
2908 if (!NT_SUCCESS(Status))
2909 {
2910 ERR("SamGetAliasMembership failed (Status %08lx)\n", Status);
2911 ApiStatus = NetpNtStatusToApiStatus(Status);
2912 goto done;
2913 }
2914
2915 if (AccountMemberCount > 0)
2916 {
2917 /* Get the Names of the builtin alias members */
2918 Status = SamLookupIdsInDomain(AccountDomainHandle,
2919 AccountMemberCount,
2920 AccountAliases,
2921 &AccountNames,
2922 NULL);
2923 if (!NT_SUCCESS(Status))
2924 {
2925 ERR("SamLookupIdsInDomain failed (Status %08lx)\n", Status);
2926 ApiStatus = NetpNtStatusToApiStatus(Status);
2927 goto done;
2928 }
2929 }
2930
2931 /* Calculate the required buffer size */
2932 Size = 0;
2933
2934 for (i = 0; i < BuiltinMemberCount; i++)
2935 {
2936 if (BuiltinNames[i].Length > 0)
2937 {
2938 Size += (sizeof(LOCALGROUP_USERS_INFO_0) + BuiltinNames[i].Length + sizeof(UNICODE_NULL));
2939 Count++;
2940 }
2941 }
2942
2943 for (i = 0; i < AccountMemberCount; i++)
2944 {
2945 if (BuiltinNames[i].Length > 0)
2946 {
2947 Size += (sizeof(LOCALGROUP_USERS_INFO_0) + AccountNames[i].Length + sizeof(UNICODE_NULL));
2948 Count++;
2949 }
2950 }
2951
2952 if (Size == 0)
2953 {
2954 ApiStatus = NERR_Success;
2955 goto done;
2956 }
2957
2958 /* Allocate buffer */
2959 ApiStatus = NetApiBufferAllocate(Size, (LPVOID*)&Buffer);
2960 if (ApiStatus != NERR_Success)
2961 goto done;
2962
2963 ZeroMemory(Buffer, Size);
2964
2965 StrPtr = (LPWSTR)((INT_PTR)Buffer + Count * sizeof(LOCALGROUP_USERS_INFO_0));
2966
2967 /* Copy data to the allocated buffer */
2968 Index = 0;
2969 for (i = 0; i < BuiltinMemberCount; i++)
2970 {
2971 if (BuiltinNames[i].Length > 0)
2972 {
2973 CopyMemory(StrPtr,
2974 BuiltinNames[i].Buffer,
2975 BuiltinNames[i].Length);
2976 Buffer[Index].lgrui0_name = StrPtr;
2977
2978 StrPtr = (LPWSTR)((INT_PTR)StrPtr + BuiltinNames[i].Length + sizeof(UNICODE_NULL));
2979 Index++;
2980 }
2981 }
2982
2983 for (i = 0; i < AccountMemberCount; i++)
2984 {
2985 if (AccountNames[i].Length > 0)
2986 {
2987 CopyMemory(StrPtr,
2988 AccountNames[i].Buffer,
2989 AccountNames[i].Length);
2990 Buffer[Index].lgrui0_name = StrPtr;
2991
2992 StrPtr = (LPWSTR)((INT_PTR)StrPtr + AccountNames[i].Length + sizeof(UNICODE_NULL));
2993 Index++;
2994 }
2995 }
2996
2997 done:
2998 if (AccountNames != NULL)
2999 SamFreeMemory(AccountNames);
3000
3001 if (BuiltinNames != NULL)
3002 SamFreeMemory(BuiltinNames);
3003
3004 if (AccountAliases != NULL)
3005 SamFreeMemory(AccountAliases);
3006
3007 if (BuiltinAliases != NULL)
3008 SamFreeMemory(BuiltinAliases);
3009
3010 if (RelativeIds != NULL)
3011 SamFreeMemory(RelativeIds);
3012
3013 if (Use != NULL)
3014 SamFreeMemory(Use);
3015
3016 if (UserSid != NULL)
3017 NetApiBufferFree(UserSid);
3018
3019 if (AccountDomainSid != NULL)
3020 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);
3021
3022 if (AccountDomainHandle != NULL)
3023 SamCloseHandle(AccountDomainHandle);
3024
3025 if (BuiltinDomainHandle != NULL)
3026 SamCloseHandle(BuiltinDomainHandle);
3027
3028 if (ServerHandle != NULL)
3029 SamCloseHandle(ServerHandle);
3030
3031 if (ApiStatus != NERR_Success && ApiStatus != ERROR_MORE_DATA)
3032 {
3033 *entriesread = 0;
3034 *totalentries = 0;
3035 }
3036 else
3037 {
3038 *entriesread = Count;
3039 *totalentries = Count;
3040 }
3041
3042 *bufptr = (LPBYTE)Buffer;
3043
3044 return ApiStatus;
3045 }
3046
3047
3048 /******************************************************************************
3049 * NetUserSetGroups (NETAPI32.@)
3050 */
3051 NET_API_STATUS
3052 WINAPI
3053 NetUserSetGroups(LPCWSTR servername,
3054 LPCWSTR username,
3055 DWORD level,
3056 LPBYTE buf,
3057 DWORD num_entries)
3058 {
3059 FIXME("(%s %s %lu %p %lu)\n",
3060 debugstr_w(servername), debugstr_w(username), level, buf, num_entries);
3061 return ERROR_ACCESS_DENIED;
3062 }
3063
3064
3065 /******************************************************************************
3066 * NetUserSetInfo (NETAPI32.@)
3067 */
3068 NET_API_STATUS
3069 WINAPI
3070 NetUserSetInfo(LPCWSTR servername,
3071 LPCWSTR username,
3072 DWORD level,
3073 LPBYTE buf,
3074 LPDWORD parm_err)
3075 {
3076 UNICODE_STRING ServerName;
3077 UNICODE_STRING UserName;
3078 SAM_HANDLE ServerHandle = NULL;
3079 SAM_HANDLE AccountDomainHandle = NULL;
3080 SAM_HANDLE UserHandle = NULL;
3081 NET_API_STATUS ApiStatus = NERR_Success;
3082 NTSTATUS Status = STATUS_SUCCESS;
3083
3084 TRACE("(%s %s %lu %p %p)\n",
3085 debugstr_w(servername), debugstr_w(username), level, buf, parm_err);
3086
3087 if (parm_err != NULL)
3088 *parm_err = PARM_ERROR_NONE;
3089
3090 /* Check the info level */
3091 switch (level)
3092 {
3093 case 0:
3094 case 1:
3095 case 2:
3096 case 3:
3097 // case 4:
3098 // case 21:
3099 // case 22:
3100 case 1003:
3101 // case 1005:
3102 case 1006:
3103 case 1007:
3104 case 1008:
3105 case 1009:
3106 // case 1010:
3107 case 1011:
3108 case 1012:
3109 case 1013:
3110 case 1014:
3111 // case 1017:
3112 // case 1018:
3113 // case 1020:
3114 case 1024:
3115 case 1025:
3116 case 1051:
3117 case 1052:
3118 case 1053:
3119 break;
3120
3121 default:
3122 return ERROR_INVALID_LEVEL;
3123 }
3124
3125 if (servername != NULL)
3126 RtlInitUnicodeString(&ServerName, servername);
3127
3128 RtlInitUnicodeString(&UserName, username);
3129
3130 /* Connect to the SAM Server */
3131 Status = SamConnect((servername != NULL) ? &ServerName : NULL,
3132 &ServerHandle,
3133 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
3134 NULL);
3135 if (!NT_SUCCESS(Status))
3136 {
3137 ERR("SamConnect failed (Status %08lx)\n", Status);
3138 ApiStatus = NetpNtStatusToApiStatus(Status);
3139 goto done;
3140 }
3141
3142 /* Open the Account Domain */
3143 Status = OpenAccountDomain(ServerHandle,
3144 (servername != NULL) ? &ServerName : NULL,
3145 DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
3146 &AccountDomainHandle);
3147 if (!NT_SUCCESS(Status))
3148 {
3149 ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
3150 ApiStatus = NetpNtStatusToApiStatus(Status);
3151 goto done;
3152 }
3153
3154 /* Open the User Account */
3155 ApiStatus = OpenUserByName(AccountDomainHandle,
3156 &UserName,
3157 USER_ALL_ACCESS,
3158 &UserHandle);
3159 if (ApiStatus != NERR_Success)
3160 {
3161 ERR("OpenUserByName failed (ApiStatus %lu)\n", ApiStatus);
3162 goto done;
3163 }
3164
3165 /* Set user information */
3166 ApiStatus = SetUserInfo(UserHandle,
3167 buf,
3168 level);
3169 if (ApiStatus != NERR_Success)
3170 {
3171 ERR("SetUserInfo failed (Status %lu)\n", ApiStatus);
3172 }
3173
3174 done:
3175 if (UserHandle != NULL)
3176 SamCloseHandle(UserHandle);
3177
3178 if (AccountDomainHandle != NULL)
3179 SamCloseHandle(AccountDomainHandle);
3180
3181 if (ServerHandle != NULL)
3182 SamCloseHandle(ServerHandle);
3183
3184 return ApiStatus;
3185 }
3186
3187 /* EOF */