Beispiel #1
0
/*
 * For given DN (pszDN content will be modified),
 * 1. allocate ppszRDNs to hold PSTR to RDN
 * 2. change pszDN ',' to '\0' and have ppszRDNs[i] point to it
 * 3. set *piNumRDNs
 *
 * Caller should free *pppszRDNs but NOT **pppszRDNs, which point into pszDN.
 */
static
DWORD
VdirSchemaInPlaceDN2RDNs(
    PSTR    pszDN,
    PSTR**  pppszRDNs,
    int*    piNumRDNs
    )
{
    DWORD   dwError = 0;
    PSTR*   ppszRDNs = NULL;
    int     iCnt = 0;
    PSTR    pChar = NULL;

    assert(pppszRDNs && piNumRDNs);

    for (iCnt = 0, pChar = pszDN; pChar; iCnt++)
    {
        pChar = VmDirStringChrA(pChar+1, ',');
    }

    dwError = VmDirAllocateMemory(
            sizeof(PSTR) * (iCnt+1),
            (PVOID)&ppszRDNs);
    BAIL_ON_VMDIR_ERROR(dwError);

    *piNumRDNs = iCnt;

    for (iCnt = 0, pChar = pszDN, ppszRDNs[0] = pszDN; pChar; iCnt++)
    {
        pChar = VmDirStringChrA(pChar+1, ',');
        if (pChar)
        {
            *pChar = '\0';
            ppszRDNs[iCnt+1] = pChar+1;
        }
    }

    *pppszRDNs = ppszRDNs;

cleanup:

    return dwError;

error:

    VMDIR_SAFE_FREE_MEMORY(ppszRDNs);

    *pppszRDNs = NULL;
    *piNumRDNs = 0;

    goto cleanup;
}
Beispiel #2
0
/*
 * Read schema definition from file
 * We only care for
 *  attributetypes
 *  objectclasses
 *  ditcontentrules
 *  attributeindices
 */
DWORD
VmDirReadSchemaFile(
    PCSTR               pszSchemaFilePath,
    PVMDIR_STRING_LIST* ppAtStrList,
    PVMDIR_STRING_LIST* ppOcStrList,
    PVMDIR_STRING_LIST* ppCrStrList,
    PVMDIR_STRING_LIST* ppIdxStrList
    )
{
    DWORD dwError = 0;
    CHAR  pbuf[1024] = {0};
    FILE* fp = NULL;

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

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

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

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

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

    dwError = VmDirStringListInitialize(&pIdxStrList, 16);
    BAIL_ON_VMDIR_ERROR(dwError);

#ifndef _WIN32
    fp = fopen(pszSchemaFilePath, "r");
#else
    if (fopen_s(&fp, pszSchemaFilePath, "r") != 0)
    {
        fp = NULL;
    }
#endif
    if (NULL == fp)
    {
        dwError = errno;
        VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL,
                "Open schema file (%s) failed. Error (%d)",
                pszSchemaFilePath, dwError);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    while (fgets(pbuf, sizeof(pbuf), fp) != NULL)
    {
        PSTR pszTag = NULL;

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

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

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

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

error:
    VmDirStringListFree(pAtStrList);
    VmDirStringListFree(pOcStrList);
    VmDirStringListFree(pCrStrList);
    VmDirStringListFree(pIdxStrList);
    goto cleanup;
}
Beispiel #3
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;
}
Beispiel #4
0
static
int
WriteAttributes(
   VDIR_OPERATION *   op,
   PVDIR_ENTRY        pEntry,
   uint32_t           iSearchReqSpecialChars,
   BerElement *       ber,
   PSTR*              ppszErrorMsg
   )
{
    int             retVal = LDAP_SUCCESS;
    unsigned int    i = 0;
    SearchReq *     sr = &(op->request.searchReq);
    BOOLEAN         mapFSPDN = FALSE;
    PVDIR_ATTRIBUTE pAttr = NULL;
    PVDIR_ATTRIBUTE pRetAttrs[3] = {pEntry->attrs, pEntry->pComputedAttrs, NULL};
    DWORD           dwCnt = 0;
    PSTR            pszLocalErrorMsg = NULL;

    // loop through both normal and computed attributes
    for ( dwCnt = 0, pAttr = pRetAttrs[dwCnt];
          pAttr != NULL;
          ++dwCnt, pAttr = pRetAttrs[dwCnt])
    {
        for ( ; pAttr != NULL;  pAttr = pAttr->next )
        {
            BOOLEAN bSendAttribute = FALSE;

            if (op->syncReqCtrl != NULL) // Replication,
            {
                // Filter attributes based on the input utdVector, and attribute's meta-data
                retVal = IsAttrInReplScope( op, pAttr->type.lberbv.bv_val, pAttr->metaData, &bSendAttribute, &pszLocalErrorMsg );
                BAIL_ON_VMDIR_ERROR( retVal );
            }
            else
            {
                // WEI: the correct way to handle this is to have attribute level 'ACL' check
                // For instance, the 'userPassword' attribute ACL defines:
                // Deny 'READ' access to everyone including administrator/admins/SELF
                // Possibly only allow 'backup Operators' 'READ' access
                // Allow 'administrator/admins' WRITE (set password)
                // Allow 'SELF' WRITE (reset password)

                // For now, do not send 'userPassword' attribute for everyone when implicitly/explicitly requested

                // normal ldap client search request
                // check if we need to return this attribute

                if (VmDirStringCompareA(pAttr->type.lberbv.bv_val, ATTR_USER_PASSWORD, FALSE) == 0)
                {
                    if ((iSearchReqSpecialChars & LDAP_SEARCH_REQUEST_CHAR_PASSWD) != 0)
                    {   // vmdir specific - return password only if special char '-' is requested
                        bSendAttribute = TRUE;
                    }
                }
                else if (VmDirStringCompareA(pAttr->type.lberbv.bv_val, ATTR_KRB_MASTER_KEY, FALSE) == 0)
                {
                    //only return master key if all of following conditions are satisfied
                    if (op->showMasterKeyCtrl && // server control must be present
                            op->conn->bIsLdaps && // must be ldaps
                            op->conn->AccessInfo.pszNormBindedDn && // can't be anonymous
                            VmDirStringCompareA(op->reqDn.bvnorm_val, gVmdirServerGlobals.systemDomainDN.bvnorm_val, FALSE) == 0 && // must query system domain object
                            op->request.searchReq.scope == LDAP_SCOPE_BASE && // scope must be base
                            op->request.searchReq.attrs != NULL && // attribute must be krbMKey only
                            VmDirStringCompareA(op->request.searchReq.attrs[0].lberbv.bv_val, ATTR_KRB_MASTER_KEY, FALSE) == 0 &&
                            op->request.searchReq.attrs[1].lberbv.bv_val == NULL)
                    {
                        retVal = VmDirSrvAccessCheckIsAdminRole( //must be administrator
                                                        op,
                                                        op->conn->AccessInfo.pszNormBindedDn,
                                                        &op->conn->AccessInfo,
                                                        &bSendAttribute);
                        BAIL_ON_VMDIR_ERROR( retVal );
                    }
                }
                else if ( (VmDirStringCompareA(pAttr->type.lberbv.bv_val, ATTR_VMW_STS_PASSWORD, FALSE) == 0)
                           ||
                           (VmDirStringCompareA(pAttr->type.lberbv.bv_val, ATTR_VMW_STS_TENANT_KEY, FALSE) == 0)
                        )
                {
                    //only admin users can read ATTR_VMW_STS_PASSWORD, ATTR_VMW_STS_TENANT_KEY attribute
                    {
                        retVal = VmDirSrvAccessCheckIsAdminRole( //must be administrator
                                                        op,
                                                        op->conn->AccessInfo.pszNormBindedDn,
                                                        &op->conn->AccessInfo,
                                                        &bSendAttribute);
                        BAIL_ON_VMDIR_ERROR( retVal );
                    }
                }
                else if (((iSearchReqSpecialChars & LDAP_SEARCH_REQUEST_CHAR_USER) != 0)                   &&
                         pAttr->pATDesc->usage == VDIR_ATTRIBUTETYPE_USER_APPLICATIONS)
                {
                    bSendAttribute = TRUE;   // return all user attributes - "*"
                }
                else if (((iSearchReqSpecialChars & LDAP_SEARCH_REQUEST_CHAR_OP) != 0)                     &&
                         (pAttr->pATDesc->usage == VDIR_ATTRIBUTETYPE_DIRECTORY_OPERATION ||
                          pAttr->pATDesc->usage == VDIR_ATTRIBUTETYPE_DSA_OPERATION       ||
                          pAttr->pATDesc->usage == VDIR_ATTRIBUTETYPE_DISTRIBUTED_OPERATION))
                {
                    bSendAttribute = TRUE;   // return all operational attributes - "+"
                }
                else
                {
                    for (i = 0; sr->attrs && sr->attrs[i].lberbv.bv_val != NULL; i++)
                    {
                        if (VmDirStringCompareA( sr->attrs[i].lberbv.bv_val, pAttr->type.lberbv.bv_val, FALSE) == 0)
                        {
                           bSendAttribute = TRUE;
                           break;
                        }
                    }
                }
            }

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

                // Non-replication/normal search request, and the attribute is FSP enabled (SJ-TBD, for now ATTR_MEMBER)
                if (op->syncReqCtrl == NULL && VmDirStringCompareA(pAttr->type.lberbv.bv_val, ATTR_MEMBER, FALSE) == 0)
                {
                    mapFSPDN = TRUE;
                }
                else
                {
                    mapFSPDN = FALSE;
                }

                if ( VmDirStringCompareA( pAttr->type.lberbv_val, ATTR_OBJECT_CLASS, FALSE ) == 0 )
                {
                    if ( op->syncReqCtrl == NULL ) // Not replication
                    {
                        BerValue bvOCTop = {OC_TOP_LEN, OC_TOP};
                        // explicitly send TOP as we don't store it in Entry/DB
                        if (ber_printf( ber, "O", &bvOCTop ) == -1 )
                        {
                            VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "WriteAttributes: ber_printf (to print an attribute value ...) failed." );
                            retVal = LDAP_OTHER;
                            BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                                            "Encoding an attribute value failed.");
                        }
                    }

                    // ADSI wants structure objetclass at the end to display correctly.
                    for ( i = pAttr->numVals ; i > 0; i-- )
                    {
                        if (ber_printf( ber, "O", &(pAttr->vals[i-1]) ) == -1 )
                        {
                            VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "WriteAttributes: ber_printf (to print an attribute value ...) failed." );
                            retVal = LDAP_OTHER;
                            BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                                            "Encoding an attribute value failed.");
                        }
                    }
                }
                else
                {
                    for ( i = 0; i< pAttr->numVals; i++ )
                    {
                        // SJ-TBD: A better/bit-more-expensive way is to Normalize the value, do GetParentDN, check if the 1st
                        // RDN is FSP container RDN ...
                        if (mapFSPDN && VmDirStringStrA(pAttr->vals[i].lberbv.bv_val, FSP_CONTAINER_RDN_ATTR_VALUE) != NULL)
                        {
                            char * tmpPos = VmDirStringChrA(pAttr->vals[i].lberbv.bv_val, ',');
                            assert( tmpPos != NULL);
                            *tmpPos = '\0';
                            pAttr->vals[i].lberbv.bv_len = tmpPos - pAttr->vals[i].lberbv.bv_val;
                        }
                        if (ber_printf( ber, "O", &(pAttr->vals[i]) ) == -1 )
                        {
                            VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "WriteAttributes: ber_printf (to print an attribute value ...) failed." );
                            retVal = LDAP_OTHER;
                            BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                                            "Encoding an attribute value failed.");
                        }
                    }
                }

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

cleanup:

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

    return( retVal );

error:

    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "WriteAttributes failed (%u)(%s)",
                     retVal, VDIR_SAFE_STRING(pszLocalErrorMsg) );

    goto cleanup;
}
Beispiel #5
0
/*
 * APIs for HA Topology Management ends here
 */
DWORD
VmDirClientJoinAtomic(
    PCSTR                   pszServerName,
    PCSTR                   pszUserName,
    PCSTR                   pszPassword,
    PCSTR                   pszDomainName,
    PCSTR                   pszMachineName,
    PCSTR                   pszOrgUnit,
    DWORD                   dwFlags,
    PVMDIR_MACHINE_INFO_A   *ppMachineInfo
    )
{
    DWORD dwError = 0;
    PVMDIR_MACHINE_INFO_A  pMachineInfo = NULL;
    PVMDIR_MACHINE_INFO_W  pRpcMachineInfo = NULL;
    PVMDIR_KRB_INFO      pKrbInfo = NULL;
    PVMDIR_KRB_INFO      pRpcKrbInfo = NULL;
    handle_t hBinding = NULL;
    PSTR pszSRPUPN = NULL;
    PSTR pszSRPUPNAlloc = NULL;
    PWSTR pwszMachineName = NULL;
    PWSTR pwszDomainName = NULL;
    PWSTR pwszOrgUnit = NULL;
    PWSTR pwszPassword = NULL;

    if (IsNullOrEmptyString(pszServerName) ||
        IsNullOrEmptyString(pszUserName) ||
        IsNullOrEmptyString(pszPassword) ||
        IsNullOrEmptyString(pszDomainName) ||
        IsNullOrEmptyString(pszMachineName) ||
        !ppMachineInfo
       )
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = VmDirAllocateStringWFromA(
                              pszDomainName,
                              &pwszDomainName
                              );
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirAllocateStringWFromA(
                              pszMachineName,
                              &pwszMachineName
                              );
    BAIL_ON_VMDIR_ERROR(dwError);

    if (!IsNullOrEmptyString(pszOrgUnit))
    {
        dwError = VmDirAllocateStringWFromA(
                              pszOrgUnit,
                              &pwszOrgUnit
                              );
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = VmDirAllocateStringWFromA(
                              pszPassword,
                              &pwszPassword
                              );
    BAIL_ON_VMDIR_ERROR(dwError);

    if (!VmDirStringChrA(pszUserName, '@'))
    {
        dwError = VmDirAllocateStringPrintf(
                    &pszSRPUPNAlloc,
                    "%s@%s",
                    pszUserName,
                    pszDomainName
                    );
        BAIL_ON_VMDIR_ERROR(dwError);

        pszSRPUPN = pszSRPUPNAlloc;
    }
    else
    {
        pszSRPUPN = (PSTR)pszUserName;
    }

    dwError = VmDirCreateBindingHandleAuthA(
                    pszServerName,
                    NULL,
                    pszSRPUPN,
                    NULL,
                    pszPassword,
                    &hBinding);
    BAIL_ON_VMDIR_ERROR(dwError);

    VMDIR_RPC_TRY
    {

        if (dwFlags & VMDIR_CLIENT_JOIN_FLAGS_PREJOINED)
        {
            dwError = RpcVmDirGetComputerAccountInfo(
                        hBinding,
                        pwszDomainName,
                        pwszPassword,
                        pwszMachineName,
                        &pRpcMachineInfo,
                        &pRpcKrbInfo
                        );
        }
        else
        {
            dwError = RpcVmDirClientJoin(
                        hBinding,
                        pwszDomainName,
                        pwszMachineName,
                        pwszOrgUnit,
                        &pRpcMachineInfo,
                        &pRpcKrbInfo
                        );
        }
    }
    VMDIR_RPC_CATCH
    {
        VMDIR_RPC_GETERROR_CODE(dwError);
    }
    VMDIR_RPC_ENDTRY;
    BAIL_ON_VMDIR_ERROR(dwError);

    if (pRpcKrbInfo)
    {
        dwError = _VmDirCopyFromRpcKrbInfo(
                          pRpcKrbInfo,
                          &pKrbInfo
                          );
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = VmDirWriteToKeyTabFile(pKrbInfo);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = _VmDirCopyFromRpcMachineInfo(
                              pRpcMachineInfo,
                              &pMachineInfo
                              );
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirConfigSetDCAccountInfo(
                                    pszMachineName,
                                    pMachineInfo->pszComputerDN,
                                    pMachineInfo->pszPassword,
                                    strlen(pMachineInfo->pszPassword),
                                    pMachineInfo->pszMachineGUID
                                    );
    BAIL_ON_VMDIR_ERROR(dwError);

    *ppMachineInfo = pMachineInfo;

cleanup:

    if (hBinding)
    {
        VmDirFreeBindingHandle(&hBinding);
    }
    if (pRpcKrbInfo)
    {
        VmDirClientRpcFreeKrbInfo(pRpcKrbInfo);
    }
    if (pRpcMachineInfo)
    {
        VmDirClientRpcFreeMachineInfoW(pRpcMachineInfo);
    }
    VMDIR_SAFE_FREE_MEMORY(pszSRPUPNAlloc);
    VMDIR_SAFE_FREE_MEMORY(pwszMachineName);
    VMDIR_SAFE_FREE_MEMORY(pwszDomainName);
    VMDIR_SAFE_FREE_MEMORY(pwszOrgUnit);
    VMDIR_SAFE_FREE_MEMORY(pwszPassword);
    return dwError;
error:
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s error (%u)", __FUNCTION__, dwError);

    if (ppMachineInfo)
    {
        *ppMachineInfo = NULL;
    }
    if (pMachineInfo)
    {
        VmDirFreeMachineInfoA(pMachineInfo);
    }
    goto cleanup;
}
Beispiel #6
0
static
int
IsAttrInReplScope(
    VDIR_OPERATION *    op,
    char *              attrType,
    char *              attrMetaData,
    BOOLEAN *           inScope,
    PSTR*               ppszErrorMsg
    )
{
    int                     retVal = LDAP_SUCCESS;
    PLW_HASHTABLE_NODE      pNode = NULL;
    char                    origInvocationId[VMDIR_GUID_STR_LEN];
    USN                     origUsn = VmDirStringToLA( VmDirStringRChrA( attrMetaData, ':' ) + 1, NULL, 10 );
    int                     rc = 0;
    PSTR                    pszLocalErrorMsg = NULL;

    *inScope = FALSE;

    // attrMetaData format is: <local USN>:<version no>:<originating server ID>:<originating time>:<originating USN>
    VmDirStringNCpyA( origInvocationId, VMDIR_GUID_STR_LEN,
                      VmDirStringChrA( VmDirStringChrA( attrMetaData, ':' ) + 1, ':') + 1, VMDIR_GUID_STR_LEN - 1);
    origInvocationId[VMDIR_GUID_STR_LEN - 1] = '\0';

    // Skip the attribute:
    //    - if the originating server for the current state is same as the requesting server or if it is one of those
    //      attributes that have "local" scope only. E.g. sending ATTR_LAST_LOCAL_USN_PROCESSED and
    //      ATTR_UP_TO_DATE_VECTOR, causes continuous back-forth replication of Replication Agreements and Server
    //      entries between various servers.

    assert( op->syncReqCtrl != NULL );

    if ((attrType != NULL && (VmDirStringCompareA( attrType, ATTR_LAST_LOCAL_USN_PROCESSED, FALSE) == 0 ||
                              VmDirStringCompareA( attrType, ATTR_UP_TO_DATE_VECTOR, FALSE) == 0 ||
                              VmDirStringCompareA( attrType, VDIR_ATTRIBUTE_SEQUENCE_RID, FALSE) == 0)))

    {
        // Reset metaData value so that we don't send local only attribute back.
        attrMetaData[0] = '\0';
        *inScope = FALSE;
        goto cleanup;
    }
    else if ( attrType != NULL && (VmDirStringCompareA( attrType, ATTR_USN_CHANGED, FALSE) == 0))
    {
        ; // always send uSNChanged. (PR 1573117)
    }
    else if (VmDirStringCompareA( origInvocationId,
                  op->syncReqCtrl->value.syncReqCtrlVal.reqInvocationId.lberbv.bv_val,TRUE ) == 0)
    {
        // Change is originated from the requesting server.
        // Reset metaData value so that we don't send metaData as well as this attribute back.
        attrMetaData[0] = '\0';
        *inScope = FALSE;
        goto cleanup;
    }
    else
    {
        rc = LwRtlHashTableFindKey( op->syncDoneCtrl->value.syncDoneCtrlVal.htUtdVector, &pNode, origInvocationId );
        rc = LwNtStatusToWin32Error(rc);
        if (rc != 0 && rc != ERROR_NOT_FOUND)
        {
            VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "IsAttrInReplScope: LwRtlHashTableFindKey failed for origInvocationId: %s",
                      origInvocationId );
            retVal = LDAP_OPERATIONS_ERROR;
            BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                            "LwRtlHashTableFindKey failed.");
        }

        if (pNode == NULL) // Attribute is to be sent in the result entry.
        {
            UptoDateVectorEntry * utdVectorEntry = NULL;
            VDIR_BERVALUE         bvServerId = VDIR_BERVALUE_INIT;

            if (VmDirAllocateMemory( sizeof( UptoDateVectorEntry ), (PVOID *)&utdVectorEntry) != 0)
            {
                retVal = LDAP_OPERATIONS_ERROR;
                BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                                "IsAttrInReplScope: BervalContentDup failed.");
            }
            bvServerId.lberbv.bv_val = origInvocationId;
            bvServerId.lberbv.bv_len = VmDirStringLenA( origInvocationId );
            if (VmDirBervalContentDup( &bvServerId, &utdVectorEntry->invocationId ) != 0)
            {
                retVal = LDAP_OPERATIONS_ERROR;
                BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                                "IsAttrInReplScope: BervalContentDup failed.");
            }
            utdVectorEntry->currMaxOrigUsnProcessed = origUsn;
            LwRtlHashTableResizeAndInsert( op->syncDoneCtrl->value.syncDoneCtrlVal.htUtdVector,
                                           &utdVectorEntry->Node, &pNode);
            assert( pNode == NULL );    // assert the key of added node is unique
        }
        else
        {
            UptoDateVectorEntry *   utdVectorEntry = NULL;
            utdVectorEntry = (UptoDateVectorEntry *)LW_STRUCT_FROM_FIELD(pNode, UptoDateVectorEntry, Node);

            if (origUsn > utdVectorEntry->reqLastOrigUsnProcessed )
            { // Attribute is to be sent in the result entry.
                // Update if origUsn of this attribute is > the current highest
                if (origUsn > utdVectorEntry->currMaxOrigUsnProcessed )
                {
                    utdVectorEntry->currMaxOrigUsnProcessed = origUsn;
                }
            }
            else
            {
                VMDIR_LOG_VERBOSE( LDAP_DEBUG_REPL_ATTR,
                          "IsAttrInReplScope: Attribute: %s, metaData: %s, replication scope = FALSE",
                          attrType, attrMetaData );

                // Reset metaData value so that we don't send metaData for this attribute back.
                attrMetaData[0] = '\0';
                *inScope = FALSE;
                goto cleanup;
            }
        }
    }

    VMDIR_LOG_INFO( LDAP_DEBUG_REPL_ATTR, "IsAttrInReplScope: Attribute: %s, metaData: %s, replication scope = TRUE",
              attrType, attrMetaData );
    *inScope = TRUE;

cleanup:

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

    return( retVal );

error:

    goto cleanup;
}
Beispiel #7
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;
}
Beispiel #8
0
static int
ParseSyncRequestControlVal(
    VDIR_OPERATION *            op,
    BerValue *                  controlValue,       // Input: control value encoded as ber
    SyncRequestControlValue *   syncReqCtrlVal,     // Output
    VDIR_LDAP_RESULT *          lr                  // Output
    )
{
    int                     retVal = LDAP_SUCCESS;
    ber_tag_t               tag = LBER_ERROR;
    ber_len_t               len = 0;
    UptoDateVectorEntry *   utdVectorEntry = NULL;
    BerElementBuffer        berbuf;
    BerElement *            ber = (BerElement *)&berbuf;
    PSTR                    pszLocalErrorMsg = NULL;
    VDIR_BACKEND_CTX        backendCtx = {0};
    USN                     maxPartnerVisibleUSN = 0;

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

    ber_init2( ber, controlValue, LBER_USE_DER );

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

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

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

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

    }

    tag = ber_peek_tag( ber, &len );

    if (tag == LBER_SEQUENCE)
    { // syncCookie

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

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

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

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

            nextServerIdStr = syncReqCtrlVal->bvUtdVector.lberbv.bv_val;

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

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

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

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

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

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

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

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

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

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

    return retVal;

error:

    VMDIR_APPEND_ERROR_MSG(lr->pszErrMsg, pszLocalErrorMsg);

    goto cleanup;
}
Beispiel #9
0
//TODO_REMOVE_REPLV2
DWORD
VmDirAttributeMetaDataToHashMap(
    PVDIR_ATTRIBUTE   pAttrAttrMetaData,
    PLW_HASHMAP*      ppMetaDataMap
    )
{
    DWORD            dwError = 0;
    DWORD            dwCnt = 0;
    PLW_HASHMAP      pMetaDataMap = NULL;
    PSTR             pszKey = NULL;
    PVMDIR_ATTRIBUTE_METADATA   pMetaData = NULL;

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

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

    for (dwCnt = 0; pAttrAttrMetaData->vals[dwCnt].lberbv.bv_val != NULL; dwCnt++)
    {
        // Format is: <attr name>:<local USN>:<version no>:<originating server ID>:<originating time>:<originating USN>
        char* pszMetaData = VmDirStringChrA(pAttrAttrMetaData->vals[dwCnt].lberbv.bv_val, ':');
        if (pszMetaData == NULL)
        {
            BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_BACKEND_INVALID_METADATA);
        }

        // pszMetaData now points to <local USN>...
        pszMetaData++;

        //pAttrAttrMetaData->vals[i] has <attr type>\0<pszMetaData>
        *(pszMetaData - 1) = '\0';

        dwError = VmDirAllocateStringA(pAttrAttrMetaData->vals[dwCnt].lberbv.bv_val, &pszKey);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = VmDirMetaDataDeserialize(pszMetaData, &pMetaData);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = LwRtlHashMapInsert(pMetaDataMap, pszKey, pMetaData, NULL);
        BAIL_ON_VMDIR_ERROR(dwError);
        pszKey = NULL; pMetaData = NULL;
    }

    *ppMetaDataMap = pMetaDataMap;

cleanup:
    return dwError;

error:
    if (pMetaDataMap)
    {
        LwRtlHashMapClear(
                pMetaDataMap,
                VmDirFreeMetaDataMapPair,
                NULL);
        LwRtlFreeHashMap(&pMetaDataMap);
    }
    VmDirFreeMetaData(pMetaData);
    VMDIR_SAFE_FREE_MEMORY(pszKey);
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError);
    goto cleanup;
}
Beispiel #10
0
/*
 * Read schema definition from file
 * We ignore -
 * 1. DN/EntryDN
 * 2. ldapSyntax
 * 3. matchingRules
 */
static
DWORD
schemaReadFile(
    PCSTR   pszSchemaFilePath,
    PSTR**  pppszDescs,
    USHORT*  pdwSize
    )
{
    static PSTR pszDNTag = "DN:";
    static PSTR pszENTRYDNTag = "ENTRYDN:";
    static PSTR pszSyntaxTag = "ldapSyntaxes:";
    static PSTR pszMatchingRuleTag = "matchingRules:";
    static PSTR pszName = "NAME ";

    DWORD dwError = 0;
    USHORT dwSize = 0;
    DWORD dwCnt = 100;
    size_t iOldLen = 0 ;
    size_t iNewLen = 0 ;

    PSTR*    ppszDescs = NULL;
    PSTR    pszTmp = NULL;

    char  pbuf[2048] = {0};
    FILE* fp = NULL;


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

#ifndef _WIN32
    fp=fopen(pszSchemaFilePath, "r");
#else
    if( fopen_s(&fp, pszSchemaFilePath, "r") != 0 )
    {
        fp = NULL;
    }
#endif
    if(NULL == fp)
    {
        dwError = errno;
        VMDIR_LOG_ERROR(    VMDIR_LOG_MASK_ALL,
                            "Open schema file (%s) failed. Error (%d)",
                            pszSchemaFilePath,
                            dwError);

        BAIL_ON_VMDIR_ERROR(dwError);
    }

    while (fgets(pbuf, sizeof(pbuf), fp) != NULL)
    {
        PSTR pszTag = NULL;
        size_t len = VmDirStringLenA(pbuf)-1;

        if (pbuf[len] == '\n')
        {
            pbuf[len] = '\0';
        }

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

        if (VmDirStringNCompareA(pbuf, pszDNTag, VmDirStringLenA(pszDNTag), FALSE) == 0              ||
            VmDirStringNCompareA(pbuf, pszENTRYDNTag, VmDirStringLenA(pszENTRYDNTag), FALSE) == 0    ||
            VmDirStringNCompareA(pbuf, pszSyntaxTag, VmDirStringLenA(pszSyntaxTag), FALSE) == 0        ||
            VmDirStringNCompareA(pbuf, pszMatchingRuleTag, VmDirStringLenA(pszMatchingRuleTag), FALSE) == 0)
        {
            continue;
        }

        if (dwCnt == dwSize + 1)
        {
            DWORD    dwOldSize = dwCnt;
            dwCnt = dwCnt * 2;

            dwError = VmDirReallocateMemoryWithInit(
                    ppszDescs,
                    (PVOID*)&ppszDescs,
                    dwCnt * sizeof(*ppszDescs),
                    dwOldSize * sizeof(*ppszDescs));
            BAIL_ON_VMDIR_ERROR(dwError);
        }

        if (pbuf[0] != ' ')
        {
            dwError = VmDirAllocateStringA(pbuf,
                    &(ppszDescs[dwSize++]));
            BAIL_ON_VMDIR_ERROR(dwError);
        }
        else
        {
            // consolidate leading spaces into one
            char* pszNonSpace = pbuf+1;
            while (*pszNonSpace == ' ') { pszNonSpace++; }
            {

                // Normalising NAME field for everything attributeTypes,objectClasses,ditContentRules , i.e Removing multiple spaces
                if (VmDirStringNCompareA(pszNonSpace, pszName, VmDirStringLenA(pszName), TRUE) == 0)
                 {
                     _VmDirNormaliseNameField (pszNonSpace, VmDirStringLenA(pszNonSpace));
                 }

                iOldLen = VmDirStringLenA(ppszDescs[dwSize-1]);
                iNewLen = VmDirStringLenA(pszNonSpace-1);

                dwError = VmDirReallocateMemoryWithInit(
                        ppszDescs[dwSize-1],
                        (PVOID*)&pszTmp,
                        sizeof(char) * (iOldLen + iNewLen + 1),
                        sizeof(char) * iOldLen);
                BAIL_ON_VMDIR_ERROR(dwError);

                dwError = VmDirCopyMemory(
                    &pszTmp[iOldLen],
                    sizeof(char) * (iOldLen + iNewLen + 1),
                    &(pszNonSpace-1)[0],
                    iNewLen
                );
                BAIL_ON_VMDIR_ERROR(dwError);

                ppszDescs[dwSize-1] = pszTmp;
                pszTmp = NULL;
            }

        }
    }

    *pppszDescs = ppszDescs;
    *pdwSize = dwSize;

cleanup:

    if (fp)
    {
        fclose(fp);
    }

    return dwError;

error:

    *pppszDescs = NULL;
    *pdwSize = 0;

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

    goto cleanup;
}
Beispiel #11
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;

}