1*c2c66affSColin Finck /* 2*c2c66affSColin Finck * COPYRIGHT: See COPYING in the top level directory 3*c2c66affSColin Finck * PROJECT: ReactOS net command 4*c2c66affSColin Finck * FILE: base/applications/network/net/cmdUser.c 5*c2c66affSColin Finck * PURPOSE: 6*c2c66affSColin Finck * 7*c2c66affSColin Finck * PROGRAMMERS: Eric Kohl 8*c2c66affSColin Finck * Curtis Wilson 9*c2c66affSColin Finck */ 10*c2c66affSColin Finck 11*c2c66affSColin Finck #include "net.h" 12*c2c66affSColin Finck 13*c2c66affSColin Finck 14*c2c66affSColin Finck static 15*c2c66affSColin Finck int 16*c2c66affSColin Finck CompareInfo(const void *a, 17*c2c66affSColin Finck const void *b) 18*c2c66affSColin Finck { 19*c2c66affSColin Finck return _wcsicmp(((PUSER_INFO_0)a)->usri0_name, 20*c2c66affSColin Finck ((PUSER_INFO_0)b)->usri0_name); 21*c2c66affSColin Finck } 22*c2c66affSColin Finck 23*c2c66affSColin Finck 24*c2c66affSColin Finck static 25*c2c66affSColin Finck NET_API_STATUS 26*c2c66affSColin Finck EnumerateUsers(VOID) 27*c2c66affSColin Finck { 28*c2c66affSColin Finck PUSER_INFO_0 pBuffer = NULL; 29*c2c66affSColin Finck PSERVER_INFO_100 pServer = NULL; 30*c2c66affSColin Finck DWORD dwRead = 0, dwTotal = 0; 31*c2c66affSColin Finck DWORD i; 32*c2c66affSColin Finck DWORD_PTR ResumeHandle = 0; 33*c2c66affSColin Finck NET_API_STATUS Status; 34*c2c66affSColin Finck 35*c2c66affSColin Finck Status = NetServerGetInfo(NULL, 36*c2c66affSColin Finck 100, 37*c2c66affSColin Finck (LPBYTE*)&pServer); 38*c2c66affSColin Finck if (Status != NERR_Success) 39*c2c66affSColin Finck return Status; 40*c2c66affSColin Finck 41*c2c66affSColin Finck ConPuts(StdOut, L"\n"); 42*c2c66affSColin Finck ConResPrintf(StdOut, IDS_USER_ACCOUNTS, pServer->sv100_name); 43*c2c66affSColin Finck ConPuts(StdOut, L"\n\n"); 44*c2c66affSColin Finck PrintPadding(L'-', 79); 45*c2c66affSColin Finck ConPuts(StdOut, L"\n"); 46*c2c66affSColin Finck 47*c2c66affSColin Finck NetApiBufferFree(pServer); 48*c2c66affSColin Finck 49*c2c66affSColin Finck do 50*c2c66affSColin Finck { 51*c2c66affSColin Finck Status = NetUserEnum(NULL, 52*c2c66affSColin Finck 0, 53*c2c66affSColin Finck 0, 54*c2c66affSColin Finck (LPBYTE*)&pBuffer, 55*c2c66affSColin Finck MAX_PREFERRED_LENGTH, 56*c2c66affSColin Finck &dwRead, 57*c2c66affSColin Finck &dwTotal, 58*c2c66affSColin Finck &ResumeHandle); 59*c2c66affSColin Finck if ((Status != NERR_Success) && (Status != ERROR_MORE_DATA)) 60*c2c66affSColin Finck return Status; 61*c2c66affSColin Finck 62*c2c66affSColin Finck qsort(pBuffer, 63*c2c66affSColin Finck dwRead, 64*c2c66affSColin Finck sizeof(PUSER_INFO_0), 65*c2c66affSColin Finck CompareInfo); 66*c2c66affSColin Finck 67*c2c66affSColin Finck for (i = 0; i < dwRead; i++) 68*c2c66affSColin Finck { 69*c2c66affSColin Finck if (pBuffer[i].usri0_name) 70*c2c66affSColin Finck ConPrintf(StdOut, L"%s\n", pBuffer[i].usri0_name); 71*c2c66affSColin Finck } 72*c2c66affSColin Finck 73*c2c66affSColin Finck NetApiBufferFree(pBuffer); 74*c2c66affSColin Finck pBuffer = NULL; 75*c2c66affSColin Finck } 76*c2c66affSColin Finck while (Status == ERROR_MORE_DATA); 77*c2c66affSColin Finck 78*c2c66affSColin Finck return NERR_Success; 79*c2c66affSColin Finck } 80*c2c66affSColin Finck 81*c2c66affSColin Finck 82*c2c66affSColin Finck static 83*c2c66affSColin Finck VOID 84*c2c66affSColin Finck PrintDateTime(DWORD dwSeconds) 85*c2c66affSColin Finck { 86*c2c66affSColin Finck LARGE_INTEGER Time; 87*c2c66affSColin Finck FILETIME FileTime; 88*c2c66affSColin Finck SYSTEMTIME SystemTime; 89*c2c66affSColin Finck WCHAR DateBuffer[80]; 90*c2c66affSColin Finck WCHAR TimeBuffer[80]; 91*c2c66affSColin Finck 92*c2c66affSColin Finck RtlSecondsSince1970ToTime(dwSeconds, &Time); 93*c2c66affSColin Finck FileTime.dwLowDateTime = Time.u.LowPart; 94*c2c66affSColin Finck FileTime.dwHighDateTime = Time.u.HighPart; 95*c2c66affSColin Finck FileTimeToLocalFileTime(&FileTime, &FileTime); 96*c2c66affSColin Finck FileTimeToSystemTime(&FileTime, &SystemTime); 97*c2c66affSColin Finck 98*c2c66affSColin Finck GetDateFormatW(LOCALE_USER_DEFAULT, 99*c2c66affSColin Finck DATE_SHORTDATE, 100*c2c66affSColin Finck &SystemTime, 101*c2c66affSColin Finck NULL, 102*c2c66affSColin Finck DateBuffer, 103*c2c66affSColin Finck 80); 104*c2c66affSColin Finck 105*c2c66affSColin Finck GetTimeFormatW(LOCALE_USER_DEFAULT, 106*c2c66affSColin Finck TIME_NOSECONDS, 107*c2c66affSColin Finck &SystemTime, 108*c2c66affSColin Finck NULL, 109*c2c66affSColin Finck TimeBuffer, 110*c2c66affSColin Finck 80); 111*c2c66affSColin Finck 112*c2c66affSColin Finck ConPrintf(StdOut, L"%s %s", DateBuffer, TimeBuffer); 113*c2c66affSColin Finck } 114*c2c66affSColin Finck 115*c2c66affSColin Finck 116*c2c66affSColin Finck static 117*c2c66affSColin Finck DWORD 118*c2c66affSColin Finck GetTimeInSeconds(VOID) 119*c2c66affSColin Finck { 120*c2c66affSColin Finck LARGE_INTEGER Time; 121*c2c66affSColin Finck FILETIME FileTime; 122*c2c66affSColin Finck DWORD dwSeconds; 123*c2c66affSColin Finck 124*c2c66affSColin Finck GetSystemTimeAsFileTime(&FileTime); 125*c2c66affSColin Finck Time.u.LowPart = FileTime.dwLowDateTime; 126*c2c66affSColin Finck Time.u.HighPart = FileTime.dwHighDateTime; 127*c2c66affSColin Finck RtlTimeToSecondsSince1970(&Time, &dwSeconds); 128*c2c66affSColin Finck 129*c2c66affSColin Finck return dwSeconds; 130*c2c66affSColin Finck } 131*c2c66affSColin Finck 132*c2c66affSColin Finck 133*c2c66affSColin Finck static 134*c2c66affSColin Finck NET_API_STATUS 135*c2c66affSColin Finck DisplayUser(LPWSTR lpUserName) 136*c2c66affSColin Finck { 137*c2c66affSColin Finck PUSER_MODALS_INFO_0 pUserModals = NULL; 138*c2c66affSColin Finck PUSER_INFO_4 pUserInfo = NULL; 139*c2c66affSColin Finck PLOCALGROUP_USERS_INFO_0 pLocalGroupInfo = NULL; 140*c2c66affSColin Finck PGROUP_USERS_INFO_0 pGroupInfo = NULL; 141*c2c66affSColin Finck DWORD dwLocalGroupRead, dwLocalGroupTotal; 142*c2c66affSColin Finck DWORD dwGroupRead, dwGroupTotal; 143*c2c66affSColin Finck DWORD dwLastSet; 144*c2c66affSColin Finck DWORD i; 145*c2c66affSColin Finck INT nPaddedLength = 29; 146*c2c66affSColin Finck NET_API_STATUS Status; 147*c2c66affSColin Finck 148*c2c66affSColin Finck /* Modify the user */ 149*c2c66affSColin Finck Status = NetUserGetInfo(NULL, 150*c2c66affSColin Finck lpUserName, 151*c2c66affSColin Finck 4, 152*c2c66affSColin Finck (LPBYTE*)&pUserInfo); 153*c2c66affSColin Finck if (Status != NERR_Success) 154*c2c66affSColin Finck return Status; 155*c2c66affSColin Finck 156*c2c66affSColin Finck Status = NetUserModalsGet(NULL, 157*c2c66affSColin Finck 0, 158*c2c66affSColin Finck (LPBYTE*)&pUserModals); 159*c2c66affSColin Finck if (Status != NERR_Success) 160*c2c66affSColin Finck goto done; 161*c2c66affSColin Finck 162*c2c66affSColin Finck Status = NetUserGetLocalGroups(NULL, 163*c2c66affSColin Finck lpUserName, 164*c2c66affSColin Finck 0, 165*c2c66affSColin Finck 0, 166*c2c66affSColin Finck (LPBYTE*)&pLocalGroupInfo, 167*c2c66affSColin Finck MAX_PREFERRED_LENGTH, 168*c2c66affSColin Finck &dwLocalGroupRead, 169*c2c66affSColin Finck &dwLocalGroupTotal); 170*c2c66affSColin Finck if (Status != NERR_Success) 171*c2c66affSColin Finck goto done; 172*c2c66affSColin Finck 173*c2c66affSColin Finck Status = NetUserGetGroups(NULL, 174*c2c66affSColin Finck lpUserName, 175*c2c66affSColin Finck 0, 176*c2c66affSColin Finck (LPBYTE*)&pGroupInfo, 177*c2c66affSColin Finck MAX_PREFERRED_LENGTH, 178*c2c66affSColin Finck &dwGroupRead, 179*c2c66affSColin Finck &dwGroupTotal); 180*c2c66affSColin Finck if (Status != NERR_Success) 181*c2c66affSColin Finck goto done; 182*c2c66affSColin Finck 183*c2c66affSColin Finck PrintPaddedResourceString(IDS_USER_NAME, nPaddedLength); 184*c2c66affSColin Finck ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_name); 185*c2c66affSColin Finck 186*c2c66affSColin Finck PrintPaddedResourceString(IDS_USER_FULL_NAME, nPaddedLength); 187*c2c66affSColin Finck ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_full_name); 188*c2c66affSColin Finck 189*c2c66affSColin Finck PrintPaddedResourceString(IDS_USER_COMMENT, nPaddedLength); 190*c2c66affSColin Finck ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_comment); 191*c2c66affSColin Finck 192*c2c66affSColin Finck PrintPaddedResourceString(IDS_USER_USER_COMMENT, nPaddedLength); 193*c2c66affSColin Finck ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_usr_comment); 194*c2c66affSColin Finck 195*c2c66affSColin Finck PrintPaddedResourceString(IDS_USER_COUNTRY_CODE, nPaddedLength); 196*c2c66affSColin Finck ConPrintf(StdOut, L"%03ld ()\n", pUserInfo->usri4_country_code); 197*c2c66affSColin Finck 198*c2c66affSColin Finck PrintPaddedResourceString(IDS_USER_ACCOUNT_ACTIVE, nPaddedLength); 199*c2c66affSColin Finck if (pUserInfo->usri4_flags & UF_ACCOUNTDISABLE) 200*c2c66affSColin Finck ConResPuts(StdOut, IDS_GENERIC_NO); 201*c2c66affSColin Finck else if (pUserInfo->usri4_flags & UF_LOCKOUT) 202*c2c66affSColin Finck ConResPuts(StdOut, IDS_GENERIC_LOCKED); 203*c2c66affSColin Finck else 204*c2c66affSColin Finck ConResPuts(StdOut, IDS_GENERIC_YES); 205*c2c66affSColin Finck ConPuts(StdOut, L"\n"); 206*c2c66affSColin Finck 207*c2c66affSColin Finck PrintPaddedResourceString(IDS_USER_ACCOUNT_EXPIRES, nPaddedLength); 208*c2c66affSColin Finck if (pUserInfo->usri4_acct_expires == TIMEQ_FOREVER) 209*c2c66affSColin Finck ConResPuts(StdOut, IDS_GENERIC_NEVER); 210*c2c66affSColin Finck else 211*c2c66affSColin Finck PrintDateTime(pUserInfo->usri4_acct_expires); 212*c2c66affSColin Finck ConPuts(StdOut, L"\n\n"); 213*c2c66affSColin Finck 214*c2c66affSColin Finck PrintPaddedResourceString(IDS_USER_PW_LAST_SET, nPaddedLength); 215*c2c66affSColin Finck dwLastSet = GetTimeInSeconds() - pUserInfo->usri4_password_age; 216*c2c66affSColin Finck PrintDateTime(dwLastSet); 217*c2c66affSColin Finck 218*c2c66affSColin Finck PrintPaddedResourceString(IDS_USER_PW_EXPIRES, nPaddedLength); 219*c2c66affSColin Finck if ((pUserInfo->usri4_flags & UF_DONT_EXPIRE_PASSWD) || pUserModals->usrmod0_max_passwd_age == TIMEQ_FOREVER) 220*c2c66affSColin Finck ConResPuts(StdOut, IDS_GENERIC_NEVER); 221*c2c66affSColin Finck else 222*c2c66affSColin Finck PrintDateTime(dwLastSet + pUserModals->usrmod0_max_passwd_age); 223*c2c66affSColin Finck ConPuts(StdOut, L"\n"); 224*c2c66affSColin Finck 225*c2c66affSColin Finck PrintPaddedResourceString(IDS_USER_PW_CHANGEABLE, nPaddedLength); 226*c2c66affSColin Finck PrintDateTime(dwLastSet + pUserModals->usrmod0_min_passwd_age); 227*c2c66affSColin Finck 228*c2c66affSColin Finck PrintPaddedResourceString(IDS_USER_PW_REQUIRED, nPaddedLength); 229*c2c66affSColin Finck ConResPuts(StdOut, (pUserInfo->usri4_flags & UF_PASSWD_NOTREQD) ? IDS_GENERIC_NO : IDS_GENERIC_YES); 230*c2c66affSColin Finck ConPuts(StdOut, L"\n"); 231*c2c66affSColin Finck 232*c2c66affSColin Finck PrintPaddedResourceString(IDS_USER_CHANGE_PW, nPaddedLength); 233*c2c66affSColin Finck ConResPuts(StdOut, (pUserInfo->usri4_flags & UF_PASSWD_CANT_CHANGE) ? IDS_GENERIC_NO : IDS_GENERIC_YES); 234*c2c66affSColin Finck ConPuts(StdOut, L"\n\n"); 235*c2c66affSColin Finck 236*c2c66affSColin Finck PrintPaddedResourceString(IDS_USER_WORKSTATIONS, nPaddedLength); 237*c2c66affSColin Finck if (pUserInfo->usri4_workstations == NULL || wcslen(pUserInfo->usri4_workstations) == 0) 238*c2c66affSColin Finck ConResPuts(StdOut, IDS_GENERIC_ALL); 239*c2c66affSColin Finck else 240*c2c66affSColin Finck ConPrintf(StdOut, L"%s", pUserInfo->usri4_workstations); 241*c2c66affSColin Finck ConPuts(StdOut, L"\n"); 242*c2c66affSColin Finck 243*c2c66affSColin Finck PrintPaddedResourceString(IDS_USER_LOGON_SCRIPT, nPaddedLength); 244*c2c66affSColin Finck ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_script_path); 245*c2c66affSColin Finck 246*c2c66affSColin Finck PrintPaddedResourceString(IDS_USER_PROFILE, nPaddedLength); 247*c2c66affSColin Finck ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_profile); 248*c2c66affSColin Finck 249*c2c66affSColin Finck PrintPaddedResourceString(IDS_USER_HOME_DIR, nPaddedLength); 250*c2c66affSColin Finck ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_home_dir); 251*c2c66affSColin Finck 252*c2c66affSColin Finck PrintPaddedResourceString(IDS_USER_LAST_LOGON, nPaddedLength); 253*c2c66affSColin Finck if (pUserInfo->usri4_last_logon == 0) 254*c2c66affSColin Finck ConResPuts(StdOut, IDS_GENERIC_NEVER); 255*c2c66affSColin Finck else 256*c2c66affSColin Finck PrintDateTime(pUserInfo->usri4_last_logon); 257*c2c66affSColin Finck ConPuts(StdOut, L"\n\n"); 258*c2c66affSColin Finck 259*c2c66affSColin Finck PrintPaddedResourceString(IDS_USER_LOGON_HOURS, nPaddedLength); 260*c2c66affSColin Finck if (pUserInfo->usri4_logon_hours == NULL) 261*c2c66affSColin Finck ConResPuts(StdOut, IDS_GENERIC_ALL); 262*c2c66affSColin Finck ConPuts(StdOut, L"\n\n"); 263*c2c66affSColin Finck 264*c2c66affSColin Finck ConPuts(StdOut, L"\n"); 265*c2c66affSColin Finck PrintPaddedResourceString(IDS_USER_LOCAL_GROUPS, nPaddedLength); 266*c2c66affSColin Finck if (dwLocalGroupTotal != 0 && pLocalGroupInfo != NULL) 267*c2c66affSColin Finck { 268*c2c66affSColin Finck for (i = 0; i < dwLocalGroupTotal; i++) 269*c2c66affSColin Finck { 270*c2c66affSColin Finck if (i != 0) 271*c2c66affSColin Finck PrintPadding(L' ', nPaddedLength); 272*c2c66affSColin Finck ConPrintf(StdOut, L"*%s\n", pLocalGroupInfo[i].lgrui0_name); 273*c2c66affSColin Finck } 274*c2c66affSColin Finck } 275*c2c66affSColin Finck else 276*c2c66affSColin Finck { 277*c2c66affSColin Finck ConPuts(StdOut, L"\n"); 278*c2c66affSColin Finck } 279*c2c66affSColin Finck 280*c2c66affSColin Finck PrintPaddedResourceString(IDS_USER_GLOBAL_GROUPS, nPaddedLength); 281*c2c66affSColin Finck if (dwGroupTotal != 0 && pGroupInfo != NULL) 282*c2c66affSColin Finck { 283*c2c66affSColin Finck for (i = 0; i < dwGroupTotal; i++) 284*c2c66affSColin Finck { 285*c2c66affSColin Finck if (i != 0) 286*c2c66affSColin Finck PrintPadding(L' ', nPaddedLength); 287*c2c66affSColin Finck ConPrintf(StdOut, L"*%s\n", pGroupInfo[i].grui0_name); 288*c2c66affSColin Finck } 289*c2c66affSColin Finck } 290*c2c66affSColin Finck else 291*c2c66affSColin Finck { 292*c2c66affSColin Finck ConPuts(StdOut, L"\n"); 293*c2c66affSColin Finck } 294*c2c66affSColin Finck 295*c2c66affSColin Finck done: 296*c2c66affSColin Finck if (pGroupInfo != NULL) 297*c2c66affSColin Finck NetApiBufferFree(pGroupInfo); 298*c2c66affSColin Finck 299*c2c66affSColin Finck if (pLocalGroupInfo != NULL) 300*c2c66affSColin Finck NetApiBufferFree(pLocalGroupInfo); 301*c2c66affSColin Finck 302*c2c66affSColin Finck if (pUserModals != NULL) 303*c2c66affSColin Finck NetApiBufferFree(pUserModals); 304*c2c66affSColin Finck 305*c2c66affSColin Finck if (pUserInfo != NULL) 306*c2c66affSColin Finck NetApiBufferFree(pUserInfo); 307*c2c66affSColin Finck 308*c2c66affSColin Finck return NERR_Success; 309*c2c66affSColin Finck } 310*c2c66affSColin Finck 311*c2c66affSColin Finck 312*c2c66affSColin Finck static 313*c2c66affSColin Finck VOID 314*c2c66affSColin Finck ReadPassword( 315*c2c66affSColin Finck LPWSTR *lpPassword, 316*c2c66affSColin Finck LPBOOL lpAllocated) 317*c2c66affSColin Finck { 318*c2c66affSColin Finck WCHAR szPassword1[PWLEN + 1]; 319*c2c66affSColin Finck WCHAR szPassword2[PWLEN + 1]; 320*c2c66affSColin Finck LPWSTR ptr; 321*c2c66affSColin Finck 322*c2c66affSColin Finck *lpAllocated = FALSE; 323*c2c66affSColin Finck 324*c2c66affSColin Finck while (TRUE) 325*c2c66affSColin Finck { 326*c2c66affSColin Finck ConResPuts(StdOut, IDS_USER_ENTER_PASSWORD1); 327*c2c66affSColin Finck ReadFromConsole(szPassword1, PWLEN + 1, FALSE); 328*c2c66affSColin Finck ConPuts(StdOut, L"\n"); 329*c2c66affSColin Finck 330*c2c66affSColin Finck ConResPuts(StdOut, IDS_USER_ENTER_PASSWORD2); 331*c2c66affSColin Finck ReadFromConsole(szPassword2, PWLEN + 1, FALSE); 332*c2c66affSColin Finck ConPuts(StdOut, L"\n"); 333*c2c66affSColin Finck 334*c2c66affSColin Finck if (wcslen(szPassword1) == wcslen(szPassword2) && 335*c2c66affSColin Finck wcscmp(szPassword1, szPassword2) == 0) 336*c2c66affSColin Finck { 337*c2c66affSColin Finck ptr = HeapAlloc(GetProcessHeap(), 338*c2c66affSColin Finck 0, 339*c2c66affSColin Finck (wcslen(szPassword1) + 1) * sizeof(WCHAR)); 340*c2c66affSColin Finck if (ptr != NULL) 341*c2c66affSColin Finck { 342*c2c66affSColin Finck wcscpy(ptr, szPassword1); 343*c2c66affSColin Finck *lpPassword = ptr; 344*c2c66affSColin Finck *lpAllocated = TRUE; 345*c2c66affSColin Finck return; 346*c2c66affSColin Finck } 347*c2c66affSColin Finck } 348*c2c66affSColin Finck else 349*c2c66affSColin Finck { 350*c2c66affSColin Finck ConPuts(StdOut, L"\n"); 351*c2c66affSColin Finck ConResPuts(StdOut, IDS_USER_NO_PASSWORD_MATCH); 352*c2c66affSColin Finck ConPuts(StdOut, L"\n"); 353*c2c66affSColin Finck *lpPassword = NULL; 354*c2c66affSColin Finck } 355*c2c66affSColin Finck } 356*c2c66affSColin Finck } 357*c2c66affSColin Finck 358*c2c66affSColin Finck 359*c2c66affSColin Finck INT 360*c2c66affSColin Finck cmdUser( 361*c2c66affSColin Finck INT argc, 362*c2c66affSColin Finck WCHAR **argv) 363*c2c66affSColin Finck { 364*c2c66affSColin Finck INT i, j; 365*c2c66affSColin Finck INT result = 0; 366*c2c66affSColin Finck BOOL bAdd = FALSE; 367*c2c66affSColin Finck BOOL bDelete = FALSE; 368*c2c66affSColin Finck #if 0 369*c2c66affSColin Finck BOOL bDomain = FALSE; 370*c2c66affSColin Finck #endif 371*c2c66affSColin Finck LPWSTR lpUserName = NULL; 372*c2c66affSColin Finck LPWSTR lpPassword = NULL; 373*c2c66affSColin Finck PUSER_INFO_4 pUserInfo = NULL; 374*c2c66affSColin Finck USER_INFO_4 UserInfo; 375*c2c66affSColin Finck LPWSTR p; 376*c2c66affSColin Finck LPWSTR endptr; 377*c2c66affSColin Finck DWORD value; 378*c2c66affSColin Finck BOOL bPasswordAllocated = FALSE; 379*c2c66affSColin Finck NET_API_STATUS Status; 380*c2c66affSColin Finck 381*c2c66affSColin Finck if (argc == 2) 382*c2c66affSColin Finck { 383*c2c66affSColin Finck Status = EnumerateUsers(); 384*c2c66affSColin Finck ConPrintf(StdOut, L"Status: %lu\n", Status); 385*c2c66affSColin Finck return 0; 386*c2c66affSColin Finck } 387*c2c66affSColin Finck else if (argc == 3) 388*c2c66affSColin Finck { 389*c2c66affSColin Finck Status = DisplayUser(argv[2]); 390*c2c66affSColin Finck ConPrintf(StdOut, L"Status: %lu\n", Status); 391*c2c66affSColin Finck return 0; 392*c2c66affSColin Finck } 393*c2c66affSColin Finck 394*c2c66affSColin Finck i = 2; 395*c2c66affSColin Finck if (argv[i][0] != L'/') 396*c2c66affSColin Finck { 397*c2c66affSColin Finck lpUserName = argv[i]; 398*c2c66affSColin Finck // ConPrintf(StdOut, L"User: %s\n", lpUserName); 399*c2c66affSColin Finck i++; 400*c2c66affSColin Finck } 401*c2c66affSColin Finck 402*c2c66affSColin Finck if (argv[i][0] != L'/') 403*c2c66affSColin Finck { 404*c2c66affSColin Finck lpPassword = argv[i]; 405*c2c66affSColin Finck // ConPrintf(StdOut, L"Password: %s\n", lpPassword); 406*c2c66affSColin Finck i++; 407*c2c66affSColin Finck } 408*c2c66affSColin Finck 409*c2c66affSColin Finck for (j = i; j < argc; j++) 410*c2c66affSColin Finck { 411*c2c66affSColin Finck if (_wcsicmp(argv[j], L"/help") == 0) 412*c2c66affSColin Finck { 413*c2c66affSColin Finck ConResPuts(StdOut, IDS_USER_HELP); 414*c2c66affSColin Finck return 0; 415*c2c66affSColin Finck } 416*c2c66affSColin Finck else if (_wcsicmp(argv[j], L"/add") == 0) 417*c2c66affSColin Finck { 418*c2c66affSColin Finck bAdd = TRUE; 419*c2c66affSColin Finck } 420*c2c66affSColin Finck else if (_wcsicmp(argv[j], L"/delete") == 0) 421*c2c66affSColin Finck { 422*c2c66affSColin Finck bDelete = TRUE; 423*c2c66affSColin Finck } 424*c2c66affSColin Finck else if (_wcsicmp(argv[j], L"/domain") == 0) 425*c2c66affSColin Finck { 426*c2c66affSColin Finck ConResPrintf(StdErr, IDS_ERROR_OPTION_NOT_SUPPORTED, L"/DOMAIN"); 427*c2c66affSColin Finck #if 0 428*c2c66affSColin Finck bDomain = TRUE; 429*c2c66affSColin Finck #endif 430*c2c66affSColin Finck } 431*c2c66affSColin Finck } 432*c2c66affSColin Finck 433*c2c66affSColin Finck if (bAdd && bDelete) 434*c2c66affSColin Finck { 435*c2c66affSColin Finck result = 1; 436*c2c66affSColin Finck goto done; 437*c2c66affSColin Finck } 438*c2c66affSColin Finck 439*c2c66affSColin Finck /* Interactive password input */ 440*c2c66affSColin Finck if (lpPassword != NULL && wcscmp(lpPassword, L"*") == 0) 441*c2c66affSColin Finck { 442*c2c66affSColin Finck ReadPassword(&lpPassword, 443*c2c66affSColin Finck &bPasswordAllocated); 444*c2c66affSColin Finck } 445*c2c66affSColin Finck 446*c2c66affSColin Finck if (!bAdd && !bDelete) 447*c2c66affSColin Finck { 448*c2c66affSColin Finck /* Modify the user */ 449*c2c66affSColin Finck Status = NetUserGetInfo(NULL, 450*c2c66affSColin Finck lpUserName, 451*c2c66affSColin Finck 4, 452*c2c66affSColin Finck (LPBYTE*)&pUserInfo); 453*c2c66affSColin Finck if (Status != NERR_Success) 454*c2c66affSColin Finck { 455*c2c66affSColin Finck ConPrintf(StdOut, L"Status: %lu\n", Status); 456*c2c66affSColin Finck result = 1; 457*c2c66affSColin Finck goto done; 458*c2c66affSColin Finck } 459*c2c66affSColin Finck } 460*c2c66affSColin Finck else if (bAdd && !bDelete) 461*c2c66affSColin Finck { 462*c2c66affSColin Finck /* Add the user */ 463*c2c66affSColin Finck ZeroMemory(&UserInfo, sizeof(USER_INFO_4)); 464*c2c66affSColin Finck 465*c2c66affSColin Finck UserInfo.usri4_name = lpUserName; 466*c2c66affSColin Finck UserInfo.usri4_password = lpPassword; 467*c2c66affSColin Finck UserInfo.usri4_flags = UF_SCRIPT | UF_NORMAL_ACCOUNT; 468*c2c66affSColin Finck 469*c2c66affSColin Finck pUserInfo = &UserInfo; 470*c2c66affSColin Finck } 471*c2c66affSColin Finck 472*c2c66affSColin Finck for (j = i; j < argc; j++) 473*c2c66affSColin Finck { 474*c2c66affSColin Finck if (_wcsnicmp(argv[j], L"/active:", 8) == 0) 475*c2c66affSColin Finck { 476*c2c66affSColin Finck p = &argv[i][8]; 477*c2c66affSColin Finck if (_wcsicmp(p, L"yes") == 0) 478*c2c66affSColin Finck { 479*c2c66affSColin Finck pUserInfo->usri4_flags &= ~UF_ACCOUNTDISABLE; 480*c2c66affSColin Finck } 481*c2c66affSColin Finck else if (_wcsicmp(p, L"no") == 0) 482*c2c66affSColin Finck { 483*c2c66affSColin Finck pUserInfo->usri4_flags |= UF_ACCOUNTDISABLE; 484*c2c66affSColin Finck } 485*c2c66affSColin Finck else 486*c2c66affSColin Finck { 487*c2c66affSColin Finck ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE, L"/ACTIVE"); 488*c2c66affSColin Finck result = 1; 489*c2c66affSColin Finck goto done; 490*c2c66affSColin Finck } 491*c2c66affSColin Finck } 492*c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/comment:", 9) == 0) 493*c2c66affSColin Finck { 494*c2c66affSColin Finck pUserInfo->usri4_comment = &argv[j][9]; 495*c2c66affSColin Finck } 496*c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/countrycode:", 13) == 0) 497*c2c66affSColin Finck { 498*c2c66affSColin Finck p = &argv[i][13]; 499*c2c66affSColin Finck value = wcstoul(p, &endptr, 10); 500*c2c66affSColin Finck if (*endptr != 0) 501*c2c66affSColin Finck { 502*c2c66affSColin Finck ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE, L"/COUNTRYCODE"); 503*c2c66affSColin Finck result = 1; 504*c2c66affSColin Finck goto done; 505*c2c66affSColin Finck } 506*c2c66affSColin Finck 507*c2c66affSColin Finck /* FIXME: verify the country code */ 508*c2c66affSColin Finck 509*c2c66affSColin Finck pUserInfo->usri4_country_code = value; 510*c2c66affSColin Finck } 511*c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/expires:", 9) == 0) 512*c2c66affSColin Finck { 513*c2c66affSColin Finck p = &argv[i][9]; 514*c2c66affSColin Finck if (_wcsicmp(p, L"never") == 0) 515*c2c66affSColin Finck { 516*c2c66affSColin Finck pUserInfo->usri4_acct_expires = TIMEQ_FOREVER; 517*c2c66affSColin Finck } 518*c2c66affSColin Finck else 519*c2c66affSColin Finck { 520*c2c66affSColin Finck /* FIXME: Parse the date */ 521*c2c66affSColin Finck ConResPrintf(StdErr, IDS_ERROR_OPTION_NOT_SUPPORTED, L"/EXPIRES"); 522*c2c66affSColin Finck } 523*c2c66affSColin Finck } 524*c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/fullname:", 10) == 0) 525*c2c66affSColin Finck { 526*c2c66affSColin Finck pUserInfo->usri4_full_name = &argv[j][10]; 527*c2c66affSColin Finck } 528*c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/homedir:", 9) == 0) 529*c2c66affSColin Finck { 530*c2c66affSColin Finck pUserInfo->usri4_home_dir = &argv[j][9]; 531*c2c66affSColin Finck } 532*c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/passwordchg:", 13) == 0) 533*c2c66affSColin Finck { 534*c2c66affSColin Finck p = &argv[i][13]; 535*c2c66affSColin Finck if (_wcsicmp(p, L"yes") == 0) 536*c2c66affSColin Finck { 537*c2c66affSColin Finck pUserInfo->usri4_flags &= ~UF_PASSWD_CANT_CHANGE; 538*c2c66affSColin Finck } 539*c2c66affSColin Finck else if (_wcsicmp(p, L"no") == 0) 540*c2c66affSColin Finck { 541*c2c66affSColin Finck pUserInfo->usri4_flags |= UF_PASSWD_CANT_CHANGE; 542*c2c66affSColin Finck } 543*c2c66affSColin Finck else 544*c2c66affSColin Finck { 545*c2c66affSColin Finck ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE, L"/PASSWORDCHG"); 546*c2c66affSColin Finck result = 1; 547*c2c66affSColin Finck goto done; 548*c2c66affSColin Finck } 549*c2c66affSColin Finck } 550*c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/passwordreq:", 13) == 0) 551*c2c66affSColin Finck { 552*c2c66affSColin Finck p = &argv[i][13]; 553*c2c66affSColin Finck if (_wcsicmp(p, L"yes") == 0) 554*c2c66affSColin Finck { 555*c2c66affSColin Finck pUserInfo->usri4_flags &= ~UF_PASSWD_NOTREQD; 556*c2c66affSColin Finck } 557*c2c66affSColin Finck else if (_wcsicmp(p, L"no") == 0) 558*c2c66affSColin Finck { 559*c2c66affSColin Finck pUserInfo->usri4_flags |= UF_PASSWD_NOTREQD; 560*c2c66affSColin Finck } 561*c2c66affSColin Finck else 562*c2c66affSColin Finck { 563*c2c66affSColin Finck ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE, L"/PASSWORDREQ"); 564*c2c66affSColin Finck result = 1; 565*c2c66affSColin Finck goto done; 566*c2c66affSColin Finck } 567*c2c66affSColin Finck } 568*c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/profilepath:", 13) == 0) 569*c2c66affSColin Finck { 570*c2c66affSColin Finck pUserInfo->usri4_profile = &argv[j][13]; 571*c2c66affSColin Finck } 572*c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/scriptpath:", 12) == 0) 573*c2c66affSColin Finck { 574*c2c66affSColin Finck pUserInfo->usri4_script_path = &argv[j][12]; 575*c2c66affSColin Finck } 576*c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/times:", 7) == 0) 577*c2c66affSColin Finck { 578*c2c66affSColin Finck /* FIXME */ 579*c2c66affSColin Finck ConResPrintf(StdErr, IDS_ERROR_OPTION_NOT_SUPPORTED, L"/TIMES"); 580*c2c66affSColin Finck } 581*c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/usercomment:", 13) == 0) 582*c2c66affSColin Finck { 583*c2c66affSColin Finck pUserInfo->usri4_usr_comment = &argv[j][13]; 584*c2c66affSColin Finck } 585*c2c66affSColin Finck else if (_wcsnicmp(argv[j], L"/workstations:", 14) == 0) 586*c2c66affSColin Finck { 587*c2c66affSColin Finck /* FIXME */ 588*c2c66affSColin Finck ConResPrintf(StdErr, IDS_ERROR_OPTION_NOT_SUPPORTED, L"/WORKSTATIONS"); 589*c2c66affSColin Finck } 590*c2c66affSColin Finck } 591*c2c66affSColin Finck 592*c2c66affSColin Finck if (!bAdd && !bDelete) 593*c2c66affSColin Finck { 594*c2c66affSColin Finck /* Modify the user */ 595*c2c66affSColin Finck Status = NetUserSetInfo(NULL, 596*c2c66affSColin Finck lpUserName, 597*c2c66affSColin Finck 4, 598*c2c66affSColin Finck (LPBYTE)pUserInfo, 599*c2c66affSColin Finck NULL); 600*c2c66affSColin Finck ConPrintf(StdOut, L"Status: %lu\n", Status); 601*c2c66affSColin Finck } 602*c2c66affSColin Finck else if (bAdd && !bDelete) 603*c2c66affSColin Finck { 604*c2c66affSColin Finck /* Add the user */ 605*c2c66affSColin Finck Status = NetUserAdd(NULL, 606*c2c66affSColin Finck 4, 607*c2c66affSColin Finck (LPBYTE)pUserInfo, 608*c2c66affSColin Finck NULL); 609*c2c66affSColin Finck ConPrintf(StdOut, L"Status: %lu\n", Status); 610*c2c66affSColin Finck } 611*c2c66affSColin Finck else if (!bAdd && bDelete) 612*c2c66affSColin Finck { 613*c2c66affSColin Finck /* Delete the user */ 614*c2c66affSColin Finck Status = NetUserDel(NULL, 615*c2c66affSColin Finck lpUserName); 616*c2c66affSColin Finck ConPrintf(StdOut, L"Status: %lu\n", Status); 617*c2c66affSColin Finck } 618*c2c66affSColin Finck 619*c2c66affSColin Finck done: 620*c2c66affSColin Finck if ((bPasswordAllocated != FALSE) && (lpPassword != NULL)) 621*c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, lpPassword); 622*c2c66affSColin Finck 623*c2c66affSColin Finck if (!bAdd && !bDelete && pUserInfo != NULL) 624*c2c66affSColin Finck NetApiBufferFree(pUserInfo); 625*c2c66affSColin Finck 626*c2c66affSColin Finck if (result != 0) 627*c2c66affSColin Finck ConResPuts(StdOut, IDS_USER_SYNTAX); 628*c2c66affSColin Finck 629*c2c66affSColin Finck return result; 630*c2c66affSColin Finck } 631*c2c66affSColin Finck 632*c2c66affSColin Finck /* EOF */ 633