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