Ejemplo n.º 1
0
/*
 * pEntry is created from a difference instance of schema.
 * Path it to use new instance it now associates with.
 * 1. inpalce menory of pAttr->type
 * 2. pEntry->pSchemaCtx
 */
static
DWORD
_VmDirSchemaInitFixBootstrapEntry(
    PVDIR_SCHEMA_INSTANCE   pSchema,
    PVDIR_ENTRY             pEntry
    )
{
    DWORD               dwError = 0;
    VDIR_ATTRIBUTE*     pAttr = NULL;
    PVDIR_SCHEMA_CTX    pNewCtx = NULL;

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

    // create the very first ctx for pSchema
    pNewCtx->pSchema = pSchema;
    pNewCtx->pSchema->usRefCount++;

    // switch pEntry to use the new schema instance it creates.
    VmDirSchemaCtxRelease(pEntry->pSchemaCtx);
    pEntry->pSchemaCtx = pNewCtx;
    pNewCtx = NULL;

    for (pAttr = pEntry->attrs; pAttr; pAttr = pAttr->next)
    {
        USHORT usId = pAttr->pATDesc->usAttrID;
        PVDIR_SCHEMA_AT_DESC pResult = pSchema->ats.ppATSortIdMap[usId - 1];

        if (!pResult)
        {   // this should never happen as attribute ID never change once it is assigned.
            dwError = ERROR_INVALID_SCHEMA;
            BAIL_ON_VMDIR_ERROR(dwError);
        }

        // patch Attribute.pATDesc
        pAttr->pATDesc = pResult;

        // patch Attribute.type in-place storage as well
        pAttr->type.lberbv.bv_val = pResult->pszName;
        pAttr->type.lberbv.bv_len = VmDirStringLenA(pAttr->type.lberbv.bv_val);
    }

cleanup:

    return dwError;

error:

    if ( pNewCtx )
    {
        VmDirSchemaCtxRelease( pNewCtx );
    }

    goto cleanup;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 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;
}
Ejemplo n.º 4
0
/*
 * Commit schema modification into cache.
 *
 * 1. commit pending cache to go live
 * 2. create self reference ctx
 * 3. release old self reference ctx
 * 4. update pEntry to have new live schema ctx association
 */
VOID
VmDirSchemaCacheModifyCommit(
    PVDIR_ENTRY  pSchemaEntry
    )
{
    DWORD               dwError = 0;
    BOOLEAN             bInLock = FALSE;
    PVDIR_SCHEMA_CTX    pOldCtx = NULL;

    if ( !pSchemaEntry || !pSchemaEntry->pSchemaCtx )
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    VMDIR_LOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex);

    if ( ! gVdirSchemaGlobals.bHasPendingChange )
    {
        VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Schema cache update pass through" );
        goto cleanup;   // no schema definition change, just pass through.
    }

    gVdirSchemaGlobals.bHasPendingChange = FALSE;
    gVdirSchemaGlobals.pSchema = pSchemaEntry->pSchemaCtx->pSchema;

    pOldCtx = gVdirSchemaGlobals.pCtx;
    gVdirSchemaGlobals.pCtx = NULL;

    VdirSchemaCtxAcquireInLock(TRUE, &gVdirSchemaGlobals.pCtx); // add global instance self reference
    assert(gVdirSchemaGlobals.pCtx);

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

    VMDIR_UNLOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex);

cleanup:

    VMDIR_UNLOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex);

    if (pOldCtx)
    {
        VmDirSchemaCtxRelease(pOldCtx);
    }

    return;

error:

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

    goto cleanup;
}
Ejemplo n.º 5
0
DWORD
VmDirLoadIndex(
    BOOLEAN bFirstboot
    )
{
    DWORD   dwError = 0;
    DWORD   i = 0;
    PVDIR_SCHEMA_CTX        pSchemaCtx = NULL;
    PVDIR_SCHEMA_AT_DESC*   ppATDescList = NULL;
    PVDIR_INDEX_CFG         pIndexCfg = NULL;

    if (bFirstboot)
    {
        // Firstboot should use only the default indices
        // Nothing to load
        goto cleanup;
    }

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

    dwError = VmDirSchemaAttrList(pSchemaCtx, &ppATDescList);
    BAIL_ON_VMDIR_ERROR(dwError);

    // Identify non-default indices by their searchFlags and open them
    for (i = 0; ppATDescList[i]; i++)
    {
        if ((ppATDescList[i]->dwSearchFlags & 1) &&
                !VmDirIndexIsDefault(ppATDescList[i]->pszName))
        {
            dwError = VmDirCustomIndexCfgInit(ppATDescList[i], &pIndexCfg);
            BAIL_ON_VMDIR_ERROR(dwError);

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

cleanup:
    VMDIR_SAFE_FREE_MEMORY(ppATDescList);
    VmDirSchemaCtxRelease(pSchemaCtx);
    return dwError;

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

    VmDirFreeIndexCfg(pIndexCfg);
    goto cleanup;
}
Ejemplo n.º 6
0
VOID
VmDirSchemaLibShutdown(
    VOID
    )
{
    BOOLEAN bInLock = FALSE;

    VMDIR_LOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex);

    // release live context and live schema
    VmDirSchemaCtxRelease(gVdirSchemaGlobals.pCtx);
    VMDIR_SAFE_FREE_MEMORY(gVdirSchemaGlobals.pszDN);

    VMDIR_UNLOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex);

    VMDIR_SAFE_FREE_MUTEX( gVdirSchemaGlobals.mutex );
}
Ejemplo n.º 7
0
DWORD
VmDirSrvSetupTenantInstance(
    PCSTR pszFQDomainName,
    PCSTR pszUsername,
    PCSTR pszPassword
    )
{
    DWORD dwError = 0;
    PSTR  pszDomainDN = NULL;
    PVDIR_SCHEMA_CTX pSchemaCtx = NULL;

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

    dwError = VmDirSrvCreateDomainDN(pszFQDomainName, &pszDomainDN);
    BAIL_ON_VMDIR_ERROR(dwError);

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

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

cleanup:

    VMDIR_SAFE_FREE_MEMORY(pszDomainDN);

    if (pSchemaCtx)
    {
        VmDirSchemaCtxRelease(pSchemaCtx);
    }

    return dwError;

error:
    VmDirLog(LDAP_DEBUG_ANY, "VmDirSrvSetupTenantInstance failed. Error(%u)", dwError);
    goto cleanup;
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
//Clone a operation struct that share the same
//transaction context with pOp
DWORD
VmDirCloneStackOperation(
    PVDIR_OPERATION         pOp,
    PVDIR_OPERATION         pOutOp,
    VDIR_OPERATION_TYPE     opType,
    ber_tag_t               requestCode,
    PVDIR_SCHEMA_CTX        pSchemaCtx
    )
{
    DWORD               dwError = 0;
    PVDIR_SCHEMA_CTX    pLocalSchemaCtx = NULL;

    BAIL_ON_VMDIR_INVALID_POINTER( pOp, dwError );
    BAIL_ON_VMDIR_INVALID_POINTER( pOutOp, dwError );

    pOutOp->opType  = opType;
    pOutOp->reqCode = requestCode;

    if ( pOutOp->reqCode == LDAP_REQ_ADD )
    {
        dwError = VmDirAllocateMemory( sizeof(*(pOutOp->request.addReq.pEntry)),
                                       (PVOID)&(pOutOp->request.addReq.pEntry) );
        BAIL_ON_VMDIR_ERROR( dwError );
    }

    if ( pSchemaCtx )
    {
        pLocalSchemaCtx = VmDirSchemaCtxClone( pSchemaCtx );
        if ( !pLocalSchemaCtx )
        {
            dwError = ERROR_NO_SCHEMA;
            BAIL_ON_VMDIR_ERROR(dwError);
        }
    }
    else
    {
        dwError = VmDirSchemaCtxAcquire(&pLocalSchemaCtx);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = VmDirAllocateAndCopyMemory(pOp->pBECtx, sizeof(*pOutOp->pBECtx ), (PVOID) &(pOutOp->pBECtx));
    BAIL_ON_VMDIR_ERROR(dwError);

    if ( pOutOp->opType == VDIR_OPERATION_TYPE_INTERNAL )
    {   // needs dummy conn->VDIR_ACCESS_INFO for ACL check
        dwError = VmDirAllocateMemory( sizeof( *pOutOp->conn), (PVOID) &(pOutOp->conn) );
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    pOutOp->pSchemaCtx = pLocalSchemaCtx;
    pLocalSchemaCtx = NULL;

cleanup:

   return dwError;

error:

    if ( pLocalSchemaCtx )
    {
        VmDirSchemaCtxRelease( pLocalSchemaCtx );
    }
    VmDirFreeOperationContent(pOutOp);

   goto cleanup;
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
0
DWORD
VmDirCreateAccount(
    PCSTR   pszUPNName,
    PCSTR   pszUserName,
    PCSTR   pszPassword,        // optional?
    PCSTR   pszEntryDN          // optional
    )
{
    DWORD   dwError = 0;
    PSTR    ppszAttributes[] =
    {
            ATTR_OBJECT_CLASS,      (PSTR)OC_USER,
            ATTR_CN,                (PSTR)pszUserName,
            ATTR_USER_PASSWORD,     (PSTR)pszPassword,
            ATTR_SAM_ACCOUNT_NAME,  (PSTR)pszUserName,
            ATTR_KRB_UPN,           (PSTR)pszUPNName,
            NULL
    };

    PVDIR_SCHEMA_CTX    pSchemaCtx = NULL;
    PSTR                pszAccountDN = NULL;

    if (    IsNullOrEmptyString(pszUPNName)                 ||
            IsNullOrEmptyString(pszUserName)
       )
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

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

    if (pszEntryDN == NULL)
    {
        dwError = VmDirUPNToAccountDN(pszUPNName, ATTR_CN, pszUserName, &pszAccountDN);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = VmDirSimpleEntryCreate(
                    pSchemaCtx,
                    ppszAttributes,
                    pszEntryDN ? (PSTR)pszEntryDN : pszAccountDN,
                    0);
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:

    VmDirSchemaCtxRelease(pSchemaCtx);

    VMDIR_SAFE_FREE_MEMORY(pszAccountDN);

    return dwError;

error:

    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL,
                     "VmDirCreateAccount UPN(%s) failed, (%u)",
                              VDIR_SAFE_STRING(pszUPNName), dwError);

    goto cleanup;
}
Ejemplo n.º 12
0
/*
 * Convert attrIndexDesc attribute into a VDIR_ATTR_INDEX_INSTANCE
 * and enable gVdirAttrIndexCache with version 0.
 */
DWORD
VdirAttrIndexInitViaEntry(
    PVDIR_ENTRY  pEntry
    )
{
    DWORD                       dwError = 0;
    DWORD                       dwCnt = 0;
    BOOLEAN                     bInLock = FALSE;
    PVDIR_ATTRIBUTE             pAttr = NULL;
    PVDIR_ATTR_INDEX_INSTANCE   pAttrIdxCache = NULL;
    USHORT                      usLive = gVdirAttrIndexGlobals.usLive;
    PVDIR_SCHEMA_CTX            pSchemaCtx = NULL;

    assert(pEntry);

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

    pAttr = VmDirEntryFindAttribute(
            ATTR_INDEX_DESC,
            pEntry);
    assert(pAttr);

    dwError = VdirAttrIndexCacheAllocate(
            &pAttrIdxCache,
            pAttr->numVals);
    BAIL_ON_VMDIR_ERROR(dwError);

    for (dwCnt = 0; dwCnt < pAttr->numVals; dwCnt++)
    {
        VDIR_CFG_ATTR_INDEX_DESC indexDesc = {0};

        dwError = VdirstrToAttrIndexDesc(
                pAttr->vals[dwCnt].lberbv.bv_val,
                &indexDesc);
        BAIL_ON_VMDIR_ERROR(dwError);

        // cache takes over indexDesc.pszAttrName
        pAttrIdxCache->pSortName[dwCnt].pszAttrName = indexDesc.pszAttrName;
        indexDesc.pszAttrName = NULL;

        pAttrIdxCache->pSortName[dwCnt].bIsUnique = indexDesc.bIsUnique;
        pAttrIdxCache->pSortName[dwCnt].iTypes = indexDesc.iTypes;
        pAttrIdxCache->pSortName[dwCnt].status = indexDesc.status;
        pAttrIdxCache->pSortName[dwCnt].bIsNumeric = VmDirSchemaAttrHasIntegerMatchingRule(
                                                            pSchemaCtx,
                                                            pAttrIdxCache->pSortName[dwCnt].pszAttrName);

        pAttrIdxCache->pSortName[dwCnt].iId = dwCnt;
    }

    qsort(pAttrIdxCache->pSortName,
          pAttrIdxCache->usNumIndex,
          sizeof(VDIR_CFG_ATTR_INDEX_DESC),
          VdirAttrIndexNameCmp);

    VMDIR_LOCK_MUTEX(bInLock, gVdirAttrIndexGlobals.mutex);

    // Set up a cache instance
    // In case there is no need to do bootstrape during server start up, usLive == 0
    // is not assigned (i.e.: schema entry is found)
    if ((usLive == 0 && gVdirAttrIndexGlobals.pCaches[usLive] != NULL) || usLive > 0)
    {
        usLive++;
    }
    gVdirAttrIndexGlobals.pCaches[usLive] = pAttrIdxCache;
    gVdirAttrIndexGlobals.usLive = usLive;

cleanup:
    VMDIR_UNLOCK_MUTEX(bInLock, gVdirAttrIndexGlobals.mutex);

    if (pSchemaCtx)
    {
        VmDirSchemaCtxRelease(pSchemaCtx);
    }

    return dwError;

error:
    if (pAttrIdxCache)
    {
        VdirAttrIdxCacheFree(pAttrIdxCache);
    }

    goto cleanup;
}
Ejemplo n.º 13
0
void
VmDirFreeEntryContent(
   VDIR_ENTRY * e
   )
{
   VmDirLog( LDAP_DEBUG_TRACE, "DeleteEntry: Begin" );

   if ( e )
   {
      VmDirLog( LDAP_DEBUG_TRACE, "DeleteEntry: DN = %s",
              e ? (e->dn.lberbv.bv_val ? e->dn.lberbv.bv_val : "") : "" );

      if (e->pParentEntry)
      {
          VmDirFreeEntryContent(e->pParentEntry);
          VMDIR_SAFE_FREE_MEMORY(e->pParentEntry);
      }

      VmDirFreeLDAPDNContent( &(e->ldapDN) );
      VmDirFreeBervalContent( &(e->dn) );
      VmDirFreeBervalContent( &(e->pdn) );
      VmDirFreeBervalContent( &(e->newpdn) );

      if (e->allocType == ENTRY_STORAGE_FORMAT_PACK)
      {
         PVDIR_ATTRIBUTE    pCurrAttr = NULL;
         PVDIR_ATTRIBUTE    pTempAttr = NULL;

         pCurrAttr = e->attrs;
         while(pCurrAttr != NULL)
         {
             pTempAttr = pCurrAttr->next;
             VmDirFreeMetaData(pCurrAttr->pMetaData);
             pCurrAttr = pTempAttr;
         }
         VMDIR_SAFE_FREE_MEMORY( e->encodedEntry );
         VmDirFreeBervalArrayContent(e->bvs, e->usNumBVs);
         VMDIR_SAFE_FREE_MEMORY( e->bvs );
         VMDIR_SAFE_FREE_MEMORY( e->savedAttrsPtr );
      }
      else if (e->allocType == ENTRY_STORAGE_FORMAT_NORMAL)
      {
         VDIR_ATTRIBUTE * currAttr = NULL;
         VDIR_ATTRIBUTE * tmpAttr = NULL;

         VMDIR_SAFE_FREE_MEMORY( e->encodedEntry );

         for (currAttr = e->attrs; currAttr != NULL; )
         {
            tmpAttr = currAttr->next;
            VmDirFreeAttribute(currAttr);
            currAttr = tmpAttr;
         }
      }

      if (e->pComputedAttrs)
      {
          VDIR_ATTRIBUTE * currAttr = NULL;
          VDIR_ATTRIBUTE * tmpAttr = NULL;

          for (currAttr = e->pComputedAttrs; currAttr != NULL; )
          {
             tmpAttr = currAttr->next;
             VmDirFreeAttribute(currAttr);
             currAttr = tmpAttr;
          }
      }

      VmDirSchemaCtxRelease(e->pSchemaCtx);
      VmDirAclCtxContentFree(e->pAclCtx);
      VMDIR_SAFE_FREE_MEMORY(e->pAclCtx);
      VMDIR_SAFE_FREE_MEMORY(e->pszGuid);

      memset(e, 0, sizeof(*e));
   }

   VmDirLog( LDAP_DEBUG_TRACE, "DeleteEntry: End" );
}
Ejemplo n.º 14
0
/* This function re-instantiates the current vmdir instance with a
 * foreign (MDB) database file. It is triggered by running vdcadmintool
 * with option 8.  Before this action, a foreign database files must be copied
 * onto diretory mdb_home_dir/partner/ which may include mdb WAL files under
 * xlogs/. See PR 1995325 for the functional spec and use cases.
 */
DWORD
VmDirSrvServerReset(
    PDWORD pServerResetState
    )
{
    int i = 0;
    DWORD dwError = 0;
    VDIR_ENTRY_ARRAY entryArray = {0};
    const char  *dbHomeDir = VMDIR_DB_DIR;
    PVDIR_SCHEMA_CTX pSchemaCtx = NULL;
    BOOLEAN bWriteInvocationId = FALSE;
    PSTR pszConfigurationContainerDn = NULL;
    PSTR pszDomainControllerContainerDn = NULL;
    PSTR pszManagedServiceAccountContainerDn = NULL;
    DEQUE computers = {0};
    PSTR pszComputer = NULL;
    PVDIR_ATTRIBUTE pAttrUPN = NULL;
    BOOLEAN bMdbWalEnable = FALSE;

    VmDirGetMdbWalEnable(&bMdbWalEnable);

    //swap current vmdir database file with the foriegn one under partner/
    dwError = _VmDirSwapDB(dbHomeDir, bMdbWalEnable);
    BAIL_ON_VMDIR_ERROR(dwError);

    //Delete Computers (domain controller accounts) under Domain Controller container
    dwError = VmDirAllocateStringPrintf(&pszDomainControllerContainerDn, "ou=%s,%s",
                VMDIR_DOMAIN_CONTROLLERS_RDN_VAL, gVmdirServerGlobals.systemDomainDN.lberbv_val);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirSimpleEqualFilterInternalSearch(pszDomainControllerContainerDn, LDAP_SCOPE_ONE,
                ATTR_OBJECT_CLASS, OC_COMPUTER, &entryArray);
    BAIL_ON_VMDIR_ERROR(dwError);

    if(entryArray.iSize > 0)
    {
        for (i = 0; i < entryArray.iSize; i++)
        {
            pAttrUPN = VmDirFindAttrByName(&entryArray.pEntry[i], ATTR_KRB_UPN);
            if (pAttrUPN)
            {
               PSTR pPc = NULL;
               dwError = VmDirAllocateStringA(pAttrUPN->vals[0].lberbv_val, &pPc);
               dequePush(&computers, pPc);
            }
            dwError = VmDirDeleteEntry(&entryArray.pEntry[i]);
            BAIL_ON_VMDIR_ERROR(dwError);
        }
    }
    VmDirFreeEntryArrayContent(&entryArray);

    /* Delete all entries in the subtree under Configuration container
     *  (e.g. under cn=Configuration,dc=vmware,dc=com).
     * This will remove the old replication topology
     */
    dwError = VmDirAllocateStringPrintf(&pszConfigurationContainerDn, "cn=%s,%s",
                VMDIR_CONFIGURATION_CONTAINER_NAME, gVmdirServerGlobals.systemDomainDN.lberbv_val);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirSimpleEqualFilterInternalSearch(pszConfigurationContainerDn, LDAP_SCOPE_SUBTREE,
                ATTR_OBJECT_CLASS, OC_DIR_SERVER, &entryArray);
    BAIL_ON_VMDIR_ERROR(dwError);

    if (entryArray.iSize > 0)
    {
        for (i = 0; i < entryArray.iSize; i++)
        {
            /* Delete all replication agreement entries for a server and
             * the server it self under the configuration/site container
             */
            dwError = VmDirInternalDeleteTree(entryArray.pEntry[i].dn.lberbv_val);
            BAIL_ON_VMDIR_ERROR(dwError);
        }
    }
    VmDirFreeEntryArrayContent(&entryArray);

    //Delete ManagedServiceAccount entries that are associated with any of the domain controllers

    dwError = VmDirAllocateStringPrintf(&pszManagedServiceAccountContainerDn, "cn=%s,%s",
                VMDIR_MSAS_RDN_VAL, gVmdirServerGlobals.systemDomainDN.lberbv_val);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirSimpleEqualFilterInternalSearch(pszManagedServiceAccountContainerDn, LDAP_SCOPE_ONE,
                ATTR_OBJECT_CLASS, OC_MANAGED_SERVICE_ACCOUNT, &entryArray);
    BAIL_ON_VMDIR_ERROR(dwError);

    if (entryArray.iSize > 0)
    {
        for (i = 0; i < entryArray.iSize; i++)
        {
            PDEQUE_NODE p = NULL;
            pAttrUPN = VmDirFindAttrByName(&entryArray.pEntry[i], ATTR_KRB_UPN);
            for(p = computers.pHead; p != NULL; p = p->pNext)
            {
                if (VmDirStringCaseStrA(pAttrUPN->vals[0].lberbv_val, p->pElement) != NULL)
                {
                    dwError = VmDirDeleteEntry(&entryArray.pEntry[i]);
                    BAIL_ON_VMDIR_ERROR(dwError);
                    break;
                }
            }
        }
    }

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

    dwError = VmDirSrvCreateServerObj(pSchemaCtx);
    BAIL_ON_VMDIR_ERROR(dwError);

    //Create server and replication entries for the current instance
    // on top of the (cleaned up) foreign database.
    dwError = VmDirSrvCreateReplAgrsContainer(pSchemaCtx);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = _VmDirPatchDSERoot(pSchemaCtx);
    BAIL_ON_VMDIR_ERROR(dwError);

    VmDirSchemaCtxRelease(pSchemaCtx);
    pSchemaCtx = NULL;

    dwError = LoadServerGlobals(&bWriteInvocationId);
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:
    if (pSchemaCtx)
    {
        VmDirSchemaCtxRelease(pSchemaCtx);
    }

    VmDirFreeEntryArrayContent(&entryArray);

    VMDIR_SAFE_FREE_MEMORY(pszConfigurationContainerDn);
    VMDIR_SAFE_FREE_MEMORY(pszDomainControllerContainerDn);

    while(!dequeIsEmpty(&computers))
    {
        dequePopLeft(&computers, (PVOID*)&pszComputer);
        VMDIR_SAFE_FREE_MEMORY(pszComputer);
    }
    return dwError;

error:
    goto cleanup;
}
Ejemplo n.º 15
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;
}
Ejemplo n.º 16
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;
}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
0
DWORD
VmDirCreateAccountEx(
    PVMDIR_SRV_ACCESS_TOKEN       pAccessToken,
    PVMDIR_USER_CREATE_PARAMS_RPC pCreateParams
    )
{
    DWORD dwError = 0;
    PVDIR_SCHEMA_CTX pSchemaCtx = NULL;
    VMDIR_USER_CREATE_PARAMS_W  createParamsW = {0};
    PVMDIR_USER_CREATE_PARAMS_A pCreateParamsA = NULL;
    PSTR  pszName_local = NULL; // Do not free
    PSTR  pszName      = NULL;
    PSTR  pszUPN_local = NULL;  // Do not free
    PSTR  pszUPN       = NULL;
    PSTR  pszAccountDN = NULL;
    PSTR  pszDomain    = NULL;
    PSTR  pszDomainDN  = NULL;
    PSTR  pszUpperDomain = NULL;
    DWORD i = 0;

    dwError = VmDirSrvValidateUserCreateParams(pCreateParams);
    BAIL_ON_VMDIR_ERROR(dwError);

    createParamsW.pwszName      = pCreateParams->pwszName;
    createParamsW.pwszAccount   = pCreateParams->pwszAccount;
    createParamsW.pwszUPN       = pCreateParams->pwszUPN;
    createParamsW.pwszFirstname = pCreateParams->pwszFirstname;
    createParamsW.pwszLastname  = pCreateParams->pwszLastname;
    createParamsW.pwszPassword  = pCreateParams->pwszPassword;

    dwError = VmDirAllocateUserCreateParamsAFromW(
                    &createParamsW,
                    &pCreateParamsA);
    BAIL_ON_VMDIR_ERROR(dwError);

    if (IsNullOrEmptyString(pCreateParamsA->pszName))
    {
        dwError = VmDirAllocateStringPrintf(
                        &pszName,
                        "%s %s",
                        pCreateParamsA->pszFirstname,
                        pCreateParamsA->pszLastname);
        BAIL_ON_VMDIR_ERROR(dwError);

        pszName_local = pszName;
    }
    else
    {
        pszName_local = pCreateParamsA->pszName;
    }

    dwError = VmDirSrvGetCallerDomain(pAccessToken, &pszDomain);
    BAIL_ON_VMDIR_ERROR(dwError);

    if (IsNullOrEmptyString(pCreateParamsA->pszUPN))
    {
        if (VmDirStringChrA(pCreateParamsA->pszAccount, '@') == NULL)
        {
            dwError = VmDirAllocateStringPrintf(
                            &pszUpperDomain,
                            "%s",
                            pszDomain);
            BAIL_ON_VMDIR_ERROR(dwError);

            for (i=0; pszUpperDomain[i]; i++)
            {
                VMDIR_ASCII_LOWER_TO_UPPER(pszUpperDomain[i]);
            }

            dwError = VmDirAllocateStringPrintf(
                            &pszUPN,
                            "%s@%s",
                            pCreateParamsA->pszAccount,
                            pszUpperDomain);
            BAIL_ON_VMDIR_ERROR(dwError);
        }
        else
        {
            dwError = VmDirAllocateStringA(pCreateParamsA->pszAccount, &pszUPN);
            BAIL_ON_VMDIR_ERROR(dwError);
        }

        pszUPN_local = pszUPN;
    }
    else
    {
        pszUPN_local = pCreateParamsA->pszUPN;
    }

    dwError = VmDirFQDNToDN(pszDomain, &pszDomainDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirAllocateStringPrintf(
                    &pszAccountDN,
                    "CN=%s,%s,%s",
                    pszName_local,
                    DEFAULT_USER_CONTAINER_RDN,
                    pszDomainDN);
    BAIL_ON_VMDIR_ERROR(dwError);

    do
    {
        PSTR    ppszAttributes[] =
        {
                ATTR_OBJECT_CLASS,      (PSTR)OC_USER,
                ATTR_CN,                pszName_local,
                ATTR_USER_PASSWORD,     pCreateParamsA->pszPassword,
                ATTR_SAM_ACCOUNT_NAME,  pCreateParamsA->pszAccount,
                ATTR_KRB_UPN,           pszUPN_local,
                ATTR_SN,                pCreateParamsA->pszLastname,
                ATTR_GIVEN_NAME,        pCreateParamsA->pszFirstname,
                NULL
        };

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

        dwError = VmDirSimpleEntryCreate(
                        pSchemaCtx,
                        ppszAttributes,
                        pszAccountDN,
                        0);
        BAIL_ON_VMDIR_ERROR(dwError);

    } while (0);

cleanup:

    VmDirSchemaCtxRelease(pSchemaCtx);

    VMDIR_SAFE_FREE_MEMORY(pszName);
    VMDIR_SAFE_FREE_MEMORY(pszUPN);
    VMDIR_SAFE_FREE_MEMORY(pszDomain);
    VMDIR_SAFE_FREE_MEMORY(pszDomainDN);
    VMDIR_SAFE_FREE_MEMORY(pszAccountDN);
    VMDIR_SAFE_FREE_MEMORY(pszUpperDomain);

    if (pCreateParamsA)
    {
        VmDirFreeUserCreateParamsA(pCreateParamsA);
    }

    return dwError;

error:

    VMDIR_LOG_ERROR(
         VMDIR_LOG_MASK_ALL,
         "VmDirCreateAccountEx Account(%s) failed, (%u)",
         VDIR_SAFE_STRING(pCreateParamsA ? pCreateParamsA->pszAccount : NULL),
         dwError);

    goto cleanup;
}
Ejemplo n.º 19
0
void
VmDirFreeOperationContent(
    PVDIR_OPERATION op
    )
{
    DWORD dwError = ERROR_SUCCESS;

    if (op)
    {
        if (op->pSchemaCtx)
        {
            VmDirSchemaCtxRelease(op->pSchemaCtx);
        }

        if (op->syncDoneCtrl)
        {
            PLW_HASHTABLE_NODE      pNode = NULL;
            LW_HASHTABLE_ITER       iter = LW_HASHTABLE_ITER_INIT;
            UptoDateVectorEntry *   pUtdVectorEntry = NULL;
            SyncDoneControlValue *  syncDoneCtrlVal = &op->syncDoneCtrl->value.syncDoneCtrlVal;

            while ((pNode = LwRtlHashTableIterate(syncDoneCtrlVal->htUtdVector, &iter)))
            {
                dwError = LwRtlHashTableRemove(syncDoneCtrlVal->htUtdVector, pNode);
                assert( dwError == 0 );
                pUtdVectorEntry = LW_STRUCT_FROM_FIELD(pNode, UptoDateVectorEntry, Node);
                VmDirFreeBervalContent( &pUtdVectorEntry->invocationId );
                VMDIR_SAFE_FREE_MEMORY( pUtdVectorEntry );
            }
            LwRtlFreeHashTable(&syncDoneCtrlVal->htUtdVector);
            assert( syncDoneCtrlVal->htUtdVector == NULL );

            VMDIR_SAFE_FREE_MEMORY( op->syncDoneCtrl );
        }

        if (op->pCondWriteCtrl)
        {
            VMDIR_SAFE_FREE_MEMORY(op->pCondWriteCtrl->value.condWriteCtrlVal.pszFilter);
        }

        if (op->reqControls)
        {
            DeleteControls(&(op->reqControls));
        }

        switch (op->reqCode)
        {
            case LDAP_REQ_BIND:
                 VmDirFreeBindRequest(&op->request.bindReq, FALSE);
                 if (op->ldapResult.replyInfo.type == REP_SASL)
                 {
                     VmDirFreeBervalContent( &(op->ldapResult.replyInfo.replyData.bvSaslReply) );
                 }
                 break;

            case LDAP_REQ_ADD:
                 VmDirFreeAddRequest(&op->request.addReq, FALSE);
                 break;

            case LDAP_REQ_SEARCH:
                 VmDirFreeSearchRequest(&op->request.searchReq, FALSE);
                 break;

            case LDAP_REQ_MODIFY:
            case LDAP_REQ_MODDN:
                 VmDirFreeModifyRequest(&op->request.modifyReq, FALSE);
                 break;

            case LDAP_REQ_DELETE:
                 VmDirFreeDeleteRequest(&op->request.deleteReq, FALSE);
                 if (op->request.modifyReq.numMods > 0)
                 {
                     //A raft follower needs to create a modifyReq for Delete OP
                     VmDirFreeModifyRequest(&op->request.modifyReq, FALSE);
                 }
                 break;

            default:
                 break;
        }

        VmDirFreeEntryArrayContent(&(op->internalSearchEntryArray));
        VmDirFreeBervalContent( &(op->reqDn) );
        VMDIR_SAFE_FREE_MEMORY(op->ldapResult.pszErrMsg);
        VmDirBackendCtxFree(op->pBECtx);
        VMDIR_SAFE_FREE_MEMORY(op->pszFilters);

        if ( op->opType == VDIR_OPERATION_TYPE_INTERNAL )
        {   // internal op owns dummy conn for ACL check
            VmDirDeleteConnection( &(op->conn)); // passing &conn to be freed seems a bit strange
        }
   }
}
Ejemplo n.º 20
0
/*
 * convert schema file into entry
 */
DWORD
VmDirSchemaInitalizeFileToEntry(
    PCSTR           pszSchemaFilePath,
    PVDIR_ENTRY*    ppEntry
    )
{
    DWORD    dwError = 0;
    USHORT   dwCnt = 0;
    PVDIR_ENTRY    pEntry = NULL;

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

    PSTR*    ppszDescs = NULL;
    USHORT   dwDescSize = 0;

    PSTR*    ppszSyntaxes = NULL;
    USHORT   dwSyntaxSize = 0;

    PSTR*    ppszMRs = NULL;
    USHORT   dwMRSize = 0;

    PVDIR_SCHEMA_CTX    pCtx = NULL;

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

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

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

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

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

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

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

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

    pEntry->allocType = ENTRY_STORAGE_FORMAT_NORMAL;

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

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

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

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

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

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

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

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

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

    pEntry->eId = SUB_SCEHMA_SUB_ENTRY_ID;

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

cleanup:

    if (pCtx)
    {
        VmDirSchemaCtxRelease(pCtx);
    }

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

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

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

    return dwError;

error:

    if (pEntry)
    {
        VmDirFreeEntry(pEntry);
    }

    goto cleanup;

}