reactos/base/applications/network/net/cmdUser.c
2019-05-28 17:23:43 +02:00

1478 lines
37 KiB
C

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS net command
* FILE: base/applications/network/net/cmdUser.c
* PURPOSE:
*
* PROGRAMMERS: Eric Kohl
* Curtis Wilson
*/
#include "net.h"
#define SECONDS_PER_DAY (60 * 60 * 24)
#define SECONDS_PER_HOUR (60 * 60)
#define HOURS_PER_DAY 24
#define DAYS_PER_WEEK 7
typedef struct _COUNTY_TABLE
{
DWORD dwCountryCode;
DWORD dwMessageId;
} COUNTRY_TABLE, *PCOUNTRY_TABLE;
static WCHAR szPasswordChars[] = L"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@#$%_-+:";
static COUNTRY_TABLE CountryTable[] =
{ { 0, 5080}, // System Default
{ 1, 5081}, // United States
{ 2, 5082}, // Canada (French)
{ 3, 5083}, // Latin America
{ 31, 5084}, // Netherlands
{ 32, 5085}, // Belgium
{ 33, 5086}, // France
{ 34, 5090}, // Spain
{ 39, 5087}, // Italy
{ 41, 5088}, // Switzerland
{ 44, 5089}, // United Kingdom
{ 45, 5091}, // Denmark
{ 46, 5092}, // Sweden
{ 47, 5093}, // Norway
{ 49, 5094}, // Germany
{ 61, 5095}, // Australia
{ 81, 5096}, // Japan
{ 82, 5097}, // Korea
{ 86, 5098}, // China (PRC)
{ 88, 5099}, // Taiwan
{ 99, 5100}, // Asia
{351, 5101}, // Portugal
{358, 5102}, // Finland
{785, 5103}, // Arabic
{972, 5104} }; // Hebrew
static
int
CompareInfo(const void *a, const void *b)
{
return _wcsicmp(((PUSER_INFO_0)a)->usri0_name,
((PUSER_INFO_0)b)->usri0_name);
}
static
NET_API_STATUS
EnumerateUsers(VOID)
{
PUSER_INFO_0 pBuffer = NULL;
PSERVER_INFO_100 pServer = NULL;
DWORD dwRead = 0, dwTotal = 0;
DWORD i;
DWORD ResumeHandle = 0;
NET_API_STATUS Status;
Status = NetServerGetInfo(NULL,
100,
(LPBYTE*)&pServer);
if (Status != NERR_Success)
return Status;
ConPuts(StdOut, L"\n");
PrintMessageStringV(4410, pServer->sv100_name);
ConPuts(StdOut, L"\n");
PrintPadding(L'-', 79);
ConPuts(StdOut, L"\n");
NetApiBufferFree(pServer);
do
{
Status = NetUserEnum(NULL,
0,
0,
(LPBYTE*)&pBuffer,
MAX_PREFERRED_LENGTH,
&dwRead,
&dwTotal,
&ResumeHandle);
if ((Status != NERR_Success) && (Status != ERROR_MORE_DATA))
return Status;
qsort(pBuffer,
dwRead,
sizeof(PUSER_INFO_0),
CompareInfo);
for (i = 0; i < dwRead; i++)
{
if (pBuffer[i].usri0_name)
ConPrintf(StdOut, L"%s\n", pBuffer[i].usri0_name);
}
NetApiBufferFree(pBuffer);
pBuffer = NULL;
}
while (Status == ERROR_MORE_DATA);
return NERR_Success;
}
static
VOID
PrintDateTime(DWORD dwSeconds)
{
LARGE_INTEGER Time;
FILETIME FileTime;
SYSTEMTIME SystemTime;
WCHAR DateBuffer[80];
WCHAR TimeBuffer[80];
RtlSecondsSince1970ToTime(dwSeconds, &Time);
FileTime.dwLowDateTime = Time.u.LowPart;
FileTime.dwHighDateTime = Time.u.HighPart;
FileTimeToLocalFileTime(&FileTime, &FileTime);
FileTimeToSystemTime(&FileTime, &SystemTime);
GetDateFormatW(LOCALE_USER_DEFAULT,
DATE_SHORTDATE,
&SystemTime,
NULL,
DateBuffer,
ARRAYSIZE(DateBuffer));
GetTimeFormatW(LOCALE_USER_DEFAULT,
TIME_NOSECONDS,
&SystemTime,
NULL,
TimeBuffer,
ARRAYSIZE(TimeBuffer));
ConPrintf(StdOut, L"%s %s", DateBuffer, TimeBuffer);
}
static
VOID
PrintLocalTime(DWORD dwSeconds)
{
LARGE_INTEGER Time;
FILETIME FileTime;
SYSTEMTIME SystemTime;
WCHAR TimeBuffer[80];
RtlSecondsSince1970ToTime(dwSeconds, &Time);
FileTime.dwLowDateTime = Time.u.LowPart;
FileTime.dwHighDateTime = Time.u.HighPart;
FileTimeToSystemTime(&FileTime, &SystemTime);
GetTimeFormatW(LOCALE_USER_DEFAULT,
TIME_NOSECONDS,
&SystemTime,
NULL,
TimeBuffer,
ARRAYSIZE(TimeBuffer));
ConPrintf(StdOut, L"%s", TimeBuffer);
}
static
DWORD
GetTimeInSeconds(VOID)
{
LARGE_INTEGER Time;
FILETIME FileTime;
DWORD dwSeconds;
GetSystemTimeAsFileTime(&FileTime);
Time.u.LowPart = FileTime.dwLowDateTime;
Time.u.HighPart = FileTime.dwHighDateTime;
RtlTimeToSecondsSince1970(&Time, &dwSeconds);
return dwSeconds;
}
static
BOOL
GetCountryFromCountryCode(
_In_ DWORD dwCountryCode,
_In_ DWORD dwCountryLength,
_Out_ PWSTR szCountryBuffer)
{
DWORD i;
for (i = 0; i < ARRAYSIZE(CountryTable); i++)
{
if (CountryTable[i].dwCountryCode == dwCountryCode)
{
if (szCountryBuffer != NULL && dwCountryLength > 0)
{
FormatMessageW(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS,
hModuleNetMsg,
CountryTable[i].dwMessageId,
LANG_USER_DEFAULT,
szCountryBuffer,
dwCountryLength,
NULL);
}
return TRUE;
}
}
return FALSE;
}
static
BOOL
GetBitValue(
PBYTE pBitmap,
DWORD dwBitNumber)
{
DWORD dwIndex = dwBitNumber / 8;
BYTE Mask = 1 << (dwBitNumber & 7);
return ((pBitmap[dwIndex] & Mask) != 0);
}
static
VOID
SetBitValue(
PBYTE pBitmap,
DWORD dwBitNumber)
{
DWORD dwIndex = dwBitNumber / 8;
BYTE Mask = 1 << (dwBitNumber & 7);
pBitmap[dwIndex] |= Mask;
}
static
VOID
PrintLogonHours(
DWORD dwUnitsPerWeek,
PBYTE pLogonHours,
INT nPaddedLength)
{
DWORD dwUnitsPerDay, dwBitNumber, dwSecondsPerUnit;
DWORD dwStartTime, dwEndTime, dwStartDay, dwEndDay, dwBias;
BOOL bBitValue, bFirst = TRUE;
TIME_ZONE_INFORMATION TimeZoneInformation;
GetTimeZoneInformation(&TimeZoneInformation);
dwBias = (TimeZoneInformation.Bias / 60) * SECONDS_PER_HOUR;
if ((dwUnitsPerWeek == 0) ||
((dwUnitsPerWeek %7) != 0))
return;
dwUnitsPerDay = dwUnitsPerWeek / 7;
if (((dwUnitsPerDay % 24) != 0) ||
((dwUnitsPerDay / 24) > 6))
return;
dwSecondsPerUnit = (SECONDS_PER_DAY) / dwUnitsPerDay;
for (dwBitNumber = 0; dwBitNumber < dwUnitsPerWeek; dwBitNumber++)
{
bBitValue = GetBitValue(pLogonHours, dwBitNumber);
if (bBitValue)
{
dwStartTime = dwSecondsPerUnit * dwBitNumber;
while (bBitValue != 0 && dwBitNumber < dwUnitsPerWeek)
{
dwBitNumber++;
if (dwBitNumber < dwUnitsPerWeek)
bBitValue = GetBitValue(pLogonHours, dwBitNumber);
}
dwEndTime = dwSecondsPerUnit * dwBitNumber;
if (!bFirst)
PrintPadding(L' ', nPaddedLength);
if (dwStartTime == 0 && dwEndTime == (SECONDS_PER_DAY * 7))
{
PrintMessageString(4302);
ConPuts(StdOut, L"\n");
}
else
{
dwStartDay = dwStartTime / SECONDS_PER_DAY;
dwEndDay = (dwEndTime / SECONDS_PER_DAY) % 7;
PrintMessageString(4307 + dwStartDay);
ConPuts(StdOut, L" ");
/* Convert from GMT to local timezone */
PrintLocalTime((dwStartTime % SECONDS_PER_DAY) - dwBias);
ConPrintf(StdOut, L" - ");
if (dwStartDay != dwEndDay)
{
PrintMessageString(4307 + dwEndDay);
ConPuts(StdOut, L" ");
}
/* Convert from GMT to local timezone */
PrintLocalTime((dwEndTime % SECONDS_PER_DAY) - dwBias);
ConPuts(StdOut, L"\n");
}
bFirst = FALSE;
}
}
if (bFirst)
{
/* No logon hours */
PrintMessageString(4434);
ConPuts(StdOut, L"\n");
}
}
static
NET_API_STATUS
DisplayUser(LPWSTR lpUserName)
{
PUSER_MODALS_INFO_0 pUserModals = NULL;
PUSER_INFO_4 pUserInfo = NULL;
PLOCALGROUP_USERS_INFO_0 pLocalGroupInfo = NULL;
PGROUP_USERS_INFO_0 pGroupInfo = NULL;
DWORD dwLocalGroupRead, dwLocalGroupTotal;
DWORD dwGroupRead, dwGroupTotal;
DWORD dwLastSet;
DWORD i;
WCHAR szCountry[40];
INT nPaddedLength = 36;
NET_API_STATUS Status;
/* Modify the user */
Status = NetUserGetInfo(NULL,
lpUserName,
4,
(LPBYTE*)&pUserInfo);
if (Status != NERR_Success)
return Status;
Status = NetUserModalsGet(NULL,
0,
(LPBYTE*)&pUserModals);
if (Status != NERR_Success)
goto done;
Status = NetUserGetLocalGroups(NULL,
lpUserName,
0,
0,
(LPBYTE*)&pLocalGroupInfo,
MAX_PREFERRED_LENGTH,
&dwLocalGroupRead,
&dwLocalGroupTotal);
if (Status != NERR_Success)
goto done;
Status = NetUserGetGroups(NULL,
lpUserName,
0,
(LPBYTE*)&pGroupInfo,
MAX_PREFERRED_LENGTH,
&dwGroupRead,
&dwGroupTotal);
if (Status != NERR_Success)
goto done;
PrintPaddedMessageString(4411, nPaddedLength);
ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_name);
PrintPaddedMessageString(4412, nPaddedLength);
ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_full_name);
PrintPaddedMessageString(4413, nPaddedLength);
ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_comment);
PrintPaddedMessageString(4414, nPaddedLength);
ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_usr_comment);
PrintPaddedMessageString(4416, nPaddedLength);
GetCountryFromCountryCode(pUserInfo->usri4_country_code,
ARRAYSIZE(szCountry), szCountry);
ConPrintf(StdOut, L"%03ld (%s)\n", pUserInfo->usri4_country_code, szCountry);
PrintPaddedMessageString(4419, nPaddedLength);
if (pUserInfo->usri4_flags & UF_ACCOUNTDISABLE)
PrintMessageString(4301);
else if (pUserInfo->usri4_flags & UF_LOCKOUT)
PrintMessageString(4440);
else
PrintMessageString(4300);
ConPuts(StdOut, L"\n");
PrintPaddedMessageString(4420, nPaddedLength);
if (pUserInfo->usri4_acct_expires == TIMEQ_FOREVER)
PrintMessageString(4305);
else
PrintDateTime(pUserInfo->usri4_acct_expires);
ConPuts(StdOut, L"\n\n");
PrintPaddedMessageString(4421, nPaddedLength);
dwLastSet = GetTimeInSeconds() - pUserInfo->usri4_password_age;
PrintDateTime(dwLastSet);
ConPuts(StdOut, L"\n");
PrintPaddedMessageString(4422, nPaddedLength);
if ((pUserInfo->usri4_flags & UF_DONT_EXPIRE_PASSWD) || pUserModals->usrmod0_max_passwd_age == TIMEQ_FOREVER)
PrintMessageString(4305);
else
PrintDateTime(dwLastSet + pUserModals->usrmod0_max_passwd_age);
ConPuts(StdOut, L"\n");
PrintPaddedMessageString(4423, nPaddedLength);
PrintDateTime(dwLastSet + pUserModals->usrmod0_min_passwd_age);
ConPuts(StdOut, L"\n");
PrintPaddedMessageString(4437, nPaddedLength);
PrintMessageString((pUserInfo->usri4_flags & UF_PASSWD_NOTREQD) ? 4301 : 4300);
ConPuts(StdOut, L"\n");
PrintPaddedMessageString(4438, nPaddedLength);
PrintMessageString((pUserInfo->usri4_flags & UF_PASSWD_CANT_CHANGE) ? 4301 : 4300);
ConPuts(StdOut, L"\n\n");
PrintPaddedMessageString(4424, nPaddedLength);
if (pUserInfo->usri4_workstations == NULL || wcslen(pUserInfo->usri4_workstations) == 0)
PrintMessageString(4302);
else
ConPrintf(StdOut, L"%s", pUserInfo->usri4_workstations);
ConPuts(StdOut, L"\n");
PrintPaddedMessageString(4429, nPaddedLength);
ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_script_path);
PrintPaddedMessageString(4439, nPaddedLength);
ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_profile);
PrintPaddedMessageString(4436, nPaddedLength);
ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_home_dir);
PrintPaddedMessageString(4430, nPaddedLength);
if (pUserInfo->usri4_last_logon == 0)
PrintMessageString(4305);
else
PrintDateTime(pUserInfo->usri4_last_logon);
ConPuts(StdOut, L"\n\n");
PrintPaddedMessageString(4432, nPaddedLength);
if (pUserInfo->usri4_logon_hours == NULL)
{
PrintMessageString(4302);
ConPuts(StdOut, L"\n");
}
else
{
PrintLogonHours(pUserInfo->usri4_units_per_week,
pUserInfo->usri4_logon_hours,
nPaddedLength);
}
ConPuts(StdOut, L"\n");
PrintPaddedMessageString(4427, nPaddedLength);
if (dwLocalGroupTotal != 0 && pLocalGroupInfo != NULL)
{
for (i = 0; i < dwLocalGroupTotal; i++)
{
if (i != 0)
PrintPadding(L' ', nPaddedLength);
ConPrintf(StdOut, L"*%s\n", pLocalGroupInfo[i].lgrui0_name);
}
}
else
{
ConPuts(StdOut, L"\n");
}
PrintPaddedMessageString(4431, nPaddedLength);
if (dwGroupTotal != 0 && pGroupInfo != NULL)
{
for (i = 0; i < dwGroupTotal; i++)
{
if (i != 0)
PrintPadding(L' ', nPaddedLength);
ConPrintf(StdOut, L"*%s\n", pGroupInfo[i].grui0_name);
}
}
else
{
ConPuts(StdOut, L"\n");
}
done:
if (pGroupInfo != NULL)
NetApiBufferFree(pGroupInfo);
if (pLocalGroupInfo != NULL)
NetApiBufferFree(pLocalGroupInfo);
if (pUserModals != NULL)
NetApiBufferFree(pUserModals);
if (pUserInfo != NULL)
NetApiBufferFree(pUserInfo);
return NERR_Success;
}
static
VOID
ReadPassword(
LPWSTR *lpPassword,
LPBOOL lpAllocated)
{
WCHAR szPassword1[PWLEN + 1];
WCHAR szPassword2[PWLEN + 1];
LPWSTR ptr;
*lpAllocated = FALSE;
while (TRUE)
{
PrintMessageString(4358);
ReadFromConsole(szPassword1, PWLEN + 1, FALSE);
ConPuts(StdOut, L"\n");
PrintMessageString(4361);
ReadFromConsole(szPassword2, PWLEN + 1, FALSE);
ConPuts(StdOut, L"\n");
if (wcslen(szPassword1) == wcslen(szPassword2) &&
wcscmp(szPassword1, szPassword2) == 0)
{
ptr = HeapAlloc(GetProcessHeap(),
0,
(wcslen(szPassword1) + 1) * sizeof(WCHAR));
if (ptr != NULL)
{
wcscpy(ptr, szPassword1);
*lpPassword = ptr;
*lpAllocated = TRUE;
return;
}
}
else
{
ConPuts(StdOut, L"\n");
PrintMessageString(3728);
*lpPassword = NULL;
}
}
}
static
VOID
GenerateRandomPassword(
LPWSTR *lpPassword,
LPBOOL lpAllocated)
{
LPWSTR pPassword = NULL;
INT nCharsLen, i, nLength = 8;
srand(GetTickCount());
pPassword = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
(nLength + 1) * sizeof(WCHAR));
if (pPassword == NULL)
return;
nCharsLen = wcslen(szPasswordChars);
for (i = 0; i < nLength; i++)
{
pPassword[i] = szPasswordChars[rand() % nCharsLen];
}
*lpPassword = pPassword;
*lpAllocated = TRUE;
}
static
NET_API_STATUS
BuildWorkstationsList(
_Out_ PWSTR *pWorkstationsList,
_In_ PWSTR pRaw)
{
BOOL isLastSep, isSep;
INT i, j;
WCHAR c;
INT nLength = 0;
INT nArgs = 0;
INT nRawLength;
PWSTR pList;
/* Check for invalid characters in the raw string */
if (wcspbrk(pRaw, L"/[]=?\\+:.") != NULL)
return 3952;
/* Count the number of workstations in the list and
* the required buffer size */
isLastSep = FALSE;
isSep = FALSE;
nRawLength = wcslen(pRaw);
for (i = 0; i < nRawLength; i++)
{
c = pRaw[i];
if (c == L',' || c == L';')
isSep = TRUE;
if (isSep == TRUE)
{
if ((isLastSep == FALSE) && (i != 0) && (i != nRawLength - 1))
nLength++;
}
else
{
nLength++;
if (isLastSep == TRUE || (isLastSep == FALSE && i == 0))
nArgs++;
}
isLastSep = isSep;
isSep = FALSE;
}
nLength++;
/* Leave, if there are no workstations in the list */
if (nArgs == 0)
{
pWorkstationsList = NULL;
return NERR_Success;
}
/* Fail if there are more than eight workstations in the list */
if (nArgs > 8)
return 3951;
/* Allocate the buffer for the clean workstation list */
pList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nLength * sizeof(WCHAR));
if (pList == NULL)
return ERROR_NOT_ENOUGH_MEMORY;
/* Build the clean workstation list */
isLastSep = FALSE;
isSep = FALSE;
nRawLength = wcslen(pRaw);
for (i = 0, j = 0; i < nRawLength; i++)
{
c = pRaw[i];
if (c == L',' || c == L';')
isSep = TRUE;
if (isSep == TRUE)
{
if ((isLastSep == FALSE) && (i != 0) && (i != nRawLength - 1))
{
pList[j] = L',';
j++;
}
}
else
{
pList[j] = c;
j++;
if (isLastSep == TRUE || (isLastSep == FALSE && i == 0))
nArgs++;
}
isLastSep = isSep;
isSep = FALSE;
}
*pWorkstationsList = pList;
return NERR_Success;
}
static
BOOL
ReadNumber(
PWSTR *s,
PWORD pwValue)
{
if (!iswdigit(**s))
return FALSE;
while (iswdigit(**s))
{
*pwValue = *pwValue * 10 + **s - L'0';
(*s)++;
}
return TRUE;
}
static
BOOL
ReadSeparator(
PWSTR *s)
{
if (**s == L'/' || **s == L'.')
{
(*s)++;
return TRUE;
}
return FALSE;
}
static
BOOL
ParseDate(
PWSTR s,
PULONG pSeconds)
{
SYSTEMTIME SystemTime = {0};
FILETIME LocalFileTime, FileTime;
LARGE_INTEGER Time;
INT nDateFormat = 0;
PWSTR p = s;
if (!*s)
return FALSE;
GetLocaleInfoW(LOCALE_USER_DEFAULT,
LOCALE_IDATE,
(PWSTR)&nDateFormat,
sizeof(INT));
switch (nDateFormat)
{
case 0: /* mmddyy */
default:
if (!ReadNumber(&p, &SystemTime.wMonth))
return FALSE;
if (!ReadSeparator(&p))
return FALSE;
if (!ReadNumber(&p, &SystemTime.wDay))
return FALSE;
if (!ReadSeparator(&p))
return FALSE;
if (!ReadNumber(&p, &SystemTime.wYear))
return FALSE;
break;
case 1: /* ddmmyy */
if (!ReadNumber(&p, &SystemTime.wDay))
return FALSE;
if (!ReadSeparator(&p))
return FALSE;
if (!ReadNumber(&p, &SystemTime.wMonth))
return FALSE;
if (!ReadSeparator(&p))
return FALSE;
if (!ReadNumber(&p, &SystemTime.wYear))
return FALSE;
break;
case 2: /* yymmdd */
if (!ReadNumber(&p, &SystemTime.wYear))
return FALSE;
if (!ReadSeparator(&p))
return FALSE;
if (!ReadNumber(&p, &SystemTime.wMonth))
return FALSE;
if (!ReadSeparator(&p))
return FALSE;
if (!ReadNumber(&p, &SystemTime.wDay))
return FALSE;
break;
}
/* if only entered two digits: */
/* assume 2000's if value less than 80 */
/* assume 1900's if value greater or equal 80 */
if (SystemTime.wYear <= 99)
{
if (SystemTime.wYear >= 80)
SystemTime.wYear += 1900;
else
SystemTime.wYear += 2000;
}
if (!SystemTimeToFileTime(&SystemTime, &LocalFileTime))
return FALSE;
if (!LocalFileTimeToFileTime(&LocalFileTime, &FileTime))
return FALSE;
Time.u.LowPart = FileTime.dwLowDateTime;
Time.u.HighPart = FileTime.dwHighDateTime;
if (!RtlTimeToSecondsSince1970(&Time, pSeconds))
return FALSE;
return TRUE;
}
static
BOOL
ParseHour(
PWSTR pszString,
PWSTR *AmPmArray,
PLONG plHour)
{
PWCHAR pChar;
LONG lHour = 0;
if (!iswdigit(pszString[0]))
return FALSE;
pChar = pszString;
while (iswdigit(*pChar))
{
lHour = lHour * 10 + *pChar - L'0';
pChar++;
}
if (lHour > 24)
return FALSE;
if (lHour == 24)
lHour = 0;
if ((*pChar != UNICODE_NULL) &&
(lHour >= 1) &&
(lHour <= 12))
{
if ((_wcsicmp(pChar, AmPmArray[0]) == 0) ||
(_wcsicmp(pChar, AmPmArray[1]) == 0))
{
if (lHour == 12)
lHour = 0;
}
else if ((_wcsicmp(pChar, AmPmArray[2]) == 0) ||
(_wcsicmp(pChar, AmPmArray[3]) == 0))
{
if (lHour != 12)
lHour += 12;
}
else
{
return FALSE;
}
}
*plHour = lHour;
return TRUE;
}
static
BOOL
ParseDay(
PWSTR pszString,
PWSTR *ShortDays,
PWSTR *LongDays,
PDWORD pdwDay)
{
DWORD i;
for (i = 0; i < 7; i++)
{
if (_wcsicmp(pszString, ShortDays[i]) == 0 ||
_wcsicmp(pszString, LongDays[i]) == 0)
{
*pdwDay = i;
return TRUE;
}
}
return FALSE;
}
static
DWORD
LocalToGmtHour(
LONG lLocalHour,
LONG lBias)
{
LONG lGmtHour;
lGmtHour = lLocalHour + lBias;
if (lGmtHour < 0)
lGmtHour += UNITS_PER_WEEK;
else if (lGmtHour > UNITS_PER_WEEK)
lGmtHour -= UNITS_PER_WEEK;
return (DWORD)lGmtHour;
}
static
DWORD
ParseLogonHours(
PWSTR pszParams,
PBYTE *ppLogonBitmap,
PDWORD pdwUnitsPerWeek)
{
TIME_ZONE_INFORMATION TimeZoneInformation;
PBYTE pLogonBitmap = NULL;
DWORD dwError = ERROR_SUCCESS;
WCHAR szBuffer[32];
PWSTR ptr1, ptr2;
WCHAR prevSep, nextSep;
DWORD dwStartDay, dwEndDay, i, j;
LONG lStartHour, lEndHour, lBias;
BYTE DayBitmap;
BYTE HourBitmap[6];
LPWSTR ShortDays[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
LPWSTR LongDays[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
LPWSTR AmPmArray[4] = {NULL, NULL, NULL, NULL};
GetTimeZoneInformation(&TimeZoneInformation);
lBias = TimeZoneInformation.Bias / 60;
pLogonBitmap = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
UNITS_PER_WEEK / 8);
if (pLogonBitmap == NULL)
return ERROR_OUTOFMEMORY;
if (*pszParams == UNICODE_NULL)
{
goto done;
}
if (wcsicmp(pszParams, L"all") == 0)
{
FillMemory(pLogonBitmap, UNITS_PER_WEEK / 8, 0xFF);
goto done;
}
for (i = 0; i < 7; i++)
{
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_HMODULE |
FORMAT_MESSAGE_IGNORE_INSERTS,
hModuleNetMsg,
4314 + i,
LANG_USER_DEFAULT,
(LPWSTR)&ShortDays[i],
0,
NULL);
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_HMODULE |
FORMAT_MESSAGE_IGNORE_INSERTS,
hModuleNetMsg,
4307 + i,
LANG_USER_DEFAULT,
(LPWSTR)&LongDays[i],
0,
NULL);
}
for (i = 0; i < 4; i++)
{
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_HMODULE |
FORMAT_MESSAGE_IGNORE_INSERTS,
hModuleNetMsg,
4322 + i,
LANG_USER_DEFAULT,
(LPWSTR)&AmPmArray[i],
0,
NULL);
}
ZeroMemory(&DayBitmap, sizeof(DayBitmap));
ZeroMemory(HourBitmap, sizeof(HourBitmap));
ZeroMemory(szBuffer, sizeof(szBuffer));
ptr1 = pszParams;
ptr2 = szBuffer;
prevSep = UNICODE_NULL;
nextSep = UNICODE_NULL;
for (;;)
{
if (*ptr1 != L'-' && *ptr1 != L',' && *ptr1 != L';' && *ptr1 != UNICODE_NULL)
{
*ptr2 = *ptr1;
ptr2++;
}
else
{
prevSep = nextSep;
nextSep = *ptr1;
if (prevSep != L'-')
{
/* Set first value */
if (iswdigit(szBuffer[0]))
{
/* Parse hour */
if (!ParseHour(szBuffer, AmPmArray, &lStartHour))
{
dwError = 3769;
break;
}
SetBitValue(HourBitmap, LocalToGmtHour(lStartHour, lBias));
}
else
{
/* Parse day */
if (!ParseDay(szBuffer, ShortDays, LongDays, &dwStartDay))
{
dwError = 3768;
break;
}
SetBitValue(&DayBitmap, dwStartDay);
}
}
else
{
/* Set second value */
if (iswdigit(szBuffer[0]))
{
/* Parse hour */
if (!ParseHour(szBuffer, AmPmArray, &lEndHour))
{
dwError = 3769;
break;
}
if (lEndHour <= lStartHour)
lEndHour += HOURS_PER_DAY;
for (i = LocalToGmtHour(lStartHour, lBias); i < LocalToGmtHour(lEndHour, lBias); i++)
SetBitValue(HourBitmap, i);
}
else
{
/* Parse day */
if (!ParseDay(szBuffer, ShortDays, LongDays, &dwEndDay))
{
dwError = 3768;
break;
}
if (dwEndDay <= dwStartDay)
dwEndDay += DAYS_PER_WEEK;
for (i = dwStartDay; i <= dwEndDay; i++)
SetBitValue(&DayBitmap, i % DAYS_PER_WEEK);
}
}
if (*ptr1 == L';' || *ptr1 == UNICODE_NULL)
{
/* Fill the logon hour bitmap */
for (i = 0; i < DAYS_PER_WEEK; i++)
{
if (GetBitValue(&DayBitmap, i))
{
for (j = 0; j < 48; j++)
{
if (GetBitValue(HourBitmap, j))
SetBitValue(pLogonBitmap, ((i * HOURS_PER_DAY) + j) % UNITS_PER_WEEK);
}
}
}
/* Reset the Bitmaps */
ZeroMemory(&DayBitmap, sizeof(DayBitmap));
ZeroMemory(HourBitmap, sizeof(HourBitmap));
}
if (*ptr1 == UNICODE_NULL)
break;
ZeroMemory(szBuffer, sizeof(szBuffer));
ptr2 = szBuffer;
}
ptr1++;
}
done:
for (i = 0; i < 7; i++)
{
LocalFree(ShortDays[i]);
LocalFree(LongDays[i]);
}
for (i = 0; i < 4; i++)
{
LocalFree(AmPmArray[i]);
}
if (dwError == ERROR_SUCCESS)
{
*ppLogonBitmap = pLogonBitmap;
*pdwUnitsPerWeek = UNITS_PER_WEEK;
}
else
{
if (pLogonBitmap != NULL)
HeapFree(GetProcessHeap(), 0, pLogonBitmap);
*ppLogonBitmap = NULL;
*pdwUnitsPerWeek = 0;
}
return dwError;
}
INT
cmdUser(
INT argc,
WCHAR **argv)
{
INT i, j;
INT result = 0;
BOOL bAdd = FALSE;
BOOL bDelete = FALSE;
#if 0
BOOL bDomain = FALSE;
#endif
BOOL bRandomPassword = FALSE;
LPWSTR lpUserName = NULL;
LPWSTR lpPassword = NULL;
PUSER_INFO_4 pUserInfo = NULL;
USER_INFO_4 UserInfo;
LPWSTR pWorkstations = NULL;
LPWSTR p;
LPWSTR endptr;
DWORD value;
BOOL bPasswordAllocated = FALSE;
PBYTE pLogonHours = NULL;
DWORD dwUnitsPerWeek;
NET_API_STATUS Status;
i = 2;
if ((i < argc) && (argv[i][0] != L'/'))
{
lpUserName = argv[i];
// ConPrintf(StdOut, L"User: %s\n", lpUserName);
i++;
}
if ((i < argc) && (argv[i][0] != L'/'))
{
lpPassword = argv[i];
// ConPrintf(StdOut, L"Password: %s\n", lpPassword);
i++;
}
for (j = i; j < argc; j++)
{
if (_wcsicmp(argv[j], L"/help") == 0)
{
PrintNetMessage(MSG_USER_HELP);
return 0;
}
else if (_wcsicmp(argv[j], L"/add") == 0)
{
bAdd = TRUE;
}
else if (_wcsicmp(argv[j], L"/delete") == 0)
{
bDelete = TRUE;
}
else if (_wcsicmp(argv[j], L"/domain") == 0)
{
ConPuts(StdErr, L"The /DOMAIN option is not supported yet.\n");
#if 0
bDomain = TRUE;
#endif
}
else if (_wcsicmp(argv[j], L"/random") == 0)
{
bRandomPassword = TRUE;
GenerateRandomPassword(&lpPassword,
&bPasswordAllocated);
}
}
if (lpUserName == NULL && lpPassword == NULL)
{
Status = EnumerateUsers();
ConPrintf(StdOut, L"Status: %lu\n", Status);
return 0;
}
else if (lpUserName != NULL && lpPassword == NULL && argc == 3)
{
Status = DisplayUser(lpUserName);
ConPrintf(StdOut, L"Status: %lu\n", Status);
return 0;
}
if (bAdd && bDelete)
{
result = 1;
goto done;
}
/* Interactive password input */
if (lpPassword != NULL && wcscmp(lpPassword, L"*") == 0)
{
ReadPassword(&lpPassword,
&bPasswordAllocated);
}
if (!bAdd && !bDelete)
{
/* Modify the user */
Status = NetUserGetInfo(NULL,
lpUserName,
4,
(LPBYTE*)&pUserInfo);
if (Status != NERR_Success)
{
ConPrintf(StdOut, L"Status: %lu\n", Status);
result = 1;
goto done;
}
}
else if (bAdd && !bDelete)
{
/* Add the user */
ZeroMemory(&UserInfo, sizeof(USER_INFO_4));
UserInfo.usri4_name = lpUserName;
UserInfo.usri4_password = lpPassword;
UserInfo.usri4_flags = UF_SCRIPT | UF_NORMAL_ACCOUNT;
UserInfo.usri4_acct_expires = TIMEQ_FOREVER;
UserInfo.usri4_primary_group_id = DOMAIN_GROUP_RID_USERS;
pUserInfo = &UserInfo;
}
for (j = i; j < argc; j++)
{
if (_wcsnicmp(argv[j], L"/active:", 8) == 0)
{
p = &argv[i][8];
if (_wcsicmp(p, L"yes") == 0)
{
pUserInfo->usri4_flags &= ~UF_ACCOUNTDISABLE;
}
else if (_wcsicmp(p, L"no") == 0)
{
pUserInfo->usri4_flags |= UF_ACCOUNTDISABLE;
}
else
{
PrintMessageStringV(3952, L"/ACTIVE");
result = 1;
goto done;
}
}
else if (_wcsnicmp(argv[j], L"/comment:", 9) == 0)
{
pUserInfo->usri4_comment = &argv[j][9];
}
else if (_wcsnicmp(argv[j], L"/countrycode:", 13) == 0)
{
p = &argv[i][13];
value = wcstoul(p, &endptr, 10);
if (*endptr != 0)
{
PrintMessageStringV(3952, L"/COUNTRYCODE");
result = 1;
goto done;
}
/* Verify the country code */
if (GetCountryFromCountryCode(value, 0, NULL))
pUserInfo->usri4_country_code = value;
}
else if (_wcsnicmp(argv[j], L"/expires:", 9) == 0)
{
p = &argv[i][9];
if (_wcsicmp(p, L"never") == 0)
{
pUserInfo->usri4_acct_expires = TIMEQ_FOREVER;
}
else if (!ParseDate(p, &pUserInfo->usri4_acct_expires))
{
PrintMessageStringV(3952, L"/EXPIRES");
result = 1;
goto done;
}
}
else if (_wcsnicmp(argv[j], L"/fullname:", 10) == 0)
{
pUserInfo->usri4_full_name = &argv[j][10];
}
else if (_wcsnicmp(argv[j], L"/homedir:", 9) == 0)
{
pUserInfo->usri4_home_dir = &argv[j][9];
}
else if (_wcsnicmp(argv[j], L"/passwordchg:", 13) == 0)
{
p = &argv[i][13];
if (_wcsicmp(p, L"yes") == 0)
{
pUserInfo->usri4_flags &= ~UF_PASSWD_CANT_CHANGE;
}
else if (_wcsicmp(p, L"no") == 0)
{
pUserInfo->usri4_flags |= UF_PASSWD_CANT_CHANGE;
}
else
{
PrintMessageStringV(3952, L"/PASSWORDCHG");
result = 1;
goto done;
}
}
else if (_wcsnicmp(argv[j], L"/passwordreq:", 13) == 0)
{
p = &argv[i][13];
if (_wcsicmp(p, L"yes") == 0)
{
pUserInfo->usri4_flags &= ~UF_PASSWD_NOTREQD;
}
else if (_wcsicmp(p, L"no") == 0)
{
pUserInfo->usri4_flags |= UF_PASSWD_NOTREQD;
}
else
{
PrintMessageStringV(3952, L"/PASSWORDREQ");
result = 1;
goto done;
}
}
else if (_wcsnicmp(argv[j], L"/profilepath:", 13) == 0)
{
pUserInfo->usri4_profile = &argv[j][13];
}
else if (_wcsnicmp(argv[j], L"/scriptpath:", 12) == 0)
{
pUserInfo->usri4_script_path = &argv[j][12];
}
else if (_wcsnicmp(argv[j], L"/times:", 7) == 0)
{
Status = ParseLogonHours(&argv[j][7],
&pLogonHours,
&dwUnitsPerWeek);
if (Status == ERROR_SUCCESS)
{
pUserInfo->usri4_logon_hours = pLogonHours;
pUserInfo->usri4_units_per_week = dwUnitsPerWeek;
}
else
{
PrintMessageString(Status);
goto done;
}
}
else if (_wcsnicmp(argv[j], L"/usercomment:", 13) == 0)
{
pUserInfo->usri4_usr_comment = &argv[j][13];
}
else if (_wcsnicmp(argv[j], L"/workstations:", 14) == 0)
{
p = &argv[i][14];
if (wcscmp(p, L"*") == 0 || wcscmp(p, L"") == 0)
{
pUserInfo->usri4_workstations = NULL;
}
else
{
Status = BuildWorkstationsList(&pWorkstations, p);
if (Status == NERR_Success)
{
pUserInfo->usri4_workstations = pWorkstations;
}
else
{
ConPrintf(StdOut, L"Status %lu\n\n", Status);
result = 1;
goto done;
}
}
}
}
if (!bAdd && !bDelete)
{
/* Modify the user */
Status = NetUserSetInfo(NULL,
lpUserName,
4,
(LPBYTE)pUserInfo,
NULL);
ConPrintf(StdOut, L"Status: %lu\n", Status);
}
else if (bAdd && !bDelete)
{
/* Add the user */
Status = NetUserAdd(NULL,
4,
(LPBYTE)pUserInfo,
NULL);
ConPrintf(StdOut, L"Status: %lu\n", Status);
}
else if (!bAdd && bDelete)
{
/* Delete the user */
Status = NetUserDel(NULL,
lpUserName);
ConPrintf(StdOut, L"Status: %lu\n", Status);
}
if (Status == NERR_Success &&
lpPassword != NULL &&
bRandomPassword == TRUE)
{
PrintMessageStringV(3968, lpUserName, lpPassword);
}
done:
if (pLogonHours != NULL)
HeapFree(GetProcessHeap(), 0, pLogonHours);
if (pWorkstations != NULL)
HeapFree(GetProcessHeap(), 0, pWorkstations);
if ((bPasswordAllocated == TRUE) && (lpPassword != NULL))
HeapFree(GetProcessHeap(), 0, lpPassword);
if (!bAdd && !bDelete && pUserInfo != NULL)
NetApiBufferFree(pUserInfo);
if (result != 0)
{
PrintMessageString(4381);
ConPuts(StdOut, L"\n");
PrintNetMessage(MSG_USER_SYNTAX);
}
return result;
}
/* EOF */