DWORD LsaSetSMBCreds( IN PCSTR pszUserPrincipalName, IN PCSTR pszPassword, IN BOOLEAN bSetDefaultCachePath, OUT PLSA_CREDS_FREE_INFO* ppFreeInfo ) { DWORD dwError = 0; krb5_error_code ret = 0; PSTR pszNewCachePath = NULL; PCSTR pszCacheName = NULL; PCSTR pszCacheType = NULL; krb5_context ctx = 0; krb5_ccache cc = 0; LW_PIO_CREDS pNewCreds = NULL; LW_PIO_CREDS pOldCreds = NULL; PLSA_CREDS_FREE_INFO pFreeInfo = NULL; PSTR pszOldCachePath = NULL; BOOLEAN bSwitchedPath = FALSE; BAIL_ON_INVALID_POINTER(ppFreeInfo); BAIL_ON_INVALID_STRING(pszUserPrincipalName); ret = krb5_init_context(&ctx); BAIL_ON_KRB_ERROR(ctx, ret); /* Generates a new filed based credentials cache in /tmp. The file will * be owned by root and only accessible by root. */ ret = krb5_cc_new_unique( ctx, "FILE", "hint", &cc); BAIL_ON_KRB_ERROR(ctx, ret); pszCacheType = krb5_cc_get_type(ctx, cc); pszCacheName = krb5_cc_get_name(ctx, cc); dwError = LwAllocateStringPrintf(&pszNewCachePath, "%s:%s", pszCacheType, pszCacheName); BAIL_ON_LSA_ERROR(dwError); dwError = LwKrb5GetTgt( pszUserPrincipalName, pszPassword, pszNewCachePath, NULL); BAIL_ON_LSA_ERROR(dwError); if (bSetDefaultCachePath) { LSA_LOG_DEBUG("Switching default credentials path for new access token"); dwError = LwKrb5SetThreadDefaultCachePath( pszNewCachePath, &pszOldCachePath); BAIL_ON_LSA_ERROR(dwError); bSwitchedPath = TRUE; } dwError = LwIoCreateKrb5CredsA( pszUserPrincipalName, pszNewCachePath, &pNewCreds); BAIL_ON_LSA_ERROR(dwError); dwError = LwAllocateMemory(sizeof(*pFreeInfo), (PVOID*)&pFreeInfo); BAIL_ON_LSA_ERROR(dwError); dwError = LwIoGetThreadCreds(&pOldCreds); BAIL_ON_LSA_ERROR(dwError); dwError = LwIoSetThreadCreds(pNewCreds); BAIL_ON_LSA_ERROR(dwError); pFreeInfo->ctx = ctx; pFreeInfo->cc = cc; pFreeInfo->pRestoreCreds = pOldCreds; pFreeInfo->pszRestoreCache = pszOldCachePath; pFreeInfo->bKrbCreds = TRUE; pOldCreds = NULL; cleanup: *ppFreeInfo = pFreeInfo; if (pOldCreds != NULL) { LwIoDeleteCreds(pOldCreds); } if (pNewCreds != NULL) { LwIoDeleteCreds(pNewCreds); } LW_SAFE_FREE_STRING(pszNewCachePath); return dwError; error: if (ctx != NULL) { if (cc != NULL) { krb5_cc_destroy(ctx, cc); } krb5_free_context(ctx); } if (pFreeInfo) { LwFreeMemory(pFreeInfo); pFreeInfo = NULL; } if (bSwitchedPath) { LwKrb5SetThreadDefaultCachePath( pszOldCachePath, NULL); LW_SAFE_FREE_STRING(pszOldCachePath); } goto cleanup; }
NTSTATUS LsaSrvGetSystemCreds( OUT LW_PIO_CREDS *ppCreds ) { NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = ERROR_SUCCESS; LW_PIO_CREDS pCreds = NULL; PSTR pszMachinePrincipal = NULL; PSTR pszCachePath = NULL; PLSA_MACHINE_ACCOUNT_INFO_A pAccountInfo = NULL; dwError = LsaSrvProviderGetMachineAccountInfoA( LSA_PROVIDER_TAG_AD, NULL, &pAccountInfo); BAIL_ON_LSA_ERROR(dwError); dwError = LwAllocateStringPrintf( &pszMachinePrincipal, "%s@%s", pAccountInfo->SamAccountName, pAccountInfo->DnsDomainName); BAIL_ON_LSA_ERROR(dwError); dwError = LwAllocateStringPrintf( &pszCachePath, "%s.%s", LSASS_KRB5_CACHE_PATH, pAccountInfo->DnsDomainName); BAIL_ON_LSA_ERROR(dwError); dwError = LwIoCreateKrb5CredsA( pszMachinePrincipal, pszCachePath, &pCreds); BAIL_ON_LSA_ERROR(dwError); *ppCreds = pCreds; cleanup: LW_SAFE_FREE_STRING(pszMachinePrincipal); LW_SAFE_FREE_STRING(pszCachePath); LsaSrvFreeMachineAccountInfoA(pAccountInfo); if (ntStatus == STATUS_SUCCESS && dwError != ERROR_SUCCESS) { ntStatus = LwWin32ErrorToNtStatus(dwError); } return ntStatus; error: if (pCreds) { LwIoDeleteCreds(pCreds); } *ppCreds = NULL; goto cleanup; }
DWORD LwTaskAcquireCredsA( PCSTR pszUsername, /* IN */ PCSTR pszPassword, /* IN */ PLW_TASK_CREDS* ppCreds /* IN OUT */ ) { DWORD dwError = 0; krb5_error_code ret = 0; PSTR pszNewCachePath = NULL; PLW_TASK_CREDS pCreds = NULL; BAIL_ON_INVALID_POINTER(ppCreds); BAIL_ON_INVALID_STRING(pszUsername); dwError = LwAllocateMemory(sizeof(*pCreds), (PVOID*)&pCreds); BAIL_ON_LW_TASK_ERROR(dwError); ret = krb5_init_context(&pCreds->ctx); BAIL_ON_KRB_ERROR(pCreds->ctx, ret); /* Generates a new filed based credentials cache in /tmp. * The file will be owned by root and only accessible by root. */ ret = krb5_cc_new_unique(pCreds->ctx, "FILE", "hint", &pCreds->cc); BAIL_ON_KRB_ERROR(pCreds->ctx, ret); dwError = LwAllocateStringPrintf( &pszNewCachePath, "%s:%s", krb5_cc_get_type(pCreds->ctx, pCreds->cc), krb5_cc_get_name(pCreds->ctx, pCreds->cc)); BAIL_ON_LW_TASK_ERROR(dwError); dwError = LwKrb5GetTgt(pszUsername, pszPassword, pszNewCachePath, NULL); BAIL_ON_LW_TASK_ERROR(dwError); dwError = LwKrb5SetDefaultCachePath( pszNewCachePath, &pCreds->pszRestoreCache); BAIL_ON_LW_TASK_ERROR(dwError); dwError = LwIoCreateKrb5CredsA( pszUsername, pszNewCachePath, &pCreds->pKrb5Creds); BAIL_ON_LW_TASK_ERROR(dwError); *ppCreds = pCreds; cleanup: LW_SAFE_FREE_STRING(pszNewCachePath); return dwError; error: *ppCreds = NULL; if (pCreds) { LwTaskFreeCreds(pCreds); } goto cleanup; }