Beispiel #1
0
/*
 * Bind to partner via "SRP" mechanism.
 */
DWORD
VmDirSafeLDAPBind(
    LDAP**      ppLd,
    PCSTR       pszHost,
    PCSTR       pszUPN,
    PCSTR       pszPassword
    )
{
    DWORD       dwError = 0;

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

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

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

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

    *ppLd = pLd;

cleanup:

    return dwError;

error:

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

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

    goto cleanup;
}
Beispiel #2
0
DWORD
VmDirMetaDataSerialize(
    PVMDIR_ATTRIBUTE_METADATA    pMetadata,
    PSTR                         pszMetadata
    )
{
    DWORD    dwError = 0;

    if (VmDirMetaDataIsEmpty(pMetadata) || !pszMetadata)
    {
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER);
    }

    dwError = VmDirStringPrintFA(
            pszMetadata,
            VMDIR_MAX_ATTR_META_DATA_LEN,
            "%"PRId64":%"PRId64":%s:%s:%"PRId64,
            pMetadata->localUsn,
            pMetadata->version,
            pMetadata->pszOrigInvoId,
            pMetadata->pszOrigTime,
            pMetadata->origUsn);
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:
    return dwError;

error:
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError);
    goto cleanup;
}
Beispiel #3
0
static
DWORD
_VmDirSchemaAttrReplaceValue(
    PVDIR_ATTRIBUTE pAttr,
    PCSTR           pszMatchSubstr,
    PCSTR           pszValue
    )
{
#define MAX_BUF_SIZE_256    256

    DWORD       dwError = 0;
    unsigned    iCnt = 0;
    CHAR        pszBuf[MAX_BUF_SIZE_256] = {0};

    dwError = VmDirStringPrintFA( pszBuf, MAX_BUF_SIZE_256 -1 , "NAME '%s' ", pszMatchSubstr );
    BAIL_ON_VMDIR_ERROR(dwError);

    for (iCnt = 0; iCnt < pAttr->numVals; iCnt++)
    {
        if ( VmDirCaselessStrStrA( pAttr->vals[iCnt].lberbv_val, pszBuf ) != NULL )
        {
            if ( VmDirStringCompareA( VDIR_SAFE_STRING(pAttr->vals[iCnt].lberbv_val),
                                      pszValue,
                                      FALSE ) != 0
                                      )
            {
                VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Merge schema, replace old - %s",
                                VDIR_SAFE_STRING(pAttr->vals[iCnt].lberbv_val));
                VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Merge schema, replace new - %s", pszValue );
            }

            VMDIR_LOG_DEBUG( VMDIR_LOG_MASK_ALL, "Merge schema, replace old - %s",
                             VDIR_SAFE_STRING(pAttr->vals[iCnt].lberbv_val));
            VmDirFreeBervalContent( &(pAttr->vals[iCnt]) );

            dwError = VmDirAllocateStringA( pszValue, &(pAttr->vals[iCnt].lberbv_val) );
            BAIL_ON_VMDIR_ERROR(dwError);
            pAttr->vals[iCnt].lberbv_len = VmDirStringLenA( pszValue );
            pAttr->vals[iCnt].bOwnBvVal = TRUE;

            VMDIR_LOG_DEBUG( VMDIR_LOG_MASK_ALL, "Merge schema, replace new - %s",
                             VDIR_SAFE_STRING(pAttr->vals[iCnt].lberbv_val));

            break;
        }
    }

cleanup:

    return dwError;

error:

    goto cleanup;
}
Beispiel #4
0
/*
 *  Bind to a host with the handle to be used later
 */
DWORD
VmDirConnectLDAPServerWithMachineAccount(
    PCSTR  pszHostName,
    PCSTR  pszDomain,
    LDAP** ppLd
    )
{
    DWORD dwError = 0;
    PSTR pszDCAccount = NULL;
    PSTR pszDCAccountPassword = NULL;
    char bufUPN[VMDIR_MAX_UPN_LEN] = {0};
    LDAP* pLd = NULL;

    dwError = VmDirRegReadDCAccount( &pszDCAccount);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirReadDCAccountPassword( &pszDCAccountPassword);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirStringPrintFA( bufUPN, sizeof(bufUPN)-1,  "%s@%s", pszDCAccount, pszDomain);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirSafeLDAPBindExt1(
        &pLd,
        pszHostName,
        bufUPN,
        pszDCAccountPassword,
        MAX_LDAP_CONNECT_NETWORK_TIMEOUT);
    BAIL_ON_VMDIR_ERROR(dwError);

    *ppLd = pLd;

cleanup:
    VMDIR_SAFE_FREE_STRINGA(pszDCAccount);
    VMDIR_SECURE_FREE_STRINGA(pszDCAccountPassword);
    return dwError;

error:
    goto cleanup;
}
Beispiel #5
0
DWORD
VmDirGetVmDirLogPath(
    PSTR  pszPath,
    PCSTR pszLogFile)
{
    DWORD dwError = 0;

#ifndef _WIN32
    //BUGBUG, should NOT hard code path
    dwError = VmDirStringCpyA(pszPath, MAX_PATH, "/var/log/vmware/vmdir/");
    BAIL_ON_VMDIR_ERROR(dwError);
#else
    _TCHAR* programDataPath           = NULL;

    if ((dwError = VmDirGetRegKeyValue( VMDIR_CONFIG_SOFTWARE_KEY_PATH, VMDIR_REG_KEY_LOG_PATH, pszPath,
                                        MAX_PATH )) != 0)
    {
       dwError = VmDirGetProgramDataEnvVar((_TCHAR *)"PROGRAMDATA", &programDataPath);
       BAIL_ON_VMDIR_ERROR(dwError);

       dwError = VmDirStringPrintFA(pszPath, MAX_PATH, "%s%s", programDataPath, "\\vmware\\cis\\logs\\vmdird\\");
       BAIL_ON_VMDIR_ERROR(dwError);
    }
#endif

    dwError = VmDirStringCatA(pszPath, MAX_PATH, pszLogFile);
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:
#ifdef _WIN32
    VMDIR_SAFE_FREE_MEMORY(programDataPath);
#endif
    return dwError;
error:
    VmDirLog(LDAP_DEBUG_ERROR, "VmDirGetVmDirLogPath failed with error (%u)\n", dwError);
    goto cleanup;
}
Beispiel #6
0
static
DWORD
SetPagedSearchCookie(
    PVDIR_OPERATION pOperation,
    ENTRYID eId,
    DWORD dwCandidatesProcessed
    )
{
    DWORD dwError = 0;

    if (gVmdirGlobals.bPagedSearchReadAhead)
    {
        dwError = VmDirPagedSearchCacheInsert(
                    pOperation,
                    dwCandidatesProcessed);
    }

    if (dwError != 0 || !gVmdirGlobals.bPagedSearchReadAhead)
    {
        //
        // We were unable to cache the information necessary. Fallback to the
        // old cookie mechanism.
        //
        dwError = VmDirStringPrintFA(
                    pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.cookie,
                    VMDIR_ARRAY_SIZE(pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.cookie),
                    "%llu",
                    eId);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

cleanup:
    return dwError;

error:
    goto cleanup;
}
Beispiel #7
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;
}
Beispiel #8
0
static
int
WriteMetaDataAttribute(
   VDIR_OPERATION *             op,
   VDIR_ATTRIBUTE *             pAttr,
   int                          numAttrMetaData,
   PATTRIBUTE_META_DATA_NODE    pAttrMetaData,
   BerElement *                 ber,
   BOOLEAN *                    nonTrivialAttrsInReplScope,
   PSTR*                        ppszErrorMsg
   )
{
    int             retVal = LDAP_SUCCESS;
    VDIR_BERVALUE   attrMetaData = { {ATTR_ATTR_META_DATA_LEN, ATTR_ATTR_META_DATA}, 0, 0, NULL };
    int             i = 0;
    VDIR_BERVALUE   berVal = VDIR_BERVALUE_INIT;
    char            attrMetaDataVal[256 + VMDIR_MAX_ATTR_META_DATA_LEN];
    PSTR            pszLocalErrorMsg = NULL;

    *nonTrivialAttrsInReplScope = FALSE;

    if (ber_printf( ber, "{O[", &(attrMetaData) ) == -1 )
    {
        VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "WriteMetaDataAttribute: ber_printf (to print attribute name ...) failed" );
        retVal = LDAP_OTHER;
        BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                        "Encoding attribute type failed.");
    }

    for ( ; pAttr != NULL; pAttr = pAttr->next)
    {
        // By this time, we have already filtered out attributes that should be send back to replication consumer
        // in prior WriteAttributes -> IsAttrInReplScope call.  They contain proper pAttr->metaData value.
        if (pAttr->metaData[0] != '\0')
        {
            VmDirStringPrintFA( attrMetaDataVal, sizeof(attrMetaDataVal), "%.256s:%s", pAttr->type.lberbv.bv_val, pAttr->metaData);
            berVal.lberbv.bv_val = attrMetaDataVal;
            berVal.lberbv.bv_len = VmDirStringLenA( attrMetaDataVal );
            if (VmDirStringCompareA( pAttr->type.lberbv.bv_val, ATTR_MODIFYTIMESTAMP, FALSE ) != 0 &&
                VmDirStringCompareA( pAttr->type.lberbv.bv_val, ATTR_USN_CHANGED, FALSE ) != 0)
            {
                // To prevent endless replication ping pong, supplier should send result only if there are changes
                // to attribute other than ATTR_USN_CHANGED and ATTR_MODIFYTIMESTAMP.
                *nonTrivialAttrsInReplScope = TRUE;
            }
            if (ber_printf( ber, "O", &berVal ) == -1 )
            {
                VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "WriteMetaDataAttribute: ber_printf (to print an attribute value ...) failed." );
                retVal = LDAP_OTHER;
                BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                                "Encoding an attribute value failed.");
            }
        }
    }
    // include attrMetaData for the deleted attributes
    for (i = 0; i<numAttrMetaData; i++)
    {
        if (pAttrMetaData[i].metaData[0] != '\0')
        {
            BOOLEAN                 bSendAttrMetaData = TRUE;
            PVDIR_SCHEMA_AT_DESC    pATDesc = NULL;

            if (op->syncReqCtrl != NULL) // Replication
            {
                retVal = IsAttrInReplScope( op, NULL, pAttrMetaData[i].metaData, &bSendAttrMetaData, &pszLocalErrorMsg );
                BAIL_ON_VMDIR_ERROR( retVal );
            }
            else
            {
                bSendAttrMetaData = TRUE;
            }
            if (bSendAttrMetaData)
            {
                if ((pATDesc = VmDirSchemaAttrIdToDesc(op->pSchemaCtx, pAttrMetaData[i].attrID)) == NULL)
                {
                    VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL,
                              "WriteMetaDataAttribute: VmDirSchemaAttrIdToDesc failed for attribute id: %d.",
                              pAttrMetaData[i].attrID  );
                    retVal = LDAP_OTHER;
                    BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                                    "WriteMetaDataAttribute: VmDirSchemaAttrIdToDesc failed.");
                }
                VmDirStringPrintFA( attrMetaDataVal, sizeof(attrMetaDataVal), "%.256s:%s", pATDesc->pszName, pAttrMetaData[i].metaData);
                berVal.lberbv.bv_val = attrMetaDataVal;
                berVal.lberbv.bv_len = VmDirStringLenA( attrMetaDataVal );
                *nonTrivialAttrsInReplScope = TRUE;
                if (ber_printf( ber, "O", &berVal ) == -1 )
                {
                    VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "WriteMetaDataAttribute: ber_printf (to print an attribute value ...) failed." );
                    retVal = LDAP_OTHER;
                    BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                                    "Encoding an attribute value failed.");
                }
            }
        }
    }

    if ( ber_printf( ber, "]N}" ) == -1 )
    {
        VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "WriteMetaDataAttribute: ber_printf (to terminate an attribute's values ...) failed" );
        retVal = LDAP_OTHER;
        BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                        "Encoding terminating an attribute type failed.");
    }

cleanup:

    if (ppszErrorMsg)
    {
        *ppszErrorMsg = pszLocalErrorMsg;
    }
    else
    {
        VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg);
    }

    return( retVal );

error:

    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "WriteMetaDataAttribute failed (%u)(%s)",
                     retVal, VDIR_SAFE_STRING(pszLocalErrorMsg) );
    goto cleanup;
}
Beispiel #9
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;
}
Beispiel #10
0
static
int
_VmDirGetRemoteDBUsingRPC(
    PCSTR   pszHostname,
    PCSTR   dbHomeDir,
    BOOLEAN *pbHasXlog)
{
    DWORD       retVal = 0;
    PSTR        pszLocalErrorMsg = NULL;
    char        dbRemoteFilename[VMDIR_MAX_FILE_NAME_LEN] = {0};
    char        localDir[VMDIR_MAX_FILE_NAME_LEN] = {0};
    char        localXlogDir[VMDIR_MAX_FILE_NAME_LEN] = {0};
    char        localFilename[VMDIR_MAX_FILE_NAME_LEN] = {0};
    PSTR        pszDcAccountPwd = NULL;
    PVMDIR_SERVER_CONTEXT hServer = NULL;
    DWORD       low_xlognum = 0;
    DWORD       high_xlognum = 0;
    DWORD       xlognum = 0;
    DWORD       remoteDbSizeMb = 0;
    DWORD       remoteDbMapSizeMb = 0;
    PBYTE       pDbPath = NULL;
    BOOLEAN     bMdbWalEnable = FALSE;

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

    retVal = VmDirAllocateMemory(VMDIR_MAX_FILE_NAME_LEN, (PVOID)&pDbPath );
    BAIL_ON_VMDIR_ERROR(retVal);

    retVal = VmDirReadDCAccountPassword(&pszDcAccountPwd);
    BAIL_ON_VMDIR_ERROR( retVal );

    retVal = VmDirOpenServerA(pszHostname, gVmdirServerGlobals.dcAccountUPN.lberbv_val, NULL, pszDcAccountPwd, 0, NULL, &hServer);
    BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
            "_VmDirGetRemoteDBUsingRPC: VmDirOpenServerA() call failed with error: %d, host name = %s",
            retVal, pszHostname  );
    VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "_VmDirGetRemoteDBUsingRPC: Connected to the replication partner (%s).", pszHostname );

    VmDirGetMdbWalEnable(&bMdbWalEnable);

    if (bMdbWalEnable)
    {
        //Set remote server backend to KEEPXLOGS  mode
        retVal = VmDirSetBackendState (hServer, MDB_STATE_KEEPXLOGS, &low_xlognum, &remoteDbSizeMb,
                                       &remoteDbMapSizeMb, pDbPath, VMDIR_MAX_FILE_NAME_LEN);
    } else
    {
        //Set remote server backend to ReadOnly mode
        retVal = VmDirSetBackendState (hServer, MDB_STATE_READONLY, &low_xlognum, &remoteDbSizeMb,
                                       &remoteDbMapSizeMb, pDbPath, VMDIR_MAX_FILE_NAME_LEN);
    }
    BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg),
            "_VmDirGetRemoteDBUsingRPC: VmDirSetBackendState failed, WalEnabled: %d, error: %d", bMdbWalEnable, retVal);

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

    retVal = _VmDirMkdir(localDir, 0700);
    BAIL_ON_VMDIR_ERROR( retVal );

    if (low_xlognum > 0)
    {
        retVal = VmDirStringPrintFA( localXlogDir, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s", localDir, fileSeperator, VMDIR_MDB_XLOGS_DIR_NAME);
        BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
                "_VmDirGetRemoteDBUsingRPC: VmDirStringPrintFA() call failed with error: %d", retVal );

        retVal = _VmDirMkdir(localXlogDir, 0700);
        BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
                "_VmDirGetRemoteDBUsingRPC: _VmDirMkdir() call failed with error: %d %s", retVal );
    }

    retVal = VmDirStringPrintFA( dbRemoteFilename, VMDIR_MAX_FILE_NAME_LEN, "%s/%s", (char *)pDbPath,
                                 VMDIR_MDB_DATA_FILE_NAME );

    BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
            "_VmDirGetRemoteDBUsingRPC: VmDirStringPrintFA() call failed with error: %d", retVal );

    retVal = VmDirStringPrintFA( localFilename, 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),
            "_VmDirGetRemoteDBUsingRPC: VmDirStringPrintFA() call failed with error: %d", retVal );

    VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "_VmDirGetRemoteDBUsingRPC: copying remote file %s with data size %ld MB with Map size %ld MB ...",
                    dbRemoteFilename, remoteDbSizeMb, remoteDbMapSizeMb );

    retVal = _VmDirGetRemoteDBFileUsingRPC( hServer, dbRemoteFilename, localFilename, remoteDbSizeMb, remoteDbMapSizeMb );
    BAIL_ON_VMDIR_ERROR( retVal );

    if (low_xlognum == 0)
    {
        VMDIR_LOG_INFO(VMDIR_LOG_MASK_ALL,
          "_VmDirGetRemoteDBUsingRPC: complete MDB cold copy - WAL not supported by remote");
        goto cleanup;
    }

    //Query current xlog number
    retVal = VmDirSetBackendState (hServer, MDB_STATE_GETXLOGNUM, &high_xlognum, &remoteDbSizeMb, &remoteDbMapSizeMb, pDbPath, VMDIR_MAX_FILE_NAME_LEN);
    BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
            "_VmDirGetRemoteDBUsingRPC: VmDirSetBackendState failed to get current xlog: %d", retVal  );

    VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "_VmDirGetRemoteDBUsingRPC: start transfering XLOGS from %d to %d", low_xlognum, high_xlognum);
    for (xlognum = low_xlognum; xlognum <= high_xlognum; xlognum++)
    {
        retVal = VmDirStringPrintFA( dbRemoteFilename, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s%c%lu", dbHomeDir, fileSeperator,
                                 VMDIR_MDB_XLOGS_DIR_NAME, fileSeperator, xlognum );
        BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
            "_VmDirGetRemoteDBUsingRPC: VmDirStringPrintFA() call failed with error: %d", retVal );

        retVal = VmDirStringPrintFA( localFilename, VMDIR_MAX_FILE_NAME_LEN, "%s%c%lu", localXlogDir, fileSeperator, xlognum);
        BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
            "_VmDirGetRemoteDBUsingRPC: VmDirStringPrintFA() call failed with error: %d", retVal );

        retVal = _VmDirGetRemoteDBFileUsingRPC( hServer, dbRemoteFilename, localFilename, 0, 0);
        BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
            "_VmDirGetRemoteDBUsingRPC: _VmDirGetRemoteDBFileUsingRPC() call failed with error: %d", retVal );
    }

    VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "_VmDirGetRemoteDBUsingRPC: complete transfering XLOGS from %d to %d", low_xlognum, high_xlognum);

cleanup:
    if (hServer)
    {
        //clear backend transfering xlog files mode.
        VmDirSetBackendState (hServer, MDB_STATE_CLEAR, &xlognum, &remoteDbSizeMb, &remoteDbMapSizeMb, pDbPath, VMDIR_MAX_FILE_NAME_LEN);
        VmDirCloseServer( hServer);
    }
    VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg);
    VMDIR_SAFE_FREE_MEMORY(pDbPath);
    VMDIR_SECURE_FREE_STRINGA(pszDcAccountPwd);
    *pbHasXlog = (low_xlognum > 0);
    return retVal;

error:
    retVal = LDAP_OPERATIONS_ERROR;
    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s", VDIR_SAFE_STRING(pszLocalErrorMsg) );
    goto cleanup;
}
Beispiel #11
0
static
DWORD
constructDeletedObjDN(
    VDIR_BERVALUE *    dn,
    const char *       objectGuidStr,
    VDIR_BERVALUE *    deletedObjDN
    )
{
    DWORD           dwError = 0;
    VDIR_BERVALUE   parentDN = VDIR_BERVALUE_INIT;
    size_t          deletedObjDNLen = 0;
    size_t          delObjsConatinerDNLength = gVmdirServerGlobals.delObjsContainerDN.lberbv.bv_len;
    char *          delObjsConatinerDN = gVmdirServerGlobals.delObjsContainerDN.lberbv.bv_val;

    deletedObjDN->lberbv.bv_val = NULL;
    deletedObjDN->lberbv.bv_len = 0;

    if (!delObjsConatinerDN)
    {
        dwError = VMDIR_ERROR_ENTRY_NOT_FOUND;
        BAIL_ON_VMDIR_ERROR( dwError );
    }

    dwError = VmDirGetParentDN( dn, &parentDN );
    BAIL_ON_VMDIR_ERROR( dwError );

    // Format of the DN of a deleted object is:
    //     <original RDN>#objectGUID:<object GUID string>,<DN of the Deleted objects container>

    deletedObjDNLen = (parentDN.lberbv.bv_len ? dn->lberbv.bv_len - parentDN.lberbv.bv_len - 1 /* Count out RDN separator */ : dn->lberbv.bv_len)
                      + 1 /* for # */ + ATTR_OBJECT_GUID_LEN + 1 /* for : */ + VmDirStringLenA( objectGuidStr )
                      + 1 /* for , */ + delObjsConatinerDNLength;

    dwError = VmDirAllocateMemory( deletedObjDNLen + 1, (PVOID *)&deletedObjDN->lberbv.bv_val );
    BAIL_ON_VMDIR_ERROR( dwError );

    deletedObjDN->lberbv.bv_len = parentDN.lberbv.bv_len ? dn->lberbv.bv_len - parentDN.lberbv.bv_len - 1 /* Count out RDN separator */
                                            : dn->lberbv.bv_len;

    // TODO: how do we know the actual buffer size ?
    dwError = VmDirCopyMemory( deletedObjDN->lberbv.bv_val, deletedObjDN->lberbv.bv_len, dn->lberbv.bv_val, deletedObjDN->lberbv.bv_len );
    BAIL_ON_VMDIR_ERROR( dwError );

    deletedObjDN->lberbv.bv_val[deletedObjDN->lberbv.bv_len] = '#';
    deletedObjDN->lberbv.bv_len++;

    // TODO: how do we know the actual buffer size ?
    dwError = VmDirCopyMemory( deletedObjDN->lberbv.bv_val + deletedObjDN->lberbv.bv_len, ATTR_OBJECT_GUID_LEN, ATTR_OBJECT_GUID,
                               ATTR_OBJECT_GUID_LEN );
    BAIL_ON_VMDIR_ERROR( dwError );

    deletedObjDN->lberbv.bv_len += ATTR_OBJECT_GUID_LEN;
    deletedObjDN->lberbv.bv_val[deletedObjDN->lberbv.bv_len] = ':';
    deletedObjDN->lberbv.bv_len++;

    // TODO: how do we know the actual buffer size ?
    dwError = VmDirCopyMemory( deletedObjDN->lberbv.bv_val + deletedObjDN->lberbv.bv_len, VmDirStringLenA( objectGuidStr ),
                               (PVOID)objectGuidStr, VmDirStringLenA( objectGuidStr ) );
    BAIL_ON_VMDIR_ERROR( dwError );

    deletedObjDN->lberbv.bv_len += VmDirStringLenA( objectGuidStr );

    // TODO: how do we know the actual buffer size ?
    VmDirStringPrintFA( deletedObjDN->lberbv.bv_val + deletedObjDN->lberbv.bv_len, delObjsConatinerDNLength + 2, ",%s",
                        delObjsConatinerDN );

    deletedObjDN->lberbv.bv_len += delObjsConatinerDNLength + 1 /* for , */;

cleanup:
    VmDirFreeBervalContent( &parentDN );

    return dwError;

error:
    if (deletedObjDN->lberbv.bv_val != NULL)
    {
        VmDirFreeMemory( deletedObjDN->lberbv.bv_val );
        deletedObjDN->lberbv.bv_val = NULL;
    }
    deletedObjDN->lberbv.bv_len = 0;
    goto cleanup;
}
Beispiel #12
0
int
WriteSyncDoneControl(
    VDIR_OPERATION *     op,
    BerElement *    ber
    )
{
    int                     retVal = LDAP_OPERATIONS_ERROR;
    PLW_HASHTABLE_NODE      pNode = NULL;
    LW_HASHTABLE_ITER       iter = LW_HASHTABLE_ITER_INIT;
    UptoDateVectorEntry *   pUtdVectorEntry = NULL;
    VDIR_BERVALUE           bvCtrlVal = VDIR_BERVALUE_INIT;
    VDIR_BERVALUE           syncDoneCtrlType = {
                                {VmDirStringLenA( LDAP_CONTROL_SYNC_DONE ), LDAP_CONTROL_SYNC_DONE}, 0, 0, NULL };

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

    if ( op->syncDoneCtrl != NULL)
    {
        if (ber_printf( ber, "t{{O", LDAP_TAG_CONTROLS, &(syncDoneCtrlType.lberbv) ) == -1 )
        {
            VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "WriteSyncDoneControl: ber_printf (to print Sync Done Control ...) failed" );
            retVal = LDAP_OPERATIONS_ERROR;
            BAIL_ON_VMDIR_ERROR( retVal );
        }
        { // Construct string format of utdVector
            int     numEntries = LwRtlHashTableGetCount( op->syncDoneCtrl->value.syncDoneCtrlVal.htUtdVector );
            char *  writer = NULL;
            size_t  tmpLen = 0;
            size_t bufferSize = (numEntries + 1 /* for lastLocalUsn */) *
                                (VMDIR_GUID_STR_LEN + 1 + VMDIR_MAX_USN_STR_LEN + 1);

            // Sync Done control value looks like: <lastLocalUsnChanged>,<serverId1>:<server 1 last originating USN>,
            // <serverId2>,<server 2 originating USN>,...

            if (VmDirAllocateMemory( bufferSize, (PVOID *)&bvCtrlVal.lberbv.bv_val) != 0)
            {
                retVal = LDAP_OPERATIONS_ERROR;
                BAIL_ON_VMDIR_ERROR( retVal );
            }
            writer = bvCtrlVal.lberbv.bv_val;
            bvCtrlVal.lberbv.bv_len = 0;

            VmDirStringPrintFA( writer, bufferSize, "%ld,", op->syncDoneCtrl->value.syncDoneCtrlVal.intLastLocalUsnProcessed );
            tmpLen = VmDirStringLenA( writer );
            writer += tmpLen;
            bufferSize -= tmpLen;
            bvCtrlVal.lberbv.bv_len += tmpLen;

            while ((pNode = LwRtlHashTableIterate(op->syncDoneCtrl->value.syncDoneCtrlVal.htUtdVector, &iter)))
            {
                pUtdVectorEntry = LW_STRUCT_FROM_FIELD(pNode, UptoDateVectorEntry, Node);
                VmDirStringPrintFA( writer, bufferSize, "%s:%ld,", pUtdVectorEntry->invocationId.lberbv.bv_val,
                                    pUtdVectorEntry->currMaxOrigUsnProcessed );
                tmpLen = VmDirStringLenA( writer );
                writer += tmpLen;
                bufferSize -= tmpLen;
                bvCtrlVal.lberbv.bv_len += tmpLen;
            }
        }

        if (ber_printf( ber, "O}}", &bvCtrlVal.lberbv) == -1 )
        {
            VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "WriteSyncDoneControl: ber_printf (to print Sync Done Control ...) failed" );
            retVal = LDAP_OPERATIONS_ERROR;
            BAIL_ON_VMDIR_ERROR( retVal );
        }

        VMDIR_LOG_DEBUG( LDAP_DEBUG_REPL, "WriteSyncDoneControl: Sync Done Control Value: %s", bvCtrlVal.lberbv.bv_val );
    }

    retVal = LDAP_SUCCESS;

cleanup:
    VMDIR_SAFE_FREE_MEMORY( bvCtrlVal.lberbv.bv_val );
    VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "WriteSyncDoneControl: Begin." );
    return retVal;

error:
    goto cleanup;
}
Beispiel #13
0
DWORD
BackupDB(PCSTR srcDir, PCSTR tgtDir)
{
#define VMDIR_MDB_DATA_FILE_NAME "data.mdb"
#define VMDIR_LOCK_DATA_FILE_NAME "lock.mdb"

    DWORD       dwError = 0;
    char        dbLocalFilename[VMDIR_MAX_FILE_NAME_LEN] = {0};
    PSTR        pszLocalErrorMsg = NULL;
    char        cpFileCmdLine[4 /* max of "cp" and "copy" */ + 1 + VMDIR_MAX_FILE_NAME_LEN + 1 +
                              VMDIR_MAX_FILE_NAME_LEN] = {0};

#ifndef _WIN32
    const char * cpFileCmd = "cp";
    const char   fileSeperator = '/';
#else
    const char * cpFileCmd = "copy";
    const char   fileSeperator = '\\';
#endif

    printf( "BackupDB: Setting vmdir state to VMDIRD_READ_ONLY \n" );
    dwError = VmDirSetState( NULL, VMDIRD_STATE_READ_ONLY );
    BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, (pszLocalErrorMsg),
                                  "BackupDB: VmDirSetState() call failed with error: %d", dwError  );

    // Backup data.mdb

    dwError = VmDirStringPrintFA( dbLocalFilename, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s", srcDir, fileSeperator,
                                  VMDIR_MDB_DATA_FILE_NAME );
    BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, (pszLocalErrorMsg),
                                  "BackupDB: VmDirStringPrintFA() call failed with error: %d", dwError );

    dwError = VmDirStringPrintFA( cpFileCmdLine, sizeof(cpFileCmdLine), "%s %s %s", cpFileCmd, dbLocalFilename, tgtDir  );
    BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, (pszLocalErrorMsg),
                                  "BackupDB: VmDirStringPrintFA() call failed with error: %d", dwError );

    printf( "BackupDB: Backing up: %s \n", dbLocalFilename );

    dwError = VmDirRun(cpFileCmdLine);
    BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, (pszLocalErrorMsg),
                                  "BackupDB: VmDirRun() call failed, cmd: %s", cpFileCmdLine );

    // Backup lock.mdb

    dwError = VmDirStringPrintFA( dbLocalFilename, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s", srcDir, fileSeperator,
                                  VMDIR_LOCK_DATA_FILE_NAME );
    BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, (pszLocalErrorMsg),
                                  "BackupDB: VmDirStringPrintFA() call failed with error: %d", dwError );

    dwError = VmDirStringPrintFA( cpFileCmdLine, sizeof(cpFileCmdLine), "%s %s %s", cpFileCmd, dbLocalFilename, tgtDir  );
    BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, (pszLocalErrorMsg),
                                  "BackupDB: VmDirStringPrintFA() call failed with error: %d", dwError );

    printf( "BackupDB: Backing up: %s \n", dbLocalFilename );

    dwError = VmDirRun(cpFileCmdLine);
    BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, (pszLocalErrorMsg),
                                  "BackupDB: VmDirRun() call failed, cmd: %s", cpFileCmdLine );

cleanup:
    printf( "BackupDB: Setting vmdir state to VMDIRD_NORMAL \n" );

    if ((dwError = VmDirSetState( NULL, VMDIRD_STATE_NORMAL )) != 0)
    {
        fprintf(stderr, "BackupDB: Setting vmdir state to VMDIRD_NORMAL failed, error (%d) \n", dwError);
    }

    VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg);

    return dwError;

error:
    fprintf( stderr, "%s\n", pszLocalErrorMsg ? pszLocalErrorMsg : "Hmmm ... no local error message."  );
    goto cleanup;
}
Beispiel #14
0
/*
 * TODO, Should chg db dir to /var/lib/vmware/vmdir/db.
 * Then we can just swap partner to db directly.
 */
static
DWORD
_VmDirSwapDBInternal(
    PCSTR   pszdbHomeDir,   // e.g. /var/lib/vmware/vmdir
    PCSTR   pszSwapDir      // e.g. /var/lib/vmware/lightwave_tmp
    )
{
    DWORD   dwError = 0;
    int     errorCode = 0;
    CHAR    cmdBuf[VMDIR_MAX_FILE_NAME_LEN] = {0};
    CHAR    partnerDBdBuf[VMDIR_MAX_FILE_NAME_LEN] = {0};
    CHAR    swapDirBuf[VMDIR_MAX_FILE_NAME_LEN] = {0};

    // /var/lib/vmware/lightwave_tmp/partner
    dwError = VmDirStringPrintFA(swapDirBuf, VMDIR_MAX_FILE_NAME_LEN,
        "%s/%s", pszSwapDir, LOCAL_PARTNER_DIR);
    BAIL_ON_VMDIR_ERROR(dwError);

    // /var/lib/vmware/vmdir/partner
    dwError = VmDirStringPrintFA(partnerDBdBuf, VMDIR_MAX_FILE_NAME_LEN,
        "%s/%s", pszdbHomeDir, LOCAL_PARTNER_DIR);
    BAIL_ON_VMDIR_ERROR(dwError);

    // rm -rf /var/lib/vmware/lightwave_tmp/partner
    dwError = VmDirStringPrintFA(cmdBuf, VMDIR_MAX_FILE_NAME_LEN,
        "rm -rf %s", swapDirBuf);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirRun(cmdBuf);
    BAIL_ON_VMDIR_ERROR(dwError);

    // mv /var/lib/vmware/vmdir/partner /var/lib/vmware/lightwave_tmp/partner
    dwError = VmDirStringPrintFA(cmdBuf, VMDIR_MAX_FILE_NAME_LEN,
        "mv %s %s", partnerDBdBuf, swapDirBuf);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirRun(cmdBuf);
    BAIL_ON_VMDIR_ERROR(dwError);

    // rm -rf /var/lib/vmware/vmdir/*
    dwError = VmDirStringPrintFA(cmdBuf, VMDIR_MAX_FILE_NAME_LEN,
        "rm -rf %s/*", pszdbHomeDir);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirRun(cmdBuf);
    BAIL_ON_VMDIR_ERROR(dwError);

    // mv /var/lib/vmware/lightwave_tmp/partner/* /var/lib/vmware/vmdir/
    dwError = VmDirStringPrintFA(cmdBuf, VMDIR_MAX_FILE_NAME_LEN,
        "mv %s/* %s/", swapDirBuf, pszdbHomeDir);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirRun(cmdBuf);
    BAIL_ON_VMDIR_ERROR(dwError);

    VMDIR_LOG_INFO(VMDIR_LOG_MASK_ALL, "%s, DB Swapped", __FUNCTION__);

cleanup:

    return dwError;

error:
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "Error %d, errno %d", dwError, errorCode);
    goto cleanup;
}
Beispiel #15
0
static
int
ProcessCandidateList(
    VDIR_OPERATION * pOperation
    )
{
    int               retVal = LDAP_SUCCESS;
    int               i = 0;
    VDIR_CANDIDATES * cl = pOperation->request.searchReq.filter->candidates;
    VDIR_ENTRY        srEntry = {0};
    VDIR_ENTRY *      pSrEntry = NULL;
    int               numSentEntries = 0;
    BOOLEAN           bInternalSearch = FALSE;
    BOOLEAN           bPageResultsCtrl = FALSE;
    DWORD             dwPageSize = 0;
    ENTRYID           lastEID = 0;

    /*
     * If the page size is greater than or equal to the sizeLimit value,
     * the server should ignore the control as the request can be satisfied in a single page.
     */
    if (pOperation->showPagedResultsCtrl && (pOperation->request.searchReq.sizeLimit == 0 ||
            pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.pageSize < (DWORD)pOperation->request.searchReq.sizeLimit))
    {
        VmDirLog( LDAP_DEBUG_TRACE, "showPagedResultsCtrl applies to this query." );
        bPageResultsCtrl = TRUE;
        dwPageSize = pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.pageSize;
        lastEID = atoi(pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.cookie);
        pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.cookie[0] = '\0';
    }

    if (cl && cl->size > 0)
    {
        if (pOperation->opType == VDIR_OPERATION_TYPE_INTERNAL)
        {   //TODO, we should have a hard limit on the cl->size we handle
            bInternalSearch = TRUE;
            VmDirFreeEntryArrayContent(&pOperation->internalSearchEntryArray);
            retVal = VmDirAllocateMemory(   sizeof(VDIR_ENTRY) * cl->size,
                                            (PVOID*)&pOperation->internalSearchEntryArray.pEntry);
            BAIL_ON_VMDIR_ERROR(retVal);
        }

        for (i = 0, numSentEntries = 0;
             (i < cl->size) && VmDirdState() != VMDIRD_STATE_SHUTDOWN &&
             (pOperation->request.searchReq.sizeLimit == 0 /* unlimited */ ||
              numSentEntries < pOperation->request.searchReq.sizeLimit);
             i++)
        {
            //skip entries we sent before
            if (bPageResultsCtrl && lastEID > 0)
            {
                if (cl->eIds[i] == lastEID)
                {
                    lastEID = 0;
                }
                continue;
            }

            VMDIR_LOG_DEBUG( LDAP_DEBUG_FILTER, "ProcessCandidateList EID(%u)", cl->eIds[i]);

            pSrEntry = bInternalSearch ?
                        (pOperation->internalSearchEntryArray.pEntry + pOperation->internalSearchEntryArray.iSize) : &srEntry;

            retVal = pOperation->pBEIF->pfnBEIdToEntry(
                        pOperation->pBECtx,
                        pOperation->pSchemaCtx,
                        cl->eIds[i],
                        pSrEntry,
                        VDIR_BACKEND_ENTRY_LOCK_READ);

            if (retVal == 0)
            {
                if (CheckIfEntryPassesFilter( pOperation, pSrEntry, pOperation->request.searchReq.filter) == FILTER_RES_TRUE)
                {
                    retVal = VmDirBuildComputedAttribute( pOperation, pSrEntry );
                    BAIL_ON_VMDIR_ERROR( retVal );

                    if (bInternalSearch)
                    {
                        pOperation->internalSearchEntryArray.iSize++;
                        pSrEntry = NULL;    // EntryArray takes over *pSrEntry content
                    }
                    else
                    {
                        retVal = VmDirSendSearchEntry( pOperation, pSrEntry );
                        if (retVal == VMDIR_ERROR_INSUFFICIENT_ACCESS)
                        {
                            VMDIR_LOG_WARNING( VMDIR_LOG_MASK_ALL,
                                               "Access deny on search entry result [%s,%d] (bindedDN-%s) (targetDn-%s)\n",
                                               __FILE__, __LINE__, pOperation->conn->AccessInfo.pszBindedDn, pSrEntry->dn.lberbv.bv_val);
                            // make sure search continues
                            retVal = 0;
                        }
                        BAIL_ON_VMDIR_ERROR( retVal );

                        if (pSrEntry->bSearchEntrySent)
                        {
                            numSentEntries++;
                        }
                    }
                }

                //We have sent one page size of entries, so we can break here
                if (bPageResultsCtrl && numSentEntries == dwPageSize){
                    retVal = VmDirStringPrintFA(
                            pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.cookie,
                            VMDIR_MAX_I64_ASCII_STR_LEN,
                            "%u",
                            pSrEntry->eId);
                    BAIL_ON_VMDIR_ERROR( retVal );
                    break;
                }

                VmDirFreeEntryContent( pSrEntry );
                pSrEntry = NULL; // Reset to NULL so that DeleteEntry is no-op.
            }
            else
            {
                // Ignore BdbEIdToEntry errors.
                VMDIR_LOG_WARNING( VMDIR_LOG_MASK_ALL, "ProcessCandiateList BEIdToEntry EID(%u), error (%u)",
                                                       cl->eIds[i], retVal);
                retVal = 0;
            }
        }

        VMDIR_LOG_VERBOSE( LDAP_DEBUG_FILTER, "(%d) candiates processed and (%d) entries sent", cl->size, numSentEntries);
    }

    if ( pOperation->request.searchReq.sizeLimit && numSentEntries < pOperation->request.searchReq.sizeLimit &&
         pOperation->pBECtx->iPartialCandidates)
    {
        retVal = LDAP_UNWILLING_TO_PERFORM;
        VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "ProcessCandiateList may return none or paritial requested entries with sizelimit %d",
                        pOperation->request.searchReq.sizeLimit);
    }

cleanup:

    pOperation->dwSentEntries = numSentEntries;
    VmDirFreeEntryContent( pSrEntry );

    return retVal;

error:

    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "ProcessCandiateList failed. (%u)", retVal);
    goto cleanup;
}