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