Beispiel #1
0
static
BOOLEAN
_VmDirReplAttrConflictCheck(
    PVMDIR_ATTRIBUTE_METADATA     pSupplierMetaData,
    PVMDIR_ATTRIBUTE_METADATA     pConsumerMetaData
    )
{
    BOOLEAN    bSupplierWon = FALSE;

    if ((pSupplierMetaData->version > pConsumerMetaData->version) ||
        (pSupplierMetaData->version == pConsumerMetaData->version &&
         VmDirStringNCompareA(
             pSupplierMetaData->pszOrigInvoId,
             pConsumerMetaData->pszOrigInvoId,
             VMDIR_GUID_STR_LEN,
             FALSE) > 0) ||
        (pSupplierMetaData->version == pConsumerMetaData->version &&
         VmDirStringNCompareA(
             pSupplierMetaData->pszOrigInvoId,
             pConsumerMetaData->pszOrigInvoId,
             VMDIR_GUID_STR_LEN,
             FALSE) == 0 &&
         pSupplierMetaData->origUsn > pConsumerMetaData->origUsn))
    {
        bSupplierWon = TRUE;
    }

    return bSupplierWon;
}
Beispiel #2
0
static
DWORD
_VmDirSchemaCheckNameform(
    PVDIR_SCHEMA_CTX        pCtx,
    PVDIR_ENTRY             pEntry,
    PVDIR_SCHEMA_OC_DESC    pStructOCDesc
    )
{
    DWORD       dwError = 0;
    PSTR        pszLocalErrorMsg = NULL;

    if ( !pCtx || !pStructOCDesc || !pEntry || !pEntry->dn.bvnorm_val )
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

#if 0

    // should NOT enable this until we have all namform and structure rule defined
    if ( pStructOCDesc->usNumMustRDNs > 0 )
    {   // not yet support multi RDNs case.  only check the first MUST RDN for now.
        size_t  iLen = VmDirStringLenA(pStructOCDesc->ppszMustRDNs[0]);

        if ( VmDirStringNCompareA( pEntry->dn.bvnorm_val,
                                   pStructOCDesc->ppszMustRDNs[0],
                                   iLen,
                                   FALSE ) != 0
             ||
             pEntry->dn.bvnorm_val[iLen] != '='
           )
        {
            dwError = ERROR_INVALID_ENTRY;
            BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrorMsg,
                                          "_VmDirSchemaCheckNameform: rdn must be (%s). (%d)",
                                          VDIR_SAFE_STRING( pStructOCDesc->ppszMustRDNs[0] ), dwError );
        }
    }

#endif

cleanup:

    VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg);

    return dwError;

error:

    if ( !pCtx->pszErrorMsg )
    {
        pCtx->pszErrorMsg = pszLocalErrorMsg;
        pszLocalErrorMsg = NULL;

        pCtx->dwErrorCode = dwError;
    }

    goto cleanup;
}
Beispiel #3
0
static
BOOLEAN
compareSubString(
    VDIR_SCHEMA_MATCH_TYPE type,
    PVDIR_BERVALUE    pAssert,
    PVDIR_BERVALUE    pBerv
    )
{
    BOOLEAN bRtn = FALSE;
    DWORD dwCnt = 0;
    size_t dwDelta = 0;

    if (!pAssert || !pBerv || pAssert->bvnorm_len > pBerv->bvnorm_len)
    {
        goto done;
    }

    dwDelta = pBerv->bvnorm_len - pAssert->bvnorm_len;

    switch (type)
    {
    case VDIR_SCHEMA_MATCH_SUBSTR_INIT:

        bRtn = (VmDirStringNCompareA(pAssert->bvnorm_val,
                        pBerv->bvnorm_val,
                        pAssert->bvnorm_len, TRUE) == 0);

        break;

    case VDIR_SCHEMA_MATCH_SUBSTR_FINAL:

        bRtn = (VmDirStringNCompareA(pAssert->bvnorm_val,
                        pBerv->bvnorm_val + dwDelta,
                        pAssert->bvnorm_len, TRUE) == 0);

        break;

    case VDIR_SCHEMA_MATCH_SUBSTR_ANY:  // TODO, not efficient
        for (dwCnt = 1; dwCnt < dwDelta; dwCnt++)
        {
            if (VmDirStringNCompareA(pAssert->bvnorm_val,
                        pBerv->bvnorm_val + dwCnt,
                        pAssert->bvnorm_len, TRUE) == 0)
            {
                bRtn = TRUE;
                break;
            }
        }

        break;

    default:

        break;
    }


done:

    return bRtn;
}
Beispiel #4
0
static
BOOLEAN
compareString(
    VDIR_SCHEMA_MATCH_TYPE type,
    PVDIR_BERVALUE    pAssert,
    PVDIR_BERVALUE    pBerv
    )
{
    BOOLEAN bRtn = FALSE;
    size_t  dwMinLen = 0;
    int     iResult = 0;

    if (!pAssert || !pBerv || pAssert->bvnorm_len > pBerv->bvnorm_len)
    {
        goto done;
    }

    switch (type)
    {
    case VDIR_SCHEMA_MATCH_EQUAL:
        if (pAssert->bvnorm_len != pBerv->bvnorm_len)
        {
            goto done;
        }

        bRtn = (VmDirStringNCompareA(pAssert->bvnorm_val, pBerv->bvnorm_val, pAssert->lberbv.bv_len, TRUE) == 0);

        break;

    case VDIR_SCHEMA_MATCH_GE:
        dwMinLen = MIN(pAssert->bvnorm_len, pBerv->bvnorm_len);
        iResult = VmDirStringNCompareA(pAssert->bvnorm_val, pBerv->bvnorm_val, dwMinLen, TRUE);

        if ((iResult > 0) ||
            (iResult == 0 && pAssert->bvnorm_len >= pBerv->bvnorm_len))
        {
            bRtn = TRUE;
        }

        break;

    case VDIR_SCHEMA_MATCH_LE:
        dwMinLen = MIN(pAssert->bvnorm_len, pBerv->bvnorm_len);
        iResult = VmDirStringNCompareA(pAssert->bvnorm_val, pAssert->lberbv.bv_val, dwMinLen, TRUE);

        if ((iResult < 0) ||
            (iResult == 0 && pAssert->bvnorm_len <= pBerv->bvnorm_len))
        {
            bRtn = TRUE;
        }

        break;

    default:

        break;
    }

done:

    return bRtn;
}
Beispiel #5
0
/*
 * Bind to a LDAP server via SSL port.
 * Require server certificate verification.
 *
 * In 5.5. mix mode, replication goes through ldaps port.
 */
DWORD
VmDirSSLBind(
     LDAP**     ppLd,
     PCSTR      pszURI,
     PCSTR      pszDN,
     PCSTR      pszPassword
     )
{
    DWORD     dwError = 0;
    int       retVal = 0;
    LDAP*     pLd = NULL;
    BerValue  ldapBindPwd = {0};
    const int ldapVer = LDAP_VERSION3;
    int       iTLSDEMAND = LDAP_OPT_X_TLS_DEMAND;
    int       iTLSMin =  LDAP_OPT_X_TLS_PROTOCOL_TLS1_0;
    PSTR      pszTrustCertFile = NULL;
    SSL_CTX*  pSslCtx = NULL;

    if ( ppLd == NULL || pszURI == NULL )
    {
        dwError = VMDIR_ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    // only allow ldaps traffic over SSL port
    if ( VmDirStringNCompareA( pszURI, VMDIR_LDAPS_PROTOCOL, 5, FALSE) != 0 )
    {
        dwError = VMDIR_ERROR_ACCESS_DENIED;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = VmDirPrepareOpensslClientCtx( &pSslCtx, &pszTrustCertFile, pszURI );
    BAIL_ON_VMDIR_ERROR(dwError);

    retVal = ldap_set_option( NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &iTLSDEMAND);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

    retVal = ldap_set_option(NULL, LDAP_OPT_X_TLS_PROTOCOL_MIN, &iTLSMin);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

    retVal = ldap_initialize(&pLd, pszURI);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

    retVal = ldap_set_option(pLd, LDAP_OPT_PROTOCOL_VERSION, &ldapVer);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

    retVal = ldap_set_option( pLd, LDAP_OPT_X_TLS_CTX, pSslCtx);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

    ldapBindPwd.bv_val = 0;
    ldapBindPwd.bv_len = 0;
    if (pszPassword)
    {
        ldapBindPwd.bv_val = (PSTR) pszPassword;
        ldapBindPwd.bv_len = (ULONG) VmDirStringLenA(pszPassword);
    }
    retVal = ldap_sasl_bind_s( pLd,
                                pszDN,
                                LDAP_SASL_SIMPLE,
                                &ldapBindPwd,      // ldaps with credentials
                                NULL,
                                NULL,
                                NULL);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

    *ppLd = pLd;

cleanup:

    if (pSslCtx)
    {
        SSL_CTX_free(pSslCtx);
    }
    VMDIR_SAFE_FREE_MEMORY(pszTrustCertFile);

    return dwError;

ldaperror:

    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "VmDirSSLBind failed for %s %s. (%d)(%s)",
                                         pszURI, pszDN,
                                         retVal, ldap_err2string(retVal));
    dwError = VmDirMapLdapError(retVal);

error:
    if (retVal == 0)
    {
        VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "_VmDirSSLBind failed. (%u)", dwError);
    }

    if ( pLd )
    {
        ldap_unbind_ext_s( pLd, NULL, NULL);
    }
    goto cleanup;
}
Beispiel #6
0
BOOLEAN
VmDirIsProtectedEntry(
    PVDIR_ENTRY pEntry
    )
{
    BOOLEAN bResult = FALSE;
    PCSTR pszDomainDn = NULL;
    PCSTR pszEntryDn = NULL;
    size_t domainDnLen = 0;
    size_t entryDnLen = 0;

    const CHAR szAdministrators[] = "cn=Administrators,cn=Builtin";
    const CHAR szCertGroup[] =      "cn=CAAdmins,cn=Builtin";
    const CHAR szDCAdminsGroup[] =  "cn=DCAdmins,cn=Builtin";
    const CHAR szUsersGroup[] =     "cn=Users,cn=Builtin";
    const CHAR szAdministrator[] =  "cn=Administrator,cn=Users";

    if (pEntry == NULL)
    {
        goto error;
    }

    pszDomainDn = gVmdirServerGlobals.systemDomainDN.lberbv.bv_val;
    if (pszDomainDn == NULL)
    {
        goto error;
    }

    pszEntryDn = pEntry->dn.lberbv.bv_val;
    if (pszEntryDn == NULL)
    {
        goto error;
    }

    entryDnLen = strlen(pszEntryDn);
    domainDnLen = strlen(pszDomainDn);

    if (entryDnLen <= domainDnLen)
    {
        goto error;
    }

    if (pszEntryDn[(entryDnLen - domainDnLen) - 1] != ',')
    {
        goto error;
    }

    // Make sure system DN matches
    if (VmDirStringCompareA(&pszEntryDn[entryDnLen - domainDnLen], pszDomainDn, FALSE))
    {
        goto error;
    }

    if (!VmDirStringNCompareA(pszEntryDn, szAdministrators, sizeof(szAdministrators) - 1, FALSE) ||
        !VmDirStringNCompareA(pszEntryDn, szCertGroup, sizeof(szCertGroup) - 1, FALSE) ||
        !VmDirStringNCompareA(pszEntryDn, szDCAdminsGroup, sizeof(szDCAdminsGroup) - 1, FALSE) ||
        !VmDirStringNCompareA(pszEntryDn, szUsersGroup, sizeof(szUsersGroup) - 1, FALSE) ||
        !VmDirStringNCompareA(pszEntryDn, szAdministrator, sizeof(szAdministrator) - 1, FALSE))
    {
        bResult = TRUE;
    }

error:
    return bResult;
}
Beispiel #7
0
/*
 * Read schema definition from file
 * We ignore -
 * 1. DN/EntryDN
 * 2. ldapSyntax
 * 3. matchingRules
 */
static
DWORD
schemaReadFile(
    PCSTR   pszSchemaFilePath,
    PSTR**  pppszDescs,
    USHORT*  pdwSize
    )
{
    static PSTR pszDNTag = "DN:";
    static PSTR pszENTRYDNTag = "ENTRYDN:";
    static PSTR pszSyntaxTag = "ldapSyntaxes:";
    static PSTR pszMatchingRuleTag = "matchingRules:";
    static PSTR pszName = "NAME ";

    DWORD dwError = 0;
    USHORT dwSize = 0;
    DWORD dwCnt = 100;
    size_t iOldLen = 0 ;
    size_t iNewLen = 0 ;

    PSTR*    ppszDescs = NULL;
    PSTR    pszTmp = NULL;

    char  pbuf[2048] = {0};
    FILE* fp = NULL;


    dwError = VmDirAllocateMemory(
            sizeof(*ppszDescs) * dwCnt,
            (PVOID*)&ppszDescs);
    BAIL_ON_VMDIR_ERROR(dwError);

#ifndef _WIN32
    fp=fopen(pszSchemaFilePath, "r");
#else
    if( fopen_s(&fp, pszSchemaFilePath, "r") != 0 )
    {
        fp = NULL;
    }
#endif
    if(NULL == fp)
    {
        dwError = errno;
        VMDIR_LOG_ERROR(    VMDIR_LOG_MASK_ALL,
                            "Open schema file (%s) failed. Error (%d)",
                            pszSchemaFilePath,
                            dwError);

        BAIL_ON_VMDIR_ERROR(dwError);
    }

    while (fgets(pbuf, sizeof(pbuf), fp) != NULL)
    {
        PSTR pszTag = NULL;
        size_t len = VmDirStringLenA(pbuf)-1;

        if (pbuf[len] == '\n')
        {
            pbuf[len] = '\0';
        }

        if ((pbuf[0] == '\0')    ||
            (pbuf[0] == '#')    ||
            (pbuf[0] != ' ' && (pszTag = VmDirStringChrA(pbuf, ':')) == NULL))
        {
            continue;
        }

        if (VmDirStringNCompareA(pbuf, pszDNTag, VmDirStringLenA(pszDNTag), FALSE) == 0              ||
            VmDirStringNCompareA(pbuf, pszENTRYDNTag, VmDirStringLenA(pszENTRYDNTag), FALSE) == 0    ||
            VmDirStringNCompareA(pbuf, pszSyntaxTag, VmDirStringLenA(pszSyntaxTag), FALSE) == 0        ||
            VmDirStringNCompareA(pbuf, pszMatchingRuleTag, VmDirStringLenA(pszMatchingRuleTag), FALSE) == 0)
        {
            continue;
        }

        if (dwCnt == dwSize + 1)
        {
            DWORD    dwOldSize = dwCnt;
            dwCnt = dwCnt * 2;

            dwError = VmDirReallocateMemoryWithInit(
                    ppszDescs,
                    (PVOID*)&ppszDescs,
                    dwCnt * sizeof(*ppszDescs),
                    dwOldSize * sizeof(*ppszDescs));
            BAIL_ON_VMDIR_ERROR(dwError);
        }

        if (pbuf[0] != ' ')
        {
            dwError = VmDirAllocateStringA(pbuf,
                    &(ppszDescs[dwSize++]));
            BAIL_ON_VMDIR_ERROR(dwError);
        }
        else
        {
            // consolidate leading spaces into one
            char* pszNonSpace = pbuf+1;
            while (*pszNonSpace == ' ') { pszNonSpace++; }
            {

                // Normalising NAME field for everything attributeTypes,objectClasses,ditContentRules , i.e Removing multiple spaces
                if (VmDirStringNCompareA(pszNonSpace, pszName, VmDirStringLenA(pszName), TRUE) == 0)
                 {
                     _VmDirNormaliseNameField (pszNonSpace, VmDirStringLenA(pszNonSpace));
                 }

                iOldLen = VmDirStringLenA(ppszDescs[dwSize-1]);
                iNewLen = VmDirStringLenA(pszNonSpace-1);

                dwError = VmDirReallocateMemoryWithInit(
                        ppszDescs[dwSize-1],
                        (PVOID*)&pszTmp,
                        sizeof(char) * (iOldLen + iNewLen + 1),
                        sizeof(char) * iOldLen);
                BAIL_ON_VMDIR_ERROR(dwError);

                dwError = VmDirCopyMemory(
                    &pszTmp[iOldLen],
                    sizeof(char) * (iOldLen + iNewLen + 1),
                    &(pszNonSpace-1)[0],
                    iNewLen
                );
                BAIL_ON_VMDIR_ERROR(dwError);

                ppszDescs[dwSize-1] = pszTmp;
                pszTmp = NULL;
            }

        }
    }

    *pppszDescs = ppszDescs;
    *pdwSize = dwSize;

cleanup:

    if (fp)
    {
        fclose(fp);
    }

    return dwError;

error:

    *pppszDescs = NULL;
    *pdwSize = 0;

    if (ppszDescs)
    {
        VmDirFreeStringArrayA(ppszDescs);
        VMDIR_SAFE_FREE_MEMORY(ppszDescs);
    }

    goto cleanup;
}
Beispiel #8
0
/*
 * convert schema file into entry
 */
DWORD
VmDirSchemaInitalizeFileToEntry(
    PCSTR           pszSchemaFilePath,
    PVDIR_ENTRY*    ppEntry
    )
{
    DWORD    dwError = 0;
    USHORT   dwCnt = 0;
    PVDIR_ENTRY    pEntry = NULL;

    PSTR    pszTag = NULL;
    PSTR    pszTagEnd = NULL;
    USHORT  dwTag = 0;

    PSTR*    ppszDescs = NULL;
    USHORT   dwDescSize = 0;

    PSTR*    ppszSyntaxes = NULL;
    USHORT   dwSyntaxSize = 0;

    PSTR*    ppszMRs = NULL;
    USHORT   dwMRSize = 0;

    PVDIR_SCHEMA_CTX    pCtx = NULL;

    if ( !pszSchemaFilePath || !ppEntry )
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = schemaReadFile(
        pszSchemaFilePath,
        &ppszDescs,
        &dwDescSize);
    BAIL_ON_VMDIR_ERROR(dwError);

    // sort ppszDescs by tag order (i.e. ats, ocs, syntax...)
    qsort(ppszDescs, dwDescSize, sizeof(*ppszDescs), schemaInitPPSTRCmp);

	dwError = VmDirSchemaCtxAcquire(&pCtx);
	BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirAllocateMemory(
        sizeof(VDIR_ENTRY),
        (PVOID*)&pEntry);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirAllocateStringA(
            SUB_SCHEMA_SUB_ENTRY_DN,
            &pEntry->dn.lberbv.bv_val);
    BAIL_ON_VMDIR_ERROR(dwError);

    pEntry->dn.bOwnBvVal = TRUE;
    pEntry->dn.lberbv.bv_len = VmDirStringLenA(pEntry->dn.lberbv.bv_val);

    dwError = VmDirNormalizeDN( &(pEntry->dn), pCtx );
    BAIL_ON_VMDIR_ERROR(dwError);

    pEntry->allocType = ENTRY_STORAGE_FORMAT_NORMAL;

    // load every thing from file except EntryDN, ldapSyntaxes and matchingRules
    {
        // By now, we know all PSTR have format - "tag: value"
        for (dwCnt=0; dwCnt < dwDescSize; dwCnt++)
        {
            PSTR pszNewTag = ppszDescs[dwCnt];
            PSTR pszNewTagEnd = VmDirStringChrA(ppszDescs[dwCnt], ':');

            if (pszTag == NULL)
            {
                pszTag = pszNewTag;
                pszTagEnd = pszNewTagEnd;
                dwTag = dwCnt;
                continue;
            }

            if (((pszTagEnd - pszTag) == (pszNewTagEnd - pszNewTag)) &&
                VmDirStringNCompareA(pszTag, pszNewTag, pszTagEnd - pszTag, TRUE) == 0)
            {
                continue;
            }
            else
            {
                dwError = schemaInitFillAttrFromFile(
                        pCtx,
                        ppszDescs+dwTag,
                        dwCnt - dwTag,
                        pszTag,
                        pszTagEnd - pszTag,
                        pEntry);
                BAIL_ON_VMDIR_ERROR(dwError);

                pszTag = pszNewTag;
                pszTagEnd = pszNewTagEnd;
                dwTag = dwCnt;
            }
        }

        dwError = schemaInitFillAttrFromFile(
                pCtx,
                ppszDescs+dwTag,
                dwCnt - dwTag,
                pszTag,
                pszTagEnd - pszTag,
                pEntry);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = VdirSyntaxGetDefinition(
            &ppszSyntaxes,
            &dwSyntaxSize);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = schemaInitFillAttrFromCache(
            pCtx,
            ppszSyntaxes,
            dwSyntaxSize,
            VDIR_ATTRIBUTE_LADPSYNTAXES,
            pEntry);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VdirMatchingRuleGetDefinition(
            &ppszMRs,
            &dwMRSize);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = schemaInitFillAttrFromCache(
            pCtx,
            ppszMRs,
            dwMRSize,
            VDIR_ATTRIBUTE_MATCHINGRULES,
            pEntry);
    BAIL_ON_VMDIR_ERROR(dwError);

    pEntry->eId = SUB_SCEHMA_SUB_ENTRY_ID;

    // NOTE, entry is only partially constructed to bootstrap schema
    *ppEntry = pEntry;

cleanup:

    if (pCtx)
    {
        VmDirSchemaCtxRelease(pCtx);
    }

    if (ppszDescs)
    {
        VmDirFreeStringArrayA(ppszDescs);
        VMDIR_SAFE_FREE_MEMORY(ppszDescs);
    }

    if (ppszSyntaxes)
    {
        VmDirFreeStringArrayA(ppszSyntaxes);
        VMDIR_SAFE_FREE_MEMORY(ppszSyntaxes);
    }

    if (ppszMRs)
    {
        VmDirFreeStringArrayA(ppszMRs);
        VMDIR_SAFE_FREE_MEMORY(ppszMRs);
    }

    return dwError;

error:

    if (pEntry)
    {
        VmDirFreeEntry(pEntry);
    }

    goto cleanup;

}