static DWORD VmAfdAllocateSidFromUid( uid_t uid, PSID *ppSid) { DWORD dwError = 0; NTSTATUS ntStatus = 0; PSID pSid = NULL; PSTR pszSid = NULL; dwError = VmAfdAllocateStringPrintf( &pszSid, "S-1-22-1-%d", /* Unix uid SID string */ uid); BAIL_ON_VMAFD_ERROR(dwError); ntStatus = RtlAllocateSidFromCString( &pSid, pszSid); dwError = LwNtStatusToWin32Error(ntStatus); BAIL_ON_VMAFD_ERROR(dwError); *ppSid = pSid; cleanup: VMAFD_SAFE_FREE_STRINGA(pszSid); return dwError; error: goto cleanup; }
static DWORD VmAfdAllocateSidFromGid( gid_t gid, PSID *ppSid) { DWORD dwError = 0; PSID pSid = NULL; PSTR pszSid = NULL; dwError = VmAfdAllocateStringPrintf( &pszSid, "S-1-22-2-%d", /* Unix gid SID string */ gid); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateSidFromCString( &pSid, pszSid); BAIL_ON_VMAFD_ERROR(dwError); *ppSid = pSid; cleanup: VMAFD_SAFE_FREE_STRINGA(pszSid); return dwError; error: goto cleanup; }
static DWORD _VmAfdWriteSuperlogEntryToEventLog( PVMAFD_SUPERLOG_ENTRY superlogEntry ) { DWORD dwError = 0; PCSTR pszDelimiter = "||"; PSTR pszMarshalledEntry = NULL; dwError = VmAfdAllocateStringPrintf( &pszMarshalledEntry, "%u%s%u%s%u%s%lu%s", superlogEntry->dwErrorCode, pszDelimiter, superlogEntry->dwCDCLastPing, pszDelimiter, superlogEntry->iStartTime, pszDelimiter, superlogEntry->iEndTime, pszDelimiter ); BAIL_ON_VMAFD_ERROR(dwError); cleanup: VMAFD_SAFE_FREE_MEMORY(pszMarshalledEntry); return dwError; error: goto cleanup; }
static DWORD VmAfdCheckCertOnDisk( PCSTR pszAlias, PCSTR pszCAPath, PCSTR pszFilename, LONG maxIndex, PBOOLEAN pbCertOnDisk ) { DWORD dwError = 0; LONG index = 0; BOOLEAN bCertOnDisk = FALSE; PSTR pszPath = NULL; PSTR pszAliasOther = NULL; // Note : maxIndex starts from 0 for (; !bCertOnDisk && (index <= maxIndex); index++) { VMAFD_SAFE_FREE_MEMORY(pszPath); dwError = VmAfdAllocateStringPrintf( &pszPath, "%s%s%s.%ld", pszCAPath, VMAFD_PATH_SEPARATOR_STR, pszFilename, index); BAIL_ON_VMAFD_ERROR(dwError); VMAFD_SAFE_FREE_MEMORY(pszAliasOther); dwError = VecsComputeCertAliasFile(pszPath, &pszAliasOther); BAIL_ON_VMAFD_ERROR(dwError); if (!VmAfdStringCompareA(pszAlias, pszAliasOther, FALSE)) { bCertOnDisk = TRUE; } } *pbCertOnDisk = bCertOnDisk; cleanup: VMAFD_SAFE_FREE_MEMORY(pszPath); VMAFD_SAFE_FREE_MEMORY(pszAliasOther); return dwError; error: *pbCertOnDisk = FALSE; goto cleanup; }
static DWORD GetPassword( PSTR *ppszPassword ) { CHAR pszPasswordBuff[100] = {0}; PSTR pszPassword = NULL; DWORD dwError = 0; struct termios tp, save; fflush(stdout); tcgetattr(0, &tp) ; memcpy (&save, &tp, sizeof (struct termios)); save.c_lflag &= ~ECHO; /* ECHO off, other bits unchanged */ tcsetattr(0, TCSANOW, &save); if (!fgets(pszPasswordBuff, 100, stdin) && ferror(stdin)) { dwError = LwErrnoToWin32Error(ferror(stdin)); BAIL_ON_VMAFD_ERROR (dwError); } if (pszPasswordBuff[strlen(pszPasswordBuff)-1] == '\n') { pszPasswordBuff[strlen(pszPasswordBuff)-1] = '\0'; } dwError = VmAfdAllocateStringPrintf( &pszPassword, "%s", pszPasswordBuff ); BAIL_ON_VMAFD_ERROR (dwError); *ppszPassword = pszPassword; cleanup: tcsetattr(0, TCSANOW, &tp); fflush (stdin); return dwError; error: if (ppszPassword) { *ppszPassword = NULL; } VMAFD_SAFE_FREE_MEMORY (pszPassword); goto cleanup; }
DWORD VmAfdConnectLdapWithMachineAccount( LDAP** ppLotus ) { DWORD dwError = 0; LDAP* pLotus = NULL; PSTR pszUpn = NULL; PVMAFD_REG_ARG pArgs = NULL; PWSTR pwszDCName = NULL; PSTR pszDCName = NULL; dwError = VmAfdGetMachineInfo(&pArgs); BAIL_ON_VMAFD_ERROR_NO_LOG(dwError); dwError = VmAfSrvGetAffinitizedDC(&pwszDCName); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringAFromW(pwszDCName, &pszDCName); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringPrintf( &pszUpn, "%s@%s", pArgs->pszAccount, pArgs->pszDomain); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdLDAPConnect( pszDCName, LDAP_PORT, pszUpn, pArgs->pszPassword, &pLotus); BAIL_ON_VMAFD_ERROR_NO_LOG(dwError); *ppLotus = pLotus; cleanup: VMAFD_SAFE_FREE_STRINGA(pszUpn); VMAFD_SAFE_FREE_STRINGA(pszDCName); VMAFD_SAFE_FREE_STRINGW(pwszDCName); VmAfdFreeRegArgs(pArgs); return dwError; error: if (pLotus) { VmAfdLdapClose(pLotus); } goto cleanup; }
DWORD VmAfdLDAPConnect( PSTR pszHostName, DWORD dwPort, PCSTR pszUpn, PCSTR pszPassword, LDAP** ppLotus ) { DWORD dwError = 0; LDAP* pDirectory = NULL; PSTR pszLdapURI = NULL; if (dwPort == 0) { dwPort = LDAP_PORT; } if (VmAfdIsIPV6AddrFormat(pszHostName)) { dwError = VmAfdAllocateStringPrintf( &pszLdapURI, "ldap://[%s]:%d", pszHostName, dwPort); } else { dwError = VmAfdAllocateStringPrintf( &pszLdapURI, "ldap://%s:%d", pszHostName, dwPort); } BAIL_ON_VMAFD_ERROR(dwError); dwError = VmDirSafeLDAPBind( &pDirectory, pszHostName, pszUpn, pszPassword); BAIL_ON_VMAFD_ERROR(dwError); *ppLotus = pDirectory; cleanup: VMAFD_SAFE_FREE_MEMORY(pszLdapURI); return dwError; error: *ppLotus = NULL; if (pDirectory != NULL) { ldap_unbind_ext(pDirectory, NULL, NULL); } goto cleanup; }
static DWORD VmAfdSrvWriteRootToDisk( PCSTR pszCertificate, PCSTR pszCAPath, PCSTR pszFilename ) { DWORD dwError = 0; LONG maxIndex = -1; PSTR pszPath = NULL; PSTR pszAlias = NULL; FILE* pFile = NULL; size_t len = 0; size_t bytesToWrite = 0; BOOLEAN bCertOnDisk = FALSE; PCSTR pszCursor = NULL; dwError = VmAfdFindFileIndex(pszCAPath, pszFilename, &maxIndex); if (dwError != ERROR_FILE_NOT_FOUND) { BAIL_ON_VMAFD_ERROR(dwError); dwError = VecsComputeCertAliasA((PSTR)pszCertificate, &pszAlias); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdCheckCertOnDisk( pszAlias, pszCAPath, pszFilename, maxIndex, &bCertOnDisk); BAIL_ON_VMAFD_ERROR(dwError); if (bCertOnDisk) { goto cleanup; } } dwError = VmAfdAllocateStringPrintf( &pszPath, "%s%s%s.%ld", pszCAPath, VMAFD_PATH_SEPARATOR_STR, pszFilename, maxIndex+1); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdOpenFilePath(pszPath, "w", &pFile); BAIL_ON_VMAFD_ERROR(dwError); len = strlen(pszCertificate); bytesToWrite = len; pszCursor = pszCertificate; while (bytesToWrite > 0) { size_t bytesWritten = 0; if ((bytesWritten = fwrite(pszCursor, 1, len, pFile)) == 0) { #ifndef _WIN32 dwError = LwErrnoToWin32Error(errno); #else dwError = GetLastError(); #endif BAIL_ON_VMAFD_ERROR(dwError); } pszCursor += bytesWritten; bytesToWrite -= bytesWritten; } cleanup: if (pFile) { fclose(pFile); } VMAFD_SAFE_FREE_MEMORY(pszPath); VMAFD_SAFE_FREE_MEMORY(pszAlias); return dwError; error: goto cleanup; }
static DWORD GetPassword( PSTR *ppszPassword ) { CHAR pszPasswordBuff[100] = {0}; PSTR pszPassword = NULL; DWORD dwError = 0; HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); DWORD mode = 0; fflush(stdout); if (!GetConsoleMode(hStdin, &mode)) { dwError = GetLastError(); BAIL_ON_VMAFD_ERROR (dwError); } if (!SetConsoleMode(hStdin, mode & (~ENABLE_ECHO_INPUT))) { dwError = GetLastError(); BAIL_ON_VMAFD_ERROR (dwError); } if (!fgets(pszPasswordBuff, 100, stdin) && ferror(stdin)) { dwError = GetLastError(); BAIL_ON_VMAFD_ERROR (dwError); } if (pszPasswordBuff[strlen(pszPasswordBuff)-1] == '\n') { pszPasswordBuff[strlen(pszPasswordBuff)-1] = '\0'; } dwError = VmAfdAllocateStringPrintf( &pszPassword, "%s", pszPasswordBuff ); BAIL_ON_VMAFD_ERROR (dwError); *ppszPassword = pszPassword; cleanup: if (!SetConsoleMode(hStdin, mode)) { dwError = GetLastError(); BAIL_ON_VMAFD_ERROR (dwError); } fflush (stdin); return dwError; error: if (ppszPassword) { *ppszPassword = NULL; } VMAFD_SAFE_FREE_MEMORY (pszPassword); goto cleanup; }
static DWORD VmAfdCliBeginOrEndUpgrade( PVM_AFD_CLI_CONTEXT pContext ) { DWORD dwError = 0; PSTR pszAccount = NULL; PSTR pszPassword = NULL; PSTR pszDomainName = NULL; BOOL bUsingIPC = FALSE; PVMAFD_SERVER pServer = NULL; if (!pContext) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMAFD_ERROR(dwError); } dwError = VmAfdGetDomainNameA(NULL,&pszDomainName); BAIL_ON_VMAFD_ERROR(dwError); if (IsNullOrEmptyString(pContext->pszServerName)) { bUsingIPC = TRUE; } if (bUsingIPC && !IsNullOrEmptyString(pContext->pszUserName)) { printf ("Getting heartbeat status of local system\n" "lightwave user-name will not be used\n" ); } if (!bUsingIPC) { //Factor domain name as well into this equation if(IsNullOrEmptyString(pContext->pszUserName)) { dwError = VmAfdGetMachineAccountInfoA(NULL, &pszAccount, &pszPassword); } else { if (VmAfdCaselessStrStrA(pContext->pszUserName, "@")) { dwError = VmAfdAllocateStringA(pContext->pszUserName, &pszAccount); } else { dwError = VmAfdAllocateStringPrintf( &pszAccount, "%s@%s", pContext->pszUserName, pszDomainName ); } BAIL_ON_VMAFD_ERROR(dwError); if (IsNullOrEmptyString(pContext->pszPassword)) { dwError = GetPassword(&pszPassword); } else { dwError = VmAfdAllocateStringA(pContext->pszPassword, &pszPassword); } BAIL_ON_VMAFD_ERROR(dwError); } } BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdOpenServerA( pContext->pszServerName, pszAccount, pszPassword, &pServer ); BAIL_ON_VMAFD_ERROR(dwError); if (pContext->action == VM_AFD_ACTION_BEGIN_UPGRADE) { dwError = VmAfdBeginUpgrade(pServer); BAIL_ON_VMAFD_ERROR(dwError); printf ("Begin upgrade state is set\n"); } else if (pContext->action == VM_AFD_ACTION_END_UPGRADE) { dwError = VmAfdEndUpgrade(pServer); BAIL_ON_VMAFD_ERROR(dwError); printf ("End upgrade state is set\n"); } cleanup: VMAFD_SAFE_FREE_MEMORY(pszAccount); VMAFD_SAFE_FREE_MEMORY(pszPassword); VMAFD_SAFE_FREE_MEMORY(pszDomainName); if (pServer) { VmAfdCloseServer(pServer); } return dwError; error: goto cleanup; }
DWORD VmAfdRestPasswordRefresh( PCSTR pszServer, PCSTR pszDomain, PCSTR pszUser, PCSTR pszPass, BOOLEAN bForce, BOOLEAN bInsecure, PSTR *ppszNewPass ) { DWORD dwError = 0; PSTR pszToken = NULL; PSTR pszNewPass = NULL; PSTR pszUrl = NULL; PVM_HTTP_CLIENT pHttpClient = NULL; PSTR pszParamString = NULL; PCSTR pszResult = NULL; PWSTR pwszCAPath = NULL; PSTR pszCAPath = NULL; if (IsNullOrEmptyString(pszServer) || IsNullOrEmptyString(pszDomain) || IsNullOrEmptyString(pszUser) || IsNullOrEmptyString(pszPass) || !ppszNewPass) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMAFD_ERROR(dwError); } if (bInsecure) { pszCAPath = NULL; } else { dwError = VmAfSrvGetCAPath(&pwszCAPath); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringAFromW(pwszCAPath, &pszCAPath); BAIL_ON_VMAFD_ERROR(dwError); } /* acquire token */ dwError = VmAfdAcquireOIDCToken( pszServer, pszDomain, pszUser, pszPass, pszCAPath, VMAFD_OIDC_VMDIR_SCOPE, &pszToken); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringPrintf( &pszParamString, "?force=%s", bForce?"true":"false"); BAIL_ON_VMAFD_ERROR(dwError); /* make rest url */ dwError = VmFormatUrl( "https", pszServer, VMDIR_REST_API_HTTPS_PORT, VMDIR_REST_API_BASE"/"VMDIR_REST_API_PASSWORD_REFRESH_CMD, pszParamString, &pszUrl); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmHttpClientInit(&pHttpClient, pszCAPath); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmHttpClientSetToken(pHttpClient, VMHTTP_TOKEN_TYPE_BEARER, pszToken); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmHttpClientPerform(pHttpClient, VMHTTP_METHOD_POST, pszUrl); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmHttpClientGetResult(pHttpClient, &pszResult); BAIL_ON_VMAFD_ERROR(dwError); dwError = _VmAfdGetHttpResultPassword(pszResult, &pszNewPass); BAIL_ON_VMAFD_ERROR(dwError); /* pszPassword could be NULL if force is not set or not aged */ /* caller handles this scenario */ *ppszNewPass = pszNewPass; cleanup: VmHttpClientFreeHandle(pHttpClient); VMAFD_SAFE_FREE_MEMORY(pszCAPath); VMAFD_SAFE_FREE_MEMORY(pwszCAPath); VMAFD_SAFE_FREE_STRINGA(pszParamString); VMAFD_SAFE_FREE_STRINGA(pszUrl); VMAFD_SAFE_FREE_STRINGA(pszToken); return dwError; error: VMAFD_SAFE_FREE_STRINGA(pszNewPass); goto cleanup; }
DWORD VmDdnsUpdateMakePacket( PSTR pszZone, PSTR pszHostname, PSTR pszName, PSTR* ppDnsPacket, DWORD* ppacketSize, DWORD headerId, DWORD dwFlag ) { PSTR pLabelName = NULL; PSTR fqdn = NULL; DWORD dwError = 0; DWORD labelLength = 0; DWORD packetSize = 0; DWORD upCount = 2; VMDNS_IP4_ADDRESS* pV4Address = NULL; VMDNS_IP6_ADDRESS* pV6Address = NULL; PVMAFD_MESSAGE_BUFFER pDnsBuffer = NULL; PSTR pDnsPacket = NULL; if(!pszZone || !pszName || !pszHostname || !ppDnsPacket || !ppacketSize) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMAFD_ERROR(dwError); } dwError = VmAfdAllocateStringPrintf( &fqdn, "%s.%s", pszName, pszZone ); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmDdnsConstructName( fqdn, &pLabelName, &labelLength ); BAIL_ON_VMAFD_ERROR(dwError); //Add updated records if(dwFlag == VMDDNS_UPDATE_PACKET) { dwError = VmDdnsGetSourceIp( &pV4Address, &pV6Address ); BAIL_ON_VMAFD_ERROR(dwError); upCount++; } dwError = VmAfdAllocateBufferStream( 0, &pDnsBuffer ); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmDdnsMakeUpdateHeader( pDnsBuffer, headerId, upCount ); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmDdnsMakeZone( pszZone, pDnsBuffer ); BAIL_ON_VMAFD_ERROR(dwError); //Delete all A records dwError = VmDdnsMakeDeleteRR( VMDDNS_TYPE_A, pLabelName, labelLength, pDnsBuffer ); BAIL_ON_VMAFD_ERROR(dwError); //Delete all AAAA records dwError = VmDdnsMakeDeleteRR( VMDDNS_TYPE_AAAA, pLabelName, labelLength, pDnsBuffer ); BAIL_ON_VMAFD_ERROR(dwError); if(dwFlag == VMDDNS_UPDATE_PACKET) { //Add A records if(pV4Address) { dwError = VmDdnsMakeUpdateRR( VMDDNS_TYPE_A, pLabelName, labelLength, pDnsBuffer, pV4Address, NULL ); BAIL_ON_VMAFD_ERROR(dwError); } else { dwError = VmDdnsMakeUpdateRR( VMDDNS_TYPE_AAAA, pLabelName, labelLength, pDnsBuffer, NULL, pV6Address ); BAIL_ON_VMAFD_ERROR(dwError); } } dwError = VmAfdCopyBufferFromBufferStream( pDnsBuffer, NULL, &packetSize ); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateMemory( packetSize, (PVOID)&pDnsPacket ); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdCopyBufferFromBufferStream( pDnsBuffer, pDnsPacket, &packetSize ); BAIL_ON_VMAFD_ERROR(dwError); *ppDnsPacket = pDnsPacket; *ppacketSize = packetSize; cleanup: VMAFD_SAFE_FREE_MEMORY(pV4Address); VMAFD_SAFE_FREE_MEMORY(pV6Address); VmAfdFreeBufferStream(pDnsBuffer); VMAFD_SAFE_FREE_STRINGA(pLabelName); VMAFD_SAFE_FREE_STRINGA(fqdn); return dwError; error: if(pDnsPacket) { VMAFD_SAFE_FREE_STRINGA(pDnsPacket); } if(ppDnsPacket) { *ppDnsPacket = NULL; } goto cleanup; }
DWORD VmAfdQueryCACerts( LDAP* pLotus, PCSTR pszCACN, BOOL bDetail, PVMAFD_CA_CERT_ARRAY* ppCACertificates ) { DWORD dwError = 0; PSTR pszClassFilter = "(objectClass=vmwCertificationAuthority)"; PSTR pszAttrEntryDN = "entryDN"; PSTR pszAttrCADN = "cACertificateDN"; PSTR pszAttrCert = "cACertificate"; PSTR pszAttrCrl = "certificateRevocationList"; PSTR pszFilter = NULL; PSTR pszComboFilter = NULL; PSTR pszSearchBaseDN= NULL; PSTR pszDomainName = NULL; LDAPMessage* pSearchResult = NULL; LDAPMessage* pCAResult = NULL; PVMAFD_CA_CERT_ARRAY pCertArray = NULL; PCHAR attrs[] = { pszAttrEntryDN, pszAttrCADN, pszAttrCert, pszAttrCrl, NULL}; struct berval** ppValues = NULL; int nCertCount = 0; int certIndex = 0; dwError = VmAfdAllocateMemory( sizeof(VMAFD_CA_CERT_ARRAY), (PVOID*)&pCertArray); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdGetDefaultDomainName( pLotus, &pszDomainName); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringPrintf( &pszSearchBaseDN, "cn=Configuration,%s", pszDomainName); BAIL_ON_VMAFD_ERROR(dwError); if (pszCACN) { dwError = VmAfdAllocateStringPrintf( &pszComboFilter, "(&(CN=%s)%s)", pszCACN, pszClassFilter); BAIL_ON_VMAFD_ERROR(dwError); pszFilter = pszComboFilter; } else { pszFilter = pszClassFilter; } dwError = ldap_search_ext_s( pLotus, pszSearchBaseDN, LDAP_SCOPE_SUBTREE, pszFilter, attrs, 0, /* get values and attrs */ NULL, NULL, NULL, 0, &pSearchResult); BAIL_ON_VMAFD_ERROR(dwError); nCertCount = ldap_count_entries(pLotus, pSearchResult); if (nCertCount > 0) { pCertArray->dwCount = nCertCount; dwError = VmAfdAllocateMemory( sizeof(VMAFD_CA_CERT) * nCertCount, (PVOID*)&pCertArray->pCACerts); BAIL_ON_VMAFD_ERROR(dwError); for ( pCAResult = ldap_first_entry(pLotus, pSearchResult); pCAResult != NULL; pCAResult = ldap_next_entry(pLotus, pCAResult), ++certIndex) { // The following assumes there's only one certificate for each CA // object. In the future if the whole chain is store, we will // update accordingly. // Copy CN dwError = VmAfdCopyQueryResultAttributeString( pLotus, pCAResult, pszAttrEntryDN, FALSE, (PSTR*)&pCertArray->pCACerts[certIndex].pCN); BAIL_ON_VMAFD_ERROR(dwError); // Copy subject DN dwError = VmAfdCopyQueryResultAttributeString( pLotus, pCAResult, pszAttrCADN, FALSE, (PSTR*)&pCertArray->pCACerts[certIndex].pSubjectDN); BAIL_ON_VMAFD_ERROR(dwError); if (bDetail) { // Copy certificate dwError = VmAfdCopyQueryResultAttributeString( pLotus, pCAResult, pszAttrCert, FALSE, (PSTR*)&pCertArray->pCACerts[certIndex].pCert); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdCopyQueryResultAttributeString( pLotus, pCAResult, pszAttrCrl, TRUE, (PSTR*)&pCertArray->pCACerts[certIndex].pCrl); BAIL_ON_VMAFD_ERROR(dwError); } } } *ppCACertificates = pCertArray; cleanup: VMAFD_SAFE_FREE_MEMORY(pszSearchBaseDN); VMAFD_SAFE_FREE_MEMORY(pszDomainName); VMAFD_SAFE_FREE_MEMORY(pszComboFilter); if (ppValues != NULL) { ldap_value_free_len(ppValues); ppValues = NULL; } if(pSearchResult != NULL) { ldap_msgfree(pSearchResult); } return dwError; error: if (pCertArray ) { VecsFreeCACertArray(pCertArray); } if (ppCACertificates) { *ppCACertificates = NULL; } goto cleanup; }
/* * If pszServerName is in IP format, use it as Lotus Server Name. * If pszServerName is NOT "localhost" which means caller specify a name they prefer, use it as the Lotus Server Name. * * Otherwise, derive FQDN based on existing network naming configuration. * i.e. Call gethostname then perform forward+reverse lookup to derive the FQDN as Lotus Server Name. * The forward+reverse look up is for kerberos naming consistency between server (Lotus) and clients, which * could be Lotus or open sources, e.g. openldap. * However, this auto name resolution is error-prone as system could have multiple IF(s) defined and * we have no idea which IF we should pick to perform reverse lookup. * Thus, the best chance to get Kerberos working is - customer provides proper FQDN as Lotus Server Name. */ static DWORD VmAfSrvGetLotusServerName( PCSTR pszServerName, PSTR* ppOutServerName ) { DWORD dwError = 0; PSTR pszHostnameCanon = NULL; PSTR pszLocalHostName = NULL; PSTR pszFQDN = NULL; if ( !pszServerName || !ppOutServerName ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMAFD_ERROR(dwError); } if ( VmAfdStringCompareA( pszServerName, "localhost", FALSE ) != 0 ) { // caller provides preferred Lotus Server Name or IP dwError = VmAfdAllocateStringA( pszServerName, &pszHostnameCanon ); BAIL_ON_VMAFD_ERROR(dwError); } else { // caller does NOT specify preferred Lotus Server Name, derives it ourselves. dwError = VmAfdGetHostName(&pszLocalHostName); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdGetCanonicalHostName(pszLocalHostName, &pszHostnameCanon); BAIL_ON_VMAFD_ERROR(dwError); } BAIL_ON_VMAFD_EMPTY_STRING(pszHostnameCanon, dwError); if (!VmAfdCheckIfIPV4AddressA(pszHostnameCanon) && !VmAfdCheckIfIPV6AddressA(pszHostnameCanon) && pszHostnameCanon[VmAfdStringLenA(pszHostnameCanon) - 1] != '.') { dwError = VmAfdAllocateStringPrintf( &pszFQDN, "%s.", pszHostnameCanon); BAIL_ON_VMAFD_ERROR(dwError); } else { pszFQDN = pszHostnameCanon; pszHostnameCanon = NULL; } *ppOutServerName = pszFQDN; VmAfdLog(VMAFD_DEBUG_ANY, "Lotus server name: (%s)", *ppOutServerName); cleanup: VMAFD_SAFE_FREE_MEMORY(pszHostnameCanon); return dwError; error: VMAFD_SAFE_FREE_MEMORY(pszFQDN); VmAfdLog(VMAFD_DEBUG_ANY, "%s failed (%s). Error(%u)", __FUNCTION__, pszServerName, dwError); goto cleanup; }
DWORD VmAfdQueryCACertAndCrlAttributes( LDAP* pLotus, PVMAFD_CERT_ARRAY* ppCertificates, PVMAFD_CRL_FILE_CONTAINER* ppCrls ) { DWORD dwError = 0; PSTR pszFilter = "(objectClass=vmwCertificationAuthority)"; PSTR pszAttrCert = "cACertificate"; PSTR pszAttrCrl = "certificateRevocationList"; PSTR pszSearchBaseDN = NULL; PSTR pszDomainName = NULL; LDAPMessage* pSearchResult = NULL; LDAPMessage* pCAResult = NULL; PCHAR attrs[] = { pszAttrCert, pszAttrCrl, NULL}; int nCertCount = 0; int nCrlCount = 0; PVMAFD_CERT_ARRAY pCertArray = NULL; PVMAFD_CRL_FILE_CONTAINER pCrlContainer = NULL; struct berval** ppValues = NULL; if (!ppCertificates || !ppCrls) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMAFD_ERROR(dwError); } dwError = VmAfdGetDefaultDomainName( pLotus, &pszDomainName); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringPrintf( &pszSearchBaseDN, "cn=Configuration,%s", pszDomainName); BAIL_ON_VMAFD_ERROR(dwError); dwError = ldap_search_ext_s( pLotus, pszSearchBaseDN, LDAP_SCOPE_SUBTREE, pszFilter, attrs, 0, /* get values and attrs */ NULL, NULL, NULL, 0, &pSearchResult); BAIL_ON_VMAFD_ERROR(dwError); for ( pCAResult = ldap_first_entry(pLotus, pSearchResult); pCAResult != NULL; pCAResult = ldap_next_entry(pLotus, pCAResult)) { nCertCount += VmAfdCountResultAttribute( pLotus, pCAResult, pszAttrCert); nCrlCount += VmAfdCountResultAttribute( pLotus, pCAResult, pszAttrCrl); } dwError = VmAfdAllocateMemory( sizeof(VMAFD_CERT_ARRAY), (PVOID*)&pCertArray); BAIL_ON_VMAFD_ERROR(dwError); pCertArray->dwCount = nCertCount; dwError = VmAfdAllocateMemory( sizeof(VMAFD_CRL_FILE_CONTAINER), (PVOID*)&pCrlContainer); BAIL_ON_VMAFD_ERROR(dwError); pCrlContainer->dwCount = nCrlCount; if (nCertCount || nCrlCount) { int certIndex = 0; int crlIndex = 0; if (nCertCount) { dwError = VmAfdAllocateMemory( sizeof(VMAFD_CERT_CONTAINER) * nCertCount, (PVOID*)&pCertArray->certificates); BAIL_ON_VMAFD_ERROR(dwError); } if (nCrlCount) { dwError = VmAfdAllocateMemory( sizeof(VMAFD_CRL_DATA) * nCrlCount, (PVOID*)&pCrlContainer->crls); BAIL_ON_VMAFD_ERROR(dwError); } for ( pCAResult = ldap_first_entry(pLotus, pSearchResult); pCAResult != NULL; pCAResult = ldap_next_entry(pLotus, pCAResult)) { // Copy certs ppValues = ldap_get_values_len( pLotus, pCAResult, pszAttrCert); if (ppValues) { int i = 0; while(ppValues[i]) { dwError = VmAfdAllocateMemory( sizeof(CHAR) * ppValues[i]->bv_len + 1, (PVOID)&pCertArray->certificates[certIndex].pCert); BAIL_ON_VMAFD_ERROR(dwError); memcpy( (PVOID) pCertArray->certificates[certIndex].pCert, (PVOID) ppValues[i]->bv_val, (size_t) ppValues[i]->bv_len); i++; certIndex++; } ldap_value_free_len(ppValues); ppValues = NULL; } // Copy CRLs ppValues = ldap_get_values_len( pLotus, pCAResult, pszAttrCrl); if (ppValues) { int i = 0; while(ppValues[i]) { dwError = VmAfdAllocateMemory( sizeof(CHAR) * ppValues[i]->bv_len + 1, (PVOID)&pCrlContainer->crls[crlIndex].buffer); BAIL_ON_VMAFD_ERROR(dwError); memcpy( (PVOID) pCrlContainer->crls[crlIndex].buffer, (PVOID) ppValues[i]->bv_val, (size_t) ppValues[i]->bv_len); i++; crlIndex++; } ldap_value_free_len(ppValues); ppValues = NULL; } } } *ppCertificates = pCertArray; *ppCrls = pCrlContainer; cleanup: VMAFD_SAFE_FREE_MEMORY(pszSearchBaseDN); VMAFD_SAFE_FREE_MEMORY(pszDomainName); if (ppValues != NULL) { ldap_value_free_len(ppValues); ppValues = NULL; } if(pSearchResult != NULL) { ldap_msgfree(pSearchResult); } return dwError; error: *ppCertificates = NULL; VMAFD_SAFE_FREE_MEMORY(pCrlContainer); if (ppCertificates) { *ppCertificates = NULL; } if(ppCrls) { *ppCrls = NULL; } if (pCertArray ) { VecsFreeCertArray(pCertArray); } goto cleanup; }
static DWORD CdcVmafdHeartbeatPing( PWSTR pwszDCName, PWSTR pwszAccount, PWSTR pwszPassword, PWSTR pwszDomainName, PBOOL pbIsAlive ) { DWORD dwError = 0; PSTR pszUPN = NULL; PSTR pszAccount = NULL; PSTR pszDomainName = NULL; PWSTR pwszUPN = NULL; BOOL bIsAlive = FALSE; PVMAFD_SERVER pServer = NULL; PVMAFD_HB_STATUS_W pHeartbeatStatus = NULL; if (IsNullOrEmptyString(pwszDCName) || IsNullOrEmptyString(pwszAccount) || IsNullOrEmptyString(pwszPassword) || IsNullOrEmptyString(pwszDomainName) || !pbIsAlive ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMAFD_ERROR(dwError); } dwError = VmAfdAllocateStringAFromW( pwszAccount, &pszAccount ); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringAFromW( pwszDomainName, &pszDomainName ); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringPrintf( &pszUPN, "%s@%s", pszAccount, pszDomainName ); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringWFromA( pszUPN, &pwszUPN ); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdOpenServerW( pwszDCName, pwszUPN, pwszPassword, &pServer ); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdGetHeartbeatStatusW( pServer, &pHeartbeatStatus ); BAIL_ON_VMAFD_ERROR(dwError); bIsAlive = pHeartbeatStatus->bIsAlive? TRUE: FALSE; *pbIsAlive = bIsAlive; cleanup: if (pServer) { VmAfdCloseServer(pServer); } if (pHeartbeatStatus) { VmAfdFreeHeartbeatStatusW(pHeartbeatStatus); } VMAFD_SAFE_FREE_MEMORY(pszUPN); VMAFD_SAFE_FREE_MEMORY(pwszUPN); VMAFD_SAFE_FREE_MEMORY(pszAccount); VMAFD_SAFE_FREE_MEMORY(pszDomainName); return dwError; error: if (pbIsAlive) { *pbIsAlive = FALSE; } VmAfdLog(VMAFD_DEBUG_ANY, "Failed to get heartbeat Status due to Error: %d", dwError ); goto cleanup; }
static DWORD VmAfSrvDirOpenConnection( PCWSTR pwszDCName, PCWSTR pwszDomain, PCWSTR pwszAccount, PCWSTR pwszPassword, PVMDIR_CONNECTION*ppConnection ) { DWORD dwError = 0; PSTR pszDCName = NULL; PSTR pszDomain = NULL; PSTR pszAccount = NULL; PSTR pszPassword = NULL; PSTR pszURI = NULL; PVMDIR_CONNECTION pConnection = NULL; dwError = VmAfdAllocateStringAFromW(pwszDCName, &pszDCName); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringAFromW(pwszDomain, &pszDomain); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringAFromW(pwszAccount, &pszAccount); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringAFromW(pwszPassword, &pszPassword); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringPrintf( &pszURI, "ldap://%s:%d", pszDCName, LDAP_PORT); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmDirConnectionOpen( pszURI, pszDomain, pszAccount, pszPassword, &pConnection); BAIL_ON_VMAFD_ERROR(dwError); *ppConnection = pConnection; cleanup: VMAFD_SAFE_FREE_MEMORY(pszURI); VMAFD_SAFE_FREE_MEMORY(pszDCName); VMAFD_SAFE_FREE_MEMORY(pszDomain); VMAFD_SAFE_FREE_MEMORY(pszAccount); VMAFD_SAFE_FREE_MEMORY(pszPassword); return dwError; error: if (ppConnection) { *ppConnection = NULL; } if (pConnection) { VmDirConnectionClose(pConnection); } goto cleanup; }
DWORD VmAfdGetDomainController( PCSTR pszDomain, PCSTR pszUserName, PCSTR pszPassword, PCSTR pszSiteName, /* OPTIONAL */ PSTR* ppszHostname, PSTR* ppszNetworkAddress ) { DWORD dwError = 0; PDNS_SERVER_INFO pServerArray = NULL; DWORD dwServerCount = 0; PSTR pszQuestion = NULL; DWORD dwDsFlags = 0; PSTR pszNetworkAddress = NULL; PSTR pszHostname = NULL; PSTR pszUPN = NULL; PSTR pszDomainDN = NULL; if (IsNullOrEmptyString(pszDomain) || !ppszHostname || !ppszNetworkAddress) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMAFD_ERROR(dwError); } if (IsNullOrEmptyString(pszSiteName)) { dwError = VmAfdAllocateStringPrintf( &pszQuestion, "_ldap._tcp.%s", pszDomain); BAIL_ON_VMAFD_ERROR(dwError); } else { dwError = VmAfdAllocateStringPrintf( &pszQuestion, "_ldap._tcp.%s._sites.%s", pszSiteName, pszDomain); BAIL_ON_VMAFD_ERROR(dwError); } dwError = LWNetDnsSrvQueryByQuestion( pszQuestion, NULL, dwDsFlags, &pServerArray, &dwServerCount); BAIL_ON_VMAFD_ERROR(dwError); if (dwServerCount > 0) { DWORD iServer = 0; dwError = VmAfdAllocateStringPrintf( &pszUPN, "%s@%s", pszUserName, pszDomain); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfSrvGetDomainDN(pszDomain, &pszDomainDN); BAIL_ON_VMAFD_ERROR(dwError); for (; iServer < dwServerCount; iServer++) { DWORD dwError2 = 0; PDNS_SERVER_INFO pServerInfo = &pServerArray[iServer]; dwError2 = VmAfSrvCheckDC( pServerInfo, pszDomainDN, pszUPN, pszPassword, &pszHostname, &pszNetworkAddress); if (dwError2 == ERROR_SUCCESS) { break; } } } if (!pszNetworkAddress || !pszHostname) { dwError = ERROR_NO_SUCH_DOMAIN; BAIL_ON_VMAFD_ERROR(dwError); } *ppszHostname = pszHostname; *ppszNetworkAddress = pszNetworkAddress; cleanup: if (pServerArray) { LWNetFreeMemory(pServerArray); } VMAFD_SAFE_FREE_MEMORY(pszQuestion); VMAFD_SAFE_FREE_MEMORY(pszUPN); VMAFD_SAFE_FREE_MEMORY(pszDomainDN); return dwError; error: if (ppszNetworkAddress) { *ppszNetworkAddress = NULL; } VMAFD_SAFE_FREE_MEMORY(pszHostname); VMAFD_SAFE_FREE_MEMORY(pszNetworkAddress); goto cleanup; }
DWORD VmAfdGetDomainControllerList( PCSTR pszDomain, PVMAFD_DC_INFO_W *ppVmAfdDCInfoList, PDWORD pdCount ) { DWORD dwError = 0; DWORD dwIndex = 0; PDNS_SERVER_INFO pServerArray = NULL; DWORD dwServerCount = 0; PSTR pszQuestion = NULL; DWORD dwDsFlags = 0; PSTR pszUPN = NULL; PSTR pszDomainDN = NULL; PVMAFD_DC_INFO_W pVmAfdDCEntries = NULL; if (IsNullOrEmptyString(pszDomain) || !ppVmAfdDCInfoList) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMAFD_ERROR(dwError); } dwError = VmAfdAllocateStringPrintf( &pszQuestion, "_ldap._tcp.%s", pszDomain); BAIL_ON_VMAFD_ERROR(dwError); dwError = LWNetDnsSrvQueryByQuestion( pszQuestion, NULL, dwDsFlags, &pServerArray, &dwServerCount); BAIL_ON_VMAFD_ERROR(dwError); if (dwServerCount > 0 ) { dwError = VmAfdAllocateMemory( sizeof(VMAFD_DC_INFO_W)*dwServerCount, (PVOID *)&pVmAfdDCEntries ); BAIL_ON_VMAFD_ERROR(dwError); for (; dwIndex < dwServerCount; dwIndex++) { PDNS_SERVER_INFO pServerInfo = &pServerArray[dwIndex]; PVMAFD_DC_INFO_W pDcInfo = &pVmAfdDCEntries[dwIndex]; dwError = VmAfdAllocateStringWFromA( pServerInfo->pszName, &pDcInfo->pwszHostName ); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringWFromA( pServerInfo->pszAddress, &pDcInfo->pwszAddress ); BAIL_ON_VMAFD_ERROR(dwError); } } *pdCount = dwServerCount; *ppVmAfdDCInfoList = pVmAfdDCEntries; cleanup: if (pServerArray) { LWNetFreeMemory(pServerArray); } VMAFD_SAFE_FREE_MEMORY(pszQuestion); VMAFD_SAFE_FREE_MEMORY(pszUPN); VMAFD_SAFE_FREE_MEMORY(pszDomainDN); return dwError; error: if (dwServerCount > 0 && pVmAfdDCEntries ) { for (dwIndex = 0; dwIndex < dwServerCount ; dwIndex++) { PVMAFD_DC_INFO_W pDcInfo = &pVmAfdDCEntries[dwIndex]; if (pDcInfo) { VMAFD_SAFE_FREE_MEMORY(pDcInfo->pwszHostName); VMAFD_SAFE_FREE_MEMORY(pDcInfo->pwszAddress); } } } VMAFD_SAFE_FREE_MEMORY(pVmAfdDCEntries); goto cleanup; }
DWORD VmAfdGetMachineInfo( PVMAFD_REG_ARG *ppArgs ) { DWORD dwError = 0; PWSTR pwszAccountName = NULL; PWSTR pwszPassword = NULL; PWSTR pwszAccountDN = NULL; PWSTR pwszDomain = NULL; PWSTR pwszAccount = NULL; PVMAFD_REG_ARG pArgs = NULL; VMAFD_DOMAIN_STATE domainState = VMAFD_DOMAIN_STATE_NONE ; dwError = VmAfSrvGetDomainState(&domainState); BAIL_ON_VMAFD_ERROR(dwError); if (domainState == VMAFD_DOMAIN_STATE_NONE) { dwError = ERROR_NOT_JOINED; BAIL_ON_VMAFD_ERROR_NO_LOG(dwError); } dwError = VmAfSrvGetMachineAccountInfo( &pwszAccount, &pwszPassword, &pwszAccountDN, NULL); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateMemory( sizeof(VMAFD_REG_ARG), (PVOID*)&pArgs); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringAFromW( pwszAccountDN, &pArgs->pszAccountDN); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringAFromW( pwszPassword, &pArgs->pszPassword); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringAFromW( pwszAccount, &pArgs->pszAccount); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfSrvGetDomainName(&pwszDomain); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringAFromW( pwszDomain, &pArgs->pszDomain); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringPrintf( &(pArgs->pszAccountUPN), "%s@%s", pArgs->pszAccount, pArgs->pszDomain); BAIL_ON_VMAFD_ERROR(dwError); if (IsNullOrEmptyString(pArgs->pszAccountDN) || IsNullOrEmptyString(pArgs->pszPassword)) { dwError = VECS_MISSING_CREDS; BAIL_ON_VMAFD_ERROR(dwError); } *ppArgs = pArgs; cleanup: VMAFD_SAFE_FREE_MEMORY(pwszAccountName); VMAFD_SAFE_FREE_MEMORY(pwszPassword); VMAFD_SAFE_FREE_MEMORY(pwszAccountDN); VMAFD_SAFE_FREE_MEMORY(pwszDomain); VMAFD_SAFE_FREE_MEMORY(pwszAccount); return dwError; error : *ppArgs = NULL; if (pArgs) { VmAfdFreeRegArgs(pArgs); } switch (dwError) { case VECS_MISSING_CREDS: VmAfdLog(VMAFD_DEBUG_ANY, "Account DN / Password missing"); break; case VECS_MISSING_DC_NAME: VmAfdLog(VMAFD_DEBUG_ANY, "Invalid domain controller name"); break; default: VmAfdLog( VMAFD_DEBUG_ANY, "Error [%d] getting machine Info", dwError); break; } goto cleanup; }