Beispiel #1
0
/* VmDirMDBDNToEntry: For a given entry DN, reads an entry from the entry DB.
 *
 * Returns: BE error - BACKEND_ERROR, BACKEND OPERATIONS, BACKEND_ENTRY_NOTFOUND
 *
 */
DWORD
VmDirMDBDNToEntry(
    PVDIR_BACKEND_CTX           pBECtx,
    PVDIR_SCHEMA_CTX            pSchemaCtx,
    VDIR_BERVALUE*              pDn,
    PVDIR_ENTRY                 pEntry,
    VDIR_BACKEND_ENTRY_LOCKTYPE entryLockType)
{
    DWORD       dwError = LDAP_SUCCESS;
    ENTRYID     eId = {0};

    // make sure we look up normalized dn value
    dwError = VmDirNormalizeDN( pDn, pSchemaCtx );
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirMDBDNToEntryId( pBECtx, pDn, &eId );
    BAIL_ON_VMDIR_ERROR( dwError );

    dwError = VmDirMDBEIdToEntry( pBECtx, pSchemaCtx, eId, pEntry, entryLockType );
    BAIL_ON_VMDIR_ERROR( dwError );

cleanup:

    return dwError;

error:

    VMDIR_LOG_ERROR( LDAP_DEBUG_BACKEND, "BEDNToEntry DN (%s) failed, (%u)(%s)",
                     VDIR_SAFE_STRING( pDn->bvnorm_val), dwError, VDIR_SAFE_STRING(pBECtx->pszBEErrorMsg) );

    VMDIR_SET_BACKEND_ERROR(dwError);   // if dwError no in BE space, set to ERROR_BACKEND_ERROR

    goto cleanup;
}
Beispiel #2
0
DWORD
VmDirGetKrbMasterKey(
    PSTR        pszFQDN, // [in] FQDN
    PBYTE*      ppKeyBlob,
    DWORD*      pSize
)
{
    DWORD       dwError = 0;
    PBYTE       pRetMasterKey = NULL;

    if (IsNullOrEmptyString(pszFQDN)
        || !ppKeyBlob
        || !pSize
       )
    {
        dwError = VMDIR_ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    // Currently, we only support single krb realm.
    // Global cache gVmdirKrbGlobals is initialized during startup stage.

    if (VmDirStringCompareA( pszFQDN, VDIR_SAFE_STRING(gVmdirKrbGlobals.pszRealm), FALSE) != 0)
    {
        dwError = VMDIR_ERROR_INVALID_REALM;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = VmDirAllocateMemory(
                    gVmdirKrbGlobals.bervMasterKey.lberbv.bv_len,
                    (PVOID*)&pRetMasterKey
                    );
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirCopyMemory (
                    pRetMasterKey,
                    gVmdirKrbGlobals.bervMasterKey.lberbv.bv_len,
                    gVmdirKrbGlobals.bervMasterKey.lberbv.bv_val,
                    gVmdirKrbGlobals.bervMasterKey.lberbv.bv_len
                    );
    BAIL_ON_VMDIR_ERROR(dwError);

    *ppKeyBlob = pRetMasterKey;
    *pSize     = (DWORD) gVmdirKrbGlobals.bervMasterKey.lberbv.bv_len;
    pRetMasterKey = NULL;

cleanup:

    return dwError;

error:

    VMDIR_LOG_ERROR( LDAP_DEBUG_RPC, "VmDirGetKrbMasterKey failed. (%u)(%s)",
                                     dwError, VDIR_SAFE_STRING(pszFQDN));
    VMDIR_SAFE_FREE_MEMORY(pRetMasterKey);

    goto cleanup;

}
Beispiel #3
0
/*
 * NormalizeMods:
 * 1. Normalize attribute values present in the modifications list.
 * 2. Make sure no duplicate value
 */
int
VmDirNormalizeMods(
    PVDIR_SCHEMA_CTX    pSchemaCtx,
    PVDIR_MODIFICATION  pMods,
    PSTR*               ppszErrorMsg
    )
{
    int            retVal = LDAP_SUCCESS;
    PVDIR_MODIFICATION pMod = NULL;
    unsigned int            i = 0;
    PSTR           pszDupAttributeName = NULL;
    PSTR           pszLocalErrorMsg = NULL;

    for (pMod = pMods; pMod != NULL; pMod = pMod->next)
    {
        if (pMod->attr.pATDesc == NULL
             &&
             (pMod->attr.pATDesc = VmDirSchemaAttrNameToDesc(pSchemaCtx, pMod->attr.type.lberbv.bv_val)) == NULL
           )
        {
            retVal = VMDIR_ERROR_UNDEFINED_TYPE;
            BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg),
                                            "Undefined attribute (%s)",
                                            VDIR_SAFE_STRING(pMod->attr.type.lberbv.bv_val));
        }
        for (i=0; i < pMod->attr.numVals; i++)
        {
            retVal = VmDirSchemaBervalNormalize(pSchemaCtx, pMod->attr.pATDesc, &pMod->attr.vals[i]);
            BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg),
                        "attribute value normalization failed (%s)(%.*s)",
                        VDIR_SAFE_STRING(pMod->attr.pATDesc->pszName),
                        VMDIR_MIN(pMod->attr.vals[i].lberbv.bv_len, VMDIR_MAX_LOG_OUTPUT_LEN),
                        VDIR_SAFE_STRING(pMod->attr.vals[i].lberbv.bv_val));
        }

        // Make sure we have no duplicate value in mod->attr
        retVal = VmDirAttributeDupValueCheck(&pMod->attr, &pszDupAttributeName);
        BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg),
                                        "attribute (%s) has duplicate value",
                                        VDIR_SAFE_STRING(pszDupAttributeName));
    }

cleanup:

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

    return retVal;

error:
    goto cleanup;
}
Beispiel #4
0
/*
    4.2.2. Bind Response
    The Bind response is defined as follows.
    BindResponse ::= [APPLICATION 1] SEQUENCE {
    COMPONENTS OF LDAPResult,
    serverSaslCreds [7] OCTET STRING OPTIONAL }
 */
VOID
VmDirSendSASLBindResponse(
    PVDIR_OPERATION     pOperation
    )
{
    DWORD               dwError = 0;
    BerElementBuffer    berbuf;
    BerElement *        ber = (BerElement *) &berbuf;
    PVDIR_LDAP_RESULT   pResult = &(pOperation->ldapResult);
    ber_tag_t           respType = GetResultTag(pOperation->reqCode);

    (void) memset( (char *)&berbuf, '\0', sizeof( BerElementBuffer ));

    ber_init2( ber, NULL, LBER_USE_DER );

    VMDIR_LOG_INFO( LDAP_DEBUG_ARGS, "VmDirSendLdapResponse: code (%d), Error (%d)(%s)",
                    respType, pResult->errCode, VDIR_SAFE_STRING(pResult->pszErrMsg));

    dwError = ber_printf( ber, "{it{ess" /*"}}"*/,
                        pOperation->msgId,                  // message sequence id
                        GetResultTag(pOperation->reqCode),  // ldap response type
                        pResult->errCode,                   // ldap return code e.g. LDAP_SASL_CONNTINUE
                        pResult->matchedDn.lberbv.bv_len > 0 ? pResult->matchedDn.lberbv.bv_val : "",
                        VDIR_SAFE_STRING(pResult->pszErrMsg));   // error text detail
    BAIL_ON_LBER_ERROR(dwError);

    // Send back TAG and SASL reply blob
    // NOTE, not exactly sure if we ever need to send Tag but WITHOUT blob reply if blob is empty.
    //       but this should NOT happen in GSSAPI scenario.
    if ( pResult->replyInfo.type == REP_SASL
         &&
         pResult->replyInfo.replyData.bvSaslReply.lberbv.bv_len > 0
       )
    {
        dwError = ber_printf( ber, "tO",
                              LDAP_TAG_SASL_RES_CREDS,
                              &pResult->replyInfo.replyData.bvSaslReply.lberbv );
        BAIL_ON_LBER_ERROR(dwError);
    }

    dwError = ber_printf( ber, "N}N}" );
    BAIL_ON_LBER_ERROR(dwError);

    dwError = WriteBerOnSocket( pOperation->conn, ber );
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:

    ber_free_buf( ber );

    return;

error:

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

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

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

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

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

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

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

            break;
        }
    }

cleanup:

    return dwError;

error:

    goto cleanup;
}
Beispiel #6
0
/* MdbDeleteEntry: Deletes an entry in the MDB DBs.
 *
 * Returns: BE error codes.
 *
 */
DWORD
VmDirMDBDeleteEntry(
    PVDIR_BACKEND_CTX   pBECtx,
    PVDIR_MODIFICATION  pMods,
    PVDIR_ENTRY         pEntry
    )
{
    DWORD                   dwError = 0;
    VDIR_MODIFICATION *     mod = NULL;
    PVDIR_DB_TXN            pTxn = NULL;

    assert( pBECtx && pBECtx->pBEPrivate && pMods && pEntry );

    pTxn = (PVDIR_DB_TXN)pBECtx->pBEPrivate;

    // Delete child from the parentId index
    dwError = MDBDeleteParentIdIndex( pBECtx, &(pEntry->pdn), pEntry->eId );
    BAIL_ON_VMDIR_ERROR(dwError);

    for (mod = pMods; mod != NULL; mod = mod->next)
    {
        switch (mod->operation)
        {
            case MOD_OP_DELETE:
                if ((dwError = MdbUpdateIndicesForAttr( pBECtx->pBE, pTxn, &(pEntry->dn), &(mod->attr.type), mod->attr.vals, mod->attr.numVals,
                                                       pEntry->eId, BE_INDEX_OP_TYPE_DELETE )) != 0)
                {
                    dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx,
                                                VDIR_SAFE_STRING(mod->attr.type.lberbv.bv_val));
                    BAIL_ON_VMDIR_ERROR( dwError );
                }
                break;
            default:
                assert( FALSE );
        }
    }

    // Delete Entry Blob
    if ((dwError = MDBDeleteEntryBlob(pBECtx, pEntry->eId)) != 0)
    {
        dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx, "MDBDeleteEntryBlob");
        BAIL_ON_VMDIR_ERROR( dwError );
    }

cleanup:
     return dwError;

error:
    VMDIR_SET_BACKEND_ERROR(dwError);   // if dwError no in BE space, set to ERROR_BACKEND_ERROR

    VMDIR_LOG_ERROR(LDAP_DEBUG_BACKEND, "VmDirMDBDeleteEntry: failed: error=%d,DN=%s",
                    dwError, VDIR_SAFE_STRING(pEntry->dn.lberbv.bv_val));
     goto cleanup;
}
Beispiel #7
0
DWORD
VmDirSchemaBervalSyntaxCheck(
    PVDIR_SCHEMA_CTX        pCtx,
    PVDIR_SCHEMA_AT_DESC    pATDesc,
    PVDIR_BERVALUE                 pBerv
    )
{
    DWORD dwError = 0;

    if (!pCtx || !pATDesc || !pBerv)
    {
        if (pCtx)
        {
            pCtx->dwErrorCode = ERROR_INVALID_PARAMETER;

            VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg);
            dwError = VmDirAllocateStringA(
                    "No descriptor or value",
                    &pCtx->pszErrorMsg);
        }

        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    //TODO, if NO pSyntax, i.e. this syntax is NOT supported yet.
    // just bypass checking and move on.
    if (pATDesc->pSyntax &&
        pATDesc->pSyntax->pValidateFunc(pBerv) == FALSE)
    {
        pCtx->dwErrorCode = ERROR_INVALID_SYNTAX;

        VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg);
        dwError = VmDirAllocateStringAVsnprintf(
                &pCtx->pszErrorMsg,
                "%s value (%s) is not a valid (%s) syntax",
                pATDesc->pszName,
                VDIR_SAFE_STRING(pBerv->lberbv.bv_val),
                VDIR_SAFE_STRING(pATDesc->pszSyntaxName));

        dwError = ERROR_INVALID_SYNTAX;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

cleanup:

    return dwError;

error:

    goto cleanup;
}
Beispiel #8
0
/* MdbCheckRefIntegrity: Checks for the attributes that have referential integrity constraint set, that the DN attribute
 *                    values refer to existing objects.
 *
 * Returns: BE error codes.
 *
 */
DWORD
VmDirMDBCheckRefIntegrity(
    PVDIR_BACKEND_CTX   pBECtx,
    PVDIR_ENTRY         pEntry)
{
    DWORD               dwError = 0;
    VDIR_ATTRIBUTE *    attr = NULL;

    assert( pBECtx && pBECtx->pBEPrivate  && pEntry );

    for (attr = pEntry->attrs; attr; attr = attr->next)
    {
        // SJ-TBD: Instead of checking referential integrity for hard coded attributes, we should have a
        // proprietary flag e.g. X-constraint in the attribute schema definition
        if (VmDirStringCompareA(attr->type.lberbv.bv_val, ATTR_MEMBER, FALSE) == 0)
        {
            unsigned int i = 0;
            ENTRYID   eId = 0;
            for (; i < attr->numVals; i++)
            {
                // Lookup in the DN index.
                if ((dwError = VmDirNormalizeDN( &(attr->vals[i]), pEntry->pSchemaCtx)) != 0)
                {
                    dwError = ERROR_BACKEND_OPERATIONS;
                    BAIL_ON_VMDIR_ERROR( dwError );
                }

                if ((dwError = VmDirMDBDNToEntryId( pBECtx, &(attr->vals[i]), &eId )) != 0)
                {
                    dwError = MDBToBackendError(dwError, ERROR_BACKEND_ENTRY_NOTFOUND,
                                                ERROR_BACKEND_CONSTRAINT, pBECtx,
                                                VDIR_SAFE_STRING(attr->vals[i].lberbv.bv_val));
                    BAIL_ON_VMDIR_ERROR( dwError );
                }
            }
        }
    }

cleanup:

    return dwError;

error:
    // TODO set pBECtx->pszBEErrorMsg
    VMDIR_LOG_ERROR( LDAP_DEBUG_BACKEND, "BE DN (%s) reference check, error (%u)(%s)",
                     pEntry->dn.lberbv_val, dwError, VDIR_SAFE_STRING(pBECtx->pszBEErrorMsg) );

    VMDIR_SET_BACKEND_ERROR(dwError);   // if dwError no in BE space, set to ERROR_BACKEND_ERROR

    goto cleanup;
}
Beispiel #9
0
/*
 * Called during entry add
 *
 *  grouptype :
 *
        http://msdn.microsoft.com/en-us/library/windows/desktop/ms675935%28v=vs.85%29.aspx
        Value   Description
        1 (0x00000001)  Specifies a group that is created by the system.
        2 (0x00000002)  Specifies a group with global scope.
        4 (0x00000004)  Specifies a group with domain local scope.
        8 (0x00000008)  Specifies a group with universal scope.
        16 (0x00000010) Specifies an APP_BASIC group for Windows Server Authorization Manager.
        32 (0x00000020) Specifies an APP_QUERY group for Windows Server Authorization Manager.
        2147483648 (0x80000000) Specifies a security group. If this flag is not set, then the group is a distribution group.

    Currently, Lotus only supports global scope (2).
 */
DWORD
VmDirPluginGroupTypePreAdd(
    PVDIR_OPERATION  pOperation,
    PVDIR_ENTRY      pEntry,
    DWORD            dwPriorResult
    )
{
    DWORD               dwError = 0;
    PSTR                pszLocalErrorMsg = NULL;

    if ( pOperation->opType != VDIR_OPERATION_TYPE_REPL
         &&
         TRUE == VmDirIsEntryWithObjectclass(pEntry, OC_GROUP)
       )
    {
        PVDIR_ATTRIBUTE pAttrGroupType = VmDirFindAttrByName(pEntry, ATTR_GROUPTYPE);

        if (pAttrGroupType == NULL)
        {
            dwError = VmDirEntryAddSingleValueStrAttribute(pEntry, ATTR_GROUPTYPE, GROUPTYPE_GLOBAL_SCOPE);
            BAIL_ON_VMDIR_ERROR(dwError);
        }
        else
        {
            if ( pAttrGroupType->numVals != 1       // grouptype is a single value attribute
                 ||
                 VmDirStringCompareA( VDIR_SAFE_STRING( pAttrGroupType->vals[0].lberbv.bv_val),
                                       GROUPTYPE_GLOBAL_SCOPE, FALSE) != 0
               )
            {
                dwError = ERROR_INVALID_ENTRY;
                BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrorMsg, "invalid or unsupported grouptype (%s)",
                                              VDIR_SAFE_STRING( pAttrGroupType->vals[0].lberbv.bv_val));
            }
        }
    }

cleanup:

    VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg);

    return dwError;

error:

    VmDirLog( LDAP_DEBUG_ANY, "Group check: (%d)(%s)", dwError, VDIR_SAFE_STRING(pszLocalErrorMsg));

    VMDIR_APPEND_ERROR_MSG(pOperation->ldapResult.pszErrMsg, pszLocalErrorMsg);

    goto cleanup;
}
Beispiel #10
0
static
DWORD
_VmDirReplDCConnectInit(
    PVMDIR_REPLICATION_AGREEMENT    pReplAgr
    )
{
    DWORD   dwError = 0;

    pReplAgr->dcConn.connType = DC_CONNECTION_TYPE_REPL;
    pReplAgr->dcConn.creds.bUseDCAccountCreds = TRUE;
    pReplAgr->dcConn.dwConnectTimeoutSec = gVmdirGlobals.dwLdapConnectTimeoutSec;

    dwError = VmDirAllocateStringA(pReplAgr->pszHostname, &pReplAgr->dcConn.pszHostname);
    BAIL_ON_VMDIR_ERROR(dwError);

    // spawn background thread to handle connection
    VmDirInitDCConnThread(&pReplAgr->dcConn);

cleanup:
    return dwError;

error:
    pReplAgr->isDeleted = TRUE;

    VMDIR_LOG_ERROR(
            VMDIR_LOG_MASK_ALL,
            "%s: %s error code (%d)",
            __FUNCTION__,
            VDIR_SAFE_STRING(pReplAgr->ldapURI),
            dwError);

    goto cleanup;
}
Beispiel #11
0
static
VOID
VmDirRegConfigHandleClose(
    PVMDIR_CONFIG_CONNECTION_HANDLE pCfgHandle
    )
{
#ifndef _WIN32
    if (pCfgHandle->hConnection)
    {
        if (pCfgHandle->hKey)
        {
            DWORD dwError = RegCloseKey(
                        pCfgHandle->hConnection,
                        pCfgHandle->hKey);
            if (dwError != 0)
            {   // Do not bail, best effort to cleanup.
                VmDirLog(
                        LDAP_DEBUG_ANY,
                        "RegCloseKey failed, Error code: (%u)(%s)",
                        dwError,
                        VDIR_SAFE_STRING(LwWin32ErrorToName(dwError)));
            }
        }

        RegCloseServer(pCfgHandle->hConnection);
    }
#else
    if (pCfgHandle->hKey)
    {
        RegCloseKey(pCfgHandle->hKey);
    }
#endif

    VMDIR_SAFE_FREE_MEMORY(pCfgHandle);
}
Beispiel #12
0
static
DWORD
_VmDirSchemaCheckNameform(
    PVDIR_SCHEMA_CTX        pCtx,
    PVDIR_ENTRY             pEntry,
    PVDIR_SCHEMA_OC_DESC    pStructOCDesc
    )
{
    DWORD       dwError = 0;
    PSTR        pszLocalErrorMsg = NULL;

    if ( !pCtx || !pStructOCDesc || !pEntry || !pEntry->dn.bvnorm_val )
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

#if 0

    // should NOT enable this until we have all namform and structure rule defined
    if ( pStructOCDesc->usNumMustRDNs > 0 )
    {   // not yet support multi RDNs case.  only check the first MUST RDN for now.
        size_t  iLen = VmDirStringLenA(pStructOCDesc->ppszMustRDNs[0]);

        if ( VmDirStringNCompareA( pEntry->dn.bvnorm_val,
                                   pStructOCDesc->ppszMustRDNs[0],
                                   iLen,
                                   FALSE ) != 0
             ||
             pEntry->dn.bvnorm_val[iLen] != '='
           )
        {
            dwError = ERROR_INVALID_ENTRY;
            BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrorMsg,
                                          "_VmDirSchemaCheckNameform: rdn must be (%s). (%d)",
                                          VDIR_SAFE_STRING( pStructOCDesc->ppszMustRDNs[0] ), dwError );
        }
    }

#endif

cleanup:

    VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg);

    return dwError;

error:

    if ( !pCtx->pszErrorMsg )
    {
        pCtx->pszErrorMsg = pszLocalErrorMsg;
        pszLocalErrorMsg = NULL;

        pCtx->dwErrorCode = dwError;
    }

    goto cleanup;
}
Beispiel #13
0
/*
 * Create an Attribute on the heap and establish its pATDesc
 * two memory allocate
 * 1. pAttribute
 * 2. pAttribute->vals (BerValue array is one more then requested)
 */
DWORD
VmDirAttributeAllocate(
    PCSTR   pszName,
    USHORT  usBerSize,
    PVDIR_SCHEMA_CTX pCtx,
    PVDIR_ATTRIBUTE* ppOutAttr)
{
    DWORD    dwError = 0;
    PVDIR_ATTRIBUTE    pAttr = NULL;

    if (!ppOutAttr)
    {
        return 0;
    }

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

    // add one more BerValue as Encode/Decode entry in data store layer needs it.
    dwError = VmDirAllocateMemory(
            sizeof(VDIR_BERVALUE) * (usBerSize + 1),
            (PVOID*)&pAttr->vals);
    BAIL_ON_VMDIR_ERROR(dwError);

    pAttr->numVals = usBerSize;

    pAttr->pATDesc = VmDirSchemaAttrNameToDesc(
                    pCtx,
                    pszName);
    if (!pAttr->pATDesc)
    {
        dwError = VMDIR_ERROR_NO_SUCH_ATTRIBUTE;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    // pAttr->type.lberbv.bv_val always store in-place
    pAttr->type.lberbv.bv_val = pAttr->pATDesc->pszName;
    pAttr->type.lberbv.bv_len = VmDirStringLenA(pAttr->type.lberbv.bv_val);

    *ppOutAttr = pAttr;

cleanup:

    return dwError;

error:

    if (pAttr)
    {
        VmDirFreeAttribute(pAttr);
    }

    VmDirLog( LDAP_DEBUG_ANY, "AllocateAttribute failed (%d)(%s)",
              dwError, VDIR_SAFE_STRING(pszName));

    goto cleanup;
}
Beispiel #14
0
int
VmDirFirstReplicationCycle(
    PCSTR                           pszHostname,
    VMDIR_REPLICATION_AGREEMENT *   pReplAgr)
{
    int                     retVal = LDAP_SUCCESS;
    PSTR                    pszLocalErrorMsg = NULL;
    BOOLEAN                 bWriteInvocationId = FALSE;
    BOOLEAN                 bHasXlog = FALSE;
#ifndef _WIN32
    const char  *dbHomeDir = VMDIR_DB_DIR;
#else
    _TCHAR      dbHomeDir[MAX_PATH];
    size_t last_char_pos = 0;
    const char   fileSeperator = '\\';

    retVal = VmDirMDBGetHomeDir(dbHomeDir);
    BAIL_ON_VMDIR_ERROR ( retVal );
    last_char_pos = strlen(dbHomeDir) - 1;
    if (dbHomeDir[last_char_pos] == fileSeperator)
    {
        dbHomeDir[last_char_pos] = '\0';
    }
#endif

    assert( gFirstReplCycleMode == FIRST_REPL_CYCLE_MODE_COPY_DB );

    retVal = _VmDirGetRemoteDBUsingRPC(pszHostname, dbHomeDir, &bHasXlog);
    BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
                "VmDirFirstReplicationCycle: _VmDirGetRemoteDBUsingRPC() call failed with error: %d", retVal );

    retVal = _VmDirSwapDB(dbHomeDir, bHasXlog);
    BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
                "VmDirFirstReplicationCycle: _VmDirSwapDB() call failed, error: %d.", retVal );

    VMDIR_LOG_INFO(VMDIR_LOG_MASK_ALL, "Remote DB copied from %s, and swapped successfully", pszHostname);

    // Wrap up the 1st replication cycle by updating replication cookies.
    retVal = _VmDirWrapUpFirstReplicationCycle( pszHostname, pReplAgr );

    BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
            "VmDirFirstReplicationCycle: _VmDirWrapUpFirstReplicationCycle() call failed, error: %d.", retVal );

    retVal = LoadServerGlobals(&bWriteInvocationId);

    BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
            "VmDirFirstReplicationCycle: LoadServerGlobals call failed, error: %d.", retVal );
cleanup:
    VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg);
    return retVal;

error:
    retVal = LDAP_OPERATIONS_ERROR;
    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s", VDIR_SAFE_STRING(pszLocalErrorMsg) );
    goto cleanup;
}
Beispiel #15
0
/*
 * Mark MUST attributes presented.
 */
static
DWORD
_VmDirSchemaCheckMustAttrPresent(
    PVDIR_SCHEMA_CTX        pCtx,
    PVDIR_SCHEMA_OC_DESC    pOCDesc,
    PVDIR_ENTRY             pEntry,
    PBOOLEAN                pbPresentList
    )
{
    DWORD   dwError = 0;
    int     iCnt = 0;

    assert(pCtx && pOCDesc && pEntry && pbPresentList);

    for (iCnt = 0; pOCDesc->ppAllMustATs[iCnt] != NULL; iCnt++)
    {
        int         iIdx = 0;
        PVDIR_ATTRIBUTE  pAttr = pEntry->attrs;

        for (iIdx = 0; pAttr != NULL; pAttr = pAttr->next, iIdx++)
        {
            if (pAttr->pATDesc->usAttrID == pOCDesc->ppAllMustATs[iCnt]->usAttrID)
            {
                pbPresentList[iIdx] = TRUE;     // find must attribute
                break;
            }
        }

        // ignore missing "nTSecurityDescriptor" must attribute for now.
        // ADSI needs it to be a must attribute.  However, it is NOT easy/clean to make and
        // enforce this change in Lotus. (e.g. in VmDirInteralAddEntry, schema check is called
        //   prior to SD generation currently.)
        // TODO, clean up SD generation in bootstratp/promo/normal paths.
        if ( pAttr == NULL
             &&
             VmDirStringCompareA( pOCDesc->ppAllMustATs[iCnt]->pszName,
                                  ATTR_OBJECT_SECURITY_DESCRIPTOR,
                                  FALSE) != 0
           )
        {
            VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg);
            VmDirAllocateStringAVsnprintf(&pCtx->pszErrorMsg,
                    "Missing must attribute (%s)",
                    VDIR_SAFE_STRING(pOCDesc->ppAllMustATs[iCnt]->pszName));

            VmDirLog( LDAP_DEBUG_ANY, "%s", pCtx->pszErrorMsg);

            dwError = pCtx->dwErrorCode = ERROR_INVALID_ENTRY;
            BAIL_ON_VMDIR_ERROR(dwError);
        }
    }

error:

    return dwError;
}
Beispiel #16
0
VOID
VdcadminSetVmdirState(
    VOID
    )
{
    DWORD       dwError = 0;
    char        pszState[SIZE_256] = {0};
    PSTR        pszLocalErrorMsg = NULL;
    PVMDIR_SERVER_CONTEXT hServer = NULL;
    VDIR_SERVER_STATE vmdirState = VMDIRD_STATE_NORMAL;

    VmDirReadString(
        "Enter state (NORMAL|READ_ONLY): ",
        pszState,
        SIZE_256,
        FALSE);

    if ( VmDirStringCompareA( pszState, "NORMAL", FALSE) == 0 )
    {
        vmdirState = VMDIRD_STATE_NORMAL;
    }
    else if ( VmDirStringCompareA( pszState, "READ_ONLY", FALSE) == 0 )
    {
        vmdirState = VMDIRD_STATE_READ_ONLY;
    }
    else
    {
        dwError = VMDIR_ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    if (g_hServer)
    {
        hServer = g_hServer;
    }

    dwError = VmDirSetState(hServer, vmdirState );
    BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, (pszLocalErrorMsg),
                                  "VmDirSetState() failed. error(%u)", dwError );

    printf("\n\n State of Vmdir set to %s\n\n", pszState);

cleanup:

    VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg);

    return;

error:

    printf("\n SetVmDirState failed: %s\n", VDIR_SAFE_STRING(pszLocalErrorMsg));

    goto cleanup;
}
Beispiel #17
0
DWORD
VmDirLogSearchRequest(
    SearchReq*  pSReq,
    ber_len_t   iNumAttr
    )
{
    DWORD   dwError = 0;
    PSTR    pszLogMsg = NULL;
    size_t  currLen = 0;
    size_t  msgSize = 0;
    int     iCnt = 0;

    assert(pSReq);

    for ( iCnt = 0, msgSize = 0; iCnt<iNumAttr; iCnt++ )
    {
       msgSize += pSReq->attrs[iCnt].lberbv.bv_len + 2 /* for a ',' and ' ' */;
    }

    dwError = VmDirAllocateMemory( msgSize + 1, (PVOID *)&pszLogMsg );
    BAIL_ON_VMDIR_ERROR(dwError);

    for ( iCnt = 0, currLen = 0; iCnt<iNumAttr; iCnt++ )
    {
       VmDirStringNPrintFA( pszLogMsg + currLen, (msgSize + 1 - currLen), msgSize, "%s, ", pSReq->attrs[iCnt].lberbv.bv_val);
       currLen += pSReq->attrs[iCnt].lberbv.bv_len + 2;
    }
    pszLogMsg[currLen - 2] = '\0';

    VMDIR_LOG_VERBOSE( LDAP_DEBUG_ARGS, "    Required attributes: %s", pszLogMsg );

cleanup:

    VMDIR_SAFE_FREE_MEMORY( pszLogMsg );

    return dwError;

error:

    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL,
        "VmDirLogSearchRequest: dwError: %lu, msgSize: %lu, iNumAttr: %lu",
        dwError, msgSize, iNumAttr);

    for ( iCnt = 0; iCnt<iNumAttr; iCnt++ )
    {
        VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL,
            "    attr[%d] len: %lu, val: \"%.*s\"",
            iCnt, pSReq->attrs[iCnt].lberbv.bv_len, 256,
            VDIR_SAFE_STRING(pSReq->attrs[iCnt].lberbv.bv_val));
    }

    goto cleanup;
}
Beispiel #18
0
/* MdbDeleteEntry: Deletes an entry in the MDB DBs.
 *
 * Returns: BE error codes.
 *
 */
DWORD
VmDirMDBDeleteEntry(
    PVDIR_BACKEND_CTX   pBECtx,
    PVDIR_MODIFICATION  pMods,
    PVDIR_ENTRY         pEntry
    )
{
    DWORD   dwError = 0;

    assert( pBECtx && pBECtx->pBEPrivate && pEntry );

    // Delete child from the parentId index
    dwError = MDBDeleteParentIdIndex( pBECtx, &(pEntry->pdn), pEntry->eId );
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirMDBModifyEntry( pBECtx, pMods, pEntry);
    BAIL_ON_VMDIR_ERROR( dwError );

    if ((dwError = MDBCreateParentIdIndex( pBECtx, &(gVmdirServerGlobals.delObjsContainerDN), pEntry->eId )) != 0)
    {
        dwError = MDBToBackendError(dwError, ERROR_BACKEND_ENTRY_NOTFOUND,
                                    ERROR_BACKEND_PARENT_NOTFOUND, pBECtx, "CreateParentIdIndex");
        BAIL_ON_VMDIR_ERROR( dwError );
    }

cleanup:

    return dwError;

error:

    VMDIR_LOG_ERROR( LDAP_DEBUG_BACKEND, "BEDeleteEntry DN (%s) failed, (%u)(%s)",
                              VDIR_SAFE_STRING( pEntry->dn.bvnorm_val),
                              dwError, VDIR_SAFE_STRING(pBECtx->pszBEErrorMsg) );

    VMDIR_SET_BACKEND_ERROR(dwError);   // if dwError no in BE space, set to ERROR_BACKEND_ERROR

    goto cleanup;
}
Beispiel #19
0
static
DWORD
AddAttrValsToEntryStruct(
   VDIR_ENTRY *     e,
   VDIR_ATTRIBUTE * eAttr,    // Entry attribute to be updated with new attribute values
   VDIR_ATTRIBUTE * modAttr,  // Modify attribute containing new attribute values
   PSTR*            ppszErrMsg
   )
{
    unsigned int     i = 0;
    unsigned int     j = 0;
    DWORD   dwError = ERROR_SUCCESS;
    PSTR    pszErrMsg = NULL;

    assert(e->allocType == ENTRY_STORAGE_FORMAT_NORMAL);

    if ((size_t)eAttr->numVals + (size_t)modAttr->numVals > UINT16_MAX)
    {
        dwError = VMDIR_ERROR_DATA_CONSTRAINT_VIOLATION;
        BAIL_ON_VMDIR_ERROR_WITH_MSG(dwError, (pszErrMsg),
                                      "Too many %s attribute values, max %u allowed.",
                                      VDIR_SAFE_STRING(eAttr->type.lberbv_val), UINT16_MAX);
    }

    dwError = VmDirReallocateMemoryWithInit(eAttr->vals, (PVOID*)(&(eAttr->vals)),
                                             (eAttr->numVals + modAttr->numVals + 1) * sizeof(VDIR_BERVALUE),
                                             (eAttr->numVals + 1) * sizeof(VDIR_BERVALUE));
    BAIL_ON_VMDIR_ERROR(dwError);

    for (i = 0, j = eAttr->numVals; i < modAttr->numVals; i++, j++)
    {
        dwError = VmDirBervalContentDup(&modAttr->vals[i], &eAttr->vals[j]);
        BAIL_ON_VMDIR_ERROR(dwError);
    }
    memset(&(eAttr->vals[j]), 0, sizeof(VDIR_BERVALUE)); // set last BerValue.lberbv.bv_val to NULL;
    eAttr->numVals += modAttr->numVals;

cleanup:
    VMDIR_SAFE_FREE_MEMORY(pszErrMsg);
    return dwError;

error:
    if (ppszErrMsg)
    {
        *ppszErrMsg = pszErrMsg;
        pszErrMsg = NULL;
    }

    goto cleanup;
}
Beispiel #20
0
static
int
_VmDirInternalNormalSearch(
    VDIR_OPERATION *    pOperation
    )
{
    int     retVal = LDAP_SUCCESS;
    PSTR    pszLocalErrMsg = NULL;
    ENTRYID eStartingId = 0;

    // should never happen - there are asserts in calling function
    if (pOperation == NULL)
    {
        BAIL_WITH_VMDIR_ERROR(retVal, VMDIR_ERROR_INVALID_PARAMETER);
    }

    retVal = BuildCandidateList(pOperation, pOperation->request.searchReq.filter, eStartingId);
    BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, pszLocalErrMsg, "BuildCandidateList failed.");

    if (pOperation->request.searchReq.filter->computeResult == FILTER_RES_TRUE)
    {
        retVal = VMDIR_ERROR_UNWILLING_TO_PERFORM;
        BAIL_ON_VMDIR_ERROR_WITH_MSG(
            retVal,
            pszLocalErrMsg,
            "Full scan of Entry DB is required. Refine your search.");
    }

    retVal = VmDirProcessCandidateList(pOperation);
    BAIL_ON_VMDIR_ERROR_WITH_MSG(
        retVal,
        pszLocalErrMsg,
        "VmDirProcessCandidateList failed. (%u)(%s)",
        retVal,
        VDIR_SAFE_STRING(pOperation->ldapResult.pszErrMsg));

cleanup:
    VMDIR_SAFE_FREE_MEMORY(pszLocalErrMsg);
    return retVal;

error:
    VMDIR_LOG_ERROR(
            VMDIR_LOG_MASK_ALL,
            "%s failed, error(%d)",
            __FUNCTION__,
            retVal);
    goto cleanup;
}
Beispiel #21
0
DWORD
VmDirSchemaCheckSetAttrDesc(
    PVDIR_SCHEMA_CTX pCtx,
    PVDIR_ENTRY           pEntry
    )
{
    DWORD dwError = 0;
    VDIR_ATTRIBUTE* pAttr = NULL;

    assert(pCtx && pEntry);

    for (pAttr = pEntry->attrs; pAttr; pAttr = pAttr->next)
    {
        if (!pAttr->pATDesc)
        {
            if (VmDirStringCompareA( pAttr->type.lberbv.bv_val, ATTR_VMW_ORGANIZATION_GUID, FALSE ) == 0)
            {
                continue; // going to delete this attribute any way.
            }
            if (VmDirStringCompareA( pAttr->type.lberbv.bv_val, ATTR_VMW_OBJECT_SECURITY_DESCRIPTOR, FALSE ) == 0)
            {
                pAttr->pATDesc = VmDirSchemaAttrNameToDesc(pCtx, ATTR_OBJECT_SECURITY_DESCRIPTOR);
            }
            else
            {
                pAttr->pATDesc = VmDirSchemaAttrNameToDesc(pCtx, pAttr->type.lberbv.bv_val);
            }
            if (!pAttr->pATDesc)
            {
                pCtx->dwErrorCode = ERROR_INVALID_SCHEMA;

                VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg);
                dwError = VmDirAllocateStringAVsnprintf(
                        &pCtx->pszErrorMsg,
                        "Attribute (%s) is not defined in schema",
                        VDIR_SAFE_STRING(pAttr->type.lberbv.bv_val));

                dwError = ERROR_INVALID_SCHEMA;
                BAIL_ON_VMDIR_ERROR(dwError);
            }
        }
    }

error:

    return dwError;
}
Beispiel #22
0
DWORD
VmDirSrvSetupTenantInstance(
    PCSTR pszFQDomainName,
    PCSTR pszUsername,
    PCSTR pszPassword
    )
{
    DWORD dwError = 0;
    PSTR  pszDomainDN = NULL;
    PVDIR_SCHEMA_CTX pSchemaCtx = NULL;

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

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

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

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

cleanup:

    VMDIR_SAFE_FREE_MEMORY(pszDomainDN);

    if (pSchemaCtx)
    {
        VmDirSchemaCtxRelease(pSchemaCtx);
    }

    return dwError;

error:
    VmDirLog(LDAP_DEBUG_ANY, "VmDirSrvSetupTenantInstance failed. Error(%u)", dwError);
    goto cleanup;
}
Beispiel #23
0
VOID
VdcadminGetVmdirState(
    VOID
    )
{
    DWORD       dwError = 0;
    PCSTR       pszState = NULL;
    PSTR        pszLocalErrorMsg = NULL;
    PVMDIR_SERVER_CONTEXT hServer = NULL;
    UINT32      vmdirState = 0;


    if (g_hServer)
    {
        hServer = g_hServer;
    }

    dwError = VmDirGetState(hServer, &vmdirState );
    BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, (pszLocalErrorMsg),
                                  "VmDirGetState() failed. error(%u)", dwError );

    switch (vmdirState)
    {
        case VMDIRD_STATE_UNDEFINED: pszState = "Undefined"; break;
        case VMDIRD_STATE_STARTUP:   pszState = "Startup"; break;
        case VMDIRD_STATE_READ_ONLY: pszState = "Read only"; break;
        case VMDIRD_STATE_NORMAL:    pszState = "Normal" ; break;
        case VMDIRD_STATE_SHUTDOWN:  pszState = "Shutdown"; break;
    }
    printf("\n\n VmDir State is - %s\n\n", pszState);

cleanup:

    VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg);

    return;

error:

    printf("\n GetVmDirState failed: %s\n", VDIR_SAFE_STRING(pszLocalErrorMsg));

    goto cleanup;
}
Beispiel #24
0
static
DWORD
_VmDirNormaliseNameField(
    PSTR    pszSource ,
    size_t      dwLen
    )
{

    DWORD    i        = 0;
    DWORD    j        = 0;
    DWORD    dwError  = 0;
    DWORD    dwState  = 0;

    for (i=0 ; i<dwLen ;i++ )
    {
        if (pszSource[i] == ' ')
        {
            if (dwState == 0 )
            {
                pszSource[j++] = pszSource[i];
                dwState = 1;
            }
            else
            {
               // Do Nothing , Ignore Extra Spaces ..
            }
        }
        else
        {
            pszSource[j++] = pszSource[i];
            dwState = 0;
        }
    }

    pszSource[j++] = '\0' ;
    VMDIR_LOG_DEBUG( VMDIR_LOG_MASK_ALL, "Formatted NAME string is  - %s",
            VDIR_SAFE_STRING(pszSource) );

    return dwError ;

}
Beispiel #25
0
/*
 * Error map from MDB to BE space
 * If no map specified, ERROR_BACKEND_ERROR is returned.
 *
 * BECtx.dwBEErrorCode is set to the first mdb error encountered
 * BECtx.pszBEErrorMsg is set to the first mdb error text encountered
 *
 * NOTE, this could be called multiple times during one LDAP level operation.
 * The last one counts.
 */
DWORD
MDBToBackendError(
    DWORD               dwMdbError,
    DWORD               dwFromMdbError,
    DWORD               dwToBEError,
    PVDIR_BACKEND_CTX   pBECtx,
    PCSTR               pszErrorContext)
{
    DWORD   dwError = 0;

    assert(pBECtx);

    if (dwMdbError != 0)
    {
        pBECtx->dwBEErrorCode = dwMdbError;
        VMDIR_SAFE_FREE_MEMORY(pBECtx->pszBEErrorMsg);
        // ignore error
        VmDirAllocateStringPrintf(    &pBECtx->pszBEErrorMsg,
                                          "(%s)(%s)",
                                          mdb_strerror(dwMdbError),
                                          VDIR_SAFE_STRING(pszErrorContext));

        if (dwMdbError == dwFromMdbError)
        {
            dwError = dwToBEError;
        }
        // check if the error is caused by one of raft callbacks
        // if yes return the same error
        else if (IS_VMDIR_ERROR_SPACE(dwMdbError))
        {
            dwError = dwMdbError;
        }
        else
        {
            dwError = ERROR_BACKEND_ERROR;
        }
    }

    return dwError;
}
Beispiel #26
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;
}
Beispiel #27
0
// Protects key from being created more than once
static
VOID
_VmDirInitThreadContextOnce(VOID)
{
    DWORD dwError = 0;
    PSTR pszLocalErrorMsg = NULL;

    dwError = pthread_key_create(&pThreadContext->threadLogContext, NULL);
    BAIL_ON_VMDIR_ERROR_WITH_MSG(dwError, (pszLocalErrorMsg), "pthread_key_create failed on threadLogContext");

    dwError = pthread_key_create(&pThreadContext->threadTxnContext, NULL);
    BAIL_ON_VMDIR_ERROR_WITH_MSG(dwError, (pszLocalErrorMsg), "pthread_key_create failed on threadTxnContext");

cleanup:
    VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg);
    return;

error:
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s: %s errcode %d", __func__, VDIR_SAFE_STRING(pszLocalErrorMsg), dwError);
    VMDIR_SAFE_FREE_MEMORY(pThreadContext);
    goto cleanup;
}
Beispiel #28
0
int
VmDirPerformBind(
    PVDIR_OPERATION   pOperation
    )
{
   BindReq *    pBindReq = &(pOperation->request.bindReq);
   int          retVal = LDAP_SUCCESS;
   ber_len_t    berLen = 0;
   ber_tag_t    berTag = 0;
   BOOLEAN      bResultAlreadySent = FALSE;

   memset( pBindReq, 0, sizeof( BindReq ));

   if (ber_scanf( pOperation->ber, "{imt", &pOperation->protocol, &(pOperation->reqDn.lberbv), &pBindReq->method ) == LBER_ERROR )
   {
      VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "PerformBind: ber_scanf failed" );

      BAIL_ON_STATIC_LDAP_ERROR( retVal, LDAP_PROTOCOL_ERROR, (pOperation->ldapResult.pszErrMsg),
                                 "Decoding error while parsing protocol version, bind DN, bind method.");
   }

   VMDIR_LOG_VERBOSE( LDAP_DEBUG_ARGS,
       "Bind Request (%s): Protocol version: %d, Bind DN: \"%s\", Method: %ld",
        pOperation->conn->szClientIP,
        pOperation->protocol,
        pOperation->reqDn.lberbv.bv_val, pBindReq->method );

   if (pOperation->protocol != LDAP_VERSION3)
   {
      VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "PerformBind: Non-ldap-v3 version." );
      BAIL_ON_STATIC_LDAP_ERROR(    retVal, LDAP_PROTOCOL_ERROR, (pOperation->ldapResult.pszErrMsg),
                                  "Currently, only LDAP V3 is supported.");
   }

   switch (pBindReq->method)
   {
       case LDAP_AUTH_SIMPLE:
               if ( ber_scanf( pOperation->ber, "m}", &(pBindReq->cred.lberbv) ) == LBER_ERROR )
               {
                   VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "PerformBind: ber_scanf failed" );
                  BAIL_ON_STATIC_LDAP_ERROR( retVal, LDAP_PROTOCOL_ERROR, (pOperation->ldapResult.pszErrMsg),
                                             "Decoding error while parsing simple credentials.");
               }

               break;

       case LDAP_AUTH_SASL:
               if ( ber_scanf( pOperation->ber, "{m" /*}*/, &(pBindReq->bvMechanism.lberbv) ) == LBER_ERROR)
               {
                   BAIL_ON_STATIC_LDAP_ERROR( retVal, LDAP_PROTOCOL_ERROR, (pOperation->ldapResult.pszErrMsg),
                                              "Decoding error while parsing sasl mechanism.");
               }

               berTag = ber_peek_tag( pOperation->ber, &berLen );
               if ( berTag == LDAP_TAG_LDAPCRED ) {
                   if ( ber_scanf( pOperation->ber, "m", &(pBindReq->cred.lberbv)) == LBER_ERROR )
                   {
                       BAIL_ON_STATIC_LDAP_ERROR( retVal, LDAP_PROTOCOL_ERROR,  (pOperation->ldapResult.pszErrMsg),
                                                  "Decoding error while parsing sasl creds.");
                   }
               }

               if ( ber_scanf( pOperation->ber, /*{{*/ "}}" ) == LBER_ERROR )
               {
                   BAIL_ON_STATIC_LDAP_ERROR( retVal, LDAP_PROTOCOL_ERROR, (pOperation->ldapResult.pszErrMsg),
                                              "Decoding error.");
               }

               break;

       default:
           BAIL_ON_STATIC_LDAP_ERROR( retVal, LDAP_UNWILLING_TO_PERFORM,  (pOperation->ldapResult.pszErrMsg),
                                      "bind method not supported.");
   }

    retVal = VmDirMLBind( pOperation );
    bResultAlreadySent = TRUE;
    if (retVal && retVal != LDAP_SASL_BIND_IN_PROGRESS)
    {
        VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL,
            "Bind Request Failed (%s) error %u: Protocol version: %d, Bind DN: \"%s\", Method: %ld",
            pOperation->conn->szClientIP,
            retVal,
            pOperation->protocol,
            VDIR_SAFE_STRING(pOperation->reqDn.lberbv.bv_val),
            pBindReq->method );
    }
    BAIL_ON_SIMPLE_LDAP_ERROR(retVal);

cleanup:

    return retVal;

ldaperror:
    pOperation->ldapResult.errCode = retVal;

    if (retVal != LDAP_NOTICE_OF_DISCONNECT && bResultAlreadySent == FALSE)
    {
        VmDirSendLdapResult( pOperation );
    }

    goto cleanup;
}
Beispiel #29
0
/* MdbModifyEntry: Updates an entry in the MDB DBs.
 *
 * Returns: BE error codes.
 *
 */
DWORD
VmDirMDBModifyEntry(
    PVDIR_BACKEND_CTX   pBECtx,
    VDIR_MODIFICATION*  pMods,
    PVDIR_ENTRY         pEntry
    )
{
    DWORD                   dwError = 0;
    VDIR_BERVALUE           newEncodedEntry = VDIR_BERVALUE_INIT;
    VDIR_MODIFICATION *     mod = NULL;
    PVDIR_DB_TXN            pTxn = NULL;

    assert( pBECtx && pBECtx->pBEPrivate && pMods && pEntry );

    pTxn = (PVDIR_DB_TXN)pBECtx->pBEPrivate;

    dwError = VmDirEncodeEntry( pEntry, &newEncodedEntry );
    BAIL_ON_VMDIR_ERROR(dwError);

    VMDIR_SAFE_FREE_MEMORY( pEntry->encodedEntry );
    // entry takes over the responsibility to free newEncodedEntry.lberbv.bv_val
    pEntry->encodedEntry = (unsigned char *)newEncodedEntry.lberbv.bv_val;

    // Create/Delete appropriate indices for indexed attributes.
    for (mod = pMods; mod != NULL; mod = mod->next)
    {
        if (mod->ignore)
        {
            continue;
        }
        switch (mod->operation)
        {
            case MOD_OP_ADD:
                if ((dwError = MdbUpdateIndicesForAttr( pTxn, &(mod->attr.type), mod->attr.vals, mod->attr.numVals,
                                                       pEntry->eId, BE_INDEX_OP_TYPE_CREATE)) != 0)
                {
                    dwError = MDBToBackendError( dwError, MDB_KEYEXIST, ERROR_BACKEND_CONSTRAINT, pBECtx,
                                                 VDIR_SAFE_STRING(mod->attr.type.lberbv.bv_val));
                    BAIL_ON_VMDIR_ERROR( dwError );
                }
                break;

            case MOD_OP_DELETE:
                if ((dwError = MdbUpdateIndicesForAttr( pTxn, &(mod->attr.type), mod->attr.vals, mod->attr.numVals,
                                                       pEntry->eId, BE_INDEX_OP_TYPE_DELETE )) != 0)
                {
                    dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx,
                                                VDIR_SAFE_STRING(mod->attr.type.lberbv.bv_val));
                    BAIL_ON_VMDIR_ERROR( dwError );
                }
                break;

            case MOD_OP_REPLACE:
            default:
                assert( FALSE );
        }
        if ((dwError = MdbUpdateAttrMetaData( pTxn, &(mod->attr), pEntry->eId, BE_INDEX_OP_TYPE_UPDATE )) != 0)
        {
            dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx,
                                        VDIR_SAFE_STRING(mod->attr.type.lberbv.bv_val));
            BAIL_ON_VMDIR_ERROR( dwError );
        }
    }

    // Update Entry DB.
    if ((dwError = MdbCreateEIDIndex(pTxn, pEntry->eId, &newEncodedEntry, FALSE /* update current eId key */)) != 0)
    {
        dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx, "CreateEIDIndex");
        BAIL_ON_VMDIR_ERROR( dwError );
    }

cleanup:

     return dwError;

error:

    VMDIR_SET_BACKEND_ERROR(dwError);   // if dwError no in BE space, set to ERROR_BACKEND_ERROR

    VMDIR_LOG_ERROR(LDAP_DEBUG_BACKEND,
             "ModifyEntry failed: error=%d,DN=%s", dwError, VDIR_SAFE_STRING(pEntry->dn.lberbv.bv_val));

     goto cleanup;
}
Beispiel #30
0
/* MdbAddEntry: Creates an entry in the MDB DBs.
 *
 * Returns: BE error codes.
 *
 */
DWORD
VmDirMDBAddEntry(
    PVDIR_BACKEND_CTX   pBECtx,
    PVDIR_ENTRY         pEntry)
{
    DWORD             dwError = 0;
    ENTRYID           entryId = 0;
    VDIR_DB_TXN*      pTxn = NULL;
    VDIR_BERVALUE     encodedEntry = VDIR_BERVALUE_INIT;
    VDIR_ATTRIBUTE *  nextAttr = NULL;

    assert( pEntry && pBECtx && pBECtx->pBEPrivate );

    pTxn = (PVDIR_DB_TXN)pBECtx->pBEPrivate;

    dwError = VmDirEncodeEntry( pEntry, &encodedEntry );
    BAIL_ON_VMDIR_ERROR(dwError);

    if (pEntry->eId != 0)    // Reserved entries have eId already
    {
        entryId = pEntry->eId;
    }
    else
    {
        VDIR_DB_DBT     EIDkey = {0};
        VDIR_DB_DBT     EIDvalue  = {0};
        unsigned char   EIDKeyBytes[sizeof( ENTRYID )] = {0};
        unsigned char   EIDValueBytes[sizeof( ENTRYID )] = {0};

        EIDkey.mv_data = &EIDKeyBytes[0];
        MDBEntryIdToDBT(BE_MDB_ENTRYID_SEQ_KEY, &EIDkey);

        dwError =  mdb_get(pTxn, gVdirMdbGlobals.mdbSeqDBi, &EIDkey, &EIDvalue);
        BAIL_ON_VMDIR_ERROR(dwError);

        assert( EIDvalue.mv_size == sizeof(ENTRYID) );
        entryId = *((ENTRYID*)EIDvalue.mv_data);

        *((ENTRYID*)&EIDValueBytes[0]) = entryId + 1;
        EIDvalue.mv_data = &EIDValueBytes[0];
        EIDvalue.mv_size = sizeof(ENTRYID);

        dwError =  mdb_put(pTxn, gVdirMdbGlobals.mdbSeqDBi, &EIDkey, &EIDvalue, BE_DB_FLAGS_ZERO);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    assert( entryId > 0 );

    if ((dwError = MDBCreateParentIdIndex(pBECtx, &(pEntry->pdn), entryId)) != 0)
    {
        dwError = MDBToBackendError(dwError, ERROR_BACKEND_ENTRY_NOTFOUND,
                                    ERROR_BACKEND_PARENT_NOTFOUND, pBECtx, "CreateParentIdIndex");
        BAIL_ON_VMDIR_ERROR( dwError );
    }

    // Update DN index first. this make sure we always return ERROR_BACKEND_ENTRY_EXISTS in such case.
    for (nextAttr = pEntry->attrs; nextAttr != NULL; nextAttr = nextAttr->next)
    {
        if (VmDirStringCompareA(nextAttr->type.lberbv.bv_val, ATTR_DN, FALSE) == 0)
        {
            // make sure we store normalized DN value.
            dwError = VmDirNormalizeDN( &(nextAttr->vals[0]), pEntry->pSchemaCtx );
            BAIL_ON_VMDIR_ERROR(dwError);

            if ((dwError = MdbUpdateIndicesForAttr( pTxn, &(nextAttr->type), nextAttr->vals, nextAttr->numVals,
                                                    entryId, BE_INDEX_OP_TYPE_CREATE)) != 0)
            {
                dwError = MDBToBackendError( dwError,
                                             MDB_KEYEXIST,
                                             ERROR_BACKEND_ENTRY_EXISTS,
                                             pBECtx,
                                             VDIR_SAFE_STRING(nextAttr->vals[0].bvnorm_val));
                BAIL_ON_VMDIR_ERROR( dwError );
            }
            if ((dwError = MdbUpdateAttrMetaData( pTxn, nextAttr, entryId, BE_INDEX_OP_TYPE_CREATE )) != 0)
            {
                dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx, "UpdateDNAttrMetaData");
                BAIL_ON_VMDIR_ERROR( dwError );
            }
        }
    }

    // Update remaining indices
    for (nextAttr = pEntry->attrs; nextAttr != NULL; nextAttr = nextAttr->next)
    {
        if (VmDirStringCompareA(nextAttr->type.lberbv.bv_val, ATTR_DN, FALSE) != 0)
        {
            if ((dwError = MdbUpdateIndicesForAttr( pTxn, &(nextAttr->type), nextAttr->vals, nextAttr->numVals,
                                                    entryId, BE_INDEX_OP_TYPE_CREATE)) != 0)
            {
                dwError = MDBToBackendError( dwError,
                                             MDB_KEYEXIST,
                                             ERROR_BACKEND_CONSTRAINT,
                                             pBECtx,
                                             VDIR_SAFE_STRING(nextAttr->type.lberbv.bv_val));
                BAIL_ON_VMDIR_ERROR( dwError );
            }
            if ((dwError = MdbUpdateAttrMetaData( pTxn, nextAttr, entryId, BE_INDEX_OP_TYPE_CREATE )) != 0)
            {
                dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx,
                                            VDIR_SAFE_STRING(nextAttr->type.lberbv.bv_val));
                BAIL_ON_VMDIR_ERROR( dwError );
            }
        }
    }

    // Update entry/blob database
    if ((dwError = MdbCreateEIDIndex(pTxn, entryId, &encodedEntry, TRUE /* 1st time new entry creation */)) != 0)
    {
        dwError = MDBToBackendError(dwError, MDB_KEYEXIST, ERROR_BACKEND_CONSTRAINT, pBECtx, "CreateEIDIndex");
        BAIL_ON_VMDIR_ERROR( dwError );
    }

cleanup:

    VMDIR_SAFE_FREE_MEMORY( encodedEntry.lberbv.bv_val );

    return dwError;

error:
    // TODO set pBECtx->pszBEErrorMsg?
    VMDIR_LOG_ERROR( LDAP_DEBUG_BACKEND, "BEAddEntry DN (%s),  (%u)(%s)", VDIR_SAFE_STRING(pEntry->dn.lberbv.bv_val),
                              dwError, VDIR_SAFE_STRING(pBECtx->pszBEErrorMsg));

    VMDIR_SET_BACKEND_ERROR(dwError);   // if dwError no in BE space, set to ERROR_BACKEND_ERROR

    goto cleanup;
}