[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 expires ");
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"Workstation allowed %s\n", 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 printf("Status: %lu\n", Status);
292 }
293 else if (bAdd && !bDelete)
294 {
295 /* Add the user */
296 ZeroMemory(&UserInfo, sizeof(USER_INFO_4));
297
298 UserInfo.usri4_name = lpUserName;
299 UserInfo.usri4_password = lpPassword;
300 UserInfo.usri4_flags = UF_SCRIPT | UF_NORMAL_ACCOUNT;
301
302 pUserInfo = &UserInfo;
303 }
304
305 for (j = i; j < argc; j++)
306 {
307 if (_wcsnicmp(argv[j], L"/active:", 8) == 0)
308 {
309 p = &argv[i][8];
310 if (_wcsicmp(p, L"yes") == 0)
311 {
312
313 }
314 else if (_wcsicmp(p, L"no") == 0)
315 {
316
317 }
318 else
319 {
320 PrintToConsole(L"You entered an invalid value for the /ACTIVE option.\n");
321 result = 1;
322 goto done;
323 }
324 }
325 else if (_wcsnicmp(argv[j], L"/comment:", 9) == 0)
326 {
327 pUserInfo->usri4_comment = &argv[j][9];
328 }
329 else if (_wcsnicmp(argv[j], L"/countrycode:", 13) == 0)
330 {
331 }
332 else if (_wcsnicmp(argv[j], L"/expires:", 9) == 0)
333 {
334 }
335 else if (_wcsnicmp(argv[j], L"/fullname:", 10) == 0)
336 {
337 pUserInfo->usri4_full_name = &argv[j][10];
338 }
339 else if (_wcsnicmp(argv[j], L"/homedir:", 9) == 0)
340 {
341 pUserInfo->usri4_home_dir = &argv[j][9];
342 }
343 else if (_wcsnicmp(argv[j], L"/passwordchg:", 13) == 0)
344 {
345 }
346 else if (_wcsnicmp(argv[j], L"/passwordreq:", 13) == 0)
347 {
348 }
349 else if (_wcsnicmp(argv[j], L"/profilepath:", 13) == 0)
350 {
351 pUserInfo->usri4_profile = &argv[j][13];
352 }
353 else if (_wcsnicmp(argv[j], L"/scriptpath:", 12) == 0)
354 {
355 pUserInfo->usri4_script_path = &argv[j][12];
356 }
357 else if (_wcsnicmp(argv[j], L"/times:", 7) == 0)
358 {
359 }
360 else if (_wcsnicmp(argv[j], L"/usercomment:", 13) == 0)
361 {
362 pUserInfo->usri4_usr_comment = &argv[j][13];
363 }
364 else if (_wcsnicmp(argv[j], L"/workstations:", 14) == 0)
365 {
366 }
367 }
368
369 if (!bAdd && !bDelete)
370 {
371 /* Modify the user */
372 Status = NetUserSetInfo(NULL,
373 lpUserName,
374 4,
375 (LPBYTE)pUserInfo,
376 NULL);
377 printf("Status: %lu\n", Status);
378 }
379 else if (bAdd && !bDelete)
380 {
381 /* Add the user */
382 Status = NetUserAdd(NULL,
383 4,
384 (LPBYTE)pUserInfo,
385 NULL);
386 printf("Status: %lu\n", Status);
387 }
388 else if (!bAdd && bDelete)
389 {
390 /* Delete the user */
391 Status = NetUserDel(NULL,
392 lpUserName);
393 printf("Status: %lu\n", Status);
394 }
395
396 done:
397 if (!bAdd && !bDelete && pUserInfo != NULL)
398 NetApiBufferFree(pUserInfo);
399
400 if (result != 0)
401 PrintResourceString(IDS_USER_SYNTAX);
402
403 return result;
404 }
405
406 /* EOF */