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