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 PrintToConsole(L
"------------------------------------------\n");
45 NetApiBufferFree(pServer
);
47 Status
= NetUserEnum(NULL
,
55 if (Status
!= NERR_Success
)
63 // printf("dwRead: %lu dwTotal: %lu\n", dwRead, dwTotal);
64 for (i
= 0; i
< dwRead
; i
++)
66 // printf("%p\n", pBuffer[i].lgrpi0_name);
67 if (pBuffer
[i
].usri0_name
)
68 PrintToConsole(L
"%s\n", pBuffer
[i
].usri0_name
);
71 NetApiBufferFree(pBuffer
);
79 PrintDateTime(DWORD dwSeconds
)
83 SYSTEMTIME SystemTime
;
87 RtlSecondsSince1970ToTime(dwSeconds
, &Time
);
88 FileTime
.dwLowDateTime
= Time
.u
.LowPart
;
89 FileTime
.dwHighDateTime
= Time
.u
.HighPart
;
90 FileTimeToLocalFileTime(&FileTime
, &FileTime
);
91 FileTimeToSystemTime(&FileTime
, &SystemTime
);
93 GetDateFormatW(LOCALE_USER_DEFAULT
,
100 GetTimeFormatW(LOCALE_USER_DEFAULT
,
107 PrintToConsole(L
"%s %s", DateBuffer
, TimeBuffer
);
113 GetTimeInSeconds(VOID
)
119 GetSystemTimeAsFileTime(&FileTime
);
120 Time
.u
.LowPart
= FileTime
.dwLowDateTime
;
121 Time
.u
.HighPart
= FileTime
.dwHighDateTime
;
122 RtlTimeToSecondsSince1970(&Time
, &dwSeconds
);
130 DisplayUser(LPWSTR lpUserName
)
132 PUSER_MODALS_INFO_0 pUserModals
= NULL
;
133 PUSER_INFO_4 pUserInfo
= NULL
;
134 PLOCALGROUP_USERS_INFO_0 pLocalGroupInfo
= NULL
;
135 PGROUP_USERS_INFO_0 pGroupInfo
= NULL
;
136 DWORD dwLocalGroupRead
, dwLocalGroupTotal
;
137 DWORD dwGroupRead
, dwGroupTotal
;
140 INT nPaddedLength
= 29;
141 NET_API_STATUS Status
;
143 /* Modify the user */
144 Status
= NetUserGetInfo(NULL
,
147 (LPBYTE
*)&pUserInfo
);
148 if (Status
!= NERR_Success
)
151 Status
= NetUserModalsGet(NULL
,
153 (LPBYTE
*)&pUserModals
);
154 if (Status
!= NERR_Success
)
157 Status
= NetUserGetLocalGroups(NULL
,
161 (LPBYTE
*)&pLocalGroupInfo
,
162 MAX_PREFERRED_LENGTH
,
165 if (Status
!= NERR_Success
)
168 Status
= NetUserGetGroups(NULL
,
171 (LPBYTE
*)&pGroupInfo
,
172 MAX_PREFERRED_LENGTH
,
175 if (Status
!= NERR_Success
)
178 PrintPaddedResourceString(IDS_USER_NAME
, nPaddedLength
);
179 PrintToConsole(L
"%s\n", pUserInfo
->usri4_name
);
181 PrintPaddedResourceString(IDS_USER_FULL_NAME
, nPaddedLength
);
182 PrintToConsole(L
"%s\n", pUserInfo
->usri4_full_name
);
184 PrintPaddedResourceString(IDS_USER_COMMENT
, nPaddedLength
);
185 PrintToConsole(L
"%s\n", pUserInfo
->usri4_comment
);
187 PrintPaddedResourceString(IDS_USER_USER_COMMENT
, nPaddedLength
);
188 PrintToConsole(L
"%s\n", pUserInfo
->usri4_usr_comment
);
190 PrintPaddedResourceString(IDS_USER_COUNTRY_CODE
, nPaddedLength
);
191 PrintToConsole(L
"%03ld ()\n", pUserInfo
->usri4_country_code
);
193 PrintPaddedResourceString(IDS_USER_ACCOUNT_ACTIVE
, nPaddedLength
);
194 if (pUserInfo
->usri4_flags
& UF_ACCOUNTDISABLE
)
195 PrintResourceString(IDS_GENERIC_NO
);
196 else if (pUserInfo
->usri4_flags
& UF_LOCKOUT
)
197 PrintResourceString(IDS_GENERIC_LOCKED
);
199 PrintResourceString(IDS_GENERIC_YES
);
200 PrintToConsole(L
"\n");
202 PrintPaddedResourceString(IDS_USER_ACCOUNT_EXPIRES
, nPaddedLength
);
203 if (pUserInfo
->usri4_acct_expires
== TIMEQ_FOREVER
)
204 PrintResourceString(IDS_GENERIC_NEVER
);
206 PrintDateTime(pUserInfo
->usri4_acct_expires
);
207 PrintToConsole(L
"\n\n");
209 PrintPaddedResourceString(IDS_USER_PW_LAST_SET
, nPaddedLength
);
210 dwLastSet
= GetTimeInSeconds() - pUserInfo
->usri4_password_age
;
211 PrintDateTime(dwLastSet
);
213 PrintPaddedResourceString(IDS_USER_PW_EXPIRES
, nPaddedLength
);
214 if ((pUserInfo
->usri4_flags
& UF_DONT_EXPIRE_PASSWD
) || pUserModals
->usrmod0_max_passwd_age
== TIMEQ_FOREVER
)
215 PrintResourceString(IDS_GENERIC_NEVER
);
217 PrintDateTime(dwLastSet
+ pUserModals
->usrmod0_max_passwd_age
);
218 PrintToConsole(L
"\n");
220 PrintPaddedResourceString(IDS_USER_PW_CHANGEABLE
, nPaddedLength
);
221 PrintDateTime(dwLastSet
+ pUserModals
->usrmod0_min_passwd_age
);
223 PrintPaddedResourceString(IDS_USER_PW_REQUIRED
, nPaddedLength
);
224 PrintResourceString((pUserInfo
->usri4_flags
& UF_PASSWD_NOTREQD
) ? IDS_GENERIC_NO
: IDS_GENERIC_YES
);
225 PrintToConsole(L
"\n");
227 PrintPaddedResourceString(IDS_USER_CHANGE_PW
, nPaddedLength
);
228 PrintResourceString((pUserInfo
->usri4_flags
& UF_PASSWD_CANT_CHANGE
) ? IDS_GENERIC_NO
: IDS_GENERIC_YES
);
229 PrintToConsole(L
"\n\n");
231 PrintPaddedResourceString(IDS_USER_WORKSTATIONS
, nPaddedLength
);
232 if (pUserInfo
->usri4_workstations
== NULL
|| wcslen(pUserInfo
->usri4_workstations
) == 0)
233 PrintResourceString(IDS_GENERIC_ALL
);
235 PrintToConsole(L
"%s", pUserInfo
->usri4_workstations
);
236 PrintToConsole(L
"\n");
238 PrintPaddedResourceString(IDS_USER_LOGON_SCRIPT
, nPaddedLength
);
239 PrintToConsole(L
"%s\n", pUserInfo
->usri4_script_path
);
241 PrintPaddedResourceString(IDS_USER_PROFILE
, nPaddedLength
);
242 PrintToConsole(L
"%s\n", pUserInfo
->usri4_profile
);
244 PrintPaddedResourceString(IDS_USER_HOME_DIR
, nPaddedLength
);
245 PrintToConsole(L
"%s\n", pUserInfo
->usri4_home_dir
);
247 PrintPaddedResourceString(IDS_USER_LAST_LOGON
, nPaddedLength
);
248 if (pUserInfo
->usri4_last_logon
== 0)
249 PrintResourceString(IDS_GENERIC_NEVER
);
251 PrintDateTime(pUserInfo
->usri4_last_logon
);
252 PrintToConsole(L
"\n\n");
254 PrintPaddedResourceString(IDS_USER_LOGON_HOURS
, nPaddedLength
);
255 if (pUserInfo
->usri4_logon_hours
== NULL
)
256 PrintResourceString(IDS_GENERIC_ALL
);
257 PrintToConsole(L
"\n\n");
259 PrintToConsole(L
"\n");
260 PrintPaddedResourceString(IDS_USER_LOCAL_GROUPS
, nPaddedLength
);
261 if (dwLocalGroupTotal
!= 0 && pLocalGroupInfo
!= NULL
)
263 for (i
= 0; i
< dwLocalGroupTotal
; i
++)
266 PrintToConsole(L
" ");
267 PrintToConsole(L
"*%s\n", pLocalGroupInfo
[i
].lgrui0_name
);
272 PrintToConsole(L
"\n");
275 PrintPaddedResourceString(IDS_USER_GLOBAL_GROUPS
, nPaddedLength
);
276 if (dwGroupTotal
!= 0 && pGroupInfo
!= NULL
)
278 for (i
= 0; i
< dwGroupTotal
; i
++)
281 PrintToConsole(L
" ");
282 PrintToConsole(L
"*%s\n", pGroupInfo
[i
].grui0_name
);
287 PrintToConsole(L
"\n");
291 if (pGroupInfo
!= NULL
)
292 NetApiBufferFree(pGroupInfo
);
294 if (pLocalGroupInfo
!= NULL
)
295 NetApiBufferFree(pLocalGroupInfo
);
297 if (pUserModals
!= NULL
)
298 NetApiBufferFree(pUserModals
);
300 if (pUserInfo
!= NULL
)
301 NetApiBufferFree(pUserInfo
);
313 WCHAR szPassword1
[PWLEN
+ 1];
314 WCHAR szPassword2
[PWLEN
+ 1];
317 *lpAllocated
= FALSE
;
321 PrintResourceString(IDS_USER_ENTER_PASSWORD1
);
322 ReadFromConsole(szPassword1
, PWLEN
+ 1, FALSE
);
323 PrintToConsole(L
"\n");
325 PrintResourceString(IDS_USER_ENTER_PASSWORD2
);
326 ReadFromConsole(szPassword2
, PWLEN
+ 1, FALSE
);
327 PrintToConsole(L
"\n");
329 if (wcslen(szPassword1
) == wcslen(szPassword2
) &&
330 wcscmp(szPassword1
, szPassword2
) == 0)
332 ptr
= HeapAlloc(GetProcessHeap(),
334 (wcslen(szPassword1
) + 1) * sizeof(WCHAR
));
337 wcscpy(ptr
, szPassword1
);
345 PrintToConsole(L
"\n");
346 PrintResourceString(IDS_USER_NO_PASSWORD_MATCH
);
347 PrintToConsole(L
"\n");
362 BOOL bDelete
= FALSE
;
364 BOOL bDomain
= FALSE
;
366 LPWSTR lpUserName
= NULL
;
367 LPWSTR lpPassword
= NULL
;
368 PUSER_INFO_4 pUserInfo
= NULL
;
369 USER_INFO_4 UserInfo
;
373 BOOL bPasswordAllocated
= FALSE
;
374 NET_API_STATUS Status
;
378 Status
= EnumerateUsers();
379 printf("Status: %lu\n", Status
);
384 Status
= DisplayUser(argv
[2]);
385 printf("Status: %lu\n", Status
);
390 if (argv
[i
][0] != L
'/')
392 lpUserName
= argv
[i
];
393 // printf("User: %S\n", lpUserName);
397 if (argv
[i
][0] != L
'/')
399 lpPassword
= argv
[i
];
400 // printf("Password: %S\n", lpPassword);
404 for (j
= i
; j
< argc
; j
++)
406 if (_wcsicmp(argv
[j
], L
"/help") == 0)
408 PrintResourceString(IDS_USER_HELP
);
411 else if (_wcsicmp(argv
[j
], L
"/add") == 0)
415 else if (_wcsicmp(argv
[j
], L
"/delete") == 0)
419 else if (_wcsicmp(argv
[j
], L
"/domain") == 0)
421 PrintResourceString(IDS_ERROR_OPTION_NOT_SUPPORTED
, L
"/DOMAIN");
434 /* Interactive password input */
435 if (lpPassword
!= NULL
&& wcscmp(lpPassword
, L
"*") == 0)
437 ReadPassword(&lpPassword
,
438 &bPasswordAllocated
);
441 if (!bAdd
&& !bDelete
)
443 /* Modify the user */
444 Status
= NetUserGetInfo(NULL
,
447 (LPBYTE
*)&pUserInfo
);
448 if (Status
!= NERR_Success
)
450 printf("Status: %lu\n", Status
);
455 else if (bAdd
&& !bDelete
)
458 ZeroMemory(&UserInfo
, sizeof(USER_INFO_4
));
460 UserInfo
.usri4_name
= lpUserName
;
461 UserInfo
.usri4_password
= lpPassword
;
462 UserInfo
.usri4_flags
= UF_SCRIPT
| UF_NORMAL_ACCOUNT
;
464 pUserInfo
= &UserInfo
;
467 for (j
= i
; j
< argc
; j
++)
469 if (_wcsnicmp(argv
[j
], L
"/active:", 8) == 0)
472 if (_wcsicmp(p
, L
"yes") == 0)
474 pUserInfo
->usri4_flags
&= ~UF_ACCOUNTDISABLE
;
476 else if (_wcsicmp(p
, L
"no") == 0)
478 pUserInfo
->usri4_flags
|= UF_ACCOUNTDISABLE
;
482 PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE
, L
"/ACTIVE");
487 else if (_wcsnicmp(argv
[j
], L
"/comment:", 9) == 0)
489 pUserInfo
->usri4_comment
= &argv
[j
][9];
491 else if (_wcsnicmp(argv
[j
], L
"/countrycode:", 13) == 0)
494 value
= wcstoul(p
, &endptr
, 10);
497 PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE
, L
"/COUNTRYCODE");
502 /* FIXME: verify the country code */
504 pUserInfo
->usri4_country_code
= value
;
506 else if (_wcsnicmp(argv
[j
], L
"/expires:", 9) == 0)
509 if (_wcsicmp(p
, L
"never") == 0)
511 pUserInfo
->usri4_acct_expires
= TIMEQ_FOREVER
;
515 /* FIXME: Parse the date */
516 PrintResourceString(IDS_ERROR_OPTION_NOT_SUPPORTED
, L
"/EXPIRES");
519 else if (_wcsnicmp(argv
[j
], L
"/fullname:", 10) == 0)
521 pUserInfo
->usri4_full_name
= &argv
[j
][10];
523 else if (_wcsnicmp(argv
[j
], L
"/homedir:", 9) == 0)
525 pUserInfo
->usri4_home_dir
= &argv
[j
][9];
527 else if (_wcsnicmp(argv
[j
], L
"/passwordchg:", 13) == 0)
530 if (_wcsicmp(p
, L
"yes") == 0)
532 pUserInfo
->usri4_flags
&= ~UF_PASSWD_CANT_CHANGE
;
534 else if (_wcsicmp(p
, L
"no") == 0)
536 pUserInfo
->usri4_flags
|= UF_PASSWD_CANT_CHANGE
;
540 PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE
, L
"/PASSWORDCHG");
545 else if (_wcsnicmp(argv
[j
], L
"/passwordreq:", 13) == 0)
548 if (_wcsicmp(p
, L
"yes") == 0)
550 pUserInfo
->usri4_flags
&= ~UF_PASSWD_NOTREQD
;
552 else if (_wcsicmp(p
, L
"no") == 0)
554 pUserInfo
->usri4_flags
|= UF_PASSWD_NOTREQD
;
558 PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE
, L
"/PASSWORDREQ");
563 else if (_wcsnicmp(argv
[j
], L
"/profilepath:", 13) == 0)
565 pUserInfo
->usri4_profile
= &argv
[j
][13];
567 else if (_wcsnicmp(argv
[j
], L
"/scriptpath:", 12) == 0)
569 pUserInfo
->usri4_script_path
= &argv
[j
][12];
571 else if (_wcsnicmp(argv
[j
], L
"/times:", 7) == 0)
574 PrintResourceString(IDS_ERROR_OPTION_NOT_SUPPORTED
, L
"/TIMES");
576 else if (_wcsnicmp(argv
[j
], L
"/usercomment:", 13) == 0)
578 pUserInfo
->usri4_usr_comment
= &argv
[j
][13];
580 else if (_wcsnicmp(argv
[j
], L
"/workstations:", 14) == 0)
583 PrintResourceString(IDS_ERROR_OPTION_NOT_SUPPORTED
, L
"/WORKSTATIONS");
587 if (!bAdd
&& !bDelete
)
589 /* Modify the user */
590 Status
= NetUserSetInfo(NULL
,
595 printf("Status: %lu\n", Status
);
597 else if (bAdd
&& !bDelete
)
600 Status
= NetUserAdd(NULL
,
604 printf("Status: %lu\n", Status
);
606 else if (!bAdd
&& bDelete
)
608 /* Delete the user */
609 Status
= NetUserDel(NULL
,
611 printf("Status: %lu\n", Status
);
615 if (bPasswordAllocated
== TRUE
&& lpPassword
!= NULL
)
616 HeapFree(GetProcessHeap(), 0, lpPassword
);
618 if (!bAdd
&& !bDelete
&& pUserInfo
!= NULL
)
619 NetApiBufferFree(pUserInfo
);
622 PrintResourceString(IDS_USER_SYNTAX
);