DWORD LsaCheckInvalidRpcServer( PVOID pSymbol, PCSTR pszLibPath ) { DWORD dwError = 0; PCSTR pszError = NULL; if (pSymbol == NULL) { LSA_LOG_ERROR("Ignoring invalid rpc server at path [%s]", (pszLibPath ? pszLibPath : "(unknown)")); pszError = dlerror(); if (!LW_IS_NULL_OR_EMPTY_STR(pszError)) { LSA_LOG_ERROR("%s", pszError); } dwError = LW_ERROR_INVALID_RPC_SERVER; BAIL_ON_LSA_ERROR(dwError); } cleanup: return dwError; error: goto cleanup; }
static void lsa_locking_function(int mode, int n, const char* file, int line) { if (mode & CRYPTO_LOCK) { pthread_mutex_lock(&gmutex_buf[n]); } else if (mode & CRYPTO_UNLOCK) { pthread_mutex_unlock(&gmutex_buf[n]); } else { LSA_LOG_ERROR("Unknown OpenSSL lock mode 0x%x", mode); } }
static DWORD ValidateAndSetLogLevel( PCSTR pszName, PCSTR pszValue ) { DWORD dwError = 0; LSA_LOG_INFO LogInfo = {}; if (!strcasecmp(pszValue, "error")) { LogInfo.maxAllowedLogLevel = LSA_LOG_LEVEL_ERROR; } else if (!strcasecmp(pszValue, "warning")) { LogInfo.maxAllowedLogLevel = LSA_LOG_LEVEL_WARNING; } else if (!strcasecmp(pszValue, "info")) { LogInfo.maxAllowedLogLevel = LSA_LOG_LEVEL_INFO; } else if (!strcasecmp(pszValue, "verbose")) { LogInfo.maxAllowedLogLevel = LSA_LOG_LEVEL_VERBOSE; } else if (!strcasecmp(pszValue, "debug")) { LogInfo.maxAllowedLogLevel = LSA_LOG_LEVEL_DEBUG; } else if (!strcasecmp(pszValue, "trace")) { LogInfo.maxAllowedLogLevel = LSA_LOG_LEVEL_TRACE; } else { LSA_LOG_ERROR("Invalid value for %s.", pszName); dwError = LW_ERROR_INVALID_LOG_LEVEL; BAIL_ON_LSA_ERROR(dwError); } dwError = LsaLogSetInfo_r(&LogInfo); BAIL_ON_LSA_ERROR(dwError); cleanup: return dwError; error: goto cleanup; }
static DWORD AD_SetConfig_MachinePasswordLifespan( PLSA_AD_CONFIG pConfig, PCSTR pszName, DWORD dwMachinePasswordSyncPwdLifetime ) { DWORD dwError = 0; if ((dwMachinePasswordSyncPwdLifetime != 0) && (dwMachinePasswordSyncPwdLifetime < AD_MACHINE_PASSWORD_SYNC_MINIMUM_SECS)) { LSA_LOG_ERROR("Failed to set MachinePasswordSyncPwdLifetime to %u. Minimum is %u.", dwMachinePasswordSyncPwdLifetime, AD_MACHINE_PASSWORD_SYNC_MINIMUM_SECS); dwError = LW_ERROR_INVALID_PARAMETER; BAIL_ON_LSA_ERROR(dwError); } if (dwMachinePasswordSyncPwdLifetime > AD_MACHINE_PASSWORD_SYNC_MAXIMUM_SECS) { LSA_LOG_ERROR("Failed to set MachinePasswordSyncPwdLifetime to %u. Maximum is %u.", dwMachinePasswordSyncPwdLifetime, AD_MACHINE_PASSWORD_SYNC_MAXIMUM_SECS); dwError = LW_ERROR_INVALID_PARAMETER; BAIL_ON_LSA_ERROR(dwError); } pConfig->dwMachinePasswordSyncLifetime = dwMachinePasswordSyncPwdLifetime; cleanup: return dwError; error: goto cleanup; }
DWORD LsaSrvStartupPreCheck( VOID ) { DWORD dwError = 0; #ifdef __LWI_DARWIN__ PSTR pszHostname = NULL; int iter = 0; // Make sure that the local hostname has been setup by the system for (iter = 0; iter < STARTUP_PRE_CHECK_WAIT; iter++) { LW_SAFE_FREE_STRING(pszHostname); dwError = LsaDnsGetHostInfo(&pszHostname); BAIL_ON_LSA_ERROR(dwError); if (!strcasecmp(pszHostname, "localhost")) { sleep(10); } else { /* Hostname now looks correct */ LSA_LOG_INFO("LSA Process start up check for hostname complete [hostname:%s]", pszHostname); break; } } if (iter >= STARTUP_PRE_CHECK_WAIT) { dwError = LW_ERROR_FAILED_STARTUP_PREREQUISITE_CHECK; LSA_LOG_ERROR("LSA start up pre-check failed to get updated hostname after %u seconds of waiting [Code:%u]", STARTUP_PRE_CHECK_WAIT*10, dwError); BAIL_ON_LSA_ERROR(dwError); } // Now that we are running, we need to flush the DirectoryService process of any negative cache entries dwError = LsaSrvFlushSystemCache(); BAIL_ON_LSA_ERROR(dwError); error: LW_SAFE_FREE_STRING(pszHostname); #endif return dwError; }
static DWORD LsaAdBatchGatherUnprovisionedModeUser( IN OUT PLSA_AD_BATCH_ITEM pItem, IN HANDLE hDirectory, IN LDAPMessage* pMessage ) { DWORD dwError = 0; // Check for a machine account. Last character in name will be "$" // In the future, it would be safer to either add a new // LSA_AD_BATCH_OBJECT_TYPE_COMPUTER value or an additional // flag to distinguish a user from a computer. For current // AD releases however, this is a sufficient check if (pItem->pszSamAccountName[strlen(pItem->pszSamAccountName)-1] == '$') { SetFlag(pItem->Flags, LSA_AD_BATCH_ITEM_FLAG_DISABLED); } #if 0 if (dwError != 0) { LSA_LOG_ERROR("Failed to get primary group ID for SID '%s'", pItem->pszSid); pItem->UserInfo.dwPrimaryGroupRid = WELLKNOWN_SID_DOMAIN_USER_GROUP_RID; dwError = 0; } #endif // Use display name for user gecos. dwError = LwLdapGetString( hDirectory, pMessage, AD_LDAP_DISPLAY_NAME_TAG, &pItem->UserInfo.pszGecos); BAIL_ON_LSA_ERROR(dwError); cleanup: return dwError; error: goto cleanup; }
static DWORD LocalCfgSetHomedirPrefix( PLOCAL_CONFIG pConfig, PCSTR pszName, PCSTR pszValue ) { DWORD dwError = 0; PSTR pszHomedirPrefix = NULL; if (LW_IS_NULL_OR_EMPTY_STR(pszValue)) { goto error; } dwError = LwAllocateString(pszValue, &pszHomedirPrefix); BAIL_ON_LSA_ERROR(dwError); LwStripWhitespace(pszHomedirPrefix, TRUE, TRUE); if (LW_IS_NULL_OR_EMPTY_STR(pszHomedirPrefix)) { goto error; } if (*pszHomedirPrefix != '/') { LSA_LOG_ERROR("Invalid home directory prefix [%s]", pszHomedirPrefix); goto error; } LW_SAFE_FREE_STRING(pConfig->pszHomedirPrefix); pConfig->pszHomedirPrefix = pszHomedirPrefix; pszHomedirPrefix = NULL; cleanup: return dwError; error: LW_SAFE_FREE_STRING(pszHomedirPrefix); goto cleanup; }
static DWORD LsaStopRpcSrv( PLSA_RPC_SERVER pRpc ) { DWORD dwError = 0; dwError = pRpc->pfnTable->pfnStop(); if (dwError) { LSA_LOG_ERROR("Couldn't stop %s rpc server (error: %u)", pRpc->pszName, dwError); } else { LSA_LOG_INFO("%s rpc server successfully stopped", pRpc->pszName); } return dwError; }
static DWORD LocalCfgSetDefaultLoginShell( PLOCAL_CONFIG pConfig, PCSTR pszName, PCSTR pszValue ) { DWORD dwError = 0; PSTR pszLoginShell = NULL; if (LW_IS_NULL_OR_EMPTY_STR(pszValue)) { goto error; } if (access(pszValue, X_OK) != 0) { LSA_LOG_ERROR("Invalid login shell [%s]", pszValue); goto error; } dwError = LwAllocateString(pszValue, &pszLoginShell); BAIL_ON_LSA_ERROR(dwError); LW_SAFE_FREE_STRING(pConfig->pszLoginShell); pConfig->pszLoginShell = pszLoginShell; pszLoginShell = NULL; cleanup: return dwError; error: LW_SAFE_FREE_STRING(pszLoginShell); goto cleanup; }
VOID LsaSrvFreeIpcMetriPack( PLSA_METRIC_PACK pMetricPack ) { if (pMetricPack) { switch (pMetricPack->dwInfoLevel) { case 0: LW_SAFE_FREE_MEMORY(pMetricPack->pMetricPack.pMetricPack0); break; case 1: LW_SAFE_FREE_MEMORY(pMetricPack->pMetricPack.pMetricPack1); break; default: { LSA_LOG_ERROR("Unsupported Metric Pack Info Level [%u]", pMetricPack->dwInfoLevel); } } LwFreeMemory(pMetricPack); } }
NTSTATUS LsaSvcmRefresh( PLW_SVCM_INSTANCE pInstance ) { DWORD dwError = 0; HANDLE hServer = NULL; LSA_LOG_VERBOSE("Refreshing configuration"); dwError = LsaSrvOpenServer( getuid(), getgid(), getpid(), &hServer); BAIL_ON_LSA_ERROR(dwError); dwError = LsaSrvRefreshConfiguration(hServer); BAIL_ON_LSA_ERROR(dwError); LSA_LOG_INFO("Refreshed configuration successfully"); cleanup: if (hServer != NULL) { LsaSrvCloseServer(hServer); } return LwWin32ErrorToNtStatus(dwError); error: LSA_LOG_ERROR("Failed to refresh configuration. [Error code:%u]", dwError); goto cleanup; }
void LsaFreeGroupInfo( DWORD dwLevel, PVOID pGroupInfo ) { switch(dwLevel) { case 0: { LsaFreeGroupInfo_0((PLSA_GROUP_INFO_0)pGroupInfo); break; } case 1: { LsaFreeGroupInfo_1((PLSA_GROUP_INFO_1)pGroupInfo); break; } default: { LSA_LOG_ERROR("Unsupported Group Info Level [%u]", dwLevel); } } }
void LsaFreeIpcGroupInfoList( PLSA_GROUP_INFO_LIST pGroupIpcInfoList ) { if (pGroupIpcInfoList) { switch (pGroupIpcInfoList->dwGroupInfoLevel) { case 0: LsaFreeGroupInfoList(0, (PVOID*)pGroupIpcInfoList->ppGroupInfoList.ppInfoList0, pGroupIpcInfoList->dwNumGroups); break; case 1: LsaFreeGroupInfoList(1, (PVOID*)pGroupIpcInfoList->ppGroupInfoList.ppInfoList1, pGroupIpcInfoList->dwNumGroups); break; default: { LSA_LOG_ERROR("Unsupported Group Info Level [%u]", pGroupIpcInfoList->dwGroupInfoLevel); } } LwFreeMemory(pGroupIpcInfoList); } }
DWORD LsaSrvInitAuthProviders( IN OPTIONAL PLSA_STATIC_PROVIDER pStaticProviders ) { DWORD dwError = 0; PLSA_AUTH_PROVIDER pUninitializedProviderList = NULL; PLSA_AUTH_PROVIDER pProviderList = NULL; PLSA_AUTH_PROVIDER pProvider = NULL; BOOLEAN bInLock = FALSE; dwError = LsaSrvAuthProviderAllocateProviderList( &pUninitializedProviderList); BAIL_ON_LSA_ERROR(dwError); while(pUninitializedProviderList) { pProvider = pUninitializedProviderList; pUninitializedProviderList = pUninitializedProviderList->pNext; pProvider->pNext = NULL; dwError = LsaSrvInitAuthProvider(pProvider, pStaticProviders); if (dwError) { LSA_LOG_ERROR("Failed to load provider '%s' from '%s' - error %u (%s)", LSA_SAFE_LOG_STRING(pProvider->pszId), LSA_SAFE_LOG_STRING(pProvider->pszProviderLibpath), dwError, LwWin32ExtErrorToName(dwError)); LsaSrvFreeAuthProvider(pProvider); pProvider = NULL; dwError = 0; } else { LsaSrvAppendAuthProviderList(&pProviderList, pProvider); pProvider = NULL; } } ENTER_AUTH_PROVIDER_LIST_WRITER_LOCK(bInLock); LsaSrvFreeAuthProviderList(gpAuthProviderList); gpAuthProviderList = pProviderList; pProviderList = NULL; LEAVE_AUTH_PROVIDER_LIST_WRITER_LOCK(bInLock); cleanup: if (pUninitializedProviderList) { LsaSrvFreeAuthProviderList(pUninitializedProviderList); } return dwError; error: if (pProviderList) { LsaSrvFreeAuthProviderList(pProviderList); } goto cleanup; }
DWORD LsaSrvFlushSystemCache( VOID ) { DWORD dwError = 0; #if defined (__LWI_DARWIN__) int i; const char* cacheUtils[] = { "/usr/sbin/lookupd", /* Before Mac OS X 10.5 */ "/usr/bin/dscacheutil" /* On Mac OS X 10.5 */ }; const char* cacheUtilCmd[] = { "/usr/sbin/lookupd -flushcache", /* Before Mac OS X 10.5 */ "/usr/bin/dscacheutil -flushcache" /* On Mac OS X 10.5 */ }; BOOLEAN bCacheFlushed = FALSE; LSA_LOG_VERBOSE("Going to flush the Mac DirectoryService cache ..."); for (i = 0; !bCacheFlushed && i < (sizeof(cacheUtils) / sizeof(cacheUtils[0])); i++) { const char* util = cacheUtils[i]; const char* command = cacheUtilCmd[i]; BOOLEAN exists; /* Sanity check */ if (!util) { continue; } dwError = LsaCheckFileExists(util, &exists); BAIL_ON_LSA_ERROR(dwError); if (!exists) { continue; } system(command); /* Bail regardless */ bCacheFlushed = TRUE; } if (!bCacheFlushed) { LSA_LOG_ERROR("Could not locate cache flush utility"); dwError = LW_ERROR_MAC_FLUSH_DS_CACHE_FAILED; BAIL_ON_LSA_ERROR(dwError); } cleanup: LSA_LOG_VERBOSE("Finished flushing the Mac DirectoryService cache"); #endif return dwError; #if defined (__LWI_DARWIN__) error: goto cleanup; #endif }
DWORD LsaSetSystemTime( time_t ttCurTime ) { DWORD dwError = 0; BOOLEAN bTimeset = FALSE; DWORD dwCount = 0; // The aix implementation of clock_settime segfaults #ifdef __LWI_AIX__ #undef HAVE_CLOCK_SETTIME #endif #if !defined(HAVE_CLOCK_SETTIME) && !defined(HAVE_SETTIMEOFDAY) #error Either clock_settime or settimeofday is needed #endif #if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) struct timespec systemspec; #endif #if HAVE_SETTIMEOFDAY || HAVE_GETTIMEOFDAY struct timeval systemval; #endif long long readTime = -1; #ifdef HAVE_CLOCK_SETTIME memset(&systemspec, 0, sizeof(systemspec)); systemspec.tv_sec = ttCurTime; #endif #if HAVE_SETTIMEOFDAY memset(&systemval, 0, sizeof(systemval)); systemval.tv_sec = ttCurTime; #endif #ifdef HAVE_CLOCK_SETTIME if (!bTimeset) { if (clock_settime(CLOCK_REALTIME, &systemspec) == -1) { LSA_LOG_VERBOSE("Setting time with clock_settime failed %d", errno); } else { LSA_LOG_VERBOSE("Setting time with clock_settime worked"); bTimeset = TRUE; } } #endif #ifdef HAVE_SETTIMEOFDAY if (!bTimeset) { if (settimeofday(&systemval, NULL) == -1) { LSA_LOG_VERBOSE("Setting time with settimeofday failed %d", errno); } else { LSA_LOG_VERBOSE("Setting time with settimeofday worked"); bTimeset = TRUE; } } #endif if (!bTimeset) { dwError = LW_ERROR_FAILED_TO_SET_TIME; BAIL_ON_LSA_ERROR(dwError); } //Verify the clock got set bTimeset = FALSE; #ifdef HAVE_CLOCK_GETTIME if (!bTimeset && clock_gettime(CLOCK_REALTIME, &systemspec) >= 0) { bTimeset = TRUE; readTime = systemspec.tv_sec; } #endif #ifdef HAVE_GETTIMEOFDAY if (!bTimeset && gettimeofday(&systemval, NULL) >= 0) { bTimeset = TRUE; readTime = systemval.tv_sec; } #endif if (!bTimeset) { dwError = LW_ERROR_FAILED_TO_SET_TIME; BAIL_ON_LSA_ERROR(dwError); } //Make sure the time is now within 5 seconds of what we set if (labs(readTime - ttCurTime) > 5) { LSA_LOG_ERROR("Attempted to set time to %ld, but it is now %ld.", ttCurTime, readTime); dwError = LW_ERROR_FAILED_TO_SET_TIME; BAIL_ON_LSA_ERROR(dwError); } //Make sure the time reported by time() is now within 5 seconds of //what we set. On virtual systems it may be slow to update. for ( dwCount = 0 ; dwCount < 5 ; dwCount++ ) { readTime = time(NULL); if (labs(readTime - ttCurTime) > 5) { LSA_LOG_DEBUG("Time is slow to update...waiting"); sleep(1); } else { break; } } cleanup: return dwError; error: goto cleanup; }
DWORD ADLdap_GetObjectGroupMembership( IN PAD_PROVIDER_CONTEXT pContext, IN PLSA_SECURITY_OBJECT pObject, OUT int* piPrimaryGroupIndex, OUT size_t* psNumGroupsFound, OUT PLSA_SECURITY_OBJECT** pppGroupInfoList ) { DWORD dwError = 0; PLSA_DM_LDAP_CONNECTION pConn = NULL; PSTR pszFullDomainName = NULL; INT i = 0; PLSA_SECURITY_OBJECT* ppGroupInfoList = NULL; size_t sNumGroupsFound = 0; int iPrimaryGroupIndex = -1; DWORD gcMembershipCount = 0; PSTR* ppGcMembershipList = NULL; DWORD dcMembershipCount = 0; PSTR* ppDcMembershipList = NULL; PLW_HASH_TABLE pGroupHash = NULL; LSA_TRUST_DIRECTION trustDirection = LSA_TRUST_DIRECTION_UNKNOWN; LSA_TRUST_MODE trustMode = LSA_TRUST_MODE_UNKNOWN; DWORD index = 0; DWORD totalSidCount = 0; PSTR* ppTotalSidList = NULL; // If we cannot get dn, then we cannot get DN information for this objects, hence BAIL if (LW_IS_NULL_OR_EMPTY_STR(pObject->pszDN)) { dwError = LW_ERROR_NO_SUCH_USER; BAIL_ON_LSA_ERROR(dwError); } dwError = LwLdapConvertDNToDomain( pObject->pszDN, &pszFullDomainName); BAIL_ON_LSA_ERROR(dwError); // Note that this function is called only for 2-way trusts. However, // the trust could be an external trust or a forest trust. We can only // query the GC if there is a forest trust. dwError = AD_DetermineTrustModeandDomainName( pContext->pState, pszFullDomainName, &trustDirection, &trustMode, NULL, NULL); BAIL_ON_LSA_ERROR(dwError); // We could only have the DN path for the user if (s)he came from a two way // trusted domain or the joined domain. LSA_ASSERT(LSA_TRUST_DIRECTION_TWO_WAY == trustDirection || LSA_TRUST_DIRECTION_SELF == trustDirection); if (trustMode != LSA_TRUST_MODE_EXTERNAL) { // Get forest info from domain's GC since there is a forest trust. // This will only include universal group information. (The domain // global groups will not include membership info in the GC.) dwError = LsaDmLdapOpenGc( pContext, pszFullDomainName, &pConn); BAIL_ON_LSA_ERROR(dwError); dwError = ADLdap_GetAttributeValuesList( pConn, pObject->pszDN, AD_LDAP_MEMBEROF_TAG, TRUE, TRUE, &gcMembershipCount, &ppGcMembershipList); BAIL_ON_LSA_ERROR(dwError); LsaDmLdapClose(pConn); pConn = NULL; } dwError = LsaDmLdapOpenDc( pContext, pszFullDomainName, &pConn); BAIL_ON_LSA_ERROR(dwError); dwError = ADLdap_GetAttributeValuesList( pConn, pObject->pszDN, AD_LDAP_MEMBEROF_TAG, TRUE, TRUE, &dcMembershipCount, &ppDcMembershipList); BAIL_ON_LSA_ERROR(dwError); dwError = LwHashCreate( (dcMembershipCount + gcMembershipCount + 1) * 2, LwHashCaselessStringCompare, LwHashCaselessStringHash, ADLdap_FreeHashStringValue, NULL, &pGroupHash); BAIL_ON_LSA_ERROR(dwError); for (index = 0; index < gcMembershipCount; index++) { PSTR pSid = ppGcMembershipList[index]; if (!LwHashExists(pGroupHash, pSid)) { // Set the value of the hash entry as NULL so this string is not // freed with the hash. dwError = LwHashSetValue(pGroupHash, pSid, NULL); BAIL_ON_LSA_ERROR(dwError); } } for (index = 0; index < dcMembershipCount; index++) { PSTR pSid = ppDcMembershipList[index]; if (!LwHashExists(pGroupHash, pSid)) { // Set the value of the hash entry as NULL so this string is not // freed with the hash. dwError = LwHashSetValue(pGroupHash, pSid, NULL); BAIL_ON_LSA_ERROR(dwError); } } if (pObject->type == LSA_OBJECT_TYPE_USER && pObject->userInfo.pszPrimaryGroupSid) { // Add the pszPrimaryGroupSID entry to the hash PSTR pSid = pObject->userInfo.pszPrimaryGroupSid; if (!LwHashExists(pGroupHash, pSid)) { // Set the value of the hash entry as NULL so this string is not // freed with the hash. dwError = LwHashSetValue(pGroupHash, pSid, NULL); BAIL_ON_LSA_ERROR(dwError); } } // Check if the user came from a domain other than the computer's domain if (LSA_TRUST_DIRECTION_TWO_WAY == trustDirection) { dwError = ADLdap_AddDomainLocalGroups( pContext, pObject, pGroupHash); BAIL_ON_LSA_ERROR(dwError); } dwError = ADLdap_MoveHashKeysToArray( pGroupHash, &totalSidCount, (PVOID**)(PVOID)&ppTotalSidList); BAIL_ON_LSA_ERROR(dwError); dwError = AD_FindObjectsBySidList( pContext, totalSidCount, ppTotalSidList, &sNumGroupsFound, &ppGroupInfoList); BAIL_ON_LSA_ERROR(dwError); AD_FilterNullEntries( ppGroupInfoList, &sNumGroupsFound); // Determine primary group index if (pObject->type == LSA_OBJECT_TYPE_USER && pObject->userInfo.pszPrimaryGroupSid && ppGroupInfoList && sNumGroupsFound) { for (i = (INT)sNumGroupsFound - 1; i >= 0; i--) { if (!strcmp(ppGroupInfoList[i]->pszObjectSid, pObject->userInfo.pszPrimaryGroupSid)) { iPrimaryGroupIndex = i; break; } } } *psNumGroupsFound = sNumGroupsFound; *pppGroupInfoList = ppGroupInfoList; *piPrimaryGroupIndex = iPrimaryGroupIndex; cleanup: LwHashSafeFree(&pGroupHash); LW_SAFE_FREE_STRING(pszFullDomainName); LwFreeStringArray(ppGcMembershipList, gcMembershipCount); LwFreeStringArray(ppDcMembershipList, dcMembershipCount); // Do not free the string pointers inside. They are borrowed from the // hash. LW_SAFE_FREE_MEMORY(ppTotalSidList); LsaDmLdapClose(pConn); return dwError; error: *pppGroupInfoList = NULL; *psNumGroupsFound = 0; *piPrimaryGroupIndex = -1; if ( dwError != LW_ERROR_DOMAIN_IS_OFFLINE ) { LSA_LOG_ERROR("Failed to group memberships of SID=%s. [error code:%u]", pObject->pszObjectSid, dwError); } ADCacheSafeFreeObjectList((DWORD)sNumGroupsFound, &ppGroupInfoList); goto cleanup; }
DWORD SELinuxCreate( PSELINUX *ppSELinux ) { DWORD dwError = 0; PSELINUX pSELinux = NULL; dwError = LwAllocateMemory(sizeof(SELINUX), (PVOID*)&pSELinux); BAIL_ON_LSA_ERROR(dwError); pSELinux->bEnabled = FALSE; #if ENABLE_SELINUX BOOLEAN bFileExists = FALSE; dwError = LsaCheckFileExists(LIBSELINUX, &bFileExists); BAIL_ON_LSA_ERROR(dwError); if (bFileExists == FALSE) { LSA_LOG_DEBUG("Could not find %s", LIBSELINUX); goto error; } pSELinux->dlhandle = dlopen(LIBSELINUX, RTLD_LAZY | RTLD_LOCAL); if (pSELinux->dlhandle == NULL) { LSA_LOG_ERROR("Could not load " LIBSELINUX ": %s", dlerror()); goto cleanup; } else { pSELinux->is_selinux_enabled = dlsym(pSELinux->dlhandle, "is_selinux_enabled"); pSELinux->matchpathcon_init = dlsym(pSELinux->dlhandle, "matchpathcon_init"); pSELinux->matchpathcon_fini = dlsym(pSELinux->dlhandle, "matchpathcon_fini"); pSELinux->matchpathcon = dlsym(pSELinux->dlhandle, "matchpathcon"); pSELinux->setfilecon= dlsym(pSELinux->dlhandle, "setfilecon"); pSELinux->freecon = dlsym(pSELinux->dlhandle, "freecon"); if (!pSELinux->is_selinux_enabled || !pSELinux->matchpathcon || !pSELinux->setfilecon || !pSELinux->freecon) { LSA_LOG_ERROR("Could not find symbol in " LIBSELINUX); dwError = LW_ERROR_LOOKUP_SYMBOL_FAILED; BAIL_ON_LSA_ERROR(dwError); } if (pSELinux->is_selinux_enabled() == 1) { LSA_LOG_DEBUG("SELinux is enabled."); if(pSELinux->matchpathcon_init != NULL) { pSELinux->matchpathcon_init(NULL); } pSELinux->bEnabled = TRUE; } } #endif *ppSELinux = pSELinux; cleanup: return dwError; error: LW_SAFE_FREE_MEMORY(pSELinux); goto cleanup; }
DWORD LsaSrvInitRpcServers( VOID ) { DWORD dwError = 0; PLSA_RPC_SERVER pRpc = NULL; PLSA_RPC_SERVER pUninitializedRpcList = NULL; PLSA_RPC_SERVER pRpcList = NULL; BOOLEAN bLocked = TRUE; dwError = LsaRpcReadRegistry(&pUninitializedRpcList); BAIL_ON_LSA_ERROR(dwError); while (pUninitializedRpcList) { pRpc = pUninitializedRpcList; pUninitializedRpcList = pUninitializedRpcList->pNext; pRpc->pNext = NULL; dwError = LsaSrvInitRpcServer(pRpc); if (dwError) { LSA_LOG_ERROR("Failed to load rpc server [%s] at [%s] [error code:%u]", (pRpc->pszName ? pRpc->pszName : "<null>"), (pRpc->pszSrvLibPath ? pRpc->pszSrvLibPath : "<null>"), dwError); LsaSrvFreeRpcServer(pRpc); pRpc = NULL; dwError = 0; } else { LsaSrvAppendRpcServerList(pRpc, &pRpcList); pRpc = NULL; } } ENTER_RPC_SERVER_LIST_WRITER_LOCK(bLocked); LsaSrvFreeRpcServerList(gpRpcServerList); gpRpcServerList = pRpcList; pRpcList = NULL; LsaStartRpcServers(gpRpcServerList); LEAVE_RPC_SERVER_LIST_WRITER_LOCK(bLocked); /* Start rpc service control worker thread to start listening for incoming rpc calls */ dwError = RpcSvcStartWorker(); BAIL_ON_LSA_ERROR(dwError); cleanup: if (pUninitializedRpcList) { LsaSrvFreeRpcServerListWithoutStopping(pUninitializedRpcList); } return dwError; error: if (pRpcList) { LsaSrvFreeRpcServerList(pRpcList); } goto cleanup; }
PVOID LADSFindUserByName( PVOID pData ) { DWORD dwError = 0; PVOID pResult = NULL; PCSTR pszName = NULL; DWORD dwInfoLevel = gLADSStressData[LADS_FIND_USER_BY_NAME].dwInfoLevel; PVOID pUserInfo = NULL; HANDLE hProvider = (HANDLE)NULL; while (!LADSProcessShouldStop()) { DWORD iName = 0; for (iName = 0; (!LADSProcessShouldStop() && (iName < gLADSStressData[LADS_FIND_USER_BY_NAME].dwNumItems)); iName++) { pszName = gLADSStressData[LADS_FIND_USER_BY_NAME].data.ppszNames[iName]; dwError = gpAuthProvider->pFnTable->pfnOpenHandle( geteuid(), getegid(), getpid(), &hProvider); BAIL_ON_LSA_ERROR(dwError); dwError = gpAuthProvider->pFnTable->pfnLookupUserByName( hProvider, pszName, dwInfoLevel, &pUserInfo); BAIL_ON_LSA_ERROR(dwError); gpAuthProvider->pFnTable->pfnCloseHandle(hProvider); hProvider = (HANDLE)NULL; LsaFreeUserInfo(dwInfoLevel, pUserInfo); pUserInfo = NULL; if (gLADSStressData[LADS_FIND_USER_BY_NAME].dwSleepMSecs) { sleep(gLADSStressData[LADS_FIND_USER_BY_NAME].dwSleepMSecs); } } } cleanup: if (pUserInfo) { LsaFreeUserInfo(dwInfoLevel, pUserInfo); } if (hProvider != (HANDLE)NULL) { gpAuthProvider->pFnTable->pfnCloseHandle(hProvider); } return pResult; error: LSA_LOG_ERROR("Failed to find user by name [%s] [error code: %u]", (LW_IS_NULL_OR_EMPTY_STR(pszName) ? "" : pszName), dwError); LADSStopProcess(); goto cleanup; }
PVOID LADSEnumGroups( PVOID pData ) { DWORD dwError = 0; PVOID pResult = NULL; DWORD dwInfoLevel = gLADSStressData[LADS_ENUM_GROUPS].dwInfoLevel; DWORD dwMaxNumGroups = 500; DWORD dwNumGroupsFound = 0; PVOID* ppGroupInfos = NULL; HANDLE hProvider = (HANDLE)NULL; HANDLE hResume = (HANDLE)NULL; while (!LADSProcessShouldStop()) { dwError = gpAuthProvider->pFnTable->pfnOpenHandle( geteuid(), getegid(), getpid(), &hProvider); BAIL_ON_LSA_ERROR(dwError); dwError = gpAuthProvider->pFnTable->pfnBeginEnumGroups( hProvider, dwInfoLevel, FALSE, 0, &hResume); BAIL_ON_LSA_ERROR(dwError); do { if (dwNumGroupsFound) { LsaFreeUserInfoList( dwInfoLevel, ppGroupInfos, dwNumGroupsFound); ppGroupInfos = NULL; dwNumGroupsFound = 0; } dwError = gpAuthProvider->pFnTable->pfnEnumGroups( hProvider, hResume, dwMaxNumGroups, &dwNumGroupsFound, &ppGroupInfos); BAIL_ON_LSA_ERROR(dwError); } while (dwNumGroupsFound && !LADSProcessShouldStop()); gpAuthProvider->pFnTable->pfnEndEnumGroups( hProvider, hResume); hResume = (HANDLE)NULL; gpAuthProvider->pFnTable->pfnCloseHandle(hProvider); hProvider = (HANDLE)NULL; if (gLADSStressData[LADS_ENUM_GROUPS].dwSleepMSecs) { sleep(gLADSStressData[LADS_ENUM_GROUPS].dwSleepMSecs); } } cleanup: if (dwNumGroupsFound) { LsaFreeUserInfoList( dwInfoLevel, ppGroupInfos, dwNumGroupsFound); } if (hProvider != (HANDLE)NULL) { if (hResume != (HANDLE)NULL) { gpAuthProvider->pFnTable->pfnEndEnumGroups( hProvider, hResume); } gpAuthProvider->pFnTable->pfnCloseHandle(hProvider); } return pResult; error: LSA_LOG_ERROR("Failed to enumerate groups [error code: %u]", dwError); LADSStopProcess(); goto cleanup; }
PVOID LADSFindGroupById( PVOID pData ) { DWORD dwError = 0; PVOID pResult = NULL; gid_t groupId = 0; DWORD dwInfoLevel = gLADSStressData[LADS_FIND_GROUP_BY_ID].dwInfoLevel; PVOID pGroupInfo = NULL; HANDLE hProvider = (HANDLE)NULL; while (!LADSProcessShouldStop()) { DWORD iGid = 0; for (iGid = 0; (!LADSProcessShouldStop() && (iGid < gLADSStressData[LADS_FIND_GROUP_BY_ID].dwNumItems)); iGid++) { groupId = gLADSStressData[LADS_FIND_GROUP_BY_ID].data.pGidArray[iGid]; dwError = gpAuthProvider->pFnTable->pfnOpenHandle( geteuid(), getegid(), getpid(), &hProvider); BAIL_ON_LSA_ERROR(dwError); dwError = gpAuthProvider->pFnTable->pfnLookupGroupById( hProvider, groupId, 0, dwInfoLevel, &pGroupInfo); BAIL_ON_LSA_ERROR(dwError); gpAuthProvider->pFnTable->pfnCloseHandle(hProvider); hProvider = (HANDLE)NULL; LsaFreeGroupInfo(dwInfoLevel, pGroupInfo); pGroupInfo = NULL; if (gLADSStressData[LADS_FIND_GROUP_BY_ID].dwSleepMSecs) { sleep(gLADSStressData[LADS_FIND_GROUP_BY_ID].dwSleepMSecs); } } } cleanup: if (pGroupInfo) { LsaFreeGroupInfo(dwInfoLevel, pGroupInfo); } if (hProvider != (HANDLE)NULL) { gpAuthProvider->pFnTable->pfnCloseHandle(hProvider); } return pResult; error: LSA_LOG_ERROR("Failed to find group by id [%ld] [error code: %u]", (long)groupId, dwError); LADSStopProcess(); goto cleanup; }
static DWORD AD_SetConfig_Umask( PLSA_AD_CONFIG pConfig, PCSTR pszName, PCSTR pszValue ) { DWORD dwError = 0; PCSTR cp = NULL; DWORD dwOct = 0; DWORD dwVal = 0; DWORD dwCnt = 0; char cp2[2]; // Convert the umask octal string to a decimal number if (LW_IS_NULL_OR_EMPTY_STR(pszValue)) { goto error; } cp2[1] = 0; for ( cp = pszValue, dwCnt = 0 ; isdigit((int)*cp) ; cp++, dwCnt++ ) { dwOct *= 8; cp2[0] = *cp; dwVal = atoi(cp2); if ( dwVal > 7 ) { LSA_LOG_ERROR("Invalid Umask [%s]", pszValue); goto error; } dwOct += dwVal; } if ( dwCnt > 4 ) { LSA_LOG_ERROR("Invalid Umask [%s]", pszValue); goto error; } // Disallow 07xx since the user should always have // access to his home directory. if ( (dwOct & 0700) == 0700 ) { LSA_LOG_ERROR("Invalid Umask [%s]. User cannot access home directory.", pszValue); goto error; } else { pConfig->dwUmask = dwOct; } cleanup: return dwError; error: goto cleanup; }
DWORD LsaSrvRefreshConfiguration( HANDLE hServer ) { DWORD dwError = 0; BOOLEAN bInLock = FALSE; PLSA_AUTH_PROVIDER pProvider = NULL; HANDLE hProvider = (HANDLE)NULL; PLSA_SRV_API_STATE pServerState = (PLSA_SRV_API_STATE)hServer; BOOLEAN bUnlockConfigLock = FALSE; LSA_SRV_API_CONFIG apiConfig; if (pServerState->peerUID) { dwError = LW_ERROR_ACCESS_DENIED; BAIL_ON_LSA_ERROR(dwError); } dwError = LsaSrvApiInitConfig(&apiConfig); BAIL_ON_LSA_ERROR(dwError); dwError = LsaSrvApiReadRegistry(&apiConfig); BAIL_ON_LSA_ERROR(dwError); pthread_mutex_lock(&gAPIConfigLock); bUnlockConfigLock = TRUE; dwError = LsaSrvApiTransferConfigContents( &apiConfig, &gAPIConfig); BAIL_ON_LSA_ERROR(dwError); pthread_mutex_unlock(&gAPIConfigLock); bUnlockConfigLock = FALSE; ENTER_AUTH_PROVIDER_LIST_READER_LOCK(bInLock); dwError = LW_ERROR_NOT_HANDLED; for (pProvider = gpAuthProviderList; pProvider; pProvider = pProvider->pNext) { dwError = LsaSrvOpenProvider( hServer, pProvider, NULL, &hProvider); BAIL_ON_LSA_ERROR(dwError); dwError = pProvider->pFnTable->pfnRefreshConfiguration( hProvider); if (dwError) { LSA_LOG_ERROR("Refreshing provider %s failed.", pProvider->pszName ? pProvider->pszName : ""); dwError = 0; } LsaSrvCloseProvider(pProvider, hProvider); hProvider = (HANDLE)NULL; } cleanup: if (hProvider != (HANDLE)NULL) { LsaSrvCloseProvider(pProvider, hProvider); } LEAVE_AUTH_PROVIDER_LIST_READER_LOCK(bInLock); LsaSrvApiFreeConfigContents(&apiConfig); if (bUnlockConfigLock) { pthread_mutex_unlock(&gAPIConfigLock); } return(dwError); error: LSA_LOG_ERROR_API_FAILED(hServer, dwError, "refresh configuration"); goto cleanup; }
DWORD LsaSrvInitAuthProvider( IN PLSA_AUTH_PROVIDER pProvider, IN OPTIONAL PLSA_STATIC_PROVIDER pStaticProviders ) { DWORD dwError = 0; PFNINITIALIZEPROVIDER pfnInitProvider = NULL; PCSTR pszError = NULL; PSTR pszProviderLibpath = NULL; int i = 0; if (pStaticProviders) { /* First look for a static provider entry with the given name */ for (i = 0; pStaticProviders[i].pszId; i++) { if (!strcmp(pStaticProviders[i].pszId, pProvider->pszId)) { pfnInitProvider = pStaticProviders[i].pInitialize; LSA_LOG_DEBUG("Provider %s loaded from static list", pProvider->pszId); break; } } } if (!pfnInitProvider) { /* Try to load the provider dynamically */ if (LW_IS_NULL_OR_EMPTY_STR(pProvider->pszProviderLibpath)) { dwError = LW_ERROR_INVALID_AUTH_PROVIDER; BAIL_ON_LSA_ERROR(dwError); } pszProviderLibpath = pProvider->pszProviderLibpath; dlerror(); pProvider->pLibHandle = dlopen(pszProviderLibpath, RTLD_NOW | RTLD_LOCAL); if (!pProvider->pLibHandle) { LSA_LOG_ERROR("Failed to open auth provider at path '%s'", pszProviderLibpath); pszError = dlerror(); if (!LW_IS_NULL_OR_EMPTY_STR(pszError)) { LSA_LOG_ERROR("%s", pszError); } dwError = LW_ERROR_INVALID_AUTH_PROVIDER; BAIL_ON_LSA_ERROR(dwError); } dlerror(); pfnInitProvider = (PFNINITIALIZEPROVIDER) dlsym( pProvider->pLibHandle, LSA_SYMBOL_NAME_INITIALIZE_PROVIDER); if (!pfnInitProvider) { LSA_LOG_ERROR("Ignoring invalid auth provider at path '%s'", pszProviderLibpath); pszError = dlerror(); if (!LW_IS_NULL_OR_EMPTY_STR(pszError)) { LSA_LOG_ERROR("%s", pszError); } dwError = LW_ERROR_INVALID_AUTH_PROVIDER; BAIL_ON_LSA_ERROR(dwError); } } dwError = pfnInitProvider( &pProvider->pszName, &pProvider->pFnTable); BAIL_ON_LSA_ERROR(dwError); dwError = LsaSrvValidateProvider(pProvider); BAIL_ON_LSA_ERROR(dwError); cleanup: return dwError; error: goto cleanup; }
DWORD ADLdap_GetGroupMembers( IN PAD_PROVIDER_CONTEXT pContext, IN PCSTR pszDomainName, IN PCSTR pszSid, OUT size_t* psCount, OUT PLSA_SECURITY_OBJECT** pppResults ) { DWORD dwError = LW_ERROR_SUCCESS; DWORD dwSidCount = 0; PSTR pszDnsDomainName = NULL; PLSA_SECURITY_OBJECT pGroupObj = NULL; PLSA_SECURITY_OBJECT* ppResults = NULL; PSTR *ppszLDAPValues = NULL; size_t sFoundCount = 0; PLSA_DM_LDAP_CONNECTION pConn = NULL; dwError = AD_FindObjectBySid( pContext, pszSid, &pGroupObj); BAIL_ON_LSA_ERROR(dwError); if (pGroupObj->type != LSA_OBJECT_TYPE_GROUP) { dwError = LW_ERROR_DATA_ERROR; BAIL_ON_LSA_ERROR(dwError); } dwError = LsaDmWrapGetDomainName( pContext->pState->hDmState, pszDomainName, &pszDnsDomainName, NULL); BAIL_ON_LSA_ERROR(dwError); dwError = LsaDmLdapOpenDc( pContext, pszDnsDomainName, &pConn); BAIL_ON_LSA_ERROR(dwError); dwError = ADLdap_GetAttributeValuesList( pConn, pGroupObj->pszDN, AD_LDAP_MEMBER_TAG, TRUE, TRUE, &dwSidCount, &ppszLDAPValues); BAIL_ON_LSA_ERROR(dwError); dwError = AD_FindObjectsBySidList( pContext, dwSidCount, ppszLDAPValues, &sFoundCount, &ppResults); BAIL_ON_LSA_ERROR(dwError); *psCount = sFoundCount; *pppResults = ppResults; cleanup: LW_SAFE_FREE_STRING(pszDnsDomainName); ADCacheSafeFreeObject(&pGroupObj); LwFreeStringArray(ppszLDAPValues, dwSidCount); LsaDmLdapClose(pConn); return dwError; error: *psCount = 0; *pppResults = NULL; LSA_LOG_ERROR("Failed to find group's members of objectSid=%s. [error code:%u]", LSA_SAFE_LOG_STRING(pszSid), dwError); ADCacheSafeFreeObjectList((DWORD)sFoundCount, &ppResults); goto cleanup; }
static DWORD LsaSrvAuthProviderAllocateProviderList( PLSA_AUTH_PROVIDER *ppProviderList ) { DWORD dwError = 0; PSTR pszLoadOrder = NULL; // Multistring PCSTR pszProvider = NULL; PSTR pszProviderKey = NULL; PLSA_AUTH_PROVIDER pProvider = NULL; PLSA_AUTH_PROVIDER pProviderList = NULL; dwError = LsaSrvAuthProviderRegGetLoadOrder(&pszLoadOrder); BAIL_ON_LSA_ERROR(dwError); if (!pszLoadOrder) { /* We should only get here if there is some problem with the * registry -- can't access it, the key isn't there, ... * -- so we will try a default set of providers. */ LSA_LOG_ERROR("Problem accessing provider configuration in registry. Trying compiled defaults [ActiveDirectory, Local]."); dwError = LsaSrvAllocateProvider( LSA_PROVIDER_TAG_AD, LSA_PROVIDER_PATH_AD, &pProvider); BAIL_ON_LSA_ERROR(dwError); if (pProvider) { LsaSrvAppendAuthProviderList(&pProviderList, pProvider); pProvider = NULL; } dwError = LsaSrvAllocateProvider( LSA_PROVIDER_TAG_LOCAL, LSA_PROVIDER_PATH_LOCAL, &pProvider); BAIL_ON_LSA_ERROR(dwError); if (pProvider) { LsaSrvAppendAuthProviderList(&pProviderList, pProvider); pProvider = NULL; } } else { pszProvider = pszLoadOrder; while ( pszProvider != NULL && *pszProvider != '\0' ) { dwError = LwAllocateStringPrintf( &pszProviderKey, "Services\\lsass\\Parameters\\Providers\\%s", pszProvider); BAIL_ON_LSA_ERROR(dwError); dwError = LsaSrvAuthLoadProvider( pszProvider, pszProviderKey, &pProvider); BAIL_ON_LSA_ERROR(dwError); if (pProvider) { LsaSrvAppendAuthProviderList(&pProviderList, pProvider); pProvider = NULL; } LW_SAFE_FREE_STRING(pszProviderKey); pszProvider = pszProvider + strlen(pszProvider) + 1; } } cleanup: *ppProviderList = pProviderList; LW_SAFE_FREE_MEMORY(pszLoadOrder); LW_SAFE_FREE_STRING(pszProviderKey); return dwError; error: LsaSrvFreeAuthProviderList(pProviderList); pProviderList = NULL; goto cleanup; }
DWORD LsaSrvInitRpcServer( PLSA_RPC_SERVER pRpc ) { DWORD dwError = 0; PFNINITIALIZERPCSRV pfnInitRpc = NULL; PCSTR pszError = NULL; PCSTR pszSrvLibPath = NULL; if (LW_IS_NULL_OR_EMPTY_STR(pRpc->pszSrvLibPath)) { dwError = ERROR_FILE_NOT_FOUND; BAIL_ON_LSA_ERROR(dwError); } pszSrvLibPath = pRpc->pszSrvLibPath; dlerror(); pRpc->phLib = dlopen(pszSrvLibPath, RTLD_NOW | RTLD_GLOBAL); if (pRpc->phLib == NULL) { LSA_LOG_ERROR("Failed to open rpc server at path [%s]", pszSrvLibPath); pszError = dlerror(); if (!LW_IS_NULL_OR_EMPTY_STR(pszError)) { LSA_LOG_ERROR("%s", pszError); } dwError = LW_ERROR_INVALID_RPC_SERVER; BAIL_ON_LSA_ERROR(dwError); } dlerror(); pfnInitRpc = (PFNINITIALIZERPCSRV)dlsym( pRpc->phLib, LSA_SYMBOL_NAME_INITIALIZE_RPCSRV); dwError = LsaCheckInvalidRpcServer( pfnInitRpc, pszSrvLibPath); BAIL_ON_LSA_ERROR(dwError); dlerror(); pRpc->pfnShutdownSrv = (PFNSHUTDOWNRPCSRV)dlsym( pRpc->phLib, LSA_SYMBOL_NAME_SHUTDOWN_RPCSRV); dwError = LsaCheckInvalidRpcServer( pRpc->pfnShutdownSrv, pszSrvLibPath); BAIL_ON_LSA_ERROR(dwError); dwError = pfnInitRpc( &pRpc->pszName, &pRpc->pfnTable); BAIL_ON_LSA_ERROR(dwError); dwError = LsaValidateRpcServer(pRpc); BAIL_ON_LSA_ERROR(dwError); cleanup: return dwError; error: goto cleanup; }