static VOID SetSpecialReturnChar( SearchReq* pSearchReq, uint32_t* pSearchReqSpecialChars ) { int iCnt = 0; assert(pSearchReq && pSearchReqSpecialChars); *pSearchReqSpecialChars = 0; if (pSearchReq->attrs == NULL) { // if no attribute requested, default to return user attributes *pSearchReqSpecialChars |= LDAP_SEARCH_REQUEST_CHAR_USER; } // see if "*" and/or "+" as part of the request attribute list. for (iCnt = 0; pSearchReq->attrs && pSearchReq->attrs[iCnt].lberbv.bv_val != NULL; iCnt++) { if (VmDirStringCompareA( pSearchReq->attrs[iCnt].lberbv.bv_val, "*", FALSE) == 0) { *pSearchReqSpecialChars |= LDAP_SEARCH_REQUEST_CHAR_USER; } else if (VmDirStringCompareA( pSearchReq->attrs[iCnt].lberbv.bv_val, "+", FALSE) == 0) { *pSearchReqSpecialChars |= LDAP_SEARCH_REQUEST_CHAR_OP; } else if (VmDirStringCompareA( pSearchReq->attrs[iCnt].lberbv.bv_val, "-", FALSE) == 0) { *pSearchReqSpecialChars |= LDAP_SEARCH_REQUEST_CHAR_PASSWD; } } }
/* * Numeric ordering attribute has matching rule integerMatch or integerOrderingMatch */ BOOLEAN VmDirSchemaAttrHasIntegerMatchingRule( PVDIR_SCHEMA_CTX pCtx, PCSTR pszName ) { DWORD dwError = 0; BOOLEAN bIsNumericOrdering = FALSE; PVDIR_SCHEMA_AT_DESC pATDesc = NULL; if (pCtx && pszName) { pATDesc = VmDirSchemaAttrNameToDesc(pCtx,pszName); if (!pATDesc) { dwError = ERROR_NO_SUCH_ATTRIBUTE; BAIL_ON_VMDIR_ERROR(dwError); } if ((pATDesc->pszEqualityMRName && VmDirStringCompareA(pATDesc->pszEqualityMRName, VDIR_MATCHING_RULE_INTEGER_MATCH, FALSE) == 0) || (pATDesc->pszOrderingMRName && VmDirStringCompareA(pATDesc->pszOrderingMRName, VDIR_MATCHING_RULE_INTEGER_ORDERING_MATCH, FALSE) == 0) ) { bIsNumericOrdering = TRUE; } } error: return bIsNumericOrdering; }
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; }
static int schemaInitPPSTRCmp( const void *ppStr1, const void *ppStr2 ) { if ((ppStr1 == NULL || *(char * const *)ppStr1 == NULL) && (ppStr2 == NULL || *(char * const *)ppStr2 == NULL)) { return 0; } if (ppStr1 == NULL || *(char * const *)ppStr1 == NULL) { return -1; } if (ppStr2 == NULL || *(char * const *)ppStr2 == NULL) { return 1; } return VmDirStringCompareA(* (char * const *) ppStr1, * (char * const *) ppStr2, TRUE); }
DWORD VmDirPrepareSwapDBInfo( PCSTR pszHostName, // partner server object cn PVMDIR_SWAP_DB_INFO* ppSwapDBInfo ) { DWORD dwError = 0; PVMDIR_SWAP_DB_INFO pLocalSwapDBInfo = NULL; if (!ppSwapDBInfo) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } dwError = VmDirAllocateMemory(sizeof(VMDIR_SWAP_DB_INFO), (PVOID*)&pLocalSwapDBInfo); BAIL_ON_VMDIR_ERROR(dwError); if (pszHostName) { dwError = VmDirAllocateStringA(pszHostName, &pLocalSwapDBInfo->pszPartnerServerName); BAIL_ON_VMDIR_ERROR(dwError); VMDIR_LOG_INFO(VMDIR_LOG_MASK_ALL, "My partner %s", pLocalSwapDBInfo->pszPartnerServerName); } dwError = VmDirInternalGetDSERootServerCN(&pLocalSwapDBInfo->pszOrgDBServerName); BAIL_ON_VMDIR_ERROR(dwError); VMDIR_LOG_INFO(VMDIR_LOG_MASK_ALL, "DB was from %s", pLocalSwapDBInfo->pszOrgDBServerName); dwError = _VmDirComposeUtdVector(pLocalSwapDBInfo); BAIL_ON_VMDIR_ERROR(dwError); if (!pLocalSwapDBInfo->pszPartnerServerName || // no partner, DR case VmDirStringCompareA( // DB copied from joining partner pLocalSwapDBInfo->pszPartnerServerName, pLocalSwapDBInfo->pszOrgDBServerName, FALSE) == 0) { dwError = VmDirAllocateStringA(pLocalSwapDBInfo->pszOrgDBMaxUSN, &pLocalSwapDBInfo->pszMyHighWaterMark); BAIL_ON_VMDIR_ERROR(dwError); } else { // DB from one node but join to another dwError = _VmDirComposeHighWaterMark(pLocalSwapDBInfo); BAIL_ON_VMDIR_ERROR(dwError); } VMDIR_LOG_INFO(VMDIR_LOG_MASK_ALL, "My High Water Mark %s", pLocalSwapDBInfo->pszMyHighWaterMark); *ppSwapDBInfo = pLocalSwapDBInfo; cleanup: return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, " error (%u)", dwError); VmDirFreeSwapDBInfo(pLocalSwapDBInfo); goto cleanup; }
static int matchingrulePSyntaxOidCmp( const void *p1, const void *p2 ) { PVDIR_MATCHING_RULE_DESC pDesc1 = (PVDIR_MATCHING_RULE_DESC) p1; PVDIR_MATCHING_RULE_DESC pDesc2 = (PVDIR_MATCHING_RULE_DESC) p2; if ((pDesc1 == NULL || pDesc1->pszSyntaxOid == NULL) && (pDesc2 == NULL || pDesc2->pszSyntaxOid == NULL)) { return 0; } if (pDesc1 == NULL || pDesc1->pszSyntaxOid == NULL) { return -1; } if (pDesc2 == NULL || pDesc2->pszSyntaxOid == NULL) { return 1; } return VmDirStringCompareA(pDesc1->pszSyntaxOid, pDesc2->pszSyntaxOid, TRUE); }
static int GenerateNewParent( PVDIR_ENTRY pEntry, PVDIR_ATTRIBUTE pDnAttr ) { int retVal = 0; VDIR_BERVALUE NewParent = VDIR_BERVALUE_INIT; if (!pEntry->pdn.bvnorm_val) { VmDirFreeBervalContent(&pEntry->pdn); retVal = VmDirGetParentDN(&pEntry->dn, &pEntry->pdn); BAIL_ON_VMDIR_ERROR(retVal); } retVal = VmDirGetParentDN(&pDnAttr->vals[0], &NewParent); BAIL_ON_VMDIR_ERROR(retVal); if (VmDirStringCompareA(pEntry->pdn.bvnorm_val, NewParent.bvnorm_val, FALSE) != 0) { retVal = VmDirBervalContentDup(&NewParent, &pEntry->newpdn); BAIL_ON_VMDIR_ERROR(retVal); } cleanup: VmDirFreeBervalContent(&NewParent); return retVal; error: goto cleanup; }
DWORD VmDirSchemaGetComputedAttribute( PCSTR pszComputedAttrName, PVDIR_ENTRY pEntry, PVDIR_ATTRIBUTE* ppOutAttr ) { DWORD dwError = 0; if ( !pszComputedAttrName || !pEntry || !ppOutAttr ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } if ( VmDirStringCompareA( pszComputedAttrName, ATTR_ALLOWD_CHILD_CLASSES_EFFECTIVE, FALSE ) == 0 ) { dwError = _VmDirSchemaComputeAllowedChildClassesEffective( pEntry, ppOutAttr ); BAIL_ON_VMDIR_ERROR(dwError); } cleanup: return dwError; error: goto cleanup; }
BOOLEAN VmDirEntryIsObjectclass( PVDIR_ENTRY pEntry, PCSTR pszOCName ) { BOOLEAN bResult = FALSE; unsigned int iCnt = 0; if (pEntry && pszOCName) { PVDIR_ATTRIBUTE pAttrOC = VmDirFindAttrByName(pEntry, ATTR_OBJECT_CLASS); for (iCnt = 0; (pAttrOC != NULL) && (iCnt < pAttrOC->numVals); iCnt++) { if (VmDirStringCompareA( pAttrOC->vals[iCnt].lberbv.bv_val, pszOCName, FALSE) == 0) { bResult = TRUE; break; } } } return bResult; }
static BOOLEAN _VmDirIsNameInCaseIgnoreList( PCSTR pszName, PCSTR* ppszList, size_t iSize ) { BOOLEAN bRtn = FALSE; size_t iCnt = 0; if ( pszName && ppszList ) { for (iCnt=0; iCnt < iSize; iCnt++) { if (VmDirStringCompareA( pszName, ppszList[iCnt], FALSE) == 0) { bRtn = TRUE; break; } } } return bRtn; }
BOOLEAN VmDirSchemaIsNameEntryLeafStructureOC( PVDIR_ENTRY pEntry, PCSTR pszName ) { DWORD dwError = 0; BOOLEAN bRet = FALSE; PVDIR_SCHEMA_OC_DESC pOCDesc = NULL; if ( !pEntry || !pszName ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirSchemaGetEntryStructureOCDesc( pEntry, &pOCDesc ); BAIL_ON_VMDIR_ERROR(dwError); if ( pOCDesc && VmDirStringCompareA( pszName, pOCDesc->pszName, FALSE ) == 0 ) { bRet = TRUE; } cleanup: return bRet; error: goto cleanup; }
/* * Sort function - * Array of VDIR_CFG_ATTR_INDEX_DESC * String compare VDIR_CFG_ATTR_INDEX_DESC.pszAttrName */ int VdirAttrIndexNameCmp( const void *p1, const void *p2 ) { PVDIR_CFG_ATTR_INDEX_DESC pDesc1 = (PVDIR_CFG_ATTR_INDEX_DESC) p1; PVDIR_CFG_ATTR_INDEX_DESC pDesc2 = (PVDIR_CFG_ATTR_INDEX_DESC) p2; if ((pDesc1 == NULL || pDesc1->pszAttrName == NULL) && (pDesc2 == NULL || pDesc2->pszAttrName == NULL)) { return 0; } if (pDesc1 == NULL || pDesc1->pszAttrName == NULL) { return -1; } if (pDesc2 == NULL || pDesc2->pszAttrName == NULL) { return 1; } return VmDirStringCompareA(pDesc1->pszAttrName, pDesc2->pszAttrName, FALSE); }
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; }
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; }
DWORD VmDirAdministratorAccessCheck( PCSTR pszUpn, PCSTR pszDomainDn ) { DWORD dwError = 0; const CHAR szAdministrators[] = "cn=Administrators,cn=Builtin"; PSTR pszAdministratorsDn = NULL; PSTR *ppszMemberships = NULL; DWORD dwMemberships = 0; PSTR pszSystemDomainDn = NULL; if (IsNullOrEmptyString(pszUpn) || IsNullOrEmptyString(pszDomainDn)) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } VMDIR_GET_SYSTEM_DOMAIN_DN(pszSystemDomainDn, dwError); dwError = VmDirGetUPNMemberships(pszUpn, &ppszMemberships, &dwMemberships); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateStringPrintf(&pszAdministratorsDn, "%s,%s", szAdministrators, pszDomainDn); BAIL_ON_VMDIR_ERROR(dwError); if (VmDirStringCompareA(pszSystemDomainDn, pszDomainDn, FALSE) == 0) { if (!VmDirIsMemberOf(ppszMemberships, dwMemberships, gVmdirServerGlobals.bvDCGroupDN.lberbv.bv_val) && !VmDirIsMemberOf(ppszMemberships, dwMemberships, pszAdministratorsDn)) { dwError = ERROR_ACCESS_DENIED; BAIL_ON_VMDIR_ERROR(dwError); } } else { if (!VmDirIsMemberOf(ppszMemberships, dwMemberships, pszAdministratorsDn)) { dwError = ERROR_ACCESS_DENIED; BAIL_ON_VMDIR_ERROR(dwError); } } cleanup: VMDIR_SAFE_FREE_MEMORY(pszAdministratorsDn); VmDirFreeMemberships(ppszMemberships, dwMemberships); return dwError; error: VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "VmDirAdministratorAccessCheck failed (%u)", dwError); goto cleanup; }
/* * 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; }
static int GenerateDeleteAttrsMods( PVDIR_OPERATION pOperation, VDIR_ENTRY * pEntry ) { int retVal = 0; VDIR_MODIFICATION * delMod = NULL; VDIR_ATTRIBUTE * attr = NULL; PVDIR_ATTRIBUTE objectGuidAttr = NULL; VDIR_BERVALUE deletedObjDN = VDIR_BERVALUE_INIT; ModifyReq * modReq = &(pOperation->request.modifyReq); for ( attr = pEntry->attrs; attr != NULL; attr = attr->next ) { // Retain the following kind of attributes if (attr->pATDesc->usage != VDIR_ATTRIBUTETYPE_USER_APPLICATIONS || VmDirStringCompareA( attr->type.lberbv.bv_val, ATTR_OBJECT_CLASS, FALSE ) == 0) { continue; } retVal = VmDirAllocateMemory( sizeof( VDIR_MODIFICATION ), (PVOID *)&(delMod) ); BAIL_ON_VMDIR_ERROR( retVal ); delMod->operation = MOD_OP_DELETE; delMod->attr.next = NULL; delMod->attr.type = attr->type; delMod->attr.pATDesc = attr->pATDesc; delMod->attr.vals = NULL; delMod->attr.numVals = 0; delMod->next = modReq->mods; modReq->mods = delMod; modReq->numMods++; } // Add mod to set new DN. objectGuidAttr = VmDirEntryFindAttribute(ATTR_OBJECT_GUID, pEntry); assert( objectGuidAttr ); retVal = constructDeletedObjDN( &pOperation->request.deleteReq.dn, objectGuidAttr->vals[0].lberbv.bv_val, &deletedObjDN ); BAIL_ON_VMDIR_ERROR( retVal ); retVal = VmDirAppendAMod( pOperation, MOD_OP_REPLACE, ATTR_DN, ATTR_DN_LEN, deletedObjDN.lberbv.bv_val, deletedObjDN.lberbv.bv_len ); BAIL_ON_VMDIR_ERROR( retVal ); cleanup: VmDirFreeMemory( deletedObjDN.lberbv.bv_val ); return retVal; error: goto cleanup; }
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; }
/* 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; }
/* * 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; }
int GenerateDeleteAttrsMods( PVDIR_OPERATION pOperation, VDIR_ENTRY * pEntry ) { int retVal = 0; VDIR_MODIFICATION * delMod = NULL; VDIR_ATTRIBUTE * attr = NULL; ModifyReq * modReq = &(pOperation->request.modifyReq); for (attr = pEntry->attrs; attr != NULL; attr = attr->next) { if (VmDirStringCompareA(attr->type.lberbv.bv_val, ATTR_DN, FALSE) == 0) { continue; } retVal = VmDirAllocateMemory( sizeof(VDIR_MODIFICATION), (PVOID*)&delMod); BAIL_ON_VMDIR_ERROR(retVal); delMod->operation = MOD_OP_DELETE; delMod->attr.next = NULL; delMod->attr.type = attr->type; delMod->attr.pATDesc = attr->pATDesc; delMod->attr.vals = NULL; delMod->attr.numVals = 0; delMod->next = modReq->mods; modReq->mods = delMod; modReq->numMods++; } retVal = VmDirAppendAMod( pOperation, MOD_OP_DELETE, ATTR_DN, ATTR_DN_LEN, pOperation->request.deleteReq.dn.lberbv.bv_val, pOperation->request.deleteReq.dn.lberbv.bv_len); BAIL_ON_VMDIR_ERROR(retVal); cleanup: return retVal; error: goto cleanup; }
/* * Remove an attribute of an entry. * Only handle ENTRY_STORAGE_FORMAT_NORMAL. */ DWORD VmDirEntryRemoveAttribute( PVDIR_ENTRY pEntry, PCSTR pszName ) { DWORD dwError = 0; PVDIR_ATTRIBUTE pAttr = NULL; PVDIR_ATTRIBUTE pPrevAttr = NULL; if (!pEntry || !pszName || pEntry->allocType != ENTRY_STORAGE_FORMAT_NORMAL) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } for (pAttr = pEntry->attrs; pAttr; pAttr = pAttr->next) { if (VmDirStringCompareA(pAttr->pATDesc->pszName, pszName, FALSE) == 0) { break; } pPrevAttr = pAttr; } if (pAttr) { if (pPrevAttr) { pPrevAttr->next = pAttr->next; } else { assert(pAttr == pEntry->attrs); pEntry->attrs = pAttr->next; } VmDirFreeAttribute(pAttr); } cleanup: return dwError; error: goto cleanup; }
DWORD VmDirEntryAttributeRemoveValue( PVDIR_ATTRIBUTE pAttr, PCSTR pszValue ) { DWORD dwError = 0; DWORD dwCnt = 0; DWORD dwBervSize = 0; PVDIR_BERVALUE pNewBerv = NULL; if (!pAttr || !pszValue) { BAIL_WITH_VMDIR_ERROR(dwError, ERROR_INVALID_PARAMETER); } //Actual size of pAttr->vals size is pAttr->numVals+1 dwError = VmDirAllocateMemory(sizeof(VDIR_BERVALUE) * (pAttr->numVals), (PVOID*)&pNewBerv); BAIL_ON_VMDIR_ERROR(dwError); for (dwCnt = 0; dwCnt < pAttr->numVals; dwCnt++) { if (VmDirStringCompareA(pszValue, pAttr->vals[dwCnt].lberbv_val, FALSE) != 0) { pNewBerv[dwBervSize] = pAttr->vals[dwCnt]; memset(pAttr->vals + dwCnt, 0, sizeof(VDIR_BERVALUE)); dwBervSize++; } } VmDirFreeBervalArrayContent(pAttr->vals, pAttr->numVals); VMDIR_SAFE_FREE_MEMORY(pAttr->vals); pAttr->vals = pNewBerv; pAttr->numVals = dwBervSize; pNewBerv = NULL; cleanup: return dwError; error: VmDirFreeBervalArrayContent(pNewBerv, dwBervSize); VMDIR_SAFE_FREE_MEMORY(pNewBerv); VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError); goto cleanup; }
static BOOLEAN _VmDirIsBenignReplConflict( PVDIR_ENTRY pEntry, PVDIR_ATTRIBUTE pAttr ) { int i = 0; CHAR excludeAttrs[] = {ATTR_USN_CHANGED}; DWORD dwError = 0; BOOLEAN bIsBenign = FALSE; VDIR_ENTRY consumerEntry = {0}; if (pEntry->eId) { if (!consumerEntry.dn.lberbv_val) { PVDIR_BACKEND_INTERFACE pBE = NULL; pBE = VmDirBackendSelect(NULL); assert(pBE); dwError = pBE->pfnBESimpleIdToEntry(pEntry->eId, &consumerEntry); BAIL_ON_VMDIR_ERROR(dwError); } for (i=0; i< VMDIR_ARRAY_SIZE(excludeAttrs); i++) { if (VmDirStringCompareA(pAttr->type.lberbv_val, &excludeAttrs[i], FALSE) == 0) { bIsBenign = TRUE; goto cleanup; } } bIsBenign = VmDirIsSameConsumerSupplierEntryAttr(pAttr, pEntry, &consumerEntry); } cleanup: VmDirFreeEntryContent(&consumerEntry); return bIsBenign; error: VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError); goto cleanup; }
BOOLEAN VmDirIsSupportedSASLMechanism( PCSTR pszMech ) { static PCSTR supportedSASLMech[] = SUPPORTED_SASL_BIND_MECHANISM; int iCnt = 0; for (iCnt = 0; supportedSASLMech[iCnt] != NULL; iCnt++) { if (VmDirStringCompareA(pszMech, supportedSASLMech[iCnt], FALSE) == 0) { return TRUE; } } return FALSE; }
int ParseAndFreeSyncStateControl( LDAPControl ***pCtrls, int *piEntryState ) { int retVal = LDAP_SUCCESS; int entryState = -1; if (pCtrls == NULL) { VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "ParseAndFreeSyncStateControl: pCtrls is NULL" ); retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_SIMPLE_LDAP_ERROR(retVal); } if ((*pCtrls)[0] == NULL) { VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "ParseAndFreeSyncStateControl: (*pCtrls)[0] is NULL" ); retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_SIMPLE_LDAP_ERROR(retVal); } if (VmDirStringCompareA((*pCtrls)[0]->ldctl_oid, LDAP_CONTROL_SYNC_STATE, TRUE) != 0) { VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "ParseAndFreeSyncStateControl: (*pCtrls)[0]->ldctrl_oid is not expected: %s", VDIR_SAFE_STRING((*pCtrls)[0]->ldctl_oid)); retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_SIMPLE_LDAP_ERROR(retVal); } retVal = ParseSyncStateControlVal(&(*pCtrls)[0]->ldctl_value, &entryState); BAIL_ON_SIMPLE_LDAP_ERROR(retVal); ldap_controls_free(*pCtrls); *pCtrls = NULL; *piEntryState = entryState; cleanup: return retVal; ldaperror: goto cleanup; }
PVDIR_ATTRIBUTE VmDirFindAttrByName( PVDIR_ENTRY pEntry, PSTR pszName) { PVDIR_ATTRIBUTE pAttr = NULL; assert (pEntry && pszName); for (pAttr = pEntry->attrs; pAttr; pAttr = pAttr->next) { if (0 == VmDirStringCompareA(pAttr->type.lberbv.bv_val, pszName, FALSE)) { break; } } return pAttr; }
/* * replace attribute in pEntry if such attribute exists. * pEntry takes over ownership of pNewAttr if success. */ DWORD VmDirEntryReplaceAttribute( PVDIR_ENTRY pEntry, PVDIR_ATTRIBUTE pNewAttr) { DWORD dwError = 0; BOOLEAN bFound = FALSE; PVDIR_ATTRIBUTE pAttr = NULL; PVDIR_ATTRIBUTE pPriorAttr = NULL; assert ( pEntry && pEntry->allocType == ENTRY_STORAGE_FORMAT_NORMAL && pNewAttr); for ( pAttr = pEntry->attrs; pAttr; pPriorAttr = pAttr, pAttr = pAttr->next ) { if (0 == VmDirStringCompareA(pAttr->type.lberbv.bv_val, pNewAttr->type.lberbv.bv_val, FALSE)) { if ( pEntry->attrs == pAttr ) { pEntry->attrs = pNewAttr; } else { pPriorAttr->next = pNewAttr; } pNewAttr->next = pAttr->next; VmDirFreeAttribute(pAttr); bFound = TRUE; break; } } if ( bFound == FALSE ) { dwError = VMDIR_ERROR_NO_SUCH_ATTRIBUTE; } return dwError; }
PVDIR_ATTRIBUTE VmDirEntryFindAttribute( PSTR pszName, PVDIR_ENTRY pEntry ) { PVDIR_ATTRIBUTE pAttr = NULL; assert( pszName && pEntry && pEntry->pSchemaCtx); for (pAttr = pEntry->attrs; pAttr; pAttr = pAttr->next) { if (VmDirStringCompareA(pszName, pAttr->type.lberbv.bv_val, FALSE) == 0) { return pAttr; } } return NULL; }
static VOID ComputeRequiredAccess( SearchReq* pSearchReq ) { DWORD i = 0, j = 0; BOOLEAN bSDAttr = FALSE; PSTR pszAttr = NULL; PCSTR pszSDAttrs[] = { ATTR_OBJECT_SECURITY_DESCRIPTOR, ATTR_ACL_STRING }; pSearchReq->accessRequired = VMDIR_RIGHT_DS_READ_PROP; for (i = 0; pSearchReq->attrs && pSearchReq->attrs[i].lberbv.bv_val; i++) { bSDAttr = FALSE; pszAttr = pSearchReq->attrs[i].lberbv.bv_val; for (j = 0; j < VMDIR_ARRAY_SIZE(pszSDAttrs); j++) { if (VmDirStringCompareA(pszAttr, pszSDAttrs[j], FALSE) == 0) { bSDAttr = TRUE; break; } } if (bSDAttr) { // SD attributes require only READ_CONTROL pSearchReq->accessRequired = VMDIR_ENTRY_READ_ACL; } else { // any other attributes require READ_PROP pSearchReq->accessRequired = VMDIR_RIGHT_DS_READ_PROP; break; // no need to continue } } }