[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 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_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 // UserInfo2->usri2_acct_expires;
1464 // UserInfo2->usri2_max_storage;
1465 // UserInfo2->usri2_units_per_week;
1466 // UserInfo2->usri2_logon_hours;
1467
1468 // usri2_bad_pw_count ignored
1469 // usri2_num_logons ignored
1470 // usri2_logon_server ignored
1471
1472 UserAllInfo.CountryCode = UserInfo2->usri2_country_code;
1473 UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
1474
1475 UserAllInfo.CodePage = UserInfo2->usri2_code_page;
1476 UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
1477 break;
1478
1479 case 3:
1480 UserInfo3 = (PUSER_INFO_3)UserInfo;
1481
1482 // usri3_name ignored
1483
1484 if (UserInfo3->usri3_password != NULL)
1485 {
1486 RtlInitUnicodeString(&UserAllInfo.NtPassword,
1487 UserInfo3->usri3_password);
1488 UserAllInfo.NtPasswordPresent = TRUE;
1489 UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
1490 }
1491
1492 // usri3_password_age ignored
1493
1494 // UserInfo3->usri3_priv;
1495
1496 if (UserInfo3->usri3_home_dir != NULL)
1497 {
1498 RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1499 UserInfo3->usri3_home_dir);
1500 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1501 }
1502
1503 if (UserInfo3->usri3_comment != NULL)
1504 {
1505 RtlInitUnicodeString(&UserAllInfo.AdminComment,
1506 UserInfo3->usri3_comment);
1507 UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1508 }
1509
1510 UserAllInfo.UserAccountControl = GetAccountControl(UserInfo3->usri3_flags);
1511 UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
1512
1513 if (UserInfo3->usri3_script_path != NULL)
1514 {
1515 RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1516 UserInfo3->usri3_script_path);
1517 UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1518 }
1519
1520 // UserInfo3->usri3_auth_flags;
1521
1522 if (UserInfo3->usri3_full_name != NULL)
1523 {
1524 RtlInitUnicodeString(&UserAllInfo.FullName,
1525 UserInfo3->usri3_full_name);
1526 UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
1527 }
1528
1529 if (UserInfo3->usri3_usr_comment != NULL)
1530 {
1531 RtlInitUnicodeString(&UserAllInfo.UserComment,
1532 UserInfo3->usri3_usr_comment);
1533 UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
1534 }
1535
1536 if (UserInfo3->usri3_parms != NULL)
1537 {
1538 RtlInitUnicodeString(&UserAllInfo.Parameters,
1539 UserInfo3->usri3_parms);
1540 UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
1541 }
1542
1543 if (UserInfo3->usri3_workstations != NULL)
1544 {
1545 RtlInitUnicodeString(&UserAllInfo.WorkStations,
1546 UserInfo3->usri3_workstations);
1547 UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
1548 }
1549
1550 // usri3_last_logon ignored
1551 // usri3_last_logoff ignored
1552
1553 // UserInfo3->usri3_acct_expires;
1554 // UserInfo3->usri3_max_storage;
1555 // UserInfo3->usri3_units_per_week;
1556 // UserInfo3->usri3_logon_hours;
1557
1558 // usri3_bad_pw_count ignored
1559 // usri3_num_logons ignored
1560 // usri3_logon_server ignored
1561
1562 UserAllInfo.CountryCode = UserInfo3->usri3_country_code;
1563 UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
1564
1565 UserAllInfo.CodePage = UserInfo3->usri3_code_page;
1566 UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
1567
1568 // usri3_user_id ignored
1569
1570 UserAllInfo.PrimaryGroupId = UserInfo3->usri3_primary_group_id;
1571 UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID;
1572
1573 if (UserInfo3->usri3_profile != NULL)
1574 {
1575 RtlInitUnicodeString(&UserAllInfo.ProfilePath,
1576 UserInfo3->usri3_profile);
1577 UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH;
1578 }
1579
1580 if (UserInfo3->usri3_home_dir_drive != NULL)
1581 {
1582 RtlInitUnicodeString(&UserAllInfo.HomeDirectoryDrive,
1583 UserInfo3->usri3_home_dir_drive);
1584 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORYDRIVE;
1585 }
1586
1587 UserAllInfo.PasswordExpired = (UserInfo3->usri3_password_expired != 0);
1588 UserAllInfo.WhichFields |= USER_ALL_PASSWORDEXPIRED;
1589 break;
1590
1591 case 4:
1592 UserInfo4 = (PUSER_INFO_4)UserInfo;
1593
1594 // usri4_name ignored
1595
1596 if (UserInfo4->usri4_password != NULL)
1597 {
1598 RtlInitUnicodeString(&UserAllInfo.NtPassword,
1599 UserInfo4->usri4_password);
1600 UserAllInfo.NtPasswordPresent = TRUE;
1601 UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
1602 }
1603
1604 // usri4_password_age ignored
1605
1606 // UserInfo3->usri4_priv;
1607
1608 if (UserInfo4->usri4_home_dir != NULL)
1609 {
1610 RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1611 UserInfo4->usri4_home_dir);
1612 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1613 }
1614
1615 if (UserInfo4->usri4_comment != NULL)
1616 {
1617 RtlInitUnicodeString(&UserAllInfo.AdminComment,
1618 UserInfo4->usri4_comment);
1619 UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1620 }
1621
1622 UserAllInfo.UserAccountControl = GetAccountControl(UserInfo4->usri4_flags);
1623 UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
1624
1625 if (UserInfo4->usri4_script_path != NULL)
1626 {
1627 RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1628 UserInfo4->usri4_script_path);
1629 UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1630 }
1631
1632 // UserInfo4->usri4_auth_flags;
1633
1634 if (UserInfo4->usri4_full_name != NULL)
1635 {
1636 RtlInitUnicodeString(&UserAllInfo.FullName,
1637 UserInfo4->usri4_full_name);
1638 UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
1639 }
1640
1641 if (UserInfo4->usri4_usr_comment != NULL)
1642 {
1643 RtlInitUnicodeString(&UserAllInfo.UserComment,
1644 UserInfo4->usri4_usr_comment);
1645 UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
1646 }
1647
1648 if (UserInfo4->usri4_parms != NULL)
1649 {
1650 RtlInitUnicodeString(&UserAllInfo.Parameters,
1651 UserInfo4->usri4_parms);
1652 UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
1653 }
1654
1655 if (UserInfo4->usri4_workstations != NULL)
1656 {
1657 RtlInitUnicodeString(&UserAllInfo.WorkStations,
1658 UserInfo4->usri4_workstations);
1659 UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
1660 }
1661
1662 // usri4_last_logon ignored
1663 // usri4_last_logoff ignored
1664
1665 // UserInfo3->usri4_acct_expires;
1666 // UserInfo3->usri4_max_storage;
1667 // UserInfo3->usri4_units_per_week;
1668 // UserInfo3->usri4_logon_hours;
1669
1670 // usri4_bad_pw_count ignored
1671 // usri4_num_logons ignored
1672 // usri4_logon_server ignored
1673
1674 UserAllInfo.CountryCode = UserInfo4->usri4_country_code;
1675 UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
1676
1677 UserAllInfo.CodePage = UserInfo4->usri4_code_page;
1678 UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
1679
1680 // usri4_user_sid ignored
1681
1682 UserAllInfo.PrimaryGroupId = UserInfo4->usri4_primary_group_id;
1683 UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID;
1684
1685 if (UserInfo4->usri4_profile != NULL)
1686 {
1687 RtlInitUnicodeString(&UserAllInfo.ProfilePath,
1688 UserInfo4->usri4_profile);
1689 UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH;
1690 }
1691
1692 if (UserInfo4->usri4_home_dir_drive != NULL)
1693 {
1694 RtlInitUnicodeString(&UserAllInfo.HomeDirectoryDrive,
1695 UserInfo4->usri4_home_dir_drive);
1696 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORYDRIVE;
1697 }
1698
1699 UserAllInfo.PasswordExpired = (UserInfo4->usri4_password_expired != 0);
1700 UserAllInfo.WhichFields |= USER_ALL_PASSWORDEXPIRED;
1701 break;
1702
1703 // case 21:
1704 // case 22:
1705
1706 case 1003:
1707 UserInfo1003 = (PUSER_INFO_1003)UserInfo;
1708
1709 if (UserInfo1003->usri1003_password != NULL)
1710 {
1711 RtlInitUnicodeString(&UserAllInfo.NtPassword,
1712 UserInfo1003->usri1003_password);
1713 UserAllInfo.NtPasswordPresent = TRUE;
1714 UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
1715 }
1716 break;
1717
1718 // case 1005:
1719
1720 case 1006:
1721 UserInfo1006 = (PUSER_INFO_1006)UserInfo;
1722
1723 if (UserInfo1006->usri1006_home_dir != NULL)
1724 {
1725 RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
1726 UserInfo1006->usri1006_home_dir);
1727 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
1728 }
1729 break;
1730
1731 case 1007:
1732 UserInfo1007 = (PUSER_INFO_1007)UserInfo;
1733
1734 if (UserInfo1007->usri1007_comment != NULL)
1735 {
1736 RtlInitUnicodeString(&UserAllInfo.AdminComment,
1737 UserInfo1007->usri1007_comment);
1738 UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
1739 }
1740 break;
1741
1742 case 1008:
1743 UserInfo1008 = (PUSER_INFO_1008)UserInfo;
1744 UserAllInfo.UserAccountControl = GetAccountControl(UserInfo1008->usri1008_flags);
1745 UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
1746 break;
1747
1748 case 1009:
1749 UserInfo1009 = (PUSER_INFO_1009)UserInfo;
1750
1751 if (UserInfo1009->usri1009_script_path != NULL)
1752 {
1753 RtlInitUnicodeString(&UserAllInfo.ScriptPath,
1754 UserInfo1009->usri1009_script_path);
1755 UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
1756 }
1757 break;
1758
1759 // case 1010:
1760
1761 case 1011:
1762 UserInfo1011 = (PUSER_INFO_1011)UserInfo;
1763
1764 if (UserInfo1011->usri1011_full_name != NULL)
1765 {
1766 RtlInitUnicodeString(&UserAllInfo.FullName,
1767 UserInfo1011->usri1011_full_name);
1768 UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
1769 }
1770 break;
1771
1772 case 1012:
1773 UserInfo1012 = (PUSER_INFO_1012)UserInfo;
1774
1775 if (UserInfo1012->usri1012_usr_comment != NULL)
1776 {
1777 RtlInitUnicodeString(&UserAllInfo.UserComment,
1778 UserInfo1012->usri1012_usr_comment);
1779 UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
1780 }
1781 break;
1782
1783 case 1013:
1784 UserInfo1013 = (PUSER_INFO_1013)UserInfo;
1785
1786 if (UserInfo1013->usri1013_parms != NULL)
1787 {
1788 RtlInitUnicodeString(&UserAllInfo.Parameters,
1789 UserInfo1013->usri1013_parms);
1790 UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
1791 }
1792 break;
1793
1794 case 1014:
1795 UserInfo1014 = (PUSER_INFO_1014)UserInfo;
1796
1797 if (UserInfo1014->usri1014_workstations != NULL)
1798 {
1799 RtlInitUnicodeString(&UserAllInfo.WorkStations,
1800 UserInfo1014->usri1014_workstations);
1801 UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
1802 }
1803 break;
1804
1805 // case 1017:
1806 // case 1018:
1807 // case 1020:
1808
1809 case 1024:
1810 UserInfo1024 = (PUSER_INFO_1024)UserInfo;
1811
1812 UserAllInfo.CountryCode = UserInfo1024->usri1024_country_code;
1813 UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
1814 break;
1815
1816 case 1025:
1817 UserInfo1025 = (PUSER_INFO_1025)UserInfo;
1818
1819 UserAllInfo.CodePage = UserInfo1025->usri1025_code_page;
1820 UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
1821 break;
1822
1823 case 1051:
1824 UserInfo1051 = (PUSER_INFO_1051)UserInfo;
1825
1826 UserAllInfo.PrimaryGroupId = UserInfo1051->usri1051_primary_group_id;
1827 UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID;
1828 break;
1829
1830 case 1052:
1831 UserInfo1052 = (PUSER_INFO_1052)UserInfo;
1832
1833 if (UserInfo1052->usri1052_profile != NULL)
1834 {
1835 RtlInitUnicodeString(&UserAllInfo.ProfilePath,
1836 UserInfo1052->usri1052_profile);
1837 UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH;
1838 }
1839 break;
1840
1841 case 1053:
1842 UserInfo1053 = (PUSER_INFO_1053)UserInfo;
1843
1844 if (UserInfo1053->usri1053_home_dir_drive != NULL)
1845 {
1846 RtlInitUnicodeString(&UserAllInfo.HomeDirectoryDrive,
1847 UserInfo1053->usri1053_home_dir_drive);
1848 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORYDRIVE;
1849 }
1850 break;
1851
1852 default:
1853 ERR("Unsupported level %lu!\n", Level);
1854 return ERROR_INVALID_PARAMETER;
1855 }
1856
1857 Status = SamSetInformationUser(UserHandle,
1858 UserAllInformation,
1859 &UserAllInfo);
1860 if (!NT_SUCCESS(Status))
1861 {
1862 ERR("SamSetInformationUser failed (Status %08lx)\n", Status);
1863 ApiStatus = NetpNtStatusToApiStatus(Status);
1864 goto done;
1865 }
1866
1867 done:
1868 return ApiStatus;
1869 }
1870
1871
1872 static
1873 NET_API_STATUS
1874 OpenUserByName(SAM_HANDLE DomainHandle,
1875 PUNICODE_STRING UserName,
1876 ULONG DesiredAccess,
1877 PSAM_HANDLE UserHandle)
1878 {
1879 PULONG RelativeIds = NULL;
1880 PSID_NAME_USE Use = NULL;
1881 NET_API_STATUS ApiStatus = NERR_Success;
1882 NTSTATUS Status = STATUS_SUCCESS;
1883
1884 /* Get the RID for the given user name */
1885 Status = SamLookupNamesInDomain(DomainHandle,
1886 1,
1887 UserName,
1888 &RelativeIds,
1889 &Use);
1890 if (!NT_SUCCESS(Status))
1891 {
1892 ERR("SamLookupNamesInDomain failed (Status %08lx)\n", Status);
1893 return NetpNtStatusToApiStatus(Status);
1894 }
1895
1896 /* Fail, if it is not an alias account */
1897 if (Use[0] != SidTypeUser)
1898 {
1899 ERR("Object is not a user!\n");
1900 ApiStatus = NERR_GroupNotFound;
1901 goto done;
1902 }
1903
1904 /* Open the alias account */
1905 Status = SamOpenUser(DomainHandle,
1906 DesiredAccess,
1907 RelativeIds[0],
1908 UserHandle);
1909 if (!NT_SUCCESS(Status))
1910 {
1911 ERR("SamOpenUser failed (Status %08lx)\n", Status);
1912 ApiStatus = NetpNtStatusToApiStatus(Status);
1913 goto done;
1914 }
1915
1916 done:
1917 if (RelativeIds != NULL)
1918 SamFreeMemory(RelativeIds);
1919
1920 if (Use != NULL)
1921 SamFreeMemory(Use);
1922
1923 return ApiStatus;
1924 }
1925
1926
1927 /************************************************************
1928 * NetUserAdd (NETAPI32.@)
1929 */
1930 NET_API_STATUS
1931 WINAPI
1932 NetUserAdd(LPCWSTR servername,
1933 DWORD level,
1934 LPBYTE bufptr,
1935 LPDWORD parm_err)
1936 {
1937 UNICODE_STRING ServerName;
1938 UNICODE_STRING UserName;
1939 SAM_HANDLE ServerHandle = NULL;
1940 SAM_HANDLE DomainHandle = NULL;
1941 SAM_HANDLE UserHandle = NULL;
1942 ULONG GrantedAccess;
1943 ULONG RelativeId;
1944 NET_API_STATUS ApiStatus = NERR_Success;
1945 NTSTATUS Status = STATUS_SUCCESS;
1946
1947 TRACE("(%s, %d, %p, %p)\n", debugstr_w(servername), level, bufptr, parm_err);
1948
1949 /* Check the info level */
1950 switch (level)
1951 {
1952 case 1:
1953 case 2:
1954 case 3:
1955 case 4:
1956 break;
1957
1958 default:
1959 return ERROR_INVALID_LEVEL;
1960 }
1961
1962 if (servername != NULL)
1963 RtlInitUnicodeString(&ServerName, servername);
1964
1965 /* Connect to the SAM Server */
1966 Status = SamConnect((servername != NULL) ? &ServerName : NULL,
1967 &ServerHandle,
1968 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
1969 NULL);
1970 if (!NT_SUCCESS(Status))
1971 {
1972 ERR("SamConnect failed (Status %08lx)\n", Status);
1973 ApiStatus = NetpNtStatusToApiStatus(Status);
1974 goto done;
1975 }
1976
1977 /* Open the Account Domain */
1978 Status = OpenAccountDomain(ServerHandle,
1979 (servername != NULL) ? &ServerName : NULL,
1980 DOMAIN_CREATE_USER | DOMAIN_LOOKUP,
1981 &DomainHandle);
1982 if (!NT_SUCCESS(Status))
1983 {
1984 ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
1985 ApiStatus = NetpNtStatusToApiStatus(Status);
1986 goto done;
1987 }
1988
1989 /* Initialize the user name string */
1990 RtlInitUnicodeString(&UserName,
1991 ((PUSER_INFO_1)bufptr)->usri1_name);
1992
1993 /* Create the user account */
1994 Status = SamCreateUser2InDomain(DomainHandle,
1995 &UserName,
1996 USER_NORMAL_ACCOUNT,
1997 USER_ALL_ACCESS | DELETE | WRITE_DAC,
1998 &UserHandle,
1999 &GrantedAccess,
2000 &RelativeId);
2001 if (!NT_SUCCESS(Status))
2002 {
2003 ERR("SamCreateUser2InDomain failed (Status %08lx)\n", Status);
2004 ApiStatus = NetpNtStatusToApiStatus(Status);
2005 goto done;
2006 }
2007
2008 /* Set user information */
2009 ApiStatus = SetUserInfo(UserHandle,
2010 bufptr,
2011 level);
2012 if (ApiStatus != NERR_Success)
2013 {
2014 ERR("SetUserInfo failed (Status %lu)\n", ApiStatus);
2015 goto done;
2016 }
2017
2018 done:
2019 if (UserHandle != NULL)
2020 SamCloseHandle(UserHandle);
2021
2022 if (DomainHandle != NULL)
2023 SamCloseHandle(DomainHandle);
2024
2025 if (ServerHandle != NULL)
2026 SamCloseHandle(ServerHandle);
2027
2028 return ApiStatus;
2029 }
2030
2031
2032 /******************************************************************************
2033 * NetUserChangePassword (NETAPI32.@)
2034 * PARAMS
2035 * domainname [I] Optional. Domain on which the user resides or the logon
2036 * domain of the current user if NULL.
2037 * username [I] Optional. Username to change the password for or the name
2038 * of the current user if NULL.
2039 * oldpassword [I] The user's current password.
2040 * newpassword [I] The password that the user will be changed to using.
2041 *
2042 * RETURNS
2043 * Success: NERR_Success.
2044 * Failure: NERR_* failure code or win error code.
2045 *
2046 */
2047 NET_API_STATUS
2048 WINAPI
2049 NetUserChangePassword(LPCWSTR domainname,
2050 LPCWSTR username,
2051 LPCWSTR oldpassword,
2052 LPCWSTR newpassword)
2053 {
2054 TRACE("(%s, %s, ..., ...)\n", debugstr_w(domainname), debugstr_w(username));
2055 return NERR_Success;
2056 }
2057
2058
2059 /************************************************************
2060 * NetUserDel (NETAPI32.@)
2061 */
2062 NET_API_STATUS
2063 WINAPI
2064 NetUserDel(LPCWSTR servername,
2065 LPCWSTR username)
2066 {
2067 UNICODE_STRING ServerName;
2068 UNICODE_STRING UserName;
2069 SAM_HANDLE ServerHandle = NULL;
2070 SAM_HANDLE DomainHandle = NULL;
2071 SAM_HANDLE UserHandle = NULL;
2072 NET_API_STATUS ApiStatus = NERR_Success;
2073 NTSTATUS Status = STATUS_SUCCESS;
2074
2075 TRACE("(%s, %s)\n", debugstr_w(servername), debugstr_w(username));
2076
2077 if (servername != NULL)
2078 RtlInitUnicodeString(&ServerName, servername);
2079
2080 RtlInitUnicodeString(&UserName, username);
2081
2082 /* Connect to the SAM Server */
2083 Status = SamConnect((servername != NULL) ? &ServerName : NULL,
2084 &ServerHandle,
2085 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
2086 NULL);
2087 if (!NT_SUCCESS(Status))
2088 {
2089 ERR("SamConnect failed (Status %08lx)\n", Status);
2090 ApiStatus = NetpNtStatusToApiStatus(Status);
2091 goto done;
2092 }
2093
2094 /* Open the Builtin Domain */
2095 Status = OpenBuiltinDomain(ServerHandle,
2096 DOMAIN_LOOKUP,
2097 &DomainHandle);
2098 if (!NT_SUCCESS(Status))
2099 {
2100 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status);
2101 ApiStatus = NetpNtStatusToApiStatus(Status);
2102 goto done;
2103 }
2104
2105 /* Open the user account in the builtin domain */
2106 ApiStatus = OpenUserByName(DomainHandle,
2107 &UserName,
2108 DELETE,
2109 &UserHandle);
2110 if (ApiStatus != NERR_Success && ApiStatus != ERROR_NONE_MAPPED)
2111 {
2112 TRACE("OpenUserByName failed (ApiStatus %lu)\n", ApiStatus);
2113 goto done;
2114 }
2115
2116 if (UserHandle == NULL)
2117 {
2118 if (DomainHandle != NULL)
2119 {
2120 SamCloseHandle(DomainHandle);
2121 DomainHandle = NULL;
2122 }
2123
2124 /* Open the Acount Domain */
2125 Status = OpenAccountDomain(ServerHandle,
2126 (servername != NULL) ? &ServerName : NULL,
2127 DOMAIN_LOOKUP,
2128 &DomainHandle);
2129 if (!NT_SUCCESS(Status))
2130 {
2131 ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
2132 ApiStatus = NetpNtStatusToApiStatus(Status);
2133 goto done;
2134 }
2135
2136 /* Open the user account in the account domain */
2137 ApiStatus = OpenUserByName(DomainHandle,
2138 &UserName,
2139 DELETE,
2140 &UserHandle);
2141 if (ApiStatus != NERR_Success)
2142 {
2143 ERR("OpenUserByName failed (ApiStatus %lu)\n", ApiStatus);
2144 if (ApiStatus == ERROR_NONE_MAPPED)
2145 ApiStatus = NERR_GroupNotFound;
2146 goto done;
2147 }
2148 }
2149
2150 /* Delete the user */
2151 Status = SamDeleteUser(UserHandle);
2152 if (!NT_SUCCESS(Status))
2153 {
2154 ERR("SamDeleteUser failed (Status %08lx)\n", Status);
2155 ApiStatus = NetpNtStatusToApiStatus(Status);
2156 goto done;
2157 }
2158
2159 done:
2160 if (UserHandle != NULL)
2161 SamCloseHandle(UserHandle);
2162
2163 if (DomainHandle != NULL)
2164 SamCloseHandle(DomainHandle);
2165
2166 if (ServerHandle != NULL)
2167 SamCloseHandle(ServerHandle);
2168
2169 return ApiStatus;
2170 }
2171
2172
2173 /************************************************************
2174 * NetUserEnum (NETAPI32.@)
2175 */
2176 NET_API_STATUS
2177 WINAPI
2178 NetUserEnum(LPCWSTR servername,
2179 DWORD level,
2180 DWORD filter,
2181 LPBYTE* bufptr,
2182 DWORD prefmaxlen,
2183 LPDWORD entriesread,
2184 LPDWORD totalentries,
2185 LPDWORD resume_handle)
2186 {
2187 UNICODE_STRING ServerName;
2188 PSAM_RID_ENUMERATION CurrentUser;
2189 PENUM_CONTEXT EnumContext = NULL;
2190 LPVOID Buffer = NULL;
2191 ULONG i;
2192 SAM_HANDLE UserHandle = NULL;
2193 PUSER_ALL_INFORMATION UserInfo = NULL;
2194
2195 NET_API_STATUS ApiStatus = NERR_Success;
2196 NTSTATUS Status = STATUS_SUCCESS;
2197
2198 TRACE("(%s %d 0x%d %p %d %p %p %p)\n", debugstr_w(servername), level,
2199 filter, bufptr, prefmaxlen, entriesread, totalentries, resume_handle);
2200
2201 *entriesread = 0;
2202 *totalentries = 0;
2203 *bufptr = NULL;
2204
2205 if (servername != NULL)
2206 RtlInitUnicodeString(&ServerName, servername);
2207
2208 if (resume_handle != NULL && *resume_handle != 0)
2209 {
2210 EnumContext = (PENUM_CONTEXT)*resume_handle;
2211 }
2212 else
2213 {
2214 ApiStatus = NetApiBufferAllocate(sizeof(ENUM_CONTEXT), (PVOID*)&EnumContext);
2215 if (ApiStatus != NERR_Success)
2216 goto done;
2217
2218 EnumContext->EnumerationContext = 0;
2219 EnumContext->Buffer = NULL;
2220 EnumContext->Count = 0;
2221 EnumContext->Index = 0;
2222 EnumContext->BuiltinDone = FALSE;
2223
2224 Status = SamConnect((servername != NULL) ? &ServerName : NULL,
2225 &EnumContext->ServerHandle,
2226 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
2227 NULL);
2228 if (!NT_SUCCESS(Status))
2229 {
2230 ERR("SamConnect failed (Status %08lx)\n", Status);
2231 ApiStatus = NetpNtStatusToApiStatus(Status);
2232 goto done;
2233 }
2234
2235 Status = OpenAccountDomain(EnumContext->ServerHandle,
2236 (servername != NULL) ? &ServerName : NULL,
2237 DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
2238 &EnumContext->AccountDomainHandle);
2239 if (!NT_SUCCESS(Status))
2240 {
2241 ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
2242 ApiStatus = NetpNtStatusToApiStatus(Status);
2243 goto done;
2244 }
2245
2246 Status = OpenBuiltinDomain(EnumContext->ServerHandle,
2247 DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
2248 &EnumContext->BuiltinDomainHandle);
2249 if (!NT_SUCCESS(Status))
2250 {
2251 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status);
2252 ApiStatus = NetpNtStatusToApiStatus(Status);
2253 goto done;
2254 }
2255 }
2256
2257 // while (TRUE)
2258 // {
2259 TRACE("EnumContext->Index: %lu\n", EnumContext->Index);
2260 TRACE("EnumContext->Count: %lu\n", EnumContext->Count);
2261
2262 if (EnumContext->Index >= EnumContext->Count)
2263 {
2264 // if (EnumContext->BuiltinDone == TRUE)
2265 // {
2266 // ApiStatus = NERR_Success;
2267 // goto done;
2268 // }
2269
2270 TRACE("Calling SamEnumerateUsersInDomain\n");
2271 Status = SamEnumerateUsersInDomain(EnumContext->AccountDomainHandle, //BuiltinDomainHandle,
2272 &EnumContext->EnumerationContext,
2273 0,
2274 (PVOID *)&EnumContext->Buffer,
2275 prefmaxlen,
2276 &EnumContext->Count);
2277
2278 TRACE("SamEnumerateUsersInDomain returned (Status %08lx)\n", Status);
2279 if (!NT_SUCCESS(Status))
2280 {
2281 ERR("SamEnumerateUsersInDomain failed (Status %08lx)\n", Status);
2282 ApiStatus = NetpNtStatusToApiStatus(Status);
2283 goto done;
2284 }
2285
2286 if (Status == STATUS_MORE_ENTRIES)
2287 {
2288 ApiStatus = NERR_BufTooSmall;
2289 goto done;
2290 }
2291 else
2292 {
2293 EnumContext->BuiltinDone = TRUE;
2294 }
2295 }
2296
2297 TRACE("EnumContext: %lu\n", EnumContext);
2298 TRACE("EnumContext->Count: %lu\n", EnumContext->Count);
2299 TRACE("EnumContext->Buffer: %p\n", EnumContext->Buffer);
2300
2301 /* Get a pointer to the current user */
2302 CurrentUser = &EnumContext->Buffer[EnumContext->Index];
2303
2304 TRACE("RID: %lu\n", CurrentUser->RelativeId);
2305
2306 Status = SamOpenUser(EnumContext->AccountDomainHandle, //BuiltinDomainHandle,
2307 USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT,
2308 CurrentUser->RelativeId,
2309 &UserHandle);
2310 if (!NT_SUCCESS(Status))
2311 {
2312 ERR("SamOpenUser failed (Status %08lx)\n", Status);
2313 ApiStatus = NetpNtStatusToApiStatus(Status);
2314 goto done;
2315 }
2316
2317 Status = SamQueryInformationUser(UserHandle,
2318 UserAllInformation,
2319 (PVOID *)&UserInfo);
2320 if (!NT_SUCCESS(Status))
2321 {
2322 ERR("SamQueryInformationUser failed (Status %08lx)\n", Status);
2323 ApiStatus = NetpNtStatusToApiStatus(Status);
2324 goto done;
2325 }
2326
2327 SamCloseHandle(UserHandle);
2328 UserHandle = NULL;
2329
2330 ApiStatus = BuildUserInfoBuffer(UserInfo,
2331 level,
2332 CurrentUser->RelativeId,
2333 &Buffer);
2334 if (ApiStatus != NERR_Success)
2335 {
2336 ERR("BuildUserInfoBuffer failed (ApiStatus %lu)\n", ApiStatus);
2337 goto done;
2338 }
2339
2340 if (UserInfo != NULL)
2341 {
2342 FreeUserInfo(UserInfo);
2343 UserInfo = NULL;
2344 }
2345
2346 EnumContext->Index++;
2347
2348 (*entriesread)++;
2349 // }
2350
2351 done:
2352 if (ApiStatus == NERR_Success && EnumContext->Index < EnumContext->Count)
2353 ApiStatus = ERROR_MORE_DATA;
2354
2355 if (EnumContext != NULL)
2356 *totalentries = EnumContext->Count;
2357
2358 if (resume_handle == NULL || ApiStatus != ERROR_MORE_DATA)
2359 {
2360 if (EnumContext != NULL)
2361 {
2362 if (EnumContext->BuiltinDomainHandle != NULL)
2363 SamCloseHandle(EnumContext->BuiltinDomainHandle);
2364
2365 if (EnumContext->AccountDomainHandle != NULL)
2366 SamCloseHandle(EnumContext->AccountDomainHandle);
2367
2368 if (EnumContext->ServerHandle != NULL)
2369 SamCloseHandle(EnumContext->ServerHandle);
2370
2371 if (EnumContext->Buffer != NULL)
2372 {
2373 for (i = 0; i < EnumContext->Count; i++)
2374 {
2375 SamFreeMemory(EnumContext->Buffer[i].Name.Buffer);
2376 }
2377
2378 SamFreeMemory(EnumContext->Buffer);
2379 }
2380
2381 NetApiBufferFree(EnumContext);
2382 EnumContext = NULL;
2383 }
2384 }
2385
2386 if (UserHandle != NULL)
2387 SamCloseHandle(UserHandle);
2388
2389 if (UserInfo != NULL)
2390 FreeUserInfo(UserInfo);
2391
2392 if (resume_handle != NULL)
2393 *resume_handle = (DWORD_PTR)EnumContext;
2394
2395 *bufptr = (LPBYTE)Buffer;
2396
2397 TRACE("return %lu\n", ApiStatus);
2398
2399 return ApiStatus;
2400 }
2401
2402
2403 /************************************************************
2404 * NetUserGetGroups (NETAPI32.@)
2405 */
2406 NET_API_STATUS
2407 WINAPI
2408 NetUserGetGroups(LPCWSTR servername,
2409 LPCWSTR username,
2410 DWORD level,
2411 LPBYTE *bufptr,
2412 DWORD prefixmaxlen,
2413 LPDWORD entriesread,
2414 LPDWORD totalentries)
2415 {
2416 FIXME("%s %s %d %p %d %p %p stub\n", debugstr_w(servername),
2417 debugstr_w(username), level, bufptr, prefixmaxlen, entriesread,
2418 totalentries);
2419
2420 *bufptr = NULL;
2421 *entriesread = 0;
2422 *totalentries = 0;
2423
2424 return ERROR_INVALID_LEVEL;
2425 }
2426
2427
2428 /************************************************************
2429 * NetUserGetInfo (NETAPI32.@)
2430 */
2431 NET_API_STATUS
2432 WINAPI
2433 NetUserGetInfo(LPCWSTR servername,
2434 LPCWSTR username,
2435 DWORD level,
2436 LPBYTE* bufptr)
2437 {
2438 UNICODE_STRING ServerName;
2439 UNICODE_STRING UserName;
2440 SAM_HANDLE ServerHandle = NULL;
2441 SAM_HANDLE AccountDomainHandle = NULL;
2442 SAM_HANDLE UserHandle = NULL;
2443 PULONG RelativeIds = NULL;
2444 PSID_NAME_USE Use = NULL;
2445 PUSER_ALL_INFORMATION UserInfo = NULL;
2446 LPVOID Buffer = NULL;
2447 NET_API_STATUS ApiStatus = NERR_Success;
2448 NTSTATUS Status = STATUS_SUCCESS;
2449
2450 TRACE("(%s, %s, %d, %p)\n", debugstr_w(servername),
2451 debugstr_w(username), level, bufptr);
2452
2453 if (servername != NULL)
2454 RtlInitUnicodeString(&ServerName, servername);
2455
2456 RtlInitUnicodeString(&UserName, username);
2457
2458 /* Connect to the SAM Server */
2459 Status = SamConnect((servername != NULL) ? &ServerName : NULL,
2460 &ServerHandle,
2461 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
2462 NULL);
2463 if (!NT_SUCCESS(Status))
2464 {
2465 ERR("SamConnect failed (Status %08lx)\n", Status);
2466 ApiStatus = NetpNtStatusToApiStatus(Status);
2467 goto done;
2468 }
2469
2470 /* Open the Account Domain */
2471 Status = OpenAccountDomain(ServerHandle,
2472 (servername != NULL) ? &ServerName : NULL,
2473 DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
2474 &AccountDomainHandle);
2475 if (!NT_SUCCESS(Status))
2476 {
2477 ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
2478 ApiStatus = NetpNtStatusToApiStatus(Status);
2479 goto done;
2480 }
2481
2482 /* Get the RID for the given user name */
2483 Status = SamLookupNamesInDomain(AccountDomainHandle,
2484 1,
2485 &UserName,
2486 &RelativeIds,
2487 &Use);
2488 if (!NT_SUCCESS(Status))
2489 {
2490 ERR("SamOpenDomain failed (Status %08lx)\n", Status);
2491 ApiStatus = NetpNtStatusToApiStatus(Status);
2492 goto done;
2493 }
2494
2495 /* Check if the account is a user account */
2496 if (Use[0] != SidTypeUser)
2497 {
2498 ERR("No user found!\n");
2499 ApiStatus = NERR_UserNotFound;
2500 goto done;
2501 }
2502
2503 TRACE("RID: %lu\n", RelativeIds[0]);
2504
2505 /* Open the user object */
2506 Status = SamOpenUser(AccountDomainHandle,
2507 USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT,
2508 RelativeIds[0],
2509 &UserHandle);
2510 if (!NT_SUCCESS(Status))
2511 {
2512 ERR("SamOpenUser failed (Status %08lx)\n", Status);
2513 ApiStatus = NetpNtStatusToApiStatus(Status);
2514 goto done;
2515 }
2516
2517 Status = SamQueryInformationUser(UserHandle,
2518 UserAllInformation,
2519 (PVOID *)&UserInfo);
2520 if (!NT_SUCCESS(Status))
2521 {
2522 ERR("SamQueryInformationUser failed (Status %08lx)\n", Status);
2523 ApiStatus = NetpNtStatusToApiStatus(Status);
2524 goto done;
2525 }
2526
2527 ApiStatus = BuildUserInfoBuffer(UserInfo,
2528 level,
2529 RelativeIds[0],
2530 &Buffer);
2531 if (ApiStatus != NERR_Success)
2532 {
2533 ERR("BuildUserInfoBuffer failed (ApiStatus %08lu)\n", ApiStatus);
2534 goto done;
2535 }
2536
2537 done:
2538 if (UserInfo != NULL)
2539 FreeUserInfo(UserInfo);
2540
2541 if (UserHandle != NULL)
2542 SamCloseHandle(UserHandle);
2543
2544 if (RelativeIds != NULL)
2545 SamFreeMemory(RelativeIds);
2546
2547 if (Use != NULL)
2548 SamFreeMemory(Use);
2549
2550 if (AccountDomainHandle != NULL)
2551 SamCloseHandle(AccountDomainHandle);
2552
2553 if (ServerHandle != NULL)
2554 SamCloseHandle(ServerHandle);
2555
2556 *bufptr = (LPBYTE)Buffer;
2557
2558 return ApiStatus;
2559 }
2560
2561
2562 /************************************************************
2563 * NetUserGetLocalGroups (NETAPI32.@)
2564 */
2565 NET_API_STATUS
2566 WINAPI
2567 NetUserGetLocalGroups(LPCWSTR servername,
2568 LPCWSTR username,
2569 DWORD level,
2570 DWORD flags,
2571 LPBYTE* bufptr,
2572 DWORD prefmaxlen,
2573 LPDWORD entriesread,
2574 LPDWORD totalentries)
2575 {
2576 UNICODE_STRING ServerName;
2577 UNICODE_STRING UserName;
2578 SAM_HANDLE ServerHandle = NULL;
2579 SAM_HANDLE BuiltinDomainHandle = NULL;
2580 SAM_HANDLE AccountDomainHandle = NULL;
2581 PSID AccountDomainSid = NULL;
2582 PSID UserSid = NULL;
2583 PULONG RelativeIds = NULL;
2584 PSID_NAME_USE Use = NULL;
2585 ULONG BuiltinMemberCount = 0;
2586 ULONG AccountMemberCount = 0;
2587 PULONG BuiltinAliases = NULL;
2588 PULONG AccountAliases = NULL;
2589 PUNICODE_STRING BuiltinNames = NULL;
2590 PUNICODE_STRING AccountNames = NULL;
2591 PLOCALGROUP_USERS_INFO_0 Buffer = NULL;
2592 ULONG Size;
2593 ULONG Count = 0;
2594 ULONG Index;
2595 ULONG i;
2596 LPWSTR StrPtr;
2597 NET_API_STATUS ApiStatus = NERR_Success;
2598 NTSTATUS Status = STATUS_SUCCESS;
2599
2600 TRACE("(%s, %s, %d, %08x, %p %d, %p, %p) stub!\n",
2601 debugstr_w(servername), debugstr_w(username), level, flags, bufptr,
2602 prefmaxlen, entriesread, totalentries);
2603
2604 if (level != 0)
2605 return ERROR_INVALID_LEVEL;
2606
2607 if (flags & ~LG_INCLUDE_INDIRECT)
2608 return ERROR_INVALID_PARAMETER;
2609
2610 if (flags & LG_INCLUDE_INDIRECT)
2611 {
2612 WARN("The flag LG_INCLUDE_INDIRECT is not supported yet!\n");
2613 }
2614
2615 if (servername != NULL)
2616 RtlInitUnicodeString(&ServerName, servername);
2617
2618 RtlInitUnicodeString(&UserName, username);
2619
2620 /* Connect to the SAM Server */
2621 Status = SamConnect((servername != NULL) ? &ServerName : NULL,
2622 &ServerHandle,
2623 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
2624 NULL);
2625 if (!NT_SUCCESS(Status))
2626 {
2627 ERR("SamConnect failed (Status %08lx)\n", Status);
2628 ApiStatus = NetpNtStatusToApiStatus(Status);
2629 goto done;
2630 }
2631
2632 /* Open the Builtin Domain */
2633 Status = OpenBuiltinDomain(ServerHandle,
2634 DOMAIN_LOOKUP | DOMAIN_GET_ALIAS_MEMBERSHIP,
2635 &BuiltinDomainHandle);
2636 if (!NT_SUCCESS(Status))
2637 {
2638 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status);
2639 ApiStatus = NetpNtStatusToApiStatus(Status);
2640 goto done;
2641 }
2642
2643 /* Get the Account Domain SID */
2644 Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL,
2645 &AccountDomainSid);
2646 if (!NT_SUCCESS(Status))
2647 {
2648 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
2649 ApiStatus = NetpNtStatusToApiStatus(Status);
2650 goto done;
2651 }
2652
2653 /* Open the Account Domain */
2654 Status = SamOpenDomain(ServerHandle,
2655 DOMAIN_LOOKUP | DOMAIN_GET_ALIAS_MEMBERSHIP,
2656 AccountDomainSid,
2657 &AccountDomainHandle);
2658 if (!NT_SUCCESS(Status))
2659 {
2660 ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
2661 ApiStatus = NetpNtStatusToApiStatus(Status);
2662 goto done;
2663 }
2664
2665 /* Get the RID for the given user name */
2666 Status = SamLookupNamesInDomain(AccountDomainHandle,
2667 1,
2668 &UserName,
2669 &RelativeIds,
2670 &Use);
2671 if (!NT_SUCCESS(Status))
2672 {
2673 ERR("SamLookupNamesInDomain failed (Status %08lx)\n", Status);
2674 ApiStatus = NetpNtStatusToApiStatus(Status);
2675 goto done;
2676 }
2677
2678 /* Fail, if it is not a user account */
2679 if (Use[0] != SidTypeUser)
2680 {
2681 ERR("Account is not a User!\n");
2682 ApiStatus = NERR_UserNotFound;
2683 goto done;
2684 }
2685
2686 /* Build the User SID from the Account Domain SID and the users RID */
2687 ApiStatus = BuildSidFromSidAndRid(AccountDomainSid,
2688 RelativeIds[0],
2689 &UserSid);
2690 if (ApiStatus != NERR_Success)
2691 {
2692 ERR("BuildSidFromSidAndRid failed!\n");
2693 goto done;
2694 }
2695
2696 /* Get alias memberships in the Builtin Domain */
2697 Status = SamGetAliasMembership(BuiltinDomainHandle,
2698 1,
2699 &UserSid,
2700 &BuiltinMemberCount,
2701 &BuiltinAliases);
2702 if (!NT_SUCCESS(Status))
2703 {
2704 ERR("SamGetAliasMembership failed (Status %08lx)\n", Status);
2705 ApiStatus = NetpNtStatusToApiStatus(Status);
2706 goto done;
2707 }
2708
2709 if (BuiltinMemberCount > 0)
2710 {
2711 /* Get the Names of the builtin alias members */
2712 Status = SamLookupIdsInDomain(BuiltinDomainHandle,
2713 BuiltinMemberCount,
2714 BuiltinAliases,
2715 &BuiltinNames,
2716 NULL);
2717 if (!NT_SUCCESS(Status))
2718 {
2719 ERR("SamLookupIdsInDomain failed (Status %08lx)\n", Status);
2720 ApiStatus = NetpNtStatusToApiStatus(Status);
2721 goto done;
2722 }
2723 }
2724
2725 /* Get alias memberships in the Account Domain */
2726 Status = SamGetAliasMembership(AccountDomainHandle,
2727 1,
2728 &UserSid,
2729 &AccountMemberCount,
2730 &AccountAliases);
2731 if (!NT_SUCCESS(Status))
2732 {
2733 ERR("SamGetAliasMembership failed (Status %08lx)\n", Status);
2734 ApiStatus = NetpNtStatusToApiStatus(Status);
2735 goto done;
2736 }
2737
2738 if (AccountMemberCount > 0)
2739 {
2740 /* Get the Names of the builtin alias members */
2741 Status = SamLookupIdsInDomain(AccountDomainHandle,
2742 AccountMemberCount,
2743 AccountAliases,
2744 &AccountNames,
2745 NULL);
2746 if (!NT_SUCCESS(Status))
2747 {
2748 ERR("SamLookupIdsInDomain failed (Status %08lx)\n", Status);
2749 ApiStatus = NetpNtStatusToApiStatus(Status);
2750 goto done;
2751 }
2752 }
2753
2754 /* Calculate the required buffer size */
2755 Size = 0;
2756
2757 for (i = 0; i < BuiltinMemberCount; i++)
2758 {
2759 if (BuiltinNames[i].Length > 0)
2760 {
2761 Size += (sizeof(LOCALGROUP_USERS_INFO_0) + BuiltinNames[i].Length + sizeof(UNICODE_NULL));
2762 Count++;
2763 }
2764 }
2765
2766 for (i = 0; i < AccountMemberCount; i++)
2767 {
2768 if (BuiltinNames[i].Length > 0)
2769 {
2770 Size += (sizeof(LOCALGROUP_USERS_INFO_0) + AccountNames[i].Length + sizeof(UNICODE_NULL));
2771 Count++;
2772 }
2773 }
2774
2775 if (Size == 0)
2776 {
2777 ApiStatus = NERR_Success;
2778 goto done;
2779 }
2780
2781 /* Allocate buffer */
2782 ApiStatus = NetApiBufferAllocate(Size, (LPVOID*)&Buffer);
2783 if (ApiStatus != NERR_Success)
2784 goto done;
2785
2786 ZeroMemory(Buffer, Size);
2787
2788 StrPtr = (LPWSTR)((INT_PTR)Buffer + Count * sizeof(LOCALGROUP_USERS_INFO_0));
2789
2790 /* Copy data to the allocated buffer */
2791 Index = 0;
2792 for (i = 0; i < BuiltinMemberCount; i++)
2793 {
2794 if (BuiltinNames[i].Length > 0)
2795 {
2796 CopyMemory(StrPtr,
2797 BuiltinNames[i].Buffer,
2798 BuiltinNames[i].Length);
2799 Buffer[Index].lgrui0_name = StrPtr;
2800
2801 StrPtr = (LPWSTR)((INT_PTR)StrPtr + BuiltinNames[i].Length + sizeof(UNICODE_NULL));
2802 Index++;
2803 }
2804 }
2805
2806 for (i = 0; i < AccountMemberCount; i++)
2807 {
2808 if (AccountNames[i].Length > 0)
2809 {
2810 CopyMemory(StrPtr,
2811 AccountNames[i].Buffer,
2812 AccountNames[i].Length);
2813 Buffer[Index].lgrui0_name = StrPtr;
2814
2815 StrPtr = (LPWSTR)((INT_PTR)StrPtr + AccountNames[i].Length + sizeof(UNICODE_NULL));
2816 Index++;
2817 }
2818 }
2819
2820 done:
2821 if (AccountNames != NULL)
2822 SamFreeMemory(AccountNames);
2823
2824 if (BuiltinNames != NULL)
2825 SamFreeMemory(BuiltinNames);
2826
2827 if (AccountAliases != NULL)
2828 SamFreeMemory(AccountAliases);
2829
2830 if (BuiltinAliases != NULL)
2831 SamFreeMemory(BuiltinAliases);
2832
2833 if (RelativeIds != NULL)
2834 SamFreeMemory(RelativeIds);
2835
2836 if (Use != NULL)
2837 SamFreeMemory(Use);
2838
2839 if (UserSid != NULL)
2840 NetApiBufferFree(UserSid);
2841
2842 if (AccountDomainSid != NULL)
2843 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);
2844
2845 if (AccountDomainHandle != NULL)
2846 SamCloseHandle(AccountDomainHandle);
2847
2848 if (BuiltinDomainHandle != NULL)
2849 SamCloseHandle(BuiltinDomainHandle);
2850
2851 if (ServerHandle != NULL)
2852 SamCloseHandle(ServerHandle);
2853
2854 if (ApiStatus != NERR_Success && ApiStatus != ERROR_MORE_DATA)
2855 {
2856 *entriesread = 0;
2857 *totalentries = 0;
2858 }
2859 else
2860 {
2861 *entriesread = Count;
2862 *totalentries = Count;
2863 }
2864
2865 *bufptr = (LPBYTE)Buffer;
2866
2867 return ApiStatus;
2868 }
2869
2870
2871 /******************************************************************************
2872 * NetUserSetGroups (NETAPI32.@)
2873 */
2874 NET_API_STATUS
2875 WINAPI
2876 NetUserSetGroups(LPCWSTR servername,
2877 LPCWSTR username,
2878 DWORD level,
2879 LPBYTE buf,
2880 DWORD num_entries)
2881 {
2882 FIXME("(%s %s %lu %p %lu)\n",
2883 debugstr_w(servername), debugstr_w(username), level, buf, num_entries);
2884 return ERROR_ACCESS_DENIED;
2885 }
2886
2887
2888 /******************************************************************************
2889 * NetUserSetInfo (NETAPI32.@)
2890 */
2891 NET_API_STATUS
2892 WINAPI
2893 NetUserSetInfo(LPCWSTR servername,
2894 LPCWSTR username,
2895 DWORD level,
2896 LPBYTE buf,
2897 LPDWORD parm_err)
2898 {
2899 UNICODE_STRING ServerName;
2900 UNICODE_STRING UserName;
2901 SAM_HANDLE ServerHandle = NULL;
2902 SAM_HANDLE AccountDomainHandle = NULL;
2903 SAM_HANDLE UserHandle = NULL;
2904 NET_API_STATUS ApiStatus = NERR_Success;
2905 NTSTATUS Status = STATUS_SUCCESS;
2906
2907 TRACE("(%s %s %lu %p %p)\n",
2908 debugstr_w(servername), debugstr_w(username), level, buf, parm_err);
2909
2910 if (parm_err != NULL)
2911 *parm_err = PARM_ERROR_NONE;
2912
2913 /* Check the info level */
2914 switch (level)
2915 {
2916 case 0:
2917 case 1:
2918 case 2:
2919 case 3:
2920 // case 4:
2921 // case 21:
2922 // case 22:
2923 case 1003:
2924 // case 1005:
2925 case 1006:
2926 case 1007:
2927 case 1008:
2928 case 1009:
2929 // case 1010:
2930 case 1011:
2931 case 1012:
2932 case 1013:
2933 case 1014:
2934 // case 1017:
2935 // case 1018:
2936 // case 1020:
2937 case 1024:
2938 case 1025:
2939 case 1051:
2940 case 1052:
2941 case 1053:
2942 break;
2943
2944 default:
2945 return ERROR_INVALID_LEVEL;
2946 }
2947
2948 if (servername != NULL)
2949 RtlInitUnicodeString(&ServerName, servername);
2950
2951 RtlInitUnicodeString(&UserName, username);
2952
2953 /* Connect to the SAM Server */
2954 Status = SamConnect((servername != NULL) ? &ServerName : NULL,
2955 &ServerHandle,
2956 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
2957 NULL);
2958 if (!NT_SUCCESS(Status))
2959 {
2960 ERR("SamConnect failed (Status %08lx)\n", Status);
2961 ApiStatus = NetpNtStatusToApiStatus(Status);
2962 goto done;
2963 }
2964
2965 /* Open the Account Domain */
2966 Status = OpenAccountDomain(ServerHandle,
2967 (servername != NULL) ? &ServerName : NULL,
2968 DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
2969 &AccountDomainHandle);
2970 if (!NT_SUCCESS(Status))
2971 {
2972 ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
2973 ApiStatus = NetpNtStatusToApiStatus(Status);
2974 goto done;
2975 }
2976
2977 /* Open the User Account */
2978 ApiStatus = OpenUserByName(AccountDomainHandle,
2979 &UserName,
2980 USER_ALL_ACCESS,
2981 &UserHandle);
2982 if (ApiStatus != NERR_Success)
2983 {
2984 ERR("OpenUserByName failed (ApiStatus %lu)\n", ApiStatus);
2985 goto done;
2986 }
2987
2988 /* Set user information */
2989 ApiStatus = SetUserInfo(UserHandle,
2990 buf,
2991 level);
2992 if (ApiStatus != NERR_Success)
2993 {
2994 ERR("SetUserInfo failed (Status %lu)\n", ApiStatus);
2995 }
2996
2997 done:
2998 if (UserHandle != NULL)
2999 SamCloseHandle(UserHandle);
3000
3001 if (AccountDomainHandle != NULL)
3002 SamCloseHandle(AccountDomainHandle);
3003
3004 if (ServerHandle != NULL)
3005 SamCloseHandle(ServerHandle);
3006
3007 return ApiStatus;
3008 }
3009
3010 /* EOF */