Example #1
0
DWORD
VmDirMDBSimpleDnToEntry(
    PSTR        pszEntryDN,
    PVDIR_ENTRY pEntry
    )
{
    DWORD               dwError = 0;
    PVDIR_SCHEMA_CTX    pSchemaCtx = NULL;
    VDIR_BERVALUE       entryDn = VDIR_BERVALUE_INIT;
    VDIR_BACKEND_CTX    mdbBECtx = {0};
    BOOLEAN             bHasTxn = FALSE;

    assert(pEntry);

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

    entryDn.lberbv.bv_val = pszEntryDN;
    entryDn.lberbv.bv_len = VmDirStringLenA(entryDn.lberbv.bv_val);

    dwError = VmDirMDBTxnBegin(&mdbBECtx, VDIR_BACKEND_TXN_READ);
    BAIL_ON_VMDIR_ERROR(dwError);
    bHasTxn = TRUE;

    dwError = VmDirMDBDNToEntry(    &mdbBECtx,
                                    pSchemaCtx,
                                    &entryDn,
                                    pEntry,
                                    VDIR_BACKEND_ENTRY_LOCK_READ);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirMDBTxnCommit(&mdbBECtx);
    bHasTxn = FALSE;
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:

    if (pSchemaCtx)
    {
        VmDirSchemaCtxRelease(pSchemaCtx);
    }

    mdbBECtx.pBEPrivate = NULL;
    VmDirBackendCtxContentFree(&mdbBECtx);
    VmDirFreeBervalContent(&entryDn);

    return dwError;

error:

    if (bHasTxn)
    {
        VmDirMDBTxnAbort(&mdbBECtx);
    }

    goto cleanup;
}
Example #2
0
static
DWORD
_VmGetHighestCommittedUSN(
    PSTR*   ppszHighestCommittedUSN
    )
{
    DWORD               dwError = 0;
    USN                 usn = 0;
    USN                 nextUSN = 0;
    VDIR_ENTRY_ARRAY    entryArray = {0};
    PSTR                pszUSN = NULL;
    VDIR_BACKEND_CTX    beCtx = {0};

    beCtx.pBE = VmDirBackendSelect(NULL);
    assert(beCtx.pBE);

    dwError = beCtx.pBE->pfnBEGetNextUSN(&beCtx, &nextUSN);
    BAIL_ON_VMDIR_ERROR(dwError);

    for (usn=nextUSN; usn > 1LL; usn--)
    {
        VMDIR_SAFE_FREE_MEMORY(pszUSN);
        VmDirFreeEntryArrayContent(&entryArray);

        dwError = VmDirAllocateStringPrintf(&pszUSN, "%" PRId64, usn);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = VmDirSimpleEqualFilterInternalSearch(
                    "", LDAP_SCOPE_SUBTREE, ATTR_USN_CHANGED, pszUSN, &entryArray);
        BAIL_ON_VMDIR_ERROR(dwError);

        if (entryArray.iSize == 1 )
        {
            break;
        }
    }

    if (usn == 0)
    {
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_STATE);
    }

    *ppszHighestCommittedUSN = pszUSN;
    pszUSN = NULL;

cleanup:
    VMDIR_SAFE_FREE_MEMORY(pszUSN);
    VmDirFreeEntryArrayContent(&entryArray);
    VmDirBackendCtxContentFree(&beCtx);

    return dwError;

error:
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "error (%u), start USN %" PRId64, dwError, nextUSN);
    goto cleanup;
}
Example #3
0
DWORD
VmDirMDBSimpleEIdToEntry(
    PVDIR_BACKEND_INTERFACE pBE,
    ENTRYID         eId,
    PVDIR_ENTRY     pEntry)
{
    DWORD               dwError = 0;
    PVDIR_SCHEMA_CTX    pSchemaCtx = NULL;
    VDIR_BACKEND_CTX    mdbBECtx = {0};
    BOOLEAN             bHasTxn = FALSE;

    assert(pBE && pEntry);

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

    mdbBECtx.pBE = pBE;

    dwError = VmDirMDBTxnBegin(&mdbBECtx, VDIR_BACKEND_TXN_READ, &bHasTxn);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirMDBEIdToEntry(   &mdbBECtx,
                                    pSchemaCtx,
                                    eId,
                                    pEntry,
                                    VDIR_BACKEND_ENTRY_LOCK_READ);
    BAIL_ON_VMDIR_ERROR(dwError);

    if (bHasTxn)
    {
        dwError = VmDirMDBTxnCommit(&mdbBECtx);
        bHasTxn = FALSE;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

cleanup:

    if (pSchemaCtx)
    {
        VmDirSchemaCtxRelease(pSchemaCtx);
    }

    VmDirBackendCtxContentFree(&mdbBECtx);

    return dwError;

error:

    if (bHasTxn)
    {
        VmDirMDBTxnAbort(&mdbBECtx);
    }

    goto cleanup;
}
Example #4
0
static
int
_VmDirSwapDB(
    PCSTR dbHomeDir,
    BOOLEAN bHasXlog)
{
    int                     retVal = LDAP_SUCCESS;
    char                    dbExistingName[VMDIR_MAX_FILE_NAME_LEN] = {0};
    char                    dbNewName[VMDIR_MAX_FILE_NAME_LEN] = {0};
    PSTR                    pszLocalErrorMsg = NULL;
    int                     errorCode = 0;
    BOOLEAN                 bLegacyDataLoaded = FALSE;
    PVDIR_BACKEND_INTERFACE pBE = NULL;

#ifndef _WIN32
    const char   fileSeperator = '/';
#else
    const char   fileSeperator = '\\';
#endif

    // Shutdown backend
    pBE = VmDirBackendSelect(NULL);
    assert(pBE);

    VmDirdStateSet(VMDIRD_STATE_SHUTDOWN);

    VmDirIndexLibShutdown();

    VmDirSchemaLibShutdown();

    pBE->pfnBEShutdown();
    VmDirBackendContentFree(pBE);

    // move .mdb files
    retVal = VmDirStringPrintFA( dbExistingName, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s%c%s", dbHomeDir, fileSeperator,
                                 LOCAL_PARTNER_DIR, fileSeperator, VMDIR_MDB_DATA_FILE_NAME);
    BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
            "_VmDirSwapDB: VmDirStringPrintFA() call failed with error: %d", retVal );

    retVal = VmDirStringPrintFA( dbNewName, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s", dbHomeDir, fileSeperator,
                                 VMDIR_MDB_DATA_FILE_NAME );
    BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
            "_VmDirSwapDB: VmDirStringPrintFA() call failed with error: %d", retVal );

#ifdef WIN32
    if (MoveFileEx(dbExistingName, dbNewName, MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING) == 0)
    {
        retVal = LDAP_OPERATIONS_ERROR;
        errorCode = GetLastError();
#else
    if (rename(dbExistingName, dbNewName) != 0)
    {
        retVal = LDAP_OPERATIONS_ERROR;
        errorCode = errno;
#endif
        BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
            "_VmDirSwapDB: rename file from %s to %s failed, errno %d", dbExistingName, dbNewName, errorCode );
    }

    retVal = VmDirStringPrintFA(dbNewName, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s%c%s", dbHomeDir, fileSeperator, VMDIR_MDB_XLOGS_DIR_NAME);
    BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
            "_VmDirSwapDB: VmDirStringPrintFA() call failed with error: %d", retVal );

    if (bHasXlog)
    {
        //move xlog directory
        retVal = VmDirStringPrintFA(dbExistingName, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s%c%s", dbHomeDir, fileSeperator,
                                    LOCAL_PARTNER_DIR, fileSeperator, VMDIR_MDB_XLOGS_DIR_NAME);
        BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
                "_VmDirSwapDB: VmDirStringPrintFA() call failed with error: %d", retVal );

#ifdef     WIN32
        if (MoveFileEx(dbExistingName, dbNewName, MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING) == 0)
        {
            retVal = LDAP_OPERATIONS_ERROR;
            errorCode = GetLastError();
#else
        if (rmdir(dbNewName) != 0)
        {
            retVal = LDAP_OPERATIONS_ERROR;
            errorCode = errno;
            BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg), "_VmDirSwapDB cannot remove directory %s, errno %d",
                                         dbNewName, errorCode);
        }

        if (rename(dbExistingName, dbNewName) != 0)
        {
            retVal = LDAP_OPERATIONS_ERROR;
            errorCode = errno;
#endif
            BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg), "_VmDirSwapDB cannot move directory from %s to %s, errno %d",
                                         dbNewName, dbExistingName, errorCode);
        }
    }

    retVal = VmDirStringPrintFA(dbExistingName, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s", dbHomeDir, fileSeperator, LOCAL_PARTNER_DIR);
    BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
            "_VmDirSwapDB: VmDirStringPrintFA() call failed with error: %d", retVal );

#ifdef WIN32
    if (RemoveDirectory(dbExistingName)==0)
    {
        errorCode = GetLastError();
#else
    if (rmdir(dbExistingName))
    {
        errorCode = errno;
#endif

        VMDIR_LOG_WARNING(VMDIR_LOG_MASK_ALL, "cannot remove directory %s errno %d", dbExistingName, errorCode);
    }

    VmDirdStateSet(VMDIRD_STATE_STARTUP);

    retVal = VmDirInitBackend(&bLegacyDataLoaded);
    BAIL_ON_VMDIR_ERROR(retVal);

    if (bLegacyDataLoaded)
    {
        retVal = VmDirPatchLocalSubSchemaSubEntry();
        BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrorMsg,
                "_VmDirSwapDB: failed to patch subschema subentry: %d", retVal );

        retVal = VmDirWriteSchemaObjects();
        BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrorMsg,
                "_VmDirSwapDB: failed to create schema tree: %d", retVal );
    }

    VmDirdStateSet(VMDIRD_STATE_NORMAL);

cleanup:
    VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg);
    return retVal;

error:
    retVal = LDAP_OPERATIONS_ERROR;
    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s", VDIR_SAFE_STRING(pszLocalErrorMsg) );
    goto cleanup;
}

static
int
_VmDirWrapUpFirstReplicationCycle(
    PCSTR                           pszHostname,
    VMDIR_REPLICATION_AGREEMENT *   pReplAgr)
{
    int                 retVal = LDAP_SUCCESS;
    PVDIR_ENTRY         pPartnerServerEntry = NULL;
    PVDIR_ATTRIBUTE     pAttrUpToDateVector = NULL;
    PVDIR_ATTRIBUTE     pAttrInvocationId = NULL;
    USN                 localUsn = 0;
    USN                 partnerLocalUsn = 0;
    char                partnerlocalUsnStr[VMDIR_MAX_USN_STR_LEN];
    VDIR_BACKEND_CTX    beCtx = {0};
    struct berval       syncDoneCtrlVal = {0};
    PVDIR_SCHEMA_CTX    pSchemaCtx = NULL;
    VDIR_OPERATION      searchOp = {0};
    PVDIR_FILTER        pSearchFilter = NULL;
    PSTR                pszSeparator = NULL;

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

    retVal = VmDirInitStackOperation( &searchOp, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_SEARCH, pSchemaCtx );
    BAIL_ON_VMDIR_ERROR(retVal);

    searchOp.pBEIF = VmDirBackendSelect(NULL);
    assert(searchOp.pBEIF);

    searchOp.reqDn.lberbv.bv_val = "";
    searchOp.reqDn.lberbv.bv_len = 0;
    searchOp.request.searchReq.scope = LDAP_SCOPE_SUBTREE;

    retVal = VmDirConcatTwoFilters(searchOp.pSchemaCtx, ATTR_CN, (PSTR) pszHostname, ATTR_OBJECT_CLASS, OC_DIR_SERVER,
                                    &pSearchFilter);
    BAIL_ON_VMDIR_ERROR(retVal);

    searchOp.request.searchReq.filter = pSearchFilter;

    retVal = VmDirInternalSearch(&searchOp);
    BAIL_ON_VMDIR_ERROR(retVal);

    if (searchOp.internalSearchEntryArray.iSize != 1)
    {
        VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL,
                    "_VmDirWrapUpFirstReplicationCycle: Unexpected (not 1) number of partner server entries found (%d)",
                    searchOp.internalSearchEntryArray.iSize );
        retVal = LDAP_OPERATIONS_ERROR;
        BAIL_ON_VMDIR_ERROR(retVal);
    }

    pPartnerServerEntry = searchOp.internalSearchEntryArray.pEntry;

    pAttrUpToDateVector = VmDirEntryFindAttribute( ATTR_UP_TO_DATE_VECTOR, pPartnerServerEntry );

    pAttrInvocationId = VmDirEntryFindAttribute( ATTR_INVOCATION_ID, pPartnerServerEntry );
    assert( pAttrInvocationId != NULL );

    beCtx.pBE = VmDirBackendSelect(NULL);
    assert(beCtx.pBE);

    if ((retVal = beCtx.pBE->pfnBEGetNextUSN( &beCtx, &localUsn )) != 0)
    {
        VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "_VmDirWrapUpFirstReplicationCycle: pfnBEGetNextUSN failed with error code: %d, "
                  "error message: %s", retVal, VDIR_SAFE_STRING(beCtx.pszBEErrorMsg) );
        BAIL_ON_VMDIR_ERROR( retVal );
    }

    retVal = _VmGetHighestCommittedUSN(localUsn, &partnerLocalUsn);
    BAIL_ON_VMDIR_ERROR( retVal );

    VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "_VmDirWrapUpFirstReplicationCycle: partnerLocalUsn %llu locaUsn %llu", partnerLocalUsn, localUsn);

    if ((retVal = VmDirStringNPrintFA( partnerlocalUsnStr, sizeof(partnerlocalUsnStr), sizeof(partnerlocalUsnStr) - 1,
                                       "%" PRId64, partnerLocalUsn)) != 0)
    {
        VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "_VmDirWrapUpFirstReplicationCycle: VmDirStringNPrintFA failed with error code: %d",
                  retVal );
        BAIL_ON_VMDIR_ERROR( retVal );
    }

    if (pAttrUpToDateVector)
    {
        if (VmDirStringEndsWith( pAttrUpToDateVector->vals[0].lberbv.bv_val, ",", FALSE))
        {
            pszSeparator = "";
        }
        else
        {
            pszSeparator = ",";
        }

        // <partnerLocalUSN>,<partner up-to-date vector>,<partner server GUID>:<partnerLocalUSN>,
        retVal = VmDirAllocateStringPrintf( &(syncDoneCtrlVal.bv_val), "%s,%s%s%s:%s,",
                                                partnerlocalUsnStr,
                                                pAttrUpToDateVector->vals[0].lberbv.bv_val,
                                                pszSeparator,
                                                pAttrInvocationId->vals[0].lberbv.bv_val,
                                                partnerlocalUsnStr);
        BAIL_ON_VMDIR_ERROR(retVal);
    }
    else
    {
        // <partnerLocalUSN>,<partner server GUID>:<partnerLocalUSN>,
        retVal = VmDirAllocateStringPrintf( &(syncDoneCtrlVal.bv_val), "%s,%s:%s,",
                                                partnerlocalUsnStr,
                                                pAttrInvocationId->vals[0].lberbv.bv_val,
                                                partnerlocalUsnStr);
        BAIL_ON_VMDIR_ERROR(retVal);
    }

    VmDirSetACLMode();

    syncDoneCtrlVal.bv_len = VmDirStringLenA(syncDoneCtrlVal.bv_val);

    if ((retVal = VmDirReplUpdateCookies( pSchemaCtx, &(syncDoneCtrlVal), pReplAgr )) != LDAP_SUCCESS)
    {
        VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "vdirReplicationThrFun: UpdateCookies failed. Error: %d", retVal );
        BAIL_ON_VMDIR_ERROR( retVal );
    }

    if ((retVal = _VmDirPatchDSERoot(pSchemaCtx)) != LDAP_SUCCESS)
    {
        VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "vdirReplicationThrFun: _VmDirPatchDSERoot failed. Error: %d", retVal );
        BAIL_ON_VMDIR_ERROR( retVal );
    }

cleanup:
    VmDirFreeOperationContent(&searchOp);
    VmDirBackendCtxContentFree(&beCtx);
    VMDIR_SAFE_FREE_MEMORY(syncDoneCtrlVal.bv_val);
    VmDirSchemaCtxRelease(pSchemaCtx);
    return retVal;

error:
    retVal = LDAP_OPERATIONS_ERROR;
    goto cleanup;
}

#ifndef VDIR_PSC_VERSION
#define VDIR_PSC_VERSION "6.7.0"
#endif

static
int
_VmDirPatchDSERoot(
    PVDIR_SCHEMA_CTX    pSchemaCtx)
{
    int                      retVal = LDAP_SUCCESS;
    VDIR_OPERATION           op = {0};
    VDIR_BERVALUE            bvDSERootDN = VDIR_BERVALUE_INIT;

    VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "_VmDirPatchDSERoot: Begin" );

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

    retVal = VmDirInitStackOperation( &op,
                                      VDIR_OPERATION_TYPE_INTERNAL,
                                      LDAP_REQ_MODIFY,
                                      pSchemaCtx );
    BAIL_ON_VMDIR_ERROR(retVal);

    retVal = VmDirNormalizeDN( &bvDSERootDN, pSchemaCtx);
    BAIL_ON_VMDIR_ERROR(retVal);

    retVal = VmDirBervalContentDup( &bvDSERootDN, &op.reqDn );
    BAIL_ON_VMDIR_ERROR(retVal);

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

    if (VmDirBervalContentDup( &op.reqDn, &op.request.modifyReq.dn ) != 0)
    {
        VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "_VmDirPatchDSERoot: BervalContentDup failed." );
        BAIL_ON_VMDIR_ERROR( retVal );
    }

    retVal = VmDirAppendAMod( &op, MOD_OP_REPLACE, ATTR_DC_ACCOUNT_UPN, ATTR_DC_ACCOUNT_UPN_LEN,
                              gVmdirServerGlobals.dcAccountUPN.lberbv.bv_val,
                              gVmdirServerGlobals.dcAccountUPN.lberbv.bv_len );
    BAIL_ON_VMDIR_ERROR( retVal );

    retVal = VmDirAppendAMod( &op, MOD_OP_REPLACE, ATTR_DC_ACCOUNT_DN, ATTR_DC_ACCOUNT_DN_LEN,
                              gVmdirServerGlobals.dcAccountDN.lberbv.bv_val,
                              gVmdirServerGlobals.dcAccountDN.lberbv.bv_len );
    BAIL_ON_VMDIR_ERROR( retVal );

    retVal = VmDirAppendAMod( &op, MOD_OP_REPLACE, ATTR_SERVER_NAME, ATTR_SERVER_NAME_LEN,
                              gVmdirServerGlobals.serverObjDN.lberbv.bv_val,
                              gVmdirServerGlobals.serverObjDN.lberbv.bv_len );
    BAIL_ON_VMDIR_ERROR( retVal );

    retVal = VmDirAppendAMod( &op, MOD_OP_REPLACE, ATTR_SITE_NAME, ATTR_SITE_NAME_LEN,
                              gVmdirServerGlobals.pszSiteName,
                              VmDirStringLenA(gVmdirServerGlobals.pszSiteName) );
    BAIL_ON_VMDIR_ERROR( retVal );

    retVal = VmDirAppendAMod( &op, MOD_OP_REPLACE, ATTR_PSC_VERSION, ATTR_PSC_VERSION_LEN,
                              VDIR_PSC_VERSION,
                              VmDirStringLenA(VDIR_PSC_VERSION) );
    BAIL_ON_VMDIR_ERROR( retVal );

    retVal = VmDirAppendAMod( &op, MOD_OP_REPLACE, ATTR_MAX_DOMAIN_FUNCTIONAL_LEVEL,
                              ATTR_MAX_DOMAIN_FUNCTIONAL_LEVEL_LEN,
                              VMDIR_MAX_DFL_STRING,
                              VmDirStringLenA(VMDIR_MAX_DFL_STRING) );
    BAIL_ON_VMDIR_ERROR( retVal );

    if ((retVal = VmDirInternalModifyEntry( &op )) != 0)
    {
        // If VmDirInternall call failed, reset retVal to LDAP level error space (for B/C)
        retVal = op.ldapResult.errCode;

        VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "_VmDirPatchDSERoot: InternalModifyEntry failed. "
                  "Error code: %d, Error string: %s", retVal, VDIR_SAFE_STRING( op.ldapResult.pszErrMsg ) );
        BAIL_ON_VMDIR_ERROR( retVal );
    }

cleanup:
    VmDirFreeOperationContent(&op);

    VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "_VmDirPatchDSERoot: End" );
    return retVal;

error:
    retVal = LDAP_OPERATIONS_ERROR;
    goto cleanup;
}
Example #5
0
static int
ParseSyncRequestControlVal(
    VDIR_OPERATION *            op,
    BerValue *                  controlValue,       // Input: control value encoded as ber
    SyncRequestControlValue *   syncReqCtrlVal,     // Output
    VDIR_LDAP_RESULT *          lr                  // Output
    )
{
    int                     retVal = LDAP_SUCCESS;
    ber_tag_t               tag = LBER_ERROR;
    ber_len_t               len = 0;
    UptoDateVectorEntry *   utdVectorEntry = NULL;
    BerElementBuffer        berbuf;
    BerElement *            ber = (BerElement *)&berbuf;
    PSTR                    pszLocalErrorMsg = NULL;
    VDIR_BACKEND_CTX        backendCtx = {0};
    USN                     maxPartnerVisibleUSN = 0;

    VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "ParseSyncRequestControlVal: Begin." );

    ber_init2( ber, controlValue, LBER_USE_DER );

    /* http://www.rfc-editor.org/rfc/rfc4533.txt
     *
     *  syncCookie ::= OCTET STRING
     *
     *  syncRequestValue ::= SEQUENCE {
     *          mode ENUMERATED {
     *              -- 0 unused
     *              refreshOnly       (1),
     *              -- 2 reserved
     *              refreshAndPersist (3)
     *          },
     *          cookie     syncCookie OPTIONAL,
     *          reloadHint BOOLEAN DEFAULT FALSE
     *  }
    */

    if (ber_scanf( ber, "{i", &(syncReqCtrlVal->mode) ) == LBER_ERROR)
    {
        VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "ParseSyncRequestControlVal: ber_scanf failed while parsing the sync request "
                  "control mode" );
        lr->errCode = LDAP_PROTOCOL_ERROR;
        retVal = LDAP_NOTICE_OF_DISCONNECT;
        BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                        "Error in reading sync request control mode from PDU.");
    }

    syncReqCtrlVal->bvLastLocalUsnProcessed.lberbv.bv_val = "";
    syncReqCtrlVal->intLastLocalUsnProcessed = 0;

    if (VmDirAllocateMemory( sizeof( VDIR_LDAP_CONTROL ), (PVOID *)&op->syncDoneCtrl) != 0)
    {
        VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "ParseSyncRequestControlVal: VmDirAllocateMemory failed " );
        lr->errCode = retVal = LDAP_OPERATIONS_ERROR;
        BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                        "ParseSyncRequestControlVal: VmDirAllocateMemory failed.");
    }
    op->syncDoneCtrl->type = LDAP_CONTROL_SYNC_DONE;
    if (LwRtlCreateHashTable( &op->syncDoneCtrl->value.syncDoneCtrlVal.htUtdVector, UtdVectorEntryGetKey,
                              LwRtlHashDigestPstr, LwRtlHashEqualPstr, NULL, VMDIR_UTD_VECTOR_HASH_TABLE_SIZE ) != 0)
    {
        VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "UpdateSyncDoneUtdVectorEntry: LwRtlCreateHashTable failed" );
        lr->errCode = retVal = LDAP_OPERATIONS_ERROR;
        BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                        "UpdateSyncDoneUtdVectorEntry: LwRtlCreateHashTable failed");

    }

    tag = ber_peek_tag( ber, &len );

    if (tag == LBER_SEQUENCE)
    { // syncCookie

        /* syncCookie ::= SEQUENCE {
         *                      reqServerId             LDAPString,
         *                      lastLocalUsnProcessed   INTEGER (0 .. maxInt),
         *                      utdVector               UptoDateVectorEntryList }
         *
         *   UptoDateVectorEntryList ::= SEQUENCE OF uptoDateVectorEntry UptoDateVectorEntry
         *
         *   UptoDateVectorEntry ::= SEQUENCE {
         *                            serverId              LDAPString,
         *                            lastOrigUsnProcessed  INTEGER (0 .. maxInt) }
         */
        // {lastLocalUsnProcessed{{<serverid1><lastOrigUsnProcessed1>}{<serverid2><lastOrigUsnProcessed2>}...}}

        if (ber_scanf( ber, "{mmm}",
                        &syncReqCtrlVal->reqInvocationId.lberbv,
                        &syncReqCtrlVal->bvLastLocalUsnProcessed.lberbv,
                        &syncReqCtrlVal->bvUtdVector.lberbv ) == LBER_ERROR )
        {
            VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "ParseSyncRequestControlVal: ber_scanf failed while parsing "
                      "lastLocalUsnProcessed in the sync request control value" );
            lr->errCode = LDAP_PROTOCOL_ERROR;
            retVal = LDAP_NOTICE_OF_DISCONNECT;
            BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                            "Error in reading lastLocalUsnProcessed in the sync request control value");
        }

        VMDIR_LOG_DEBUG( LDAP_DEBUG_REPL, "ParseSyncRequestControlVal: ServerId: %s, lastLocalUsnProcessed: %s, utdVector: %s",
                  syncReqCtrlVal->reqInvocationId.lberbv.bv_val, syncReqCtrlVal->bvLastLocalUsnProcessed.lberbv.bv_val,
                  syncReqCtrlVal->bvUtdVector.lberbv.bv_val );

        syncReqCtrlVal->intLastLocalUsnProcessed = op->syncDoneCtrl->value.syncDoneCtrlVal.intLastLocalUsnProcessed =
                                   VmDirStringToLA( syncReqCtrlVal->bvLastLocalUsnProcessed.lberbv.bv_val, NULL, 10 );
        {
            char *                  nextServerIdStr = NULL;
            char *                  nextOrigUsnStr = NULL;

            nextServerIdStr = syncReqCtrlVal->bvUtdVector.lberbv.bv_val;

            while( nextServerIdStr != NULL && nextServerIdStr[0] != '\0')
            {
                PLW_HASHTABLE_NODE pNode = NULL;

                if (VmDirAllocateMemory( sizeof(UptoDateVectorEntry), (PVOID *)&utdVectorEntry ) != 0)
                {
                    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "ParseSyncRequestControlVal: VmDirAllocateMemory failed " );
                    lr->errCode = retVal = LDAP_OPERATIONS_ERROR;
                    BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                                    "ParseSyncRequestControlVal: VmDirAllocateMemory failed");
                }

                nextOrigUsnStr = VmDirStringChrA( nextServerIdStr, ':');
                *nextOrigUsnStr = '\0';
                nextOrigUsnStr++;
                utdVectorEntry->invocationId.lberbv.bv_val = nextServerIdStr;
                utdVectorEntry->invocationId.lberbv.bv_len = VmDirStringLenA( nextServerIdStr );

                nextServerIdStr = VmDirStringChrA( nextOrigUsnStr, ',');
                *nextServerIdStr = '\0';
                nextServerIdStr++;

                utdVectorEntry->currMaxOrigUsnProcessed = utdVectorEntry->reqLastOrigUsnProcessed =
                                                              atol( nextOrigUsnStr );

                LwRtlHashTableResizeAndInsert( op->syncDoneCtrl->value.syncDoneCtrlVal.htUtdVector,
                                               &utdVectorEntry->Node, &pNode);
                assert( pNode == NULL );    // assert the key of added node is unique.
            }
        }

        tag = ber_peek_tag( ber, &len );
    }
    if (tag == LBER_BOOLEAN)
    {
        ber_int_t reloadHint;
        if (ber_scanf( ber, "b", &reloadHint) == LBER_ERROR)
        {
            VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "ParseSyncRequestControlVal: Error in reading reloadHint from the PDU" );
            lr->errCode = LDAP_PROTOCOL_ERROR;
            retVal = LDAP_NOTICE_OF_DISCONNECT;
            BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                            "Error in reading reloadHint from the PDU.");
        }
        if (reloadHint)
        {
            syncReqCtrlVal->reloadHint = TRUE;
        }
    }
    if ( ber_scanf( ber, "}") == LBER_ERROR ) // End of control value
    {
        VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "ParseSyncRequestControlVal: ber_scanf failed while parsing the end of "
                  "sync request control value." );
        lr->errCode = LDAP_PROTOCOL_ERROR;
        retVal = LDAP_NOTICE_OF_DISCONNECT;
        BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                        "Decoding error while parsing the end of sync request control value.");
    }

    backendCtx.pBE = VmDirBackendSelect("");
    maxPartnerVisibleUSN = backendCtx.pBE->pfnBEGetLeastOutstandingUSN( &backendCtx, FALSE ) - 1;

    if (syncReqCtrlVal->intLastLocalUsnProcessed > maxPartnerVisibleUSN)
    {
        VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "ParseSyncRequestControlVal: ServerId %s has processed my USN (%u), my max USN is (%u).",
                         syncReqCtrlVal->reqInvocationId.lberbv.bv_val, syncReqCtrlVal->intLastLocalUsnProcessed, maxPartnerVisibleUSN );
        lr->errCode = LDAP_UNWILLING_TO_PERFORM;
        retVal = LDAP_NOTICE_OF_DISCONNECT;
        BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg), "Partner is ahead of my changes.");
    }

cleanup:
    // Even in the error case, syncDoneCtrl should be freed during operation delete.
    VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "ParseSyncRequestControlVal: End." );
    VmDirBackendCtxContentFree( &backendCtx );
    VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg);

    return retVal;

error:

    VMDIR_APPEND_ERROR_MSG(lr->pszErrMsg, pszLocalErrorMsg);

    goto cleanup;
}
Example #6
0
DWORD
VmDirIndexLibInit(
    PVMDIR_MUTEX    pModMutex
    )
{
    static VDIR_DEFAULT_INDEX_CFG defIdx[] = VDIR_INDEX_INITIALIZER;

    DWORD   dwError = 0;
    DWORD   i = 0;
    PSTR    pszLastOffset = NULL;
    ENTRYID maxEId = 0;
    VDIR_BACKEND_CTX    beCtx = {0};
    BOOLEAN             bHasTxn = FALSE;
    PVDIR_INDEX_CFG     pIndexCfg = NULL;
    PVDIR_SCHEMA_CTX    pSchemaCtx = NULL;
    PVDIR_SCHEMA_AT_DESC    pATDesc = NULL;

    if (!pModMutex)
    {
        dwError = VMDIR_ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    // pModMutex refers to gVdirSchemaGlobals.cacheModMutex,
    // so do not free it during shutdown
    gVdirIndexGlobals.mutex = pModMutex;

    dwError = VmDirAllocateCondition(&gVdirIndexGlobals.cond);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = LwRtlCreateHashMap(
            &gVdirIndexGlobals.pIndexCfgMap,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    beCtx.pBE = VmDirBackendSelect(NULL);

    dwError = beCtx.pBE->pfnBETxnBegin(&beCtx, VDIR_BACKEND_TXN_WRITE);
    BAIL_ON_VMDIR_ERROR(dwError);
    bHasTxn = TRUE;

    // get fields to continue indexing from where it left last time
    dwError = beCtx.pBE->pfnBEUniqKeyGetValue(
            &beCtx, INDEX_LAST_OFFSET_KEY, &pszLastOffset);
    if (dwError)
    {
        dwError = beCtx.pBE->pfnBEMaxEntryId(&maxEId);
        BAIL_ON_VMDIR_ERROR(dwError);

        if (maxEId == ENTRY_ID_SEQ_INITIAL_VALUE)
        {
            gVdirIndexGlobals.bFirstboot = TRUE;
        }
        else
        {
            gVdirIndexGlobals.bLegacyDB = TRUE;
        }

        // set index_last_offset = -1 to indicate indexing has started
        gVdirIndexGlobals.offset = -1;
        dwError = beCtx.pBE->pfnBEUniqKeySetValue(
                &beCtx, INDEX_LAST_OFFSET_KEY, "-1");
        BAIL_ON_VMDIR_ERROR(dwError);
    }
    else
    {
        dwError = VmDirStringToINT64(pszLastOffset, NULL, &gVdirIndexGlobals.offset);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = beCtx.pBE->pfnBETxnCommit(&beCtx);
    BAIL_ON_VMDIR_ERROR(dwError);
    bHasTxn = FALSE;

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

    // open default indices
    for (i = 0; defIdx[i].pszAttrName; i++)
    {
        dwError = VmDirDefaultIndexCfgInit(&defIdx[i], &pIndexCfg);
        BAIL_ON_VMDIR_ERROR(dwError);

        // update attribute types in schema cache with their index info
        dwError = VmDirSchemaAttrNameToDescriptor(
                pSchemaCtx, pIndexCfg->pszAttrName, &pATDesc);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = VmDirIndexCfgGetAllScopesInStrArray(
                pIndexCfg, &pATDesc->ppszUniqueScopes);
        BAIL_ON_VMDIR_ERROR(dwError);

        pATDesc->dwSearchFlags |= 1;

        // for free later
        pATDesc->pLdapAt->ppszUniqueScopes = pATDesc->ppszUniqueScopes;
        pATDesc->pLdapAt->dwSearchFlags = pATDesc->dwSearchFlags;

        dwError = VmDirIndexOpen(pIndexCfg);
        BAIL_ON_VMDIR_ERROR(dwError);
        pIndexCfg = NULL;
    }

    // VMIT support
    dwError = VmDirIndexLibInitVMIT();
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = InitializeIndexingThread();
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:
    if (bHasTxn)
    {
        beCtx.pBE->pfnBETxnAbort(&beCtx);
    }
    VmDirBackendCtxContentFree(&beCtx);
    VmDirSchemaCtxRelease(pSchemaCtx);
    VMDIR_SAFE_FREE_MEMORY(pszLastOffset);
    return dwError;

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

    VmDirFreeIndexCfg(pIndexCfg);
    goto cleanup;
}
Example #7
0
DWORD
VmDirSchemaAttrIdMapReadDB(
    PVDIR_SCHEMA_ATTR_ID_MAP    pAttrIdMap
    )
{
    DWORD   dwError = 0;
    DWORD   i = 0;
    VDIR_BACKEND_CTX    beCtx = {0};
    BOOLEAN             bHasTxn = FALSE;
    PVMDIR_STRING_LIST  pStringList = NULL;
    PSTR                pszBuf = NULL;
    PSTR                pszName = NULL;
    PSTR                pszId = NULL;
    USHORT              usId = 0;

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

    beCtx.pBE = VmDirBackendSelect(PERSISTED_DSE_ROOT_DN);

    dwError = beCtx.pBE->pfnBETxnBegin(&beCtx, VDIR_BACKEND_TXN_READ, &bHasTxn);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = beCtx.pBE->pfnBEDupKeyGetValues(
            &beCtx, ATTR_ID_MAP_KEY, &pStringList);
    BAIL_ON_VMDIR_ERROR(dwError);

    if (bHasTxn)
    {
        dwError = beCtx.pBE->pfnBETxnCommit(&beCtx);
        bHasTxn = FALSE;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    for (i = 0; i < pStringList->dwCount; i++)
    {
        dwError = VmDirAllocateStringA(pStringList->pStringList[i], &pszBuf);
        BAIL_ON_VMDIR_ERROR(dwError);

        pszId = VmDirStringTokA(pszBuf, SCHEMA_ATTR_ID_MAP_SEP, &pszName);
        usId = (USHORT)VmDirStringToIA(pszId);

        if (VmDirSchemaAttrIdMapGetAttrId(pAttrIdMap, pszName, NULL) != 0)
        {
            dwError = VmDirAllocateStringA(pszName, &pszName);
            BAIL_ON_VMDIR_ERROR(dwError);

            dwError = LwRtlHashMapInsert(pAttrIdMap->pStoredIds,
                    pszName, (PVOID)(uintptr_t)usId, NULL);
            BAIL_ON_VMDIR_ERROR(dwError);

            if (usId >= pAttrIdMap->usNextId)
            {
                pAttrIdMap->usNextId = usId + 1;
            }
        }

        VMDIR_SAFE_FREE_MEMORY(pszBuf);
    }

cleanup:
    VmDirBackendCtxContentFree(&beCtx);
    VmDirStringListFree(pStringList);
    return dwError;

error:
    if (bHasTxn)
    {
        beCtx.pBE->pfnBETxnAbort(&beCtx);
    }
    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL,
            "%s failed, error (%d)", __FUNCTION__, dwError );

    VMDIR_SAFE_FREE_MEMORY(pszBuf);
    goto cleanup;
}
Example #8
0
DWORD
VmDirSchemaAttrIdMapUpdateDB(
    PVDIR_SCHEMA_ATTR_ID_MAP    pAttrIdMap
    )
{
    DWORD   dwError = 0;
    DWORD   dwNumNewIds = 0;
    LW_HASHMAP_ITER iter = LW_HASHMAP_ITER_INIT;
    LW_HASHMAP_PAIR pair = {NULL, NULL};
    PSTR                pszMapStr = NULL;
    PVMDIR_STRING_LIST  pMapStrList = NULL;
    VDIR_BACKEND_CTX    beCtx = {0};
    BOOLEAN             bHasTxn = FALSE;

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

    dwNumNewIds = LwRtlHashMapGetCount(pAttrIdMap->pNewIds);
    if (dwNumNewIds == 0)
    {   // No new Id
        goto cleanup;
    }

    dwError = VmDirStringListInitialize(&pMapStrList, dwNumNewIds);
    BAIL_ON_VMDIR_ERROR(dwError);

    while (LwRtlHashMapIterate(pAttrIdMap->pNewIds, &iter, &pair))
    {
        dwError = VmDirAllocateStringPrintf(&pszMapStr, "%d%s%s",
                (USHORT)(uintptr_t)pair.pValue,
                SCHEMA_ATTR_ID_MAP_SEP,
                (PSTR)pair.pKey);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = VmDirStringListAdd(pMapStrList, pszMapStr);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    beCtx.pBE = VmDirBackendSelect(PERSISTED_DSE_ROOT_DN);

    dwError = beCtx.pBE->pfnBETxnBegin(&beCtx, VDIR_BACKEND_TXN_WRITE, &bHasTxn);
    BAIL_ON_VMDIR_ERROR( dwError );

    dwError = beCtx.pBE->pfnBEDupKeySetValues(&beCtx, ATTR_ID_MAP_KEY, pMapStrList);
    BAIL_ON_VMDIR_ERROR(dwError);

    if (bHasTxn)
    {
        dwError = beCtx.pBE->pfnBETxnCommit(&beCtx);
        bHasTxn = FALSE;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    LwRtlHashMapResetIter(&iter);
    while (LwRtlHashMapIterate(pAttrIdMap->pNewIds, &iter, &pair))
    {
        dwError = LwRtlHashMapInsert(pAttrIdMap->pStoredIds,
                pair.pKey, pair.pValue, NULL);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    LwRtlHashMapClear(pAttrIdMap->pNewIds, VmDirNoopHashMapPairFree, NULL);

cleanup:
    VmDirBackendCtxContentFree(&beCtx);
    VmDirStringListFree(pMapStrList);
    return dwError;

error:
    if (bHasTxn)
    {
        beCtx.pBE->pfnBETxnAbort(&beCtx);
    }
    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL,
            "%s failed, error (%d)", __FUNCTION__, dwError );

    goto cleanup;

}