Exemple #1
0
static
int
GenerateNewParent(
    PVDIR_ENTRY pEntry,
    PVDIR_ATTRIBUTE pDnAttr
    )
{
    int retVal = 0;
    VDIR_BERVALUE  NewParent = VDIR_BERVALUE_INIT;

    if (!pEntry->pdn.bvnorm_val)
    {
        VmDirFreeBervalContent(&pEntry->pdn);

        retVal = VmDirGetParentDN(&pEntry->dn, &pEntry->pdn);
        BAIL_ON_VMDIR_ERROR(retVal);
    }

    retVal = VmDirGetParentDN(&pDnAttr->vals[0], &NewParent);
    BAIL_ON_VMDIR_ERROR(retVal);

    if (VmDirStringCompareA(pEntry->pdn.bvnorm_val, NewParent.bvnorm_val, FALSE) != 0)
    {
        retVal = VmDirBervalContentDup(&NewParent, &pEntry->newpdn);
        BAIL_ON_VMDIR_ERROR(retVal);
    }

cleanup:
    VmDirFreeBervalContent(&NewParent);
    return retVal;

error:
    goto cleanup;
}
Exemple #2
0
/*
 * Allocate string into pDupBerval
 */
DWORD
VmDirStringToBervalContent(
    PCSTR              pszBerval,
    PVDIR_BERVALUE     pDupBerval
    )
{
    DWORD    dwError = 0;

    VmDirFreeBervalContent(pDupBerval);

    dwError = VmDirAllocateStringA(pszBerval, &pDupBerval->lberbv.bv_val);
    BAIL_ON_VMDIR_ERROR(dwError);

    pDupBerval->bOwnBvVal = TRUE;

    pDupBerval->lberbv.bv_len = VmDirStringLenA(pDupBerval->lberbv.bv_val);

cleanup:

    return dwError;

error:

    VmDirFreeBervalContent(pDupBerval);

    goto cleanup;
}
Exemple #3
0
/*
 *  called by replication thread only
 */
VOID
VmDirFreeReplicationAgreement(
    PVMDIR_REPLICATION_AGREEMENT    pReplAgr
    )
{
    if (pReplAgr && pReplAgr->dcConn.connState != DC_CONNECTION_STATE_CONNECTING)
    {
        VmDirFreeDCConnContent(&pReplAgr->dcConn);
        VmDirFreeBervalContent(&pReplAgr->lastLocalUsnProcessed);
        VmDirFreeBervalContent(&pReplAgr->dn);
        VMDIR_SAFE_FREE_MEMORY(pReplAgr->pszHostname);
        VMDIR_SAFE_FREE_MEMORY(pReplAgr->pszInvocationID);
        VMDIR_SAFE_FREE_MEMORY(pReplAgr);
    }
}
Exemple #4
0
/*
 * Free a heap Attribute
 * (ATTENTION: if the pAttr is within a pEntry, only when pEntry is constructed as
 * ENTRY_STORAGE_FORMAT_NORMAL allocation type, its attribute can be freed using this function;
 * otherwise, an entry's attribute free is taken care of by 'pEntry->bvs'
 */
VOID
VmDirFreeAttribute(
    PVDIR_ATTRIBUTE pAttr
    )
{
    if (!pAttr)
    {
        return;
    }

    // pAttr->type is always store in place and has NO bvnorm_val.  no need to free here.
    if (!dequeIsEmpty(&pAttr->valueMetaDataToAdd))
    {
        VmDirFreeAttrValueMetaDataDequeueContent(&pAttr->valueMetaDataToAdd);
    }
    if (!dequeIsEmpty(&pAttr->valueMetaDataToDelete))
    {
        VmDirFreeAttrValueMetaDataDequeueContent(&pAttr->valueMetaDataToDelete);
    }

    VmDirFreeMetaData(pAttr->pMetaData);

    VmDirFreeBervalContent(&pAttr->type);
    VmDirFreeBervalArrayContent(pAttr->vals, pAttr->numVals);
    VMDIR_SAFE_FREE_MEMORY(pAttr->vals);
    VMDIR_SAFE_FREE_MEMORY(pAttr);
}
Exemple #5
0
void
VmDirFreeBindRequest(
    BindReq*     pBindReq,
    BOOLEAN      bFreeSelf)
{
    if (pBindReq != NULL)
    {
        VmDirFreeBervalContent( &(pBindReq->cred) );
        VmDirFreeBervalContent( &(pBindReq->bvMechanism) );

        if (bFreeSelf)
        {
            VMDIR_SAFE_FREE_MEMORY( pBindReq );
        }
    }
}
Exemple #6
0
/*
 * Free SASL related resources.
 */
VOID
VmDirSASLSessionClose(
    PVDIR_SASL_BIND_INFO    pSaslBindInfo
    )
{
    if (pSaslBindInfo)
    {
        if (pSaslBindInfo->pSaslCtx)
        {
            if (pSaslBindInfo->saslSSF > 0)
            {
                VmDirSASLSockbufRemove(pSaslBindInfo->pSockbuf);
            }

            sasl_dispose(&pSaslBindInfo->pSaslCtx);
            pSaslBindInfo->pSaslCtx = NULL;
        }

        VMDIR_SAFE_FREE_MEMORY(pSaslBindInfo->pSessionCB);
        VMDIR_SAFE_FREE_MEMORY(pSaslBindInfo->pszBindUserName);
        VmDirFreeBervalContent(&pSaslBindInfo->bvMechnism);
    }

    return;
}
Exemple #7
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;
}
Exemple #8
0
/*
 * Free a heap BerValue
 */
VOID
VmDirFreeBerval(
    VDIR_BERVALUE* pBerv
    )
{
    VmDirFreeBervalContent(pBerv);
    VMDIR_SAFE_FREE_MEMORY(pBerv);

    return;
}
Exemple #9
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;
}
Exemple #10
0
/*
 * Free a heap Attribute
 * (ATTENTION: if the pAttr is within a pEntry, only when pEntry is constructed as
 * ENTRY_STORAGE_FORMAT_NORMAL allocation type, its attribute can be freed using this function;
 * otherwise, an entry's attribute free is taken care of by 'pEntry->bvs'
 */
VOID
VmDirFreeAttribute(
    PVDIR_ATTRIBUTE pAttr
    )
{
    if (!pAttr)
    {
        return;
    }

    VmDirFreeBervalContent(&pAttr->type);
    VmDirFreeBervalArrayContent(pAttr->vals, pAttr->numVals);
    VMDIR_SAFE_FREE_MEMORY(pAttr->vals);
    VMDIR_SAFE_FREE_MEMORY(pAttr);
}
Exemple #11
0
void
VmDirFreeDeleteRequest(
   DeleteReq * dr,
   BOOLEAN     freeSelf
   )
{
    if (dr != NULL)
    {
        VmDirFreeBervalContent( &(dr->dn) );

        if (freeSelf)
        {
            VMDIR_SAFE_FREE_MEMORY( dr );
        }
    }

    return;
}
Exemple #12
0
static
void
RemoveAttrVals(
   VDIR_ATTRIBUTE * eAttr,    // Entry attribute to be updated after removing certain attribute values
   VDIR_ATTRIBUTE * modAttr   // Modify attribute containing attribute values to be deleted
   )
{
    unsigned int        i = 0;
    unsigned int        j = 0;
    int                 k = 0;

    for (i=0; i < eAttr->numVals; i++)
    {
        // eAttr values are already normalized.
        assert(eAttr->vals[i].bvnorm_val);

        for (j = 0; j < modAttr->numVals; j++)
        {
            // modAttr values are already normalized.
            assert(modAttr->vals[j].bvnorm_val);

            if (eAttr->vals[i].bvnorm_len == modAttr->vals[j].bvnorm_len &&
                memcmp(eAttr->vals[i].bvnorm_val, modAttr->vals[j].bvnorm_val, modAttr->vals[j].bvnorm_len) == 0)
            {
                break;
            }
        }
        if (j == modAttr->numVals) // current value (i th) is NOT being deleted
        {
            eAttr->vals[k++] = eAttr->vals[i];
        }
        else // current value (i th) is being deleted
        {
            VmDirFreeBervalContent(&eAttr->vals[i]);
        }
    }
    eAttr->numVals = k;
    memset(&(eAttr->vals[k]), 0, sizeof(VDIR_BERVALUE)); // set last BerValue.lberbv.bv_val to NULL;

    return;
}
Exemple #13
0
DWORD
VmDirResetPassword(
    PCSTR       pszUPN,
    PCSTR       pszNewPassword
    )
{
    DWORD               dwError = 0;
    VDIR_BERVALUE       bvPassword = VDIR_BERVALUE_INIT;
    PSTR                pszDN = NULL;

    if ( IsNullOrEmptyString(pszUPN) || IsNullOrEmptyString(pszNewPassword) )
    {
        dwError = VMDIR_ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = VmDirUPNToDN( pszUPN, &pszDN );
    BAIL_ON_VMDIR_ERROR(dwError);

    bvPassword.lberbv_val = (PSTR)pszNewPassword;
    bvPassword.lberbv_len = VmDirStringLenA(pszNewPassword);
    dwError = VmDirInternalEntryAttributeReplace( NULL,
                                                  pszDN,
                                                  ATTR_USER_PASSWORD,
                                                  &bvPassword);
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:

    VmDirFreeBervalContent(&bvPassword);

    return dwError;

error:

    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "VmDirResetPassword (%s) failed, (%u)",
                              VDIR_SAFE_STRING(pszUPN), dwError);
    goto cleanup;
}
Exemple #14
0
static
DWORD
_VmDirRESTCreateCondWriteCtrl(
    PVDIR_OPERATION pOp,
    PCSTR           pszTenant,
    PCSTR           pszCondWriteFilter
    )
{
    DWORD           dwError = 0;
    VDIR_BERVALUE   bvFilter = VDIR_BERVALUE_INIT;
    PVDIR_FILTER    pObjectFilter = NULL;
    PVDIR_FILTER    pDNFilter = NULL;

    dwError = StrFilterToFilter(pszCondWriteFilter, &pObjectFilter);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirRESTFilterObjectToDN(
                pszTenant,
                pObjectFilter,
                &pDNFilter);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = FilterToStrFilter(pDNFilter, &bvFilter);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirAddCondWriteCtrl(pOp, bvFilter.lberbv_val);
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:
    VmDirFreeBervalContent(&bvFilter);
    DeleteFilter(pObjectFilter);
    DeleteFilter(pDNFilter);

    return dwError;

error:
    goto cleanup;
}
Exemple #15
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;
}
Exemple #16
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
        }
   }
}
Exemple #17
0
/*
 * Determine whether the supplier's attr-value-meta-data wins by checking it against local
 * attr-meta-data and local attr-value-meta-data.
 * It first compares the <version><invocation-id> of that in local attr-meta-data which was
 * applied either in the previous transaction or the previous modification in the current
 * transactions. Then if the <version><invocation-id> matches, it looks up the local server
 * to see if the same attr-value-meta-data exist: if supplier's attr-value-meta-data has a
 * newer timestamp then it wins and inScope set to TRUE.
 */
DWORD
VmDirReplResolveValueMetaDataConflicts(
    PVDIR_OPERATION                    pModOp,
    PVDIR_ATTRIBUTE                    pAttr,
    PVMDIR_VALUE_ATTRIBUTE_METADATA    pSupplierValueMetaData,
    ENTRYID                            entryId,
    PBOOLEAN                           pInScope
    )
{
    DWORD                              dwError = 0;
    VDIR_BERVALUE                      bervSupplierValueMetaData = VDIR_BERVALUE_INIT;
    VDIR_BERVALUE                      bervConsumerValueMetaData = VDIR_BERVALUE_INIT;
    DEQUE                              valueMetaDataQueue = {0};
    PVMDIR_VALUE_ATTRIBUTE_METADATA    pConsumerValueMetaData = NULL;

    if (!pModOp || !pAttr || !pSupplierValueMetaData || !pInScope)
    {
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER);
    }

    *pInScope = TRUE;
    dwError = pModOp->pBEIF->pfnBEGetAttrMetaData(pModOp->pBECtx, pAttr, entryId);
    BAIL_ON_VMDIR_ERROR(dwError);

    //Consumer <version><originating-server-id> in metaValueData
    //not match supplier's <version<<originating-server-id> in metaData
    //this value-meta-data out of scope
    if (pSupplierValueMetaData->version != pAttr->pMetaData->version ||
        VmDirStringCompareA(
            pSupplierValueMetaData->pszOrigInvoId, pAttr->pMetaData->pszOrigInvoId, TRUE) != 0)
    {
        *pInScope = FALSE;
        goto cleanup;
    }

    if (VmDirLogGetMask() & LDAP_DEBUG_REPL)
    {
        //Ignore error, used only for logging
        VmDirValueMetaDataSerialize(pSupplierValueMetaData, &bervSupplierValueMetaData);
        VmDirValueMetaDataSerialize(pConsumerValueMetaData, &bervConsumerValueMetaData);
    }

    dwError = pModOp->pBEIF->pfnBEGetAttrValueMetaData(
            pModOp->pBECtx, entryId, pAttr->pATDesc->usAttrID, &valueMetaDataQueue);
    BAIL_ON_VMDIR_ERROR(dwError);

    while(!dequeIsEmpty(&valueMetaDataQueue))
    {
        VMDIR_SAFE_FREE_VALUE_METADATA(pConsumerValueMetaData);

        dequePopLeft(&valueMetaDataQueue, (PVOID*)&pConsumerValueMetaData);

        if (pConsumerValueMetaData->dwValSize != pSupplierValueMetaData->dwValSize ||
            VmDirCompareMemory(
                    pConsumerValueMetaData->pszValue,
                    pSupplierValueMetaData->pszValue,
                    pConsumerValueMetaData->dwValSize) != 0)
        {
            continue;
        }

        if (VmDirStringCompareA(
                    pConsumerValueMetaData->pszValChgOrigTime,
                    pSupplierValueMetaData->pszValChgOrigTime,
                    TRUE) > 0)
        {
            *pInScope = FALSE;

            VMDIR_LOG_DEBUG(
                    LDAP_DEBUG_REPL,
                    "%s: supplier attr-value-meta lose: %s consumer: %s",
                    __FUNCTION__,
                    VDIR_SAFE_STRING(bervSupplierValueMetaData.lberbv_val),
                    VDIR_SAFE_STRING(bervConsumerValueMetaData.lberbv_val));
        }
    }

    if (*pInScope)
    {
        VMDIR_LOG_DEBUG(
                LDAP_DEBUG_REPL,
                "%s: supplier attr-value-meta won: %s",
                __FUNCTION__,
                VDIR_SAFE_STRING(bervSupplierValueMetaData.lberbv_val));
    }

cleanup:
    VmDirFreeBervalContent(&bervSupplierValueMetaData);
    VmDirFreeBervalContent(&bervConsumerValueMetaData);
    VMDIR_SAFE_FREE_VALUE_METADATA(pConsumerValueMetaData);
    VmDirFreeAttrValueMetaDataDequeueContent(&valueMetaDataQueue);
    return dwError;

error:
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError);
    goto cleanup;
}
Exemple #18
0
/*
 * Set SRP Identifier's secret on existing entry with Password set
 */
DWORD
VmDirSRPSetIdentityData(
    PCSTR       pszUPN,
    PCSTR       pszClearTextPassword
    )
{
    DWORD               dwError = 0;
    VDIR_OPERATION      op = {0};
    PSTR                pszLocalErrMsg = NULL;
    VDIR_ENTRY_ARRAY    entryArray = {0};
    PVDIR_ENTRY         pEntry = NULL;
    PVDIR_ATTRIBUTE     pAttrSecret = NULL;
    VDIR_BERVALUE       bvUPN = VDIR_BERVALUE_INIT;
    VDIR_BERVALUE       bvClearTextPassword = VDIR_BERVALUE_INIT;
    VDIR_BERVALUE       bervSecretBlob = VDIR_BERVALUE_INIT;


    if ( IsNullOrEmptyString(pszUPN)    ||
         IsNullOrEmptyString(pszClearTextPassword)
        )
    {
        dwError = VMDIR_ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    bvUPN.lberbv_val = (PSTR)pszUPN;
    bvUPN.lberbv_len = VmDirStringLenA(pszUPN);

    bvClearTextPassword.lberbv_val = (PSTR)pszClearTextPassword;
    bvClearTextPassword.lberbv_len = VmDirStringLenA(pszClearTextPassword);

    dwError = VmDirSimpleEqualFilterInternalSearch(
                    "",
                    LDAP_SCOPE_SUBTREE,
                    ATTR_KRB_UPN,
                    pszUPN,
                    &entryArray);
    BAIL_ON_VMDIR_ERROR(dwError);

    if (entryArray.iSize == 1)
    {
        pAttrSecret = VmDirFindAttrByName(&(entryArray.pEntry[0]), ATTR_SRP_SECRET);
        if (pAttrSecret)
        {
            dwError = VMDIR_ERROR_ENTRY_ALREADY_EXIST;
            BAIL_ON_VMDIR_ERROR(dwError);
        }
    }
    else
    {
        dwError = VMDIR_ERROR_DATA_CONSTRAINT_VIOLATION;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    pEntry = &(entryArray.pEntry[0]);

    dwError = VdirPasswordCheck(&bvClearTextPassword, pEntry);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirSRPCreateSecret(&bvUPN, &bvClearTextPassword, &bervSecretBlob);
    BAIL_ON_VMDIR_ERROR(dwError);


    if (pEntry->allocType == ENTRY_STORAGE_FORMAT_PACK)
    {
        dwError = VmDirEntryUnpack( pEntry );
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = VmDirInitStackOperation( &op, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_MODIFY, NULL);
    BAIL_ON_VMDIR_ERROR_WITH_MSG(dwError, pszLocalErrMsg, "VmDirSRPSetIdentityData: VmDirInitStackOperation failed: %u", dwError);

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

    op.reqDn.lberbv.bv_val = pEntry->dn.lberbv.bv_val;
    op.reqDn.lberbv.bv_len = pEntry->dn.lberbv.bv_len;
    op.request.modifyReq.dn.lberbv = op.reqDn.lberbv;

    dwError = VmDirAppendAMod( &op,
                               MOD_OP_ADD,
                               ATTR_SRP_SECRET,
                               ATTR_SRP_SECRET_LEN,
                               bervSecretBlob.lberbv_val,
                               bervSecretBlob.lberbv_len);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirInternalModifyEntry(&op);
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:

    VmDirFreeBervalContent(&bervSecretBlob);
    VmDirFreeEntryArrayContent(&entryArray);
    VmDirFreeOperationContent(&op);
    return dwError;

error:

    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL,
                     "VmDirSRPSetIdentityData (%s) failed, (%u)", VDIR_SAFE_STRING(pszUPN), dwError);
    goto cleanup;
}
Exemple #19
0
/*
 * Test whether the origUsn is in scope so that attribute, attr-meta-data or
 * attr-value-meta-data be sent back to the replicaiton consumer based on whether
 * the origUsn for that invocationId has been processed already by the consumer
 * TODO: Needed Refractoring
 */
DWORD
VmDirIsUsnInScope(
    PVDIR_OPERATION     pOperation,
    PCSTR               pAttrName,
    PCSTR               pszOrigInvocationId,
    USN                 origUsn,
    USN                 localUSN,
    USN                 priorSentUSNCreated,
    PBOOLEAN            pbIsUsnInScope
    )
{
    DWORD                   dwError = 0;
    PLW_HASHTABLE_NODE      pNode = NULL;
    PSTR                    pszLocalErrorMsg = NULL;
    UptoDateVectorEntry     *pUtdVectorEntry = NULL;
    UptoDateVectorEntry     *pNewUtdVectorEntry = NULL;
    int                     retVal = 0;

    if (!pOperation ||
        !pszOrigInvocationId ||
        !pbIsUsnInScope ||
        !pOperation->syncReqCtrl ||
        !pOperation->syncDoneCtrl)
    {
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER);
    }

    *pbIsUsnInScope = FALSE;

    //Originating server for the current state is same as the requesting server
    if (VmDirStringCompareA(
                pszOrigInvocationId,
                pOperation->syncReqCtrl->value.syncReqCtrlVal.reqInvocationId.lberbv.bv_val,
                TRUE) == 0)
    {
        *pbIsUsnInScope = FALSE;
        goto cleanup;
    }

    retVal = LwRtlHashTableFindKey(
            pOperation->syncDoneCtrl->value.syncDoneCtrlVal.htUtdVector, &pNode, pszOrigInvocationId);

    retVal = LwNtStatusToWin32Error(retVal);

    if (retVal != 0 && retVal != ERROR_NOT_FOUND)
    {
        VMDIR_LOG_VERBOSE(
                VMDIR_LOG_MASK_ALL,
                "%s: LwRtlHashTableFindKey failed for origInvocationId: %s",
                __FUNCTION__,
                pszOrigInvocationId);
        dwError = LDAP_OPERATIONS_ERROR;
        BAIL_ON_VMDIR_ERROR_WITH_MSG(dwError, (pszLocalErrorMsg), "LwRtlHashTableFindKey failed.");
    }

    if (pNode == NULL)
    {
        VDIR_BERVALUE    bvServerId = VDIR_BERVALUE_INIT;

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

        bvServerId.lberbv.bv_val = (PSTR)pszOrigInvocationId;
        bvServerId.lberbv.bv_len = VmDirStringLenA(pszOrigInvocationId);

        dwError = VmDirBervalContentDup(&bvServerId, &pNewUtdVectorEntry->invocationId);
        BAIL_ON_VMDIR_ERROR(dwError);

        pNewUtdVectorEntry->currMaxOrigUsnProcessed = origUsn;

        LwRtlHashTableResizeAndInsert(
                pOperation->syncDoneCtrl->value.syncDoneCtrlVal.htUtdVector,
                &pNewUtdVectorEntry->Node,
                &pNode);

        // assert the key of added node is unique
        assert(pNode == NULL);

        pNewUtdVectorEntry = NULL;
        *pbIsUsnInScope = TRUE;

        goto cleanup;
    }

    pUtdVectorEntry = (UptoDateVectorEntry *)LW_STRUCT_FROM_FIELD(pNode, UptoDateVectorEntry, Node);

    if (origUsn > pUtdVectorEntry->reqLastOrigUsnProcessed )
    {
        // attribute or the valueMetaData item in scope if origUsn valueMetaData is > the current highest
        if (origUsn > pUtdVectorEntry->currMaxOrigUsnProcessed )
        {
            pUtdVectorEntry->currMaxOrigUsnProcessed = origUsn;
        }

        // Note, this handles ADD->MODIFY case but not multiple MODIFYs scenario.
        // However, it is fine as consumer should be able to handle redundant feed from supplier.
        // The key point here is to NOT send ATTR_USN_CREATED, so we can derive correct sync_state in WriteSyncStateControl.
        if (localUSN > priorSentUSNCreated)
        {
            *pbIsUsnInScope = TRUE;

            if (priorSentUSNCreated > 0)
            {
                VMDIR_LOG_INFO(
                        LDAP_DEBUG_REPL,
                        "%s new usn %llu after prior usncreated %llu attr %s",
                        __FUNCTION__,
                        origUsn,
                        priorSentUSNCreated,
                        VDIR_SAFE_STRING(pAttrName));
            }
        }
        else
        {
            VMDIR_LOG_INFO(
                    LDAP_DEBUG_REPL,
                    "%s (add->modify) race condition avoided. skip prior usncreated %llu attr %s",
                    __FUNCTION__,
                    priorSentUSNCreated,
                    VDIR_SAFE_STRING(pAttrName));
        }

        goto cleanup;
    }

    VMDIR_LOG_INFO(
            LDAP_DEBUG_REPL,
            "%s: (not in scope) attr name: %s orig invo: %s utdUsn: %"PRId64" usn: %"PRId64,
            __FUNCTION__,
            VDIR_SAFE_STRING(pAttrName),
            VDIR_SAFE_STRING(pszOrigInvocationId),
            pUtdVectorEntry->reqLastOrigUsnProcessed,
            origUsn);

cleanup:
    VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg);
    return dwError;

error:
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError);
    if (pNewUtdVectorEntry)
    {
        VmDirFreeBervalContent(&pNewUtdVectorEntry->invocationId);
    }
    VMDIR_SAFE_FREE_MEMORY(pNewUtdVectorEntry);
    goto cleanup;
}
Exemple #20
0
DWORD
VmDirIsAttrValueInScope(
   PVDIR_OPERATION    pOperation,
   PDEQUE             pAllValueMetaDataQueue,
   PDEQUE             pValueMetaDataToSendQueue
   )
{
    DWORD                              dwError = 0;
    VDIR_BERVALUE                      bervValueMetaData = VDIR_BERVALUE_INIT;
    PVMDIR_VALUE_ATTRIBUTE_METADATA    pValueMetaData = NULL;

    if (!pOperation ||
        !pAllValueMetaDataQueue ||
        !pValueMetaDataToSendQueue)
    {
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER);
    }

    while (!dequeIsEmpty(pAllValueMetaDataQueue))
    {
        BOOLEAN bUsnInScope = FALSE;

        VMDIR_SAFE_FREE_VALUE_METADATA(pValueMetaData);
        dequePopLeft(pAllValueMetaDataQueue, (PVOID*)&pValueMetaData);

        dwError = VmDirIsUsnInScope(
                pOperation,
                NULL,
                pValueMetaData->pszValChgOrigInvoId,
                pValueMetaData->valChgOrigUsn,
                pValueMetaData->localUsn,
                0,
                &bUsnInScope);
        BAIL_ON_VMDIR_ERROR(dwError);

        if (!bUsnInScope)
        {
            continue;
        }

        if (VmDirLogGetMask() & LDAP_DEBUG_REPL)
        {
            //ignore error
            VmDirValueMetaDataSerialize(pValueMetaData, &bervValueMetaData);
            VMDIR_LOG_INFO(
                    LDAP_DEBUG_REPL,
                    "%s: valueMetaData: %s, usnInScope true",
                    __FUNCTION__,
                    VDIR_SAFE_STRING(bervValueMetaData.lberbv_val));
            VmDirFreeBervalContent(&bervValueMetaData);
        }

        dwError = dequePush(pValueMetaDataToSendQueue, pValueMetaData);
        BAIL_ON_VMDIR_ERROR(dwError);

        pValueMetaData = NULL;
    }

cleanup:
    VMDIR_SAFE_FREE_VALUE_METADATA(pValueMetaData);
    return dwError;

error:
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError);
    goto cleanup;
}
Exemple #21
0
int
VmDirPerformSearch(
    PVDIR_OPERATION   pOperation
    )
{
   ber_len_t     size = 0;
   SearchReq *   sr = &(pOperation->request.searchReq);
   int           retVal = LDAP_SUCCESS;
   BerValue*           pLberBerv = NULL;
   PSTR                pszLocalErrorMsg = NULL;
   BOOLEAN             bResultAlreadySent = FALSE;
   PVDIR_LDAP_RESULT   pResult = &(pOperation->ldapResult);

   // Parse base object, scope, deref alias, sizeLimit, timeLimit and typesOnly search parameters.
   if ( ber_scanf( pOperation->ber, "{miiiib", &(pOperation->reqDn.lberbv), &sr->scope, &sr->derefAlias, &sr->sizeLimit,
                   &sr->timeLimit, &sr->attrsOnly ) == LBER_ERROR )
   {
      VMDIR_LOG_ERROR( LDAP_DEBUG_ARGS, "PerformSearch: Decoding baseDN, ... attrsOnly error." );
      pResult->errCode = LDAP_PROTOCOL_ERROR;
      retVal = LDAP_NOTICE_OF_DISCONNECT;
      BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                      "Decoding error while parsing baseDN, ... attrsOnly.");
   }

   VMDIR_LOG_VERBOSE( LDAP_DEBUG_ARGS, "Search Request: base: \"%s\", scope: %d, deref: %d, sizeLimit: %d, timeLimit: %d,"
             "attrsOnly: %d", pOperation->reqDn.lberbv.bv_val, sr->scope, sr->derefAlias, sr->sizeLimit, sr->timeLimit,
             sr->attrsOnly);

   if (sr->scope != LDAP_SCOPE_BASE && sr->scope != LDAP_SCOPE_ONELEVEL &&
       sr->scope != LDAP_SCOPE_SUBTREE)
   {
       pResult->errCode = retVal = LDAP_PROTOCOL_ERROR;
       BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "Invalid scope" );
   }

   if (sr->sizeLimit < 0 || sr->sizeLimit > LDAP_MAXINT)
   {
       pResult->errCode = retVal = LDAP_PROTOCOL_ERROR;
       BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "Invalid size limit: %d", sr->sizeLimit  );
   }

   if (sr->timeLimit < 0 || sr->timeLimit > LDAP_MAXINT)
   {
       pResult->errCode = retVal = LDAP_PROTOCOL_ERROR;
       BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "Invalid time limit: %d", sr->timeLimit );
   }

   if (sr->derefAlias != LDAP_DEREF_NEVER && sr->derefAlias != LDAP_DEREF_SEARCHING &&
       sr->derefAlias != LDAP_DEREF_FINDING && sr->derefAlias != LDAP_DEREF_ALWAYS)
   {
      pResult->errCode = retVal = LDAP_PROTOCOL_ERROR;
      BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg), "Invalid dereference alias parameter");
   }

   // Parse filter
   retVal = ParseFilter( pOperation, &sr->filter, pResult );
   BAIL_ON_VMDIR_ERROR(retVal);

   // Log String filter, if desired.
   if (VmDirLogGetLevel() >= VMDIR_LOG_VERBOSE && VmDirLogGetMask() & LDAP_DEBUG_ARGS)
   {
      VDIR_BERVALUE strFilter = VDIR_BERVALUE_INIT;
      FilterToStrFilter( sr->filter, &strFilter );
      VMDIR_LOG_VERBOSE( LDAP_DEBUG_ARGS, "    Filter: %s", strFilter.lberbv.bv_val );
      VmDirFreeBervalContent(&strFilter);
   }

   // Parse attributes. 'M' => attribute names point within (in-place) the ber.
   size = sizeof( BerValue ); // Size of the structure is passed-in, and number of attributes are returned back in
                              // the same parameter.
   if ( ber_scanf( pOperation->ber, "{M}}", &pLberBerv, &size, 0 ) == LBER_ERROR )
   {
      pResult->errCode = LDAP_PROTOCOL_ERROR;
      retVal = LDAP_NOTICE_OF_DISCONNECT;
      BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg), "Decoding error while parsing required attributes.");
   }

   // copy pLberBerv content into sr->attrs
   if (pLberBerv && size > 0)
   {
       int iCnt = 0;

       if (VmDirAllocateMemory(sizeof(VDIR_BERVALUE) * (size+1), (PVOID*)&sr->attrs) != 0)
       {
           pResult->errCode = retVal = LDAP_OPERATIONS_ERROR;
           BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg), "no memory");
       }

       for (iCnt = 0; iCnt < size; iCnt++)
       {
           sr->attrs[iCnt].lberbv.bv_val = pLberBerv[iCnt].bv_val;
           sr->attrs[iCnt].lberbv.bv_len = pLberBerv[iCnt].bv_len;
       }
   }

   // Log list of the required attributes, if desired.
   if (( VmDirLogGetMask() & LDAP_DEBUG_ARGS) && size > 0)
   {
       if (VmDirLogSearchRequest(sr, size) != 0)
       {
           pResult->errCode = retVal = LDAP_OPERATIONS_ERROR;
           BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg), "Error while logging search request");
       }
   }

   // Parse LDAP controls present (if any) in the request.
   retVal = ParseRequestControls(pOperation, pResult);  // ldapResult.errCode set inside
   BAIL_ON_VMDIR_ERROR( retVal );

   retVal = pResult->errCode = VmDirMLSearch( pOperation );
   bResultAlreadySent = TRUE;
   BAIL_ON_VMDIR_ERROR(retVal);

cleanup:

    VMDIR_SAFE_FREE_MEMORY(pLberBerv);
    VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg);

    return retVal;

error:

    VMDIR_APPEND_ERROR_MSG(pResult->pszErrMsg, pszLocalErrorMsg);
    if (retVal != LDAP_NOTICE_OF_DISCONNECT && bResultAlreadySent == FALSE)
    {
        VmDirSendLdapResult( pOperation );
    }

    goto cleanup;
}
Exemple #22
0
static
DWORD
VmDirSrvModifyPersistedDSERoot(
    PVDIR_SCHEMA_CTX pSchemaCtx,
    PSTR             pszRootNamingContextDN,
    PSTR             pszConfigNamingContextDN,
    PSTR             pszSchemaNamingContextDN,
    PSTR             pszSubSchemaSubEntryDN,
    PSTR             pszServerDN,
    PSTR             pszDefaultAdminDN,
    PSTR             pszDCAccountDN,
    PSTR             pszDCAccountUPN,
    PSTR             pszDelObjsContainerDN,
    PSTR             pszSiteName
    )
{
    DWORD dwError = 0;
    PSTR ppszPersistedDSERootAttrs[] =
    {
            ATTR_ROOT_DOMAIN_NAMING_CONTEXT,    pszRootNamingContextDN,
            ATTR_DEFAULT_NAMING_CONTEXT,        pszRootNamingContextDN,
            ATTR_CONFIG_NAMING_CONTEXT,         pszConfigNamingContextDN,
            ATTR_SCHEMA_NAMING_CONTEXT,         pszSchemaNamingContextDN,
            ATTR_SUB_SCHEMA_SUB_ENTRY,          pszSubSchemaSubEntryDN,
            ATTR_NAMING_CONTEXTS,               pszRootNamingContextDN,
            ATTR_NAMING_CONTEXTS,               pszConfigNamingContextDN,
            ATTR_NAMING_CONTEXTS,               pszSchemaNamingContextDN,
            ATTR_SERVER_NAME,                   pszServerDN,
            ATTR_DEFAULT_ADMIN_DN,              pszDefaultAdminDN,
            ATTR_DC_ACCOUNT_DN,                 pszDCAccountDN,
            ATTR_DC_ACCOUNT_UPN,                pszDCAccountUPN,
            ATTR_DEL_OBJS_CONTAINER,            pszDelObjsContainerDN,
            ATTR_SITE_NAME,                     pszSiteName,
            NULL
    };

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

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

    // Setup target DN

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

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

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

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

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

    // Setup mods

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

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

    // Modify

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

cleanup:

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

    return dwError;

error:
    VmDirLog(LDAP_DEBUG_ANY, VDIR_SAFE_STRING(pszLocalErrMsg) );
    goto cleanup;
}
Exemple #23
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;
}
Exemple #24
0
/*
 * 1) Find the attribute that holds attribute meta data.
 * 2) Attributes for usnCreated/usnChanged are updated with current local USN
 * 3) If we are doing a modify/delete, attribute meta data is checked to see supplier/consumer wins.
 *        - If supplier attribute won, update its meta data with current local USN.
 *        - If consumer wins don't write corresponding attribute.
 *        - Special case: supplier lost for UsnChanged, replace the metaData with consumer's metaData.
 * 4) If no attribute metaData exists, create it.
 */
DWORD
VmDirReplSetAttrNewMetaData(
    PVDIR_OPERATION     pOperation,
    PVDIR_ENTRY         pEntry,
    PLW_HASHMAP*        ppMetaDataMap
    )
{
    DWORD               dwError = LDAP_SUCCESS;
    PVDIR_ATTRIBUTE     pCurrAttr = NULL;
    PVDIR_ATTRIBUTE     pPrevAttr = NULL;
    PVDIR_ATTRIBUTE     pAttrAttrMetaData = NULL;
    PLW_HASHMAP         pMetaDataMap = NULL;

    if (!pOperation || !pEntry || !ppMetaDataMap)
    {
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER);
    }

    for (pPrevAttr = NULL, pCurrAttr = pEntry->attrs;
         pCurrAttr;
         pPrevAttr = pCurrAttr, pCurrAttr = pCurrAttr->next)
    {
        if (VmDirStringCompareA(pCurrAttr->type.lberbv.bv_val, ATTR_ATTR_META_DATA, FALSE) == 0)
        {
            if (pPrevAttr == NULL)
            {
                pEntry->attrs = pCurrAttr->next;
            }
            else
            {
                pPrevAttr->next = pCurrAttr->next;
            }

            pAttrAttrMetaData = pCurrAttr;

            dwError = VmDirAttributeMetaDataToHashMap(pAttrAttrMetaData, &pMetaDataMap);
            BAIL_ON_VMDIR_ERROR(dwError);

            *ppMetaDataMap = pMetaDataMap;
            continue;
        }

        if (VmDirStringCompareA(pCurrAttr->type.lberbv.bv_val, ATTR_USN_CREATED, FALSE) == 0 ||
            VmDirStringCompareA(pCurrAttr->type.lberbv.bv_val, ATTR_USN_CHANGED, FALSE) == 0)
        {
            char      pszLocalUsn[VMDIR_MAX_USN_STR_LEN] = {'\0'};
            size_t    localUsnStrlen = 0;

            dwError = VmDirStringNPrintFA(
                    pszLocalUsn,
                    sizeof(pszLocalUsn),
                    sizeof(pszLocalUsn) - 1,
                    "%"PRId64,
                    pOperation->pWriteQueueEle->usn);
            BAIL_ON_VMDIR_ERROR(dwError);

            localUsnStrlen = VmDirStringLenA(pszLocalUsn);

            VmDirFreeBervalContent(&pCurrAttr->vals[0]);

            dwError = VmDirAllocateAndCopyMemory(pszLocalUsn, localUsnStrlen, (PVOID*)&pCurrAttr->vals[0].lberbv.bv_val);
            BAIL_ON_VMDIR_ERROR(dwError);

            pCurrAttr->vals[0].lberbv.bv_len = localUsnStrlen;
            pCurrAttr->vals[0].bOwnBvVal = TRUE;
            continue;
        }
    }

    if (pAttrAttrMetaData == NULL)
    {
        VMDIR_LOG_ERROR(
                VMDIR_LOG_MASK_ALL,
                "%s: attrMetaData attribute not present in Entry: %s",
                __FUNCTION__,
                pEntry->dn.lberbv.bv_val);
        BAIL_WITH_VMDIR_ERROR(dwError, LDAP_OPERATIONS_ERROR);
    }

    if (pOperation->reqCode == LDAP_REQ_MODIFY)
    {
        dwError = VmDirReplResolveConflicts(
                pOperation,
                pEntry,
                pMetaDataMap);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = _VmDirReplPopulateAttrNewMetaData(
            pEntry,
            pOperation->pWriteQueueEle->usn,
            pMetaDataMap);
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:
    VmDirFreeAttribute(pAttrAttrMetaData);
    return dwError;

error:
    goto cleanup;
}
Exemple #25
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" );
}
Exemple #26
0
static
int
DeleteRefAttributesValue(
    VDIR_OPERATION * pOperation,
    VDIR_BERVALUE * dn
    )
{
    int               retVal = LDAP_SUCCESS;
    VDIR_FILTER *     f = NULL;
    VDIR_CANDIDATES * cl = NULL;
    VDIR_ENTRY        groupEntry = {0};
    VDIR_ENTRY *      pGroupEntry = NULL;
    int          i = 0;
    VDIR_MODIFICATION mod = {0};
    ModifyReq    mr;
    VDIR_BERVALUE     delVals[2];
    PSTR              pszLocalErrorMsg = NULL;

    assert( pOperation != NULL && pOperation->pBEIF != NULL && dn != NULL);

    retVal = VmDirNormalizeDN( dn, pOperation->pSchemaCtx );
    BAIL_ON_VMDIR_ERROR( retVal );

    // Set filter
    retVal = VmDirAllocateMemory( sizeof( VDIR_FILTER ), (PVOID *)&f);
    BAIL_ON_VMDIR_ERROR( retVal );

    f->choice = LDAP_FILTER_EQUALITY;
    f->filtComp.ava.type.lberbv.bv_val = ATTR_MEMBER;
    f->filtComp.ava.type.lberbv.bv_len = ATTR_MEMBER_LEN;
    f->filtComp.ava.value = *dn;
    if ((f->filtComp.ava.pATDesc = VmDirSchemaAttrNameToDesc( pOperation->pSchemaCtx, ATTR_MEMBER)) == NULL)
    {
        retVal = VMDIR_ERROR_NO_SUCH_ATTRIBUTE;
        BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                        "undefined attribute (%s)",
                                        VDIR_SAFE_STRING(ATTR_MEMBER));
    }
    // Set ModifyReq structure
    memset(&mr, 0, sizeof(ModifyReq));
    mod.operation = MOD_OP_DELETE;
    mod.attr.type.lberbv.bv_val = ATTR_MEMBER;
    mod.attr.type.lberbv.bv_len = ATTR_MEMBER_LEN;
    mod.attr.pATDesc = f->filtComp.ava.pATDesc;

    mod.attr.next = NULL;
    delVals[0] = *dn;
    memset(&(delVals[1]), 0, sizeof(VDIR_BERVALUE));
    mod.attr.vals = delVals;
    mod.attr.numVals = 1;
    mod.next = NULL;
    mr.mods = &mod;
    mr.numMods = 1;

    retVal = pOperation->pBEIF->pfnBEGetCandidates( pOperation->pBECtx, f);
    if ( retVal != 0 )
    {
        if (retVal == VMDIR_ERROR_BACKEND_ENTRY_NOTFOUND)
        {
            retVal = LDAP_SUCCESS;  // no member refer to this DN. return ok/0
        }
        else
        {
            retVal = VMDIR_ERROR_GENERIC;
            BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                        "DeleteRefAttributesValue: Building group list (BdbGetCandidates()) failed.");
        }
    }
    else
    {
        cl = f->candidates;

        for (i = 0; i < cl->size; i++)
        {
            pGroupEntry = &groupEntry;
            if ((retVal = VmDirModifyEntryCoreLogic( pOperation, &mr, cl->eIds[i], pGroupEntry)) != 0)
            {
                switch (retVal)
                {
                    case VMDIR_ERROR_BACKEND_PARENT_NOTFOUND:
                    case VMDIR_ERROR_BACKEND_ENTRY_NOTFOUND:
                    case VMDIR_ERROR_ENTRY_NOT_FOUND:
                        continue;

                    default: // Including LDAP_LOCK_DEADLOCK, which is handled by the caller
                        BAIL_ON_VMDIR_ERROR( retVal );
                }
            }

            VmDirFreeBervalContent( &(mr.dn) ); // VmDirModifyEntryCoreLogic fill in DN if not exists
            VmDirFreeEntryContent( pGroupEntry );
            pGroupEntry = NULL; // Reset to NULL so that DeleteEntry is no-op.
        }
    }

cleanup:
    memset(&(f->filtComp.ava.value), 0, sizeof(VDIR_BERVALUE)); // Since ava.value is NOT owned by filter.
    DeleteFilter( f );
    VmDirFreeEntryContent( pGroupEntry );
    VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg);

    return retVal;

error:

    VMDIR_APPEND_ERROR_MSG(pOperation->ldapResult.pszErrMsg, pszLocalErrorMsg);
    goto cleanup;
}
Exemple #27
0
/*
 * TODO: Should not allow renaming computers, domain controllers, replication
 * agreements, server objects
 */
static int
VmDirGenerateRenameAttrsMods(
    PVDIR_OPERATION pOperation
    )
{
    int                 retVal = 0;
    ModifyReq *         modReq = &(pOperation->request.modifyReq);
    VDIR_BERVALUE       parentdn = VDIR_BERVALUE_INIT;
    VDIR_BERVALUE       NewDn = VDIR_BERVALUE_INIT;
    VDIR_BERVALUE       OldRdn = VDIR_BERVALUE_INIT;
    VDIR_BERVALUE       NewRdn = VDIR_BERVALUE_INIT;
    PSTR pszOldRdnAttrName = NULL;
    PSTR pszOldRdnAttrVal = NULL;
    PSTR pszNewRdnAttrName = NULL;
    PSTR pszNewRdnAttrVal = NULL;

    if (modReq->newrdn.lberbv.bv_len == 0)
    {
        goto cleanup; // Nothing to do
    }

    if (strchr(modReq->newrdn.lberbv.bv_val, RDN_SEPARATOR_CHAR)) // FIXME : Need to handle escape
    {
        retVal = VMDIR_ERROR_UNWILLING_TO_PERFORM;
        //BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, pszLocalErrMsg, "New RDN has more than one component");
        BAIL_ON_VMDIR_ERROR(retVal);
    }

    if (modReq->newSuperior.lberbv.bv_len)
    {
        retVal = VmDirNormalizeDN(&(modReq->newSuperior), pOperation->pSchemaCtx);
        BAIL_ON_VMDIR_ERROR(retVal)

        retVal = VmDirCatDN(&modReq->newrdn, &modReq->newSuperior, &NewDn);
        BAIL_ON_VMDIR_ERROR(retVal);
    }
    else
    {
        retVal = VmDirGetParentDN(&modReq->dn, &parentdn);
        BAIL_ON_VMDIR_ERROR(retVal);

        retVal = VmDirCatDN(&modReq->newrdn, &parentdn, &NewDn);
        BAIL_ON_VMDIR_ERROR(retVal);
    }

    retVal = VmDirNormalizeDN(&NewDn, pOperation->pSchemaCtx);
    BAIL_ON_VMDIR_ERROR(retVal);

    retVal = VmDirGetRdn(&NewDn, &NewRdn);
    BAIL_ON_VMDIR_ERROR(retVal);

    retVal = VmDirRdnToNameValue(&NewRdn, &pszNewRdnAttrName, &pszNewRdnAttrVal);
    BAIL_ON_VMDIR_ERROR(retVal);

    retVal = VmDirGetRdn(&modReq->dn, &OldRdn);
    BAIL_ON_VMDIR_ERROR(retVal);

    retVal = VmDirRdnToNameValue(&OldRdn, &pszOldRdnAttrName, &pszOldRdnAttrVal);
    BAIL_ON_VMDIR_ERROR(retVal);

    // Change DN
    retVal = VmDirAppendAMod(pOperation, MOD_OP_REPLACE, ATTR_DN, ATTR_DN_LEN, NewDn.bvnorm_val, NewDn.bvnorm_len);
    BAIL_ON_VMDIR_ERROR(retVal);


    if (strcmp(pszNewRdnAttrName, pszOldRdnAttrName) == 0)
    {
        if (strcmp(pszNewRdnAttrVal, pszOldRdnAttrVal) != 0)
        {
            // Change was like CN=User1,... to CN=User2,... then may want to
            // modify CN if bDeleteOldRdn
            if (modReq->bDeleteOldRdn)
            {
                retVal = VmDirAppendAMod(pOperation, MOD_OP_DELETE, pszOldRdnAttrName, (int) VmDirStringLenA(pszOldRdnAttrName), pszOldRdnAttrVal, VmDirStringLenA(pszOldRdnAttrVal));
                BAIL_ON_VMDIR_ERROR(retVal);
            }

            retVal = VmDirAppendAMod(pOperation, MOD_OP_ADD, pszNewRdnAttrName, (int)VmDirStringLenA(pszNewRdnAttrName), pszNewRdnAttrVal, VmDirStringLenA(pszNewRdnAttrVal));
            BAIL_ON_VMDIR_ERROR(retVal);
        }
    }
    else
    {
        // If change was like CN=User1,... to OU=MyOU,... then
        // need to add attribute OU=MyOu and potentially delete attribute CN=User1
        retVal = VmDirAppendAMod(pOperation, MOD_OP_ADD, pszNewRdnAttrName, (int)VmDirStringLenA(pszNewRdnAttrName), pszNewRdnAttrVal, VmDirStringLenA(pszNewRdnAttrVal));
        BAIL_ON_VMDIR_ERROR(retVal);

        if (modReq->bDeleteOldRdn)
        {
            retVal = VmDirAppendAMod(pOperation, MOD_OP_DELETE, pszOldRdnAttrName,(int) VmDirStringLenA(pszOldRdnAttrName), NULL, 0);
            BAIL_ON_VMDIR_ERROR(retVal);
        }
    }

cleanup:

    VmDirFreeBervalContent(&parentdn);
    VmDirFreeBervalContent(&NewDn);
    VmDirFreeBervalContent(&OldRdn);
    VmDirFreeBervalContent(&NewRdn);
    VMDIR_SAFE_FREE_STRINGA(pszOldRdnAttrName);
    VMDIR_SAFE_FREE_STRINGA(pszOldRdnAttrVal);
    VMDIR_SAFE_FREE_STRINGA(pszNewRdnAttrName);
    VMDIR_SAFE_FREE_STRINGA(pszNewRdnAttrVal);
    return retVal;

error:
    goto cleanup;
}
Exemple #28
0
static
DWORD
_PopulateOperationModAttributes(
        LDAP *pLd,
        LDAPMessage *pEntry,
        PVDIR_OPERATION pLdapOp
        )
{
    DWORD dwError = 0;
    struct berval** ppValues = NULL;
    PLW_HASHMAP pHashMap = NULL;

    PSTR pszBuf = NULL;
    PSTR pszAttrName = NULL;
    PSTR pszAttrMetaData = NULL;
    PSTR pszAttrUsnlessMetaData = NULL;
    PSTR pszAttrNewMetaData = NULL;
    PSTR pszKey = NULL;
    PSTR pszValue = NULL;
    USN localUsn = 0;
    PVDIR_BERVALUE pBerValue = NULL;
    size_t iBerValueSize = 0;
    DWORD i = 0, j = 0;

    dwError = LwRtlCreateHashMap(
            &pHashMap,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL
            );
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = pLdapOp->pBEIF->pfnBEGetNextUSN(pLdapOp->pBECtx, &localUsn);
    BAIL_ON_VMDIR_ERROR(dwError);

    if (!(ppValues = ldap_get_values_len(pLd, pEntry, ATTR_ATTR_META_DATA)))
    {
        dwError = VMDIR_ERROR_SCHEMA_BAD_METADATA;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    for (i = 0; ppValues[i] != NULL; i++)
    {
        dwError = VmDirAllocateStringA(ppValues[i]->bv_val, &pszBuf);
        BAIL_ON_VMDIR_ERROR(dwError);

        pszAttrName = VmDirStringTokA(pszBuf, ":", &pszAttrMetaData);
        VmDirStringTokA(pszAttrMetaData, ":", &pszAttrUsnlessMetaData);

        dwError = VmDirAllocateStringPrintf(
                &pszAttrNewMetaData,
                "%ld:%s",
                localUsn,
                pszAttrUsnlessMetaData);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = VmDirAllocateStringA(pszAttrName, &pszKey);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = LwRtlHashMapInsert(pHashMap, pszKey, pszAttrNewMetaData, NULL);
        BAIL_ON_VMDIR_ERROR(dwError);

        VMDIR_SAFE_FREE_MEMORY(pszBuf);
    }
    ldap_value_free_len(ppValues);
    ppValues = NULL;

    for (i = 0; ppszSchemaEntryAttrs[i] != NULL; i++)
    {
        if (VmDirStringCompareA(ppszSchemaEntryAttrs[i], ATTR_ATTR_META_DATA, FALSE) != 0)
        {
            ppValues = ldap_get_values_len(pLd, pEntry, ppszSchemaEntryAttrs[i]);
            if (ppValues)
            {
                iBerValueSize = ldap_count_values_len(ppValues);
                dwError = VmDirAllocateMemory(
                        sizeof(VDIR_BERVALUE) * iBerValueSize,
                        (PVOID*)&pBerValue);
                BAIL_ON_VMDIR_ERROR(dwError);

                if (VmDirStringCompareA(ppszSchemaEntryAttrs[i], ATTR_USN_CHANGED, FALSE) == 0)
                {
                    assert(iBerValueSize == 1);

                    dwError = VmDirAllocateStringPrintf(&pBerValue[0].lberbv_val, "%ld", localUsn);
                    BAIL_ON_VMDIR_ERROR(dwError);
                    pBerValue[0].lberbv_len = VmDirStringLenA(pBerValue[0].lberbv_val);
                    pBerValue[0].bOwnBvVal = TRUE;
                }
                else
                {
                    for (j = 0; j < iBerValueSize; j++)
                    {
                        dwError = VmDirAllocateStringA(ppValues[j]->bv_val, &pBerValue[j].lberbv_val);
                        BAIL_ON_VMDIR_ERROR(dwError);
                        pBerValue[j].lberbv_len = ppValues[j]->bv_len;
                        pBerValue[j].bOwnBvVal = TRUE;
                    }
                }

                dwError = VmDirOperationAddModReq(
                        pLdapOp,
                        MOD_OP_REPLACE,
                        ppszSchemaEntryAttrs[i],
                        pBerValue,
                        iBerValueSize);
                BAIL_ON_VMDIR_ERROR(dwError);

                dwError = LwRtlHashMapFindKey(
                        pHashMap,
                        (PVOID*)&pszValue,
                        ppszSchemaEntryAttrs[i]);
                BAIL_ON_VMDIR_ERROR(dwError);

                dwError = VmDirStringCpyA(
                        pLdapOp->request.modifyReq.mods->attr.metaData,
                        VMDIR_MAX_ATTR_META_DATA_LEN,
                        pszValue);
                BAIL_ON_VMDIR_ERROR(dwError);

                ldap_value_free_len(ppValues);
                ppValues = NULL;
                for (j = 0; j < iBerValueSize; j++)
                {
                    VmDirFreeBervalContent(&pBerValue[j]);
                }
                VMDIR_SAFE_FREE_MEMORY(pBerValue);
            }
        }
    }

cleanup:
    LwRtlHashMapClear(pHashMap, _FreeStringPair, NULL);
    LwRtlFreeHashMap(&pHashMap);
    return dwError;

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

    VMDIR_SAFE_FREE_MEMORY(pszBuf);
    VMDIR_SAFE_FREE_MEMORY(pszAttrNewMetaData);
    if (ppValues)
    {
        ldap_value_free_len(ppValues);
    }
    for (j = 0; j < iBerValueSize; j++)
    {
        VmDirFreeBervalContent(&pBerValue[j]);
    }
    VMDIR_SAFE_FREE_MEMORY(pBerValue);
    goto cleanup;
}
Exemple #29
0
/*
 * Duplicate content of pBerval into pDupBerval
 */
DWORD
VmDirBervalContentDup(
    PVDIR_BERVALUE     pBerval,
    PVDIR_BERVALUE     pDupBerval
    )
{
    DWORD    dwError = 0;

    assert(pBerval && pDupBerval);

    VmDirFreeBervalContent(pDupBerval);

    dwError = VmDirAllocateMemory(pBerval->lberbv.bv_len+1, (PVOID*)&pDupBerval->lberbv.bv_val);
    BAIL_ON_VMDIR_ERROR(dwError);
    if (pBerval->lberbv.bv_len > 0)
    {
        dwError = VmDirCopyMemory(
            pDupBerval->lberbv.bv_val,
            (pBerval->lberbv.bv_len+1),
            pBerval->lberbv.bv_val,
            pBerval->lberbv.bv_len
        );
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    pDupBerval->bOwnBvVal = TRUE;
    pDupBerval->lberbv.bv_len = pBerval->lberbv.bv_len;

    if (pBerval->lberbv.bv_val == pBerval->bvnorm_val)
    {
        pDupBerval->bvnorm_val = pDupBerval->lberbv.bv_val;
        pDupBerval->bvnorm_len = pDupBerval->lberbv.bv_len;
    }
    else if (pBerval->bvnorm_val == NULL)
    {
        pDupBerval->bvnorm_val = NULL;
        pDupBerval->bvnorm_len = 0;
    }
    else
    {
        dwError = VmDirAllocateMemory(pBerval->bvnorm_len+1, (PVOID*)&pDupBerval->bvnorm_val);
        BAIL_ON_VMDIR_ERROR(dwError);
        if (pBerval->bvnorm_len > 0)
        {
            dwError = VmDirCopyMemory(
                pDupBerval->bvnorm_val,
                pBerval->bvnorm_len+1,
                pBerval->bvnorm_val,
                pBerval->bvnorm_len
            );
            BAIL_ON_VMDIR_ERROR(dwError);
        }
        pDupBerval->bvnorm_len = pBerval->bvnorm_len;
    }

cleanup:

    return dwError;

error:

    VmDirFreeBervalContent(pDupBerval);

    goto cleanup;
}
Exemple #30
0
/*
 * DelAttrValsFromEntryStruct: Deletes a complete attribute or specific attribute values from the entry.
 * Assumption: This function assumes/asserts that the modAttr does exist in the entry.
 *
 */
static
int
DelAttrValsFromEntryStruct(
   PVDIR_SCHEMA_CTX  pSchemaCtx,
   VDIR_ENTRY *      e,
   VDIR_ATTRIBUTE *  modAttr,
   PSTR*             ppszErrorMsg
   )
{
    int                 retVal = LDAP_SUCCESS;
    VDIR_ATTRIBUTE *    prevAttr = NULL;
    VDIR_ATTRIBUTE *    currAttr = NULL;
    VDIR_ATTRIBUTE *    eAttr = NULL;
    unsigned int        i = 0;
    unsigned int        j = 0;
    PSTR                pszLocalErrorMsg = NULL;

    assert(e->allocType == ENTRY_STORAGE_FORMAT_NORMAL);

    // Locate which attribute (values) we are trying to delete
    for (currAttr = e->attrs; currAttr != NULL; prevAttr = currAttr, currAttr = currAttr->next)
    {
        if (VmDirStringCompareA(modAttr->type.lberbv.bv_val, currAttr->type.lberbv.bv_val, FALSE) == 0)
        {
            break;
        }
    }

    assert(currAttr != NULL);

    eAttr = currAttr;

    // Normalize eAttr values
    for (i = 0; i < eAttr->numVals; i++)
    {
        retVal = VmDirSchemaBervalNormalize(pSchemaCtx, eAttr->pATDesc, &eAttr->vals[i]);
        BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg),
                            "normalize (%s)(%.*s)",
                            VDIR_SAFE_STRING(eAttr->pATDesc->pszName),
                            VMDIR_MIN(eAttr->vals[i].lberbv.bv_len, VMDIR_MAX_LOG_OUTPUT_LEN),
                            VDIR_SAFE_STRING(eAttr->vals[i].lberbv.bv_val));
    }

    if (modAttr->numVals == 1 && eAttr->pATDesc->bSingleValue &&
        (VmDirStringCompareA(eAttr->pATDesc->pszName, ATTR_MODIFYTIMESTAMP, FALSE) == 0 ||
         VmDirStringCompareA(eAttr->pATDesc->pszName, ATTR_CREATETIMESTAMP, FALSE) == 0 ||
         VmDirStringCompareA(eAttr->pATDesc->pszName, ATTR_CREATORS_NAME, FALSE) == 0 ||
         VmDirStringCompareA(eAttr->pATDesc->pszName, ATTR_MODIFIERS_NAME, FALSE) == 0))
    {
        /* Force deleting the attribute value whether or not the value matches.
         * A raft follower may alter the timestamps/creator locally, e.g. rollback vmwAttrUniquenessScope,
         * which may fail to remove the value if it doesn't match that value seen  at the raft leader.
         */
        VmDirFreeBervalContent(&modAttr->vals[0]);
        modAttr->numVals = 0;
    }

    // Complete attribute is to be deleted.
    if (modAttr->numVals == 0)
    {
        // Make a copy of BerValues into modAttr so that these values can be used to delete from the index,
        // if it is an indexed attribute.

        VMDIR_SAFE_FREE_MEMORY(modAttr->vals);
        retVal = VmDirAllocateMemory((eAttr->numVals + 1) * sizeof(VDIR_BERVALUE), (PVOID *)&modAttr->vals);
        BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg), "no memory");

        for (i = 0; i < eAttr->numVals; i++)
        {
            VmDirBervalContentDup(&eAttr->vals[i], &modAttr->vals[i]);
        }
        modAttr->numVals = eAttr->numVals;

        // Adjust the "next" pointer of the attribute before the attribute being deleted. => Altering the attribute
        // chain.
        if (prevAttr == NULL) // if it is the first attribute
        {
            e->attrs = eAttr->next;
        }
        else
        {
            prevAttr->next = eAttr->next;
        }

        VmDirFreeAttribute(eAttr);
    }
    else // Specific attribute values need to be deleted.
    {
        // Check if all attribute values that are being deleted exist in the Attribute
        for (i=0; i < modAttr->numVals; i++)
        {
            // modAttr values are already normalized.
            assert(modAttr->vals[i].bvnorm_val);

            for (j = 0; j < eAttr->numVals; j++)
            {
                // eAttr values are already normalized.
                assert(eAttr->vals[j].bvnorm_val);

                if (modAttr->vals[i].bvnorm_len == eAttr->vals[j].bvnorm_len &&
                    memcmp(modAttr->vals[i].bvnorm_val, eAttr->vals[j].bvnorm_val, modAttr->vals[i].bvnorm_len) == 0)
                {
                    break;
                }
            }
            if (j == eAttr->numVals) // did not find a match
            {
                retVal = VMDIR_ERROR_NO_SUCH_ATTRIBUTE;
                BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg),
                                        "Attribute (%s) value (%.*s) being deleted does not exist.",
                                        VDIR_SAFE_STRING(modAttr->type.lberbv.bv_val),
                                        VMDIR_MIN(modAttr->vals[i].lberbv.bv_len, VMDIR_MAX_LOG_OUTPUT_LEN),
                                        VDIR_SAFE_STRING(modAttr->vals[i].lberbv.bv_val));
            }
        }
        // All values are being deleted. => Delete the whole attribute
        if (modAttr->numVals == eAttr->numVals)
        {
            // Adjust the "next" pointer of the attribute before the attribute being deleted. => Altering the attribute
            // chain.
            if (prevAttr == NULL) // if it is the first attribute
            {
                e->attrs = eAttr->next;
            }
            else
            {
                prevAttr->next = eAttr->next;
            }
            VmDirFreeAttribute(eAttr);
        }
        else
        {
            RemoveAttrVals(eAttr, modAttr);
        }
    }

cleanup:

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

    return retVal;

error:
    goto cleanup;
}