2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS net command
4 * FILE: base/applications/network/net/cmdUser.c
7 * PROGRAMMERS: Eric Kohl
13 #define SECONDS_PER_DAY (60 * 60 * 24)
14 #define SECONDS_PER_HOUR (60 * 60)
16 typedef struct _COUNTY_TABLE
20 } COUNTRY_TABLE
, *PCOUNTRY_TABLE
;
23 static WCHAR szPasswordChars
[] = L
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@#$%_-+:";
24 static COUNTRY_TABLE CountryTable
[] =
25 { { 0, 5080}, // System Default
26 { 1, 5081}, // United States
27 { 2, 5082}, // Canada (French)
28 { 3, 5083}, // Latin America
29 { 31, 5084}, // Netherlands
30 { 32, 5085}, // Belgium
31 { 33, 5086}, // France
34 { 41, 5088}, // Switzerland
35 { 44, 5089}, // United Kingdom
36 { 45, 5091}, // Denmark
37 { 46, 5092}, // Sweden
38 { 47, 5093}, // Norway
39 { 49, 5094}, // Germany
40 { 61, 5095}, // Australia
43 { 86, 5098}, // China (PRC)
44 { 88, 5099}, // Taiwan
46 {351, 5101}, // Portugal
47 {358, 5102}, // Finland
48 {785, 5103}, // Arabic
49 {972, 5104} }; // Hebrew
54 CompareInfo(const void *a
, const void *b
)
56 return _wcsicmp(((PUSER_INFO_0
)a
)->usri0_name
,
57 ((PUSER_INFO_0
)b
)->usri0_name
);
65 PUSER_INFO_0 pBuffer
= NULL
;
66 PSERVER_INFO_100 pServer
= NULL
;
67 DWORD dwRead
= 0, dwTotal
= 0;
69 DWORD ResumeHandle
= 0;
70 NET_API_STATUS Status
;
72 Status
= NetServerGetInfo(NULL
,
75 if (Status
!= NERR_Success
)
78 ConPuts(StdOut
, L
"\n");
79 PrintMessageStringV(4410, pServer
->sv100_name
);
80 ConPuts(StdOut
, L
"\n");
81 PrintPadding(L
'-', 79);
82 ConPuts(StdOut
, L
"\n");
84 NetApiBufferFree(pServer
);
88 Status
= NetUserEnum(NULL
,
96 if ((Status
!= NERR_Success
) && (Status
!= ERROR_MORE_DATA
))
101 sizeof(PUSER_INFO_0
),
104 for (i
= 0; i
< dwRead
; i
++)
106 if (pBuffer
[i
].usri0_name
)
107 ConPrintf(StdOut
, L
"%s\n", pBuffer
[i
].usri0_name
);
110 NetApiBufferFree(pBuffer
);
113 while (Status
== ERROR_MORE_DATA
);
121 PrintDateTime(DWORD dwSeconds
)
125 SYSTEMTIME SystemTime
;
126 WCHAR DateBuffer
[80];
127 WCHAR TimeBuffer
[80];
129 RtlSecondsSince1970ToTime(dwSeconds
, &Time
);
130 FileTime
.dwLowDateTime
= Time
.u
.LowPart
;
131 FileTime
.dwHighDateTime
= Time
.u
.HighPart
;
132 FileTimeToLocalFileTime(&FileTime
, &FileTime
);
133 FileTimeToSystemTime(&FileTime
, &SystemTime
);
135 GetDateFormatW(LOCALE_USER_DEFAULT
,
140 ARRAYSIZE(DateBuffer
));
142 GetTimeFormatW(LOCALE_USER_DEFAULT
,
147 ARRAYSIZE(TimeBuffer
));
149 ConPrintf(StdOut
, L
"%s %s", DateBuffer
, TimeBuffer
);
155 PrintLocalTime(DWORD dwSeconds
)
159 SYSTEMTIME SystemTime
;
160 WCHAR TimeBuffer
[80];
162 RtlSecondsSince1970ToTime(dwSeconds
, &Time
);
163 FileTime
.dwLowDateTime
= Time
.u
.LowPart
;
164 FileTime
.dwHighDateTime
= Time
.u
.HighPart
;
165 FileTimeToSystemTime(&FileTime
, &SystemTime
);
167 GetTimeFormatW(LOCALE_USER_DEFAULT
,
172 ARRAYSIZE(TimeBuffer
));
174 ConPrintf(StdOut
, L
"%s", TimeBuffer
);
180 GetTimeInSeconds(VOID
)
186 GetSystemTimeAsFileTime(&FileTime
);
187 Time
.u
.LowPart
= FileTime
.dwLowDateTime
;
188 Time
.u
.HighPart
= FileTime
.dwHighDateTime
;
189 RtlTimeToSecondsSince1970(&Time
, &dwSeconds
);
197 GetCountryFromCountryCode(
198 _In_ DWORD dwCountryCode
,
199 _In_ DWORD dwCountryLength
,
200 _Out_ PWSTR szCountryBuffer
)
204 for (i
= 0; i
< ARRAYSIZE(CountryTable
); i
++)
206 if (CountryTable
[i
].dwCountryCode
== dwCountryCode
)
208 if (szCountryBuffer
!= NULL
&& dwCountryLength
> 0)
210 FormatMessageW(FORMAT_MESSAGE_FROM_HMODULE
| FORMAT_MESSAGE_IGNORE_INSERTS
,
212 CountryTable
[i
].dwMessageId
,
233 DWORD dwIndex
= dwBitNumber
/ 8;
234 BYTE Mask
= 1 << (dwBitNumber
& 7);
236 return ((pLogonHours
[dwIndex
] & Mask
) != 0);
243 DWORD dwUnitsPerWeek
,
247 DWORD dwUnitsPerDay
, dwBitNumber
, dwSecondsPerUnit
;
248 DWORD dwStartTime
, dwEndTime
, dwStartDay
, dwEndDay
;
249 BOOL bBitValue
, bFirst
= TRUE
;
251 if ((dwUnitsPerWeek
== 0) ||
252 ((dwUnitsPerWeek
%7) != 0))
255 dwUnitsPerDay
= dwUnitsPerWeek
/ 7;
257 if (((dwUnitsPerDay
% 24) != 0) ||
258 ((dwUnitsPerDay
/ 24) > 6))
261 dwSecondsPerUnit
= (SECONDS_PER_DAY
) / dwUnitsPerDay
;
263 for (dwBitNumber
= 0; dwBitNumber
< dwUnitsPerWeek
; dwBitNumber
++)
265 bBitValue
= BitValue(pLogonHours
, dwBitNumber
);
268 dwStartTime
= dwSecondsPerUnit
* dwBitNumber
;
270 while (bBitValue
!= 0 && dwBitNumber
< dwUnitsPerWeek
)
273 if (dwBitNumber
< dwUnitsPerWeek
)
274 bBitValue
= BitValue(pLogonHours
, dwBitNumber
);
277 dwEndTime
= dwSecondsPerUnit
* dwBitNumber
;
280 PrintPadding(L
' ', nPaddedLength
);
282 if (dwStartTime
== 0 && dwEndTime
== (SECONDS_PER_DAY
* 7))
284 PrintMessageString(4302);
285 ConPuts(StdOut
, L
"\n");
289 dwStartDay
= dwStartTime
/ SECONDS_PER_DAY
;
290 dwEndDay
= (dwEndTime
/ SECONDS_PER_DAY
) % 7;
292 PrintMessageString(4307 + dwStartDay
);
293 ConPuts(StdOut
, L
" ");
294 PrintLocalTime((dwStartTime
% SECONDS_PER_DAY
) + SECONDS_PER_HOUR
);
296 ConPrintf(StdOut
, L
" - ");
297 if (dwStartDay
!= dwEndDay
)
299 PrintMessageString(4307 + dwEndDay
);
300 ConPuts(StdOut
, L
" ");
303 PrintLocalTime((dwEndTime
% SECONDS_PER_DAY
) + SECONDS_PER_HOUR
);
304 ConPuts(StdOut
, L
"\n");
315 DisplayUser(LPWSTR lpUserName
)
317 PUSER_MODALS_INFO_0 pUserModals
= NULL
;
318 PUSER_INFO_4 pUserInfo
= NULL
;
319 PLOCALGROUP_USERS_INFO_0 pLocalGroupInfo
= NULL
;
320 PGROUP_USERS_INFO_0 pGroupInfo
= NULL
;
321 DWORD dwLocalGroupRead
, dwLocalGroupTotal
;
322 DWORD dwGroupRead
, dwGroupTotal
;
326 INT nPaddedLength
= 36;
327 NET_API_STATUS Status
;
329 /* Modify the user */
330 Status
= NetUserGetInfo(NULL
,
333 (LPBYTE
*)&pUserInfo
);
334 if (Status
!= NERR_Success
)
337 Status
= NetUserModalsGet(NULL
,
339 (LPBYTE
*)&pUserModals
);
340 if (Status
!= NERR_Success
)
343 Status
= NetUserGetLocalGroups(NULL
,
347 (LPBYTE
*)&pLocalGroupInfo
,
348 MAX_PREFERRED_LENGTH
,
351 if (Status
!= NERR_Success
)
354 Status
= NetUserGetGroups(NULL
,
357 (LPBYTE
*)&pGroupInfo
,
358 MAX_PREFERRED_LENGTH
,
361 if (Status
!= NERR_Success
)
364 PrintPaddedMessageString(4411, nPaddedLength
);
365 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_name
);
367 PrintPaddedMessageString(4412, nPaddedLength
);
368 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_full_name
);
370 PrintPaddedMessageString(4413, nPaddedLength
);
371 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_comment
);
373 PrintPaddedMessageString(4414, nPaddedLength
);
374 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_usr_comment
);
376 PrintPaddedMessageString(4416, nPaddedLength
);
377 GetCountryFromCountryCode(pUserInfo
->usri4_country_code
,
378 ARRAYSIZE(szCountry
), szCountry
);
379 ConPrintf(StdOut
, L
"%03ld (%s)\n", pUserInfo
->usri4_country_code
, szCountry
);
381 PrintPaddedMessageString(4419, nPaddedLength
);
382 if (pUserInfo
->usri4_flags
& UF_ACCOUNTDISABLE
)
383 PrintMessageString(4301);
384 else if (pUserInfo
->usri4_flags
& UF_LOCKOUT
)
385 PrintMessageString(4440);
387 PrintMessageString(4300);
388 ConPuts(StdOut
, L
"\n");
390 PrintPaddedMessageString(4420, nPaddedLength
);
391 if (pUserInfo
->usri4_acct_expires
== TIMEQ_FOREVER
)
392 PrintMessageString(4305);
394 PrintDateTime(pUserInfo
->usri4_acct_expires
);
395 ConPuts(StdOut
, L
"\n\n");
397 PrintPaddedMessageString(4421, nPaddedLength
);
398 dwLastSet
= GetTimeInSeconds() - pUserInfo
->usri4_password_age
;
399 PrintDateTime(dwLastSet
);
400 ConPuts(StdOut
, L
"\n");
402 PrintPaddedMessageString(4422, nPaddedLength
);
403 if ((pUserInfo
->usri4_flags
& UF_DONT_EXPIRE_PASSWD
) || pUserModals
->usrmod0_max_passwd_age
== TIMEQ_FOREVER
)
404 PrintMessageString(4305);
406 PrintDateTime(dwLastSet
+ pUserModals
->usrmod0_max_passwd_age
);
407 ConPuts(StdOut
, L
"\n");
409 PrintPaddedMessageString(4423, nPaddedLength
);
410 PrintDateTime(dwLastSet
+ pUserModals
->usrmod0_min_passwd_age
);
411 ConPuts(StdOut
, L
"\n");
413 PrintPaddedMessageString(4437, nPaddedLength
);
414 PrintMessageString((pUserInfo
->usri4_flags
& UF_PASSWD_NOTREQD
) ? 4301 : 4300);
415 ConPuts(StdOut
, L
"\n");
417 PrintPaddedMessageString(4438, nPaddedLength
);
418 PrintMessageString((pUserInfo
->usri4_flags
& UF_PASSWD_CANT_CHANGE
) ? 4301 : 4300);
419 ConPuts(StdOut
, L
"\n\n");
421 PrintPaddedMessageString(4424, nPaddedLength
);
422 if (pUserInfo
->usri4_workstations
== NULL
|| wcslen(pUserInfo
->usri4_workstations
) == 0)
423 PrintMessageString(4302);
425 ConPrintf(StdOut
, L
"%s", pUserInfo
->usri4_workstations
);
426 ConPuts(StdOut
, L
"\n");
428 PrintPaddedMessageString(4429, nPaddedLength
);
429 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_script_path
);
431 PrintPaddedMessageString(4439, nPaddedLength
);
432 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_profile
);
434 PrintPaddedMessageString(4436, nPaddedLength
);
435 ConPrintf(StdOut
, L
"%s\n", pUserInfo
->usri4_home_dir
);
437 PrintPaddedMessageString(4430, nPaddedLength
);
438 if (pUserInfo
->usri4_last_logon
== 0)
439 PrintMessageString(4305);
441 PrintDateTime(pUserInfo
->usri4_last_logon
);
442 ConPuts(StdOut
, L
"\n\n");
444 PrintPaddedMessageString(4432, nPaddedLength
);
445 if (pUserInfo
->usri4_logon_hours
== NULL
)
447 PrintMessageString(4302);
448 ConPuts(StdOut
, L
"\n");
452 PrintLogonHours(pUserInfo
->usri4_units_per_week
,
453 pUserInfo
->usri4_logon_hours
,
457 ConPuts(StdOut
, L
"\n");
458 PrintPaddedMessageString(4427, nPaddedLength
);
459 if (dwLocalGroupTotal
!= 0 && pLocalGroupInfo
!= NULL
)
461 for (i
= 0; i
< dwLocalGroupTotal
; i
++)
464 PrintPadding(L
' ', nPaddedLength
);
465 ConPrintf(StdOut
, L
"*%s\n", pLocalGroupInfo
[i
].lgrui0_name
);
470 ConPuts(StdOut
, L
"\n");
473 PrintPaddedMessageString(4431, nPaddedLength
);
474 if (dwGroupTotal
!= 0 && pGroupInfo
!= NULL
)
476 for (i
= 0; i
< dwGroupTotal
; i
++)
479 PrintPadding(L
' ', nPaddedLength
);
480 ConPrintf(StdOut
, L
"*%s\n", pGroupInfo
[i
].grui0_name
);
485 ConPuts(StdOut
, L
"\n");
489 if (pGroupInfo
!= NULL
)
490 NetApiBufferFree(pGroupInfo
);
492 if (pLocalGroupInfo
!= NULL
)
493 NetApiBufferFree(pLocalGroupInfo
);
495 if (pUserModals
!= NULL
)
496 NetApiBufferFree(pUserModals
);
498 if (pUserInfo
!= NULL
)
499 NetApiBufferFree(pUserInfo
);
511 WCHAR szPassword1
[PWLEN
+ 1];
512 WCHAR szPassword2
[PWLEN
+ 1];
515 *lpAllocated
= FALSE
;
519 PrintMessageString(4358);
520 ReadFromConsole(szPassword1
, PWLEN
+ 1, FALSE
);
521 ConPuts(StdOut
, L
"\n");
523 PrintMessageString(4361);
524 ReadFromConsole(szPassword2
, PWLEN
+ 1, FALSE
);
525 ConPuts(StdOut
, L
"\n");
527 if (wcslen(szPassword1
) == wcslen(szPassword2
) &&
528 wcscmp(szPassword1
, szPassword2
) == 0)
530 ptr
= HeapAlloc(GetProcessHeap(),
532 (wcslen(szPassword1
) + 1) * sizeof(WCHAR
));
535 wcscpy(ptr
, szPassword1
);
543 ConPuts(StdOut
, L
"\n");
544 PrintMessageString(3728);
553 GenerateRandomPassword(
557 LPWSTR pPassword
= NULL
;
558 INT nCharsLen
, i
, nLength
= 8;
560 srand(GetTickCount());
562 pPassword
= HeapAlloc(GetProcessHeap(),
564 (nLength
+ 1) * sizeof(WCHAR
));
565 if (pPassword
== NULL
)
568 nCharsLen
= wcslen(szPasswordChars
);
570 for (i
= 0; i
< nLength
; i
++)
572 pPassword
[i
] = szPasswordChars
[rand() % nCharsLen
];
575 *lpPassword
= pPassword
;
582 BuildWorkstationsList(
583 _Out_ PWSTR
*pWorkstationsList
,
586 BOOL isLastSep
, isSep
;
594 /* Check for invalid characters in the raw string */
595 if (wcspbrk(pRaw
, L
"/[]=?\\+:.") != NULL
)
598 /* Count the number of workstations in the list and
599 * the required buffer size */
602 nRawLength
= wcslen(pRaw
);
603 for (i
= 0; i
< nRawLength
; i
++)
606 if (c
== L
',' || c
== L
';')
611 if ((isLastSep
== FALSE
) && (i
!= 0) && (i
!= nRawLength
- 1))
618 if (isLastSep
== TRUE
|| (isLastSep
== FALSE
&& i
== 0))
628 /* Leave, if there are no workstations in the list */
631 pWorkstationsList
= NULL
;
635 /* Fail if there are more than eight workstations in the list */
639 /* Allocate the buffer for the clean workstation list */
640 pList
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, nLength
* sizeof(WCHAR
));
642 return ERROR_NOT_ENOUGH_MEMORY
;
644 /* Build the clean workstation list */
647 nRawLength
= wcslen(pRaw
);
648 for (i
= 0, j
= 0; i
< nRawLength
; i
++)
651 if (c
== L
',' || c
== L
';')
656 if ((isLastSep
== FALSE
) && (i
!= 0) && (i
!= nRawLength
- 1))
667 if (isLastSep
== TRUE
|| (isLastSep
== FALSE
&& i
== 0))
675 *pWorkstationsList
= pList
;
690 while (iswdigit(**s
))
692 *pwValue
= *pwValue
* 10 + **s
- L
'0';
705 if (**s
== L
'/' || **s
== L
'.')
721 SYSTEMTIME SystemTime
= {0};
722 FILETIME LocalFileTime
, FileTime
;
730 GetLocaleInfoW(LOCALE_USER_DEFAULT
,
739 if (!ReadNumber(&p
, &SystemTime
.wMonth
))
741 if (!ReadSeparator(&p
))
743 if (!ReadNumber(&p
, &SystemTime
.wDay
))
745 if (!ReadSeparator(&p
))
747 if (!ReadNumber(&p
, &SystemTime
.wYear
))
752 if (!ReadNumber(&p
, &SystemTime
.wDay
))
754 if (!ReadSeparator(&p
))
756 if (!ReadNumber(&p
, &SystemTime
.wMonth
))
758 if (!ReadSeparator(&p
))
760 if (!ReadNumber(&p
, &SystemTime
.wYear
))
765 if (!ReadNumber(&p
, &SystemTime
.wYear
))
767 if (!ReadSeparator(&p
))
769 if (!ReadNumber(&p
, &SystemTime
.wMonth
))
771 if (!ReadSeparator(&p
))
773 if (!ReadNumber(&p
, &SystemTime
.wDay
))
778 /* if only entered two digits: */
779 /* assume 2000's if value less than 80 */
780 /* assume 1900's if value greater or equal 80 */
781 if (SystemTime
.wYear
<= 99)
783 if (SystemTime
.wYear
>= 80)
784 SystemTime
.wYear
+= 1900;
786 SystemTime
.wYear
+= 2000;
789 if (!SystemTimeToFileTime(&SystemTime
, &LocalFileTime
))
792 if (!LocalFileTimeToFileTime(&LocalFileTime
, &FileTime
))
795 Time
.u
.LowPart
= FileTime
.dwLowDateTime
;
796 Time
.u
.HighPart
= FileTime
.dwHighDateTime
;
798 if (!RtlTimeToSecondsSince1970(&Time
, pSeconds
))
813 BOOL bDelete
= FALSE
;
815 BOOL bDomain
= FALSE
;
817 BOOL bRandomPassword
= FALSE
;
818 LPWSTR lpUserName
= NULL
;
819 LPWSTR lpPassword
= NULL
;
820 PUSER_INFO_4 pUserInfo
= NULL
;
821 USER_INFO_4 UserInfo
;
822 LPWSTR pWorkstations
= NULL
;
826 BOOL bPasswordAllocated
= FALSE
;
827 NET_API_STATUS Status
;
830 if ((i
< argc
) && (argv
[i
][0] != L
'/'))
832 lpUserName
= argv
[i
];
833 // ConPrintf(StdOut, L"User: %s\n", lpUserName);
837 if ((i
< argc
) && (argv
[i
][0] != L
'/'))
839 lpPassword
= argv
[i
];
840 // ConPrintf(StdOut, L"Password: %s\n", lpPassword);
844 for (j
= i
; j
< argc
; j
++)
846 if (_wcsicmp(argv
[j
], L
"/help") == 0)
848 PrintNetMessage(MSG_USER_HELP
);
851 else if (_wcsicmp(argv
[j
], L
"/add") == 0)
855 else if (_wcsicmp(argv
[j
], L
"/delete") == 0)
859 else if (_wcsicmp(argv
[j
], L
"/domain") == 0)
861 ConPuts(StdErr
, L
"The /DOMAIN option is not supported yet.\n");
866 else if (_wcsicmp(argv
[j
], L
"/random") == 0)
868 bRandomPassword
= TRUE
;
869 GenerateRandomPassword(&lpPassword
,
870 &bPasswordAllocated
);
874 if (lpUserName
== NULL
&& lpPassword
== NULL
)
876 Status
= EnumerateUsers();
877 ConPrintf(StdOut
, L
"Status: %lu\n", Status
);
880 else if (lpUserName
!= NULL
&& lpPassword
== NULL
)
882 Status
= DisplayUser(lpUserName
);
883 ConPrintf(StdOut
, L
"Status: %lu\n", Status
);
893 /* Interactive password input */
894 if (lpPassword
!= NULL
&& wcscmp(lpPassword
, L
"*") == 0)
896 ReadPassword(&lpPassword
,
897 &bPasswordAllocated
);
900 if (!bAdd
&& !bDelete
)
902 /* Modify the user */
903 Status
= NetUserGetInfo(NULL
,
906 (LPBYTE
*)&pUserInfo
);
907 if (Status
!= NERR_Success
)
909 ConPrintf(StdOut
, L
"Status: %lu\n", Status
);
914 else if (bAdd
&& !bDelete
)
917 ZeroMemory(&UserInfo
, sizeof(USER_INFO_4
));
919 UserInfo
.usri4_name
= lpUserName
;
920 UserInfo
.usri4_password
= lpPassword
;
921 UserInfo
.usri4_flags
= UF_SCRIPT
| UF_NORMAL_ACCOUNT
;
922 UserInfo
.usri4_acct_expires
= TIMEQ_FOREVER
;
923 UserInfo
.usri4_primary_group_id
= DOMAIN_GROUP_RID_USERS
;
925 pUserInfo
= &UserInfo
;
928 for (j
= i
; j
< argc
; j
++)
930 if (_wcsnicmp(argv
[j
], L
"/active:", 8) == 0)
933 if (_wcsicmp(p
, L
"yes") == 0)
935 pUserInfo
->usri4_flags
&= ~UF_ACCOUNTDISABLE
;
937 else if (_wcsicmp(p
, L
"no") == 0)
939 pUserInfo
->usri4_flags
|= UF_ACCOUNTDISABLE
;
943 PrintMessageStringV(3952, L
"/ACTIVE");
948 else if (_wcsnicmp(argv
[j
], L
"/comment:", 9) == 0)
950 pUserInfo
->usri4_comment
= &argv
[j
][9];
952 else if (_wcsnicmp(argv
[j
], L
"/countrycode:", 13) == 0)
955 value
= wcstoul(p
, &endptr
, 10);
958 PrintMessageStringV(3952, L
"/COUNTRYCODE");
963 /* Verify the country code */
964 if (GetCountryFromCountryCode(value
, 0, NULL
))
965 pUserInfo
->usri4_country_code
= value
;
967 else if (_wcsnicmp(argv
[j
], L
"/expires:", 9) == 0)
970 if (_wcsicmp(p
, L
"never") == 0)
972 pUserInfo
->usri4_acct_expires
= TIMEQ_FOREVER
;
974 else if (!ParseDate(p
, &pUserInfo
->usri4_acct_expires
))
976 PrintMessageStringV(3952, L
"/EXPIRES");
981 else if (_wcsnicmp(argv
[j
], L
"/fullname:", 10) == 0)
983 pUserInfo
->usri4_full_name
= &argv
[j
][10];
985 else if (_wcsnicmp(argv
[j
], L
"/homedir:", 9) == 0)
987 pUserInfo
->usri4_home_dir
= &argv
[j
][9];
989 else if (_wcsnicmp(argv
[j
], L
"/passwordchg:", 13) == 0)
992 if (_wcsicmp(p
, L
"yes") == 0)
994 pUserInfo
->usri4_flags
&= ~UF_PASSWD_CANT_CHANGE
;
996 else if (_wcsicmp(p
, L
"no") == 0)
998 pUserInfo
->usri4_flags
|= UF_PASSWD_CANT_CHANGE
;
1002 PrintMessageStringV(3952, L
"/PASSWORDCHG");
1007 else if (_wcsnicmp(argv
[j
], L
"/passwordreq:", 13) == 0)
1010 if (_wcsicmp(p
, L
"yes") == 0)
1012 pUserInfo
->usri4_flags
&= ~UF_PASSWD_NOTREQD
;
1014 else if (_wcsicmp(p
, L
"no") == 0)
1016 pUserInfo
->usri4_flags
|= UF_PASSWD_NOTREQD
;
1020 PrintMessageStringV(3952, L
"/PASSWORDREQ");
1025 else if (_wcsnicmp(argv
[j
], L
"/profilepath:", 13) == 0)
1027 pUserInfo
->usri4_profile
= &argv
[j
][13];
1029 else if (_wcsnicmp(argv
[j
], L
"/scriptpath:", 12) == 0)
1031 pUserInfo
->usri4_script_path
= &argv
[j
][12];
1033 else if (_wcsnicmp(argv
[j
], L
"/times:", 7) == 0)
1036 ConPuts(StdErr
, L
"The /TIMES option is not supported yet.\n");
1038 else if (_wcsnicmp(argv
[j
], L
"/usercomment:", 13) == 0)
1040 pUserInfo
->usri4_usr_comment
= &argv
[j
][13];
1042 else if (_wcsnicmp(argv
[j
], L
"/workstations:", 14) == 0)
1045 if (wcscmp(p
, L
"*") == 0 || wcscmp(p
, L
"") == 0)
1047 pUserInfo
->usri4_workstations
= NULL
;
1051 Status
= BuildWorkstationsList(&pWorkstations
, p
);
1052 if (Status
== NERR_Success
)
1054 pUserInfo
->usri4_workstations
= pWorkstations
;
1058 ConPrintf(StdOut
, L
"Status %lu\n\n", Status
);
1066 if (!bAdd
&& !bDelete
)
1068 /* Modify the user */
1069 Status
= NetUserSetInfo(NULL
,
1074 ConPrintf(StdOut
, L
"Status: %lu\n", Status
);
1076 else if (bAdd
&& !bDelete
)
1079 Status
= NetUserAdd(NULL
,
1083 ConPrintf(StdOut
, L
"Status: %lu\n", Status
);
1085 else if (!bAdd
&& bDelete
)
1087 /* Delete the user */
1088 Status
= NetUserDel(NULL
,
1090 ConPrintf(StdOut
, L
"Status: %lu\n", Status
);
1093 if (Status
== NERR_Success
&&
1094 lpPassword
!= NULL
&&
1095 bRandomPassword
== TRUE
)
1097 PrintMessageStringV(3968, lpUserName
, lpPassword
);
1101 if (pWorkstations
!= NULL
)
1102 HeapFree(GetProcessHeap(), 0, pWorkstations
);
1104 if ((bPasswordAllocated
== TRUE
) && (lpPassword
!= NULL
))
1105 HeapFree(GetProcessHeap(), 0, lpPassword
);
1107 if (!bAdd
&& !bDelete
&& pUserInfo
!= NULL
)
1108 NetApiBufferFree(pUserInfo
);
1112 PrintMessageString(4381);
1113 ConPuts(StdOut
, L
"\n");
1114 PrintNetMessage(MSG_USER_SYNTAX
);