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