[NET]
[reactos.git] / reactos / base / applications / network / net / cmdUser.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS net command
4 * FILE:
5 * PURPOSE:
6 *
7 * PROGRAMMERS: Eric Kohl
8 */
9
10 #include "net.h"
11
12
13 static
14 int
15 CompareInfo(const void *a,
16 const void *b)
17 {
18 return _wcsicmp(((PUSER_INFO_0)a)->usri0_name,
19 ((PUSER_INFO_0)b)->usri0_name);
20 }
21
22
23 static
24 NET_API_STATUS
25 EnumerateUsers(VOID)
26 {
27 PUSER_INFO_0 pBuffer = NULL;
28 PSERVER_INFO_100 pServer = NULL;
29 DWORD dwRead = 0, dwTotal = 0;
30 DWORD i;
31 DWORD_PTR ResumeHandle = 0;
32 NET_API_STATUS Status;
33
34 Status = NetServerGetInfo(NULL,
35 100,
36 (LPBYTE*)&pServer);
37 if (Status != NERR_Success)
38 return Status;
39
40 PrintToConsole(L"\nUser accounts for \\\\%s\n\n", pServer->sv100_name);
41
42 NetApiBufferFree(pServer);
43
44 PrintToConsole(L"------------------------------------------\n");
45
46 Status = NetUserEnum(NULL,
47 0,
48 0,
49 (LPBYTE*)&pBuffer,
50 MAX_PREFERRED_LENGTH,
51 &dwRead,
52 &dwTotal,
53 &ResumeHandle);
54 if (Status != NERR_Success)
55 return Status;
56
57 qsort(pBuffer,
58 dwRead,
59 sizeof(PUSER_INFO_0),
60 CompareInfo);
61
62 // printf("dwRead: %lu dwTotal: %lu\n", dwRead, dwTotal);
63 for (i = 0; i < dwRead; i++)
64 {
65 // printf("%p\n", pBuffer[i].lgrpi0_name);
66 if (pBuffer[i].usri0_name)
67 PrintToConsole(L"%s\n", pBuffer[i].usri0_name);
68 }
69
70 NetApiBufferFree(pBuffer);
71
72 return NERR_Success;
73 }
74
75
76 static
77 VOID
78 PrintDateTime(DWORD dwSeconds)
79 {
80 LARGE_INTEGER Time;
81 FILETIME FileTime;
82 SYSTEMTIME SystemTime;
83 WCHAR DateBuffer[80];
84 WCHAR TimeBuffer[80];
85
86 RtlSecondsSince1970ToTime(dwSeconds, &Time);
87 FileTime.dwLowDateTime = Time.u.LowPart;
88 FileTime.dwHighDateTime = Time.u.HighPart;
89 FileTimeToLocalFileTime(&FileTime, &FileTime);
90 FileTimeToSystemTime(&FileTime, &SystemTime);
91
92 GetDateFormatW(LOCALE_USER_DEFAULT,
93 DATE_SHORTDATE,
94 &SystemTime,
95 NULL,
96 DateBuffer,
97 80);
98
99 GetTimeFormatW(LOCALE_USER_DEFAULT,
100 TIME_NOSECONDS,
101 &SystemTime,
102 NULL,
103 TimeBuffer,
104 80);
105
106 PrintToConsole(L"%s %s\n", DateBuffer, TimeBuffer);
107 }
108
109
110 static
111 DWORD
112 GetTimeInSeconds(VOID)
113 {
114 LARGE_INTEGER Time;
115 FILETIME FileTime;
116 DWORD dwSeconds;
117
118 GetSystemTimeAsFileTime(&FileTime);
119 Time.u.LowPart = FileTime.dwLowDateTime;
120 Time.u.HighPart = FileTime.dwHighDateTime;
121 RtlTimeToSecondsSince1970(&Time, &dwSeconds);
122
123 return dwSeconds;
124 }
125
126
127 static
128 NET_API_STATUS
129 DisplayUser(LPWSTR lpUserName)
130 {
131 PUSER_MODALS_INFO_0 pUserModals = NULL;
132 PUSER_INFO_4 pUserInfo = NULL;
133 DWORD dwLastSet;
134 NET_API_STATUS Status;
135
136 /* Modify the user */
137 Status = NetUserGetInfo(NULL,
138 lpUserName,
139 4,
140 (LPBYTE*)&pUserInfo);
141 if (Status != NERR_Success)
142 return Status;
143
144 Status = NetUserModalsGet(NULL,
145 0,
146 (LPBYTE*)&pUserModals);
147 if (Status != NERR_Success)
148 goto done;
149
150 PrintToConsole(L"User name %s\n", pUserInfo->usri4_name);
151 PrintToConsole(L"Full name %s\n", pUserInfo->usri4_full_name);
152 PrintToConsole(L"Comment %s\n", pUserInfo->usri4_comment);
153 PrintToConsole(L"User comment %s\n", pUserInfo->usri4_usr_comment);
154 PrintToConsole(L"Country code %03ld ()\n", pUserInfo->usri4_country_code);
155 PrintToConsole(L"Account active %s\n", (pUserInfo->usri4_flags & UF_ACCOUNTDISABLE)? L"No" : ((pUserInfo->usri4_flags & UF_LOCKOUT) ? L"Locked" : L"Yes"));
156 PrintToConsole(L"Account expires ");
157 if (pUserInfo->usri4_acct_expires == TIMEQ_FOREVER)
158 PrintToConsole(L"Never\n");
159 else
160 PrintDateTime(pUserInfo->usri4_acct_expires);
161
162 PrintToConsole(L"\n");
163
164 PrintToConsole(L"Password last set ");
165 dwLastSet = GetTimeInSeconds() - pUserInfo->usri4_password_age;
166 PrintDateTime(dwLastSet);
167
168 PrintToConsole(L"Password expires ");
169 if ((pUserInfo->usri4_flags & UF_DONT_EXPIRE_PASSWD) || pUserModals->usrmod0_max_passwd_age == TIMEQ_FOREVER)
170 PrintToConsole(L"Never\n");
171 else
172 PrintDateTime(dwLastSet + pUserModals->usrmod0_max_passwd_age);
173
174 PrintToConsole(L"Password changeable ");
175 PrintDateTime(dwLastSet + pUserModals->usrmod0_min_passwd_age);
176
177 PrintToConsole(L"Password required %s\n", (pUserInfo->usri4_flags & UF_PASSWD_NOTREQD) ? L"No" : L"Yes");
178 PrintToConsole(L"User may change password %s\n", (pUserInfo->usri4_flags & UF_PASSWD_CANT_CHANGE) ? L"No" : L"Yes");
179
180 PrintToConsole(L"\n");
181 PrintToConsole(L"Workstations allowed %s\n", (pUserInfo->usri4_workstations == NULL || wcslen(pUserInfo->usri4_workstations) == 0) ? L"All" : pUserInfo->usri4_workstations);
182 PrintToConsole(L"Logon script %s\n", pUserInfo->usri4_script_path);
183 PrintToConsole(L"User profile %s\n", pUserInfo->usri4_profile);
184 PrintToConsole(L"Home directory %s\n", pUserInfo->usri4_home_dir);
185 PrintToConsole(L"Last logon ");
186 if (pUserInfo->usri4_last_logon == 0)
187 PrintToConsole(L"Never\n");
188 else
189 PrintDateTime(pUserInfo->usri4_last_logon);
190 PrintToConsole(L"\n");
191 PrintToConsole(L"Logon hours allowed \n");
192 PrintToConsole(L"\n");
193 PrintToConsole(L"Local group memberships \n");
194 PrintToConsole(L"Global group memberships \n");
195
196 done:
197 if (pUserModals != NULL)
198 NetApiBufferFree(pUserModals);
199
200 if (pUserInfo != NULL)
201 NetApiBufferFree(pUserInfo);
202
203 return NERR_Success;
204 }
205
206
207 INT
208 cmdUser(
209 INT argc,
210 WCHAR **argv)
211 {
212 INT i, j;
213 INT result = 0;
214 BOOL bAdd = FALSE;
215 BOOL bDelete = FALSE;
216 #if 0
217 BOOL bDomain = FALSE;
218 #endif
219 LPWSTR lpUserName = NULL;
220 LPWSTR lpPassword = NULL;
221 PUSER_INFO_4 pUserInfo = NULL;
222 USER_INFO_4 UserInfo;
223 LPWSTR p;
224 NET_API_STATUS Status;
225
226 if (argc == 2)
227 {
228 Status = EnumerateUsers();
229 printf("Status: %lu\n", Status);
230 return 0;
231 }
232 else if (argc == 3)
233 {
234 Status = DisplayUser(argv[2]);
235 printf("Status: %lu\n", Status);
236 return 0;
237 }
238
239 i = 2;
240 if (argv[i][0] != L'/')
241 {
242 lpUserName = argv[i];
243 printf("User: %S\n", lpUserName);
244 i++;
245 }
246
247 if (argv[i][0] != L'/')
248 {
249 lpPassword = argv[i];
250 printf("Password: %S\n", lpPassword);
251 i++;
252 }
253
254 for (j = i; j < argc; j++)
255 {
256 if (_wcsicmp(argv[j], L"/help") == 0)
257 {
258 PrintResourceString(IDS_USER_HELP);
259 return 0;
260 }
261 else if (_wcsicmp(argv[j], L"/add") == 0)
262 {
263 bAdd = TRUE;
264 }
265 else if (_wcsicmp(argv[j], L"/delete") == 0)
266 {
267 bDelete = TRUE;
268 }
269 else if (_wcsicmp(argv[j], L"/domain") == 0)
270 {
271 printf("The /DOMAIN option is not supported yet!\n");
272 #if 0
273 bDomain = TRUE;
274 #endif
275 }
276 }
277
278 if (bAdd && bDelete)
279 {
280 result = 1;
281 goto done;
282 }
283
284 if (!bAdd && !bDelete)
285 {
286 /* Modify the user */
287 Status = NetUserGetInfo(NULL,
288 lpUserName,
289 4,
290 (LPBYTE*)&pUserInfo);
291 if (Status != NERR_Success)
292 {
293 printf("Status: %lu\n", Status);
294 result = 1;
295 goto done;
296 }
297 }
298 else if (bAdd && !bDelete)
299 {
300 /* Add the user */
301 ZeroMemory(&UserInfo, sizeof(USER_INFO_4));
302
303 UserInfo.usri4_name = lpUserName;
304 UserInfo.usri4_password = lpPassword;
305 UserInfo.usri4_flags = UF_SCRIPT | UF_NORMAL_ACCOUNT;
306
307 pUserInfo = &UserInfo;
308 }
309
310 for (j = i; j < argc; j++)
311 {
312 if (_wcsnicmp(argv[j], L"/active:", 8) == 0)
313 {
314 p = &argv[i][8];
315 if (_wcsicmp(p, L"yes") == 0)
316 {
317 UserInfo.usri4_flags &= ~UF_ACCOUNTDISABLE;
318 }
319 else if (_wcsicmp(p, L"no") == 0)
320 {
321 UserInfo.usri4_flags |= UF_ACCOUNTDISABLE;
322 }
323 else
324 {
325 PrintToConsole(L"You entered an invalid value for the /ACTIVE option.\n");
326 result = 1;
327 goto done;
328 }
329 }
330 else if (_wcsnicmp(argv[j], L"/comment:", 9) == 0)
331 {
332 pUserInfo->usri4_comment = &argv[j][9];
333 }
334 else if (_wcsnicmp(argv[j], L"/countrycode:", 13) == 0)
335 {
336 }
337 else if (_wcsnicmp(argv[j], L"/expires:", 9) == 0)
338 {
339 }
340 else if (_wcsnicmp(argv[j], L"/fullname:", 10) == 0)
341 {
342 pUserInfo->usri4_full_name = &argv[j][10];
343 }
344 else if (_wcsnicmp(argv[j], L"/homedir:", 9) == 0)
345 {
346 pUserInfo->usri4_home_dir = &argv[j][9];
347 }
348 else if (_wcsnicmp(argv[j], L"/passwordchg:", 13) == 0)
349 {
350 }
351 else if (_wcsnicmp(argv[j], L"/passwordreq:", 13) == 0)
352 {
353 }
354 else if (_wcsnicmp(argv[j], L"/profilepath:", 13) == 0)
355 {
356 pUserInfo->usri4_profile = &argv[j][13];
357 }
358 else if (_wcsnicmp(argv[j], L"/scriptpath:", 12) == 0)
359 {
360 pUserInfo->usri4_script_path = &argv[j][12];
361 }
362 else if (_wcsnicmp(argv[j], L"/times:", 7) == 0)
363 {
364 }
365 else if (_wcsnicmp(argv[j], L"/usercomment:", 13) == 0)
366 {
367 pUserInfo->usri4_usr_comment = &argv[j][13];
368 }
369 else if (_wcsnicmp(argv[j], L"/workstations:", 14) == 0)
370 {
371 }
372 }
373
374 if (!bAdd && !bDelete)
375 {
376 /* Modify the user */
377 Status = NetUserSetInfo(NULL,
378 lpUserName,
379 4,
380 (LPBYTE)pUserInfo,
381 NULL);
382 printf("Status: %lu\n", Status);
383 }
384 else if (bAdd && !bDelete)
385 {
386 /* Add the user */
387 Status = NetUserAdd(NULL,
388 4,
389 (LPBYTE)pUserInfo,
390 NULL);
391 printf("Status: %lu\n", Status);
392 }
393 else if (!bAdd && bDelete)
394 {
395 /* Delete the user */
396 Status = NetUserDel(NULL,
397 lpUserName);
398 printf("Status: %lu\n", Status);
399 }
400
401 done:
402 if (!bAdd && !bDelete && pUserInfo != NULL)
403 NetApiBufferFree(pUserInfo);
404
405 if (result != 0)
406 PrintResourceString(IDS_USER_SYNTAX);
407
408 return result;
409 }
410
411 /* EOF */