void DJManageDaemonsDescription( BOOLEAN bStart, PSTR *description, LWException **exc ) { BOOLEAN bFileExists = TRUE; LWException *innerExc = NULL; StringBuffer buffer; PSTR daemonDescription = NULL; LW_CLEANUP_CTERR(exc, CTStringBufferConstruct(&buffer)); LW_CLEANUP_CTERR(exc, CTCheckFileExists(PWGRD, &bFileExists)); if(bFileExists && bStart) { LW_CLEANUP_CTERR(exc, CTStringBufferAppend(&buffer, "Shutdown pwgrd because it only handles usernames up to 8 characters long. This is done by running '/sbin/init.d/pwgr stop' and setting PWGR=0 in "PWGRD".")); } *description = CTStringBufferFreeze(&buffer); cleanup: CT_SAFE_FREE_STRING(daemonDescription); LW_HANDLE(&innerExc); CTStringBufferDestroy(&buffer); }
DWORD DJFixLoginConfigFile( PCSTR pszPath ) { DWORD ceError = ERROR_SUCCESS; PCSTR pszFilePath = NULL; PSTR pszTmpPath = NULL; PSTR pszFinalPath = NULL; BOOLEAN bFileExists = FALSE; FILE* fp = NULL; FILE* fp_new = NULL; DynamicArray lines; PSTR currentSystem = NULL; memset(&lines, 0, sizeof(lines)); if (IsNullOrEmptyString(pszPath)) pszFilePath = LOGIN_CONFIG_PATH; else pszFilePath = pszPath; GCE(ceError = CTGetFileTempPath( pszFilePath, &pszFinalPath, &pszTmpPath)); GCE(ceError = CTCheckFileExists(pszFinalPath, &bFileExists)); if (!bFileExists) goto cleanup; GCE(ceError = CTOpenFile(pszFinalPath, "r", &fp)); GCE(ceError = CTReadLines(fp, &lines)); GCE(ceError = CTSafeCloseFile(&fp)); GCE(ceError = GetAuthType(&lines, ¤tSystem)); if(!strcmp(currentSystem, "PAM_AUTH")) goto cleanup; GCE(ceError = SetAuthType(&lines, "PAM_AUTH")); GCE(ceError = CTOpenFile(pszTmpPath, "w", &fp_new)); GCE(ceError = CTWriteLines(fp_new, &lines)); GCE(ceError = CTSafeCloseFile(&fp_new)); GCE(ceError = CTSafeReplaceFile(pszFilePath, pszTmpPath)); cleanup: CTSafeCloseFile(&fp); CTSafeCloseFile(&fp_new); CT_SAFE_FREE_STRING(currentSystem); CT_SAFE_FREE_STRING(pszTmpPath); CT_SAFE_FREE_STRING(pszFinalPath); CTFreeLines(&lines); return ceError; }
DWORD CTCheckFileOrLinkExists( PCSTR pszPath, PBOOLEAN pbExists ) { DWORD ceError = ERROR_SUCCESS; BAIL_ON_CENTERIS_ERROR(ceError = CTCheckFileExists(pszPath, pbExists)); if(*pbExists == TRUE) goto error; BAIL_ON_CENTERIS_ERROR(ceError = CTCheckLinkExists(pszPath, pbExists)); error: return ceError; }
static DWORD WriteHostnameToFiles( PSTR pszComputerName, PSTR* ppszHostfilePaths ) { DWORD ceError = ERROR_SUCCESS; PSTR pszFilePath = (ppszHostfilePaths ? *ppszHostfilePaths : NULL); BOOLEAN bFileExists = FALSE; FILE* fp = NULL; while (pszFilePath != NULL && *pszFilePath != '\0') { ceError = CTCheckFileExists(pszFilePath, &bFileExists); BAIL_ON_CENTERIS_ERROR(ceError); if (bFileExists) { fp = fopen(pszFilePath, "w"); if (fp == NULL) { ceError = LwMapErrnoToLwError(errno); BAIL_ON_CENTERIS_ERROR(ceError); } if (fprintf(fp, "%s\n", pszComputerName) < 0) { ceError = LwMapErrnoToLwError(errno); BAIL_ON_CENTERIS_ERROR(ceError); } fclose(fp); fp = NULL; } pszFilePath = *(++ppszHostfilePaths); } error: if (fp) { fclose(fp); } return ceError; }
static DWORD DJFlushCache( ) { DWORD ceError = ERROR_SUCCESS; int i; const char* cacheUtils[] = { "/usr/sbin/lookupd", /* Before Mac OS X 10.5 */ "/usr/bin/dscacheutil" /* On Mac OS X 10.5 */ }; DJ_LOG_INFO("Flushing dns cache"); for (i = 0; i < (sizeof(cacheUtils) / sizeof(cacheUtils[0])); i++) { const char* command = cacheUtils[i]; BOOLEAN exists; /* Sanity check */ if (!command) { continue; } ceError = CTCheckFileExists(command, &exists); BAIL_ON_CENTERIS_ERROR(ceError); if (!exists) { continue; } ceError = CTShell("%command -flushcache", CTSHELL_STRING(command, command)); /* Bail regardless */ goto error; } DJ_LOG_ERROR("Could not locate cache flush utility"); ceError = ERROR_FILE_NOT_FOUND; error: return ceError; }
static QueryResult QueryPamMode(const JoinProcessOptions *options, LWException **exc) { BOOLEAN bFileExists = FALSE; DistroInfo distro; QueryResult result = NotApplicable; FILE* fp = NULL; DynamicArray lines; PCSTR pszFilePath = LOGIN_CONFIG_PATH; PSTR currentSystem = NULL; memset(&lines, 0, sizeof(lines)); memset(&distro, 0, sizeof(distro)); if(!options->joiningDomain || options->enableMultipleJoins) goto cleanup; LW_CLEANUP_CTERR(exc, DJGetDistroInfo(NULL, &distro)); if(distro.os != OS_AIX || strcmp(distro.version, "5.3")) goto cleanup; LW_CLEANUP_CTERR(exc, CTCheckFileExists(pszFilePath, &bFileExists)); if (!bFileExists) goto cleanup; result = SufficientlyConfigured; LW_CLEANUP_CTERR(exc, CTOpenFile(pszFilePath, "r", &fp)); LW_CLEANUP_CTERR(exc, CTReadLines(fp, &lines)); LW_CLEANUP_CTERR(exc, CTSafeCloseFile(&fp)); LW_CLEANUP_CTERR(exc, GetAuthType(&lines, ¤tSystem)); if(strcmp(currentSystem, "PAM_AUTH")) goto cleanup; result = FullyConfigured; cleanup: CT_SAFE_FREE_STRING(currentSystem); DJFreeDistroInfo(&distro); CTSafeCloseFile(&fp); CTFreeLines(&lines); return result; }
static void FixNetworkInterfaces( PSTR pszComputerName, LWException **exc ) { DWORD ceError = ERROR_SUCCESS; int EE = 0; BOOLEAN bFileExists = FALSE; BOOLEAN bDirExists = FALSE; PSTR* ppszPaths = NULL; DWORD nPaths = 0; DWORD iPath = 0; CHAR szBuf[1024]; PSTR pszPathifcfg = NULL; BOOLEAN bDHCPHost = FALSE; PSTR pszMachineSID = NULL; PCSTR networkConfigPath = "/etc/sysconfig/network"; LW_CLEANUP_CTERR(exc, DJGetMachineSID(&pszMachineSID)); /* * fixup HOSTNAME variable in /etc/sysconfig/network file if it exists * note that 'network' is a *directory* on some dists (ie SUSE), * is a *file* on others (ie Redhat). weird. */ LW_CLEANUP_CTERR(exc, CTCheckFileExists(networkConfigPath, &bFileExists)); if (bFileExists) { sprintf(szBuf, "s/^.*\\(HOSTNAME\\).*=.*$/\\1=%s/", pszComputerName); LW_CLEANUP_CTERR(exc, CTRunSedOnFile(networkConfigPath, networkConfigPath, FALSE, szBuf)); } LW_CLEANUP_CTERR(exc, CTCheckDirectoryExists("/etc/sysconfig/network", &bDirExists)); if (!bDirExists) { LW_CLEANUP_CTERR(exc, CTCheckDirectoryExists("/etc/sysconfig/network-scripts", &bDirExists)); } if (bDirExists) { struct { PCSTR dir; PCSTR glob; } const searchPaths[] = { {"/etc/sysconfig/network", "ifcfg-eth-id-[^.]*$"}, {"/etc/sysconfig/network", "ifcfg-eth0[^.]*$"}, {"/etc/sysconfig/network", "ifcfg-eth[^.]*$"}, {"/etc/sysconfig/network", "ifcfg-eth-bus[^.]*$"}, //SLES 10.1 on zSeries uses one of: // /etc/sysconfig/network/ifcfg-qeth-bus-ccw-0.0.0500 // /etc/sysconfig/network/ifcfg-ctc-bus-ccw-0.0.0004 {"/etc/sysconfig/network", "ifcfg-qeth-bus.*\\.[0-9]\\+$"}, {"/etc/sysconfig/network", "ifcfg-ctc-bus.*\\.[0-9]\\+$"}, // Redhat uses /etc/sysconfig/network-scripts/ifcfg-eth<number> {"/etc/sysconfig/network-scripts", "ifcfg-eth[^.]*$"}, // RHEL 6 uses this {"/etc/sysconfig/network-scripts", "ifcfg-Auto_eth[^.]*$"}, // ESX 3.5 and 4.0 use // /etc/sysconfig/network-scripts/ifcfg-vswif<number> {"/etc/sysconfig/network-scripts", "ifcfg-vswif[^.]*$"}, // RHEL 7: network interface naming seems to be ensXX or enoXXXX, etc. {"/etc/sysconfig/network-scripts", "ifcfg-en[^.]*$"}, {NULL, NULL} }; // Find the ifcfg file pszPathifcfg = NULL; for(iPath = 0; searchPaths[iPath].dir != NULL && pszPathifcfg == NULL; iPath++) { if (ppszPaths) { CTFreeStringArray(ppszPaths, nPaths); ppszPaths = NULL; } ceError = CTGetMatchingFilePathsInFolder(searchPaths[iPath].dir, searchPaths[iPath].glob, &ppszPaths, &nPaths); if(ceError == ERROR_DIRECTORY) { ceError = ERROR_SUCCESS; continue; } LW_CLEANUP_CTERR(exc, ceError); if(nPaths > 0) { LW_CLEANUP_CTERR(exc, CTAllocateString(ppszPaths[0], &pszPathifcfg)); } } if (IsNullOrEmptyString(pszPathifcfg)) { LW_CLEANUP_CTERR(exc, ERROR_FILE_NOT_FOUND); } DJ_LOG_INFO("Found ifcfg file at %s", pszPathifcfg); LW_CLEANUP_CTERR(exc, DJCheckIfDHCPHost(pszPathifcfg, &bDHCPHost)); if (bDHCPHost) { LW_CLEANUP_CTERR(exc, DJFixDHCPHost(pszPathifcfg, pszComputerName)); } } ceError = CTShell("/bin/hostname %hostname >/dev/null", CTSHELL_STRING(hostname, pszComputerName)); LW_CLEANUP_CTERR(exc, ceError); // Only DHCP boxes need to restart their networks if (bDHCPHost) { LW_CLEANUP_CTERR(exc, DJConfigureDHCPService(pszComputerName)); } cleanup: // This ensures that we do not change the SID after a machine name // change. The issue here is that Samba implements its SAM such that // a machine name change changes the seeding used for the machine SID. // Therefore, we must re-store the old SID with the new machine name // seed. if (pszMachineSID) { if (*pszMachineSID != '\0') DJSetMachineSID(pszMachineSID); CTFreeString(pszMachineSID); } if (ppszPaths) CTFreeStringArray(ppszPaths, nPaths); if (pszPathifcfg) CTFreeString(pszPathifcfg); DJ_LOG_VERBOSE("FixNetworkInterfaces LEAVE -> 0x%08x (EE = %d)", ceError, EE); }
static DWORD DJConfigureDHCPService( PSTR pszComputerName ) { DWORD ceError = ERROR_SUCCESS; int EE = 0; BOOLEAN bFileExists = FALSE; PSTR dhcpFilePath = "/etc/sysconfig/network/dhcp"; PSTR ppszArgs[] = { "/bin/sed", "s/^.*\\(DHCLIENT_SET_HOSTNAME\\).*=.*$/\\1=\\\"no\\\"/", dhcpFilePath, NULL }; #if !defined(HAVE_SETHOSTNAME) || !HAVE_DECL_SETHOSTNAME PSTR ppszNetArgs[] = { #if defined(_AIX) "/etc/rc.d/init.d/network", #else "/etc/init.d/network", #endif "restart", NULL }; #endif PPROCINFO pProcInfo = NULL; LONG status = 0; PSTR pszFinalPath = NULL; PSTR pszTmpPath = NULL; ceError = CTCheckFileExists(dhcpFilePath, &bFileExists); CLEANUP_ON_DWORD_EE(ceError, EE); if (bFileExists) { ceError = CTGetFileTempPath( dhcpFilePath, &pszFinalPath, &pszTmpPath); CLEANUP_ON_DWORD_EE(ceError, EE); ppszArgs[2] = pszFinalPath; ceError = DJSpawnProcessOutputToFile(ppszArgs[0], ppszArgs, pszTmpPath, &pProcInfo); CLEANUP_ON_DWORD_EE(ceError, EE); ceError = DJGetProcessStatus(pProcInfo, &status); CLEANUP_ON_DWORD_EE(ceError, EE); if (status != 0) { ceError = ERROR_FAIL_RESTART; CLEANUP_ON_DWORD_EE(ceError, EE); } ceError = CTSafeReplaceFile(pszFinalPath, pszTmpPath); CLEANUP_ON_DWORD_EE(ceError, EE); } if (pProcInfo) { FreeProcInfo(pProcInfo); pProcInfo = NULL; } #if defined(HAVE_SETHOSTNAME) && HAVE_DECL_SETHOSTNAME if (sethostname(pszComputerName, strlen(pszComputerName)) < 0) { ceError = LwMapErrnoToLwError(errno); CLEANUP_ON_DWORD_EE(ceError, EE); } #else ceError = DJFixNetworkManagerOnlineTimeout(); CLEANUP_ON_DWORD_EE(ceError, EE); /* Restart network */ ceError = DJSpawnProcess(ppszNetArgs[0], ppszNetArgs, &pProcInfo); CLEANUP_ON_DWORD_EE(ceError, EE); ceError = DJGetProcessStatus(pProcInfo, &status); CLEANUP_ON_DWORD_EE(ceError, EE); if (status != 0) { ceError = ERROR_BAD_COMMAND; CLEANUP_ON_DWORD_EE(ceError, EE); } #endif cleanup: if (pProcInfo) FreeProcInfo(pProcInfo); DJ_LOG_VERBOSE("DJRestartDHCPService LEAVE -> 0x%08x (EE = %d)", ceError, EE); CT_SAFE_FREE_STRING(pszFinalPath); CT_SAFE_FREE_STRING(pszTmpPath); return ceError; }
static DWORD DJFixNetworkManagerOnlineTimeout( ) { DWORD ceError = ERROR_SUCCESS; PSTR pszFilePath = "/etc/sysconfig/network/config"; DWORD dwTimeout = 60; int EE = 0; BOOLEAN bFileExists = FALSE; char *isEnabled = NULL; char *currentTimeout = NULL; char *sedExpression = NULL; long currentTimeoutLong; char *conversionEnd; ceError = CTCheckFileExists(pszFilePath, &bFileExists); CLEANUP_ON_DWORD_EE(ceError, EE); if(!bFileExists) goto cleanup; ceError = CTShell(". %pszFilePath; echo \"$NETWORKMANAGER\" >%enabled; echo \"$NM_ONLINE_TIMEOUT\" >%timeout", CTSHELL_STRING (pszFilePath, pszFilePath), CTSHELL_BUFFER (enabled, &isEnabled), CTSHELL_BUFFER (timeout, ¤tTimeout)); CLEANUP_ON_DWORD_EE(ceError, EE); CTStripTrailingWhitespace(isEnabled); CTStripTrailingWhitespace(currentTimeout); DJ_LOG_VERBOSE("Network manager enabled [%s] network manager timeout [%s]", isEnabled, currentTimeout); if(strcasecmp(isEnabled, "yes")) { DJ_LOG_INFO("Network manager is not enabled"); goto cleanup; } currentTimeoutLong = strtol(currentTimeout, &conversionEnd, 10); if(*conversionEnd != '\0') { DJ_LOG_INFO("Unable to convert network manager timeout to long"); currentTimeoutLong = 0; } if(currentTimeoutLong < dwTimeout) { DJ_LOG_INFO("Setting network manager timeout to %d", dwTimeout); ceError = CTAllocateStringPrintf(&sedExpression, "s/^\\([ \t]*NM_ONLINE_TIMEOUT[ \t]*=[ \t]*\\).*$/\\1%d/", dwTimeout); CLEANUP_ON_DWORD_EE(ceError, EE); ceError = CTRunSedOnFile(pszFilePath, pszFilePath, FALSE, sedExpression); CLEANUP_ON_DWORD_EE(ceError, EE); } cleanup: DJ_LOG_VERBOSE("DJFixNetworkManagerOnlineTimeout LEAVE -> 0x%08x (EE = %d)", ceError, EE); CT_SAFE_FREE_STRING(isEnabled); CT_SAFE_FREE_STRING(currentTimeout); CT_SAFE_FREE_STRING(sedExpression); return ceError; }
DWORD ReadNsswitchConf(NsswitchConf *conf, const char *testPrefix, BOOLEAN allowFileCreate) { PSTR copyDestPath = NULL; PSTR defaultFilePath = NULL; DWORD ceError = ERROR_SUCCESS; BOOLEAN bFileExists = FALSE; memset(conf, 0, sizeof(*conf)); //Keep trying to read different filenames until one of them is found if(!bFileExists) { bFileExists = TRUE; ceError = ReadNsswitchFile(conf, testPrefix, "/etc/nsswitch.conf"); if(ceError == ERROR_FILE_NOT_FOUND) { bFileExists = FALSE; ceError = ERROR_SUCCESS; } GCE(ceError); } if(!bFileExists) { bFileExists = TRUE; ceError = ReadNsswitchFile(conf, testPrefix, "/etc/netsvc.conf"); if(ceError == ERROR_FILE_NOT_FOUND) { bFileExists = FALSE; ceError = ERROR_SUCCESS; } GCE(ceError); } /* HP-UX 11.xx does not appear to have an nsswitch file in place by default. If we don't find on already installed, use our own */ if(!bFileExists) { GCE(ceError = CTAllocateStringPrintf( &defaultFilePath, "%s%s", testPrefix, NSSWITCH_LWIDEFAULTS)); GCE(ceError = CTCheckFileExists(defaultFilePath, &bFileExists)); if (bFileExists) { ceError = ReadNsswitchFile(conf, testPrefix, NSSWITCH_LWIDEFAULTS); GCE(ceError); CT_SAFE_FREE_STRING(conf->filename); conf->modified = TRUE; if(allowFileCreate) { GCE(ceError = CTStrdup(NSSWITCH_CONF_PATH, &conf->filename)); /* Copy over the original file. This way the user can more * clearly see what we changed by comparing nsswitch.conf with * nsswitch.conf.lwidentity.orig. Also, the permissions will be * correct this way when the file is written out. */ DJ_LOG_INFO("Copying default nsswitch file"); GCE(ceError = CTAllocateStringPrintf( ©DestPath, "%s%s", testPrefix, NSSWITCH_CONF_PATH)); ceError = CTCopyFileWithOriginalPerms(defaultFilePath, copyDestPath); GCE(ceError); } else { GCE(ceError = CTStrdup(NSSWITCH_LWIDEFAULTS, &conf->filename)); } } } if(!bFileExists) { GCE(ceError = ERROR_FILE_NOT_FOUND); } cleanup: CT_SAFE_FREE_STRING(copyDestPath); CT_SAFE_FREE_STRING(defaultFilePath); return ceError; }
void DJManageDaemons( BOOLEAN bStart, LWException **exc ) { BOOLEAN bFileExists = TRUE; FILE* fp = NULL; LWException *innerExc = NULL; int i; PLSA_LOG_INFO pLogInfo = NULL; BOOLEAN bLsassContacted = FALSE; DWORD dwError = 0; LW_HANDLE hLsa = NULL; LW_CLEANUP_CTERR(exc, CTCheckFileExists(PWGRD, &bFileExists)); if(bFileExists) { //Shutdown pwgr (a nscd-like daemon) on HP-UX because it only handles //usernames up to 8 characters in length. LW_TRY(exc, DJStartStopDaemon("pwgr", FALSE, &LW_EXC)); LW_CLEANUP_CTERR(exc, CTRunSedOnFile(PWGRD, PWGRD, FALSE, "s/=1/=0/")); } if(bStart) { // Set registry value for gpagentd to autostart. dwError = SetBooleanRegistryValue("Services\\gpagent", "Autostart", TRUE); // Trigger gpagentd start dwError = DJStartService("gpagent"); // Make sure lsass is responding bLsassContacted = FALSE; for (i = 0; !bLsassContacted && i < 30; i++) { DJ_LOG_INFO("Trying to contact lsassd"); if (hLsa) { LsaCloseServer(hLsa); hLsa = NULL; } dwError = LsaOpenServer(&hLsa); if (dwError == ERROR_FILE_NOT_FOUND || dwError == LW_ERROR_ERRNO_ECONNREFUSED) { DJ_LOG_INFO("Failed with %d", dwError); dwError = 0; sleep(1); continue; } LW_CLEANUP_CTERR(exc, dwError); LW_CLEANUP_CTERR(exc, LsaGetLogInfo(hLsa, &pLogInfo)); bLsassContacted = TRUE; } if (!bLsassContacted) { LW_RAISE_EX(exc, ERROR_SERVICE_NOT_ACTIVE, "Unable to reach lsassd", "The lsass daemon could not be reached for 30 seconds after trying to start it. Please verify it is running."); goto cleanup; } } else { dwError = SetBooleanRegistryValue("Services\\gpagent", "Autostart", FALSE); dwError = DJStopService("gpagent"); } cleanup: CTSafeCloseFile(&fp); if (pLogInfo) { LsaFreeLogInfo(pLogInfo); } if (hLsa) { LsaCloseServer(hLsa); } LW_HANDLE(&innerExc); }
DWORD CTIsProgramRunning( PCSTR pszPidFile, PCSTR pszProgramName, pid_t *pPid, PBOOLEAN pbRunning ) { DWORD ceError = ERROR_SUCCESS; pid_t pid = 0; int fd = -1; int result; char contents[20]; BOOLEAN bFileExists = FALSE; if(pbRunning != NULL) *pbRunning = FALSE; if(pPid != NULL) *pPid = -1; ceError = CTCheckFileExists(pszPidFile, &bFileExists); BAIL_ON_CENTERIS_ERROR(ceError); if (bFileExists) { fd = open(pszPidFile, O_RDONLY, 0644); if (fd < 0) { ceError = LwMapErrnoToLwError(errno); BAIL_ON_CENTERIS_ERROR(ceError); } result = read(fd, contents, sizeof(contents)-1); if (result < 0) { ceError = LwMapErrnoToLwError(errno); BAIL_ON_CENTERIS_ERROR(ceError); } else if (result > 0) { contents[result-1] = 0; result = atoi(contents); } if (result <= 0) { ceError = ERROR_PROC_NOT_FOUND; BAIL_ON_CENTERIS_ERROR(ceError); } pid = (pid_t) result; result = kill(pid, 0); if (!result) { // Verify that the peer process is the auth daemon ceError = CTMatchProgramToPID(pszProgramName, pid); BAIL_ON_CENTERIS_ERROR(ceError); if(pbRunning != NULL) { *pbRunning = TRUE; } if ( pPid ) { *pPid = pid; } } else if (errno == ESRCH) { ceError = ERROR_PROC_NOT_FOUND; BAIL_ON_CENTERIS_ERROR(ceError); } else { ceError = LwMapErrnoToLwError(errno); BAIL_ON_CENTERIS_ERROR(ceError); } } error: if (fd != -1) { close(fd); } return (ceError == ERROR_PROC_NOT_FOUND ? ERROR_SUCCESS : ceError); }