1c2c66affSColin Finck /*
2c2c66affSColin Finck * COPYRIGHT: See COPYING in the top level directory
3c2c66affSColin Finck * PROJECT: ReactOS net command
4c2c66affSColin Finck * FILE: base/applications/network/net/cmdUser.c
5c2c66affSColin Finck * PURPOSE:
6c2c66affSColin Finck *
7c2c66affSColin Finck * PROGRAMMERS: Eric Kohl
8c2c66affSColin Finck * Curtis Wilson
9c2c66affSColin Finck */
10c2c66affSColin Finck
11c2c66affSColin Finck #include "net.h"
12c2c66affSColin Finck
130ca92979SEric Kohl #define SECONDS_PER_DAY (60 * 60 * 24)
140ca92979SEric Kohl #define SECONDS_PER_HOUR (60 * 60)
15ccd95b98SEric Kohl #define HOURS_PER_DAY 24
16ccd95b98SEric Kohl #define DAYS_PER_WEEK 7
170ca92979SEric Kohl
1808d30403SEric Kohl typedef struct _COUNTY_TABLE
1908d30403SEric Kohl {
2008d30403SEric Kohl DWORD dwCountryCode;
2108d30403SEric Kohl DWORD dwMessageId;
2208d30403SEric Kohl } COUNTRY_TABLE, *PCOUNTRY_TABLE;
2308d30403SEric Kohl
2408d30403SEric Kohl
25b4969dc0SEric Kohl static WCHAR szPasswordChars[] = L"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@#$%_-+:";
2608d30403SEric Kohl static COUNTRY_TABLE CountryTable[] =
2708d30403SEric Kohl { { 0, 5080}, // System Default
2808d30403SEric Kohl { 1, 5081}, // United States
2908d30403SEric Kohl { 2, 5082}, // Canada (French)
3008d30403SEric Kohl { 3, 5083}, // Latin America
3108d30403SEric Kohl { 31, 5084}, // Netherlands
3208d30403SEric Kohl { 32, 5085}, // Belgium
3308d30403SEric Kohl { 33, 5086}, // France
3408d30403SEric Kohl { 34, 5090}, // Spain
3508d30403SEric Kohl { 39, 5087}, // Italy
3608d30403SEric Kohl { 41, 5088}, // Switzerland
3708d30403SEric Kohl { 44, 5089}, // United Kingdom
3808d30403SEric Kohl { 45, 5091}, // Denmark
3908d30403SEric Kohl { 46, 5092}, // Sweden
4008d30403SEric Kohl { 47, 5093}, // Norway
4108d30403SEric Kohl { 49, 5094}, // Germany
4208d30403SEric Kohl { 61, 5095}, // Australia
4308d30403SEric Kohl { 81, 5096}, // Japan
4408d30403SEric Kohl { 82, 5097}, // Korea
4508d30403SEric Kohl { 86, 5098}, // China (PRC)
4608d30403SEric Kohl { 88, 5099}, // Taiwan
4708d30403SEric Kohl { 99, 5100}, // Asia
4808d30403SEric Kohl {351, 5101}, // Portugal
4908d30403SEric Kohl {358, 5102}, // Finland
5008d30403SEric Kohl {785, 5103}, // Arabic
5108d30403SEric Kohl {972, 5104} }; // Hebrew
5208d30403SEric Kohl
53b4969dc0SEric Kohl
54c2c66affSColin Finck static
55c2c66affSColin Finck int
CompareInfo(const void * a,const void * b)56506bd64eSEric Kohl CompareInfo(const void *a, const void *b)
57c2c66affSColin Finck {
58c2c66affSColin Finck return _wcsicmp(((PUSER_INFO_0)a)->usri0_name,
59c2c66affSColin Finck ((PUSER_INFO_0)b)->usri0_name);
60c2c66affSColin Finck }
61c2c66affSColin Finck
62c2c66affSColin Finck
63c2c66affSColin Finck static
64c2c66affSColin Finck NET_API_STATUS
EnumerateUsers(VOID)65c2c66affSColin Finck EnumerateUsers(VOID)
66c2c66affSColin Finck {
67c2c66affSColin Finck PUSER_INFO_0 pBuffer = NULL;
68c2c66affSColin Finck PSERVER_INFO_100 pServer = NULL;
69c2c66affSColin Finck DWORD dwRead = 0, dwTotal = 0;
70c2c66affSColin Finck DWORD i;
716f130666STimo Kreuzer DWORD ResumeHandle = 0;
72c2c66affSColin Finck NET_API_STATUS Status;
73c2c66affSColin Finck
74c2c66affSColin Finck Status = NetServerGetInfo(NULL,
75c2c66affSColin Finck 100,
76c2c66affSColin Finck (LPBYTE*)&pServer);
77c2c66affSColin Finck if (Status != NERR_Success)
78c2c66affSColin Finck return Status;
79c2c66affSColin Finck
80c2c66affSColin Finck ConPuts(StdOut, L"\n");
81050db4faSEric Kohl PrintMessageStringV(4410, pServer->sv100_name);
82050db4faSEric Kohl ConPuts(StdOut, L"\n");
83c2c66affSColin Finck PrintPadding(L'-', 79);
84c2c66affSColin Finck ConPuts(StdOut, L"\n");
85c2c66affSColin Finck
86c2c66affSColin Finck NetApiBufferFree(pServer);
87c2c66affSColin Finck
88c2c66affSColin Finck do
89c2c66affSColin Finck {
90c2c66affSColin Finck Status = NetUserEnum(NULL,
91c2c66affSColin Finck 0,
92c2c66affSColin Finck 0,
93c2c66affSColin Finck (LPBYTE*)&pBuffer,
94c2c66affSColin Finck MAX_PREFERRED_LENGTH,
95c2c66affSColin Finck &dwRead,
96c2c66affSColin Finck &dwTotal,
97c2c66affSColin Finck &ResumeHandle);
98c2c66affSColin Finck if ((Status != NERR_Success) && (Status != ERROR_MORE_DATA))
99c2c66affSColin Finck return Status;
100c2c66affSColin Finck
101c2c66affSColin Finck qsort(pBuffer,
102c2c66affSColin Finck dwRead,
103c2c66affSColin Finck sizeof(PUSER_INFO_0),
104506bd64eSEric Kohl CompareInfo);
105c2c66affSColin Finck
106c2c66affSColin Finck for (i = 0; i < dwRead; i++)
107c2c66affSColin Finck {
108c2c66affSColin Finck if (pBuffer[i].usri0_name)
109c2c66affSColin Finck ConPrintf(StdOut, L"%s\n", pBuffer[i].usri0_name);
110c2c66affSColin Finck }
111c2c66affSColin Finck
112c2c66affSColin Finck NetApiBufferFree(pBuffer);
113c2c66affSColin Finck pBuffer = NULL;
114c2c66affSColin Finck }
115c2c66affSColin Finck while (Status == ERROR_MORE_DATA);
116c2c66affSColin Finck
117c2c66affSColin Finck return NERR_Success;
118c2c66affSColin Finck }
119c2c66affSColin Finck
120c2c66affSColin Finck
121c2c66affSColin Finck static
122c2c66affSColin Finck VOID
PrintDateTime(DWORD dwSeconds)123c2c66affSColin Finck PrintDateTime(DWORD dwSeconds)
124c2c66affSColin Finck {
125c2c66affSColin Finck LARGE_INTEGER Time;
126c2c66affSColin Finck FILETIME FileTime;
127c2c66affSColin Finck SYSTEMTIME SystemTime;
128c2c66affSColin Finck WCHAR DateBuffer[80];
129c2c66affSColin Finck WCHAR TimeBuffer[80];
130c2c66affSColin Finck
131c2c66affSColin Finck RtlSecondsSince1970ToTime(dwSeconds, &Time);
132c2c66affSColin Finck FileTime.dwLowDateTime = Time.u.LowPart;
133c2c66affSColin Finck FileTime.dwHighDateTime = Time.u.HighPart;
134c2c66affSColin Finck FileTimeToLocalFileTime(&FileTime, &FileTime);
135c2c66affSColin Finck FileTimeToSystemTime(&FileTime, &SystemTime);
136c2c66affSColin Finck
137c2c66affSColin Finck GetDateFormatW(LOCALE_USER_DEFAULT,
138c2c66affSColin Finck DATE_SHORTDATE,
139c2c66affSColin Finck &SystemTime,
140c2c66affSColin Finck NULL,
141c2c66affSColin Finck DateBuffer,
1424cf5013aSEric Kohl ARRAYSIZE(DateBuffer));
143c2c66affSColin Finck
144c2c66affSColin Finck GetTimeFormatW(LOCALE_USER_DEFAULT,
145c2c66affSColin Finck TIME_NOSECONDS,
146c2c66affSColin Finck &SystemTime,
147c2c66affSColin Finck NULL,
148c2c66affSColin Finck TimeBuffer,
1494cf5013aSEric Kohl ARRAYSIZE(TimeBuffer));
150c2c66affSColin Finck
151c2c66affSColin Finck ConPrintf(StdOut, L"%s %s", DateBuffer, TimeBuffer);
152c2c66affSColin Finck }
153c2c66affSColin Finck
154c2c66affSColin Finck
155c2c66affSColin Finck static
1560ca92979SEric Kohl VOID
PrintLocalTime(DWORD dwSeconds)1570ca92979SEric Kohl PrintLocalTime(DWORD dwSeconds)
1580ca92979SEric Kohl {
1590ca92979SEric Kohl LARGE_INTEGER Time;
1600ca92979SEric Kohl FILETIME FileTime;
1610ca92979SEric Kohl SYSTEMTIME SystemTime;
1620ca92979SEric Kohl WCHAR TimeBuffer[80];
1630ca92979SEric Kohl
1640ca92979SEric Kohl RtlSecondsSince1970ToTime(dwSeconds, &Time);
1650ca92979SEric Kohl FileTime.dwLowDateTime = Time.u.LowPart;
1660ca92979SEric Kohl FileTime.dwHighDateTime = Time.u.HighPart;
1670ca92979SEric Kohl FileTimeToSystemTime(&FileTime, &SystemTime);
1680ca92979SEric Kohl
1690ca92979SEric Kohl GetTimeFormatW(LOCALE_USER_DEFAULT,
1700ca92979SEric Kohl TIME_NOSECONDS,
1710ca92979SEric Kohl &SystemTime,
1720ca92979SEric Kohl NULL,
1730ca92979SEric Kohl TimeBuffer,
1740ca92979SEric Kohl ARRAYSIZE(TimeBuffer));
1750ca92979SEric Kohl
1760ca92979SEric Kohl ConPrintf(StdOut, L"%s", TimeBuffer);
1770ca92979SEric Kohl }
1780ca92979SEric Kohl
1790ca92979SEric Kohl
1800ca92979SEric Kohl static
181c2c66affSColin Finck DWORD
GetTimeInSeconds(VOID)182c2c66affSColin Finck GetTimeInSeconds(VOID)
183c2c66affSColin Finck {
184c2c66affSColin Finck LARGE_INTEGER Time;
185c2c66affSColin Finck FILETIME FileTime;
186c2c66affSColin Finck DWORD dwSeconds;
187c2c66affSColin Finck
188c2c66affSColin Finck GetSystemTimeAsFileTime(&FileTime);
189c2c66affSColin Finck Time.u.LowPart = FileTime.dwLowDateTime;
190c2c66affSColin Finck Time.u.HighPart = FileTime.dwHighDateTime;
191c2c66affSColin Finck RtlTimeToSecondsSince1970(&Time, &dwSeconds);
192c2c66affSColin Finck
193c2c66affSColin Finck return dwSeconds;
194c2c66affSColin Finck }
195c2c66affSColin Finck
196c2c66affSColin Finck
197c2c66affSColin Finck static
19808d30403SEric Kohl BOOL
GetCountryFromCountryCode(_In_ DWORD dwCountryCode,_In_ DWORD dwCountryLength,_Out_ PWSTR szCountryBuffer)19908d30403SEric Kohl GetCountryFromCountryCode(
20008d30403SEric Kohl _In_ DWORD dwCountryCode,
20108d30403SEric Kohl _In_ DWORD dwCountryLength,
20208d30403SEric Kohl _Out_ PWSTR szCountryBuffer)
20308d30403SEric Kohl {
20408d30403SEric Kohl DWORD i;
20508d30403SEric Kohl
20608d30403SEric Kohl for (i = 0; i < ARRAYSIZE(CountryTable); i++)
20708d30403SEric Kohl {
20808d30403SEric Kohl if (CountryTable[i].dwCountryCode == dwCountryCode)
20908d30403SEric Kohl {
21008d30403SEric Kohl if (szCountryBuffer != NULL && dwCountryLength > 0)
21108d30403SEric Kohl {
21208d30403SEric Kohl FormatMessageW(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS,
21308d30403SEric Kohl hModuleNetMsg,
21408d30403SEric Kohl CountryTable[i].dwMessageId,
21508d30403SEric Kohl LANG_USER_DEFAULT,
21608d30403SEric Kohl szCountryBuffer,
21708d30403SEric Kohl dwCountryLength,
21808d30403SEric Kohl NULL);
21908d30403SEric Kohl }
22008d30403SEric Kohl
22108d30403SEric Kohl return TRUE;
22208d30403SEric Kohl }
22308d30403SEric Kohl }
22408d30403SEric Kohl
22508d30403SEric Kohl return FALSE;
22608d30403SEric Kohl }
22708d30403SEric Kohl
22808d30403SEric Kohl
22908d30403SEric Kohl static
2304cf5013aSEric Kohl BOOL
GetBitValue(PBYTE pBitmap,DWORD dwBitNumber)231ccd95b98SEric Kohl GetBitValue(
232ccd95b98SEric Kohl PBYTE pBitmap,
2334cf5013aSEric Kohl DWORD dwBitNumber)
2344cf5013aSEric Kohl {
2354cf5013aSEric Kohl DWORD dwIndex = dwBitNumber / 8;
2364cf5013aSEric Kohl BYTE Mask = 1 << (dwBitNumber & 7);
2374cf5013aSEric Kohl
238ccd95b98SEric Kohl return ((pBitmap[dwIndex] & Mask) != 0);
239ccd95b98SEric Kohl }
240ccd95b98SEric Kohl
241ccd95b98SEric Kohl
242ccd95b98SEric Kohl static
243ccd95b98SEric Kohl VOID
SetBitValue(PBYTE pBitmap,DWORD dwBitNumber)244ccd95b98SEric Kohl SetBitValue(
245ccd95b98SEric Kohl PBYTE pBitmap,
246ccd95b98SEric Kohl DWORD dwBitNumber)
247ccd95b98SEric Kohl {
248ccd95b98SEric Kohl DWORD dwIndex = dwBitNumber / 8;
249ccd95b98SEric Kohl BYTE Mask = 1 << (dwBitNumber & 7);
250ccd95b98SEric Kohl
251ccd95b98SEric Kohl pBitmap[dwIndex] |= Mask;
2524cf5013aSEric Kohl }
2534cf5013aSEric Kohl
2544cf5013aSEric Kohl
2554cf5013aSEric Kohl static
2564cf5013aSEric Kohl VOID
PrintLogonHours(DWORD dwUnitsPerWeek,PBYTE pLogonHours,INT nPaddedLength)2574cf5013aSEric Kohl PrintLogonHours(
2584cf5013aSEric Kohl DWORD dwUnitsPerWeek,
2594cf5013aSEric Kohl PBYTE pLogonHours,
2604cf5013aSEric Kohl INT nPaddedLength)
2614cf5013aSEric Kohl {
2624cf5013aSEric Kohl DWORD dwUnitsPerDay, dwBitNumber, dwSecondsPerUnit;
263e5b635edSEric Kohl DWORD dwStartTime, dwEndTime, dwStartDay, dwEndDay, dwBias;
2644cf5013aSEric Kohl BOOL bBitValue, bFirst = TRUE;
265e5b635edSEric Kohl TIME_ZONE_INFORMATION TimeZoneInformation;
266e5b635edSEric Kohl
267e5b635edSEric Kohl GetTimeZoneInformation(&TimeZoneInformation);
268e5b635edSEric Kohl dwBias = (TimeZoneInformation.Bias / 60) * SECONDS_PER_HOUR;
2694cf5013aSEric Kohl
2704cf5013aSEric Kohl if ((dwUnitsPerWeek == 0) ||
2714cf5013aSEric Kohl ((dwUnitsPerWeek %7) != 0))
2724cf5013aSEric Kohl return;
2734cf5013aSEric Kohl
2744cf5013aSEric Kohl dwUnitsPerDay = dwUnitsPerWeek / 7;
2754cf5013aSEric Kohl
2764cf5013aSEric Kohl if (((dwUnitsPerDay % 24) != 0) ||
2774cf5013aSEric Kohl ((dwUnitsPerDay / 24) > 6))
2784cf5013aSEric Kohl return;
2794cf5013aSEric Kohl
2800ca92979SEric Kohl dwSecondsPerUnit = (SECONDS_PER_DAY) / dwUnitsPerDay;
2814cf5013aSEric Kohl
2824cf5013aSEric Kohl for (dwBitNumber = 0; dwBitNumber < dwUnitsPerWeek; dwBitNumber++)
2834cf5013aSEric Kohl {
284ccd95b98SEric Kohl bBitValue = GetBitValue(pLogonHours, dwBitNumber);
2854cf5013aSEric Kohl if (bBitValue)
2864cf5013aSEric Kohl {
2874cf5013aSEric Kohl dwStartTime = dwSecondsPerUnit * dwBitNumber;
2884cf5013aSEric Kohl
2894cf5013aSEric Kohl while (bBitValue != 0 && dwBitNumber < dwUnitsPerWeek)
2904cf5013aSEric Kohl {
2914cf5013aSEric Kohl dwBitNumber++;
2924cf5013aSEric Kohl if (dwBitNumber < dwUnitsPerWeek)
293ccd95b98SEric Kohl bBitValue = GetBitValue(pLogonHours, dwBitNumber);
2944cf5013aSEric Kohl }
2954cf5013aSEric Kohl
2964cf5013aSEric Kohl dwEndTime = dwSecondsPerUnit * dwBitNumber;
2974cf5013aSEric Kohl
2984cf5013aSEric Kohl if (!bFirst)
2994cf5013aSEric Kohl PrintPadding(L' ', nPaddedLength);
3004cf5013aSEric Kohl
3010ca92979SEric Kohl if (dwStartTime == 0 && dwEndTime == (SECONDS_PER_DAY * 7))
3024cf5013aSEric Kohl {
3034cf5013aSEric Kohl PrintMessageString(4302);
3044cf5013aSEric Kohl ConPuts(StdOut, L"\n");
3054cf5013aSEric Kohl }
3064cf5013aSEric Kohl else
3074cf5013aSEric Kohl {
3080ca92979SEric Kohl dwStartDay = dwStartTime / SECONDS_PER_DAY;
3090ca92979SEric Kohl dwEndDay = (dwEndTime / SECONDS_PER_DAY) % 7;
3100ca92979SEric Kohl
3110ca92979SEric Kohl PrintMessageString(4307 + dwStartDay);
3120ca92979SEric Kohl ConPuts(StdOut, L" ");
313ccd95b98SEric Kohl
314e5b635edSEric Kohl /* Convert from GMT to local timezone */
315e5b635edSEric Kohl PrintLocalTime((dwStartTime % SECONDS_PER_DAY) - dwBias);
3160ca92979SEric Kohl
3170ca92979SEric Kohl ConPrintf(StdOut, L" - ");
3180ca92979SEric Kohl if (dwStartDay != dwEndDay)
3190ca92979SEric Kohl {
3200ca92979SEric Kohl PrintMessageString(4307 + dwEndDay);
3210ca92979SEric Kohl ConPuts(StdOut, L" ");
3220ca92979SEric Kohl }
3230ca92979SEric Kohl
324e5b635edSEric Kohl /* Convert from GMT to local timezone */
325e5b635edSEric Kohl PrintLocalTime((dwEndTime % SECONDS_PER_DAY) - dwBias);
3260ca92979SEric Kohl ConPuts(StdOut, L"\n");
3274cf5013aSEric Kohl }
3284cf5013aSEric Kohl
3294cf5013aSEric Kohl bFirst = FALSE;
3304cf5013aSEric Kohl }
3314cf5013aSEric Kohl }
33223825149SEric Kohl
33323825149SEric Kohl if (bFirst)
33423825149SEric Kohl {
33523825149SEric Kohl /* No logon hours */
33623825149SEric Kohl PrintMessageString(4434);
33723825149SEric Kohl ConPuts(StdOut, L"\n");
33823825149SEric Kohl }
3394cf5013aSEric Kohl }
3404cf5013aSEric Kohl
3414cf5013aSEric Kohl
3424cf5013aSEric Kohl static
343c2c66affSColin Finck NET_API_STATUS
DisplayUser(LPWSTR lpUserName)344c2c66affSColin Finck DisplayUser(LPWSTR lpUserName)
345c2c66affSColin Finck {
346c2c66affSColin Finck PUSER_MODALS_INFO_0 pUserModals = NULL;
347c2c66affSColin Finck PUSER_INFO_4 pUserInfo = NULL;
348c2c66affSColin Finck PLOCALGROUP_USERS_INFO_0 pLocalGroupInfo = NULL;
349c2c66affSColin Finck PGROUP_USERS_INFO_0 pGroupInfo = NULL;
350c2c66affSColin Finck DWORD dwLocalGroupRead, dwLocalGroupTotal;
351c2c66affSColin Finck DWORD dwGroupRead, dwGroupTotal;
352c2c66affSColin Finck DWORD dwLastSet;
353c2c66affSColin Finck DWORD i;
35408d30403SEric Kohl WCHAR szCountry[40];
355050db4faSEric Kohl INT nPaddedLength = 36;
356c2c66affSColin Finck NET_API_STATUS Status;
357c2c66affSColin Finck
358c2c66affSColin Finck /* Modify the user */
359c2c66affSColin Finck Status = NetUserGetInfo(NULL,
360c2c66affSColin Finck lpUserName,
361c2c66affSColin Finck 4,
362c2c66affSColin Finck (LPBYTE*)&pUserInfo);
363c2c66affSColin Finck if (Status != NERR_Success)
364c2c66affSColin Finck return Status;
365c2c66affSColin Finck
366c2c66affSColin Finck Status = NetUserModalsGet(NULL,
367c2c66affSColin Finck 0,
368c2c66affSColin Finck (LPBYTE*)&pUserModals);
369c2c66affSColin Finck if (Status != NERR_Success)
370c2c66affSColin Finck goto done;
371c2c66affSColin Finck
372c2c66affSColin Finck Status = NetUserGetLocalGroups(NULL,
373c2c66affSColin Finck lpUserName,
374c2c66affSColin Finck 0,
375c2c66affSColin Finck 0,
376c2c66affSColin Finck (LPBYTE*)&pLocalGroupInfo,
377c2c66affSColin Finck MAX_PREFERRED_LENGTH,
378c2c66affSColin Finck &dwLocalGroupRead,
379c2c66affSColin Finck &dwLocalGroupTotal);
380c2c66affSColin Finck if (Status != NERR_Success)
381c2c66affSColin Finck goto done;
382c2c66affSColin Finck
383c2c66affSColin Finck Status = NetUserGetGroups(NULL,
384c2c66affSColin Finck lpUserName,
385c2c66affSColin Finck 0,
386c2c66affSColin Finck (LPBYTE*)&pGroupInfo,
387c2c66affSColin Finck MAX_PREFERRED_LENGTH,
388c2c66affSColin Finck &dwGroupRead,
389c2c66affSColin Finck &dwGroupTotal);
390c2c66affSColin Finck if (Status != NERR_Success)
391c2c66affSColin Finck goto done;
392c2c66affSColin Finck
393050db4faSEric Kohl PrintPaddedMessageString(4411, nPaddedLength);
394c2c66affSColin Finck ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_name);
395c2c66affSColin Finck
396050db4faSEric Kohl PrintPaddedMessageString(4412, nPaddedLength);
397c2c66affSColin Finck ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_full_name);
398c2c66affSColin Finck
399050db4faSEric Kohl PrintPaddedMessageString(4413, nPaddedLength);
400c2c66affSColin Finck ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_comment);
401c2c66affSColin Finck
402050db4faSEric Kohl PrintPaddedMessageString(4414, nPaddedLength);
403c2c66affSColin Finck ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_usr_comment);
404c2c66affSColin Finck
405050db4faSEric Kohl PrintPaddedMessageString(4416, nPaddedLength);
40608d30403SEric Kohl GetCountryFromCountryCode(pUserInfo->usri4_country_code,
40708d30403SEric Kohl ARRAYSIZE(szCountry), szCountry);
40808d30403SEric Kohl ConPrintf(StdOut, L"%03ld (%s)\n", pUserInfo->usri4_country_code, szCountry);
409c2c66affSColin Finck
410050db4faSEric Kohl PrintPaddedMessageString(4419, nPaddedLength);
411c2c66affSColin Finck if (pUserInfo->usri4_flags & UF_ACCOUNTDISABLE)
41288f899e1SEric Kohl PrintMessageString(4301);
413c2c66affSColin Finck else if (pUserInfo->usri4_flags & UF_LOCKOUT)
414050db4faSEric Kohl PrintMessageString(4440);
415c2c66affSColin Finck else
41688f899e1SEric Kohl PrintMessageString(4300);
417c2c66affSColin Finck ConPuts(StdOut, L"\n");
418c2c66affSColin Finck
419050db4faSEric Kohl PrintPaddedMessageString(4420, nPaddedLength);
420c2c66affSColin Finck if (pUserInfo->usri4_acct_expires == TIMEQ_FOREVER)
42188f899e1SEric Kohl PrintMessageString(4305);
422c2c66affSColin Finck else
423c2c66affSColin Finck PrintDateTime(pUserInfo->usri4_acct_expires);
424c2c66affSColin Finck ConPuts(StdOut, L"\n\n");
425c2c66affSColin Finck
426050db4faSEric Kohl PrintPaddedMessageString(4421, nPaddedLength);
427c2c66affSColin Finck dwLastSet = GetTimeInSeconds() - pUserInfo->usri4_password_age;
428c2c66affSColin Finck PrintDateTime(dwLastSet);
429e3d000c3SMarian Schubert ConPuts(StdOut, L"\n");
430c2c66affSColin Finck
431050db4faSEric Kohl PrintPaddedMessageString(4422, nPaddedLength);
432c2c66affSColin Finck if ((pUserInfo->usri4_flags & UF_DONT_EXPIRE_PASSWD) || pUserModals->usrmod0_max_passwd_age == TIMEQ_FOREVER)
43388f899e1SEric Kohl PrintMessageString(4305);
434c2c66affSColin Finck else
435c2c66affSColin Finck PrintDateTime(dwLastSet + pUserModals->usrmod0_max_passwd_age);
436c2c66affSColin Finck ConPuts(StdOut, L"\n");
437c2c66affSColin Finck
438050db4faSEric Kohl PrintPaddedMessageString(4423, nPaddedLength);
439c2c66affSColin Finck PrintDateTime(dwLastSet + pUserModals->usrmod0_min_passwd_age);
440e3d000c3SMarian Schubert ConPuts(StdOut, L"\n");
441c2c66affSColin Finck
442050db4faSEric Kohl PrintPaddedMessageString(4437, nPaddedLength);
44388f899e1SEric Kohl PrintMessageString((pUserInfo->usri4_flags & UF_PASSWD_NOTREQD) ? 4301 : 4300);
444c2c66affSColin Finck ConPuts(StdOut, L"\n");
445c2c66affSColin Finck
446050db4faSEric Kohl PrintPaddedMessageString(4438, nPaddedLength);
44788f899e1SEric Kohl PrintMessageString((pUserInfo->usri4_flags & UF_PASSWD_CANT_CHANGE) ? 4301 : 4300);
448c2c66affSColin Finck ConPuts(StdOut, L"\n\n");
449c2c66affSColin Finck
450050db4faSEric Kohl PrintPaddedMessageString(4424, nPaddedLength);
451c2c66affSColin Finck if (pUserInfo->usri4_workstations == NULL || wcslen(pUserInfo->usri4_workstations) == 0)
45288f899e1SEric Kohl PrintMessageString(4302);
453c2c66affSColin Finck else
454c2c66affSColin Finck ConPrintf(StdOut, L"%s", pUserInfo->usri4_workstations);
455c2c66affSColin Finck ConPuts(StdOut, L"\n");
456c2c66affSColin Finck
457050db4faSEric Kohl PrintPaddedMessageString(4429, nPaddedLength);
458c2c66affSColin Finck ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_script_path);
459c2c66affSColin Finck
460050db4faSEric Kohl PrintPaddedMessageString(4439, nPaddedLength);
461c2c66affSColin Finck ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_profile);
462c2c66affSColin Finck
463050db4faSEric Kohl PrintPaddedMessageString(4436, nPaddedLength);
464c2c66affSColin Finck ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_home_dir);
465c2c66affSColin Finck
466050db4faSEric Kohl PrintPaddedMessageString(4430, nPaddedLength);
467c2c66affSColin Finck if (pUserInfo->usri4_last_logon == 0)
46888f899e1SEric Kohl PrintMessageString(4305);
469c2c66affSColin Finck else
470c2c66affSColin Finck PrintDateTime(pUserInfo->usri4_last_logon);
471c2c66affSColin Finck ConPuts(StdOut, L"\n\n");
472c2c66affSColin Finck
473050db4faSEric Kohl PrintPaddedMessageString(4432, nPaddedLength);
474c2c66affSColin Finck if (pUserInfo->usri4_logon_hours == NULL)
4754cf5013aSEric Kohl {
47688f899e1SEric Kohl PrintMessageString(4302);
4774cf5013aSEric Kohl ConPuts(StdOut, L"\n");
4784cf5013aSEric Kohl }
4794cf5013aSEric Kohl else
4804cf5013aSEric Kohl {
4814cf5013aSEric Kohl PrintLogonHours(pUserInfo->usri4_units_per_week,
4824cf5013aSEric Kohl pUserInfo->usri4_logon_hours,
4834cf5013aSEric Kohl nPaddedLength);
4844cf5013aSEric Kohl }
485c2c66affSColin Finck
486c2c66affSColin Finck ConPuts(StdOut, L"\n");
487050db4faSEric Kohl PrintPaddedMessageString(4427, nPaddedLength);
488c2c66affSColin Finck if (dwLocalGroupTotal != 0 && pLocalGroupInfo != NULL)
489c2c66affSColin Finck {
490c2c66affSColin Finck for (i = 0; i < dwLocalGroupTotal; i++)
491c2c66affSColin Finck {
492c2c66affSColin Finck if (i != 0)
493c2c66affSColin Finck PrintPadding(L' ', nPaddedLength);
494c2c66affSColin Finck ConPrintf(StdOut, L"*%s\n", pLocalGroupInfo[i].lgrui0_name);
495c2c66affSColin Finck }
496c2c66affSColin Finck }
497c2c66affSColin Finck else
498c2c66affSColin Finck {
499c2c66affSColin Finck ConPuts(StdOut, L"\n");
500c2c66affSColin Finck }
501c2c66affSColin Finck
502050db4faSEric Kohl PrintPaddedMessageString(4431, nPaddedLength);
503c2c66affSColin Finck if (dwGroupTotal != 0 && pGroupInfo != NULL)
504c2c66affSColin Finck {
505c2c66affSColin Finck for (i = 0; i < dwGroupTotal; i++)
506c2c66affSColin Finck {
507c2c66affSColin Finck if (i != 0)
508c2c66affSColin Finck PrintPadding(L' ', nPaddedLength);
509c2c66affSColin Finck ConPrintf(StdOut, L"*%s\n", pGroupInfo[i].grui0_name);
510c2c66affSColin Finck }
511c2c66affSColin Finck }
512c2c66affSColin Finck else
513c2c66affSColin Finck {
514c2c66affSColin Finck ConPuts(StdOut, L"\n");
515c2c66affSColin Finck }
516c2c66affSColin Finck
517c2c66affSColin Finck done:
518c2c66affSColin Finck if (pGroupInfo != NULL)
519c2c66affSColin Finck NetApiBufferFree(pGroupInfo);
520c2c66affSColin Finck
521c2c66affSColin Finck if (pLocalGroupInfo != NULL)
522c2c66affSColin Finck NetApiBufferFree(pLocalGroupInfo);
523c2c66affSColin Finck
524c2c66affSColin Finck if (pUserModals != NULL)
525c2c66affSColin Finck NetApiBufferFree(pUserModals);
526c2c66affSColin Finck
527c2c66affSColin Finck if (pUserInfo != NULL)
528c2c66affSColin Finck NetApiBufferFree(pUserInfo);
529c2c66affSColin Finck
530c2c66affSColin Finck return NERR_Success;
531c2c66affSColin Finck }
532c2c66affSColin Finck
533c2c66affSColin Finck
534c2c66affSColin Finck static
535c2c66affSColin Finck VOID
ReadPassword(LPWSTR * lpPassword,LPBOOL lpAllocated)536c2c66affSColin Finck ReadPassword(
537c2c66affSColin Finck LPWSTR *lpPassword,
538c2c66affSColin Finck LPBOOL lpAllocated)
539c2c66affSColin Finck {
540c2c66affSColin Finck WCHAR szPassword1[PWLEN + 1];
541c2c66affSColin Finck WCHAR szPassword2[PWLEN + 1];
542c2c66affSColin Finck LPWSTR ptr;
543c2c66affSColin Finck
544c2c66affSColin Finck *lpAllocated = FALSE;
545c2c66affSColin Finck
546c2c66affSColin Finck while (TRUE)
547c2c66affSColin Finck {
5485563525aSEric Kohl PrintMessageString(4358);
549c2c66affSColin Finck ReadFromConsole(szPassword1, PWLEN + 1, FALSE);
550c2c66affSColin Finck ConPuts(StdOut, L"\n");
551c2c66affSColin Finck
5525563525aSEric Kohl PrintMessageString(4361);
553c2c66affSColin Finck ReadFromConsole(szPassword2, PWLEN + 1, FALSE);
554c2c66affSColin Finck ConPuts(StdOut, L"\n");
555c2c66affSColin Finck
556c2c66affSColin Finck if (wcslen(szPassword1) == wcslen(szPassword2) &&
557c2c66affSColin Finck wcscmp(szPassword1, szPassword2) == 0)
558c2c66affSColin Finck {
559c2c66affSColin Finck ptr = HeapAlloc(GetProcessHeap(),
560c2c66affSColin Finck 0,
561c2c66affSColin Finck (wcslen(szPassword1) + 1) * sizeof(WCHAR));
562c2c66affSColin Finck if (ptr != NULL)
563c2c66affSColin Finck {
564c2c66affSColin Finck wcscpy(ptr, szPassword1);
565c2c66affSColin Finck *lpPassword = ptr;
566c2c66affSColin Finck *lpAllocated = TRUE;
567c2c66affSColin Finck return;
568c2c66affSColin Finck }
569c2c66affSColin Finck }
570c2c66affSColin Finck else
571c2c66affSColin Finck {
572c2c66affSColin Finck ConPuts(StdOut, L"\n");
5735563525aSEric Kohl PrintMessageString(3728);
574c2c66affSColin Finck *lpPassword = NULL;
575c2c66affSColin Finck }
576c2c66affSColin Finck }
577c2c66affSColin Finck }
578c2c66affSColin Finck
579c2c66affSColin Finck
580b4969dc0SEric Kohl static
581b4969dc0SEric Kohl VOID
GenerateRandomPassword(LPWSTR * lpPassword,LPBOOL lpAllocated)582b4969dc0SEric Kohl GenerateRandomPassword(
583b4969dc0SEric Kohl LPWSTR *lpPassword,
584b4969dc0SEric Kohl LPBOOL lpAllocated)
585b4969dc0SEric Kohl {
586b4969dc0SEric Kohl LPWSTR pPassword = NULL;
587b4969dc0SEric Kohl INT nCharsLen, i, nLength = 8;
588b4969dc0SEric Kohl
589b4969dc0SEric Kohl srand(GetTickCount());
590b4969dc0SEric Kohl
591b4969dc0SEric Kohl pPassword = HeapAlloc(GetProcessHeap(),
592b4969dc0SEric Kohl HEAP_ZERO_MEMORY,
593b4969dc0SEric Kohl (nLength + 1) * sizeof(WCHAR));
594b4969dc0SEric Kohl if (pPassword == NULL)
595b4969dc0SEric Kohl return;
596b4969dc0SEric Kohl
597b4969dc0SEric Kohl nCharsLen = wcslen(szPasswordChars);
598b4969dc0SEric Kohl
599b4969dc0SEric Kohl for (i = 0; i < nLength; i++)
600b4969dc0SEric Kohl {
601b4969dc0SEric Kohl pPassword[i] = szPasswordChars[rand() % nCharsLen];
602b4969dc0SEric Kohl }
603b4969dc0SEric Kohl
604b4969dc0SEric Kohl *lpPassword = pPassword;
605b4969dc0SEric Kohl *lpAllocated = TRUE;
606b4969dc0SEric Kohl }
607b4969dc0SEric Kohl
608b4969dc0SEric Kohl
609add1be24SEric Kohl static
610add1be24SEric Kohl NET_API_STATUS
BuildWorkstationsList(_Out_ PWSTR * pWorkstationsList,_In_ PWSTR pRaw)611add1be24SEric Kohl BuildWorkstationsList(
612add1be24SEric Kohl _Out_ PWSTR *pWorkstationsList,
613add1be24SEric Kohl _In_ PWSTR pRaw)
614add1be24SEric Kohl {
615add1be24SEric Kohl BOOL isLastSep, isSep;
616add1be24SEric Kohl INT i, j;
617add1be24SEric Kohl WCHAR c;
618add1be24SEric Kohl INT nLength = 0;
619add1be24SEric Kohl INT nArgs = 0;
620add1be24SEric Kohl INT nRawLength;
621add1be24SEric Kohl PWSTR pList;
622add1be24SEric Kohl
623add1be24SEric Kohl /* Check for invalid characters in the raw string */
624add1be24SEric Kohl if (wcspbrk(pRaw, L"/[]=?\\+:.") != NULL)
625add1be24SEric Kohl return 3952;
626add1be24SEric Kohl
627add1be24SEric Kohl /* Count the number of workstations in the list and
628add1be24SEric Kohl * the required buffer size */
629add1be24SEric Kohl isLastSep = FALSE;
630add1be24SEric Kohl isSep = FALSE;
631add1be24SEric Kohl nRawLength = wcslen(pRaw);
632add1be24SEric Kohl for (i = 0; i < nRawLength; i++)
633add1be24SEric Kohl {
634add1be24SEric Kohl c = pRaw[i];
635add1be24SEric Kohl if (c == L',' || c == L';')
636add1be24SEric Kohl isSep = TRUE;
637add1be24SEric Kohl
638add1be24SEric Kohl if (isSep == TRUE)
639add1be24SEric Kohl {
640add1be24SEric Kohl if ((isLastSep == FALSE) && (i != 0) && (i != nRawLength - 1))
641add1be24SEric Kohl nLength++;
642add1be24SEric Kohl }
643add1be24SEric Kohl else
644add1be24SEric Kohl {
645add1be24SEric Kohl nLength++;
646add1be24SEric Kohl
647add1be24SEric Kohl if (isLastSep == TRUE || (isLastSep == FALSE && i == 0))
648add1be24SEric Kohl nArgs++;
649add1be24SEric Kohl }
650add1be24SEric Kohl
651add1be24SEric Kohl isLastSep = isSep;
652add1be24SEric Kohl isSep = FALSE;
653add1be24SEric Kohl }
654add1be24SEric Kohl
655add1be24SEric Kohl nLength++;
656add1be24SEric Kohl
657add1be24SEric Kohl /* Leave, if there are no workstations in the list */
658add1be24SEric Kohl if (nArgs == 0)
659add1be24SEric Kohl {
660add1be24SEric Kohl pWorkstationsList = NULL;
661add1be24SEric Kohl return NERR_Success;
662add1be24SEric Kohl }
663add1be24SEric Kohl
664add1be24SEric Kohl /* Fail if there are more than eight workstations in the list */
665add1be24SEric Kohl if (nArgs > 8)
666add1be24SEric Kohl return 3951;
667add1be24SEric Kohl
668add1be24SEric Kohl /* Allocate the buffer for the clean workstation list */
669add1be24SEric Kohl pList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nLength * sizeof(WCHAR));
670add1be24SEric Kohl if (pList == NULL)
671add1be24SEric Kohl return ERROR_NOT_ENOUGH_MEMORY;
672add1be24SEric Kohl
673add1be24SEric Kohl /* Build the clean workstation list */
674add1be24SEric Kohl isLastSep = FALSE;
675add1be24SEric Kohl isSep = FALSE;
676add1be24SEric Kohl nRawLength = wcslen(pRaw);
677add1be24SEric Kohl for (i = 0, j = 0; i < nRawLength; i++)
678add1be24SEric Kohl {
679add1be24SEric Kohl c = pRaw[i];
680add1be24SEric Kohl if (c == L',' || c == L';')
681add1be24SEric Kohl isSep = TRUE;
682add1be24SEric Kohl
683add1be24SEric Kohl if (isSep == TRUE)
684add1be24SEric Kohl {
685add1be24SEric Kohl if ((isLastSep == FALSE) && (i != 0) && (i != nRawLength - 1))
686add1be24SEric Kohl {
687add1be24SEric Kohl pList[j] = L',';
688add1be24SEric Kohl j++;
689add1be24SEric Kohl }
690add1be24SEric Kohl }
691add1be24SEric Kohl else
692add1be24SEric Kohl {
693add1be24SEric Kohl pList[j] = c;
694add1be24SEric Kohl j++;
695add1be24SEric Kohl
696add1be24SEric Kohl if (isLastSep == TRUE || (isLastSep == FALSE && i == 0))
697add1be24SEric Kohl nArgs++;
698add1be24SEric Kohl }
699add1be24SEric Kohl
700add1be24SEric Kohl isLastSep = isSep;
701add1be24SEric Kohl isSep = FALSE;
702add1be24SEric Kohl }
703add1be24SEric Kohl
704add1be24SEric Kohl *pWorkstationsList = pList;
705add1be24SEric Kohl
706add1be24SEric Kohl return NERR_Success;
707add1be24SEric Kohl }
708add1be24SEric Kohl
709add1be24SEric Kohl
710bf76e1bfSEric Kohl static
711bf76e1bfSEric Kohl BOOL
ReadNumber(PWSTR * s,PWORD pwValue)712bf76e1bfSEric Kohl ReadNumber(
713bf76e1bfSEric Kohl PWSTR *s,
714bf76e1bfSEric Kohl PWORD pwValue)
715bf76e1bfSEric Kohl {
716bf76e1bfSEric Kohl if (!iswdigit(**s))
717bf76e1bfSEric Kohl return FALSE;
718bf76e1bfSEric Kohl
719bf76e1bfSEric Kohl while (iswdigit(**s))
720bf76e1bfSEric Kohl {
721bf76e1bfSEric Kohl *pwValue = *pwValue * 10 + **s - L'0';
722bf76e1bfSEric Kohl (*s)++;
723bf76e1bfSEric Kohl }
724bf76e1bfSEric Kohl
725bf76e1bfSEric Kohl return TRUE;
726bf76e1bfSEric Kohl }
727bf76e1bfSEric Kohl
728bf76e1bfSEric Kohl
729bf76e1bfSEric Kohl static
730bf76e1bfSEric Kohl BOOL
ReadSeparator(PWSTR * s)731bf76e1bfSEric Kohl ReadSeparator(
732bf76e1bfSEric Kohl PWSTR *s)
733bf76e1bfSEric Kohl {
734bf76e1bfSEric Kohl if (**s == L'/' || **s == L'.')
735bf76e1bfSEric Kohl {
736bf76e1bfSEric Kohl (*s)++;
737bf76e1bfSEric Kohl return TRUE;
738bf76e1bfSEric Kohl }
739bf76e1bfSEric Kohl
740bf76e1bfSEric Kohl return FALSE;
741bf76e1bfSEric Kohl }
742bf76e1bfSEric Kohl
743bf76e1bfSEric Kohl
744bf76e1bfSEric Kohl static
745bf76e1bfSEric Kohl BOOL
ParseDate(PWSTR s,PULONG pSeconds)746bf76e1bfSEric Kohl ParseDate(
747bf76e1bfSEric Kohl PWSTR s,
748bf76e1bfSEric Kohl PULONG pSeconds)
749bf76e1bfSEric Kohl {
750bf76e1bfSEric Kohl SYSTEMTIME SystemTime = {0};
751bf76e1bfSEric Kohl FILETIME LocalFileTime, FileTime;
752bf76e1bfSEric Kohl LARGE_INTEGER Time;
753bf76e1bfSEric Kohl INT nDateFormat = 0;
754bf76e1bfSEric Kohl PWSTR p = s;
755bf76e1bfSEric Kohl
756bf76e1bfSEric Kohl if (!*s)
757bf76e1bfSEric Kohl return FALSE;
758bf76e1bfSEric Kohl
759bf76e1bfSEric Kohl GetLocaleInfoW(LOCALE_USER_DEFAULT,
760bf76e1bfSEric Kohl LOCALE_IDATE,
761bf76e1bfSEric Kohl (PWSTR)&nDateFormat,
762bf76e1bfSEric Kohl sizeof(INT));
763bf76e1bfSEric Kohl
764bf76e1bfSEric Kohl switch (nDateFormat)
765bf76e1bfSEric Kohl {
766bf76e1bfSEric Kohl case 0: /* mmddyy */
767bf76e1bfSEric Kohl default:
768bf76e1bfSEric Kohl if (!ReadNumber(&p, &SystemTime.wMonth))
769bf76e1bfSEric Kohl return FALSE;
770bf76e1bfSEric Kohl if (!ReadSeparator(&p))
771bf76e1bfSEric Kohl return FALSE;
772bf76e1bfSEric Kohl if (!ReadNumber(&p, &SystemTime.wDay))
773bf76e1bfSEric Kohl return FALSE;
774bf76e1bfSEric Kohl if (!ReadSeparator(&p))
775bf76e1bfSEric Kohl return FALSE;
776bf76e1bfSEric Kohl if (!ReadNumber(&p, &SystemTime.wYear))
777bf76e1bfSEric Kohl return FALSE;
778bf76e1bfSEric Kohl break;
779bf76e1bfSEric Kohl
780bf76e1bfSEric Kohl case 1: /* ddmmyy */
781bf76e1bfSEric Kohl if (!ReadNumber(&p, &SystemTime.wDay))
782bf76e1bfSEric Kohl return FALSE;
783bf76e1bfSEric Kohl if (!ReadSeparator(&p))
784bf76e1bfSEric Kohl return FALSE;
785bf76e1bfSEric Kohl if (!ReadNumber(&p, &SystemTime.wMonth))
786bf76e1bfSEric Kohl return FALSE;
787bf76e1bfSEric Kohl if (!ReadSeparator(&p))
788bf76e1bfSEric Kohl return FALSE;
789bf76e1bfSEric Kohl if (!ReadNumber(&p, &SystemTime.wYear))
790bf76e1bfSEric Kohl return FALSE;
791bf76e1bfSEric Kohl break;
792bf76e1bfSEric Kohl
793bf76e1bfSEric Kohl case 2: /* yymmdd */
794bf76e1bfSEric Kohl if (!ReadNumber(&p, &SystemTime.wYear))
795bf76e1bfSEric Kohl return FALSE;
796bf76e1bfSEric Kohl if (!ReadSeparator(&p))
797bf76e1bfSEric Kohl return FALSE;
798bf76e1bfSEric Kohl if (!ReadNumber(&p, &SystemTime.wMonth))
799bf76e1bfSEric Kohl return FALSE;
800bf76e1bfSEric Kohl if (!ReadSeparator(&p))
801bf76e1bfSEric Kohl return FALSE;
802bf76e1bfSEric Kohl if (!ReadNumber(&p, &SystemTime.wDay))
803bf76e1bfSEric Kohl return FALSE;
804bf76e1bfSEric Kohl break;
805bf76e1bfSEric Kohl }
806bf76e1bfSEric Kohl
807bf76e1bfSEric Kohl /* if only entered two digits: */
808bf76e1bfSEric Kohl /* assume 2000's if value less than 80 */
809bf76e1bfSEric Kohl /* assume 1900's if value greater or equal 80 */
810bf76e1bfSEric Kohl if (SystemTime.wYear <= 99)
811bf76e1bfSEric Kohl {
812bf76e1bfSEric Kohl if (SystemTime.wYear >= 80)
813bf76e1bfSEric Kohl SystemTime.wYear += 1900;
814bf76e1bfSEric Kohl else
815bf76e1bfSEric Kohl SystemTime.wYear += 2000;
816bf76e1bfSEric Kohl }
817bf76e1bfSEric Kohl
818bf76e1bfSEric Kohl if (!SystemTimeToFileTime(&SystemTime, &LocalFileTime))
819bf76e1bfSEric Kohl return FALSE;
820bf76e1bfSEric Kohl
821bf76e1bfSEric Kohl if (!LocalFileTimeToFileTime(&LocalFileTime, &FileTime))
822bf76e1bfSEric Kohl return FALSE;
823bf76e1bfSEric Kohl
824bf76e1bfSEric Kohl Time.u.LowPart = FileTime.dwLowDateTime;
825bf76e1bfSEric Kohl Time.u.HighPart = FileTime.dwHighDateTime;
826bf76e1bfSEric Kohl
827bf76e1bfSEric Kohl if (!RtlTimeToSecondsSince1970(&Time, pSeconds))
828bf76e1bfSEric Kohl return FALSE;
829bf76e1bfSEric Kohl
830bf76e1bfSEric Kohl return TRUE;
831bf76e1bfSEric Kohl }
832bf76e1bfSEric Kohl
833bf76e1bfSEric Kohl
834611e6d7dSEric Kohl static
835ccd95b98SEric Kohl BOOL
ParseHour(PWSTR pszString,PWSTR * AmPmArray,PLONG plHour)836ccd95b98SEric Kohl ParseHour(
837ccd95b98SEric Kohl PWSTR pszString,
838df31f870SEric Kohl PWSTR *AmPmArray,
839e5b635edSEric Kohl PLONG plHour)
840ccd95b98SEric Kohl {
841ccd95b98SEric Kohl PWCHAR pChar;
842e5b635edSEric Kohl LONG lHour = 0;
843ccd95b98SEric Kohl
844ccd95b98SEric Kohl if (!iswdigit(pszString[0]))
845ccd95b98SEric Kohl return FALSE;
846ccd95b98SEric Kohl
847ccd95b98SEric Kohl pChar = pszString;
848ccd95b98SEric Kohl while (iswdigit(*pChar))
849ccd95b98SEric Kohl {
850e5b635edSEric Kohl lHour = lHour * 10 + *pChar - L'0';
851ccd95b98SEric Kohl pChar++;
852ccd95b98SEric Kohl }
853ccd95b98SEric Kohl
854e5b635edSEric Kohl if (lHour > 24)
855ccd95b98SEric Kohl return FALSE;
856ccd95b98SEric Kohl
857e5b635edSEric Kohl if (lHour == 24)
858e5b635edSEric Kohl lHour = 0;
859ccd95b98SEric Kohl
860ccd95b98SEric Kohl if ((*pChar != UNICODE_NULL) &&
861e5b635edSEric Kohl (lHour >= 1) &&
862e5b635edSEric Kohl (lHour <= 12))
863ccd95b98SEric Kohl {
864df31f870SEric Kohl if ((_wcsicmp(pChar, AmPmArray[0]) == 0) ||
865df31f870SEric Kohl (_wcsicmp(pChar, AmPmArray[1]) == 0))
866ccd95b98SEric Kohl {
867e5b635edSEric Kohl if (lHour == 12)
868e5b635edSEric Kohl lHour = 0;
869ccd95b98SEric Kohl }
870df31f870SEric Kohl else if ((_wcsicmp(pChar, AmPmArray[2]) == 0) ||
871df31f870SEric Kohl (_wcsicmp(pChar, AmPmArray[3]) == 0))
872ccd95b98SEric Kohl {
873e5b635edSEric Kohl if (lHour != 12)
874e5b635edSEric Kohl lHour += 12;
875ccd95b98SEric Kohl }
876ccd95b98SEric Kohl else
877ccd95b98SEric Kohl {
878ccd95b98SEric Kohl return FALSE;
879ccd95b98SEric Kohl }
880ccd95b98SEric Kohl }
881ccd95b98SEric Kohl
882e5b635edSEric Kohl *plHour = lHour;
883ccd95b98SEric Kohl
884ccd95b98SEric Kohl return TRUE;
885ccd95b98SEric Kohl }
886ccd95b98SEric Kohl
887ccd95b98SEric Kohl
888ccd95b98SEric Kohl static
889ccd95b98SEric Kohl BOOL
ParseDay(PWSTR pszString,PWSTR * ShortDays,PWSTR * LongDays,PDWORD pdwDay)890ccd95b98SEric Kohl ParseDay(
891ccd95b98SEric Kohl PWSTR pszString,
892df31f870SEric Kohl PWSTR *ShortDays,
893df31f870SEric Kohl PWSTR *LongDays,
894ccd95b98SEric Kohl PDWORD pdwDay)
895ccd95b98SEric Kohl {
896ccd95b98SEric Kohl DWORD i;
897ccd95b98SEric Kohl
898df31f870SEric Kohl for (i = 0; i < 7; i++)
899ccd95b98SEric Kohl {
900df31f870SEric Kohl if (_wcsicmp(pszString, ShortDays[i]) == 0 ||
901df31f870SEric Kohl _wcsicmp(pszString, LongDays[i]) == 0)
902ccd95b98SEric Kohl {
903ccd95b98SEric Kohl *pdwDay = i;
904ccd95b98SEric Kohl return TRUE;
905ccd95b98SEric Kohl }
906ccd95b98SEric Kohl }
907ccd95b98SEric Kohl
908ccd95b98SEric Kohl return FALSE;
909ccd95b98SEric Kohl }
910ccd95b98SEric Kohl
911ccd95b98SEric Kohl
912ccd95b98SEric Kohl static
913611e6d7dSEric Kohl DWORD
LocalToGmtHour(LONG lLocalHour,LONG lBias)914d0d7c5f0SEric Kohl LocalToGmtHour(
915d0d7c5f0SEric Kohl LONG lLocalHour,
916d0d7c5f0SEric Kohl LONG lBias)
917d0d7c5f0SEric Kohl {
918d0d7c5f0SEric Kohl LONG lGmtHour;
919d0d7c5f0SEric Kohl
920d0d7c5f0SEric Kohl lGmtHour = lLocalHour + lBias;
921d0d7c5f0SEric Kohl if (lGmtHour < 0)
922d0d7c5f0SEric Kohl lGmtHour += UNITS_PER_WEEK;
923d0d7c5f0SEric Kohl else if (lGmtHour > UNITS_PER_WEEK)
924d0d7c5f0SEric Kohl lGmtHour -= UNITS_PER_WEEK;
925d0d7c5f0SEric Kohl
926d0d7c5f0SEric Kohl return (DWORD)lGmtHour;
927d0d7c5f0SEric Kohl }
928d0d7c5f0SEric Kohl
929d0d7c5f0SEric Kohl
930d0d7c5f0SEric Kohl static
931d0d7c5f0SEric Kohl DWORD
ParseLogonHours(PWSTR pszParams,PBYTE * ppLogonBitmap,PDWORD pdwUnitsPerWeek)932611e6d7dSEric Kohl ParseLogonHours(
933611e6d7dSEric Kohl PWSTR pszParams,
934ccd95b98SEric Kohl PBYTE *ppLogonBitmap,
935611e6d7dSEric Kohl PDWORD pdwUnitsPerWeek)
936611e6d7dSEric Kohl {
937e5b635edSEric Kohl TIME_ZONE_INFORMATION TimeZoneInformation;
938ccd95b98SEric Kohl PBYTE pLogonBitmap = NULL;
939611e6d7dSEric Kohl DWORD dwError = ERROR_SUCCESS;
940ccd95b98SEric Kohl WCHAR szBuffer[32];
941ccd95b98SEric Kohl PWSTR ptr1, ptr2;
942ccd95b98SEric Kohl WCHAR prevSep, nextSep;
943e5b635edSEric Kohl DWORD dwStartDay, dwEndDay, i, j;
944e5b635edSEric Kohl LONG lStartHour, lEndHour, lBias;
945ccd95b98SEric Kohl BYTE DayBitmap;
946ccd95b98SEric Kohl BYTE HourBitmap[6];
947df31f870SEric Kohl LPWSTR ShortDays[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
948df31f870SEric Kohl LPWSTR LongDays[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
949df31f870SEric Kohl LPWSTR AmPmArray[4] = {NULL, NULL, NULL, NULL};
950611e6d7dSEric Kohl
951e5b635edSEric Kohl GetTimeZoneInformation(&TimeZoneInformation);
952e5b635edSEric Kohl lBias = TimeZoneInformation.Bias / 60;
953e5b635edSEric Kohl
954ccd95b98SEric Kohl pLogonBitmap = HeapAlloc(GetProcessHeap(),
955611e6d7dSEric Kohl HEAP_ZERO_MEMORY,
956611e6d7dSEric Kohl UNITS_PER_WEEK / 8);
957ccd95b98SEric Kohl if (pLogonBitmap == NULL)
958611e6d7dSEric Kohl return ERROR_OUTOFMEMORY;
959611e6d7dSEric Kohl
960611e6d7dSEric Kohl if (*pszParams == UNICODE_NULL)
961611e6d7dSEric Kohl {
962611e6d7dSEric Kohl goto done;
963611e6d7dSEric Kohl }
964611e6d7dSEric Kohl
965*e4930be4STimo Kreuzer if (_wcsicmp(pszParams, L"all") == 0)
966611e6d7dSEric Kohl {
967ccd95b98SEric Kohl FillMemory(pLogonBitmap, UNITS_PER_WEEK / 8, 0xFF);
968611e6d7dSEric Kohl goto done;
969611e6d7dSEric Kohl }
970611e6d7dSEric Kohl
971df31f870SEric Kohl for (i = 0; i < 7; i++)
972df31f870SEric Kohl {
973df31f870SEric Kohl FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
974df31f870SEric Kohl FORMAT_MESSAGE_FROM_HMODULE |
975df31f870SEric Kohl FORMAT_MESSAGE_IGNORE_INSERTS,
976df31f870SEric Kohl hModuleNetMsg,
977df31f870SEric Kohl 4314 + i,
978df31f870SEric Kohl LANG_USER_DEFAULT,
979df31f870SEric Kohl (LPWSTR)&ShortDays[i],
980df31f870SEric Kohl 0,
981df31f870SEric Kohl NULL);
982df31f870SEric Kohl
983df31f870SEric Kohl FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
984df31f870SEric Kohl FORMAT_MESSAGE_FROM_HMODULE |
985df31f870SEric Kohl FORMAT_MESSAGE_IGNORE_INSERTS,
986df31f870SEric Kohl hModuleNetMsg,
987df31f870SEric Kohl 4307 + i,
988df31f870SEric Kohl LANG_USER_DEFAULT,
989df31f870SEric Kohl (LPWSTR)&LongDays[i],
990df31f870SEric Kohl 0,
991df31f870SEric Kohl NULL);
992df31f870SEric Kohl }
993df31f870SEric Kohl
994df31f870SEric Kohl for (i = 0; i < 4; i++)
995df31f870SEric Kohl {
996df31f870SEric Kohl FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
997df31f870SEric Kohl FORMAT_MESSAGE_FROM_HMODULE |
998df31f870SEric Kohl FORMAT_MESSAGE_IGNORE_INSERTS,
999df31f870SEric Kohl hModuleNetMsg,
1000df31f870SEric Kohl 4322 + i,
1001df31f870SEric Kohl LANG_USER_DEFAULT,
1002df31f870SEric Kohl (LPWSTR)&AmPmArray[i],
1003df31f870SEric Kohl 0,
1004df31f870SEric Kohl NULL);
1005df31f870SEric Kohl }
1006df31f870SEric Kohl
1007ccd95b98SEric Kohl ZeroMemory(&DayBitmap, sizeof(DayBitmap));
1008ccd95b98SEric Kohl ZeroMemory(HourBitmap, sizeof(HourBitmap));
1009ccd95b98SEric Kohl
1010ccd95b98SEric Kohl ZeroMemory(szBuffer, sizeof(szBuffer));
1011ccd95b98SEric Kohl ptr1 = pszParams;
1012ccd95b98SEric Kohl ptr2 = szBuffer;
1013ccd95b98SEric Kohl prevSep = UNICODE_NULL;
1014ccd95b98SEric Kohl nextSep = UNICODE_NULL;
1015ccd95b98SEric Kohl for (;;)
1016ccd95b98SEric Kohl {
1017ccd95b98SEric Kohl if (*ptr1 != L'-' && *ptr1 != L',' && *ptr1 != L';' && *ptr1 != UNICODE_NULL)
1018ccd95b98SEric Kohl {
1019ccd95b98SEric Kohl *ptr2 = *ptr1;
1020ccd95b98SEric Kohl ptr2++;
1021ccd95b98SEric Kohl }
1022ccd95b98SEric Kohl else
1023ccd95b98SEric Kohl {
1024ccd95b98SEric Kohl prevSep = nextSep;
1025ccd95b98SEric Kohl nextSep = *ptr1;
1026ccd95b98SEric Kohl
1027ccd95b98SEric Kohl if (prevSep != L'-')
1028ccd95b98SEric Kohl {
1029e5b635edSEric Kohl /* Set first value */
1030ccd95b98SEric Kohl if (iswdigit(szBuffer[0]))
1031ccd95b98SEric Kohl {
1032e5b635edSEric Kohl /* Parse hour */
1033df31f870SEric Kohl if (!ParseHour(szBuffer, AmPmArray, &lStartHour))
1034ccd95b98SEric Kohl {
1035ccd95b98SEric Kohl dwError = 3769;
1036ccd95b98SEric Kohl break;
1037ccd95b98SEric Kohl }
1038ccd95b98SEric Kohl
1039d0d7c5f0SEric Kohl SetBitValue(HourBitmap, LocalToGmtHour(lStartHour, lBias));
1040ccd95b98SEric Kohl }
1041ccd95b98SEric Kohl else
1042ccd95b98SEric Kohl {
1043e5b635edSEric Kohl /* Parse day */
1044df31f870SEric Kohl if (!ParseDay(szBuffer, ShortDays, LongDays, &dwStartDay))
1045ccd95b98SEric Kohl {
1046611e6d7dSEric Kohl dwError = 3768;
1047ccd95b98SEric Kohl break;
1048ccd95b98SEric Kohl }
1049ccd95b98SEric Kohl
1050ccd95b98SEric Kohl SetBitValue(&DayBitmap, dwStartDay);
1051ccd95b98SEric Kohl }
1052ccd95b98SEric Kohl }
1053ccd95b98SEric Kohl else
1054ccd95b98SEric Kohl {
1055e5b635edSEric Kohl /* Set second value */
1056ccd95b98SEric Kohl if (iswdigit(szBuffer[0]))
1057ccd95b98SEric Kohl {
1058e5b635edSEric Kohl /* Parse hour */
1059df31f870SEric Kohl if (!ParseHour(szBuffer, AmPmArray, &lEndHour))
1060ccd95b98SEric Kohl {
1061ccd95b98SEric Kohl dwError = 3769;
1062ccd95b98SEric Kohl break;
1063ccd95b98SEric Kohl }
1064ccd95b98SEric Kohl
1065d0d7c5f0SEric Kohl if (lEndHour <= lStartHour)
1066e5b635edSEric Kohl lEndHour += HOURS_PER_DAY;
1067ccd95b98SEric Kohl
1068d0d7c5f0SEric Kohl for (i = LocalToGmtHour(lStartHour, lBias); i < LocalToGmtHour(lEndHour, lBias); i++)
1069ccd95b98SEric Kohl SetBitValue(HourBitmap, i);
1070ccd95b98SEric Kohl }
1071ccd95b98SEric Kohl else
1072ccd95b98SEric Kohl {
1073e5b635edSEric Kohl /* Parse day */
1074df31f870SEric Kohl if (!ParseDay(szBuffer, ShortDays, LongDays, &dwEndDay))
1075ccd95b98SEric Kohl {
1076ccd95b98SEric Kohl dwError = 3768;
1077ccd95b98SEric Kohl break;
1078ccd95b98SEric Kohl }
1079ccd95b98SEric Kohl
1080ccd95b98SEric Kohl if (dwEndDay <= dwStartDay)
1081ccd95b98SEric Kohl dwEndDay += DAYS_PER_WEEK;
1082ccd95b98SEric Kohl
1083ccd95b98SEric Kohl for (i = dwStartDay; i <= dwEndDay; i++)
1084ccd95b98SEric Kohl SetBitValue(&DayBitmap, i % DAYS_PER_WEEK);
1085ccd95b98SEric Kohl }
1086ccd95b98SEric Kohl }
1087ccd95b98SEric Kohl
1088ccd95b98SEric Kohl if (*ptr1 == L';' || *ptr1 == UNICODE_NULL)
1089ccd95b98SEric Kohl {
1090e5b635edSEric Kohl /* Fill the logon hour bitmap */
1091ccd95b98SEric Kohl for (i = 0; i < DAYS_PER_WEEK; i++)
1092ccd95b98SEric Kohl {
1093ccd95b98SEric Kohl if (GetBitValue(&DayBitmap, i))
1094ccd95b98SEric Kohl {
1095ccd95b98SEric Kohl for (j = 0; j < 48; j++)
1096ccd95b98SEric Kohl {
1097ccd95b98SEric Kohl if (GetBitValue(HourBitmap, j))
1098ccd95b98SEric Kohl SetBitValue(pLogonBitmap, ((i * HOURS_PER_DAY) + j) % UNITS_PER_WEEK);
1099ccd95b98SEric Kohl }
1100ccd95b98SEric Kohl }
1101ccd95b98SEric Kohl }
1102ccd95b98SEric Kohl
1103e5b635edSEric Kohl /* Reset the Bitmaps */
1104ccd95b98SEric Kohl ZeroMemory(&DayBitmap, sizeof(DayBitmap));
1105ccd95b98SEric Kohl ZeroMemory(HourBitmap, sizeof(HourBitmap));
1106ccd95b98SEric Kohl }
1107ccd95b98SEric Kohl
1108ccd95b98SEric Kohl if (*ptr1 == UNICODE_NULL)
1109ccd95b98SEric Kohl break;
1110ccd95b98SEric Kohl
1111ccd95b98SEric Kohl ZeroMemory(szBuffer, sizeof(szBuffer));
1112ccd95b98SEric Kohl ptr2 = szBuffer;
1113ccd95b98SEric Kohl }
1114ccd95b98SEric Kohl
1115ccd95b98SEric Kohl ptr1++;
1116ccd95b98SEric Kohl }
1117ccd95b98SEric Kohl
1118611e6d7dSEric Kohl done:
1119df31f870SEric Kohl for (i = 0; i < 7; i++)
1120df31f870SEric Kohl {
1121df31f870SEric Kohl LocalFree(ShortDays[i]);
1122df31f870SEric Kohl LocalFree(LongDays[i]);
1123df31f870SEric Kohl }
1124df31f870SEric Kohl
1125df31f870SEric Kohl for (i = 0; i < 4; i++)
1126df31f870SEric Kohl {
1127df31f870SEric Kohl LocalFree(AmPmArray[i]);
1128df31f870SEric Kohl }
1129df31f870SEric Kohl
1130611e6d7dSEric Kohl if (dwError == ERROR_SUCCESS)
1131611e6d7dSEric Kohl {
1132ccd95b98SEric Kohl *ppLogonBitmap = pLogonBitmap;
1133611e6d7dSEric Kohl *pdwUnitsPerWeek = UNITS_PER_WEEK;
1134611e6d7dSEric Kohl }
1135611e6d7dSEric Kohl else
1136611e6d7dSEric Kohl {
1137ccd95b98SEric Kohl if (pLogonBitmap != NULL)
1138ccd95b98SEric Kohl HeapFree(GetProcessHeap(), 0, pLogonBitmap);
1139ccd95b98SEric Kohl *ppLogonBitmap = NULL;
1140ccd95b98SEric Kohl *pdwUnitsPerWeek = 0;
1141611e6d7dSEric Kohl }
1142611e6d7dSEric Kohl
1143611e6d7dSEric Kohl return dwError;
1144611e6d7dSEric Kohl }
1145611e6d7dSEric Kohl
1146611e6d7dSEric Kohl
1147c2c66affSColin Finck INT
cmdUser(INT argc,WCHAR ** argv)1148c2c66affSColin Finck cmdUser(
1149c2c66affSColin Finck INT argc,
1150c2c66affSColin Finck WCHAR **argv)
1151c2c66affSColin Finck {
1152c2c66affSColin Finck INT i, j;
1153c2c66affSColin Finck INT result = 0;
1154c2c66affSColin Finck BOOL bAdd = FALSE;
1155c2c66affSColin Finck BOOL bDelete = FALSE;
1156c2c66affSColin Finck #if 0
1157c2c66affSColin Finck BOOL bDomain = FALSE;
1158c2c66affSColin Finck #endif
1159b4969dc0SEric Kohl BOOL bRandomPassword = FALSE;
1160c2c66affSColin Finck LPWSTR lpUserName = NULL;
1161c2c66affSColin Finck LPWSTR lpPassword = NULL;
1162c2c66affSColin Finck PUSER_INFO_4 pUserInfo = NULL;
1163c2c66affSColin Finck USER_INFO_4 UserInfo;
1164add1be24SEric Kohl LPWSTR pWorkstations = NULL;
1165c2c66affSColin Finck LPWSTR p;
1166c2c66affSColin Finck LPWSTR endptr;
1167c2c66affSColin Finck DWORD value;
1168c2c66affSColin Finck BOOL bPasswordAllocated = FALSE;
1169611e6d7dSEric Kohl PBYTE pLogonHours = NULL;
1170611e6d7dSEric Kohl DWORD dwUnitsPerWeek;
1171c2c66affSColin Finck NET_API_STATUS Status;
1172c2c66affSColin Finck
1173c2c66affSColin Finck i = 2;
11744d8859cfSEric Kohl if ((i < argc) && (argv[i][0] != L'/'))
1175c2c66affSColin Finck {
1176c2c66affSColin Finck lpUserName = argv[i];
1177c2c66affSColin Finck // ConPrintf(StdOut, L"User: %s\n", lpUserName);
1178c2c66affSColin Finck i++;
1179c2c66affSColin Finck }
1180c2c66affSColin Finck
11814d8859cfSEric Kohl if ((i < argc) && (argv[i][0] != L'/'))
1182c2c66affSColin Finck {
1183c2c66affSColin Finck lpPassword = argv[i];
1184c2c66affSColin Finck // ConPrintf(StdOut, L"Password: %s\n", lpPassword);
1185c2c66affSColin Finck i++;
1186c2c66affSColin Finck }
1187c2c66affSColin Finck
1188c2c66affSColin Finck for (j = i; j < argc; j++)
1189c2c66affSColin Finck {
1190c2c66affSColin Finck if (_wcsicmp(argv[j], L"/help") == 0)
1191c2c66affSColin Finck {
11924e28e654SEric Kohl PrintNetMessage(MSG_USER_HELP);
1193c2c66affSColin Finck return 0;
1194c2c66affSColin Finck }
1195c2c66affSColin Finck else if (_wcsicmp(argv[j], L"/add") == 0)
1196c2c66affSColin Finck {
1197c2c66affSColin Finck bAdd = TRUE;
1198c2c66affSColin Finck }
1199c2c66affSColin Finck else if (_wcsicmp(argv[j], L"/delete") == 0)
1200c2c66affSColin Finck {
1201c2c66affSColin Finck bDelete = TRUE;
1202c2c66affSColin Finck }
1203c2c66affSColin Finck else if (_wcsicmp(argv[j], L"/domain") == 0)
1204c2c66affSColin Finck {
120529bf2097SEric Kohl ConPuts(StdErr, L"The /DOMAIN option is not supported yet.\n");
1206c2c66affSColin Finck #if 0
1207c2c66affSColin Finck bDomain = TRUE;
1208c2c66affSColin Finck #endif
1209c2c66affSColin Finck }
1210b4969dc0SEric Kohl else if (_wcsicmp(argv[j], L"/random") == 0)
1211b4969dc0SEric Kohl {
1212b4969dc0SEric Kohl bRandomPassword = TRUE;
1213b4969dc0SEric Kohl GenerateRandomPassword(&lpPassword,
1214b4969dc0SEric Kohl &bPasswordAllocated);
1215b4969dc0SEric Kohl }
1216c2c66affSColin Finck }
1217c2c66affSColin Finck
12184e28e654SEric Kohl if (lpUserName == NULL && lpPassword == NULL)
12194e28e654SEric Kohl {
12204e28e654SEric Kohl Status = EnumerateUsers();
1221073607c2SMarat Nagayev PrintMessageString(TranslateAppMessage(Status));
12224e28e654SEric Kohl return 0;
12234e28e654SEric Kohl }
1224611e6d7dSEric Kohl else if (lpUserName != NULL && lpPassword == NULL && argc == 3)
12254e28e654SEric Kohl {
12264e28e654SEric Kohl Status = DisplayUser(lpUserName);
1227073607c2SMarat Nagayev PrintMessageString(TranslateAppMessage(Status));
12284e28e654SEric Kohl return 0;
12294e28e654SEric Kohl }
12304e28e654SEric Kohl
1231c2c66affSColin Finck if (bAdd && bDelete)
1232c2c66affSColin Finck {
1233c2c66affSColin Finck result = 1;
1234c2c66affSColin Finck goto done;
1235c2c66affSColin Finck }
1236c2c66affSColin Finck
1237c2c66affSColin Finck /* Interactive password input */
1238c2c66affSColin Finck if (lpPassword != NULL && wcscmp(lpPassword, L"*") == 0)
1239c2c66affSColin Finck {
1240c2c66affSColin Finck ReadPassword(&lpPassword,
1241c2c66affSColin Finck &bPasswordAllocated);
1242c2c66affSColin Finck }
1243c2c66affSColin Finck
1244c2c66affSColin Finck if (!bAdd && !bDelete)
1245c2c66affSColin Finck {
1246c2c66affSColin Finck /* Modify the user */
1247c2c66affSColin Finck Status = NetUserGetInfo(NULL,
1248c2c66affSColin Finck lpUserName,
1249c2c66affSColin Finck 4,
1250c2c66affSColin Finck (LPBYTE*)&pUserInfo);
1251c2c66affSColin Finck if (Status != NERR_Success)
1252c2c66affSColin Finck {
1253073607c2SMarat Nagayev PrintMessageString(TranslateAppMessage(Status));
1254c2c66affSColin Finck result = 1;
1255c2c66affSColin Finck goto done;
1256c2c66affSColin Finck }
1257c2c66affSColin Finck }
1258073607c2SMarat Nagayev else if (bAdd)
1259c2c66affSColin Finck {
1260c2c66affSColin Finck /* Add the user */
1261c2c66affSColin Finck ZeroMemory(&UserInfo, sizeof(USER_INFO_4));
1262c2c66affSColin Finck
1263c2c66affSColin Finck UserInfo.usri4_name = lpUserName;
1264c2c66affSColin Finck UserInfo.usri4_password = lpPassword;
1265c2c66affSColin Finck UserInfo.usri4_flags = UF_SCRIPT | UF_NORMAL_ACCOUNT;
12668f63c209SEric Kohl UserInfo.usri4_acct_expires = TIMEQ_FOREVER;
12674bbbc408SEric Kohl UserInfo.usri4_primary_group_id = DOMAIN_GROUP_RID_USERS;
1268c2c66affSColin Finck
1269c2c66affSColin Finck pUserInfo = &UserInfo;
1270c2c66affSColin Finck }
1271c2c66affSColin Finck
1272c2c66affSColin Finck for (j = i; j < argc; j++)
1273c2c66affSColin Finck {
1274c2c66affSColin Finck if (_wcsnicmp(argv[j], L"/active:", 8) == 0)
1275c2c66affSColin Finck {
1276c2c66affSColin Finck p = &argv[i][8];
1277c2c66affSColin Finck if (_wcsicmp(p, L"yes") == 0)
1278c2c66affSColin Finck {
1279c2c66affSColin Finck pUserInfo->usri4_flags &= ~UF_ACCOUNTDISABLE;
1280c2c66affSColin Finck }
1281c2c66affSColin Finck else if (_wcsicmp(p, L"no") == 0)
1282c2c66affSColin Finck {
1283c2c66affSColin Finck pUserInfo->usri4_flags |= UF_ACCOUNTDISABLE;
1284c2c66affSColin Finck }
1285c2c66affSColin Finck else
1286c2c66affSColin Finck {
128729bf2097SEric Kohl PrintMessageStringV(3952, L"/ACTIVE");
1288c2c66affSColin Finck result = 1;
1289c2c66affSColin Finck goto done;
1290c2c66affSColin Finck }
1291c2c66affSColin Finck }
1292c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/comment:", 9) == 0)
1293c2c66affSColin Finck {
1294c2c66affSColin Finck pUserInfo->usri4_comment = &argv[j][9];
1295c2c66affSColin Finck }
1296c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/countrycode:", 13) == 0)
1297c2c66affSColin Finck {
1298c2c66affSColin Finck p = &argv[i][13];
1299c2c66affSColin Finck value = wcstoul(p, &endptr, 10);
1300c2c66affSColin Finck if (*endptr != 0)
1301c2c66affSColin Finck {
130229bf2097SEric Kohl PrintMessageStringV(3952, L"/COUNTRYCODE");
1303c2c66affSColin Finck result = 1;
1304c2c66affSColin Finck goto done;
1305c2c66affSColin Finck }
1306c2c66affSColin Finck
130708d30403SEric Kohl /* Verify the country code */
130808d30403SEric Kohl if (GetCountryFromCountryCode(value, 0, NULL))
1309c2c66affSColin Finck pUserInfo->usri4_country_code = value;
1310c2c66affSColin Finck }
1311c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/expires:", 9) == 0)
1312c2c66affSColin Finck {
1313c2c66affSColin Finck p = &argv[i][9];
1314c2c66affSColin Finck if (_wcsicmp(p, L"never") == 0)
1315c2c66affSColin Finck {
1316c2c66affSColin Finck pUserInfo->usri4_acct_expires = TIMEQ_FOREVER;
1317c2c66affSColin Finck }
1318bf76e1bfSEric Kohl else if (!ParseDate(p, &pUserInfo->usri4_acct_expires))
1319c2c66affSColin Finck {
132029bf2097SEric Kohl PrintMessageStringV(3952, L"/EXPIRES");
1321bf76e1bfSEric Kohl result = 1;
1322bf76e1bfSEric Kohl goto done;
1323c2c66affSColin Finck }
1324c2c66affSColin Finck }
1325c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/fullname:", 10) == 0)
1326c2c66affSColin Finck {
1327c2c66affSColin Finck pUserInfo->usri4_full_name = &argv[j][10];
1328c2c66affSColin Finck }
1329c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/homedir:", 9) == 0)
1330c2c66affSColin Finck {
1331c2c66affSColin Finck pUserInfo->usri4_home_dir = &argv[j][9];
1332c2c66affSColin Finck }
1333c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/passwordchg:", 13) == 0)
1334c2c66affSColin Finck {
1335c2c66affSColin Finck p = &argv[i][13];
1336c2c66affSColin Finck if (_wcsicmp(p, L"yes") == 0)
1337c2c66affSColin Finck {
1338c2c66affSColin Finck pUserInfo->usri4_flags &= ~UF_PASSWD_CANT_CHANGE;
1339c2c66affSColin Finck }
1340c2c66affSColin Finck else if (_wcsicmp(p, L"no") == 0)
1341c2c66affSColin Finck {
1342c2c66affSColin Finck pUserInfo->usri4_flags |= UF_PASSWD_CANT_CHANGE;
1343c2c66affSColin Finck }
1344c2c66affSColin Finck else
1345c2c66affSColin Finck {
134629bf2097SEric Kohl PrintMessageStringV(3952, L"/PASSWORDCHG");
1347c2c66affSColin Finck result = 1;
1348c2c66affSColin Finck goto done;
1349c2c66affSColin Finck }
1350c2c66affSColin Finck }
1351c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/passwordreq:", 13) == 0)
1352c2c66affSColin Finck {
1353c2c66affSColin Finck p = &argv[i][13];
1354c2c66affSColin Finck if (_wcsicmp(p, L"yes") == 0)
1355c2c66affSColin Finck {
1356c2c66affSColin Finck pUserInfo->usri4_flags &= ~UF_PASSWD_NOTREQD;
1357c2c66affSColin Finck }
1358c2c66affSColin Finck else if (_wcsicmp(p, L"no") == 0)
1359c2c66affSColin Finck {
1360c2c66affSColin Finck pUserInfo->usri4_flags |= UF_PASSWD_NOTREQD;
1361c2c66affSColin Finck }
1362c2c66affSColin Finck else
1363c2c66affSColin Finck {
136429bf2097SEric Kohl PrintMessageStringV(3952, L"/PASSWORDREQ");
1365c2c66affSColin Finck result = 1;
1366c2c66affSColin Finck goto done;
1367c2c66affSColin Finck }
1368c2c66affSColin Finck }
1369c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/profilepath:", 13) == 0)
1370c2c66affSColin Finck {
1371c2c66affSColin Finck pUserInfo->usri4_profile = &argv[j][13];
1372c2c66affSColin Finck }
1373c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/scriptpath:", 12) == 0)
1374c2c66affSColin Finck {
1375c2c66affSColin Finck pUserInfo->usri4_script_path = &argv[j][12];
1376c2c66affSColin Finck }
1377c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/times:", 7) == 0)
1378c2c66affSColin Finck {
1379611e6d7dSEric Kohl Status = ParseLogonHours(&argv[j][7],
1380611e6d7dSEric Kohl &pLogonHours,
1381611e6d7dSEric Kohl &dwUnitsPerWeek);
1382611e6d7dSEric Kohl if (Status == ERROR_SUCCESS)
1383611e6d7dSEric Kohl {
1384611e6d7dSEric Kohl pUserInfo->usri4_logon_hours = pLogonHours;
1385611e6d7dSEric Kohl pUserInfo->usri4_units_per_week = dwUnitsPerWeek;
1386611e6d7dSEric Kohl }
1387611e6d7dSEric Kohl else
1388611e6d7dSEric Kohl {
1389611e6d7dSEric Kohl PrintMessageString(Status);
1390611e6d7dSEric Kohl goto done;
1391611e6d7dSEric Kohl }
1392c2c66affSColin Finck }
1393c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/usercomment:", 13) == 0)
1394c2c66affSColin Finck {
1395c2c66affSColin Finck pUserInfo->usri4_usr_comment = &argv[j][13];
1396c2c66affSColin Finck }
1397c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/workstations:", 14) == 0)
1398c2c66affSColin Finck {
1399add1be24SEric Kohl p = &argv[i][14];
1400add1be24SEric Kohl if (wcscmp(p, L"*") == 0 || wcscmp(p, L"") == 0)
1401add1be24SEric Kohl {
1402add1be24SEric Kohl pUserInfo->usri4_workstations = NULL;
1403add1be24SEric Kohl }
1404add1be24SEric Kohl else
1405add1be24SEric Kohl {
1406add1be24SEric Kohl Status = BuildWorkstationsList(&pWorkstations, p);
1407add1be24SEric Kohl if (Status == NERR_Success)
1408add1be24SEric Kohl {
1409add1be24SEric Kohl pUserInfo->usri4_workstations = pWorkstations;
1410add1be24SEric Kohl }
1411add1be24SEric Kohl else
1412add1be24SEric Kohl {
1413073607c2SMarat Nagayev PrintMessageString(TranslateAppMessage(Status));
1414add1be24SEric Kohl result = 1;
1415add1be24SEric Kohl goto done;
1416add1be24SEric Kohl }
1417add1be24SEric Kohl }
1418c2c66affSColin Finck }
1419c2c66affSColin Finck }
1420c2c66affSColin Finck
1421c2c66affSColin Finck if (!bAdd && !bDelete)
1422c2c66affSColin Finck {
1423c2c66affSColin Finck /* Modify the user */
1424c2c66affSColin Finck Status = NetUserSetInfo(NULL,
1425c2c66affSColin Finck lpUserName,
1426c2c66affSColin Finck 4,
1427c2c66affSColin Finck (LPBYTE)pUserInfo,
1428c2c66affSColin Finck NULL);
1429c2c66affSColin Finck }
1430073607c2SMarat Nagayev else if (bAdd)
1431c2c66affSColin Finck {
1432c2c66affSColin Finck /* Add the user */
1433c2c66affSColin Finck Status = NetUserAdd(NULL,
1434c2c66affSColin Finck 4,
1435c2c66affSColin Finck (LPBYTE)pUserInfo,
1436c2c66affSColin Finck NULL);
1437c2c66affSColin Finck }
1438073607c2SMarat Nagayev else if (bDelete)
1439c2c66affSColin Finck {
1440c2c66affSColin Finck /* Delete the user */
1441c2c66affSColin Finck Status = NetUserDel(NULL,
1442c2c66affSColin Finck lpUserName);
1443c2c66affSColin Finck }
1444c2c66affSColin Finck
1445073607c2SMarat Nagayev PrintMessageString(TranslateAppMessage(Status));
1446073607c2SMarat Nagayev
1447b4969dc0SEric Kohl if (Status == NERR_Success &&
1448b4969dc0SEric Kohl lpPassword != NULL &&
1449b4969dc0SEric Kohl bRandomPassword == TRUE)
1450b4969dc0SEric Kohl {
14515563525aSEric Kohl PrintMessageStringV(3968, lpUserName, lpPassword);
1452b4969dc0SEric Kohl }
1453b4969dc0SEric Kohl
1454c2c66affSColin Finck done:
1455611e6d7dSEric Kohl if (pLogonHours != NULL)
1456611e6d7dSEric Kohl HeapFree(GetProcessHeap(), 0, pLogonHours);
1457611e6d7dSEric Kohl
1458add1be24SEric Kohl if (pWorkstations != NULL)
1459add1be24SEric Kohl HeapFree(GetProcessHeap(), 0, pWorkstations);
1460add1be24SEric Kohl
1461506bd64eSEric Kohl if ((bPasswordAllocated == TRUE) && (lpPassword != NULL))
1462c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, lpPassword);
1463c2c66affSColin Finck
1464c2c66affSColin Finck if (!bAdd && !bDelete && pUserInfo != NULL)
1465c2c66affSColin Finck NetApiBufferFree(pUserInfo);
1466c2c66affSColin Finck
1467c2c66affSColin Finck if (result != 0)
1468480cd1e6SEric Kohl {
146929bf2097SEric Kohl PrintMessageString(4381);
147029bf2097SEric Kohl ConPuts(StdOut, L"\n");
14714e28e654SEric Kohl PrintNetMessage(MSG_USER_SYNTAX);
1472480cd1e6SEric Kohl }
1473c2c66affSColin Finck
1474c2c66affSColin Finck return result;
1475c2c66affSColin Finck }
1476c2c66affSColin Finck
1477c2c66affSColin Finck /* EOF */
1478