int LeaveMain( int argc, const char** argv ) { DWORD dwError = 0; LEAVE_ARGS args = { 0 }; dwError = ParseLeaveArgs(argc, argv, &args); GOTO_CLEANUP_ON_WINERROR(dwError); dwError = DoLeaveDomain( args.pszDomain, args.pszUsername, args.pszPassword, args.JoinFlags); GOTO_CLEANUP_ON_WINERROR(dwError); cleanup: if (dwError) { PrintError(dwError); } FreeLeaveArgsContents(&args); return dwError ? 1 : 0; }
static DWORD DoLeaveDomain( IN PCSTR pszDomain, IN OPTIONAL PCSTR pszUsername, IN OPTIONAL PCSTR pszPassword, IN LSA_NET_JOIN_FLAGS JoinFlags ) { HANDLE hLsa = NULL; DWORD dwError = 0; PCSTR pszUseDomain = IsSetFlag(JoinFlags, LSA_NET_JOIN_DOMAIN_MULTIPLE) ? pszDomain : NULL; assert(pszDomain); printf("Leaving AD Domain: %s\n", pszDomain); dwError = LsaOpenServer(&hLsa); GOTO_CLEANUP_ON_WINERROR(dwError); dwError = LsaAdLeaveDomain2(hLsa, pszUsername, pszPassword, pszUseDomain, JoinFlags); GOTO_CLEANUP_ON_WINERROR(dwError); printf("SUCCESS\n"); cleanup: if (hLsa) { LsaCloseServer(hLsa); } return dwError; }
int JoinMain( int argc, const char** argv ) { DWORD dwError = 0; JOIN_ARGS args = { 0 }; dwError = ParseJoinArgs(argc, argv, &args); GOTO_CLEANUP_ON_WINERROR(dwError); dwError = DoJoinDomain( args.pszDomain, args.pszUsername, args.pszPassword, args.pszMachineName, args.pszDnsSuffix, args.pszOu, args.pszOsName, args.pszOsVersion, args.pszOsServicePack, args.JoinFlags); GOTO_CLEANUP_ON_WINERROR(dwError); cleanup: if (dwError) { PrintError(dwError); } FreeJoinArgsContents(&args); return dwError ? 1 : 0; }
static DWORD LwpsConvertTimeWindowsToUnix( IN LONG64 WindowsTime, OUT time_t* pUnixTime ) { DWORD dwError = 0; LONG64 unixTime = 0; if (WindowsTime < 0) { dwError = ERROR_INVALID_PARAMETER; GOTO_CLEANUP_ON_WINERROR(dwError); } unixTime = WindowsTime/10000000LL - 11644473600LL; // Ensure the range is within time_t. if (unixTime != (time_t) unixTime) { dwError = ERROR_ARITHMETIC_OVERFLOW; GOTO_CLEANUP_ON_WINERROR(dwError); } cleanup: if (dwError) { unixTime = 0; } *pUnixTime = (time_t) unixTime; return 0; }
static DWORD LsaPstorepGetPluginNames( OUT PSTR** Names, OUT PDWORD Count ) { DWORD dwError = 0; HANDLE registryConnection = NULL; HKEY keyHandle = NULL; PSTR* loadOrder = NULL; DWORD loadOrderCount = 0; dwError = LwRegOpenServer(®istryConnection); GOTO_CLEANUP_ON_WINERROR(dwError); dwError = LwRegOpenKeyExA( registryConnection, NULL, LSA_PSTORE_REG_KEY_PATH_PLUGINS, 0, GENERIC_READ, &keyHandle); if (dwError == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE) { dwError = 0; GOTO_CLEANUP(); } GOTO_CLEANUP_ON_WINERROR(dwError); dwError = LsaPstorepRegGetMultiStringA( registryConnection, keyHandle, LSA_PSTORE_REG_VALUE_NAME_PLUGINS_LOAD_ORDER, &loadOrder, &loadOrderCount); if (dwError == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE) { dwError = 0; } GOTO_CLEANUP_ON_WINERROR(dwError); cleanup: if (dwError) { LSA_PSTORE_FREE_STRING_ARRAY_A(&loadOrder, &loadOrderCount); } *Names = loadOrder; *Count = loadOrderCount; return dwError; }
static DWORD GetCurrentDomain( OUT PSTR* ppszDnsDomainName ) { DWORD dwError = 0; HANDLE hLsa = NULL; PLSA_MACHINE_ACCOUNT_INFO_A pAccountInfo = NULL; PSTR pszDnsDomainName = NULL; dwError = LsaOpenServer(&hLsa); GOTO_CLEANUP_ON_WINERROR(dwError); dwError = LsaAdGetMachineAccountInfo(hLsa, NULL, &pAccountInfo); GOTO_CLEANUP_ON_WINERROR(dwError); dwError = LwAllocateString( pAccountInfo->DnsDomainName, &pszDnsDomainName); GOTO_CLEANUP_ON_WINERROR(dwError); cleanup: if (dwError) { LW_SAFE_FREE_MEMORY(pszDnsDomainName); } if (hLsa) { LsaCloseServer(hLsa); } if (pAccountInfo) { LsaAdFreeMachineAccountInfo(pAccountInfo); } *ppszDnsDomainName = pszDnsDomainName; return dwError; }
static DWORD CleanupUsername( IN PCSTR pszDomain, IN OUT PSTR* ppszUsername ) { DWORD dwError = 0; PSTR pszOldUsername = *ppszUsername; PSTR pszNewUsername = NULL; // Fix up username and prompt for password, if needed. if (pszOldUsername) { PSTR at = NULL; if (strchr(pszOldUsername, '\\')) { fprintf(stderr, "The USERNAME (%s) is not allowed to contain a backslash.\n", pszOldUsername); exit(1); } at = strchr(pszOldUsername, '@'); if (at) { LwStrToUpper(at); } else { dwError = LwAllocateStringPrintf( &pszNewUsername, "%s@%s", pszOldUsername, pszDomain); GOTO_CLEANUP_ON_WINERROR(dwError); } } cleanup: if (dwError) { LW_SAFE_FREE_MEMORY(pszNewUsername); } if (pszNewUsername) { LW_SAFE_FREE_MEMORY(*ppszUsername); *ppszUsername = pszNewUsername; } return dwError; }
static DWORD LwpsConvertTimeUnixToWindows( IN time_t UnixTime, OUT PLONG64 pWindowsTime ) { DWORD dwError = 0; LONG64 windowsTime = 0; #if SIZEOF_TIME_T > 4 if ((LONG64) UnixTime < - 11644473600LL) { dwError = ERROR_INVALID_PARAMETER; GOTO_CLEANUP_ON_WINERROR(dwError); } #endif windowsTime = (LONG64) UnixTime + 11644473600LL; if (windowsTime < 0) { dwError = ERROR_ARITHMETIC_OVERFLOW; GOTO_CLEANUP_ON_WINERROR(dwError); } windowsTime *= 10000000LL; if (windowsTime < 0) { dwError = ERROR_ARITHMETIC_OVERFLOW; GOTO_CLEANUP_ON_WINERROR(dwError); } cleanup: if (dwError) { windowsTime = 0; } *pWindowsTime = windowsTime; return 0; }
static DWORD GetArgumentValue( IN PCSTR pszProgramName, IN SHOW_USAGE_CALLBACK ShowUsageError, IN OUT PLW_ARGV_CURSOR pCursor, IN OPTIONAL PCSTR pszArgumentName, OUT PSTR* ppszArgumentValue ) { DWORD dwError = 0; PSTR result = NULL; PCSTR value = LwArgvCursorPop(pCursor); if (!value) { if (pszArgumentName) { fprintf(stderr, "Missing %s argument.\n", pszArgumentName); ShowUsageError(pszProgramName); } } else { dwError = LwAllocateString(value, &result); GOTO_CLEANUP_ON_WINERROR(dwError); } cleanup: if (dwError) { LW_SAFE_FREE_MEMORY(result); } *ppszArgumentValue = result; return dwError; }
static DWORD GetHostname( OUT PSTR* ppszHostname ) { DWORD dwError = 0; CHAR buffer[1024] = { 0 }; PSTR dot = NULL; PSTR pszHostname = NULL; if (gethostname(buffer, sizeof(buffer) - 1) == -1) { dwError = LwErrnoToWin32Error(errno); assert(dwError); GOTO_CLEANUP(); } dot = strchr(buffer, '.'); if (dot) { *dot = 0; } dwError = LwAllocateString(buffer, &pszHostname); GOTO_CLEANUP_ON_WINERROR(dwError); cleanup: if (dwError) { LW_SAFE_FREE_STRING(pszHostname); } *ppszHostname = pszHostname; return dwError; }
static DWORD ParseLeaveArgs( IN int argc, IN const char *argv[], OUT PLEAVE_ARGS pArgs ) { DWORD dwError = 0; PCSTR programName = NULL; PCSTR option = NULL; LW_ARGV_CURSOR cursor; SHOW_USAGE_CALLBACK ShowUsageHelp = ShowLeaveUsageHelp; SHOW_USAGE_CALLBACK ShowUsageError = ShowLeaveUsageError; memset(pArgs, 0, sizeof(*pArgs)); LwArgvCursorInit(&cursor, argc, argv); programName = LwArgvCursorPop(&cursor); // Process options: for (;;) { option = PopNextOption(&cursor); if (!option) { break; } else if (IsHelpOption(option)) { ShowUsageHelp(programName); } else if (!strcmp("--multiple", option)) { SetFlag(pArgs->JoinFlags, LSA_NET_JOIN_DOMAIN_MULTIPLE); dwError = GetOptionValue(programName, ShowUsageError, &cursor, option, &pArgs->pszDomain); GOTO_CLEANUP_ON_WINERROR(dwError); LwStrToUpper(pArgs->pszDomain); } else { fprintf(stderr, "Unrecognized option: %s\n", option); ShowUsageError(programName); } } // Optional arguments dwError = GetArgumentValue(programName, ShowUsageError, &cursor, NULL, &pArgs->pszUsername); assert(!dwError); dwError = GetArgumentValue(programName, ShowUsageError, &cursor, NULL, &pArgs->pszPassword); assert(!dwError); if (LwArgvCursorRemaining(&cursor)) { fprintf(stderr, "Too many arguments.\n"); ShowUsageError(programName); } // Initialize implicit domain argument. if (!pArgs->pszDomain) { dwError = GetCurrentDomain(&pArgs->pszDomain); if (NERR_SetupNotJoined == dwError) { fprintf(stderr, "The computer is not joined to a domain.\n"); exit(1); } GOTO_CLEANUP_ON_WINERROR(dwError); } // If USERNAME was specified, clean it up and get password // as needed. if (pArgs->pszUsername) { dwError = CleanupUsername(pArgs->pszDomain, &pArgs->pszUsername); GOTO_CLEANUP_ON_WINERROR(dwError); if (!pArgs->pszPassword) { dwError = PromptPassword(pArgs->pszUsername, &pArgs->pszPassword); GOTO_CLEANUP_ON_WINERROR(dwError); } } cleanup: if (dwError) { FreeLeaveArgsContents(pArgs); } return dwError; }
static DWORD ParseJoinArgs( IN int argc, IN const char *argv[], OUT PJOIN_ARGS pArgs ) { DWORD dwError = 0; PCSTR programName = NULL; PCSTR option = NULL; LW_ARGV_CURSOR cursor; SHOW_USAGE_CALLBACK ShowUsageHelp = ShowJoinUsageHelp; SHOW_USAGE_CALLBACK ShowUsageError = ShowJoinUsageError; memset(pArgs, 0, sizeof(*pArgs)); LwArgvCursorInit(&cursor, argc, argv); programName = LwArgvCursorPop(&cursor); // Process options: for (;;) { option = PopNextOption(&cursor); if (!option) { break; } else if (IsHelpOption(option)) { ShowUsageHelp(programName); } else if (!strcmp("--name", option)) { dwError = GetOptionValue(programName, ShowUsageError, &cursor, option, &pArgs->pszMachineName); GOTO_CLEANUP_ON_WINERROR(dwError); } else if (!strcmp("--dnssuffix", option)) { dwError = GetOptionValue(programName, ShowUsageError, &cursor, option, &pArgs->pszDnsSuffix); GOTO_CLEANUP_ON_WINERROR(dwError); } else if (!strcmp("--ou", option)) { dwError = GetOptionValue(programName, ShowUsageError, &cursor, option, &pArgs->pszOu); GOTO_CLEANUP_ON_WINERROR(dwError); } else if (!strcmp("--osname", option)) { dwError = GetOptionValue(programName, ShowUsageError, &cursor, option, &pArgs->pszOsName); GOTO_CLEANUP_ON_WINERROR(dwError); } else if (!strcmp("--osversion", option)) { dwError = GetOptionValue(programName, ShowUsageError, &cursor, option, &pArgs->pszOsVersion); GOTO_CLEANUP_ON_WINERROR(dwError); } else if (!strcmp("--osservicepack", option)) { dwError = GetOptionValue(programName, ShowUsageError, &cursor, option, &pArgs->pszOsServicePack); GOTO_CLEANUP_ON_WINERROR(dwError); } else if (!strcmp("--notimesync", option)) { SetFlag(pArgs->JoinFlags, LSA_NET_JOIN_DOMAIN_NOTIMESYNC); } else if (!strcmp("--multiple", option)) { SetFlag(pArgs->JoinFlags, LSA_NET_JOIN_DOMAIN_NOTIMESYNC); SetFlag(pArgs->JoinFlags, LSA_NET_JOIN_DOMAIN_MULTIPLE); } else { fprintf(stderr, "Unrecognized option: %s\n", option); ShowUsageError(programName); } } // Process arguments: dwError = GetArgumentValue(programName, ShowUsageError, &cursor, "DOMAIN", &pArgs->pszDomain); GOTO_CLEANUP_ON_WINERROR(dwError); LwStrToUpper(pArgs->pszDomain); dwError = GetArgumentValue(programName, ShowUsageError, &cursor, "USERNAME", &pArgs->pszUsername); GOTO_CLEANUP_ON_WINERROR(dwError); // Optional argument dwError = GetArgumentValue(programName, ShowUsageError, &cursor, NULL, &pArgs->pszPassword); assert(!dwError); if (LwArgvCursorRemaining(&cursor)) { fprintf(stderr, "Too many arguments.\n"); ShowUsageError(programName); } // Initialize missing options as needed if (!pArgs->pszDnsSuffix) { dwError = LwAllocateString(pArgs->pszDomain, &pArgs->pszDnsSuffix); GOTO_CLEANUP_ON_WINERROR(dwError); } LwStrToLower(pArgs->pszDnsSuffix); if (!pArgs->pszMachineName) { dwError = GetHostname(&pArgs->pszMachineName); GOTO_CLEANUP_ON_WINERROR(dwError); } if (!pArgs->pszOsName || !pArgs->pszOsVersion || !pArgs->pszOsServicePack) { dwError = GetOsInfo( pArgs->pszOsName ? NULL : &pArgs->pszOsName, pArgs->pszOsVersion ? NULL : &pArgs->pszOsVersion, pArgs->pszOsServicePack ? NULL : &pArgs->pszOsServicePack); GOTO_CLEANUP_ON_WINERROR(dwError); } dwError = CleanupUsername(pArgs->pszDomain, &pArgs->pszUsername); GOTO_CLEANUP_ON_WINERROR(dwError); if (!pArgs->pszPassword) { dwError = PromptPassword(pArgs->pszUsername, &pArgs->pszPassword); GOTO_CLEANUP_ON_WINERROR(dwError); } cleanup: if (dwError) { FreeJoinArgsContents(pArgs); } return dwError; }
static DWORD GetPassword( OUT PSTR* ppszPassword ) { DWORD dwError = 0; CHAR buffer[129] = { 0 }; int i = 0; BOOLEAN needReset = FALSE; struct termios oldAttributes; struct termios newAttributes; PSTR pszPassword = NULL; if (tcgetattr(0, &oldAttributes) == -1) { dwError = LwErrnoToWin32Error(errno); assert(dwError); GOTO_CLEANUP(); } newAttributes = oldAttributes; ClearFlag(newAttributes.c_lflag, ECHO); if (tcsetattr(0, TCSANOW, &newAttributes) == -1) { dwError = LwErrnoToWin32Error(errno); assert(dwError); GOTO_CLEANUP(); } needReset = TRUE; for (i = 0; i < (sizeof(buffer) - 1); i++) { if (read(0, &buffer[i], 1)) { if (buffer[i] == '\n') { buffer[i] = 0; break; } } else { dwError = LwErrnoToWin32Error(errno); assert(dwError); GOTO_CLEANUP(); } } if (i == (sizeof(buffer) - 1)) { dwError = LwErrnoToWin32Error(ENOBUFS); assert(dwError); GOTO_CLEANUP(); } dwError = LwAllocateString(buffer, &pszPassword); GOTO_CLEANUP_ON_WINERROR(dwError); cleanup: if (dwError) { LW_SAFE_FREE_MEMORY(pszPassword); } if (needReset) { if (tcsetattr(0, TCSANOW, &oldAttributes) == -1) { assert(0); } } *ppszPassword = pszPassword; return dwError; }
static DWORD DoJoinDomain( IN PCSTR pszDomain, IN PCSTR pszUsername, IN PCSTR pszPassword, IN PCSTR pszMachineName, IN PCSTR pszDnsSuffix, IN OPTIONAL PCSTR pszOu, IN PCSTR pszOsName, IN PCSTR pszOsVersion, IN PCSTR pszOsServicePack, IN LSA_NET_JOIN_FLAGS JoinFlags ) { DWORD dwError = 0; HANDLE hLsa = NULL; PSTR pszCurrentDomain = NULL; assert(pszDomain); assert(pszUsername); assert(pszPassword); assert(pszMachineName); assert(pszDnsSuffix); assert(pszOsName); assert(pszOsVersion); assert(pszOsServicePack); printf("Joining to AD Domain: %s\n" "With Computer DNS Name: %s.%s\n\n", pszDomain, pszMachineName, pszDnsSuffix); dwError = LsaOpenServer(&hLsa); GOTO_CLEANUP_ON_WINERROR(dwError); dwError = LsaAdJoinDomain( hLsa, pszMachineName, pszDnsSuffix, pszDomain, pszOu, pszUsername, pszPassword, pszOsName, pszOsVersion, pszOsServicePack, JoinFlags); GOTO_CLEANUP_ON_WINERROR(dwError); printf("SUCCESS!\n"); dwError = GetCurrentDomain(&pszCurrentDomain); GOTO_CLEANUP_ON_WINERROR(dwError); printf("Your computer is now joined to '%s'\n", pszCurrentDomain); cleanup: if (hLsa) { LsaCloseServer(hLsa); } LW_SAFE_FREE_MEMORY(pszCurrentDomain); return dwError; }
static DWORD GetOsInfo( OUT OPTIONAL PSTR* ppszOsName, OUT OPTIONAL PSTR* ppszOsVersion, OUT OPTIONAL PSTR* ppszOsServicePack ) { DWORD dwError = 0; struct utsname utsBuffer = { { 0 } }; PSTR pszOsName = NULL; PSTR pszOsVersion = NULL; PSTR pszOsServicePack = NULL; if (uname(&utsBuffer) == -1) { dwError = LwErrnoToWin32Error(errno); assert(dwError); GOTO_CLEANUP(); } if (ppszOsName) { dwError = LwAllocateString(utsBuffer.sysname, &pszOsName); GOTO_CLEANUP_ON_WINERROR(dwError); } if (ppszOsVersion) { if (!strcmp(utsBuffer.sysname, "AIX")) { dwError = LwAllocateStringPrintf( &pszOsVersion, "%s.%s", utsBuffer.version, utsBuffer.release); GOTO_CLEANUP_ON_WINERROR(dwError); } else { dwError = LwAllocateString(utsBuffer.release, &pszOsVersion); GOTO_CLEANUP_ON_WINERROR(dwError); } } if (ppszOsServicePack) { if (!strcmp(utsBuffer.sysname, "AIX")) { dwError = LwAllocateString("", &pszOsServicePack); GOTO_CLEANUP_ON_WINERROR(dwError); } else { dwError = LwAllocateString(utsBuffer.version, &pszOsServicePack); GOTO_CLEANUP_ON_WINERROR(dwError); } } cleanup: if (dwError) { LW_SAFE_FREE_STRING(pszOsName); LW_SAFE_FREE_STRING(pszOsVersion); LW_SAFE_FREE_STRING(pszOsServicePack); } if (ppszOsName) { *ppszOsName = pszOsName; } if (ppszOsVersion) { *ppszOsVersion = pszOsVersion; } if (ppszOsServicePack) { *ppszOsServicePack = pszOsServicePack; } return dwError; }