VOID VmDnsTrimDomainNameSuffix( PSTR pszName, PCSTR pcszDomainName ) { PSTR pszTail = NULL; if (IsNullOrEmptyString(pszName) || IsNullOrEmptyString(pcszDomainName)) { return; } if (VmDnsStringLenA(pszName) <= VmDnsStringLenA(pcszDomainName)) { return; } if (!VmDnsAllocateStringPrintfA(&pszTail, ".%s.", pcszDomainName)) { VmDnsStringTrimA(pszName, pszTail, FALSE); VMDNS_SAFE_FREE_STRINGA(pszTail); } if (!VmDnsAllocateStringPrintfA(&pszTail, ".%s", pcszDomainName)) { VmDnsStringTrimA(pszName, pszTail, FALSE); VMDNS_SAFE_FREE_STRINGA(pszTail); } }
DWORD VmDnsSrvRecordToString( PVMDNS_RECORD pRecord, PSTR* ppStr ) { DWORD dwError = ERROR_SUCCESS; PSTR pStr = NULL; PCSTR pszType = NULL; dwError = VmDnsRecordTypeToString(pRecord->dwType, &pszType); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsAllocateStringPrintfA( &pStr, "Type: %s, " "Name: %s, " "Target: %s, " "Port: %hu, " "Priority: %hu, " "Weight: %hu", pszType, pRecord->pszName, pRecord->Data.SRV.pNameTarget, pRecord->Data.SRV.wPort, pRecord->Data.SRV.wPriority, pRecord->Data.SRV.wWeight ); *ppStr = pStr; BAIL_ON_VMDNS_ERROR(dwError); cleanup: return dwError; error: VMDNS_SAFE_FREE_STRINGA(pStr); goto cleanup; }
DWORD VmDnsPtrRecordToString( PVMDNS_RECORD pRecord, PSTR* ppStr ) { DWORD dwError = ERROR_SUCCESS; PSTR pStr = NULL; PCSTR pszType = NULL; dwError = VmDnsRecordTypeToString(pRecord->dwType, &pszType); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsAllocateStringPrintfA( &pStr, "Type: %s\n" "Name: %s\n" "Class: %hu\n" "TTL: %u\n" "Server: %s\n", pszType, pRecord->pszName, pRecord->iClass, pRecord->dwTtl, pRecord->Data.PTR.pNameHost ); BAIL_ON_VMDNS_ERROR(dwError); *ppStr = pStr; cleanup: return dwError; error: VMDNS_SAFE_FREE_STRINGA(pStr); goto cleanup; }
static DWORD VmDnsCliValidateAndCompleteRecord( PVM_DNS_CLI_CONTEXT pContext ) { DWORD dwError = 0; PSTR pszTargetFQDN = NULL; pContext->record.iClass = VMDNS_CLASS_IN; pContext->record.dwTtl = VMDNS_DEFAULT_TTL; dwError = VmDnsCliValidateRecordInput(pContext); BAIL_ON_VMDNS_ERROR(dwError); switch (pContext->record.dwType) { case VMDNS_RR_TYPE_A: case VMDNS_RR_TYPE_AAAA: dwError = VmDnsMakeFQDN( pContext->record.pszName, pContext->pszZone, &pszTargetFQDN); BAIL_ON_VMDNS_ERROR(dwError); if (pszTargetFQDN) { VMDNS_SAFE_FREE_STRINGA(pContext->record.pszName); pContext->record.pszName = pszTargetFQDN; pszTargetFQDN = NULL; } break; case VMDNS_RR_TYPE_SRV: dwError = VmDnsAllocateStringPrintfA(&pContext->record.pszName, "%s.%s.%s", pContext->pszService, pContext->pszProtocol, pContext->pszZone); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsMakeFQDN(pContext->record.Data.SRV.pNameTarget, pContext->pszZone, &pszTargetFQDN); BAIL_ON_VMDNS_ERROR(dwError); if (pszTargetFQDN) { VMDNS_SAFE_FREE_STRINGA(pContext->record.Data.SRV.pNameTarget); pContext->record.Data.SRV.pNameTarget = pszTargetFQDN; pszTargetFQDN = NULL; } break; case VMDNS_RR_TYPE_NS: dwError = VmDnsMakeFQDN(pContext->record.Data.NS.pNameHost, pContext->pszZone, &pszTargetFQDN); BAIL_ON_VMDNS_ERROR(dwError); if (pszTargetFQDN) { VMDNS_SAFE_FREE_STRINGA(pContext->record.Data.NS.pNameHost); pContext->record.Data.NS.pNameHost = pszTargetFQDN; pszTargetFQDN = NULL; } DWORD dwNameLen = strlen(pContext->record.pszName); if (pContext->record.pszName[dwNameLen -1] != '.') { dwError = VmDnsAllocateStringPrintfA(&pszTargetFQDN, "%s.", pContext->record.pszName); BAIL_ON_VMDNS_ERROR(dwError); if (pszTargetFQDN) { VMDNS_SAFE_FREE_STRINGA(pContext->record.pszName); pContext->record.pszName = pszTargetFQDN; pszTargetFQDN = NULL; } } break; case VMDNS_RR_TYPE_PTR: if (!VmDnsStringStrA(pContext->record.pszName, pContext->pszZone)) { fprintf(stderr, "Error: IP address doesn't belong to " "the given reverse zone.\n"); dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } dwError = VmDnsMakeFQDN( pContext->record.pszName, pContext->pszZone, &pszTargetFQDN); BAIL_ON_VMDNS_ERROR(dwError); if (pszTargetFQDN) { VMDNS_SAFE_FREE_STRINGA(pContext->record.pszName); pContext->record.pszName = pszTargetFQDN; pszTargetFQDN = NULL; } break; case VMDNS_RR_TYPE_CNAME: dwError = VmDnsMakeFQDN(pContext->record.Data.CNAME.pNameHost, pContext->pszZone, &pszTargetFQDN); BAIL_ON_VMDNS_ERROR(dwError); if (pszTargetFQDN) { VMDNS_SAFE_FREE_STRINGA(pContext->record.Data.CNAME.pNameHost); pContext->record.Data.NS.pNameHost = pszTargetFQDN; pszTargetFQDN = NULL; } dwError = VmDnsMakeFQDN( pContext->record.pszName, pContext->pszZone, &pszTargetFQDN); BAIL_ON_VMDNS_ERROR(dwError); if (pszTargetFQDN) { VMDNS_SAFE_FREE_STRINGA(pContext->record.pszName); pContext->record.pszName = pszTargetFQDN; pszTargetFQDN = NULL; } break; default: dwError = ERROR_NOT_SUPPORTED; break; } if (IsNullOrEmptyString(pContext->record.pszName)) { fprintf(stderr, "Error: DNS Record name is not specified\n"); dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } cleanup: return dwError; error: goto cleanup; }
static DWORD VmDnsCliDelRecord( PVM_DNS_CLI_CONTEXT pContext ) { DWORD dwError = 0; DWORD idx = 0; PVMDNS_RECORD_ARRAY pRecordArray = NULL; BOOL bFound = FALSE; PSTR pszTargetFQDN = NULL; if (pContext->record.dwType == VMDNS_RR_TYPE_SOA) { fprintf(stdout, "SOA record cannot be deleted.\n"); dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } dwError = VmDnsCliValidateAndCompleteRecord(pContext); BAIL_ON_VMDNS_ERROR(dwError); if (pContext->record.dwType == VMDNS_RR_TYPE_SRV) { dwError = VmDnsMakeFQDN(pContext->record.Data.SRV.pNameTarget, pContext->pszZone, &pszTargetFQDN); BAIL_ON_VMDNS_ERROR(dwError); if (pszTargetFQDN) { VMDNS_SAFE_FREE_STRINGA(pContext->record.Data.SRV.pNameTarget); pContext->record.Data.SRV.pNameTarget = pszTargetFQDN; pszTargetFQDN = NULL; } } if (pContext->record.dwType == VMDNS_RR_TYPE_NS) { dwError = VmDnsMakeFQDN(pContext->record.Data.NS.pNameHost, pContext->pszZone, &pszTargetFQDN); BAIL_ON_VMDNS_ERROR(dwError); if (pszTargetFQDN) { VMDNS_SAFE_FREE_STRINGA(pContext->record.Data.NS.pNameHost); pContext->record.Data.NS.pNameHost = pszTargetFQDN; pszTargetFQDN = NULL; } DWORD dwNameLen = strlen(pContext->record.pszName); if (pContext->record.pszName[dwNameLen -1] != '.') { VmDnsAllocateStringPrintfA(&pszTargetFQDN, "%s.", pContext->record.pszName); VMDNS_SAFE_FREE_STRINGA(pContext->record.pszName); pContext->record.pszName = pszTargetFQDN; pszTargetFQDN = NULL; } } if (pContext->record.dwType == VMDNS_RR_TYPE_PTR) { dwError = VmDnsMakeFQDN( pContext->record.pszName, pContext->pszZone, &pszTargetFQDN); BAIL_ON_VMDNS_ERROR(dwError); if (pszTargetFQDN) { VMDNS_SAFE_FREE_STRINGA(pContext->record.pszName); pContext->record.pszName = pszTargetFQDN; pszTargetFQDN = NULL; } } else { VmDnsTrimDomainNameSuffix(pContext->record.pszName, pContext->pszZone); dwError = VmDnsMakeFQDN( pContext->record.pszName, pContext->pszZone, &pszTargetFQDN); BAIL_ON_VMDNS_ERROR(dwError); if (pszTargetFQDN) { VMDNS_SAFE_FREE_STRINGA(pContext->record.pszName); pContext->record.pszName = pszTargetFQDN; pszTargetFQDN = NULL; } } dwError = VmDnsQueryRecordsA( pContext->pServerContext, pContext->pszZone, pContext->record.pszName, pContext->record.dwType, 0, &pRecordArray); BAIL_ON_VMDNS_ERROR(dwError); for (; idx < pRecordArray->dwCount; ++idx) { if (VmDnsMatchRecord(&pRecordArray->Records[idx], &pContext->record)) { dwError = VmDnsDeleteRecordA( pContext->pServerContext, pContext->pszZone, &pRecordArray->Records[idx] ); BAIL_ON_VMDNS_ERROR(dwError); bFound = TRUE; } } error: if (!bFound) { fprintf(stderr, "Error: no matching record found.\n"); } VMDNS_SAFE_FREE_STRINGA(pszTargetFQDN); VmDnsFreeRecordArray(pRecordArray); return dwError; }
DWORD VmDnsLdapAccessCheck( PCSTR szAuthPrinc, VMDNS_USER_TYPE userType ) { DWORD dwError = ERROR_SUCCESS; PVMDNS_DIR_CONTEXT pLd = NULL; PSTR* ppszMemberships = NULL; PSTR szGroupName = NULL; PSTR pszDomainName = NULL; DWORD dwMemberships = 0; if (IsNullOrEmptyString(szAuthPrinc) || (userType != VMDNS_ADMINISTRATORS)) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } dwError = VmDnsDirConnect("localhost", &pLd); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsLdapGetMemberships( pLd, szAuthPrinc, &ppszMemberships, &dwMemberships ); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsGetDefaultDomainName(pLd, &pszDomainName); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsAllocateStringPrintfA( &szGroupName, "%s,%s", VMDNS_ADMINISTRATORS_GROUP, pszDomainName); BAIL_ON_VMDNS_ERROR(dwError); VMDNS_LOG_INFO("Checking upn: %s against DNS admin group: %s ", szGroupName, szAuthPrinc); if (!VmDnsIsMemberOf( ppszMemberships, dwMemberships, szGroupName )) { dwError = ERROR_ACCESS_DENIED; BAIL_ON_VMDNS_ERROR(dwError); } cleanup: VMDNS_SAFE_FREE_STRINGA(pszDomainName); VMDNS_SAFE_FREE_STRINGA(szGroupName); if (ppszMemberships) { VmDnsFreeMemberShips(ppszMemberships, dwMemberships); ppszMemberships = NULL; } if (pLd) { VmDnsDirClose(pLd); pLd = NULL; } return dwError; error: goto cleanup; }