DWORD LwKrb5SetThreadDefaultCachePath( IN PCSTR pszCachePath, OUT PSTR* ppszPreviousCachePath ) { DWORD dwError = 0; DWORD dwMajorStatus = 0; DWORD dwMinorStatus = 0; PSTR pszOrigCachePath = NULL; // Set the default for gss dwMajorStatus = gss_krb5_ccache_name( (OM_uint32 *)&dwMinorStatus, pszCachePath, (ppszPreviousCachePath) ? (const char**)&pszOrigCachePath : NULL); BAIL_ON_GSS_ERROR(dwError, dwMajorStatus, dwMinorStatus); LW_LOG_DEBUG("Switched gss krb5 credentials path from %s to %s", LW_SAFE_LOG_STRING(pszOrigCachePath), LW_SAFE_LOG_STRING(pszCachePath)); if (ppszPreviousCachePath) { if (!LW_IS_NULL_OR_EMPTY_STR(pszOrigCachePath)) { dwError = LwAllocateString(pszOrigCachePath, ppszPreviousCachePath); BAIL_ON_LW_ERROR(dwError); } else { *ppszPreviousCachePath = NULL; } } cleanup: return dwError; error: if (ppszPreviousCachePath) { *ppszPreviousCachePath = NULL; } goto cleanup; }
DWORD UmnSrvUpdateUsers( HANDLE hLsass, PLW_EVENTLOG_CONNECTION pEventlog, HANDLE hReg, HKEY hParameters, long long PreviousRun, long long Now ) { DWORD uid = 0; DWORD dwError = 0; struct passwd *pUser = NULL; LSA_QUERY_LIST list = { 0 }; PLSA_SECURITY_OBJECT* ppObjects = NULL; HKEY hUsers = NULL; BOOLEAN skipNoLogin = FALSE; dwError = UmnSrvGetSkipNoLogin( &skipNoLogin); BAIL_ON_UMN_ERROR(dwError); list.pdwIds = &uid; dwError = RegOpenKeyExA( hReg, hParameters, "Users", 0, KEY_ALL_ACCESS, &hUsers); BAIL_ON_UMN_ERROR(dwError); while ((pUser = getpwent()) != NULL) { if (skipNoLogin && pUser->pw_shell && (!strcmp(pUser->pw_shell, "/sbin/nologin") || !strcmp(pUser->pw_shell, "/bin/nologin") || !strcmp(pUser->pw_shell, "/usr/sbin/nologin") || !strcmp(pUser->pw_shell, "/usr/bin/false") || !strcmp(pUser->pw_shell, "/bin/false"))) { UMN_LOG_VERBOSE("Skipping enumerated user '%s' (uid %d) because their shell prevents them from logging in.", LW_SAFE_LOG_STRING(pUser->pw_name), uid); continue; } uid = pUser->pw_uid; dwError = LsaFindObjects( hLsass, NULL, 0, LSA_OBJECT_TYPE_USER, LSA_QUERY_TYPE_BY_UNIX_ID, 1, list, &ppObjects); if (dwError == ERROR_SUCCESS && ppObjects && ppObjects[0] && ppObjects[0]->enabled && ppObjects[0]->userInfo.pszUnixName && pUser->pw_name && !strcmp(ppObjects[0]->userInfo.pszUnixName, pUser->pw_name)) { UMN_LOG_VERBOSE("Skipping enumerated user '%s' (uid %d) because they came from lsass", LW_SAFE_LOG_STRING(pUser->pw_name), uid); } else { dwError = UmnSrvUpdateUser( pEventlog, hReg, hUsers, PreviousRun, Now, pUser); BAIL_ON_UMN_ERROR(dwError); } if (ppObjects) { LsaFreeSecurityObjectList(1, ppObjects); ppObjects = NULL; } } dwError = UmnSrvFindDeletedUsers( pEventlog, hReg, "Users", hUsers, Now); BAIL_ON_UMN_ERROR(dwError); cleanup: if (ppObjects) { LsaFreeSecurityObjectList(1, ppObjects); } if (hUsers) { RegCloseKey(hReg, hUsers); } return dwError; error: goto cleanup; }
DWORD UmnSrvFindDeletedUsers( PLW_EVENTLOG_CONNECTION pEventlog, HANDLE hReg, PCSTR pUserKeyName, HKEY hUsers, long long Now ) { DWORD dwError = 0; DWORD subKeyCount = 0; DWORD maxSubKeyLen = 0; DWORD subKeyLen = 0; DWORD i = 0; PSTR pKeyName = NULL; DWORD lastUpdated = 0; DWORD lastUpdatedLen = 0; USER_MONITOR_PASSWD old = { 0 }; dwError = RegQueryInfoKeyA( hReg, hUsers, NULL, NULL, NULL, &subKeyCount, &maxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL); BAIL_ON_UMN_ERROR(dwError); dwError = LwAllocateMemory( maxSubKeyLen + 1, (PVOID *)&pKeyName); for (i = 0; i < subKeyCount; i++) { if (gbPollerThreadShouldExit) { dwError = ERROR_CANCELLED; BAIL_ON_UMN_ERROR(dwError); } subKeyLen = maxSubKeyLen; dwError = RegEnumKeyExA( hReg, hUsers, i, pKeyName, &subKeyLen, NULL, NULL, NULL, NULL); BAIL_ON_UMN_ERROR(dwError); pKeyName[subKeyLen] = 0; lastUpdatedLen = sizeof(lastUpdated); dwError = RegGetValueA( hReg, hUsers, pKeyName, "LastUpdated", 0, NULL, (PBYTE)&lastUpdated, &lastUpdatedLen); if (dwError == LWREG_ERROR_NO_SUCH_KEY_OR_VALUE) { UMN_LOG_WARNING("User %s not completely written. The user monitor service may have previously terminated ungracefully.", LW_SAFE_LOG_STRING(pKeyName)); lastUpdated = 0; dwError = 0; } else { BAIL_ON_UMN_ERROR(dwError); } if (lastUpdated < Now) { UmnSrvFreeUserContents(&old); dwError = UmnSrvReadUser( pUserKeyName, pKeyName, &old); BAIL_ON_UMN_ERROR(dwError); UMN_LOG_INFO("User '%s' deleted", old.pw_name); dwError = RegDeleteKeyA( hReg, hUsers, pKeyName); BAIL_ON_UMN_ERROR(dwError); if (!strcmp(pUserKeyName, "Users")) { dwError = UmnSrvWriteUserEvent( pEventlog, old.LastUpdated, &old, Now, NULL); BAIL_ON_UMN_ERROR(dwError); } else { dwError = UmnSrvWriteADUserEvent( pEventlog, old.LastUpdated, &old, Now, NULL); BAIL_ON_UMN_ERROR(dwError); } // Make sure we don't skip the next key since this one was deleted i--; subKeyCount--; } } cleanup: UmnSrvFreeUserContents(&old); LW_SAFE_FREE_STRING(pKeyName); return dwError; error: goto cleanup; }
static DWORD LwTaskCliList( int argc, char* argv[] ) { DWORD dwError = 0; PLW_TASK_CLIENT_CONNECTION pConnection = NULL; LW_TASK_TYPE taskType = LW_TASK_TYPE_MIGRATE; DWORD dwNumTasks = 0; DWORD dwNumTotalTasks = 0; DWORD dwResume = 0; PLW_TASK_INFO pTaskInfoArray = NULL; BOOLEAN bContinue = TRUE; if (argc > 0) { if (!strcmp(argv[0], "migrate-share")) { taskType = LW_TASK_TYPE_MIGRATE; } else { fprintf(stderr, "Error: unknown task type [%s]\n", argv[0]); dwError = ERROR_BAD_ARGUMENTS; BAIL_ON_LW_TASK_ERROR(dwError); } } dwError = LwTaskOpenServer(&pConnection); BAIL_ON_LW_TASK_ERROR(dwError); do { DWORD iTask = 0; if (pTaskInfoArray) { LwTaskFreeTaskInfoArray(pTaskInfoArray, dwNumTasks); pTaskInfoArray = NULL; } dwError = LwTaskEnum( pConnection, taskType, &pTaskInfoArray, &dwNumTasks, &dwNumTotalTasks, &dwResume); switch (dwError) { case ERROR_MORE_DATA: bContinue = TRUE; dwError = ERROR_SUCCESS; break; case ERROR_SUCCESS: bContinue = FALSE; break; default: break; } BAIL_ON_LW_TASK_ERROR(dwError); for (; iTask < dwNumTasks; iTask++) { PLW_TASK_INFO pTaskInfo = &pTaskInfoArray[iTask]; fprintf(stdout, "\nTask id: [%s]\n", pTaskInfo->pszTaskId); fprintf(stdout, "\nArguments: \n"); if (pTaskInfo->dwNumArgs > 0) { DWORD iArg = 0; for (; iArg < pTaskInfo->dwNumArgs; iArg++) { PLW_TASK_ARG pArg = &pTaskInfo->pArgArray[iArg]; fprintf(stdout, "Name: %s\n", LW_SAFE_LOG_STRING(pArg->pszArgName)); fprintf(stdout, "Value: %s\n", LW_SAFE_LOG_STRING(pArg->pszArgValue)); } } } } while (bContinue); cleanup: if (pTaskInfoArray) { LwTaskFreeTaskInfoArray(pTaskInfoArray, dwNumTasks); pTaskInfoArray = NULL; } if (pConnection) { LwTaskCloseServer(pConnection); } return dwError; error: goto cleanup; }