Пример #1
0
/*
 * reorder value of objectclass in pOCAttr->vals
 * 1. structureOC->parentOC->parentOC->....->TOP(not included)
 *    expand parent objectclass if not supplied.
 * 2. aux OCs
 * We then store its values in this order in backend.
 */
static
DWORD
_VmDirSchemaReorderObjectClassAttr(
    PVDIR_ATTRIBUTE         pOCAttr,
    PVDIR_SCHEMA_OC_DESC    pStructureOCDesc,
    PVDIR_SCHEMA_OC_DESC*   ppAuxOCDesc)
{
    DWORD       dwError = 0;
    int         iCnt = 0;
    int         iAUXCnt = 0;
    int         iTotal = 0;
    PVDIR_BERVALUE          pBerv = NULL;
    PVDIR_SCHEMA_OC_DESC    pLocalDesc = pStructureOCDesc;

    if ( !pOCAttr || !pStructureOCDesc )
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    // number of structure objectclass (except top)
    for (iCnt = 0; pLocalDesc != NULL; pLocalDesc = pLocalDesc->pStructSupOC, iCnt++) {}
    // number of aux objectclass
    for (iAUXCnt = 0; ppAuxOCDesc && ppAuxOCDesc[iAUXCnt] != NULL; iAUXCnt++) {};
    iTotal = iCnt + iAUXCnt;

    dwError = VmDirAllocateMemory( sizeof(VDIR_BERVALUE) * (iTotal + 1),
                                   (PVOID*)&pBerv);
    BAIL_ON_VMDIR_ERROR(dwError);

    // start with leaf structure objectclass and walk up the tree to top (NOT included)
    for (iCnt = 0, pLocalDesc = pStructureOCDesc;
         pLocalDesc != NULL;
         pLocalDesc = pLocalDesc->pStructSupOC, iCnt++)
    {
        PCSTR pszOrgName = NULL;
        unsigned int   iTmp = 0;

        for (iTmp = 0; iTmp < pOCAttr->numVals; iTmp++)
        {
            if (VmDirStringCompareA( pLocalDesc->pszName,
                                     pOCAttr->vals[iTmp].lberbv_val,
                                     FALSE) == 0)
            {   // keep whatever value provided from clients
                pszOrgName = pOCAttr->vals[iTmp].lberbv_val;
                break;
            }
        }

        dwError = VmDirAllocateStringA( pszOrgName ? pszOrgName : pLocalDesc->pszName,
                                        &(pBerv[iCnt].lberbv_val) );
        BAIL_ON_VMDIR_ERROR(dwError);

        pBerv[iCnt].lberbv_len = VmDirStringLenA(pBerv[iCnt].lberbv_val);
        pBerv[iCnt].bOwnBvVal = TRUE;
        // TODO, Do we need to normalize value here?
    }

    // append aux objectclasses after structure objectclasses
    for (iAUXCnt = 0; ppAuxOCDesc && ppAuxOCDesc[iAUXCnt] != NULL; iAUXCnt++, iCnt++)
    {
        PCSTR pszOrgName = NULL;
        unsigned int   iTmp = 0;

        for (iTmp = 0; iTmp < pOCAttr->numVals; iTmp++)
        {
            if (VmDirStringCompareA( ppAuxOCDesc[iAUXCnt]->pszName,
                                     pOCAttr->vals[iTmp].lberbv_val,
                                     FALSE) == 0)
            {   // keep whatever value provided from clients
                pszOrgName = pOCAttr->vals[iTmp].lberbv_val;
                break;
            }
        }

        dwError = VmDirAllocateStringA( pszOrgName ? pszOrgName : ppAuxOCDesc[iAUXCnt]->pszName,
                                        &(pBerv[iCnt].lberbv_val) );
        BAIL_ON_VMDIR_ERROR(dwError);

        pBerv[iCnt].lberbv_len = VmDirStringLenA(pBerv[iCnt].lberbv_val);
        pBerv[iCnt].bOwnBvVal = TRUE;
        // TODO, Do we need to normalize value here?
    }

    VmDirFreeBervalArrayContent( pOCAttr->vals, pOCAttr->numVals );
    VMDIR_SAFE_FREE_MEMORY( pOCAttr->vals );

    pOCAttr->vals = pBerv;
    pOCAttr->numVals = iTotal;

cleanup:

    return dwError;

error:

    VmDirFreeBervalArrayContent( pBerv, iTotal );
    VMDIR_SAFE_FREE_MEMORY( pBerv );

    goto cleanup;
}
Пример #2
0
/*
 * read one schema element definition from file and normalize its definition.
 */
static
DWORD
_VmDirReadOneDefFromFile(
    FILE*              fp,
    PVMDIR_STRING_LIST pStrList
    )
{
    DWORD   dwError = 0;
    size_t  iSize = VMDIR_SIZE_9216, iLen = 0;
    CHAR    pDescBuf[VMDIR_SIZE_9216+1] = {0};
    CHAR    pbuf[VMDIR_SIZE_4096] = {0};
    PCSTR   pPrefix = "( ";
    size_t  iPrefixLen = VmDirStringLenA(pPrefix);
    PSTR    pOut = NULL;

    dwError = VmDirStringNCatA(
            pDescBuf+iLen, iSize-iLen, pPrefix, iPrefixLen);
    BAIL_ON_VMDIR_ERROR(dwError);
    iLen += iPrefixLen;

    while (fgets(pbuf, sizeof(pbuf), fp) != NULL)
    {
        size_t len = VmDirStringLenA(pbuf) - 1;
        if (pbuf[len] == '\n')
        {
            pbuf[len] = '\0';
        }

        if ( pbuf[0] == '#')
        {
            continue;
        }

        if ( pbuf[0] == ' ')
        {
            dwError = VmDirStringNCatA(
                    pDescBuf+iLen, iSize-iLen, pbuf, VmDirStringLenA(pbuf));
            BAIL_ON_VMDIR_ERROR(dwError);
            iLen += VmDirStringLenA(pbuf);
        }
        else
        {
            break;
        }
    }

    if (pDescBuf[0] != '\0')
    {
        VmdDirNormalizeString(pDescBuf);
        dwError = VmDirAllocateStringA(pDescBuf, &pOut);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = VmDirStringListAdd(pStrList, pOut);
        BAIL_ON_VMDIR_ERROR(dwError);
        pOut = NULL;
    }

cleanup:
    return dwError;

error:
    VMDIR_SAFE_FREE_MEMORY(pOut);
    goto cleanup;
}
Пример #3
0
/*
 * Create a new schema cache via pEntry, then active this cache.
 */
DWORD
VmDirSchemaInitializeViaEntry(
    PVDIR_ENTRY    pEntry
    )
{
    BOOLEAN  bLoadOk = TRUE;
    BOOLEAN  bInLock = FALSE;
    DWORD    dwError = 0;

    PVDIR_SCHEMA_CTX pLiveCtx = NULL;
    PVDIR_SCHEMA_INSTANCE pInstance = NULL;
    PVDIR_SCHEMA_INSTANCE pLiveInstance = NULL;

    VMDIR_LOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex);

    // get reference to current schema, to clean up later
    pLiveInstance = gVdirSchemaGlobals.pSchema;
    pLiveCtx      = gVdirSchemaGlobals.pCtx;

    // instantiate a schema cache - pInstance
    dwError = VdirSchemaInstanceInitViaEntry(
            pEntry,
            &pInstance);
    BAIL_ON_VMDIR_ERROR(dwError);

    gVdirSchemaGlobals.pSchema = pInstance;

    dwError = VdirSchemaCtxAcquireInLock(TRUE, &gVdirSchemaGlobals.pCtx); // add self reference
    BAIL_ON_VMDIR_ERROR(dwError);

    assert(gVdirSchemaGlobals.pCtx);

    VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Startup schema instance (%p)", gVdirSchemaGlobals.pSchema);

    VMDIR_UNLOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex);

cleanup:

    if (bLoadOk)
    {
        VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL,
            "Schema - AttributeTypes:(size=%d, nextid=%d) Objectclasses:(size=%d)",
            pEntry->pSchemaCtx->pSchema->ats.usNumATs,
            pEntry->pSchemaCtx->pSchema->ats.usNextId,
            pEntry->pSchemaCtx->pSchema->ocs.usNumOCs);
    }

    VMDIR_UNLOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex);

    if (pLiveCtx)
    {
        VmDirSchemaCtxRelease(pLiveCtx);
    }

    return dwError;

error:

    if (pInstance)
    {
        VdirSchemaInstanceFree(pInstance);
    }

    gVdirSchemaGlobals.pSchema = pLiveInstance;
    gVdirSchemaGlobals.pCtx = pLiveCtx;
    pLiveCtx = NULL;

    bLoadOk = FALSE;

    goto cleanup;
}
Пример #4
0
DWORD
VmDirLocalAPIHandler(
    PVM_DIR_SECURITY_CONTEXT pSecurityContext,
    PBYTE pRequest,
    DWORD dwRequestSize,
    PBYTE * ppResponse,
    DWORD * pdwResponseSize
    )
{
    DWORD dwError = 0;
    UINT32 uApiType = 0;
    PBYTE pResponse = NULL;
    DWORD dwResponseSize = 0;

    if (dwRequestSize < sizeof(UINT32))
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR (dwError);
    }

    if (!pSecurityContext)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR (dwError);
    }

    uApiType = *((PUINT32)pRequest);

    switch(uApiType)
    {
      case VMDIR_IPC_INITIALIZE_HOST:

        dwError = VmDirIpcInitializeHost(
                        pSecurityContext,
                        pRequest,
                        dwRequestSize,
                        &pResponse,
                        &dwResponseSize
                        );
        break;

      case VMDIR_IPC_INITIALIZE_TENANT:

        dwError = VmDirIpcInitializeTenant(
                        pSecurityContext,
                        pRequest,
                        dwRequestSize,
                        &pResponse,
                        &dwResponseSize
                        );
        break;

      case VMDIR_IPC_FORCE_RESET_PASSWORD:

        dwError = VmDirIpcForceResetPassword(
                        pSecurityContext,
                        pRequest,
                        dwRequestSize,
                        &pResponse,
                        &dwResponseSize
                        );
        break;

      case VMDIR_IPC_GET_SRP_SECRET:

        dwError = VmDirIpcGetSRPSecret(
                        pSecurityContext,
                        pRequest,
                        dwRequestSize,
                        &pResponse,
                        &dwResponseSize
                        );
        break;

      case VMDIR_IPC_SET_SRP_SECRET:

        dwError = VmDirIpcSetSRPSecret(
                        pSecurityContext,
                        pRequest,
                        dwRequestSize,
                        &pResponse,
                        &dwResponseSize
                        );
        break;

      case VMDIR_IPC_GENERATE_PASSWORD:

        dwError = VmDirIpcGeneratePassword(
                        pSecurityContext,
                        pRequest,
                        dwRequestSize,
                        &pResponse,
                        &dwResponseSize
                        );
        break;

      case VMDIR_IPC_GET_SERVER_STATE:
        dwError = VmDirIpcGetServerState(
                        pSecurityContext,
                        pRequest,
                        dwRequestSize,
                        &pResponse,
                        &dwResponseSize
                        );
        break;

      default:

        dwError = ERROR_INVALID_PARAMETER;
        break;
    }
    BAIL_ON_VMDIR_ERROR(dwError);

    *ppResponse = pResponse;
    *pdwResponseSize = dwResponseSize;

cleanup:
    return dwError;

error:
    if (ppResponse)
    {
        *ppResponse = NULL;
    }
    if (pdwResponseSize)
    {
        *pdwResponseSize = 0;
    }
    if (pResponse)
    {
        VMDIR_SAFE_FREE_MEMORY (pResponse);
    }
    goto cleanup;
}
Пример #5
0
/*
 * This is NOT RFC 4514 compliance.
 *
 * 1. separate into RDNs
 * 2. for each RDN, normalize value based on its syntax
 *    (does not handle multi-value RDN case)
 *    remove all leading/trailing spaces
 * 3. reconstruct DN based on RDNs
 */
DWORD
VmDirNormalizeDN(
    PVDIR_BERVALUE      pBerv,
    PVDIR_SCHEMA_CTX    pSchemaCtx
    )
{
    DWORD   dwError = 0;
    PSTR    pszTmpDN = NULL;
    PSTR*   ppszRDNs = NULL;
    PSTR*   ppszNormRDNs = NULL;
    int     iNumRDNs = 0;
    int     iCnt = 0;
    size_t  iNormDNSize = 0;

    PVDIR_SCHEMA_CTX    pCtx = pSchemaCtx;

    if (!pBerv || !pBerv->lberbv.bv_val)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    // Already normalized. => Nothing to be done.
    if ( pBerv->bvnorm_val != NULL )
    {
        dwError = 0;
        goto cleanup;
    }
    // Nothing to be normalized for the ROOT DN
    if (pBerv->lberbv.bv_len == 0)
    {
        pBerv->bvnorm_val = pBerv->lberbv.bv_val;
        pBerv->bvnorm_len = 0;
        dwError = 0;
        goto cleanup;
    }

    if (pCtx == NULL)
    {
        dwError = VmDirSchemaCtxAcquire(&pCtx);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    // make a local copy
    dwError = VmDirAllocateStringA(
            pBerv->lberbv.bv_val,
            &pszTmpDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VdirSchemaInPlaceDN2RDNs(
            pszTmpDN,
            &ppszRDNs,
            &iNumRDNs);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirAllocateMemory(
            sizeof(PSTR) * (iNumRDNs + 1),
            (PVOID)&ppszNormRDNs);
    BAIL_ON_VMDIR_ERROR(dwError);

    for (iCnt=0; ppszRDNs[iCnt] && iCnt < iNumRDNs; iCnt++)
    {
        size_t           iNameLen = 0 ;
        VDIR_BERVALUE    berval = VDIR_BERVALUE_INIT;
        PVDIR_SCHEMA_AT_DESC    pATDesc = NULL;

        char* pChar = VmDirStringChrA(ppszRDNs[iCnt], '=');
        if (!pChar)
        {
            dwError = ERROR_INVALID_DN;
            BAIL_ON_VMDIR_ERROR(dwError);
        }

        *pChar = '\0';

        iNameLen = VmDirStringLenA(ppszRDNs[iCnt]);
        // attribute name - remove all leading/trailing spaces
        while (ppszRDNs[iCnt][iNameLen-1] == ' ')
        {
            ppszRDNs[iCnt][iNameLen-1] = '\0';
            iNameLen--;
            assert(iNameLen > 0); // MIN 1 char for name
        }
        while (ppszRDNs[iCnt][0] == ' ')
        {
            ppszRDNs[iCnt]++;
        }

        pATDesc = VmDirSchemaAttrNameToDesc(pCtx, ppszRDNs[iCnt]);
        if (!pATDesc)
        {
            dwError = ERROR_INVALID_DN;
            BAIL_ON_VMDIR_ERROR(dwError);
        }

        berval.lberbv.bv_val = pChar+1;
        berval.lberbv.bv_len = VmDirStringLenA(berval.lberbv.bv_val);
        dwError = VmDirSchemaBervalNormalize(pCtx, pATDesc, &berval);
        BAIL_ON_VMDIR_ERROR(dwError);

        if (berval.bvnorm_len == 0)
        {
            dwError = ERROR_INVALID_DN;
            BAIL_ON_VMDIR_ERROR(dwError);
        }

        if (berval.lberbv.bv_val == berval.bvnorm_val)
        {
            dwError = VmDirAllocateStringA(
                    berval.lberbv.bv_val,
                    &ppszNormRDNs[iCnt]);
            BAIL_ON_VMDIR_ERROR(dwError);
        }
        else
        {   // ppszNormRDNs takes over bvnorm_val
            ppszNormRDNs[iCnt] = berval.bvnorm_val;
        }

        iNormDNSize = iNormDNSize + berval.bvnorm_len + (pChar - ppszRDNs[iCnt]) + 2;
    }

    // Reconstruct normalized DN
    VMDIR_SAFE_FREE_MEMORY(pBerv->bvnorm_val);
    pBerv->bvnorm_len = 0;
    dwError = VmDirAllocateMemory(
            sizeof(char) * (iNormDNSize+1),
            (PVOID)&pBerv->bvnorm_val);
    BAIL_ON_VMDIR_ERROR(dwError);

    for (iCnt = 0; ppszNormRDNs[iCnt] && iCnt < iNumRDNs; iCnt++)
    {
        size_t iValueLen = VmDirStringLenA(ppszNormRDNs[iCnt]);
        int iValueOffset = 0;

        // attribute value - remove leading/trailing spaces
        while (ppszNormRDNs[iCnt][iValueOffset] == ' ')
        {
            iValueOffset++;
            assert(iValueOffset < iValueLen);
        }
        while (ppszNormRDNs[iCnt][iValueLen-1] == ' ')
        {
            ppszNormRDNs[iCnt][iValueLen-1] = '\0';
            iValueLen--;
            assert(iValueLen > 0);
        }

        // attribute name to lower case
        {
            char* pToLower = NULL;
            for (pToLower = ppszRDNs[iCnt]; *pToLower != '\0'; pToLower++)
            {
                *pToLower = (char) tolower(*pToLower);
            }
        }

        VmDirStringCatA(pBerv->bvnorm_val, (iNormDNSize+1), ppszRDNs[iCnt]);
        VmDirStringCatA(pBerv->bvnorm_val, (iNormDNSize+1), "=");
        VmDirStringCatA(pBerv->bvnorm_val, (iNormDNSize+1), ppszNormRDNs[iCnt]+iValueOffset);
        if (iCnt + 1 < iNumRDNs)
        {
            VmDirStringCatA(pBerv->bvnorm_val, (iNormDNSize+1), ",");
        }
    }

    pBerv->bvnorm_len = VmDirStringLenA(pBerv->bvnorm_val);

cleanup:

    if (pCtx && pCtx != pSchemaCtx)
    {
        VmDirSchemaCtxRelease(pCtx);
    }

    VMDIR_SAFE_FREE_MEMORY(pszTmpDN);
    VMDIR_SAFE_FREE_MEMORY(ppszRDNs); // ppszRDNs[i] is in place of pszTmpDN

    VmDirFreeStringArrayA(ppszNormRDNs);
    VMDIR_SAFE_FREE_MEMORY(ppszNormRDNs);

    return dwError;

error:

    goto cleanup;
}
Пример #6
0
/*
 * Get the next available USN number.
 */
DWORD
VmDirMDBGetNextUSN(
    PVDIR_BACKEND_CTX   pBECtx,
    USN *               pUsn)
{
    DWORD           dwError = 0;
    PVDIR_DB_TXN    pTxn = NULL;
    PVDIR_DB_TXN    pLocalTxn = NULL;
    VDIR_DB_DBT     key = {0};
    VDIR_DB_DBT     value  = {0};
    unsigned char   USNKeyBytes[sizeof( USN )] = {0};
    unsigned char   USNValueBytes[sizeof( USN )] = {0};
    USN             localUSN = 0;
    BOOLEAN         bRevertUSN = FALSE;
    BOOLEAN         bUnsetMaxUSN = TRUE;

    assert( pBECtx && pUsn );

    pTxn = (PVDIR_DB_TXN)pBECtx->pBEPrivate;
    if (pTxn)
    {
        pLocalTxn = pTxn;
    }
    else
    {
        dwError = mdb_txn_begin( gVdirMdbGlobals.mdbEnv, BE_DB_PARENT_TXN_NULL, BE_DB_FLAGS_ZERO, &pLocalTxn );
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    key.mv_data = &USNKeyBytes[0];
    MDBEntryIdToDBT(BE_MDB_USN_SEQ_KEY, &key);

    dwError =  mdb_get(pLocalTxn, gVdirMdbGlobals.mdbSeqDBi, &key, &value);
    BAIL_ON_VMDIR_ERROR(dwError);

    assert( value.mv_size == sizeof(USN) );
    localUSN = *((USN*)value.mv_data);

    *((USN*)&USNValueBytes[0]) = localUSN + 1;
    value.mv_size = sizeof(USN);
    value.mv_data = &USNValueBytes[0];

    dwError =  mdb_put(pLocalTxn, gVdirMdbGlobals.mdbSeqDBi, &key, &value, BE_DB_FLAGS_ZERO);
    BAIL_ON_VMDIR_ERROR(dwError);

    if (pBECtx->wTxnUSN == 0)
    {   // capture and set outstanding USN within txn scope
        pBECtx->wTxnUSN = localUSN;

        dwError = VmDirBackendAddOutstandingUSN( pBECtx );
        BAIL_ON_VMDIR_ERROR(dwError);
        bRevertUSN = TRUE;
    }
    else
    {   // if BECtx has wTxnUSN already (nested txn), it should be smaller than new USN here.
        if (pBECtx->wTxnUSN >= localUSN)
        {
            VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "nested OP/TXN USN ordering logic error: (%ld)(%ld)",
                      pBECtx->wTxnUSN, localUSN );
            dwError = LDAP_OPERATIONS_ERROR;
            BAIL_ON_VMDIR_ERROR(dwError);
        }
        VmDirBackendSetMaxOutstandingUSN(pBECtx, localUSN);
        bUnsetMaxUSN = TRUE;
    }

    if (pLocalTxn != pTxn)
    {
        dwError = mdb_txn_commit(pLocalTxn);
        pLocalTxn = NULL;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    *pUsn = localUSN;

cleanup:

    return dwError;

error:

    if (bUnsetMaxUSN)
    {
        VmDirBackendSetMaxOutstandingUSN(pBECtx, localUSN - 1);
    }

    if (bRevertUSN)
    {
        VmDirBackendRemoveOutstandingUSN( pBECtx );
        pBECtx->wTxnUSN = 0;
    }

    if (pLocalTxn && pLocalTxn != pTxn)
    {
        mdb_txn_abort(pLocalTxn);
    }

    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL,
            "VmDirMDBGetNextUSN: failed with error (%d),(%s)",
             dwError, mdb_strerror(dwError) );

    dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx, "GetNextUSN");

    goto cleanup;
}
Пример #7
0
/* MdbEIdToEntry: For a given entry ID, reads an entry from the entry DB.
 *
 * Returns: BE error - BACKEND_ERROR, BACKEND OPERATIONS, BACKEND_ENTRY_NOTFOUND
 *
 */
DWORD
VmDirMDBEIdToEntry(
    PVDIR_BACKEND_CTX           pBECtx,
    PVDIR_SCHEMA_CTX            pSchemaCtx,
    ENTRYID                     eId,
    PVDIR_ENTRY                 pEntry,
    VDIR_BACKEND_ENTRY_LOCKTYPE entryLockType)
{
    DWORD           dwError = 0;
    VDIR_DB         mdbDBi = 0;
    PVDIR_DB_TXN    pTxn = NULL;
    VDIR_DB_DBT     key = {0};
    VDIR_DB_DBT     value = {0};
    unsigned char   eIdBytes[sizeof( ENTRYID )] = {0};
    unsigned char*  pszBlob = NULL;

    assert(pBECtx && pBECtx->pBEPrivate && pSchemaCtx && pEntry);

    pTxn = (PVDIR_DB_TXN)pBECtx->pBEPrivate;

    mdbDBi = gVdirMdbGlobals.mdbEntryDB.pMdbDataFiles[0].mdbDBi;

    // Set key
    key.mv_data = &eIdBytes[0];
    MDBEntryIdToDBT(eId, &key);

    if ((dwError = mdb_get(pTxn, mdbDBi, &key, &value) ) != 0)
    {
        dwError = MDBToBackendError(dwError, MDB_NOTFOUND, ERROR_BACKEND_ENTRY_NOTFOUND, pBECtx, "EIDToEntry");
        BAIL_ON_VMDIR_ERROR( dwError );
    }

    if ((dwError = VmDirAllocateMemory( value.mv_size, (PVOID *)&pszBlob)) != 0)
    {
        dwError = ERROR_BACKEND_OPERATIONS;
        BAIL_ON_VMDIR_ERROR( dwError );
    }

    if ((dwError = VmDirCopyMemory(pszBlob, value.mv_size, value.mv_data, value.mv_size)) != 0)
    {
        dwError = ERROR_BACKEND_OPERATIONS;
        BAIL_ON_VMDIR_ERROR( dwError );
    }

    // encodedEntry takes over pszBlob
    pEntry->encodedEntry = pszBlob;
    pszBlob = NULL;

    pEntry->eId = eId;
    dwError = VmDirDecodeEntry(pSchemaCtx, pEntry );
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:

    return dwError;

error:

    VMDIR_LOG_ERROR( LDAP_DEBUG_BACKEND, "VmDirMDBEIdToEntry, eid(%u) failed (%u)", eId, dwError);

    VMDIR_SAFE_FREE_MEMORY(pszBlob);
    VmDirFreeEntryContent( pEntry );

    VMDIR_SET_BACKEND_ERROR(dwError);   // if dwError no in BE space, set to ERROR_BACKEND_ERROR

    goto cleanup;
}
Пример #8
0
DWORD
VmDirSASLSRPBindExt1(
     LDAP**     ppLd,
     PCSTR      pszURI,
     PCSTR      pszUPN,
     PCSTR      pszPass,
     int        iTimeout
     )
{
    DWORD       dwError = 0;
    int         retVal = 0;
    PSTR        pszLowerCaseUPN = NULL;
    LDAP*       pLd = NULL;
    const int   ldapVer = LDAP_VERSION3;
    const int   iSaslNoCanon = 1;
    VMDIR_SASL_INTERACTIVE_DEFAULT srpDefault = {0};
    int         iCnt = 0;
    struct timeval  optTimeout={0};

    optTimeout.tv_usec = 0;
    optTimeout.tv_sec = iTimeout;

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

    dwError = VmDirAllocASCIIUpperToLower( pszUPN, &pszLowerCaseUPN );
    BAIL_ON_VMDIR_ERROR(dwError);

    srpDefault.pszAuthName = pszLowerCaseUPN;
    srpDefault.pszPass     = pszPass;

    for (iCnt=0; iCnt<2; iCnt++)
    {
        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);

        // turn off SASL hostname canonicalization for SRP mech
        retVal = ldap_set_option(pLd, LDAP_OPT_X_SASL_NOCANON, &iSaslNoCanon);
        BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

        if (iTimeout > 0)
        {
            // timeout connect
            retVal = ldap_set_option(pLd, LDAP_OPT_NETWORK_TIMEOUT, (void *)&optTimeout);
            BAIL_ON_SIMPLE_LDAP_ERROR(retVal);
        }

        retVal = ldap_sasl_interactive_bind_s( pLd,
                                                NULL,
                                                "SRP",
                                                NULL,
                                                NULL,
                                                LDAP_SASL_QUIET,
                                                _VmDirSASLSRPInteraction,
                                                &srpDefault);
        if (retVal == LDAP_SERVER_DOWN || retVal == LDAP_TIMEOUT)
        {
            VmDirSleep(50); // pause 50 ms
            if ( pLd )
            {
                ldap_unbind_ext_s(pLd, NULL, NULL);
                pLd = NULL;
            }
            continue;   // if transient network error, retry once.
        }
        else
        {
            break;
        }
    }
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);  // bail ldap_sasl_interactive_bind_s failure.

    *ppLd = pLd;

cleanup:

    VMDIR_SAFE_FREE_MEMORY(pszLowerCaseUPN);

    return dwError;

ldaperror:

    VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "_VmDirSASLSRPBind failed. (%d)(%s)",
                                           retVal, ldap_err2string(retVal) );
    dwError = VmDirMapLdapError(retVal);

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

    if ( pLd )
    {
        ldap_unbind_ext_s( pLd, NULL, NULL);
    }
    goto cleanup;
}
Пример #9
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;
}
Пример #10
0
/*
 * 1. entry must have one and only one structure object class (from same oc tree)
 * 2. auxiliary object class content rule compliance
 * 3. entry must have all MUST attributes
 * 4. entry may have allowed MAY attributes
 */
static
DWORD
_VmDirSchemaCheckEntryStructure(
    PVDIR_SCHEMA_CTX        pCtx,
    PVDIR_ENTRY             pEntry,
    PVDIR_ATTRIBUTE         pOCAttr,
    BOOLEAN*                pbPresentList
    )
{
    DWORD                   dwError = 0;
    unsigned int            iCnt = 0;
    int                     iNumAuxOCs = 0;
    BOOLEAN                 bHasStructuralOC = FALSE;
    PVDIR_SCHEMA_OC_DESC    pStructOCDesc = NULL; // leaf structural OC
    PVDIR_SCHEMA_OC_DESC*   ppAuxOCDesc = NULL;

    assert(pCtx && pEntry && pOCAttr && pbPresentList);

    dwError = VmDirAllocateMemory(
            sizeof(PVDIR_SCHEMA_OC_DESC*) * (pOCAttr->numVals),
            (PVOID)&ppAuxOCDesc);
    BAIL_ON_VMDIR_ERROR(dwError);

    // walk through objectclass value to collect structure and aux ocs info
    for (iCnt = 0; iCnt < pOCAttr->numVals; iCnt++)
    {
        PVDIR_SCHEMA_OC_DESC pOCDesc =
                _VmDirSchemaCheckOCDescLookup(pCtx, pOCAttr->vals[iCnt].lberbv.bv_val);
        if (!pOCDesc)
        {
            VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg);
            VmDirAllocateStringAVsnprintf(
                    &pCtx->pszErrorMsg,
                    "Objectclass (%s) is not defined in schema",
                    VDIR_SAFE_STRING(pOCAttr->vals[iCnt].lberbv.bv_val));

            VmDirLog( LDAP_DEBUG_ANY, "schemaCheckStructure: (%s)", VDIR_SAFE_STRING(pCtx->pszErrorMsg));

            dwError = pCtx->dwErrorCode = ERROR_INVALID_ENTRY;
            BAIL_ON_VMDIR_ERROR(dwError);
        }

        switch (pOCDesc->type)
        {
        case VDIR_OC_STRUCTURAL:
            bHasStructuralOC = TRUE;

            if (!pStructOCDesc)
            {
                pStructOCDesc = pOCDesc;
                pEntry->pszStructureOC = pOCAttr->vals[iCnt].lberbv.bv_val;
            }
            else
            {   // make sure they are from the same structure tree
                PVDIR_SCHEMA_OC_DESC    pTmpOCDesc = pStructOCDesc;

                for (; pTmpOCDesc; pTmpOCDesc = pTmpOCDesc->pStructSupOC)
                {
                    if (pTmpOCDesc == pOCDesc) { break; }
                }

                if (!pTmpOCDesc) //  pOCDesc is NOT ancestor of pStructOCDesc
                {
                    for (pTmpOCDesc = pOCDesc; pTmpOCDesc; pTmpOCDesc = pTmpOCDesc->pStructSupOC)
                    {
                        if (pTmpOCDesc == pStructOCDesc)
                        {
                            // reset pStructOCDesc
                            pStructOCDesc = pOCDesc;
                            pEntry->pszStructureOC = pOCAttr->vals[iCnt].lberbv.bv_val;
                            break;
                        }
                    }
                }

                if (!pTmpOCDesc)
                {
                    VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg);
                    VmDirAllocateStringAVsnprintf(
                            &pCtx->pszErrorMsg,
                            "Entry can have only one structure objectclass.",
                            VDIR_SAFE_STRING(pOCDesc->pszName));

                    dwError = pCtx->dwErrorCode =  ERROR_INVALID_ENTRY;
                    BAIL_ON_VMDIR_ERROR(dwError);
                }
            }
            break;

        case VDIR_OC_AUXILIARY:
            ppAuxOCDesc[iNumAuxOCs] = pOCDesc;
            iNumAuxOCs++;
            break;

        default:
            // ABSTRACT object class
            break;
        }
    }

    // must have one structure oc
    if (bHasStructuralOC == FALSE)
    {
        VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg);
        VmDirAllocateStringA(
                "Entry has no structural objectclass",
                &pCtx->pszErrorMsg);

        dwError = pCtx->dwErrorCode = ERROR_INVALID_ENTRY;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    // enforce obejctclass value storing order structureOC->parentOC->...->TOP(not included)->AUXOC....
    dwError = _VmDirSchemaReorderObjectClassAttr( pOCAttr,
                                                  pStructOCDesc,
                                                  ppAuxOCDesc);
    BAIL_ON_VMDIR_ERROR(dwError);

    // enforce nameform (RDN)
    dwError = _VmDirSchemaCheckNameform( pCtx, pEntry, pStructOCDesc);
    BAIL_ON_VMDIR_ERROR(dwError);

    // content rule auxiliary constraint check
    if (iNumAuxOCs > 0)
    {
        dwError = _VmDirSchemaCheckContentRuleAuxOC(
                pCtx,
                pStructOCDesc,
                ppAuxOCDesc);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    {   // must attributes check
        dwError = _VmDirSchemaCheckMustAttrPresent(
                pCtx,
                pStructOCDesc,
                pEntry,
                pbPresentList);
        BAIL_ON_VMDIR_ERROR(dwError);

        for (iCnt = 0; ppAuxOCDesc[iCnt]; iCnt++)
        {
            dwError = _VmDirSchemaCheckMustAttrPresent(
                    pCtx,
                    ppAuxOCDesc[iCnt],
                    pEntry,
                    pbPresentList);
            BAIL_ON_VMDIR_ERROR(dwError);
        }
    }

    {   // may attributes check
        dwError = _VmDirSchemaCheckMayAttrPresent(
                pCtx,
                pStructOCDesc->ppAllMayATs,
                pEntry,
                pbPresentList);
        BAIL_ON_VMDIR_ERROR(dwError);

        for (iCnt = 0; ppAuxOCDesc[iCnt]; iCnt++)
        {
            dwError = _VmDirSchemaCheckMayAttrPresent(
                    pCtx,
                    ppAuxOCDesc[iCnt]->ppAllMayATs,
                    pEntry,
                    pbPresentList);
            BAIL_ON_VMDIR_ERROR(dwError);
        }
    }

cleanup:

    VMDIR_SAFE_FREE_MEMORY(ppAuxOCDesc);

    return dwError;

error:

    goto cleanup;
}
Пример #11
0
/*
 * 1. must have objectclass value
 * 2. must have structural objectclass (done in schemaCheckStructure)
 * 3. must match contentrule allowed auxiliary objectclass definition
 * 4. must have all MUST attributes
 * 5. may have allowed MAY attributes
 */
static
DWORD
_VmDirSchemaCheckStructure(
    PVDIR_SCHEMA_CTX    pCtx,
    PVDIR_ENTRY         pEntry
    )
{
    DWORD   dwError = 0;
    USHORT  usCnt = 0;
    BOOLEAN*    pbPresentList = NULL;
    DWORD   numAttrs = 0;
    PVDIR_ATTRIBUTE pTmpAttr = NULL;
    VDIR_ATTRIBUTE* pOCAttr = NULL;

    for (pTmpAttr = pEntry->attrs; pTmpAttr != NULL; pTmpAttr = pTmpAttr->next)
    {
        numAttrs++;
    }

    if (numAttrs == 0)
    {
        pCtx->dwErrorCode = ERROR_INVALID_ENTRY;

        VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg);
        dwError = VmDirAllocateStringA(
                "Entry has no attributes",
                &pCtx->pszErrorMsg);

        dwError = ERROR_INVALID_ENTRY;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = VmDirAllocateMemory(
            sizeof(BOOLEAN) * numAttrs,
            (PVOID*)&pbPresentList);
    BAIL_ON_VMDIR_ERROR(dwError);

    pOCAttr = _VmDirchemaCheckFindObjectClass(pCtx, pEntry);

    if (!pOCAttr || pOCAttr->numVals < 1)
    {
        pCtx->dwErrorCode = ERROR_INVALID_ENTRY;
        VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg);
        dwError = VmDirAllocateStringA("Entry has no objectclass",&pCtx->pszErrorMsg);

        dwError = ERROR_INVALID_ENTRY;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = _VmDirSchemaCheckEntryStructure(
            pCtx,
            pEntry,
            pOCAttr,
            pbPresentList);
    BAIL_ON_VMDIR_ERROR(dwError);

    {   // all VDIR_ATTRIBUTE_USER_APPLICATION attribute should be marked
        PVDIR_ATTRIBUTE pAttr = NULL;
        for (usCnt = 0, pAttr = pEntry->attrs;
             usCnt < numAttrs;
             usCnt++, pAttr = pAttr->next)
        {

            if (!pbPresentList[usCnt] && pAttr->pATDesc->usage == VDIR_ATTRIBUTETYPE_USER_APPLICATIONS)
            {
                VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg);
                dwError = VmDirAllocateStringAVsnprintf(
                        &pCtx->pszErrorMsg,
                        "Attribute (%s) not allowed",
                        VDIR_SAFE_STRING(pAttr->type.lberbv.bv_val));

                dwError = pCtx->dwErrorCode = ERROR_INVALID_ENTRY;
                BAIL_ON_VMDIR_ERROR(dwError);
            }
        }
    }

cleanup:

    VMDIR_SAFE_FREE_MEMORY(pbPresentList);

    return dwError;

error:

    goto cleanup;
}
Пример #12
0
/*
 * Per structure objectclass, verify contentrule auxiliary object class
 */
static
DWORD
_VmDirSchemaCheckContentRuleAuxOC(
    PVDIR_SCHEMA_CTX        pCtx,
    PVDIR_SCHEMA_OC_DESC    pStructureOCDesc,
    PVDIR_SCHEMA_OC_DESC*   ppAuxOCDesc
    )
{
    DWORD   dwError = 0;
    int     iCnt = 0;
    BOOLEAN bHasAllowedAuxOC = FALSE;

    assert(pCtx && pStructureOCDesc && ppAuxOCDesc);

    if (pCtx->pSchema->contentRules.usNumContents == 0)
    {
        // schema no content rule support
        goto cleanup;
    }

    bHasAllowedAuxOC = pStructureOCDesc->ppAllowedAuxOCs ? TRUE : FALSE;

    if (!bHasAllowedAuxOC && ppAuxOCDesc[0])
    {   // entry structure oc has NO allowedAuxOCs but entry now has aux ocs
        dwError = ERROR_INVALID_ENTRY;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    for (; ppAuxOCDesc[iCnt]; iCnt++)
    {
        int iIdx = 0;
        for (;pStructureOCDesc->ppAllowedAuxOCs[iIdx]; iIdx++)
        {
            if (pStructureOCDesc->ppAllowedAuxOCs[iIdx] == ppAuxOCDesc[iCnt])
            {
                break;
            }
        }

        if (pStructureOCDesc->ppAllowedAuxOCs[iIdx] == NULL)
        {   // entry aux oc not found in allowed list from content rule
            dwError = ERROR_INVALID_ENTRY;
            BAIL_ON_VMDIR_ERROR(dwError);
        }
    }

cleanup:

    return dwError;

error:

    pCtx->dwErrorCode = ERROR_INVALID_ENTRY;
    VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg);
    VmDirAllocateStringAVsnprintf(
            &pCtx->pszErrorMsg,
            "Aux objectclass (%s) is not allowed.",
            VDIR_SAFE_STRING(ppAuxOCDesc[iCnt]->pszName));

    VmDirLog( LDAP_DEBUG_ANY, "%s", VDIR_SAFE_STRING(pCtx->pszErrorMsg));

    goto cleanup;
}
Пример #13
0
static
DWORD
_VmDirSchemaCheckSyntaxAndDimension(
    PVDIR_SCHEMA_CTX    pCtx,
    PVDIR_ENTRY         pEntry
    )
{
    DWORD           dwError = 0;
    VDIR_ATTRIBUTE* pAttr = NULL;

    for (pAttr = pEntry->attrs; pAttr;  pAttr = pAttr->next)
    {
        USHORT usCnt = 0;

        if (pAttr->pATDesc->bSingleValue && pAttr->numVals != 1)
        {
            pCtx->dwErrorCode = ERROR_INVALID_ENTRY;

            VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg);
            dwError = VmDirAllocateStringAVsnprintf(
                    &pCtx->pszErrorMsg,
                    "Attribute (%s) can have at most one value",
                    VDIR_SAFE_STRING(pAttr->type.lberbv.bv_val));

            dwError = ERROR_INVALID_ENTRY;
            BAIL_ON_VMDIR_ERROR(dwError);
        }

        for (usCnt = 0; usCnt < pAttr->numVals; usCnt++)
        {
            if (pAttr->pATDesc->uiMaxSize > 0)
            {
                //TODO, for server control/manipulate attribute, we should exclude this restriction
                // as they no longer in their original form.  (e.g. userPassword)
                if (pAttr->vals[usCnt].lberbv.bv_len > pAttr->pATDesc->uiMaxSize)
                {
                    VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg);
                    VmDirAllocateStringAVsnprintf(    // ignore error
                            &pCtx->pszErrorMsg,
                            "Attribute (%s) value too long, max (%d) allowed.",
                            VDIR_SAFE_STRING(pAttr->type.lberbv.bv_val),
                            pAttr->pATDesc->uiMaxSize);

                    dwError = pCtx->dwErrorCode = LDAP_CONSTRAINT_VIOLATION;
                    BAIL_ON_VMDIR_ERROR(dwError);
                }
            }

            dwError = VmDirSchemaBervalSyntaxCheck(
                    pCtx,
                    pAttr->pATDesc,
                    &pAttr->vals[usCnt]);
            BAIL_ON_VMDIR_ERROR(dwError);
        }
    }

cleanup:

    return dwError;

error:

    VmDirLog( LDAP_DEBUG_ANY, "%s", VDIR_SAFE_STRING(pCtx->pszErrorMsg));

    goto cleanup;
}
Пример #14
0
/*
 * Entry schema check dit structure rule
 */
DWORD
VmDirSchemaCheckDITStructure(
    PVDIR_SCHEMA_CTX pCtx,
    PVDIR_ENTRY           pParentEntry,
    PVDIR_ENTRY           pEntry
    )
{
    DWORD   dwError = 0;
    unsigned int     iCnt = 0;
    BOOLEAN bParentAllowed = FALSE;
    PVDIR_ATTRIBUTE              pParentOCAttr = NULL;
    PVDIR_SCHEMA_OC_DESC    pStructureOCDesc = NULL;
    VDIR_SCHEMA_OC_DESC     ocKey = {0};

    assert(pCtx && pEntry);

// BUBBUG - bypass checking until we define castle structure rules
goto cleanup;

    if (pCtx->pSchema->structureRules.usNumStructures == 0)
    {
        // schema has no structure rule defined
        goto cleanup;
    }

    if (!pEntry->pszStructureOC)
    {
        VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg);
        dwError = VmDirAllocateStringAVsnprintf(
                &pCtx->pszErrorMsg,
                "Entry has no structure objectclass/pszStructureOC.");

        dwError = pCtx->dwErrorCode = ERROR_INVALID_ENTRY;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    ocKey.pszName = pEntry->pszStructureOC;
    pStructureOCDesc = (PVDIR_SCHEMA_OC_DESC) bsearch(
            &ocKey,
            pCtx->pSchema->ocs.pOCSortName,
            pCtx->pSchema->ocs.usNumOCs,
            sizeof(VDIR_SCHEMA_OC_DESC),
            VdirSchemaPOCNameCmp);

    if (!pStructureOCDesc)
    {
        VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg);
        dwError = VmDirAllocateStringAVsnprintf(
                &pCtx->pszErrorMsg,
                "Structure oc (%s) not defined.",
                VDIR_SAFE_STRING(pEntry->pszStructureOC));

        dwError = pCtx->dwErrorCode = ERROR_INVALID_ENTRY;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    if (pParentEntry)
    {
        pParentOCAttr = _VmDirchemaCheckFindObjectClass(pCtx, pParentEntry);
    }

    if (pParentOCAttr)
    {
        if (pStructureOCDesc->ppszAllowedParentOCs)
        {
            // loop through parent object class to check allowedParentsOCs
            //TODO, we can arrange structure object class to be the first to eliminate loop.
            for (iCnt = 0; iCnt < pParentOCAttr->numVals; iCnt++)
            {
                int iIdx = 0;
                for (;pStructureOCDesc->ppszAllowedParentOCs[iIdx]; iIdx++)
                {
                    if (VmDirStringCompareA(pParentOCAttr->vals[iCnt].lberbv.bv_val,
                                   pStructureOCDesc->ppszAllowedParentOCs[iIdx],
                                   FALSE) == 0)
                    {
                        // allowed under this parent
                        bParentAllowed = TRUE;
                        break;
                    }
                }

                if (pStructureOCDesc->ppszAllowedParentOCs[iIdx] != NULL)
                {
                    break;
                }
            }
        }
    }
    else
    {
        if (pStructureOCDesc->bAllowedParentRoot == TRUE)
        {   // allowed under root
            bParentAllowed = TRUE;
        }
    }

    if (!bParentAllowed)
    {
        VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg);
        dwError = VmDirAllocateStringAVsnprintf(
                &pCtx->pszErrorMsg,
                "(%s) not allowed under its parent",
                VDIR_SAFE_STRING(pEntry->pszStructureOC));

        dwError = pCtx->dwErrorCode = ERROR_INVALID_ENTRY;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

cleanup:

    return dwError;

error:

    goto cleanup;
}
Пример #15
0
VOID
VdcadminTestSASLClient(
    VOID
    )
{
    DWORD   dwError = 0;
    char    pszServerHost[SIZE_256] = {0};
    char    pszServerPort[SIZE_256] = {0};
    char    pszServerSSLPort[SIZE_256] = {0};
    char    pszBindDN[SIZE_256] = {0};
    char    pszBindUPN[SIZE_256] = {0};
    char    pszPassword[SIZE_256] = {0};
    PSTR    pszLDAPURI = NULL;
    PSTR    pszLDAPSURI = NULL;

    VmDirReadString(
        "Please enter LDAP server host: ",
        pszServerHost,
        SIZE_256,
        FALSE);

    VmDirReadString(
        "Please enter LDAP server port: ",
        pszServerPort,
        SIZE_256,
        FALSE);

    VmDirReadString(
        "Please enter LDAP server SSL port: ",
        pszServerSSLPort,
        SIZE_256,
        FALSE);

    VmDirReadString(
        "Please enter LDAP Bind DN: ",
        pszBindDN,
        SIZE_256,
        FALSE);

    VmDirReadString(
        "Please enter LDAP Bind UPN: ",
        pszBindUPN,
        SIZE_256,
        FALSE);

    VmDirReadString(
        "Please enter LDAP Bind password: "******"\n");

    dwError = VmDirAllocateStringAVsnprintf( &pszLDAPURI,
                                             "ldap://%s:%s",
                                             pszServerHost[0] != '\0' ? pszServerHost : "localhost",
                                             pszServerPort);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirAllocateStringAVsnprintf( &pszLDAPSURI,
                                             "ldaps://%s:%s",
                                             pszServerHost[0] != '\0' ? pszServerHost : "localhost",
                                             pszServerSSLPort);
    BAIL_ON_VMDIR_ERROR(dwError);

    _VdcadminClientTestSimpleBind( pszLDAPURI, pszBindDN, pszPassword );

    _VdcadminClientTestSimpleSSLBind( pszLDAPSURI, pszBindDN, pszPassword );

    _VdcadminClientTestSRPBind( pszLDAPURI, pszBindUPN, pszPassword );

    _VdcadminClientTestGSSAPIBind( pszLDAPURI );


cleanup:

    memset(pszPassword, 0, sizeof(pszPassword));

    VMDIR_SAFE_FREE_MEMORY(pszLDAPURI);
    VMDIR_SAFE_FREE_MEMORY(pszLDAPSURI);

    return;

error:

    printf("TestVdcadminSASLClient failed. (%d)\n", dwError);
    goto cleanup;
}
Пример #16
0
DWORD
VmDirSafeLDAPBindToPort(
    LDAP**      ppLd,
    PCSTR       pszHost,
    DWORD       dwPort,
    PCSTR       pszUPN,
    PCSTR       pszPassword,
    int         iTimeout
    )
{
    DWORD       dwError = 0;

    LDAP*       pLd = NULL;
    char        ldapURI[VMDIR_MAX_LDAP_URI_LEN + 1] = {0};
    DWORD       dwLdapPort = DEFAULT_LDAP_PORT_NUM;
    DWORD       dwTmpLdapPort = 0;

    if (ppLd == NULL || pszHost == NULL || pszUPN == NULL || pszPassword == NULL)
    {
        dwError = VMDIR_ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    if (dwPort)
    {
        dwLdapPort = dwPort;
    }
    else if (VmDirGetRegKeyValueDword(
                VMDIR_CONFIG_PARAMETER_V1_KEY_PATH,
                VMDIR_REG_KEY_LDAP_PORT,
                &dwTmpLdapPort,
                DEFAULT_LDAP_PORT_NUM) == ERROR_SUCCESS)
    {
        dwLdapPort = dwTmpLdapPort;
    }

    if ( VmDirIsIPV6AddrFormat( pszHost ) )
    {
        dwError = VmDirStringPrintFA( ldapURI, sizeof(ldapURI)-1,  "%s://[%s]:%d",
                                      VMDIR_LDAP_PROTOCOL, pszHost, dwLdapPort);
    }
    else
    {
        dwError = VmDirStringPrintFA( ldapURI, sizeof(ldapURI)-1,  "%s://%s:%d",
                                      VMDIR_LDAP_PROTOCOL, pszHost, dwLdapPort);
    }
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirSASLSRPBindExt1( &pLd, &(ldapURI[0]), pszUPN, pszPassword, iTimeout);
    BAIL_ON_VMDIR_ERROR(dwError);

    *ppLd = pLd;

cleanup:

    return dwError;

error:

    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s to (%s) failed. SRP(%d)",
                     __FUNCTION__, ldapURI, dwError );

    if ( pLd )
    {
        ldap_unbind_ext_s( pLd, NULL, NULL);
    }

    goto cleanup;
}
Пример #17
0
/*
 * Before modify schema cache, make sure new schema is valid.
 * 1. schema of pEntry must be live one
 * 2. create new schema instance via pEntry
 * 3. check active and new schema compatibility
 *    NOT compatible - reject this operation
 *    Compatible but NO semantic chnage - update schema entry
 *    Compatible and has semantic chnage - update schema entry and cache
 * 4. make new instance pending in gVdirSchemaGlobals
 */
DWORD
VmDirSchemaCacheModifyPrepare(
    PVDIR_OPERATION      pOperation,
    VDIR_MODIFICATION*   pMods,
    PVDIR_ENTRY          pSchemaEntry
    )
{
    DWORD dwError = 0;
    BOOLEAN                 bInLock = FALSE;
    PSTR                    pszLocalErrMsg = NULL;
    BOOLEAN                 bOwnNewInstance = FALSE;
    BOOLEAN                 bCompatible = FALSE;            // schema compatible
    BOOLEAN                 bNeedCachePatch = FALSE;        // schema semantic/cache change
    PVDIR_SCHEMA_INSTANCE   pNewInstance = NULL;            // DO NOT free, pEntry should take over it.
    PVDIR_SCHEMA_INSTANCE   pEntryOrgSchemaInstance = NULL;

    if ( !pMods || !pSchemaEntry || !pOperation )
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    {
        PVDIR_MODIFICATION  pLocalMods = NULL;
        PCSTR               immutableList[] = VDIR_IMMUTABLE_SCHEMA_ELEMENT_INITIALIZER;
        int                 iImmutableSize = sizeof(immutableList)/sizeof(immutableList[0]);

        for (pLocalMods = pMods; pLocalMods; pLocalMods = pLocalMods->next)
        {
            BOOLEAN bImmutableElement = _VmDirIsNameInCaseIgnoreList( pLocalMods->attr.pATDesc->pszName,
                                                                      immutableList,
                                                                      iImmutableSize);
            if ( bImmutableElement )
            {
                dwError = ERROR_OPERATION_NOT_PERMITTED;
                BAIL_ON_VMDIR_ERROR_WITH_MSG(dwError, pszLocalErrMsg,
                                             "modify (%s) not allowed", pLocalMods->attr.pATDesc->pszName);
            }
        }
    }

    // make sure pEntry uses live schema
    if (! vdirIsLiveSchema(pSchemaEntry->pSchemaCtx->pSchema))
    {
        dwError = LDAP_UNWILLING_TO_PERFORM;
        BAIL_ON_VMDIR_ERROR_WITH_MSG(dwError, pszLocalErrMsg, "Out dated schema");
    }

    pEntryOrgSchemaInstance = pSchemaEntry->pSchemaCtx->pSchema;
    // instantiate a schema cache - pNewInstance
    // If this call succeed, do NOT free pNewInstance.  pEntry->pSchemaCtx takes it over.
    dwError = VdirSchemaInstanceInitViaEntry(   pSchemaEntry,
                                                &pNewInstance);
    if ( dwError != 0
         &&
         pSchemaEntry->pSchemaCtx->pSchema != pNewInstance )
    {
        // we still own pNewInstance and need to free it.
        bOwnNewInstance = TRUE;
    }
    BAIL_ON_VMDIR_ERROR_WITH_MSG(dwError, pszLocalErrMsg, "Entry to schema instance failed (%d)", dwError);

    // check if two instances are compatible and if schema patching is needed
    dwError = VmDirSchemaInstancePatchCheck( pEntryOrgSchemaInstance,
                                             pNewInstance,
                                             &bCompatible,
                                             &bNeedCachePatch);
    BAIL_ON_VMDIR_ERROR_WITH_MSG(dwError, pszLocalErrMsg, "VmDirSchemaInstancePatch (%d)", dwError);

    if ( !bCompatible )
    {
        dwError = LDAP_UNWILLING_TO_PERFORM;
        BAIL_ON_VMDIR_ERROR_WITH_MSG(dwError, pszLocalErrMsg, "Schema NOT compatible (%d)", dwError);
    }

    if ( !bNeedCachePatch )
    {   // no semantic change, just update schema entry
        VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Prepare schema entry update");
    }
    else
    {   // need schema entry and cache update
        VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Prepare schema entry and instance update (%p)", pNewInstance);
    }

    VMDIR_LOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex);
    if ( bNeedCachePatch )
    {
        gVdirSchemaGlobals.bHasPendingChange = TRUE;
    }
    VMDIR_UNLOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex);


cleanup:

    VMDIR_UNLOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex);

    VMDIR_SAFE_FREE_MEMORY(pszLocalErrMsg);

    return dwError;

error:

    if ( bOwnNewInstance )
    {
        VdirSchemaInstanceFree( pNewInstance );
    }

    VMDIR_SET_LDAP_RESULT_ERROR( &pOperation->ldapResult, dwError, pszLocalErrMsg );

    goto cleanup;
}
Пример #18
0
DWORD
VmDirAnonymousLDAPBindWithTimeout(
    LDAP**      ppLd,
    PCSTR       pszLdapURI,
    int         timeout
    )
{
    DWORD       dwError = 0;
    int         retVal = 0;
    const int   ldapVer = LDAP_VERSION3;
    BerValue    ldapBindPwd = {0};
    LDAP*       pLocalLd = NULL;
    struct timeval nettimeout = {0};


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

    retVal = ldap_initialize( &pLocalLd, pszLdapURI);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

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

    if (timeout > 0)
    {
        nettimeout.tv_sec = timeout;

        // timeout connect
        retVal = ldap_set_option(pLocalLd, LDAP_OPT_NETWORK_TIMEOUT, (void *)&nettimeout);
        BAIL_ON_SIMPLE_LDAP_ERROR(retVal);
    }

    ldapBindPwd.bv_val = NULL;
    ldapBindPwd.bv_len = 0;

    retVal = ldap_sasl_bind_s(
                               pLocalLd,
                               "",
                               LDAP_SASL_SIMPLE,
                               &ldapBindPwd,  // no credentials
                               NULL,
                               NULL,
                               NULL);
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

    *ppLd = pLocalLd;

cleanup:

    return dwError;

ldaperror:

    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "VmDirAnonymousLDAPBind to (%s) failed. (%d)(%s)",
                     VDIR_SAFE_STRING(pszLdapURI), retVal, ldap_err2string(retVal) );
    dwError = VmDirMapLdapError(retVal);

error:
    if (retVal == 0)
    {
        VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "VmDirAnonymousLDAPBind to (%s) failed. (%u)", VDIR_SAFE_STRING(pszLdapURI), dwError);
    }

    if (pLocalLd)
    {
        ldap_unbind_ext_s( pLocalLd, NULL, NULL);
    }

    goto cleanup;
}
Пример #19
0
/* MdbAddEntry: Creates an entry in the MDB DBs.
 *
 * Returns: BE error codes.
 *
 */
DWORD
VmDirMDBAddEntry(
    PVDIR_BACKEND_CTX   pBECtx,
    PVDIR_ENTRY         pEntry)
{
    DWORD             dwError = 0;
    ENTRYID           entryId = 0;
    VDIR_DB_TXN*      pTxn = NULL;
    VDIR_BERVALUE     encodedEntry = VDIR_BERVALUE_INIT;
    VDIR_ATTRIBUTE *  nextAttr = NULL;

    assert( pEntry && pBECtx && pBECtx->pBEPrivate );

    pTxn = (PVDIR_DB_TXN)pBECtx->pBEPrivate;

    dwError = VmDirEncodeEntry( pEntry, &encodedEntry );
    BAIL_ON_VMDIR_ERROR(dwError);

    if (pEntry->eId != 0)    // Reserved entries have eId already
    {
        entryId = pEntry->eId;
    }
    else
    {
        VDIR_DB_DBT     EIDkey = {0};
        VDIR_DB_DBT     EIDvalue  = {0};
        unsigned char   EIDKeyBytes[sizeof( ENTRYID )] = {0};
        unsigned char   EIDValueBytes[sizeof( ENTRYID )] = {0};

        EIDkey.mv_data = &EIDKeyBytes[0];
        MDBEntryIdToDBT(BE_MDB_ENTRYID_SEQ_KEY, &EIDkey);

        dwError =  mdb_get(pTxn, gVdirMdbGlobals.mdbSeqDBi, &EIDkey, &EIDvalue);
        BAIL_ON_VMDIR_ERROR(dwError);

        assert( EIDvalue.mv_size == sizeof(ENTRYID) );
        entryId = *((ENTRYID*)EIDvalue.mv_data);

        *((ENTRYID*)&EIDValueBytes[0]) = entryId + 1;
        EIDvalue.mv_data = &EIDValueBytes[0];
        EIDvalue.mv_size = sizeof(ENTRYID);

        dwError =  mdb_put(pTxn, gVdirMdbGlobals.mdbSeqDBi, &EIDkey, &EIDvalue, BE_DB_FLAGS_ZERO);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    assert( entryId > 0 );

    if ((dwError = MDBCreateParentIdIndex(pBECtx, &(pEntry->pdn), entryId)) != 0)
    {
        dwError = MDBToBackendError(dwError, ERROR_BACKEND_ENTRY_NOTFOUND,
                                    ERROR_BACKEND_PARENT_NOTFOUND, pBECtx, "CreateParentIdIndex");
        BAIL_ON_VMDIR_ERROR( dwError );
    }

    // Update DN index first. this make sure we always return ERROR_BACKEND_ENTRY_EXISTS in such case.
    for (nextAttr = pEntry->attrs; nextAttr != NULL; nextAttr = nextAttr->next)
    {
        if (VmDirStringCompareA(nextAttr->type.lberbv.bv_val, ATTR_DN, FALSE) == 0)
        {
            // make sure we store normalized DN value.
            dwError = VmDirNormalizeDN( &(nextAttr->vals[0]), pEntry->pSchemaCtx );
            BAIL_ON_VMDIR_ERROR(dwError);

            if ((dwError = MdbUpdateIndicesForAttr( pTxn, &(nextAttr->type), nextAttr->vals, nextAttr->numVals,
                                                    entryId, BE_INDEX_OP_TYPE_CREATE)) != 0)
            {
                dwError = MDBToBackendError( dwError,
                                             MDB_KEYEXIST,
                                             ERROR_BACKEND_ENTRY_EXISTS,
                                             pBECtx,
                                             VDIR_SAFE_STRING(nextAttr->vals[0].bvnorm_val));
                BAIL_ON_VMDIR_ERROR( dwError );
            }
            if ((dwError = MdbUpdateAttrMetaData( pTxn, nextAttr, entryId, BE_INDEX_OP_TYPE_CREATE )) != 0)
            {
                dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx, "UpdateDNAttrMetaData");
                BAIL_ON_VMDIR_ERROR( dwError );
            }
        }
    }

    // Update remaining indices
    for (nextAttr = pEntry->attrs; nextAttr != NULL; nextAttr = nextAttr->next)
    {
        if (VmDirStringCompareA(nextAttr->type.lberbv.bv_val, ATTR_DN, FALSE) != 0)
        {
            if ((dwError = MdbUpdateIndicesForAttr( pTxn, &(nextAttr->type), nextAttr->vals, nextAttr->numVals,
                                                    entryId, BE_INDEX_OP_TYPE_CREATE)) != 0)
            {
                dwError = MDBToBackendError( dwError,
                                             MDB_KEYEXIST,
                                             ERROR_BACKEND_CONSTRAINT,
                                             pBECtx,
                                             VDIR_SAFE_STRING(nextAttr->type.lberbv.bv_val));
                BAIL_ON_VMDIR_ERROR( dwError );
            }
            if ((dwError = MdbUpdateAttrMetaData( pTxn, nextAttr, entryId, BE_INDEX_OP_TYPE_CREATE )) != 0)
            {
                dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx,
                                            VDIR_SAFE_STRING(nextAttr->type.lberbv.bv_val));
                BAIL_ON_VMDIR_ERROR( dwError );
            }
        }
    }

    // Update entry/blob database
    if ((dwError = MdbCreateEIDIndex(pTxn, entryId, &encodedEntry, TRUE /* 1st time new entry creation */)) != 0)
    {
        dwError = MDBToBackendError(dwError, MDB_KEYEXIST, ERROR_BACKEND_CONSTRAINT, pBECtx, "CreateEIDIndex");
        BAIL_ON_VMDIR_ERROR( dwError );
    }

cleanup:

    VMDIR_SAFE_FREE_MEMORY( encodedEntry.lberbv.bv_val );

    return dwError;

error:
    // TODO set pBECtx->pszBEErrorMsg?
    VMDIR_LOG_ERROR( LDAP_DEBUG_BACKEND, "BEAddEntry DN (%s),  (%u)(%s)", VDIR_SAFE_STRING(pEntry->dn.lberbv.bv_val),
                              dwError, VDIR_SAFE_STRING(pBECtx->pszBEErrorMsg));

    VMDIR_SET_BACKEND_ERROR(dwError);   // if dwError no in BE space, set to ERROR_BACKEND_ERROR

    goto cleanup;
}
Пример #20
0
static
DWORD
VmDirSrvInitKrb(
    PVDIR_SCHEMA_CTX pSchemaCtx,
    PCSTR            pszFQDomainName,
    PCSTR            pszDomainDN
    )
{
    DWORD       dwError = 0;
    PSTR        pszRealmName = NULL;
    PBYTE       pMasterKey = NULL;
    DWORD       dwMasterKeyLen = 0;
    PBYTE       pEncMasterKey = NULL;
    DWORD       dwEncMasterKeyLen = 0;
    PSTR        pszTgtUPN = NULL;
    PSTR        pszTgtCN = NULL;
    PSTR        pszTgtPasswd = NULL;
    PSTR        pszKMUPN = NULL;
    PSTR        pszKMPasswd = NULL;
    PSTR        pszKMDN = NULL;
    VDIR_BERVALUE   bervMKey = VDIR_BERVALUE_INIT;
    VDIR_BERVALUE   bervEncMKey = VDIR_BERVALUE_INIT;

    assert (pSchemaCtx && pszFQDomainName && pszDomainDN );

    dwError = VmDirKrbRealmNameNormalize(pszFQDomainName, &pszRealmName);
    BAIL_ON_VMDIR_ERROR(dwError);

    // create krb master key
    dwError = VmKdcGenerateMasterKey(
                    &pMasterKey,
                    &dwMasterKeyLen,
                    &pEncMasterKey,
                    &dwEncMasterKeyLen);
    BAIL_ON_VMDIR_ERROR(dwError);

    bervMKey.lberbv.bv_val = pMasterKey;
    bervMKey.lberbv.bv_len = dwMasterKeyLen;
    bervEncMKey.lberbv.bv_val = pEncMasterKey;
    bervEncMKey.lberbv.bv_len = dwEncMasterKeyLen;

    // add krb master key to domain entry
    dwError = VmDirInternalEntryAttributeReplace(
                    pSchemaCtx,
                    pszDomainDN,
                    ATTR_KRB_MASTER_KEY,
                    &bervMKey);
    BAIL_ON_VMDIR_ERROR(dwError);

    // init gVmdirKrbGlobals (to cache krbMKey), which is needed in VmDirCreateAccount below.
    dwError = VmDirKrbInit();
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirAllocateStringAVsnprintf(
                    &pszTgtUPN,
                    "krbtgt/%s@%s",
                    pszRealmName,
                    pszRealmName);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirAllocateStringAVsnprintf(
                    &pszTgtCN,
                    "krbtgt/%s",
                    pszRealmName);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmKdcGenerateRandomPassword(
                    VMDIR_KDC_RANDOM_PWD_LEN,
                    &pszTgtPasswd);
    BAIL_ON_VMDIR_ERROR(dwError);

    // create krbtgt principal
    dwError = VmDirCreateAccount(
                    pszTgtUPN,
                    pszTgtCN,
                    pszTgtPasswd,
                    NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirAllocateStringAVsnprintf(
                    &pszKMUPN,
                    "K/M@%s",
                    pszRealmName);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmKdcGenerateRandomPassword(
                    VMDIR_KDC_RANDOM_PWD_LEN,
                    &pszKMPasswd);
    BAIL_ON_VMDIR_ERROR(dwError);

    // create K/M principal
    dwError = VmDirCreateAccount(
                    pszKMUPN,
                    "K/M",           // TODO, cn=k/M for now
                    pszKMPasswd,
                    NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirUPNToAccountDN(
                    pszKMUPN,
                    "cn",
                    "K/M",
                    &pszKMDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    // K/M principal need special ATTR_KRB_PRINCIPAL - encoded master key/pEncMasterKey
    dwError = VmDirInternalEntryAttributeReplace(
                    pSchemaCtx,
                    pszKMDN,
                    ATTR_KRB_PRINCIPAL_KEY,
                    &bervEncMKey);
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:

    VMDIR_SAFE_FREE_MEMORY(pMasterKey);
    VMDIR_SAFE_FREE_MEMORY(pEncMasterKey);
    VMDIR_SAFE_FREE_MEMORY(pszTgtUPN);
    VMDIR_SAFE_FREE_MEMORY(pszTgtCN);
    VMDIR_SAFE_FREE_MEMORY(pszTgtPasswd);
    VMDIR_SAFE_FREE_MEMORY(pszKMUPN);
    VMDIR_SAFE_FREE_MEMORY(pszKMPasswd);
    VMDIR_SAFE_FREE_MEMORY(pszRealmName);
    VMDIR_SAFE_FREE_MEMORY(pszKMDN);

    return dwError;

error:
    goto cleanup;
}
Пример #21
0
/* MdbModifyEntry: Updates an entry in the MDB DBs.
 *
 * Returns: BE error codes.
 *
 */
DWORD
VmDirMDBModifyEntry(
    PVDIR_BACKEND_CTX   pBECtx,
    VDIR_MODIFICATION*  pMods,
    PVDIR_ENTRY         pEntry
    )
{
    DWORD                   dwError = 0;
    VDIR_BERVALUE           newEncodedEntry = VDIR_BERVALUE_INIT;
    VDIR_MODIFICATION *     mod = NULL;
    PVDIR_DB_TXN            pTxn = NULL;

    assert( pBECtx && pBECtx->pBEPrivate && pMods && pEntry );

    pTxn = (PVDIR_DB_TXN)pBECtx->pBEPrivate;

    dwError = VmDirEncodeEntry( pEntry, &newEncodedEntry );
    BAIL_ON_VMDIR_ERROR(dwError);

    VMDIR_SAFE_FREE_MEMORY( pEntry->encodedEntry );
    // entry takes over the responsibility to free newEncodedEntry.lberbv.bv_val
    pEntry->encodedEntry = (unsigned char *)newEncodedEntry.lberbv.bv_val;

    // Create/Delete appropriate indices for indexed attributes.
    for (mod = pMods; mod != NULL; mod = mod->next)
    {
        if (mod->ignore)
        {
            continue;
        }
        switch (mod->operation)
        {
            case MOD_OP_ADD:
                if ((dwError = MdbUpdateIndicesForAttr( pTxn, &(mod->attr.type), mod->attr.vals, mod->attr.numVals,
                                                       pEntry->eId, BE_INDEX_OP_TYPE_CREATE)) != 0)
                {
                    dwError = MDBToBackendError( dwError, MDB_KEYEXIST, ERROR_BACKEND_CONSTRAINT, pBECtx,
                                                 VDIR_SAFE_STRING(mod->attr.type.lberbv.bv_val));
                    BAIL_ON_VMDIR_ERROR( dwError );
                }
                break;

            case MOD_OP_DELETE:
                if ((dwError = MdbUpdateIndicesForAttr( pTxn, &(mod->attr.type), mod->attr.vals, mod->attr.numVals,
                                                       pEntry->eId, BE_INDEX_OP_TYPE_DELETE )) != 0)
                {
                    dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx,
                                                VDIR_SAFE_STRING(mod->attr.type.lberbv.bv_val));
                    BAIL_ON_VMDIR_ERROR( dwError );
                }
                break;

            case MOD_OP_REPLACE:
            default:
                assert( FALSE );
        }
        if ((dwError = MdbUpdateAttrMetaData( pTxn, &(mod->attr), pEntry->eId, BE_INDEX_OP_TYPE_UPDATE )) != 0)
        {
            dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx,
                                        VDIR_SAFE_STRING(mod->attr.type.lberbv.bv_val));
            BAIL_ON_VMDIR_ERROR( dwError );
        }
    }

    // Update Entry DB.
    if ((dwError = MdbCreateEIDIndex(pTxn, pEntry->eId, &newEncodedEntry, FALSE /* update current eId key */)) != 0)
    {
        dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx, "CreateEIDIndex");
        BAIL_ON_VMDIR_ERROR( dwError );
    }

cleanup:

     return dwError;

error:

    VMDIR_SET_BACKEND_ERROR(dwError);   // if dwError no in BE space, set to ERROR_BACKEND_ERROR

    VMDIR_LOG_ERROR(LDAP_DEBUG_BACKEND,
             "ModifyEntry failed: error=%d,DN=%s", dwError, VDIR_SAFE_STRING(pEntry->dn.lberbv.bv_val));

     goto cleanup;
}
Пример #22
0
DWORD
VmDirSrvSetupHostInstance(
    PCSTR   pszFQDomainName,
    PCSTR   pszUsername,
    PCSTR   pszPassword,
    PCSTR   pszSiteName,
    PCSTR   pszReplURI,
    UINT32  firstReplCycleMode
    )
{
    DWORD   dwError = 0;

    PCSTR   pszDelObjsContainerName =     "Deleted Objects";
    PCSTR   pszConfigContainerName =      VMDIR_CONFIGURATION_CONTAINER_NAME;
    PCSTR   pszCAContainerName =          VMDIR_CA_CONTAINER_NAME;
    PCSTR   pszSitesContainerName =       VMDIR_SITES_RDN_VAL;
    PCSTR   pszSiteContainerName =        "Default-First-Site";
    PCSTR   pszServersContainerName =     VMDIR_SERVERS_CONTAINER_NAME;
    PCSTR   pszReplAgrsContainerName =    VMDIR_REPL_AGRS_CONTAINER_NAME;
    PCSTR   pszDCsContainerName =         VMDIR_DOMAIN_CONTROLLERS_RDN_VAL;
    PCSTR   pszComputersContainerName =   VMDIR_COMPUTERS_RDN_VAL;
    PCSTR   pszMSAsContainerName =        VMDIR_MSAS_RDN_VAL;

    PSTR    pszDomainDN = NULL;
    PSTR    pszDelObjsContainerDN = NULL;     // CN=Deleted Objects,<domain DN>
    PSTR    pszConfigContainerDN = NULL;      // CN=Configuration,<domain DN>
    PSTR    pszCAContainerDN = NULL;          // CN=Certificate-Authorities,CN=Configuration,<domain DN>
    PSTR    pszSitesContainerDN = NULL;       // CN=Sites,<configuration DN>
    PSTR    pszSiteContainerDN = NULL;        // CN=<Site-Name>,<Sites container DN>
    PSTR    pszServersContainerDN = NULL;     // CN=Servers,<Site container DN>
    PSTR    pszServerDN = NULL;               // CN=<fully qualified host name>,<Servers container DN>
    PSTR    pszReplAgrsContainerDN = NULL;    // CN=Replication Agreements,<Server DN>
    PSTR    pszReplAgrDN = NULL;              // labeledURI=<ldap://192.165.226.127>,<ReplAgrsContainerDN>
    PSTR    pszDCsContainerDN = NULL;         // OU=Domain Controllers,<domain DN>
    PSTR    pszComputersContainerDN = NULL;   // OU=Computers,<domain DN>
    PSTR    pszDCAccountDN = NULL;            // CN=<fully qualified host name>,OU=Domain Controllers,<domain DN>
    PSTR    pszDCAccountUPN = NULL;            // <hostname>@<domain name>
    PSTR    pszComputerAccountDN = NULL;      // CN=<fully qualified host name>,OU=Domain Computers,<domain DN>
    PSTR    pszMSAsDN = NULL;                 // CN=<Managed Service Accounts>,<domain DN>
    PSTR    pszUpperCaseFQDomainName = NULL;
    PSTR    pszLowerCaseHostName = NULL;
    PSTR    pszDefaultAdminDN = NULL;

    PVDIR_SCHEMA_CTX     pSchemaCtx = NULL;
    char                 pszHostName[VMDIR_MAX_HOSTNAME_LEN];
    VDIR_BERVALUE        bv = VDIR_BERVALUE_INIT;

    BOOLEAN                       bInLockReplCycle = FALSE;
    PVMDIR_REPLICATION_AGREEMENT  pReplAgr = NULL;
    BOOLEAN                       bInLock = FALSE;
    PSTR                          pszUserDN = NULL;
    PCSTR                         pszUsersContainerName    = "Users";
    PSTR                          pszUsersContainerDN   = NULL; // CN=Users,<domain DN>

    VMDIR_LOG_INFO(VMDIR_LOG_MASK_ALL, "Setting up a host instance (%s).",
			               VDIR_SAFE_STRING(pszFQDomainName));

    if (pszSiteName)
    {
        pszSiteContainerName = pszSiteName;
    }

    // If joining another node, copy schema from the partner first.
    if (!IsNullOrEmptyString(pszReplURI))
    {
        dwError = VmDirCopyPartnerSchema(
                pszFQDomainName,
                pszUsername,
                pszPassword,
                pszReplURI);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

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

    // Construct important DNs and create the persisted DSE Root entry

    // Domain DN
    dwError = VmDirSrvCreateDomainDN( pszFQDomainName, &pszDomainDN );
    BAIL_ON_VMDIR_ERROR(dwError);

    // Deleted objects container DN
    dwError = VmDirSrvCreateDN( pszDelObjsContainerName, pszDomainDN, &pszDelObjsContainerDN );
    BAIL_ON_VMDIR_ERROR(dwError);

    // Configuration container DN
    dwError = VmDirSrvCreateDN( pszConfigContainerName, pszDomainDN, &pszConfigContainerDN );
    BAIL_ON_VMDIR_ERROR(dwError);

    // Domain Controllers container DN
    dwError = VmDirAllocateStringAVsnprintf(&pszDCsContainerDN, "%s=%s,%s", ATTR_OU, pszDCsContainerName, pszDomainDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    // Domain Computers container DN
    dwError = VmDirAllocateStringAVsnprintf(&pszComputersContainerDN, "%s=%s,%s", ATTR_OU, pszComputersContainerName, pszDomainDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    // Sites container DN
    dwError = VmDirSrvCreateDN( pszSitesContainerName, pszConfigContainerDN, &pszSitesContainerDN );
    BAIL_ON_VMDIR_ERROR(dwError);

    // Certificate-Authorities container DN
    dwError = VmDirSrvCreateDN( pszCAContainerName, pszConfigContainerDN, &pszCAContainerDN );
    BAIL_ON_VMDIR_ERROR(dwError);

    // Particular site container DN
    dwError = VmDirSrvCreateDN( pszSiteContainerName, pszSitesContainerDN, &pszSiteContainerDN );
    BAIL_ON_VMDIR_ERROR(dwError);

    // Servers within the site container DN
    dwError = VmDirSrvCreateDN( pszServersContainerName, pszSiteContainerDN, &pszServersContainerDN );
    BAIL_ON_VMDIR_ERROR(dwError);

    // This server DN

    // vdcpromo sets this key.
    dwError = VmDirGetRegKeyValue( VMDIR_CONFIG_PARAMETER_KEY_PATH,
                                   VMDIR_REG_KEY_DC_ACCOUNT,
                                   pszHostName,
                                   sizeof(pszHostName)-1);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirAllocASCIIUpperToLower( pszHostName, &pszLowerCaseHostName );
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirSrvCreateDN( pszLowerCaseHostName, pszServersContainerDN, &pszServerDN );
    BAIL_ON_VMDIR_ERROR(dwError);

    // Domain controller account DN
    dwError = VmDirSrvCreateDN( pszLowerCaseHostName, pszDCsContainerDN, &pszDCAccountDN );
    BAIL_ON_VMDIR_ERROR(dwError);

    // Domain controller account UPN
    dwError = VmDirAllocASCIILowerToUpper( pszFQDomainName, &pszUpperCaseFQDomainName );
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirAllocateStringAVsnprintf(&pszDCAccountUPN, "%s@%s", pszLowerCaseHostName, pszUpperCaseFQDomainName );
    BAIL_ON_VMDIR_ERROR(dwError);

    // Computer account DN
    dwError = VmDirSrvCreateDN( pszLowerCaseHostName, pszComputersContainerDN, &pszComputerAccountDN );
    BAIL_ON_VMDIR_ERROR(dwError);

    // Replication agreements container DN
    dwError = VmDirSrvCreateDN( pszReplAgrsContainerName, pszServerDN, &pszReplAgrsContainerDN );
    BAIL_ON_VMDIR_ERROR(dwError);

    // Managed Service Accounts container DN
    dwError = VmDirSrvCreateDN( pszMSAsContainerName, pszDomainDN, &pszMSAsDN );
    BAIL_ON_VMDIR_ERROR(dwError);

    // Default administrator DN
    dwError = VmDirAllocateStringAVsnprintf( &pszDefaultAdminDN, "cn=%s,cn=%s,%s",
                                             pszUsername, pszUsersContainerName, pszDomainDN );
    BAIL_ON_VMDIR_ERROR(dwError);

    if (firstReplCycleMode != FIRST_REPL_CYCLE_MODE_USE_COPIED_DB)
    {
        // Modify persisted DSE Root entry
        dwError = VmDirSrvModifyPersistedDSERoot( pSchemaCtx, pszDomainDN, pszConfigContainerDN, SCHEMA_NAMING_CONTEXT_DN,
                                                  SUB_SCHEMA_SUB_ENTRY_DN, pszServerDN, pszDefaultAdminDN,
                                                  pszDCAccountDN, pszDCAccountUPN, pszDelObjsContainerDN,
                                                  (PSTR) pszSiteContainerName );
    }
    BAIL_ON_VMDIR_ERROR(dwError);

    // set gVmdirServerGlobals.bvDefaultAdminDN
    dwError = VmDirAllocateBerValueAVsnprintf(
                &gVmdirServerGlobals.bvDefaultAdminDN,
                "%s",
                pszDefaultAdminDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirNormalizeDN( &gVmdirServerGlobals.bvDefaultAdminDN, pSchemaCtx);
    BAIL_ON_VMDIR_ERROR(dwError);

    // set systemDomainDN
    dwError = VmDirAllocateBerValueAVsnprintf(
                &gVmdirServerGlobals.systemDomainDN,
                "%s",
                pszDomainDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirNormalizeDN( &gVmdirServerGlobals.systemDomainDN, pSchemaCtx);
    BAIL_ON_VMDIR_ERROR(dwError);

    // set serverObjDN
    dwError = VmDirAllocateBerValueAVsnprintf(
                &gVmdirServerGlobals.serverObjDN,
                "%s",
                pszServerDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirNormalizeDN( &gVmdirServerGlobals.serverObjDN, pSchemaCtx);
    BAIL_ON_VMDIR_ERROR(dwError);

    // set dcAccountDN
    dwError = VmDirAllocateBerValueAVsnprintf(
                &gVmdirServerGlobals.dcAccountDN,
                "%s",
                pszDCAccountDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirNormalizeDN( &gVmdirServerGlobals.dcAccountDN, pSchemaCtx);
    BAIL_ON_VMDIR_ERROR(dwError);

    // set dcAccountUPN
    dwError = VmDirAllocateBerValueAVsnprintf(
                &gVmdirServerGlobals.dcAccountUPN,
                "%s",
                pszDCAccountUPN);
    BAIL_ON_VMDIR_ERROR(dwError);

    // Set replInterval and replPageSize
    gVmdirServerGlobals.replInterval = VmDirStringToIA(VMDIR_DEFAULT_REPL_INTERVAL);
    gVmdirServerGlobals.replPageSize = VmDirStringToIA(VMDIR_DEFAULT_REPL_PAGE_SIZE);

    // Set utdVector
    VmDirFreeBervalContent(&bv);
    bv.lberbv.bv_val = "";
    bv.lberbv.bv_len = 0;
    dwError = VmDirBervalContentDup( &bv, &gVmdirServerGlobals.utdVector );
    BAIL_ON_VMDIR_ERROR(dwError);

    // Set delObjsContainerDN
    VmDirFreeBervalContent(&bv);
    bv.lberbv.bv_val = pszDelObjsContainerDN;
    bv.lberbv.bv_len = VmDirStringLenA( bv.lberbv.bv_val );
    dwError = VmDirBervalContentDup( &bv, &gVmdirServerGlobals.delObjsContainerDN );
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirNormalizeDN(&gVmdirServerGlobals.delObjsContainerDN, pSchemaCtx);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirAllocateStringA( pszSiteContainerName, &gVmdirServerGlobals.pszSiteName);
    BAIL_ON_VMDIR_ERROR(dwError);

    // Create Administrator DN
    dwError = VmDirSrvCreateDN( pszUsersContainerName, pszDomainDN, &pszUsersContainerDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirSrvCreateUserDN( pszUsername, pszUsersContainerDN, &pszUserDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    // set DomainControllerGroupDN for first,second+ host setup
    dwError = VmDirAllocateBerValueAVsnprintf(
                &gVmdirServerGlobals.bvDCGroupDN,
                "cn=%s,cn=%s,%s",
                VMDIR_DC_GROUP_NAME,
                VMDIR_BUILTIN_CONTAINER_NAME,
                pszDomainDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirNormalizeDN( &(gVmdirServerGlobals.bvDCGroupDN), pSchemaCtx);
    BAIL_ON_VMDIR_ERROR(dwError);

    // set DCClientGroupDN for first,second+ host setup
    dwError = VmDirAllocateBerValueAVsnprintf(
                &gVmdirServerGlobals.bvDCClientGroupDN,
                "cn=%s,cn=%s,%s",
                VMDIR_DCCLIENT_GROUP_NAME,
                VMDIR_BUILTIN_CONTAINER_NAME,
                pszDomainDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirNormalizeDN( &(gVmdirServerGlobals.bvDCClientGroupDN), pSchemaCtx);
    BAIL_ON_VMDIR_ERROR(dwError);

    // set ServicesRootDN for first,second+ host setup
    dwError = VmDirAllocateBerValueAVsnprintf(
                &gVmdirServerGlobals.bvServicesRootDN,
                "cn=%s,%s",
                VMDIR_SERVICES_CONTAINER_NAME,
                pszDomainDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirNormalizeDN( &(gVmdirServerGlobals.bvServicesRootDN), pSchemaCtx);
    BAIL_ON_VMDIR_ERROR(dwError);

    if (IsNullOrEmptyString(pszReplURI)) // 1st directory instance is being setup
    {
        // Set gVmdirServerGlobals.serverId FIRST, so that correct SID can be generated for the objects added subsequently.
        gVmdirServerGlobals.serverId = 1;

        dwError = VmDirSrvSetupDomainInstance( pSchemaCtx, TRUE, TRUE, pszFQDomainName, pszDomainDN, pszUsername,
                                               pszPassword );
        BAIL_ON_VMDIR_ERROR(dwError);

        // Create Deleted Objects container
        dwError = VmDirSrvCreateContainerWithEID( pSchemaCtx, pszDelObjsContainerDN, pszDelObjsContainerName,
                                                 DEL_ENTRY_CONTAINER_ENTRY_ID );
        BAIL_ON_VMDIR_ERROR(dwError);

        // Create Domain Controllers container
        dwError = VmDirSrvCreateOUContainer( pSchemaCtx, pszDCsContainerDN, pszDCsContainerName );
        BAIL_ON_VMDIR_ERROR(dwError);

        // Create Computers container
        dwError = VmDirSrvCreateOUContainer( pSchemaCtx, pszComputersContainerDN, pszComputersContainerName );
        BAIL_ON_VMDIR_ERROR(dwError);

        // Create Managed Service Accounts container
        dwError = VmDirSrvCreateContainer( pSchemaCtx, pszMSAsDN, pszMSAsContainerName );
        BAIL_ON_VMDIR_ERROR(dwError);

        // Create Configuration container
        dwError = VmDirSrvCreateConfigContainer( pSchemaCtx, pszConfigContainerDN, pszConfigContainerName );
        BAIL_ON_VMDIR_ERROR(dwError);

        // Create Certificate-Authorities container
        dwError = VmDirSrvCreateContainer( pSchemaCtx, pszCAContainerDN, pszCAContainerName );
        BAIL_ON_VMDIR_ERROR(dwError);

        // Create Sites container
        dwError = VmDirSrvCreateContainer( pSchemaCtx, pszSitesContainerDN, pszSitesContainerName );
        BAIL_ON_VMDIR_ERROR(dwError);

        /*
        // Create Site-Name container
        dwError = VmDirSrvCreateContainer( pSchemaCtx, pszSiteContainerDN, pszSiteContainerName );
        BAIL_ON_VMDIR_ERROR(dwError);

        // Create Servers container
        dwError = VmDirSrvCreateContainer( pSchemaCtx, pszServersContainerDN, pszServersContainerName );
        BAIL_ON_VMDIR_ERROR(dwError);
        */

        // Create Site-Name container, Servers container, and THE Server object
        dwError = VmDirSrvCreateServerObj( pSchemaCtx );
        BAIL_ON_VMDIR_ERROR(dwError);

        // Create Replication Agreements container
        dwError = VmDirSrvCreateReplAgrsContainer( pSchemaCtx );
        BAIL_ON_VMDIR_ERROR(dwError);

        // 1st replica => no replication agreements => 1st replication cycle done
        VMDIR_LOCK_MUTEX(bInLockReplCycle, gVmdirGlobals.replCycleDoneMutex);
        VmDirConditionSignal(gVmdirGlobals.replCycleDoneCondition);
        VMDIR_UNLOCK_MUTEX(bInLockReplCycle, gVmdirGlobals.replCycleDoneMutex);
    }
    else
    {
        dwError = VmDirAllocateStringAVsnprintf( &pszReplAgrDN, "labeledURI=%s,%s", pszReplURI, pszReplAgrsContainerDN );
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = VmDirConstructReplAgr( pSchemaCtx, pszReplURI,
                                         VMDIR_DEFAULT_REPL_LAST_USN_PROCESSED, pszReplAgrDN, &pReplAgr );
        BAIL_ON_VMDIR_ERROR(dwError);

        gFirstReplCycleMode = firstReplCycleMode;

        VMDIR_LOCK_MUTEX(bInLock, gVmdirGlobals.replAgrsMutex);
        pReplAgr->next = gVmdirReplAgrs;
        gVmdirReplAgrs = pReplAgr; // ownership transfer
        // wake up replication thread waiting on the existence
        // of a replication agreement.
        VmDirConditionSignal(gVmdirGlobals.replAgrsCondition);
        VMDIR_UNLOCK_MUTEX(bInLock, gVmdirGlobals.replAgrsMutex);
    }

cleanup:

    if (pSchemaCtx)
    {
        VmDirSchemaCtxRelease(pSchemaCtx);
    }

    VMDIR_SAFE_FREE_MEMORY(pszDomainDN);
    VMDIR_SAFE_FREE_MEMORY(pszDelObjsContainerDN);
    VMDIR_SAFE_FREE_MEMORY(pszConfigContainerDN);
    VMDIR_SAFE_FREE_MEMORY(pszCAContainerDN);
    VMDIR_SAFE_FREE_MEMORY(pszSitesContainerDN);
    VMDIR_SAFE_FREE_MEMORY(pszSiteContainerDN);
    VMDIR_SAFE_FREE_MEMORY(pszServersContainerDN);
    VMDIR_SAFE_FREE_MEMORY(pszServerDN);
    VMDIR_SAFE_FREE_MEMORY(pszReplAgrsContainerDN);
    VMDIR_SAFE_FREE_MEMORY(pszReplAgrDN);
    VMDIR_SAFE_FREE_MEMORY(pszDCsContainerDN);
    VMDIR_SAFE_FREE_MEMORY(pszDCAccountDN);
    VMDIR_SAFE_FREE_MEMORY(pszDCAccountUPN);
    VMDIR_SAFE_FREE_MEMORY(pszComputersContainerDN);
    VMDIR_SAFE_FREE_MEMORY(pszComputerAccountDN);
    VMDIR_SAFE_FREE_MEMORY(pszMSAsDN);
    VMDIR_SAFE_FREE_MEMORY(pszUpperCaseFQDomainName);
    VMDIR_SAFE_FREE_MEMORY(pszUsersContainerDN);
    VMDIR_SAFE_FREE_MEMORY(pszUserDN);
    VMDIR_SAFE_FREE_MEMORY(pszDefaultAdminDN);
    VMDIR_SAFE_FREE_MEMORY(pszLowerCaseHostName);

    VmDirFreeBervalContent(&bv);

    return dwError;

error:
    VmDirLog(LDAP_DEBUG_ANY, "VmDirSrvSetupHostInstance failed. Error(%u)", dwError);
    goto cleanup;
}
Пример #23
0
/*
 * 1. remove extra spaces (i.e. collapse spaces into one)
 * 2. if bIsCaseIgnore, change to lower case
 * 3. if NO change in value, *ppOutBerv is NULL
 */
static
DWORD
normalizeString(
    BOOLEAN     bIsCaseIgnore,
    PVDIR_BERVALUE     pBerv
    )
{
    DWORD dwError = 0;
    DWORD dwCnt = 0;
    DWORD dwNewSize = 0;
    BOOLEAN bIsValueChanged = FALSE;

    char plocalBuf[128] = {0};
    char* pBuf = &plocalBuf[0];

    assert(pBerv);

    if (pBerv->bvnorm_val && pBerv->lberbv.bv_val != pBerv->bvnorm_val)
    {
        // cleanup bvnorm val/len
        VMDIR_SAFE_FREE_MEMORY(pBerv->bvnorm_val);
        pBerv->bvnorm_len = 0;
    }

    if (pBerv->lberbv.bv_len > 127)
    {
        dwError = VmDirAllocateMemory(
                sizeof(char) * pBerv->lberbv.bv_len + 1,
                (PVOID*)&pBuf);
    }

    for (dwCnt = 0; dwCnt < pBerv->lberbv.bv_len; dwCnt++)
    {
        if (! VDIR_ASCII_SPACE(pBerv->lberbv.bv_val[dwCnt]))
        {
            break;
        }
    }

    if (dwCnt != 0)
    {   // consolidate leading spaces to just one
        pBuf[dwNewSize++] = ' ';
    }

    for (;dwCnt < pBerv->lberbv.bv_len; dwCnt++)
    {
        if (VDIR_ASCII_SPACE(pBerv->lberbv.bv_val[dwCnt]))
        {
            if ((dwCnt < pBerv->lberbv.bv_len - 1 &&
                 !VDIR_ASCII_SPACE(pBerv->lberbv.bv_val[dwCnt+1])) ||
                (dwCnt == pBerv->lberbv.bv_len -1))
            {
                pBuf[dwNewSize] = pBerv->lberbv.bv_val[dwCnt];
                if (bIsCaseIgnore)
                {
                    VIDR_ASCII_UPPER_TO_LOWER(pBuf[dwNewSize], bIsValueChanged);
                }
                dwNewSize++;

            }
            // skip extra middle and trailing spaces
        }
        else
        {
            pBuf[dwNewSize] = pBerv->lberbv.bv_val[dwCnt];
            if (bIsCaseIgnore)
            {
                VIDR_ASCII_UPPER_TO_LOWER(pBuf[dwNewSize], bIsValueChanged);
            }
            dwNewSize++;
        }
    }

    if (dwNewSize == pBerv->lberbv.bv_len && !bIsValueChanged)
    {   // value == normalized value, point to self
        pBerv->bvnorm_val = pBerv->lberbv.bv_val;
        pBerv->bvnorm_len = pBerv->lberbv.bv_len;
    }
    else
    {
        dwError = VmDirAllocateStringA(
                pBuf,
                &pBerv->bvnorm_val);
        BAIL_ON_VMDIR_ERROR(dwError);

        pBerv->bvnorm_len = dwNewSize;
    }

cleanup:

    if (pBuf != &plocalBuf[0])
    {
        VMDIR_SAFE_FREE_MEMORY(pBuf);
    }

    return dwError;

error:

    goto cleanup;
}
Пример #24
0
static
DWORD
VmDirSrvSetupDomainInstance(
    PVDIR_SCHEMA_CTX pSchemaCtx,
    BOOLEAN          bSetupHost,
    BOOLEAN          bFirstNodeBootstrap,
    PCSTR            pszFQDomainName,
    PCSTR            pszDomainDN,
    PCSTR            pszUsername,
    PCSTR            pszPassword
    )
{
    DWORD dwError = 0;

    PCSTR pszUsersContainerName    = "Users";
    PCSTR pszBuiltInContainerName  = "Builtin";
    PCSTR pszFSPsContainerName  = FSP_CONTAINER_RDN_ATTR_VALUE;
    PCSTR pszBuiltInUsersGroupName = "Users";
    PCSTR pszBuiltInAdministratorsGroupName = "Administrators";

    PSTR pszUsersContainerDN   = NULL; // CN=Users,<domain DN>
    PSTR pszBuiltInContainerDN = NULL; // CN=BuiltIn,<domain DN>
    PSTR pszFSPsContainerDN = NULL;     // CN=ForeignSecurityPrincipals,<domain DN>
    PSTR pszUserDN = NULL;
    PSTR pszBuiltInUsersGroupDN = NULL;
    PSTR pszBuiltInAdministratorsGroupDN = NULL;
    PSTR pszDefaultPasswdLockoutPolicyDN = NULL;
    PSTR pszDCGroupDN = NULL;
    PSTR pszDCClientGroupDN = NULL;
    PSTR pszCertGroupDN = NULL;
    PSTR pszTenantRealmName = NULL;

    PSECURITY_DESCRIPTOR_RELATIVE pSecDescRel = NULL;
    ULONG                         ulSecDescRel = 0;
    SECURITY_INFORMATION          SecInfo = 0;

    PSTR pszAdminSid = NULL;
    PSTR pszBuiltInUsersGroupSid = NULL;
    PSTR pszAdminsGroupSid = NULL;
    PSTR pszAdminUserKrbUPN = NULL;

    int i = 0;
    int startOfRdnInd = 0;

    // Create host/tenant domain

    dwError = VmDirSrvCreateDomain(pSchemaCtx, bSetupHost, pszDomainDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    // Create Users container

    dwError = VmDirSrvCreateDN( pszUsersContainerName, pszDomainDN, &pszUsersContainerDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirSrvCreateContainer( pSchemaCtx, pszUsersContainerDN, pszUsersContainerName);
    BAIL_ON_VMDIR_ERROR(dwError);

    // Create Builtin container

    dwError = VmDirSrvCreateDN( pszBuiltInContainerName, pszDomainDN, &pszBuiltInContainerDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirSrvCreateBuiltinContainer( pSchemaCtx, pszBuiltInContainerDN, pszBuiltInContainerName );
    BAIL_ON_VMDIR_ERROR(dwError);

    // Create ForeignSecurityPrincipals container

    dwError = VmDirSrvCreateDN( pszFSPsContainerName, pszDomainDN, &pszFSPsContainerDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirSrvCreateContainer( pSchemaCtx, pszFSPsContainerDN, pszFSPsContainerName);
    BAIL_ON_VMDIR_ERROR(dwError);

    if (bSetupHost)
    {
        // only do this for the very first node startup.
        if (bFirstNodeBootstrap)
        {
            dwError = VmDirSrvInitKrb(pSchemaCtx, pszFQDomainName, pszDomainDN);
            BAIL_ON_VMDIR_ERROR(dwError);

            // prepare administrator krb UPN for the very first node
            dwError = VmDirAllocateStringAVsnprintf(
                            &pszAdminUserKrbUPN,
                            "%s@%s",
                            pszUsername,
                            gVmdirKrbGlobals.pszRealm);
            BAIL_ON_VMDIR_ERROR(dwError);
        }
    }
    else
    {   // setup tenant scenario.
        // Though we only support system domain kdc, we need UPN for SRP to function.
        dwError = VmDirKrbRealmNameNormalize(pszFQDomainName, &pszTenantRealmName);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = VmDirAllocateStringAVsnprintf(
                        &pszAdminUserKrbUPN,
                        "%s@%s",
                        pszUsername,
                        pszTenantRealmName);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    // Create Admin user

    dwError = VmDirSrvCreateUserDN( pszUsername, pszUsersContainerDN, &pszUserDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirGenerateWellknownSid(pszDomainDN,
                                        VMDIR_DOMAIN_USER_RID_ADMIN,
                                        &pszAdminSid);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirSrvCreateUser( pSchemaCtx,
                                  (bSetupHost && bFirstNodeBootstrap) ? DEFAULT_ADMINISTRATOR_ENTRY_ID : 0,
                                  pszUsername, pszUsername, pszFQDomainName, pszUsername, pszPassword,
                                  pszUserDN, pszAdminSid, pszAdminUserKrbUPN);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirSetAdministratorPasswordNeverExpires();
    BAIL_ON_VMDIR_ERROR(dwError);

    // Create BuiltInUsers group

    dwError = VmDirAllocateStringAVsnprintf( &pszBuiltInUsersGroupDN, "cn=%s,%s", pszBuiltInUsersGroupName,
                                             pszBuiltInContainerDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirGenerateWellknownSid(pszDomainDN,
                                        VMDIR_DOMAIN_ALIAS_RID_USERS,
                                        &pszBuiltInUsersGroupSid);
    BAIL_ON_VMDIR_ERROR(dwError);

    //
    // Create the user group for tenant setup or for first host setup.
    //
    if (bSetupHost == FALSE || bFirstNodeBootstrap == TRUE)
    {
        dwError = VmDirSrvCreateBuiltInUsersGroup( pSchemaCtx, pszBuiltInUsersGroupName,
                                                   pszBuiltInUsersGroupDN, pszUserDN,
                                                   pszBuiltInUsersGroupSid);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    // Create BuiltInAdministrators group

    dwError = VmDirAllocateStringAVsnprintf( &pszBuiltInAdministratorsGroupDN, "cn=%s,%s",
                                             pszBuiltInAdministratorsGroupName, pszBuiltInContainerDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirGenerateWellknownSid(pszDomainDN,
                                        VMDIR_DOMAIN_ALIAS_RID_ADMINS,
                                        &pszAdminsGroupSid);
    BAIL_ON_VMDIR_ERROR(dwError);

    //
    // Create the admin group for tenant setup or for first host setup.
    //
    if (bSetupHost == FALSE || bFirstNodeBootstrap == TRUE)
    {
        dwError = VmDirSrvCreateBuiltInAdminGroup( pSchemaCtx, pszBuiltInAdministratorsGroupName,
                                                   pszBuiltInAdministratorsGroupDN, pszUserDN,
                                                   pszAdminsGroupSid );
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    //
    // Create DCadmins/DCClients/CERTAdmins groups only for the very first
    // host setup.
    //
    if ( bSetupHost && bFirstNodeBootstrap )
    {
        // create DCAdmins Group
        dwError = VmDirAllocateStringAVsnprintf( &pszDCGroupDN,
                                                 "cn=%s,%s",
                                                 VMDIR_DC_GROUP_NAME,
                                                 pszBuiltInContainerDN);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = _VmDirSrvCreateBuiltInGroup( pSchemaCtx,
                                               VMDIR_DC_GROUP_NAME,
                                               pszDCGroupDN);
        BAIL_ON_VMDIR_ERROR(dwError);

        // create DCClients Group
        dwError = VmDirAllocateStringAVsnprintf( &pszDCClientGroupDN,
                                                 "cn=%s,%s",
                                                 VMDIR_DCCLIENT_GROUP_NAME,
                                                 pszBuiltInContainerDN);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = _VmDirSrvCreateBuiltInGroup( pSchemaCtx,
                                               VMDIR_DCCLIENT_GROUP_NAME,
                                               pszDCClientGroupDN);
        BAIL_ON_VMDIR_ERROR(dwError);

        // create CertAdmins Group
        dwError = VmDirAllocateStringAVsnprintf( &pszCertGroupDN,
                                                 "cn=%s,%s",
                                                 VMDIR_CERT_GROUP_NAME,
                                                 pszBuiltInContainerDN);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = _VmDirSrvCreateBuiltInCertGroup( pSchemaCtx,
                                                   VMDIR_CERT_GROUP_NAME,
                                                   pszCertGroupDN,
                                                   pszUserDN,           // member: default administrator
                                                   pszDCGroupDN,        // member: DCAdmins group
                                                   pszDCClientGroupDN); // member: DCClients group
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    // Set up SD for the entries created during instance set up
    // Default allows administrator VMDIR_ENTRY_ALL_ACCESS,
    // oneself VMDIR_ENTRY_GENERIC_WRITE
    dwError = VmDirSrvCreateDefaultSecDescRel( pszUserDN, pszAdminsGroupSid,
                                               &pSecDescRel, &ulSecDescRel, &SecInfo);
    BAIL_ON_VMDIR_ERROR(dwError);

    // add the same sd for all the objects created during instance set-up

    // Set SD for the Domain objects
    for (i = (int) VmDirStringLenA(pszDomainDN) - 1; i >= 0; i-- )
    {
        if (i == 0 || pszDomainDN[i] == RDN_SEPARATOR_CHAR)
        {
            startOfRdnInd = (i == 0) ? 0 : i + 1 /* for , */;
            dwError = VmDirSetSecurityDescriptorForDn( (PSTR)pszDomainDN + startOfRdnInd, SecInfo, pSecDescRel, ulSecDescRel);
            BAIL_ON_VMDIR_ERROR(dwError);
        }
    }

    dwError = VmDirSetSecurityDescriptorForDn( (PSTR)pszDomainDN, SecInfo, pSecDescRel, ulSecDescRel);
    BAIL_ON_VMDIR_ERROR(dwError);

    // Set SD for the administrator object

    dwError = VmDirSetSecurityDescriptorForDn( pszUserDN, SecInfo, pSecDescRel, ulSecDescRel);
    BAIL_ON_VMDIR_ERROR(dwError);

    // Set SD for Users container

    dwError = VmDirSetSecurityDescriptorForDn( pszUsersContainerDN, SecInfo, pSecDescRel, ulSecDescRel);
    BAIL_ON_VMDIR_ERROR(dwError);

    // Set SD for Builtin container

    dwError = VmDirSetSecurityDescriptorForDn( pszBuiltInContainerDN, SecInfo, pSecDescRel, ulSecDescRel);
    BAIL_ON_VMDIR_ERROR(dwError);

    // Set SD for ForeignSecurityPrincipals container

    dwError = VmDirSetSecurityDescriptorForDn( pszFSPsContainerDN, SecInfo, pSecDescRel, ulSecDescRel);
    BAIL_ON_VMDIR_ERROR(dwError);

    if (bSetupHost == FALSE || bFirstNodeBootstrap == TRUE)
    {
        // Set SD for BuiltInUsers group

        dwError = VmDirSetSecurityDescriptorForDn( pszBuiltInUsersGroupDN, SecInfo, pSecDescRel, ulSecDescRel);
        BAIL_ON_VMDIR_ERROR(dwError);

        // Set SD for BuiltInAdministrators group

        dwError = VmDirSetSecurityDescriptorForDn( pszBuiltInAdministratorsGroupDN, SecInfo, pSecDescRel, ulSecDescRel);
        BAIL_ON_VMDIR_ERROR(dwError);

    }

    if ( bSetupHost && bFirstNodeBootstrap )
    {
        // Set SD for BuiltIn DC group
        dwError = VmDirSetSecurityDescriptorForDn( pszDCGroupDN, SecInfo, pSecDescRel, ulSecDescRel);
        BAIL_ON_VMDIR_ERROR(dwError);

        // Set SD for BuiltIn DCClients group
        dwError = VmDirSetSecurityDescriptorForDn(pszDCClientGroupDN, SecInfo, pSecDescRel, ulSecDescRel);
        BAIL_ON_VMDIR_ERROR(dwError);

        // Set SD for BuiltIn Cert group
        dwError = VmDirSetSecurityDescriptorForDn( pszCertGroupDN, SecInfo, pSecDescRel, ulSecDescRel);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    // Create default password and lockout policy
    dwError = VmDirSrvCreateDN( PASSWD_LOCKOUT_POLICY_DEFAULT_CN, pszDomainDN, &pszDefaultPasswdLockoutPolicyDN );
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirSrvCreateDefaultPasswdPolicy(pSchemaCtx, pszDefaultPasswdLockoutPolicyDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    // Set SD for Password lockout policy object
    dwError = VmDirSetSecurityDescriptorForDn( pszDefaultPasswdLockoutPolicyDN, SecInfo, pSecDescRel, ulSecDescRel);
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:

    VMDIR_SAFE_FREE_MEMORY(pszUsersContainerDN);
    VMDIR_SAFE_FREE_MEMORY(pszBuiltInContainerDN);
    VMDIR_SAFE_FREE_MEMORY(pszFSPsContainerDN);
    VMDIR_SAFE_FREE_MEMORY(pszUserDN);
    VMDIR_SAFE_FREE_MEMORY(pszBuiltInUsersGroupDN);
    VMDIR_SAFE_FREE_MEMORY(pszBuiltInAdministratorsGroupDN);
    VMDIR_SAFE_FREE_MEMORY(pszDefaultPasswdLockoutPolicyDN);
    VMDIR_SAFE_FREE_MEMORY(pszDCGroupDN);
    VMDIR_SAFE_FREE_MEMORY(pszDCClientGroupDN);
    VMDIR_SAFE_FREE_MEMORY(pszCertGroupDN);
    VMDIR_SAFE_FREE_MEMORY(pszTenantRealmName);

    VMDIR_SAFE_FREE_MEMORY(pSecDescRel);

    VMDIR_SAFE_FREE_MEMORY(pszAdminSid);
    VMDIR_SAFE_FREE_MEMORY(pszBuiltInUsersGroupSid);
    VMDIR_SAFE_FREE_MEMORY(pszAdminsGroupSid);
    VMDIR_SAFE_FREE_MEMORY(pszAdminUserKrbUPN);

    return dwError;

error:
    VmDirLog(LDAP_DEBUG_ANY, "VmDirSrvSetupDomainInstance failed. Error(%u)", dwError);
    goto cleanup;
}
Пример #25
0
/*
 * Read schema definition from file
 * We only care for
 *  attributetypes
 *  objectclasses
 *  ditcontentrules
 *  attributeindices
 */
DWORD
VmDirReadSchemaFile(
    PCSTR               pszSchemaFilePath,
    PVMDIR_STRING_LIST* ppAtStrList,
    PVMDIR_STRING_LIST* ppOcStrList,
    PVMDIR_STRING_LIST* ppCrStrList,
    PVMDIR_STRING_LIST* ppIdxStrList
    )
{
    DWORD dwError = 0;
    CHAR  pbuf[1024] = {0};
    FILE* fp = NULL;

    PVMDIR_STRING_LIST  pAtStrList = NULL;
    PVMDIR_STRING_LIST  pOcStrList = NULL;
    PVMDIR_STRING_LIST  pCrStrList = NULL;
    PVMDIR_STRING_LIST  pIdxStrList = NULL;

    if (!pszSchemaFilePath || !ppAtStrList || !ppOcStrList || !ppCrStrList || !ppIdxStrList)
    {
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER);
    }

    dwError = VmDirStringListInitialize(&pAtStrList, 2048);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirStringListInitialize(&pOcStrList, 512);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirStringListInitialize(&pCrStrList, 512);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirStringListInitialize(&pIdxStrList, 16);
    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;

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

        if (IS_ATTRIBUTETYPES_TAG(pbuf))
        {
            dwError = _VmDirReadOneDefFromFile(fp, pAtStrList);
            BAIL_ON_VMDIR_ERROR(dwError);
        }
        else if (IS_OBJECTCLASSES_TAG(pbuf))
        {
            dwError = _VmDirReadOneDefFromFile(fp, pOcStrList);
            BAIL_ON_VMDIR_ERROR(dwError);
        }
        else if (IS_CONTENTRULES_TAG(pbuf))
        {
            dwError = _VmDirReadOneDefFromFile(fp, pCrStrList);
            BAIL_ON_VMDIR_ERROR(dwError);
        }
        else if (IS_ATTRIBUTEINDICES_TAG(pbuf))
        {
            dwError = _VmDirReadOneDefFromFile(fp, pIdxStrList);
            BAIL_ON_VMDIR_ERROR(dwError);
        }
        else
        {
            continue;
        }
    }

    *ppAtStrList = pAtStrList;
    *ppOcStrList = pOcStrList;
    *ppCrStrList = pCrStrList;
    *ppIdxStrList = pIdxStrList;

cleanup:
    if (fp)
    {
        fclose(fp);
    }
    return dwError;

error:
    VmDirStringListFree(pAtStrList);
    VmDirStringListFree(pOcStrList);
    VmDirStringListFree(pCrStrList);
    VmDirStringListFree(pIdxStrList);
    goto cleanup;
}
Пример #26
0
static
DWORD
VmDirSrvModifyPersistedDSERoot(
    PVDIR_SCHEMA_CTX pSchemaCtx,
    PSTR             pszRootNamingContextDN,
    PSTR             pszConfigNamingContextDN,
    PSTR             pszSchemaNamingContextDN,
    PSTR             pszSubSchemaSubEntryDN,
    PSTR             pszServerDN,
    PSTR             pszDefaultAdminDN,
    PSTR             pszDCAccountDN,
    PSTR             pszDCAccountUPN,
    PSTR             pszDelObjsContainerDN,
    PSTR             pszSiteName
    )
{
    DWORD dwError = 0;
    PSTR ppszPersistedDSERootAttrs[] =
    {
            ATTR_ROOT_DOMAIN_NAMING_CONTEXT,    pszRootNamingContextDN,
            ATTR_DEFAULT_NAMING_CONTEXT,        pszRootNamingContextDN,
            ATTR_CONFIG_NAMING_CONTEXT,         pszConfigNamingContextDN,
            ATTR_SCHEMA_NAMING_CONTEXT,         pszSchemaNamingContextDN,
            ATTR_SUB_SCHEMA_SUB_ENTRY,          pszSubSchemaSubEntryDN,
            ATTR_NAMING_CONTEXTS,               pszRootNamingContextDN,
            ATTR_NAMING_CONTEXTS,               pszConfigNamingContextDN,
            ATTR_NAMING_CONTEXTS,               pszSchemaNamingContextDN,
            ATTR_SERVER_NAME,                   pszServerDN,
            ATTR_DEFAULT_ADMIN_DN,              pszDefaultAdminDN,
            ATTR_DC_ACCOUNT_DN,                 pszDCAccountDN,
            ATTR_DC_ACCOUNT_UPN,                pszDCAccountUPN,
            ATTR_DEL_OBJS_CONTAINER,            pszDelObjsContainerDN,
            ATTR_SITE_NAME,                     pszSiteName,
            NULL
    };

    VDIR_OPERATION  op = {0};
    PSTR            pszLocalErrMsg = NULL;
    VDIR_BERVALUE   bvDSERootDN = VDIR_BERVALUE_INIT;
    int             i = 0;

    dwError = VmDirInitStackOperation( &op, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_MODIFY, NULL );
    BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrMsg,
            "VmDirSrvModifyPersistedDSERoot: VmDirInitStackOperation failed with error code: %d.", dwError );

    // Setup target DN

    bvDSERootDN.lberbv.bv_val = PERSISTED_DSE_ROOT_DN;
    bvDSERootDN.lberbv.bv_len = VmDirStringLenA( bvDSERootDN.lberbv.bv_val );

    dwError = VmDirNormalizeDN( &bvDSERootDN, op.pSchemaCtx);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirBervalContentDup( &bvDSERootDN, &op.reqDn );
    BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrMsg,
            "VmDirSrvModifyPersistedDSERoot: BervalContentDup failed with error code: %d.", dwError );

    op.pBEIF = VmDirBackendSelect(op.reqDn.lberbv.bv_val);
    assert(op.pBEIF);

    dwError = VmDirBervalContentDup( &op.reqDn, &op.request.modifyReq.dn );
    BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrMsg,
                "VmDirSrvModifyPersistedDSERoot: BervalContentDup failed with error code: %d.", dwError );

    // Setup mods

    for (i = 0; ppszPersistedDSERootAttrs[i] != NULL; i += 2 )
    {
        dwError = VmDirAppendAMod( &op, MOD_OP_REPLACE,
                                   ppszPersistedDSERootAttrs[i],
                                   (int) VmDirStringLenA(ppszPersistedDSERootAttrs[i]),
                                   ppszPersistedDSERootAttrs[i + 1],
                                   VmDirStringLenA(ppszPersistedDSERootAttrs[i + 1]) );
        BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrMsg,
                    "VmDirSrvModifyPersistedDSERoot: VmDirAppendAMod failed with error code: %d.", dwError );
    }

    dwError = VmDirAppendAMod( &op, MOD_OP_DELETE, ATTR_INVOCATION_ID, ATTR_INVOCATION_ID_LEN,
                               gVmdirServerGlobals.invocationId.lberbv.bv_val,
                               gVmdirServerGlobals.invocationId.lberbv.bv_len );
    BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrMsg,
                    "VmDirSrvModifyPersistedDSERoot: VmDirAppendAMod failed with error code: %d.", dwError );

    // Modify

    dwError = VmDirInternalModifyEntry( &op );
    BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrMsg,
                "VmDirSrvModifyPersistedDSERoot: InternalModifyEntry failed. DN: %s, Error code: %d, Error string: %s",
                op.reqDn.lberbv.bv_val, dwError, VDIR_SAFE_STRING( op.ldapResult.pszErrMsg ) );

cleanup:

    VmDirFreeBervalContent(&bvDSERootDN);
    VmDirFreeOperationContent(&op);
    VMDIR_SAFE_FREE_MEMORY(pszLocalErrMsg);

    return dwError;

error:
    VmDirLog(LDAP_DEBUG_ANY, VDIR_SAFE_STRING(pszLocalErrMsg) );
    goto cleanup;
}
Пример #27
0
/* UnionCandidates: Take a union of 2 candidates lists.
 *
 */
static void
UnionCandidates(
    VDIR_CANDIDATES ** srcCandidates,
    VDIR_CANDIDATES ** dstCandidates)
{
    DWORD        dwError = 0;
    VDIR_CANDIDATES * resCandidates = NULL;
    int          i = 0;
    int          j = 0;

    VmDirLog( LDAP_DEBUG_TRACE, "UnionCandidates: Begin" );

    assert( srcCandidates != NULL && *srcCandidates != NULL && dstCandidates != NULL && *dstCandidates != NULL );
    assert( (*srcCandidates)->positive == (*dstCandidates)->positive );

    if ((*srcCandidates)->size == 0)
    {
        goto done;
    }
    if ((*dstCandidates)->size == 0)
    {
        DeleteCandidates( dstCandidates );
        *dstCandidates = *srcCandidates;
        *srcCandidates = NULL;
        goto done;
    }
    if ((*dstCandidates)->eIdsSorted == FALSE)
    {
        qsort ( (*dstCandidates)->eIds, (*dstCandidates)->size, sizeof( ENTRYID ), _VmDirCompareEntryIds );
        (*dstCandidates)->eIdsSorted = TRUE;
    }
    if ((*srcCandidates)->eIdsSorted == FALSE)
    {
        qsort ( (*srcCandidates)->eIds, (*srcCandidates)->size, sizeof( ENTRYID ), _VmDirCompareEntryIds );
        (*srcCandidates)->eIdsSorted = TRUE;
    }

    resCandidates = NewCandidates( (*srcCandidates)->size + (*dstCandidates)->size, (*srcCandidates)->positive );

    for (i = 0, j = 0; (i < (*srcCandidates)->size) && (j < (*dstCandidates)->size); )
    {
        if ((*srcCandidates)->eIds[i] < (*dstCandidates)->eIds[j])
        {
            dwError = VmDirAddToCandidates( resCandidates, (*srcCandidates)->eIds[i]);
            BAIL_ON_VMDIR_ERROR(dwError);
            i++;
            continue;
        }
        if ((*dstCandidates)->eIds[j] < (*srcCandidates)->eIds[i])
        {
            dwError = VmDirAddToCandidates( resCandidates, (*dstCandidates)->eIds[j]);
            BAIL_ON_VMDIR_ERROR(dwError);
            j++;
            continue;
        }
        dwError = VmDirAddToCandidates( resCandidates, (*dstCandidates)->eIds[j]);
        BAIL_ON_VMDIR_ERROR(dwError);
        i++;
        j++;
    }
    for (; i < (*srcCandidates)->size; i++)
    {
        dwError = VmDirAddToCandidates( resCandidates, (*srcCandidates)->eIds[i]);
        BAIL_ON_VMDIR_ERROR(dwError);
    }
    for (; j < (*dstCandidates)->size; j++)
    {
        dwError = VmDirAddToCandidates( resCandidates, (*dstCandidates)->eIds[j]);
        BAIL_ON_VMDIR_ERROR(dwError);
    }
    resCandidates->eIdsSorted = TRUE;

    DeleteCandidates( dstCandidates );
    *dstCandidates = resCandidates;

done:
    VmDirLog( LDAP_DEBUG_TRACE, "UnionCandidates: End" );

    return;

error:

    DeleteCandidates( dstCandidates );
    resCandidates->size = 0;
    *dstCandidates = resCandidates;

    goto done;
}
Пример #28
0
static
VOID
_VdcadminClientTestSimpleSSLBind(
    PCSTR   pszLDAPSURI,
    PCSTR   pszDefaultBindDN,
    PCSTR   pszDefaultPasswd
    )
{
    DWORD   dwError = 0;
    int     ldap_version_3 = LDAP_VERSION3;
    int     iTLSNever = LDAP_OPT_X_TLS_NEVER;
    int     iTLSMin = LDAP_OPT_X_TLS_PROTOCOL_TLS1_0;
    LDAP *  pLD = NULL;
    BerValue    ldapBindPwd = {0};

    dwError = ldap_initialize( &pLD, pszLDAPSURI );
    /* Set LDAP V3 protocol version */
    ldap_set_option( pLD, LDAP_OPT_PROTOCOL_VERSION, &ldap_version_3 );
    ldap_set_option(NULL, LDAP_OPT_X_TLS_PROTOCOL_MIN, &iTLSMin);
    ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &iTLSNever);

    dwError = ldap_sasl_bind_s(    pLD,
                                   "",
                                   LDAP_SASL_SIMPLE,
                                   &ldapBindPwd,  // no credentials
                                   NULL,
                                   NULL,
                                   NULL);
    BAIL_ON_VMDIR_ERROR(dwError);
    printf("%s (ANONYMOUS) bind succeeded.\n", pszLDAPSURI);

    ldapBindPwd.bv_val = (PSTR)pszDefaultPasswd;
    ldapBindPwd.bv_len = strlen( pszDefaultPasswd );
    dwError = ldap_sasl_bind_s(    pLD,
                                   pszDefaultBindDN,
                                   LDAP_SASL_SIMPLE,
                                   &ldapBindPwd,  // ldaps with credentials
                                   NULL,
                                   NULL,
                                   NULL);
    BAIL_ON_VMDIR_ERROR(dwError);
    printf("%s (%s) bind succeeded.\n\n", pszLDAPSURI, VDIR_SAFE_STRING(pszDefaultBindDN) );

cleanup:

    if (pLD)
    {
        dwError = ldap_unbind_ext_s(    pLD,
                                        NULL,
                                        NULL);
    }

    return;

error:

    printf("\n\n++++++++++++++++++++ %s SSL bind failed. (%d)(%s)\n\n",
           pszLDAPSURI, dwError, ldap_err2string(dwError));

    goto cleanup;
}
Пример #29
0
/*
 *    Bootstrap initial schema from default data.
 *    Not a full schema as ones that initialize from file or entry,
 *    but with limited information that we can bootstrap schema entry from
 *    data store or file.
 *    1.  pSchema->ats.pSortName (in sort order)
 *    1.1 pSchema->ats.pSortName(pszName, usIdMap)
 *    2.  pSchema->ats.dwNumATs
 *    3.  pSchema->ats.ppSortIdMap (in sort order)
 *    4.  pSchema-> bIsBootStrapSchema = TRUE
 *    5.  pSchema->usNextId = 100
 *
 *    gVdirSchemaGlobals.pInstances[0] = bootstrap schema
 *
 */
DWORD
VmDirSchemaLibInit(
    VOID
    )
{
    BOOLEAN bInLock = FALSE;
    DWORD   dwError = 0;
    DWORD   dwCnt = 0;
    PVDIR_SCHEMA_INSTANCE pSchema = NULL;

    PSTR OCTable[] = VDIR_SCHEMA_BOOTSTRP_OC_INITIALIZER;
    VDIR_SCHEMA_BOOTSTRAP_TABLE ATTable[] = VDIR_SCHEMA_BOOTSTRP_ATTR_INITIALIZER;

    // initialize gVdirSchemaGlobals
    dwError = VmDirAllocateMutex(&gVdirSchemaGlobals.mutex);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VdirSchemaInstanceAllocate(   &pSchema,
                                            sizeof(ATTable)/sizeof(ATTable[0]),
                                            sizeof(OCTable)/sizeof(OCTable[0]),
                                            0,  // no content rule in bootstrap
                                            0,  // no structure rule in bootstrap
                                            0); // no fnameforma in bootstrap
    BAIL_ON_VMDIR_ERROR(dwError);

    for (dwCnt = 0 ; dwCnt < sizeof(ATTable)/sizeof(ATTable[0]); dwCnt++)
    {
        dwError = VmDirSchemaParseStrToATDesc(
                ATTable[dwCnt].pszDesc,
                pSchema->ats.pATSortName+dwCnt);
        BAIL_ON_VMDIR_ERROR(dwError);

        pSchema->ats.pATSortName[dwCnt].usAttrID = ATTable[dwCnt].usAttrID;
    }

    qsort(pSchema->ats.pATSortName,
          pSchema->ats.usNumATs,
          sizeof(VDIR_SCHEMA_AT_DESC),
          VdirSchemaPATNameCmp);

    dwError = VmDirAllocateMemory(
            sizeof(PVDIR_SCHEMA_AT_DESC) * pSchema->ats.usNumATs,
            (PVOID*)&pSchema->ats.ppATSortIdMap);
    BAIL_ON_VMDIR_ERROR(dwError);

    for (dwCnt = 0 ; dwCnt < sizeof(ATTable)/sizeof(ATTable[0]); dwCnt++)
    {
        pSchema->ats.ppATSortIdMap[pSchema->ats.pATSortName[dwCnt].usAttrID -1] =
                &pSchema->ats.pATSortName[dwCnt];
    }

    pSchema-> bIsBootStrapSchema = TRUE;
    pSchema->ats.usNextId = MAX_RESERVED_ATTR_ID_MAP + 1;

    dwError = VdirSyntaxLoad();
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VdirMatchingRuleLoad();
    BAIL_ON_VMDIR_ERROR(dwError);

    VMDIR_LOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex);

    gVdirSchemaGlobals.pSchema = pSchema;
    dwError = VdirSchemaCtxAcquireInLock(TRUE, &gVdirSchemaGlobals.pCtx); // add self reference
    BAIL_ON_VMDIR_ERROR(dwError);

    assert(gVdirSchemaGlobals.pCtx);

    VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "Startup bootstrap schema instance (%p)", gVdirSchemaGlobals.pSchema);

cleanup:

    VMDIR_UNLOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex);

    return dwError;

error:

    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "VmDirSchemaLibInit failed (%d)", dwError);

    gVdirSchemaGlobals.pSchema = NULL;

    if (pSchema)
    {
        VdirSchemaInstanceFree(pSchema);
    }

    goto cleanup;
}
Пример #30
0
DWORD
VmDirLdapSchemaInit(
    PVDIR_LDAP_SCHEMA*  ppSchema
    )
{
    DWORD   dwError = 0;
    PVDIR_LDAP_SCHEMA   pSchema = NULL;

    if (!ppSchema)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = VmDirAllocateMemory(
            sizeof(VDIR_LDAP_SCHEMA),
            (PVOID*)&pSchema);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = LwRtlCreateHashMap(&pSchema->attributeTypes,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = LwRtlCreateHashMap(&pSchema->objectClasses,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = LwRtlCreateHashMap(&pSchema->contentRules,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = LwRtlCreateHashMap(&pSchema->structureRules,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = LwRtlCreateHashMap(&pSchema->nameForms,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    *ppSchema = pSchema;

cleanup:
    return dwError;

error:
    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL,
            "%s failed, error (%d)", __FUNCTION__, dwError );

    VmDirFreeLdapSchema(pSchema);
    goto cleanup;
}