2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS net command
7 * PROGRAMMERS: Eric Kohl
15 CompareInfo(const void *a
,
18 return _wcsicmp(((PUSER_INFO_0
)a
)->usri0_name
,
19 ((PUSER_INFO_0
)b
)->usri0_name
);
27 PUSER_INFO_0 pBuffer
= NULL
;
28 PSERVER_INFO_100 pServer
= NULL
;
29 DWORD dwRead
= 0, dwTotal
= 0;
31 DWORD_PTR ResumeHandle
= 0;
32 NET_API_STATUS Status
;
34 Status
= NetServerGetInfo(NULL
,
37 if (Status
!= NERR_Success
)
40 PrintToConsole(L
"\n");
41 PrintResourceString(IDS_USER_ACCOUNTS
, pServer
->sv100_name
);
42 PrintToConsole(L
"\n\n");
43 PrintPadding(L
'-', 79);
44 PrintToConsole(L
"\n");
46 NetApiBufferFree(pServer
);
48 Status
= NetUserEnum(NULL
,
56 if (Status
!= NERR_Success
)
64 // printf("dwRead: %lu dwTotal: %lu\n", dwRead, dwTotal);
65 for (i
= 0; i
< dwRead
; i
++)
67 // printf("%p\n", pBuffer[i].lgrpi0_name);
68 if (pBuffer
[i
].usri0_name
)
69 PrintToConsole(L
"%s\n", pBuffer
[i
].usri0_name
);
72 NetApiBufferFree(pBuffer
);
80 PrintDateTime(DWORD dwSeconds
)
84 SYSTEMTIME SystemTime
;
88 RtlSecondsSince1970ToTime(dwSeconds
, &Time
);
89 FileTime
.dwLowDateTime
= Time
.u
.LowPart
;
90 FileTime
.dwHighDateTime
= Time
.u
.HighPart
;
91 FileTimeToLocalFileTime(&FileTime
, &FileTime
);
92 FileTimeToSystemTime(&FileTime
, &SystemTime
);
94 GetDateFormatW(LOCALE_USER_DEFAULT
,
101 GetTimeFormatW(LOCALE_USER_DEFAULT
,
108 PrintToConsole(L
"%s %s", DateBuffer
, TimeBuffer
);
114 GetTimeInSeconds(VOID
)
120 GetSystemTimeAsFileTime(&FileTime
);
121 Time
.u
.LowPart
= FileTime
.dwLowDateTime
;
122 Time
.u
.HighPart
= FileTime
.dwHighDateTime
;
123 RtlTimeToSecondsSince1970(&Time
, &dwSeconds
);
131 DisplayUser(LPWSTR lpUserName
)
133 PUSER_MODALS_INFO_0 pUserModals
= NULL
;
134 PUSER_INFO_4 pUserInfo
= NULL
;
135 PLOCALGROUP_USERS_INFO_0 pLocalGroupInfo
= NULL
;
136 PGROUP_USERS_INFO_0 pGroupInfo
= NULL
;
137 DWORD dwLocalGroupRead
, dwLocalGroupTotal
;
138 DWORD dwGroupRead
, dwGroupTotal
;
141 INT nPaddedLength
= 29;
142 NET_API_STATUS Status
;
144 /* Modify the user */
145 Status
= NetUserGetInfo(NULL
,
148 (LPBYTE
*)&pUserInfo
);
149 if (Status
!= NERR_Success
)
152 Status
= NetUserModalsGet(NULL
,
154 (LPBYTE
*)&pUserModals
);
155 if (Status
!= NERR_Success
)
158 Status
= NetUserGetLocalGroups(NULL
,
162 (LPBYTE
*)&pLocalGroupInfo
,
163 MAX_PREFERRED_LENGTH
,
166 if (Status
!= NERR_Success
)
169 Status
= NetUserGetGroups(NULL
,
172 (LPBYTE
*)&pGroupInfo
,
173 MAX_PREFERRED_LENGTH
,
176 if (Status
!= NERR_Success
)
179 PrintPaddedResourceString(IDS_USER_NAME
, nPaddedLength
);
180 PrintToConsole(L
"%s\n", pUserInfo
->usri4_name
);
182 PrintPaddedResourceString(IDS_USER_FULL_NAME
, nPaddedLength
);
183 PrintToConsole(L
"%s\n", pUserInfo
->usri4_full_name
);
185 PrintPaddedResourceString(IDS_USER_COMMENT
, nPaddedLength
);
186 PrintToConsole(L
"%s\n", pUserInfo
->usri4_comment
);
188 PrintPaddedResourceString(IDS_USER_USER_COMMENT
, nPaddedLength
);
189 PrintToConsole(L
"%s\n", pUserInfo
->usri4_usr_comment
);
191 PrintPaddedResourceString(IDS_USER_COUNTRY_CODE
, nPaddedLength
);
192 PrintToConsole(L
"%03ld ()\n", pUserInfo
->usri4_country_code
);
194 PrintPaddedResourceString(IDS_USER_ACCOUNT_ACTIVE
, nPaddedLength
);
195 if (pUserInfo
->usri4_flags
& UF_ACCOUNTDISABLE
)
196 PrintResourceString(IDS_GENERIC_NO
);
197 else if (pUserInfo
->usri4_flags
& UF_LOCKOUT
)
198 PrintResourceString(IDS_GENERIC_LOCKED
);
200 PrintResourceString(IDS_GENERIC_YES
);
201 PrintToConsole(L
"\n");
203 PrintPaddedResourceString(IDS_USER_ACCOUNT_EXPIRES
, nPaddedLength
);
204 if (pUserInfo
->usri4_acct_expires
== TIMEQ_FOREVER
)
205 PrintResourceString(IDS_GENERIC_NEVER
);
207 PrintDateTime(pUserInfo
->usri4_acct_expires
);
208 PrintToConsole(L
"\n\n");
210 PrintPaddedResourceString(IDS_USER_PW_LAST_SET
, nPaddedLength
);
211 dwLastSet
= GetTimeInSeconds() - pUserInfo
->usri4_password_age
;
212 PrintDateTime(dwLastSet
);
214 PrintPaddedResourceString(IDS_USER_PW_EXPIRES
, nPaddedLength
);
215 if ((pUserInfo
->usri4_flags
& UF_DONT_EXPIRE_PASSWD
) || pUserModals
->usrmod0_max_passwd_age
== TIMEQ_FOREVER
)
216 PrintResourceString(IDS_GENERIC_NEVER
);
218 PrintDateTime(dwLastSet
+ pUserModals
->usrmod0_max_passwd_age
);
219 PrintToConsole(L
"\n");
221 PrintPaddedResourceString(IDS_USER_PW_CHANGEABLE
, nPaddedLength
);
222 PrintDateTime(dwLastSet
+ pUserModals
->usrmod0_min_passwd_age
);
224 PrintPaddedResourceString(IDS_USER_PW_REQUIRED
, nPaddedLength
);
225 PrintResourceString((pUserInfo
->usri4_flags
& UF_PASSWD_NOTREQD
) ? IDS_GENERIC_NO
: IDS_GENERIC_YES
);
226 PrintToConsole(L
"\n");
228 PrintPaddedResourceString(IDS_USER_CHANGE_PW
, nPaddedLength
);
229 PrintResourceString((pUserInfo
->usri4_flags
& UF_PASSWD_CANT_CHANGE
) ? IDS_GENERIC_NO
: IDS_GENERIC_YES
);
230 PrintToConsole(L
"\n\n");
232 PrintPaddedResourceString(IDS_USER_WORKSTATIONS
, nPaddedLength
);
233 if (pUserInfo
->usri4_workstations
== NULL
|| wcslen(pUserInfo
->usri4_workstations
) == 0)
234 PrintResourceString(IDS_GENERIC_ALL
);
236 PrintToConsole(L
"%s", pUserInfo
->usri4_workstations
);
237 PrintToConsole(L
"\n");
239 PrintPaddedResourceString(IDS_USER_LOGON_SCRIPT
, nPaddedLength
);
240 PrintToConsole(L
"%s\n", pUserInfo
->usri4_script_path
);
242 PrintPaddedResourceString(IDS_USER_PROFILE
, nPaddedLength
);
243 PrintToConsole(L
"%s\n", pUserInfo
->usri4_profile
);
245 PrintPaddedResourceString(IDS_USER_HOME_DIR
, nPaddedLength
);
246 PrintToConsole(L
"%s\n", pUserInfo
->usri4_home_dir
);
248 PrintPaddedResourceString(IDS_USER_LAST_LOGON
, nPaddedLength
);
249 if (pUserInfo
->usri4_last_logon
== 0)
250 PrintResourceString(IDS_GENERIC_NEVER
);
252 PrintDateTime(pUserInfo
->usri4_last_logon
);
253 PrintToConsole(L
"\n\n");
255 PrintPaddedResourceString(IDS_USER_LOGON_HOURS
, nPaddedLength
);
256 if (pUserInfo
->usri4_logon_hours
== NULL
)
257 PrintResourceString(IDS_GENERIC_ALL
);
258 PrintToConsole(L
"\n\n");
260 PrintToConsole(L
"\n");
261 PrintPaddedResourceString(IDS_USER_LOCAL_GROUPS
, nPaddedLength
);
262 if (dwLocalGroupTotal
!= 0 && pLocalGroupInfo
!= NULL
)
264 for (i
= 0; i
< dwLocalGroupTotal
; i
++)
267 PrintPadding(L
' ', nPaddedLength
);
268 PrintToConsole(L
"*%s\n", pLocalGroupInfo
[i
].lgrui0_name
);
273 PrintToConsole(L
"\n");
276 PrintPaddedResourceString(IDS_USER_GLOBAL_GROUPS
, nPaddedLength
);
277 if (dwGroupTotal
!= 0 && pGroupInfo
!= NULL
)
279 for (i
= 0; i
< dwGroupTotal
; i
++)
282 PrintPadding(L
' ', nPaddedLength
);
283 PrintToConsole(L
"*%s\n", pGroupInfo
[i
].grui0_name
);
288 PrintToConsole(L
"\n");
292 if (pGroupInfo
!= NULL
)
293 NetApiBufferFree(pGroupInfo
);
295 if (pLocalGroupInfo
!= NULL
)
296 NetApiBufferFree(pLocalGroupInfo
);
298 if (pUserModals
!= NULL
)
299 NetApiBufferFree(pUserModals
);
301 if (pUserInfo
!= NULL
)
302 NetApiBufferFree(pUserInfo
);
314 WCHAR szPassword1
[PWLEN
+ 1];
315 WCHAR szPassword2
[PWLEN
+ 1];
318 *lpAllocated
= FALSE
;
322 PrintResourceString(IDS_USER_ENTER_PASSWORD1
);
323 ReadFromConsole(szPassword1
, PWLEN
+ 1, FALSE
);
324 PrintToConsole(L
"\n");
326 PrintResourceString(IDS_USER_ENTER_PASSWORD2
);
327 ReadFromConsole(szPassword2
, PWLEN
+ 1, FALSE
);
328 PrintToConsole(L
"\n");
330 if (wcslen(szPassword1
) == wcslen(szPassword2
) &&
331 wcscmp(szPassword1
, szPassword2
) == 0)
333 ptr
= HeapAlloc(GetProcessHeap(),
335 (wcslen(szPassword1
) + 1) * sizeof(WCHAR
));
338 wcscpy(ptr
, szPassword1
);
346 PrintToConsole(L
"\n");
347 PrintResourceString(IDS_USER_NO_PASSWORD_MATCH
);
348 PrintToConsole(L
"\n");
363 BOOL bDelete
= FALSE
;
365 BOOL bDomain
= FALSE
;
367 LPWSTR lpUserName
= NULL
;
368 LPWSTR lpPassword
= NULL
;
369 PUSER_INFO_4 pUserInfo
= NULL
;
370 USER_INFO_4 UserInfo
;
374 BOOL bPasswordAllocated
= FALSE
;
375 NET_API_STATUS Status
;
379 Status
= EnumerateUsers();
380 printf("Status: %lu\n", Status
);
385 Status
= DisplayUser(argv
[2]);
386 printf("Status: %lu\n", Status
);
391 if (argv
[i
][0] != L
'/')
393 lpUserName
= argv
[i
];
394 // printf("User: %S\n", lpUserName);
398 if (argv
[i
][0] != L
'/')
400 lpPassword
= argv
[i
];
401 // printf("Password: %S\n", lpPassword);
405 for (j
= i
; j
< argc
; j
++)
407 if (_wcsicmp(argv
[j
], L
"/help") == 0)
409 PrintResourceString(IDS_USER_HELP
);
412 else if (_wcsicmp(argv
[j
], L
"/add") == 0)
416 else if (_wcsicmp(argv
[j
], L
"/delete") == 0)
420 else if (_wcsicmp(argv
[j
], L
"/domain") == 0)
422 PrintResourceString(IDS_ERROR_OPTION_NOT_SUPPORTED
, L
"/DOMAIN");
435 /* Interactive password input */
436 if (lpPassword
!= NULL
&& wcscmp(lpPassword
, L
"*") == 0)
438 ReadPassword(&lpPassword
,
439 &bPasswordAllocated
);
442 if (!bAdd
&& !bDelete
)
444 /* Modify the user */
445 Status
= NetUserGetInfo(NULL
,
448 (LPBYTE
*)&pUserInfo
);
449 if (Status
!= NERR_Success
)
451 printf("Status: %lu\n", Status
);
456 else if (bAdd
&& !bDelete
)
459 ZeroMemory(&UserInfo
, sizeof(USER_INFO_4
));
461 UserInfo
.usri4_name
= lpUserName
;
462 UserInfo
.usri4_password
= lpPassword
;
463 UserInfo
.usri4_flags
= UF_SCRIPT
| UF_NORMAL_ACCOUNT
;
465 pUserInfo
= &UserInfo
;
468 for (j
= i
; j
< argc
; j
++)
470 if (_wcsnicmp(argv
[j
], L
"/active:", 8) == 0)
473 if (_wcsicmp(p
, L
"yes") == 0)
475 pUserInfo
->usri4_flags
&= ~UF_ACCOUNTDISABLE
;
477 else if (_wcsicmp(p
, L
"no") == 0)
479 pUserInfo
->usri4_flags
|= UF_ACCOUNTDISABLE
;
483 PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE
, L
"/ACTIVE");
488 else if (_wcsnicmp(argv
[j
], L
"/comment:", 9) == 0)
490 pUserInfo
->usri4_comment
= &argv
[j
][9];
492 else if (_wcsnicmp(argv
[j
], L
"/countrycode:", 13) == 0)
495 value
= wcstoul(p
, &endptr
, 10);
498 PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE
, L
"/COUNTRYCODE");
503 /* FIXME: verify the country code */
505 pUserInfo
->usri4_country_code
= value
;
507 else if (_wcsnicmp(argv
[j
], L
"/expires:", 9) == 0)
510 if (_wcsicmp(p
, L
"never") == 0)
512 pUserInfo
->usri4_acct_expires
= TIMEQ_FOREVER
;
516 /* FIXME: Parse the date */
517 PrintResourceString(IDS_ERROR_OPTION_NOT_SUPPORTED
, L
"/EXPIRES");
520 else if (_wcsnicmp(argv
[j
], L
"/fullname:", 10) == 0)
522 pUserInfo
->usri4_full_name
= &argv
[j
][10];
524 else if (_wcsnicmp(argv
[j
], L
"/homedir:", 9) == 0)
526 pUserInfo
->usri4_home_dir
= &argv
[j
][9];
528 else if (_wcsnicmp(argv
[j
], L
"/passwordchg:", 13) == 0)
531 if (_wcsicmp(p
, L
"yes") == 0)
533 pUserInfo
->usri4_flags
&= ~UF_PASSWD_CANT_CHANGE
;
535 else if (_wcsicmp(p
, L
"no") == 0)
537 pUserInfo
->usri4_flags
|= UF_PASSWD_CANT_CHANGE
;
541 PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE
, L
"/PASSWORDCHG");
546 else if (_wcsnicmp(argv
[j
], L
"/passwordreq:", 13) == 0)
549 if (_wcsicmp(p
, L
"yes") == 0)
551 pUserInfo
->usri4_flags
&= ~UF_PASSWD_NOTREQD
;
553 else if (_wcsicmp(p
, L
"no") == 0)
555 pUserInfo
->usri4_flags
|= UF_PASSWD_NOTREQD
;
559 PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE
, L
"/PASSWORDREQ");
564 else if (_wcsnicmp(argv
[j
], L
"/profilepath:", 13) == 0)
566 pUserInfo
->usri4_profile
= &argv
[j
][13];
568 else if (_wcsnicmp(argv
[j
], L
"/scriptpath:", 12) == 0)
570 pUserInfo
->usri4_script_path
= &argv
[j
][12];
572 else if (_wcsnicmp(argv
[j
], L
"/times:", 7) == 0)
575 PrintResourceString(IDS_ERROR_OPTION_NOT_SUPPORTED
, L
"/TIMES");
577 else if (_wcsnicmp(argv
[j
], L
"/usercomment:", 13) == 0)
579 pUserInfo
->usri4_usr_comment
= &argv
[j
][13];
581 else if (_wcsnicmp(argv
[j
], L
"/workstations:", 14) == 0)
584 PrintResourceString(IDS_ERROR_OPTION_NOT_SUPPORTED
, L
"/WORKSTATIONS");
588 if (!bAdd
&& !bDelete
)
590 /* Modify the user */
591 Status
= NetUserSetInfo(NULL
,
596 printf("Status: %lu\n", Status
);
598 else if (bAdd
&& !bDelete
)
601 Status
= NetUserAdd(NULL
,
605 printf("Status: %lu\n", Status
);
607 else if (!bAdd
&& bDelete
)
609 /* Delete the user */
610 Status
= NetUserDel(NULL
,
612 printf("Status: %lu\n", Status
);
616 if (bPasswordAllocated
== TRUE
&& lpPassword
!= NULL
)
617 HeapFree(GetProcessHeap(), 0, lpPassword
);
619 if (!bAdd
&& !bDelete
&& pUserInfo
!= NULL
)
620 NetApiBufferFree(pUserInfo
);
623 PrintResourceString(IDS_USER_SYNTAX
);