DWORD ADLdap_GetObjectSid( HANDLE hDirectory, LDAPMessage* pMessage, PSTR* ppszSid ) { DWORD dwError = 0; UCHAR* pucSIDBytes = NULL; DWORD dwSIDByteLength = 0; PSTR pszSid = NULL; BAIL_ON_INVALID_POINTER(pMessage); if (hDirectory == (HANDLE)NULL) { dwError = LW_ERROR_INVALID_PARAMETER; BAIL_ON_LSA_ERROR(dwError); } dwError = LwLdapGetBytes( hDirectory, pMessage, AD_LDAP_OBJECTSID_TAG, &pucSIDBytes, &dwSIDByteLength); BAIL_ON_LSA_ERROR(dwError); BAIL_ON_INVALID_POINTER(pucSIDBytes); dwError = LsaSidBytesToString( pucSIDBytes, dwSIDByteLength, &pszSid); BAIL_ON_LSA_ERROR(dwError); *ppszSid = pszSid; cleanup: LW_SAFE_FREE_MEMORY(pucSIDBytes); return dwError; error: LW_SAFE_FREE_STRING(pszSid); *ppszSid = NULL; goto cleanup; }
DWORD NtlmClientEncryptMessage( IN PNTLM_CONTEXT_HANDLE phContext, IN BOOLEAN bEncrypt, IN OUT PSecBufferDesc pMessage, IN DWORD MessageSeqNo ) { DWORD dwError = LW_ERROR_SUCCESS; BAIL_ON_INVALID_POINTER(phContext); dwError = NtlmTransactEncryptMessage( *phContext, bEncrypt, pMessage, MessageSeqNo); BAIL_ON_LSA_ERROR(dwError); cleanup: return(dwError); error: // we may not want to clear the IN OUT params on error //memset(pMessage, 0, sizeof(SecBufferDesc)); goto cleanup; }
DWORD UmnSrvGetSkipNoLogin( PBOOLEAN pValue ) { DWORD dwError = 0; BOOLEAN bUnlockConfigLock = FALSE; BAIL_ON_INVALID_POINTER(pValue); pthread_rwlock_rdlock(&gUmnConfigLock); bUnlockConfigLock = TRUE; *pValue = gpAPIConfig->SkipNoLogin; cleanup: if (bUnlockConfigLock) { pthread_rwlock_unlock(&gUmnConfigLock); } return dwError; error: *pValue = 0; goto cleanup; }
LSASS_API DWORD LsaSetMachineName( HANDLE hLsaConnection, PCSTR pszMachineName ) { DWORD dwError = 0; size_t sNameLen = 0; BAIL_ON_INVALID_POINTER(pszMachineName); sNameLen = strlen(pszMachineName); if (sNameLen == 0) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_LSA_ERROR(dwError); } dwError = LsaProviderIoControl(hLsaConnection, LSA_PROVIDER_TAG_LOCAL, LSA_LOCAL_IO_SETDOMAINNAME, (DWORD)(sNameLen + 1), (PVOID)pszMachineName, NULL, NULL); error: return dwError; }
NTSTATUS LsaSrvInitUnicodeStringEx( PUNICODE_STRING pOut, PCWSTR pwszIn ) { NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = ERROR_SUCCESS; size_t sLen = 0; size_t sSize = 0; BAIL_ON_INVALID_POINTER(pOut); if (pwszIn) { dwError = LwWc16sLen(pwszIn, &sLen); BAIL_ON_LSA_ERROR(dwError); sSize = (sLen + 1) * sizeof(WCHAR); ntStatus = LsaSrvAllocateMemory(OUT_PPVOID(&pOut->Buffer), sSize); BAIL_ON_NTSTATUS_ERROR(ntStatus); memcpy(pOut->Buffer, pwszIn, sLen * sizeof(WCHAR)); } else { pOut->Buffer = NULL; } pOut->MaximumLength = sSize; pOut->Length = sLen * sizeof(WCHAR); cleanup: if (ntStatus == STATUS_SUCCESS && dwError != ERROR_SUCCESS) { ntStatus = LwWin32ErrorToNtStatus(dwError); } return ntStatus; error: if (pOut->Buffer) { LsaSrvFreeMemory(pOut->Buffer); pOut->Buffer = NULL; } pOut->MaximumLength = 0; pOut->Length = 0; goto cleanup; }
DWORD LsaSetSMBAnonymousCreds( OUT PLSA_CREDS_FREE_INFO* ppFreeInfo ) { DWORD dwError = 0; LW_PIO_CREDS pNewCreds = NULL; LW_PIO_CREDS pOldCreds = NULL; PLSA_CREDS_FREE_INFO pFreeInfo = NULL; BAIL_ON_INVALID_POINTER(ppFreeInfo); dwError = LwIoCreatePlainCredsA( "", "", "", &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->pRestoreCreds = pOldCreds; pFreeInfo->bKrbCreds = FALSE; pOldCreds = NULL; cleanup: *ppFreeInfo = pFreeInfo; if (pOldCreds != NULL) { LwIoDeleteCreds(pOldCreds); } if (pNewCreds != NULL) { LwIoDeleteCreds(pNewCreds); } return dwError; error: if (pFreeInfo) { LwFreeMemory(pFreeInfo); pFreeInfo = NULL; } goto cleanup; }
DWORD LsaDataBlobCopy( PLSA_DATA_BLOB *ppDst, PLSA_DATA_BLOB pSrc ) { DWORD dwError = LW_ERROR_INTERNAL; BAIL_ON_INVALID_POINTER(ppDst); BAIL_ON_INVALID_POINTER(pSrc); dwError = LsaDataBlobStore(ppDst, pSrc->dwLen, pSrc->pData); BAIL_ON_LSA_ERROR(dwError); cleanup: return dwError; error: goto cleanup; }
DWORD LsaValidateGroupInfo( PVOID pGroupInfo, DWORD dwGroupInfoLevel ) { DWORD dwError = 0; BAIL_ON_INVALID_POINTER(pGroupInfo); dwError = LsaValidateGroupInfoLevel(dwGroupInfoLevel); BAIL_ON_LSA_ERROR(dwError); switch (dwGroupInfoLevel) { case 0: { PLSA_GROUP_INFO_0 pGroupInfo_0 = (PLSA_GROUP_INFO_0)pGroupInfo; dwError = LsaValidateGroupName(pGroupInfo_0->pszName); BAIL_ON_LSA_ERROR(dwError); break; } case 1: { PLSA_GROUP_INFO_1 pGroupInfo_1 = (PLSA_GROUP_INFO_1)pGroupInfo; dwError = LsaValidateGroupName(pGroupInfo_1->pszName); BAIL_ON_LSA_ERROR(dwError); break; } default: dwError = LW_ERROR_UNSUPPORTED_GROUP_LEVEL; BAIL_ON_LSA_ERROR(dwError); } cleanup: return dwError; error: goto cleanup; }
DWORD LocalMarshalAttrToBOOLEAN( PDIRECTORY_ENTRY pEntry, PWSTR pwszAttrName, PBOOLEAN pbValue ) { DWORD dwError = 0; PDIRECTORY_ATTRIBUTE pAttr = NULL; PATTRIBUTE_VALUE pAttrValue = NULL; BAIL_ON_INVALID_POINTER(pEntry); dwError = LocalFindAttribute( pEntry, pwszAttrName, &pAttr); BAIL_ON_LSA_ERROR(dwError); if (pAttr->ulNumValues > 1) { dwError = LW_ERROR_DATA_ERROR; } else if (pAttr->ulNumValues == 0) { dwError = LW_ERROR_NO_ATTRIBUTE_VALUE; } else { pAttrValue = &pAttr->pValues[0]; if (pAttrValue->Type != DIRECTORY_ATTR_TYPE_BOOLEAN) { dwError = LW_ERROR_INVALID_ATTRIBUTE_VALUE; } } BAIL_ON_LSA_ERROR(dwError); *pbValue = pAttrValue->data.bBooleanValue; cleanup: return dwError; error: *pbValue = FALSE; goto cleanup; }
DWORD LocalMarshalAttrToLargeInteger( PDIRECTORY_ENTRY pEntry, PWSTR pwszAttrName, PLONG64 pllValue ) { DWORD dwError = 0; PDIRECTORY_ATTRIBUTE pAttr = NULL; PATTRIBUTE_VALUE pAttrValue = NULL; BAIL_ON_INVALID_POINTER(pEntry); dwError = LocalFindAttribute( pEntry, pwszAttrName, &pAttr); BAIL_ON_LSA_ERROR(dwError); if (pAttr->ulNumValues > 1) { dwError = LW_ERROR_DATA_ERROR; } else if (pAttr->ulNumValues == 0) { dwError = LW_ERROR_NO_ATTRIBUTE_VALUE; } else { pAttrValue = &pAttr->pValues[0]; if (pAttrValue->Type != DIRECTORY_ATTR_TYPE_LARGE_INTEGER) { dwError = LW_ERROR_INVALID_ATTRIBUTE_VALUE; } } BAIL_ON_LSA_ERROR(dwError); *pllValue = pAttrValue->data.llValue; cleanup: return dwError; error: *pllValue = 0; goto cleanup; }
DWORD LsaSrvGetMetrics( HANDLE hServer, DWORD dwInfoLevel, PVOID* ppMetricPack ) { DWORD dwError = 0; PVOID pMetricPack = NULL; BAIL_ON_INVALID_POINTER(ppMetricPack); switch(dwInfoLevel) { case 0: dwError = LsaSrvGetMetrics_0( &pMetricPack); break; case 1: dwError = LsaSrvGetMetrics_1( &pMetricPack); break; default: dwError = LW_ERROR_INVALID_METRIC_INFO_LEVEL; break; } BAIL_ON_LSA_ERROR(dwError); *ppMetricPack = pMetricPack; cleanup: return dwError; error: LSA_LOG_ERROR_API_FAILED(hServer, dwError, "get metrics (level=%u)", dwInfoLevel); *ppMetricPack = NULL; LW_SAFE_FREE_MEMORY(pMetricPack); goto cleanup; }
DWORD LsaGetDirectoryFromPath( IN PCSTR pszPath, OUT PSTR* ppszDir ) { PCSTR pszLastSlash = NULL; PSTR pszDir = NULL; DWORD dwError = 0; BAIL_ON_INVALID_POINTER(pszPath); pszLastSlash = strrchr(pszPath, '/'); if (pszLastSlash == pszPath) { //Include the trailing / since this is the root directory ( / ) pszLastSlash++; } if (pszLastSlash == NULL) { dwError = LwAllocateString( ".", &pszDir); BAIL_ON_LSA_ERROR(dwError); } else { dwError = LwStrndup( pszPath, pszLastSlash - pszPath, &pszDir); BAIL_ON_LSA_ERROR(dwError); } *ppszDir = pszDir; cleanup: return dwError; error: LW_SAFE_FREE_STRING(pszDir); *ppszDir = NULL; goto cleanup; }
DWORD NtlmClientFreeCredentialsHandle( IN PNTLM_CRED_HANDLE phCredential ) { DWORD dwError = LW_ERROR_SUCCESS; BAIL_ON_INVALID_POINTER(phCredential); if (*phCredential != NULL) { dwError = NtlmTransactFreeCredentialsHandle(*phCredential); } error: return dwError; }
DWORD NtlmClientExportSecurityContext( IN PNTLM_CONTEXT_HANDLE phContext, IN DWORD fFlags, OUT PSecBuffer pPackedContext ) { DWORD dwError = LW_ERROR_SUCCESS; BAIL_ON_INVALID_POINTER(phContext); dwError = NtlmTransactExportSecurityContext( *phContext, fFlags, pPackedContext); BAIL_ON_LSA_ERROR(dwError); error: return(dwError); }
DWORD NtlmClientQueryContextAttributes( IN PNTLM_CONTEXT_HANDLE phContext, IN DWORD ulAttribute, OUT PVOID pBuffer ) { DWORD dwError = LW_ERROR_SUCCESS; BAIL_ON_INVALID_POINTER(phContext); dwError = NtlmTransactQueryContextAttributes( *phContext, ulAttribute, pBuffer); error: return dwError; }
DWORD LsaModifyGroup_RemoveMembers( PLSA_GROUP_MOD_INFO pGroupModInfo, PVOID pData ) { DWORD dwError = 0; PCSTR pszSID = NULL; DWORD iMember = 0; BAIL_ON_INVALID_POINTER(pGroupModInfo); pszSID = (PCSTR)pData; pGroupModInfo->dwRemoveMembersNum++; dwError = LwReallocMemory(pGroupModInfo->pRemoveMembers, (PVOID*)&pGroupModInfo->pRemoveMembers, sizeof(pGroupModInfo->pRemoveMembers[0]) * pGroupModInfo->dwRemoveMembersNum); BAIL_ON_LSA_ERROR(dwError); if (pszSID) { iMember = pGroupModInfo->dwRemoveMembersNum - 1; dwError = LwAllocateString( pszSID, &pGroupModInfo->pRemoveMembers[iMember].pszSid); BAIL_ON_LSA_ERROR(dwError); pGroupModInfo->actions.bRemoveMembers = TRUE; } cleanup: return dwError; error: goto cleanup; }
DWORD LsaDataBlobAllocate( PLSA_DATA_BLOB *ppBlob, DWORD dwSize ) { DWORD dwError = LW_ERROR_INTERNAL; LSA_DATA_BLOB *pBlob = NULL; BAIL_ON_INVALID_POINTER(ppBlob); dwError = LwAllocateMemory(sizeof(LSA_DATA_BLOB), (PVOID*)&pBlob); BAIL_ON_LSA_ERROR(dwError); pBlob->dwLen = dwSize; pBlob->pData = NULL; if (pBlob->dwLen > 0) { dwError = LwAllocateMemory(pBlob->dwLen, (PVOID*)&pBlob->pData); BAIL_ON_LSA_ERROR(dwError); memset(pBlob->pData, 0x0, pBlob->dwLen); } *ppBlob = pBlob; cleanup: return dwError; error: if (pBlob) { LwFreeMemory(pBlob); } goto cleanup; }
DWORD LsaLogSetInfo( PLSA_LOG_INFO pLogInfo ) { DWORD dwError = 0; BAIL_ON_INVALID_POINTER(pLogInfo); // The only information that is allowed // to be set after the log is initialized // is the log level gLsaMaxLogLevel = pLogInfo->maxAllowedLogLevel; cleanup: return dwError; error: goto cleanup; }
DWORD LsaDataBlobStore( PLSA_DATA_BLOB *ppBlob, DWORD dwSize, const PBYTE pBuffer ) { DWORD dwError = LW_ERROR_INTERNAL; BAIL_ON_INVALID_POINTER(ppBlob); dwError = LsaDataBlobAllocate(ppBlob, dwSize); BAIL_ON_LSA_ERROR(dwError); if (dwSize > 0) { memcpy((*ppBlob)->pData, pBuffer, dwSize); } cleanup: return dwError; error: goto cleanup; }
DWORD SamDbGetObjectRecordInfoBySID_inlock( PSAM_DIRECTORY_CONTEXT pDirectoryContext, PCSTR pszObjectSID, PLONG64 pllObjectRecordId, SAMDB_OBJECT_CLASS* pObjectClass ) { DWORD dwError = 0; sqlite3_stmt* pSqlStatement = NULL; LONG64 llObjectRecordId = 0; SAMDB_OBJECT_CLASS objectClass = SAMDB_OBJECT_CLASS_UNKNOWN; BAIL_ON_INVALID_POINTER(pszObjectSID); if (!pDirectoryContext->pDbContext->pQueryObjectRecordInfoStmt) { PCSTR pszQueryTemplate = "SELECT " SAM_DB_COL_RECORD_ID "," \ SAM_DB_COL_OBJECT_CLASS \ " FROM " SAM_DB_OBJECTS_TABLE \ " WHERE " SAM_DB_COL_OBJECT_SID " = ?1"; dwError = sqlite3_prepare_v2( pDirectoryContext->pDbContext->pDbHandle, pszQueryTemplate, -1, &pDirectoryContext->pDbContext->pQueryObjectRecordInfoStmt, NULL); BAIL_ON_SAMDB_SQLITE_ERROR_DB( dwError, pDirectoryContext->pDbContext->pDbHandle); } pSqlStatement = pDirectoryContext->pDbContext->pQueryObjectRecordInfoStmt; dwError = sqlite3_bind_text( pSqlStatement, 1, pszObjectSID, -1, SQLITE_TRANSIENT); BAIL_ON_SAMDB_SQLITE_ERROR_STMT(dwError, pSqlStatement); if ((dwError = sqlite3_step(pSqlStatement) == SQLITE_ROW)) { if (sqlite3_column_count(pSqlStatement) != 2) { dwError = LW_ERROR_DATA_ERROR; BAIL_ON_SAMDB_ERROR(dwError); } llObjectRecordId = sqlite3_column_int64( pSqlStatement, 0); objectClass = sqlite3_column_int( pSqlStatement, 1); dwError = LW_ERROR_SUCCESS; } else if (dwError == SQLITE_DONE) { dwError = LW_ERROR_NO_SUCH_OBJECT; } BAIL_ON_SAMDB_SQLITE_ERROR_STMT(dwError, pSqlStatement); *pllObjectRecordId = llObjectRecordId; *pObjectClass = objectClass; cleanup: if (pDirectoryContext->pDbContext->pQueryObjectRecordInfoStmt) { sqlite3_reset(pDirectoryContext->pDbContext->pQueryObjectRecordInfoStmt); } return dwError; error: *pllObjectRecordId = 0; *pObjectClass = SAMDB_OBJECT_CLASS_UNKNOWN; goto cleanup; }
DWORD LocalMarshalAttrToANSIFromUnicodeString( PDIRECTORY_ENTRY pEntry, PWSTR pwszAttrName, PSTR* ppszValue ) { DWORD dwError = 0; PDIRECTORY_ATTRIBUTE pAttr = NULL; PATTRIBUTE_VALUE pAttrValue = NULL; PSTR pszValue = NULL; BAIL_ON_INVALID_POINTER(pEntry); dwError = LocalFindAttribute( pEntry, pwszAttrName, &pAttr); BAIL_ON_LSA_ERROR(dwError); if (pAttr->ulNumValues > 1) { dwError = LW_ERROR_DATA_ERROR; } else if (pAttr->ulNumValues == 0) { dwError = LW_ERROR_NO_ATTRIBUTE_VALUE; } else { pAttrValue = &pAttr->pValues[0]; if (pAttrValue->Type != DIRECTORY_ATTR_TYPE_UNICODE_STRING) { dwError = LW_ERROR_INVALID_ATTRIBUTE_VALUE; } else if (!pAttrValue->data.pwszStringValue) { dwError = LW_ERROR_NO_ATTRIBUTE_VALUE; } } BAIL_ON_LSA_ERROR(dwError); dwError = LwWc16sToMbs( pAttrValue->data.pwszStringValue, &pszValue); BAIL_ON_LSA_ERROR(dwError); *ppszValue = pszValue; cleanup: return dwError; error: *ppszValue = NULL; LW_SAFE_FREE_STRING(pszValue); goto cleanup; }
DWORD LocalMarshalAttrToOctetStream( PDIRECTORY_ENTRY pEntry, PWSTR pwszAttrName, PBYTE* ppData, PDWORD pdwDataLen ) { DWORD dwError = 0; PDIRECTORY_ATTRIBUTE pAttr = NULL; PATTRIBUTE_VALUE pAttrValue = NULL; PBYTE pData = NULL; DWORD dwDataLen = 0; BAIL_ON_INVALID_POINTER(pEntry); dwError = LocalFindAttribute( pEntry, pwszAttrName, &pAttr); BAIL_ON_LSA_ERROR(dwError); if (pAttr->ulNumValues > 1) { dwError = LW_ERROR_DATA_ERROR; } else if (pAttr->ulNumValues == 0) { dwError = LW_ERROR_NO_ATTRIBUTE_VALUE; } else { pAttrValue = &pAttr->pValues[0]; if (pAttrValue->Type != DIRECTORY_ATTR_TYPE_OCTET_STREAM) { dwError = LW_ERROR_INVALID_ATTRIBUTE_VALUE; } else if (!pAttrValue->data.pOctetString || !pAttrValue->data.pOctetString->pBytes || !pAttrValue->data.pOctetString->ulNumBytes) { dwError = LW_ERROR_NO_ATTRIBUTE_VALUE; } } BAIL_ON_LSA_ERROR(dwError); dwError = LwAllocateMemory( pAttrValue->data.pOctetString->ulNumBytes, (PVOID*)&pData); BAIL_ON_LSA_ERROR(dwError); dwDataLen = pAttrValue->data.pOctetString->ulNumBytes; memcpy(pData, pAttrValue->data.pOctetString->pBytes, dwDataLen); *ppData = pData; *pdwDataLen = dwDataLen; cleanup: return dwError; error: *ppData = NULL; *pdwDataLen = 0; LW_SAFE_FREE_MEMORY(pData); goto cleanup; }
DWORD LocalMarshalAttrToSid( PDIRECTORY_ENTRY pEntry, PWSTR pwszAttrName, PSID *ppSid ) { DWORD dwError = 0; NTSTATUS ntStatus = 0; PDIRECTORY_ATTRIBUTE pAttr = NULL; PATTRIBUTE_VALUE pAttrValue = NULL; PSID pSid = NULL; DWORD dwSidSize = 0; PSID pRetSid = NULL; BAIL_ON_INVALID_POINTER(pEntry); dwError = LocalFindAttribute( pEntry, pwszAttrName, &pAttr); BAIL_ON_LSA_ERROR(dwError); if (pAttr->ulNumValues > 1) { dwError = LW_ERROR_DATA_ERROR; } else if (pAttr->ulNumValues == 0) { dwError = LW_ERROR_NO_ATTRIBUTE_VALUE; } else { pAttrValue = &pAttr->pValues[0]; if (pAttrValue->Type == DIRECTORY_ATTR_TYPE_UNICODE_STRING) { ntStatus = RtlAllocateSidFromWC16String( &pSid, pAttrValue->data.pwszStringValue); BAIL_ON_NT_STATUS(ntStatus); } else if (pAttrValue->Type == DIRECTORY_ATTR_TYPE_ANSI_STRING) { ntStatus = RtlAllocateSidFromCString( &pSid, pAttrValue->data.pszStringValue); BAIL_ON_NT_STATUS(ntStatus); } else { dwError = LW_ERROR_INVALID_ATTRIBUTE_VALUE; } } BAIL_ON_LSA_ERROR(dwError); dwSidSize = RtlLengthSid(pSid); dwError = LwAllocateMemory( dwSidSize, OUT_PPVOID(&pRetSid)); BAIL_ON_LSA_ERROR(dwError); ntStatus = RtlCopySid( dwSidSize, pRetSid, pSid); BAIL_ON_NT_STATUS(ntStatus); *ppSid = pRetSid; cleanup: RTL_FREE(&pSid); if (dwError == ERROR_SUCCESS && ntStatus != STATUS_SUCCESS) { dwError = LwNtStatusToWin32Error(ntStatus); } return dwError; error: LW_SAFE_FREE_MEMORY(pRetSid); *ppSid = 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; }
DWORD LsaSrvGetStatus( HANDLE hServer, PCSTR pszTargetProvider, PLSASTATUS* ppLsaStatus ) { DWORD dwError = 0; BOOLEAN bInLock = FALSE; PLSA_AUTH_PROVIDER pProvider = NULL; DWORD dwProviderCount = 0; DWORD iCount = 0; DWORD dwStatusIndex = 0; HANDLE hProvider = (HANDLE)NULL; PLSASTATUS pLsaStatus = NULL; PLSA_AUTH_PROVIDER_STATUS pProviderOwnedStatus = NULL; BOOLEAN bFoundProvider = FALSE; PSTR pszTargetProviderName = NULL; PSTR pszTargetInstance = NULL; BAIL_ON_INVALID_POINTER(ppLsaStatus); dwError = LwAllocateMemory( sizeof(LSASTATUS), (PVOID*)&pLsaStatus); BAIL_ON_LSA_ERROR(dwError); pLsaStatus->dwUptime = (DWORD)difftime(time(NULL), gServerStartTime); dwError = LsaSrvGetLsassVersion( &pLsaStatus->lsassVersion); BAIL_ON_LSA_ERROR(dwError); dwError = LsaReadVersionFile( &pLsaStatus->productVersion); BAIL_ON_LSA_ERROR(dwError); if (pszTargetProvider) { dwError = LsaSrvGetTargetElements( pszTargetProvider, &pszTargetProviderName, &pszTargetInstance); BAIL_ON_LSA_ERROR(dwError); } ENTER_AUTH_PROVIDER_LIST_READER_LOCK(bInLock); if (pszTargetProviderName) { dwProviderCount = 1; } else { dwProviderCount = LsaGetNumberOfProviders_inlock(); } if (!dwProviderCount) { goto done; } dwError = LwAllocateMemory( dwProviderCount * sizeof(LSA_AUTH_PROVIDER_STATUS), (PVOID*)&pLsaStatus->pAuthProviderStatusList); BAIL_ON_LSA_ERROR(dwError); pLsaStatus->dwCount = dwProviderCount; dwError = LW_ERROR_NOT_HANDLED; for (pProvider = gpAuthProviderList, iCount = 0, dwStatusIndex = 0; pProvider; pProvider = pProvider->pNext, iCount++) { PLSA_AUTH_PROVIDER_STATUS pAuthProviderStatus = NULL; if (pszTargetProviderName) { if (!strcmp(pszTargetProviderName, pProvider->pszName)) { bFoundProvider = TRUE; } else { continue; } } dwError = LsaSrvOpenProvider( hServer, pProvider, pszTargetInstance, &hProvider); BAIL_ON_LSA_ERROR(dwError); pAuthProviderStatus = &pLsaStatus->pAuthProviderStatusList[dwStatusIndex++]; dwError = LwAllocateString( pProvider->pszName, &pAuthProviderStatus->pszId); BAIL_ON_LSA_ERROR(dwError); dwError = pProvider->pFnTable->pfnGetStatus( hProvider, &pProviderOwnedStatus); if (dwError == LW_ERROR_NOT_HANDLED) { dwError = 0; } else { BAIL_ON_LSA_ERROR(dwError); dwError = LsaSrvCopyProviderStatus( pProviderOwnedStatus, pAuthProviderStatus); BAIL_ON_LSA_ERROR(dwError); pProvider->pFnTable->pfnFreeStatus( pProviderOwnedStatus); pProviderOwnedStatus = NULL; } LsaSrvCloseProvider(pProvider, hProvider); hProvider = (HANDLE)NULL; } if (pszTargetProviderName && !bFoundProvider) { dwError = LW_ERROR_INVALID_AUTH_PROVIDER; BAIL_ON_LSA_ERROR(dwError); } done: *ppLsaStatus = pLsaStatus; cleanup: LW_SAFE_FREE_STRING(pszTargetProviderName); LW_SAFE_FREE_STRING(pszTargetInstance); if (pProvider != NULL && pProviderOwnedStatus) { pProvider->pFnTable->pfnFreeStatus( pProviderOwnedStatus); } if (hProvider != NULL) { LsaSrvCloseProvider(pProvider, hProvider); } LEAVE_AUTH_PROVIDER_LIST_READER_LOCK(bInLock); return dwError; error: LSA_LOG_ERROR_API_FAILED(hServer, dwError, "get lsass status"); if (ppLsaStatus) { *ppLsaStatus = NULL; } if (pLsaStatus) { LsaFreeStatus(pLsaStatus); } goto cleanup; }
DWORD LocalDirCreateNewAccountSecurityDescriptor( PSID pDomainSid, DWORD dwRid, DWORD dwObjectClass, PSECURITY_DESCRIPTOR_ABSOLUTE *ppSecDesc ) { NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = ERROR_SUCCESS; PSECURITY_DESCRIPTOR_ABSOLUTE pSecDesc = NULL; PSID pAdminSid = NULL; DWORD dwAdminSidSize = 0; PSID pBuiltinAdminsSid = NULL; DWORD dwBuiltinAdminsSidSize = 0; PACL pDacl = NULL; BAIL_ON_INVALID_POINTER(pDomainSid); BAIL_ON_INVALID_POINTER(ppSecDesc); if (dwRid <= DOMAIN_USER_RID_MAX) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_LSA_ERROR(dwError); } if (dwObjectClass != DIR_OBJECT_CLASS_USER && dwObjectClass != DIR_OBJECT_CLASS_LOCAL_GROUP) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_LSA_ERROR(dwError); } dwError = LwAllocateMemory(SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE, OUT_PPVOID(&pSecDesc)); BAIL_ON_LSA_ERROR(dwError); ntStatus = RtlCreateSecurityDescriptorAbsolute( pSecDesc, SECURITY_DESCRIPTOR_REVISION); BAIL_ON_NT_STATUS(ntStatus); /* * Set owner (Administrator) */ dwError = LwAllocateWellKnownSid(WinAccountAdministratorSid, pDomainSid, &pAdminSid, &dwAdminSidSize); BAIL_ON_LSA_ERROR(dwError); ntStatus = RtlSetOwnerSecurityDescriptor(pSecDesc, pAdminSid, FALSE); BAIL_ON_NT_STATUS(ntStatus); /* * Set group (BUILTIN\Administrators) */ dwError = LwAllocateWellKnownSid(WinBuiltinAdministratorsSid, NULL, &pBuiltinAdminsSid, &dwBuiltinAdminsSidSize); BAIL_ON_LSA_ERROR(dwError); ntStatus = RtlSetGroupSecurityDescriptor(pSecDesc, pBuiltinAdminsSid, FALSE); BAIL_ON_NT_STATUS(ntStatus); /* * Create default DACL */ if (dwObjectClass == DIR_OBJECT_CLASS_USER) { ntStatus = LocalDirCreateLocalUserDacl(pDomainSid, dwRid, &pDacl); } else if (dwObjectClass == DIR_OBJECT_CLASS_LOCAL_GROUP) { ntStatus = LocalDirCreateLocalGroupDacl(pDomainSid, dwRid, &pDacl); } BAIL_ON_NT_STATUS(ntStatus); ntStatus = RtlSetDaclSecurityDescriptor( pSecDesc, TRUE, pDacl, FALSE); BAIL_ON_NT_STATUS(ntStatus); *ppSecDesc = pSecDesc; cleanup: if (dwError == ERROR_SUCCESS && ntStatus != STATUS_SUCCESS) { dwError = LwNtStatusToWin32Error(ntStatus); } return dwError; error: LocalDirFreeSecurityDescriptor(&pSecDesc); goto cleanup; }
DWORD LsaRpcReadRegistry( PLSA_RPC_SERVER *ppRpcSrvList ) { DWORD dwError = 0; PLSA_CONFIG_REG pReg = NULL; PSTR pszServers = NULL; PSTR pszServerKey = NULL; PSTR pszServer = NULL; BAIL_ON_INVALID_POINTER(ppRpcSrvList); dwError = LsaOpenConfig( "Services\\lsass\\Parameters\\RPCServers", "Policy\\Services\\lsass\\Parameters\\RPCServers", &pReg); BAIL_ON_LSA_ERROR(dwError); if (pReg == NULL) { goto error; } dwError = LsaReadConfigMultiString( pReg, "LoadOrder", FALSE, &pszServers, NULL); BAIL_ON_LSA_ERROR(dwError); LsaCloseConfig(pReg); pReg = NULL; if (LW_IS_NULL_OR_EMPTY_STR(pszServers) ) { goto error; } pszServer = pszServers; while (pszServer != NULL && *pszServer != '\0') { dwError = LwAllocateStringPrintf( &pszServerKey, "Services\\lsass\\Parameters\\RpcServers\\%s", pszServer); BAIL_ON_LSA_ERROR(dwError); dwError = LsaRpcReadServer( pszServer, pszServerKey, ppRpcSrvList); BAIL_ON_LSA_ERROR(dwError); LW_SAFE_FREE_STRING(pszServerKey); pszServer = pszServer + strlen(pszServer) + 1; } cleanup: LW_SAFE_FREE_STRING(pszServers); LW_SAFE_FREE_STRING(pszServerKey); LsaCloseConfig(pReg); pReg = NULL; return dwError; error: goto cleanup; }
DWORD LsaMarshalGroupInfo1( HANDLE hLsa, LSA_FIND_FLAGS FindFlags, PLSA_SECURITY_OBJECT pGroup, DWORD dwMemberCount, PLSA_SECURITY_OBJECT* ppMembers, DWORD dwGroupInfoLevel, PVOID* ppGroupInfo ) { DWORD dwError = 0; PVOID pGroupInfo = NULL; PLSA_GROUP_INFO_1 pGroupInfo1 = NULL; /* The variable represents pGroupInfo casted to different types. Do not * free these values directly, free pGroupInfo instead. */ size_t sIndex = 0; size_t sEnabled = 0; *ppGroupInfo = NULL; BAIL_ON_INVALID_POINTER(pGroup); if (pGroup->type != LSA_OBJECT_TYPE_GROUP) { dwError = LW_ERROR_INVALID_PARAMETER; BAIL_ON_LSA_ERROR(dwError); } if (!pGroup->enabled) { dwError = LW_ERROR_NO_SUCH_GROUP; BAIL_ON_LSA_ERROR(dwError); } dwError = LwAllocateMemory( sizeof(LSA_GROUP_INFO_1), (PVOID*)&pGroupInfo); BAIL_ON_LSA_ERROR(dwError); pGroupInfo1 = (PLSA_GROUP_INFO_1) pGroupInfo; pGroupInfo1->gid = pGroup->groupInfo.gid; dwError = LwAllocateString( pGroup->groupInfo.pszUnixName, &pGroupInfo1->pszName); BAIL_ON_LSA_ERROR(dwError); // Optional values use LwStrDupOrNull. Required values use // LwAllocateString. dwError = LwStrDupOrNull( pGroup->groupInfo.pszPasswd, &pGroupInfo1->pszPasswd); BAIL_ON_LSA_ERROR(dwError); dwError = LwAllocateString( pGroup->pszObjectSid, &pGroupInfo1->pszSid); BAIL_ON_LSA_ERROR(dwError); if (pGroup->pszDN) { dwError = LwAllocateString( pGroup->pszDN, &pGroupInfo1->pszDN); BAIL_ON_LSA_ERROR(dwError); } for (sIndex = 0; sIndex < dwMemberCount; sIndex++) { if (ppMembers[sIndex]) { if (ppMembers[sIndex]->enabled) { sEnabled++; } if (ppMembers[sIndex]->type != LSA_OBJECT_TYPE_USER) { dwError = LW_ERROR_INVALID_PARAMETER; BAIL_ON_LSA_ERROR(dwError); } } } dwError = LwAllocateMemory( //Leave room for terminating null pointer sizeof(PSTR) * (sEnabled+1), (PVOID*)&pGroupInfo1->ppszMembers); BAIL_ON_LSA_ERROR(dwError); sEnabled = 0; for (sIndex = 0; sIndex < dwMemberCount; sIndex++) { if (ppMembers[sIndex]) { if (ppMembers[sIndex]->enabled) { dwError = LwAllocateString( ppMembers[sIndex]->userInfo.pszUnixName, &pGroupInfo1->ppszMembers[sEnabled++]); BAIL_ON_LSA_ERROR(dwError); } } } *ppGroupInfo = pGroupInfo; cleanup: return dwError; error: if (pGroupInfo) { LsaFreeGroupInfo(dwGroupInfoLevel, pGroupInfo); pGroupInfo = NULL; } *ppGroupInfo = NULL; goto cleanup; }
DWORD LsaMarshalUserInfo( PLSA_SECURITY_OBJECT pUser, DWORD dwUserInfoLevel, PVOID* ppUserInfo ) { DWORD dwError = 0; PVOID pUserInfo = NULL; /* These variables represent pUserInfo casted to different types. Do not * free these values directly, free pUserInfo instead. */ PLSA_USER_INFO_0 pUserInfo0 = NULL; PLSA_USER_INFO_1 pUserInfo1 = NULL; PLSA_USER_INFO_2 pUserInfo2 = NULL; *ppUserInfo = NULL; BAIL_ON_INVALID_POINTER(pUser); if (pUser->type != LSA_OBJECT_TYPE_USER) { dwError = LW_ERROR_INVALID_PARAMETER; BAIL_ON_LSA_ERROR(dwError); } if (!pUser->enabled) { dwError = LW_ERROR_NO_SUCH_USER; BAIL_ON_LSA_ERROR(dwError); } switch(dwUserInfoLevel) { case 0: dwError = LwAllocateMemory( sizeof(LSA_USER_INFO_0), (PVOID*)&pUserInfo); BAIL_ON_LSA_ERROR(dwError); pUserInfo0 = (PLSA_USER_INFO_0) pUserInfo; break; case 1: dwError = LwAllocateMemory( sizeof(LSA_USER_INFO_1), (PVOID*)&pUserInfo); BAIL_ON_LSA_ERROR(dwError); pUserInfo0 = (PLSA_USER_INFO_0) pUserInfo; pUserInfo1 = (PLSA_USER_INFO_1) pUserInfo; break; case 2: dwError = LwAllocateMemory( sizeof(LSA_USER_INFO_2), (PVOID*)&pUserInfo); BAIL_ON_LSA_ERROR(dwError); pUserInfo0 = (PLSA_USER_INFO_0) pUserInfo; pUserInfo1 = (PLSA_USER_INFO_1) pUserInfo; pUserInfo2 = (PLSA_USER_INFO_2) pUserInfo; break; default: dwError = LW_ERROR_INVALID_PARAMETER; BAIL_ON_LSA_ERROR(dwError); break; } if (pUserInfo0 != NULL) { pUserInfo0->uid = pUser->userInfo.uid; pUserInfo0->gid = pUser->userInfo.gid; dwError = LwAllocateString( pUser->userInfo.pszUnixName, &pUserInfo0->pszName); BAIL_ON_LSA_ERROR(dwError); // Optional values use LwStrDupOrNull. Required values use // LwAllocateString. dwError = LwStrDupOrNull( pUser->userInfo.pszPasswd, &pUserInfo0->pszPasswd); BAIL_ON_LSA_ERROR(dwError); dwError = LwStrDupOrNull( pUser->userInfo.pszGecos, &pUserInfo0->pszGecos); BAIL_ON_LSA_ERROR(dwError); dwError = LwAllocateString( pUser->userInfo.pszShell, &pUserInfo0->pszShell); BAIL_ON_LSA_ERROR(dwError); dwError = LwAllocateString( pUser->userInfo.pszHomedir, &pUserInfo0->pszHomedir); BAIL_ON_LSA_ERROR(dwError); dwError = LwAllocateString( pUser->pszObjectSid, &pUserInfo0->pszSid); BAIL_ON_LSA_ERROR(dwError); } if (pUserInfo1 != NULL) { dwError = LwStrDupOrNull( pUser->pszDN, &pUserInfo1->pszDN); BAIL_ON_LSA_ERROR(dwError); dwError = LwStrDupOrNull( pUser->userInfo.pszUPN, &pUserInfo1->pszUPN); BAIL_ON_LSA_ERROR(dwError); pUserInfo1->bIsGeneratedUPN = pUser->userInfo.bIsGeneratedUPN; pUserInfo1->bIsLocalUser = pUser->bIsLocal; pUserInfo1->pLMHash = NULL; pUserInfo1->dwLMHashLen = 0; pUserInfo1->pNTHash = NULL; pUserInfo1->dwNTHashLen = 0; } if (pUserInfo2 != NULL) { struct timeval current_tv; UINT64 u64current_NTtime = 0; if (pUser->userInfo.bIsAccountInfoKnown) { if (gettimeofday(¤t_tv, NULL) < 0) { dwError = LwMapErrnoToLwError(errno); BAIL_ON_LSA_ERROR(dwError); } LsaConvertTimeUnix2Nt(current_tv.tv_sec, &u64current_NTtime); if (pUser->userInfo.bPasswordNeverExpires || pUser->userInfo.qwPwdExpires == 0) { //password never expires pUserInfo2->dwDaysToPasswordExpiry = 0LL; } else if (pUser->userInfo.bPasswordExpired || u64current_NTtime >= pUser->userInfo.qwPwdExpires) { //password is expired already pUserInfo2->dwDaysToPasswordExpiry = 0LL; } else { pUserInfo2->dwDaysToPasswordExpiry = (pUser->userInfo.qwPwdExpires - u64current_NTtime) / (10000000LL * 24*60*60); } pUserInfo2->bPasswordNeverExpires = pUser->userInfo.bPasswordNeverExpires; pUserInfo2->bPasswordExpired = pUser->userInfo.bPasswordExpired; pUserInfo2->bPromptPasswordChange = pUser->userInfo.bPromptPasswordChange; pUserInfo2->bUserCanChangePassword = pUser->userInfo.bUserCanChangePassword; pUserInfo2->bAccountDisabled = pUser->userInfo.bAccountDisabled; pUserInfo2->bAccountExpired = pUser->userInfo.bAccountExpired; pUserInfo2->bAccountLocked = pUser->userInfo.bAccountLocked; } else { pUserInfo2->dwDaysToPasswordExpiry = 0LL; pUserInfo2->bPasswordExpired = FALSE; pUserInfo2->bPasswordNeverExpires = TRUE; pUserInfo2->bPromptPasswordChange = FALSE; pUserInfo2->bUserCanChangePassword = FALSE; pUserInfo2->bAccountDisabled = FALSE; pUserInfo2->bAccountExpired = FALSE; pUserInfo2->bAccountLocked = FALSE; } } *ppUserInfo = pUserInfo; cleanup: return dwError; error: if (pUserInfo) { LsaFreeUserInfo(dwUserInfoLevel, pUserInfo); pUserInfo = NULL; } *ppUserInfo = NULL; goto cleanup; }
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; }