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
"\nUser accounts for \\\\%s\n\n", pServer
->sv100_name
);
42 NetApiBufferFree(pServer
);
44 PrintToConsole(L
"------------------------------------------\n");
46 Status
= NetUserEnum(NULL
,
54 if (Status
!= NERR_Success
)
62 // printf("dwRead: %lu dwTotal: %lu\n", dwRead, dwTotal);
63 for (i
= 0; i
< dwRead
; i
++)
65 // printf("%p\n", pBuffer[i].lgrpi0_name);
66 if (pBuffer
[i
].usri0_name
)
67 PrintToConsole(L
"%s\n", pBuffer
[i
].usri0_name
);
70 NetApiBufferFree(pBuffer
);
78 PrintDateTime(DWORD dwSeconds
)
82 SYSTEMTIME SystemTime
;
86 RtlSecondsSince1970ToTime(dwSeconds
, &Time
);
87 FileTime
.dwLowDateTime
= Time
.u
.LowPart
;
88 FileTime
.dwHighDateTime
= Time
.u
.HighPart
;
89 FileTimeToLocalFileTime(&FileTime
, &FileTime
);
90 FileTimeToSystemTime(&FileTime
, &SystemTime
);
92 GetDateFormatW(LOCALE_USER_DEFAULT
,
99 GetTimeFormatW(LOCALE_USER_DEFAULT
,
106 PrintToConsole(L
"%s %s\n", DateBuffer
, TimeBuffer
);
112 GetTimeInSeconds(VOID
)
118 GetSystemTimeAsFileTime(&FileTime
);
119 Time
.u
.LowPart
= FileTime
.dwLowDateTime
;
120 Time
.u
.HighPart
= FileTime
.dwHighDateTime
;
121 RtlTimeToSecondsSince1970(&Time
, &dwSeconds
);
129 DisplayUser(LPWSTR lpUserName
)
131 PUSER_MODALS_INFO_0 pUserModals
= NULL
;
132 PUSER_INFO_4 pUserInfo
= NULL
;
133 PLOCALGROUP_USERS_INFO_0 pLocalGroupInfo
= NULL
;
134 PGROUP_USERS_INFO_0 pGroupInfo
= NULL
;
135 DWORD dwLocalGroupRead
, dwLocalGroupTotal
;
136 DWORD dwGroupRead
, dwGroupTotal
;
139 NET_API_STATUS Status
;
141 /* Modify the user */
142 Status
= NetUserGetInfo(NULL
,
145 (LPBYTE
*)&pUserInfo
);
146 if (Status
!= NERR_Success
)
149 Status
= NetUserModalsGet(NULL
,
151 (LPBYTE
*)&pUserModals
);
152 if (Status
!= NERR_Success
)
155 Status
= NetUserGetLocalGroups(NULL
,
159 (LPBYTE
*)&pLocalGroupInfo
,
160 MAX_PREFERRED_LENGTH
,
163 if (Status
!= NERR_Success
)
166 Status
= NetUserGetGroups(NULL
,
169 (LPBYTE
*)&pGroupInfo
,
170 MAX_PREFERRED_LENGTH
,
173 if (Status
!= NERR_Success
)
176 PrintPaddedResourceString(IDS_USER_NAME
);
177 PrintToConsole(L
"%s\n", pUserInfo
->usri4_name
);
179 PrintPaddedResourceString(IDS_USER_FULL_NAME
);
180 PrintToConsole(L
"%s\n", pUserInfo
->usri4_full_name
);
182 PrintPaddedResourceString(IDS_USER_COMMENT
);
183 PrintToConsole(L
"%s\n", pUserInfo
->usri4_comment
);
185 PrintPaddedResourceString(IDS_USER_USER_COMMENT
);
186 PrintToConsole(L
"%s\n", pUserInfo
->usri4_usr_comment
);
188 PrintPaddedResourceString(IDS_USER_COUNTRY_CODE
);
189 PrintToConsole(L
"%03ld ()\n", pUserInfo
->usri4_country_code
);
191 PrintPaddedResourceString(IDS_USER_ACCOUNT_ACTIVE
);
192 PrintToConsole(L
"%s\n", (pUserInfo
->usri4_flags
& UF_ACCOUNTDISABLE
)? L
"No" : ((pUserInfo
->usri4_flags
& UF_LOCKOUT
) ? L
"Locked" : L
"Yes"));
194 PrintPaddedResourceString(IDS_USER_ACCOUNT_EXPIRES
);
195 if (pUserInfo
->usri4_acct_expires
== TIMEQ_FOREVER
)
196 PrintToConsole(L
"Never\n");
198 PrintDateTime(pUserInfo
->usri4_acct_expires
);
200 PrintToConsole(L
"\n");
202 PrintPaddedResourceString(IDS_USER_PW_LAST_SET
);
203 dwLastSet
= GetTimeInSeconds() - pUserInfo
->usri4_password_age
;
204 PrintDateTime(dwLastSet
);
206 PrintPaddedResourceString(IDS_USER_PW_EXPIRES
);
207 if ((pUserInfo
->usri4_flags
& UF_DONT_EXPIRE_PASSWD
) || pUserModals
->usrmod0_max_passwd_age
== TIMEQ_FOREVER
)
208 PrintToConsole(L
"Never\n");
210 PrintDateTime(dwLastSet
+ pUserModals
->usrmod0_max_passwd_age
);
212 PrintPaddedResourceString(IDS_USER_PW_CHANGEABLE
);
213 PrintDateTime(dwLastSet
+ pUserModals
->usrmod0_min_passwd_age
);
215 PrintPaddedResourceString(IDS_USER_PW_REQUIRED
);
216 PrintToConsole(L
"%s\n", (pUserInfo
->usri4_flags
& UF_PASSWD_NOTREQD
) ? L
"No" : L
"Yes");
218 PrintPaddedResourceString(IDS_USER_CHANGE_PW
);
219 PrintToConsole(L
"%s\n", (pUserInfo
->usri4_flags
& UF_PASSWD_CANT_CHANGE
) ? L
"No" : L
"Yes");
221 PrintToConsole(L
"\n");
223 PrintPaddedResourceString(IDS_USER_WORKSTATIONS
);
224 PrintToConsole(L
"%s\n", (pUserInfo
->usri4_workstations
== NULL
|| wcslen(pUserInfo
->usri4_workstations
) == 0) ? L
"All" : pUserInfo
->usri4_workstations
);
226 PrintPaddedResourceString(IDS_USER_LOGON_SCRIPT
);
227 PrintToConsole(L
"%s\n", pUserInfo
->usri4_script_path
);
229 PrintPaddedResourceString(IDS_USER_PROFILE
);
230 PrintToConsole(L
"%s\n", pUserInfo
->usri4_profile
);
232 PrintPaddedResourceString(IDS_USER_HOME_DIR
);
233 PrintToConsole(L
"%s\n", pUserInfo
->usri4_home_dir
);
235 PrintPaddedResourceString(IDS_USER_LAST_LOGON
);
236 if (pUserInfo
->usri4_last_logon
== 0)
237 PrintToConsole(L
"Never\n");
239 PrintDateTime(pUserInfo
->usri4_last_logon
);
241 PrintToConsole(L
"\n");
243 PrintPaddedResourceString(IDS_USER_LOGON_HOURS
);
244 if (pUserInfo
->usri4_logon_hours
== NULL
)
245 PrintToConsole(L
"All\n");
247 PrintToConsole(L
"\n");
249 PrintToConsole(L
"\n");
250 PrintPaddedResourceString(IDS_USER_LOCAL_GROUPS
);
251 if (dwLocalGroupTotal
!= 0 && pLocalGroupInfo
!= NULL
)
253 for (i
= 0; i
< dwLocalGroupTotal
; i
++)
256 PrintToConsole(L
" ");
257 PrintToConsole(L
"*%s\n", pLocalGroupInfo
[i
].lgrui0_name
);
262 PrintToConsole(L
"\n");
265 PrintPaddedResourceString(IDS_USER_GLOBAL_GROUPS
);
266 if (dwGroupTotal
!= 0 && pGroupInfo
!= NULL
)
268 for (i
= 0; i
< dwGroupTotal
; i
++)
271 PrintToConsole(L
" ");
272 PrintToConsole(L
"*%s\n", pGroupInfo
[i
].grui0_name
);
277 PrintToConsole(L
"\n");
281 if (pGroupInfo
!= NULL
)
282 NetApiBufferFree(pGroupInfo
);
284 if (pLocalGroupInfo
!= NULL
)
285 NetApiBufferFree(pLocalGroupInfo
);
287 if (pUserModals
!= NULL
)
288 NetApiBufferFree(pUserModals
);
290 if (pUserInfo
!= NULL
)
291 NetApiBufferFree(pUserInfo
);
303 WCHAR szPassword1
[PWLEN
+ 1];
304 WCHAR szPassword2
[PWLEN
+ 1];
307 *lpAllocated
= FALSE
;
311 PrintResourceString(IDS_USER_ENTER_PASSWORD1
);
312 ReadFromConsole(szPassword1
, PWLEN
+ 1, FALSE
);
315 PrintResourceString(IDS_USER_ENTER_PASSWORD2
);
316 ReadFromConsole(szPassword2
, PWLEN
+ 1, FALSE
);
319 if (wcslen(szPassword1
) == wcslen(szPassword2
) &&
320 wcscmp(szPassword1
, szPassword2
) == 0)
322 ptr
= HeapAlloc(GetProcessHeap(),
324 (wcslen(szPassword1
) + 1) * sizeof(WCHAR
));
327 wcscpy(ptr
, szPassword1
);
335 PrintResourceString(IDS_USER_NO_PASSWORD_MATCH
);
350 BOOL bDelete
= FALSE
;
352 BOOL bDomain
= FALSE
;
354 LPWSTR lpUserName
= NULL
;
355 LPWSTR lpPassword
= NULL
;
356 PUSER_INFO_4 pUserInfo
= NULL
;
357 USER_INFO_4 UserInfo
;
361 BOOL bPasswordAllocated
= FALSE
;
362 NET_API_STATUS Status
;
366 Status
= EnumerateUsers();
367 printf("Status: %lu\n", Status
);
372 Status
= DisplayUser(argv
[2]);
373 printf("Status: %lu\n", Status
);
378 if (argv
[i
][0] != L
'/')
380 lpUserName
= argv
[i
];
381 // printf("User: %S\n", lpUserName);
385 if (argv
[i
][0] != L
'/')
387 lpPassword
= argv
[i
];
388 // printf("Password: %S\n", lpPassword);
392 for (j
= i
; j
< argc
; j
++)
394 if (_wcsicmp(argv
[j
], L
"/help") == 0)
396 PrintResourceString(IDS_USER_HELP
);
399 else if (_wcsicmp(argv
[j
], L
"/add") == 0)
403 else if (_wcsicmp(argv
[j
], L
"/delete") == 0)
407 else if (_wcsicmp(argv
[j
], L
"/domain") == 0)
409 PrintResourceString(IDS_ERROR_OPTION_NOT_SUPPORTED
, L
"/DOMAIN");
422 /* Interactive password input */
423 if (lpPassword
!= NULL
&& wcscmp(lpPassword
, L
"*") == 0)
425 ReadPassword(&lpPassword
,
426 &bPasswordAllocated
);
429 if (!bAdd
&& !bDelete
)
431 /* Modify the user */
432 Status
= NetUserGetInfo(NULL
,
435 (LPBYTE
*)&pUserInfo
);
436 if (Status
!= NERR_Success
)
438 printf("Status: %lu\n", Status
);
443 else if (bAdd
&& !bDelete
)
446 ZeroMemory(&UserInfo
, sizeof(USER_INFO_4
));
448 UserInfo
.usri4_name
= lpUserName
;
449 UserInfo
.usri4_password
= lpPassword
;
450 UserInfo
.usri4_flags
= UF_SCRIPT
| UF_NORMAL_ACCOUNT
;
452 pUserInfo
= &UserInfo
;
455 for (j
= i
; j
< argc
; j
++)
457 if (_wcsnicmp(argv
[j
], L
"/active:", 8) == 0)
460 if (_wcsicmp(p
, L
"yes") == 0)
462 pUserInfo
->usri4_flags
&= ~UF_ACCOUNTDISABLE
;
464 else if (_wcsicmp(p
, L
"no") == 0)
466 pUserInfo
->usri4_flags
|= UF_ACCOUNTDISABLE
;
470 PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE
, L
"/ACTIVE");
475 else if (_wcsnicmp(argv
[j
], L
"/comment:", 9) == 0)
477 pUserInfo
->usri4_comment
= &argv
[j
][9];
479 else if (_wcsnicmp(argv
[j
], L
"/countrycode:", 13) == 0)
482 value
= wcstoul(p
, &endptr
, 10);
485 PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE
, L
"/COUNTRYCODE");
490 /* FIXME: verify the country code */
492 pUserInfo
->usri4_country_code
= value
;
494 else if (_wcsnicmp(argv
[j
], L
"/expires:", 9) == 0)
497 if (_wcsicmp(p
, L
"never") == 0)
499 pUserInfo
->usri4_acct_expires
= TIMEQ_FOREVER
;
503 /* FIXME: Parse the date */
504 PrintResourceString(IDS_ERROR_OPTION_NOT_SUPPORTED
, L
"/EXPIRES");
507 else if (_wcsnicmp(argv
[j
], L
"/fullname:", 10) == 0)
509 pUserInfo
->usri4_full_name
= &argv
[j
][10];
511 else if (_wcsnicmp(argv
[j
], L
"/homedir:", 9) == 0)
513 pUserInfo
->usri4_home_dir
= &argv
[j
][9];
515 else if (_wcsnicmp(argv
[j
], L
"/passwordchg:", 13) == 0)
518 if (_wcsicmp(p
, L
"yes") == 0)
520 pUserInfo
->usri4_flags
&= ~UF_PASSWD_CANT_CHANGE
;
522 else if (_wcsicmp(p
, L
"no") == 0)
524 pUserInfo
->usri4_flags
|= UF_PASSWD_CANT_CHANGE
;
528 PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE
, L
"/PASSWORDCHG");
533 else if (_wcsnicmp(argv
[j
], L
"/passwordreq:", 13) == 0)
536 if (_wcsicmp(p
, L
"yes") == 0)
538 pUserInfo
->usri4_flags
&= ~UF_PASSWD_NOTREQD
;
540 else if (_wcsicmp(p
, L
"no") == 0)
542 pUserInfo
->usri4_flags
|= UF_PASSWD_NOTREQD
;
546 PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE
, L
"/PASSWORDREQ");
551 else if (_wcsnicmp(argv
[j
], L
"/profilepath:", 13) == 0)
553 pUserInfo
->usri4_profile
= &argv
[j
][13];
555 else if (_wcsnicmp(argv
[j
], L
"/scriptpath:", 12) == 0)
557 pUserInfo
->usri4_script_path
= &argv
[j
][12];
559 else if (_wcsnicmp(argv
[j
], L
"/times:", 7) == 0)
562 PrintResourceString(IDS_ERROR_OPTION_NOT_SUPPORTED
, L
"/TIMES");
564 else if (_wcsnicmp(argv
[j
], L
"/usercomment:", 13) == 0)
566 pUserInfo
->usri4_usr_comment
= &argv
[j
][13];
568 else if (_wcsnicmp(argv
[j
], L
"/workstations:", 14) == 0)
571 PrintResourceString(IDS_ERROR_OPTION_NOT_SUPPORTED
, L
"/WORKSTATIONS");
575 if (!bAdd
&& !bDelete
)
577 /* Modify the user */
578 Status
= NetUserSetInfo(NULL
,
583 printf("Status: %lu\n", Status
);
585 else if (bAdd
&& !bDelete
)
588 Status
= NetUserAdd(NULL
,
592 printf("Status: %lu\n", Status
);
594 else if (!bAdd
&& bDelete
)
596 /* Delete the user */
597 Status
= NetUserDel(NULL
,
599 printf("Status: %lu\n", Status
);
603 if (bPasswordAllocated
== TRUE
&& lpPassword
!= NULL
)
604 HeapFree(GetProcessHeap(), 0, lpPassword
);
606 if (!bAdd
&& !bDelete
&& pUserInfo
!= NULL
)
607 NetApiBufferFree(pUserInfo
);
610 PrintResourceString(IDS_USER_SYNTAX
);