/* * pEntry is created from a difference instance of schema. * Path it to use new instance it now associates with. * 1. inpalce menory of pAttr->type * 2. pEntry->pSchemaCtx */ static DWORD _VmDirSchemaInitFixBootstrapEntry( PVDIR_SCHEMA_INSTANCE pSchema, PVDIR_ENTRY pEntry ) { DWORD dwError = 0; VDIR_ATTRIBUTE* pAttr = NULL; PVDIR_SCHEMA_CTX pNewCtx = NULL; dwError = VmDirAllocateMemory( sizeof(*pNewCtx), (PVOID)&pNewCtx ); BAIL_ON_VMDIR_ERROR(dwError); // create the very first ctx for pSchema pNewCtx->pSchema = pSchema; pNewCtx->pSchema->usRefCount++; // switch pEntry to use the new schema instance it creates. VmDirSchemaCtxRelease(pEntry->pSchemaCtx); pEntry->pSchemaCtx = pNewCtx; pNewCtx = NULL; for (pAttr = pEntry->attrs; pAttr; pAttr = pAttr->next) { USHORT usId = pAttr->pATDesc->usAttrID; PVDIR_SCHEMA_AT_DESC pResult = pSchema->ats.ppATSortIdMap[usId - 1]; if (!pResult) { // this should never happen as attribute ID never change once it is assigned. dwError = ERROR_INVALID_SCHEMA; BAIL_ON_VMDIR_ERROR(dwError); } // patch Attribute.pATDesc pAttr->pATDesc = pResult; // patch Attribute.type in-place storage as well pAttr->type.lberbv.bv_val = pResult->pszName; pAttr->type.lberbv.bv_len = VmDirStringLenA(pAttr->type.lberbv.bv_val); } cleanup: return dwError; error: if ( pNewCtx ) { VmDirSchemaCtxRelease( pNewCtx ); } goto cleanup; }
DWORD VmDirMDBSimpleDnToEntry( PSTR pszEntryDN, PVDIR_ENTRY pEntry ) { DWORD dwError = 0; PVDIR_SCHEMA_CTX pSchemaCtx = NULL; VDIR_BERVALUE entryDn = VDIR_BERVALUE_INIT; VDIR_BACKEND_CTX mdbBECtx = {0}; BOOLEAN bHasTxn = FALSE; assert(pEntry); dwError = VmDirSchemaCtxAcquire(&pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); entryDn.lberbv.bv_val = pszEntryDN; entryDn.lberbv.bv_len = VmDirStringLenA(entryDn.lberbv.bv_val); dwError = VmDirMDBTxnBegin(&mdbBECtx, VDIR_BACKEND_TXN_READ); BAIL_ON_VMDIR_ERROR(dwError); bHasTxn = TRUE; dwError = VmDirMDBDNToEntry( &mdbBECtx, pSchemaCtx, &entryDn, pEntry, VDIR_BACKEND_ENTRY_LOCK_READ); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirMDBTxnCommit(&mdbBECtx); bHasTxn = FALSE; BAIL_ON_VMDIR_ERROR(dwError); cleanup: if (pSchemaCtx) { VmDirSchemaCtxRelease(pSchemaCtx); } mdbBECtx.pBEPrivate = NULL; VmDirBackendCtxContentFree(&mdbBECtx); VmDirFreeBervalContent(&entryDn); return dwError; error: if (bHasTxn) { VmDirMDBTxnAbort(&mdbBECtx); } goto cleanup; }
DWORD VmDirMDBSimpleEIdToEntry( PVDIR_BACKEND_INTERFACE pBE, ENTRYID eId, PVDIR_ENTRY pEntry) { DWORD dwError = 0; PVDIR_SCHEMA_CTX pSchemaCtx = NULL; VDIR_BACKEND_CTX mdbBECtx = {0}; BOOLEAN bHasTxn = FALSE; assert(pBE && pEntry); dwError = VmDirSchemaCtxAcquire(&pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); mdbBECtx.pBE = pBE; dwError = VmDirMDBTxnBegin(&mdbBECtx, VDIR_BACKEND_TXN_READ, &bHasTxn); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirMDBEIdToEntry( &mdbBECtx, pSchemaCtx, eId, pEntry, VDIR_BACKEND_ENTRY_LOCK_READ); BAIL_ON_VMDIR_ERROR(dwError); if (bHasTxn) { dwError = VmDirMDBTxnCommit(&mdbBECtx); bHasTxn = FALSE; BAIL_ON_VMDIR_ERROR(dwError); } cleanup: if (pSchemaCtx) { VmDirSchemaCtxRelease(pSchemaCtx); } VmDirBackendCtxContentFree(&mdbBECtx); return dwError; error: if (bHasTxn) { VmDirMDBTxnAbort(&mdbBECtx); } goto cleanup; }
/* * Commit schema modification into cache. * * 1. commit pending cache to go live * 2. create self reference ctx * 3. release old self reference ctx * 4. update pEntry to have new live schema ctx association */ VOID VmDirSchemaCacheModifyCommit( PVDIR_ENTRY pSchemaEntry ) { DWORD dwError = 0; BOOLEAN bInLock = FALSE; PVDIR_SCHEMA_CTX pOldCtx = NULL; if ( !pSchemaEntry || !pSchemaEntry->pSchemaCtx ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } VMDIR_LOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex); if ( ! gVdirSchemaGlobals.bHasPendingChange ) { VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Schema cache update pass through" ); goto cleanup; // no schema definition change, just pass through. } gVdirSchemaGlobals.bHasPendingChange = FALSE; gVdirSchemaGlobals.pSchema = pSchemaEntry->pSchemaCtx->pSchema; pOldCtx = gVdirSchemaGlobals.pCtx; gVdirSchemaGlobals.pCtx = NULL; VdirSchemaCtxAcquireInLock(TRUE, &gVdirSchemaGlobals.pCtx); // add global instance self reference assert(gVdirSchemaGlobals.pCtx); VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Enable schema instance (%p)", gVdirSchemaGlobals.pSchema); VMDIR_UNLOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex); cleanup: VMDIR_UNLOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex); if (pOldCtx) { VmDirSchemaCtxRelease(pOldCtx); } return; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "VmDirSchemaCacheModifyCommit failed (%d)", dwError); goto cleanup; }
DWORD VmDirLoadIndex( BOOLEAN bFirstboot ) { DWORD dwError = 0; DWORD i = 0; PVDIR_SCHEMA_CTX pSchemaCtx = NULL; PVDIR_SCHEMA_AT_DESC* ppATDescList = NULL; PVDIR_INDEX_CFG pIndexCfg = NULL; if (bFirstboot) { // Firstboot should use only the default indices // Nothing to load goto cleanup; } dwError = VmDirSchemaCtxAcquire(&pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSchemaAttrList(pSchemaCtx, &ppATDescList); BAIL_ON_VMDIR_ERROR(dwError); // Identify non-default indices by their searchFlags and open them for (i = 0; ppATDescList[i]; i++) { if ((ppATDescList[i]->dwSearchFlags & 1) && !VmDirIndexIsDefault(ppATDescList[i]->pszName)) { dwError = VmDirCustomIndexCfgInit(ppATDescList[i], &pIndexCfg); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirIndexOpen(pIndexCfg); BAIL_ON_VMDIR_ERROR(dwError); pIndexCfg = NULL; } } cleanup: VMDIR_SAFE_FREE_MEMORY(ppATDescList); VmDirSchemaCtxRelease(pSchemaCtx); return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s failed, error (%d)", __FUNCTION__, dwError ); VmDirFreeIndexCfg(pIndexCfg); goto cleanup; }
VOID VmDirSchemaLibShutdown( VOID ) { BOOLEAN bInLock = FALSE; VMDIR_LOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex); // release live context and live schema VmDirSchemaCtxRelease(gVdirSchemaGlobals.pCtx); VMDIR_SAFE_FREE_MEMORY(gVdirSchemaGlobals.pszDN); VMDIR_UNLOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex); VMDIR_SAFE_FREE_MUTEX( gVdirSchemaGlobals.mutex ); }
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; }
DWORD VmDirSrvSetupHostInstance( PCSTR pszFQDomainName, PCSTR pszUsername, PCSTR pszPassword, PCSTR pszSiteName, PCSTR pszReplURI, UINT32 firstReplCycleMode ) { DWORD dwError = 0; PCSTR pszDelObjsContainerName = "Deleted Objects"; PCSTR pszConfigContainerName = VMDIR_CONFIGURATION_CONTAINER_NAME; PCSTR pszCAContainerName = VMDIR_CA_CONTAINER_NAME; PCSTR pszSitesContainerName = VMDIR_SITES_RDN_VAL; PCSTR pszSiteContainerName = "Default-First-Site"; PCSTR pszServersContainerName = VMDIR_SERVERS_CONTAINER_NAME; PCSTR pszReplAgrsContainerName = VMDIR_REPL_AGRS_CONTAINER_NAME; PCSTR pszDCsContainerName = VMDIR_DOMAIN_CONTROLLERS_RDN_VAL; PCSTR pszComputersContainerName = VMDIR_COMPUTERS_RDN_VAL; PCSTR pszMSAsContainerName = VMDIR_MSAS_RDN_VAL; PSTR pszDomainDN = NULL; PSTR pszDelObjsContainerDN = NULL; // CN=Deleted Objects,<domain DN> PSTR pszConfigContainerDN = NULL; // CN=Configuration,<domain DN> PSTR pszCAContainerDN = NULL; // CN=Certificate-Authorities,CN=Configuration,<domain DN> PSTR pszSitesContainerDN = NULL; // CN=Sites,<configuration DN> PSTR pszSiteContainerDN = NULL; // CN=<Site-Name>,<Sites container DN> PSTR pszServersContainerDN = NULL; // CN=Servers,<Site container DN> PSTR pszServerDN = NULL; // CN=<fully qualified host name>,<Servers container DN> PSTR pszReplAgrsContainerDN = NULL; // CN=Replication Agreements,<Server DN> PSTR pszReplAgrDN = NULL; // labeledURI=<ldap://192.165.226.127>,<ReplAgrsContainerDN> PSTR pszDCsContainerDN = NULL; // OU=Domain Controllers,<domain DN> PSTR pszComputersContainerDN = NULL; // OU=Computers,<domain DN> PSTR pszDCAccountDN = NULL; // CN=<fully qualified host name>,OU=Domain Controllers,<domain DN> PSTR pszDCAccountUPN = NULL; // <hostname>@<domain name> PSTR pszComputerAccountDN = NULL; // CN=<fully qualified host name>,OU=Domain Computers,<domain DN> PSTR pszMSAsDN = NULL; // CN=<Managed Service Accounts>,<domain DN> PSTR pszUpperCaseFQDomainName = NULL; PSTR pszLowerCaseHostName = NULL; PSTR pszDefaultAdminDN = NULL; PVDIR_SCHEMA_CTX pSchemaCtx = NULL; char pszHostName[VMDIR_MAX_HOSTNAME_LEN]; VDIR_BERVALUE bv = VDIR_BERVALUE_INIT; BOOLEAN bInLockReplCycle = FALSE; PVMDIR_REPLICATION_AGREEMENT pReplAgr = NULL; BOOLEAN bInLock = FALSE; PSTR pszUserDN = NULL; PCSTR pszUsersContainerName = "Users"; PSTR pszUsersContainerDN = NULL; // CN=Users,<domain DN> VMDIR_LOG_INFO(VMDIR_LOG_MASK_ALL, "Setting up a host instance (%s).", VDIR_SAFE_STRING(pszFQDomainName)); if (pszSiteName) { pszSiteContainerName = pszSiteName; } // If joining another node, copy schema from the partner first. if (!IsNullOrEmptyString(pszReplURI)) { dwError = VmDirCopyPartnerSchema( pszFQDomainName, pszUsername, pszPassword, pszReplURI); BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirSchemaCtxAcquire( &pSchemaCtx ); BAIL_ON_VMDIR_ERROR(dwError); // Construct important DNs and create the persisted DSE Root entry // Domain DN dwError = VmDirSrvCreateDomainDN( pszFQDomainName, &pszDomainDN ); BAIL_ON_VMDIR_ERROR(dwError); // Deleted objects container DN dwError = VmDirSrvCreateDN( pszDelObjsContainerName, pszDomainDN, &pszDelObjsContainerDN ); BAIL_ON_VMDIR_ERROR(dwError); // Configuration container DN dwError = VmDirSrvCreateDN( pszConfigContainerName, pszDomainDN, &pszConfigContainerDN ); BAIL_ON_VMDIR_ERROR(dwError); // Domain Controllers container DN dwError = VmDirAllocateStringAVsnprintf(&pszDCsContainerDN, "%s=%s,%s", ATTR_OU, pszDCsContainerName, pszDomainDN); BAIL_ON_VMDIR_ERROR(dwError); // Domain Computers container DN dwError = VmDirAllocateStringAVsnprintf(&pszComputersContainerDN, "%s=%s,%s", ATTR_OU, pszComputersContainerName, pszDomainDN); BAIL_ON_VMDIR_ERROR(dwError); // Sites container DN dwError = VmDirSrvCreateDN( pszSitesContainerName, pszConfigContainerDN, &pszSitesContainerDN ); BAIL_ON_VMDIR_ERROR(dwError); // Certificate-Authorities container DN dwError = VmDirSrvCreateDN( pszCAContainerName, pszConfigContainerDN, &pszCAContainerDN ); BAIL_ON_VMDIR_ERROR(dwError); // Particular site container DN dwError = VmDirSrvCreateDN( pszSiteContainerName, pszSitesContainerDN, &pszSiteContainerDN ); BAIL_ON_VMDIR_ERROR(dwError); // Servers within the site container DN dwError = VmDirSrvCreateDN( pszServersContainerName, pszSiteContainerDN, &pszServersContainerDN ); BAIL_ON_VMDIR_ERROR(dwError); // This server DN // vdcpromo sets this key. dwError = VmDirGetRegKeyValue( VMDIR_CONFIG_PARAMETER_KEY_PATH, VMDIR_REG_KEY_DC_ACCOUNT, pszHostName, sizeof(pszHostName)-1); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocASCIIUpperToLower( pszHostName, &pszLowerCaseHostName ); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSrvCreateDN( pszLowerCaseHostName, pszServersContainerDN, &pszServerDN ); BAIL_ON_VMDIR_ERROR(dwError); // Domain controller account DN dwError = VmDirSrvCreateDN( pszLowerCaseHostName, pszDCsContainerDN, &pszDCAccountDN ); BAIL_ON_VMDIR_ERROR(dwError); // Domain controller account UPN dwError = VmDirAllocASCIILowerToUpper( pszFQDomainName, &pszUpperCaseFQDomainName ); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateStringAVsnprintf(&pszDCAccountUPN, "%s@%s", pszLowerCaseHostName, pszUpperCaseFQDomainName ); BAIL_ON_VMDIR_ERROR(dwError); // Computer account DN dwError = VmDirSrvCreateDN( pszLowerCaseHostName, pszComputersContainerDN, &pszComputerAccountDN ); BAIL_ON_VMDIR_ERROR(dwError); // Replication agreements container DN dwError = VmDirSrvCreateDN( pszReplAgrsContainerName, pszServerDN, &pszReplAgrsContainerDN ); BAIL_ON_VMDIR_ERROR(dwError); // Managed Service Accounts container DN dwError = VmDirSrvCreateDN( pszMSAsContainerName, pszDomainDN, &pszMSAsDN ); BAIL_ON_VMDIR_ERROR(dwError); // Default administrator DN dwError = VmDirAllocateStringAVsnprintf( &pszDefaultAdminDN, "cn=%s,cn=%s,%s", pszUsername, pszUsersContainerName, pszDomainDN ); BAIL_ON_VMDIR_ERROR(dwError); if (firstReplCycleMode != FIRST_REPL_CYCLE_MODE_USE_COPIED_DB) { // Modify persisted DSE Root entry dwError = VmDirSrvModifyPersistedDSERoot( pSchemaCtx, pszDomainDN, pszConfigContainerDN, SCHEMA_NAMING_CONTEXT_DN, SUB_SCHEMA_SUB_ENTRY_DN, pszServerDN, pszDefaultAdminDN, pszDCAccountDN, pszDCAccountUPN, pszDelObjsContainerDN, (PSTR) pszSiteContainerName ); } BAIL_ON_VMDIR_ERROR(dwError); // set gVmdirServerGlobals.bvDefaultAdminDN dwError = VmDirAllocateBerValueAVsnprintf( &gVmdirServerGlobals.bvDefaultAdminDN, "%s", pszDefaultAdminDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirNormalizeDN( &gVmdirServerGlobals.bvDefaultAdminDN, pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); // set systemDomainDN dwError = VmDirAllocateBerValueAVsnprintf( &gVmdirServerGlobals.systemDomainDN, "%s", pszDomainDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirNormalizeDN( &gVmdirServerGlobals.systemDomainDN, pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); // set serverObjDN dwError = VmDirAllocateBerValueAVsnprintf( &gVmdirServerGlobals.serverObjDN, "%s", pszServerDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirNormalizeDN( &gVmdirServerGlobals.serverObjDN, pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); // set dcAccountDN dwError = VmDirAllocateBerValueAVsnprintf( &gVmdirServerGlobals.dcAccountDN, "%s", pszDCAccountDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirNormalizeDN( &gVmdirServerGlobals.dcAccountDN, pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); // set dcAccountUPN dwError = VmDirAllocateBerValueAVsnprintf( &gVmdirServerGlobals.dcAccountUPN, "%s", pszDCAccountUPN); BAIL_ON_VMDIR_ERROR(dwError); // Set replInterval and replPageSize gVmdirServerGlobals.replInterval = VmDirStringToIA(VMDIR_DEFAULT_REPL_INTERVAL); gVmdirServerGlobals.replPageSize = VmDirStringToIA(VMDIR_DEFAULT_REPL_PAGE_SIZE); // Set utdVector VmDirFreeBervalContent(&bv); bv.lberbv.bv_val = ""; bv.lberbv.bv_len = 0; dwError = VmDirBervalContentDup( &bv, &gVmdirServerGlobals.utdVector ); BAIL_ON_VMDIR_ERROR(dwError); // Set delObjsContainerDN VmDirFreeBervalContent(&bv); bv.lberbv.bv_val = pszDelObjsContainerDN; bv.lberbv.bv_len = VmDirStringLenA( bv.lberbv.bv_val ); dwError = VmDirBervalContentDup( &bv, &gVmdirServerGlobals.delObjsContainerDN ); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirNormalizeDN(&gVmdirServerGlobals.delObjsContainerDN, pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateStringA( pszSiteContainerName, &gVmdirServerGlobals.pszSiteName); BAIL_ON_VMDIR_ERROR(dwError); // Create Administrator DN dwError = VmDirSrvCreateDN( pszUsersContainerName, pszDomainDN, &pszUsersContainerDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSrvCreateUserDN( pszUsername, pszUsersContainerDN, &pszUserDN); BAIL_ON_VMDIR_ERROR(dwError); // set DomainControllerGroupDN for first,second+ host setup dwError = VmDirAllocateBerValueAVsnprintf( &gVmdirServerGlobals.bvDCGroupDN, "cn=%s,cn=%s,%s", VMDIR_DC_GROUP_NAME, VMDIR_BUILTIN_CONTAINER_NAME, pszDomainDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirNormalizeDN( &(gVmdirServerGlobals.bvDCGroupDN), pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); // set DCClientGroupDN for first,second+ host setup dwError = VmDirAllocateBerValueAVsnprintf( &gVmdirServerGlobals.bvDCClientGroupDN, "cn=%s,cn=%s,%s", VMDIR_DCCLIENT_GROUP_NAME, VMDIR_BUILTIN_CONTAINER_NAME, pszDomainDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirNormalizeDN( &(gVmdirServerGlobals.bvDCClientGroupDN), pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); // set ServicesRootDN for first,second+ host setup dwError = VmDirAllocateBerValueAVsnprintf( &gVmdirServerGlobals.bvServicesRootDN, "cn=%s,%s", VMDIR_SERVICES_CONTAINER_NAME, pszDomainDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirNormalizeDN( &(gVmdirServerGlobals.bvServicesRootDN), pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); if (IsNullOrEmptyString(pszReplURI)) // 1st directory instance is being setup { // Set gVmdirServerGlobals.serverId FIRST, so that correct SID can be generated for the objects added subsequently. gVmdirServerGlobals.serverId = 1; dwError = VmDirSrvSetupDomainInstance( pSchemaCtx, TRUE, TRUE, pszFQDomainName, pszDomainDN, pszUsername, pszPassword ); BAIL_ON_VMDIR_ERROR(dwError); // Create Deleted Objects container dwError = VmDirSrvCreateContainerWithEID( pSchemaCtx, pszDelObjsContainerDN, pszDelObjsContainerName, DEL_ENTRY_CONTAINER_ENTRY_ID ); BAIL_ON_VMDIR_ERROR(dwError); // Create Domain Controllers container dwError = VmDirSrvCreateOUContainer( pSchemaCtx, pszDCsContainerDN, pszDCsContainerName ); BAIL_ON_VMDIR_ERROR(dwError); // Create Computers container dwError = VmDirSrvCreateOUContainer( pSchemaCtx, pszComputersContainerDN, pszComputersContainerName ); BAIL_ON_VMDIR_ERROR(dwError); // Create Managed Service Accounts container dwError = VmDirSrvCreateContainer( pSchemaCtx, pszMSAsDN, pszMSAsContainerName ); BAIL_ON_VMDIR_ERROR(dwError); // Create Configuration container dwError = VmDirSrvCreateConfigContainer( pSchemaCtx, pszConfigContainerDN, pszConfigContainerName ); BAIL_ON_VMDIR_ERROR(dwError); // Create Certificate-Authorities container dwError = VmDirSrvCreateContainer( pSchemaCtx, pszCAContainerDN, pszCAContainerName ); BAIL_ON_VMDIR_ERROR(dwError); // Create Sites container dwError = VmDirSrvCreateContainer( pSchemaCtx, pszSitesContainerDN, pszSitesContainerName ); BAIL_ON_VMDIR_ERROR(dwError); /* // Create Site-Name container dwError = VmDirSrvCreateContainer( pSchemaCtx, pszSiteContainerDN, pszSiteContainerName ); BAIL_ON_VMDIR_ERROR(dwError); // Create Servers container dwError = VmDirSrvCreateContainer( pSchemaCtx, pszServersContainerDN, pszServersContainerName ); BAIL_ON_VMDIR_ERROR(dwError); */ // Create Site-Name container, Servers container, and THE Server object dwError = VmDirSrvCreateServerObj( pSchemaCtx ); BAIL_ON_VMDIR_ERROR(dwError); // Create Replication Agreements container dwError = VmDirSrvCreateReplAgrsContainer( pSchemaCtx ); BAIL_ON_VMDIR_ERROR(dwError); // 1st replica => no replication agreements => 1st replication cycle done VMDIR_LOCK_MUTEX(bInLockReplCycle, gVmdirGlobals.replCycleDoneMutex); VmDirConditionSignal(gVmdirGlobals.replCycleDoneCondition); VMDIR_UNLOCK_MUTEX(bInLockReplCycle, gVmdirGlobals.replCycleDoneMutex); } else { dwError = VmDirAllocateStringAVsnprintf( &pszReplAgrDN, "labeledURI=%s,%s", pszReplURI, pszReplAgrsContainerDN ); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirConstructReplAgr( pSchemaCtx, pszReplURI, VMDIR_DEFAULT_REPL_LAST_USN_PROCESSED, pszReplAgrDN, &pReplAgr ); BAIL_ON_VMDIR_ERROR(dwError); gFirstReplCycleMode = firstReplCycleMode; VMDIR_LOCK_MUTEX(bInLock, gVmdirGlobals.replAgrsMutex); pReplAgr->next = gVmdirReplAgrs; gVmdirReplAgrs = pReplAgr; // ownership transfer // wake up replication thread waiting on the existence // of a replication agreement. VmDirConditionSignal(gVmdirGlobals.replAgrsCondition); VMDIR_UNLOCK_MUTEX(bInLock, gVmdirGlobals.replAgrsMutex); } cleanup: if (pSchemaCtx) { VmDirSchemaCtxRelease(pSchemaCtx); } VMDIR_SAFE_FREE_MEMORY(pszDomainDN); VMDIR_SAFE_FREE_MEMORY(pszDelObjsContainerDN); VMDIR_SAFE_FREE_MEMORY(pszConfigContainerDN); VMDIR_SAFE_FREE_MEMORY(pszCAContainerDN); VMDIR_SAFE_FREE_MEMORY(pszSitesContainerDN); VMDIR_SAFE_FREE_MEMORY(pszSiteContainerDN); VMDIR_SAFE_FREE_MEMORY(pszServersContainerDN); VMDIR_SAFE_FREE_MEMORY(pszServerDN); VMDIR_SAFE_FREE_MEMORY(pszReplAgrsContainerDN); VMDIR_SAFE_FREE_MEMORY(pszReplAgrDN); VMDIR_SAFE_FREE_MEMORY(pszDCsContainerDN); VMDIR_SAFE_FREE_MEMORY(pszDCAccountDN); VMDIR_SAFE_FREE_MEMORY(pszDCAccountUPN); VMDIR_SAFE_FREE_MEMORY(pszComputersContainerDN); VMDIR_SAFE_FREE_MEMORY(pszComputerAccountDN); VMDIR_SAFE_FREE_MEMORY(pszMSAsDN); VMDIR_SAFE_FREE_MEMORY(pszUpperCaseFQDomainName); VMDIR_SAFE_FREE_MEMORY(pszUsersContainerDN); VMDIR_SAFE_FREE_MEMORY(pszUserDN); VMDIR_SAFE_FREE_MEMORY(pszDefaultAdminDN); VMDIR_SAFE_FREE_MEMORY(pszLowerCaseHostName); VmDirFreeBervalContent(&bv); return dwError; error: VmDirLog(LDAP_DEBUG_ANY, "VmDirSrvSetupHostInstance failed. Error(%u)", dwError); goto cleanup; }
//Clone a operation struct that share the same //transaction context with pOp DWORD VmDirCloneStackOperation( PVDIR_OPERATION pOp, PVDIR_OPERATION pOutOp, VDIR_OPERATION_TYPE opType, ber_tag_t requestCode, PVDIR_SCHEMA_CTX pSchemaCtx ) { DWORD dwError = 0; PVDIR_SCHEMA_CTX pLocalSchemaCtx = NULL; BAIL_ON_VMDIR_INVALID_POINTER( pOp, dwError ); BAIL_ON_VMDIR_INVALID_POINTER( pOutOp, dwError ); pOutOp->opType = opType; pOutOp->reqCode = requestCode; if ( pOutOp->reqCode == LDAP_REQ_ADD ) { dwError = VmDirAllocateMemory( sizeof(*(pOutOp->request.addReq.pEntry)), (PVOID)&(pOutOp->request.addReq.pEntry) ); BAIL_ON_VMDIR_ERROR( dwError ); } if ( pSchemaCtx ) { pLocalSchemaCtx = VmDirSchemaCtxClone( pSchemaCtx ); if ( !pLocalSchemaCtx ) { dwError = ERROR_NO_SCHEMA; BAIL_ON_VMDIR_ERROR(dwError); } } else { dwError = VmDirSchemaCtxAcquire(&pLocalSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirAllocateAndCopyMemory(pOp->pBECtx, sizeof(*pOutOp->pBECtx ), (PVOID) &(pOutOp->pBECtx)); BAIL_ON_VMDIR_ERROR(dwError); if ( pOutOp->opType == VDIR_OPERATION_TYPE_INTERNAL ) { // needs dummy conn->VDIR_ACCESS_INFO for ACL check dwError = VmDirAllocateMemory( sizeof( *pOutOp->conn), (PVOID) &(pOutOp->conn) ); BAIL_ON_VMDIR_ERROR(dwError); } pOutOp->pSchemaCtx = pLocalSchemaCtx; pLocalSchemaCtx = NULL; cleanup: return dwError; error: if ( pLocalSchemaCtx ) { VmDirSchemaCtxRelease( pLocalSchemaCtx ); } VmDirFreeOperationContent(pOutOp); goto cleanup; }
/* * Create a new schema cache via pEntry, then active this cache. */ DWORD VmDirSchemaInitializeViaEntry( PVDIR_ENTRY pEntry ) { BOOLEAN bLoadOk = TRUE; BOOLEAN bInLock = FALSE; DWORD dwError = 0; PVDIR_SCHEMA_CTX pLiveCtx = NULL; PVDIR_SCHEMA_INSTANCE pInstance = NULL; PVDIR_SCHEMA_INSTANCE pLiveInstance = NULL; VMDIR_LOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex); // get reference to current schema, to clean up later pLiveInstance = gVdirSchemaGlobals.pSchema; pLiveCtx = gVdirSchemaGlobals.pCtx; // instantiate a schema cache - pInstance dwError = VdirSchemaInstanceInitViaEntry( pEntry, &pInstance); BAIL_ON_VMDIR_ERROR(dwError); gVdirSchemaGlobals.pSchema = pInstance; dwError = VdirSchemaCtxAcquireInLock(TRUE, &gVdirSchemaGlobals.pCtx); // add self reference BAIL_ON_VMDIR_ERROR(dwError); assert(gVdirSchemaGlobals.pCtx); VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Startup schema instance (%p)", gVdirSchemaGlobals.pSchema); VMDIR_UNLOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex); cleanup: if (bLoadOk) { VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "Schema - AttributeTypes:(size=%d, nextid=%d) Objectclasses:(size=%d)", pEntry->pSchemaCtx->pSchema->ats.usNumATs, pEntry->pSchemaCtx->pSchema->ats.usNextId, pEntry->pSchemaCtx->pSchema->ocs.usNumOCs); } VMDIR_UNLOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex); if (pLiveCtx) { VmDirSchemaCtxRelease(pLiveCtx); } return dwError; error: if (pInstance) { VdirSchemaInstanceFree(pInstance); } gVdirSchemaGlobals.pSchema = pLiveInstance; gVdirSchemaGlobals.pCtx = pLiveCtx; pLiveCtx = NULL; bLoadOk = FALSE; goto cleanup; }
DWORD VmDirCreateAccount( PCSTR pszUPNName, PCSTR pszUserName, PCSTR pszPassword, // optional? PCSTR pszEntryDN // optional ) { DWORD dwError = 0; PSTR ppszAttributes[] = { ATTR_OBJECT_CLASS, (PSTR)OC_USER, ATTR_CN, (PSTR)pszUserName, ATTR_USER_PASSWORD, (PSTR)pszPassword, ATTR_SAM_ACCOUNT_NAME, (PSTR)pszUserName, ATTR_KRB_UPN, (PSTR)pszUPNName, NULL }; PVDIR_SCHEMA_CTX pSchemaCtx = NULL; PSTR pszAccountDN = NULL; if ( IsNullOrEmptyString(pszUPNName) || IsNullOrEmptyString(pszUserName) ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirSchemaCtxAcquire( &pSchemaCtx ); BAIL_ON_VMDIR_ERROR( dwError ); if (pszEntryDN == NULL) { dwError = VmDirUPNToAccountDN(pszUPNName, ATTR_CN, pszUserName, &pszAccountDN); BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirSimpleEntryCreate( pSchemaCtx, ppszAttributes, pszEntryDN ? (PSTR)pszEntryDN : pszAccountDN, 0); BAIL_ON_VMDIR_ERROR(dwError); cleanup: VmDirSchemaCtxRelease(pSchemaCtx); VMDIR_SAFE_FREE_MEMORY(pszAccountDN); return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "VmDirCreateAccount UPN(%s) failed, (%u)", VDIR_SAFE_STRING(pszUPNName), dwError); goto cleanup; }
/* * Convert attrIndexDesc attribute into a VDIR_ATTR_INDEX_INSTANCE * and enable gVdirAttrIndexCache with version 0. */ DWORD VdirAttrIndexInitViaEntry( PVDIR_ENTRY pEntry ) { DWORD dwError = 0; DWORD dwCnt = 0; BOOLEAN bInLock = FALSE; PVDIR_ATTRIBUTE pAttr = NULL; PVDIR_ATTR_INDEX_INSTANCE pAttrIdxCache = NULL; USHORT usLive = gVdirAttrIndexGlobals.usLive; PVDIR_SCHEMA_CTX pSchemaCtx = NULL; assert(pEntry); dwError = VmDirSchemaCtxAcquire(&pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); assert(pSchemaCtx); pAttr = VmDirEntryFindAttribute( ATTR_INDEX_DESC, pEntry); assert(pAttr); dwError = VdirAttrIndexCacheAllocate( &pAttrIdxCache, pAttr->numVals); BAIL_ON_VMDIR_ERROR(dwError); for (dwCnt = 0; dwCnt < pAttr->numVals; dwCnt++) { VDIR_CFG_ATTR_INDEX_DESC indexDesc = {0}; dwError = VdirstrToAttrIndexDesc( pAttr->vals[dwCnt].lberbv.bv_val, &indexDesc); BAIL_ON_VMDIR_ERROR(dwError); // cache takes over indexDesc.pszAttrName pAttrIdxCache->pSortName[dwCnt].pszAttrName = indexDesc.pszAttrName; indexDesc.pszAttrName = NULL; pAttrIdxCache->pSortName[dwCnt].bIsUnique = indexDesc.bIsUnique; pAttrIdxCache->pSortName[dwCnt].iTypes = indexDesc.iTypes; pAttrIdxCache->pSortName[dwCnt].status = indexDesc.status; pAttrIdxCache->pSortName[dwCnt].bIsNumeric = VmDirSchemaAttrHasIntegerMatchingRule( pSchemaCtx, pAttrIdxCache->pSortName[dwCnt].pszAttrName); pAttrIdxCache->pSortName[dwCnt].iId = dwCnt; } qsort(pAttrIdxCache->pSortName, pAttrIdxCache->usNumIndex, sizeof(VDIR_CFG_ATTR_INDEX_DESC), VdirAttrIndexNameCmp); VMDIR_LOCK_MUTEX(bInLock, gVdirAttrIndexGlobals.mutex); // Set up a cache instance // In case there is no need to do bootstrape during server start up, usLive == 0 // is not assigned (i.e.: schema entry is found) if ((usLive == 0 && gVdirAttrIndexGlobals.pCaches[usLive] != NULL) || usLive > 0) { usLive++; } gVdirAttrIndexGlobals.pCaches[usLive] = pAttrIdxCache; gVdirAttrIndexGlobals.usLive = usLive; cleanup: VMDIR_UNLOCK_MUTEX(bInLock, gVdirAttrIndexGlobals.mutex); if (pSchemaCtx) { VmDirSchemaCtxRelease(pSchemaCtx); } return dwError; error: if (pAttrIdxCache) { VdirAttrIdxCacheFree(pAttrIdxCache); } goto cleanup; }
void VmDirFreeEntryContent( VDIR_ENTRY * e ) { VmDirLog( LDAP_DEBUG_TRACE, "DeleteEntry: Begin" ); if ( e ) { VmDirLog( LDAP_DEBUG_TRACE, "DeleteEntry: DN = %s", e ? (e->dn.lberbv.bv_val ? e->dn.lberbv.bv_val : "") : "" ); if (e->pParentEntry) { VmDirFreeEntryContent(e->pParentEntry); VMDIR_SAFE_FREE_MEMORY(e->pParentEntry); } VmDirFreeLDAPDNContent( &(e->ldapDN) ); VmDirFreeBervalContent( &(e->dn) ); VmDirFreeBervalContent( &(e->pdn) ); VmDirFreeBervalContent( &(e->newpdn) ); if (e->allocType == ENTRY_STORAGE_FORMAT_PACK) { PVDIR_ATTRIBUTE pCurrAttr = NULL; PVDIR_ATTRIBUTE pTempAttr = NULL; pCurrAttr = e->attrs; while(pCurrAttr != NULL) { pTempAttr = pCurrAttr->next; VmDirFreeMetaData(pCurrAttr->pMetaData); pCurrAttr = pTempAttr; } VMDIR_SAFE_FREE_MEMORY( e->encodedEntry ); VmDirFreeBervalArrayContent(e->bvs, e->usNumBVs); VMDIR_SAFE_FREE_MEMORY( e->bvs ); VMDIR_SAFE_FREE_MEMORY( e->savedAttrsPtr ); } else if (e->allocType == ENTRY_STORAGE_FORMAT_NORMAL) { VDIR_ATTRIBUTE * currAttr = NULL; VDIR_ATTRIBUTE * tmpAttr = NULL; VMDIR_SAFE_FREE_MEMORY( e->encodedEntry ); for (currAttr = e->attrs; currAttr != NULL; ) { tmpAttr = currAttr->next; VmDirFreeAttribute(currAttr); currAttr = tmpAttr; } } if (e->pComputedAttrs) { VDIR_ATTRIBUTE * currAttr = NULL; VDIR_ATTRIBUTE * tmpAttr = NULL; for (currAttr = e->pComputedAttrs; currAttr != NULL; ) { tmpAttr = currAttr->next; VmDirFreeAttribute(currAttr); currAttr = tmpAttr; } } VmDirSchemaCtxRelease(e->pSchemaCtx); VmDirAclCtxContentFree(e->pAclCtx); VMDIR_SAFE_FREE_MEMORY(e->pAclCtx); VMDIR_SAFE_FREE_MEMORY(e->pszGuid); memset(e, 0, sizeof(*e)); } VmDirLog( LDAP_DEBUG_TRACE, "DeleteEntry: End" ); }
/* This function re-instantiates the current vmdir instance with a * foreign (MDB) database file. It is triggered by running vdcadmintool * with option 8. Before this action, a foreign database files must be copied * onto diretory mdb_home_dir/partner/ which may include mdb WAL files under * xlogs/. See PR 1995325 for the functional spec and use cases. */ DWORD VmDirSrvServerReset( PDWORD pServerResetState ) { int i = 0; DWORD dwError = 0; VDIR_ENTRY_ARRAY entryArray = {0}; const char *dbHomeDir = VMDIR_DB_DIR; PVDIR_SCHEMA_CTX pSchemaCtx = NULL; BOOLEAN bWriteInvocationId = FALSE; PSTR pszConfigurationContainerDn = NULL; PSTR pszDomainControllerContainerDn = NULL; PSTR pszManagedServiceAccountContainerDn = NULL; DEQUE computers = {0}; PSTR pszComputer = NULL; PVDIR_ATTRIBUTE pAttrUPN = NULL; BOOLEAN bMdbWalEnable = FALSE; VmDirGetMdbWalEnable(&bMdbWalEnable); //swap current vmdir database file with the foriegn one under partner/ dwError = _VmDirSwapDB(dbHomeDir, bMdbWalEnable); BAIL_ON_VMDIR_ERROR(dwError); //Delete Computers (domain controller accounts) under Domain Controller container dwError = VmDirAllocateStringPrintf(&pszDomainControllerContainerDn, "ou=%s,%s", VMDIR_DOMAIN_CONTROLLERS_RDN_VAL, gVmdirServerGlobals.systemDomainDN.lberbv_val); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSimpleEqualFilterInternalSearch(pszDomainControllerContainerDn, LDAP_SCOPE_ONE, ATTR_OBJECT_CLASS, OC_COMPUTER, &entryArray); BAIL_ON_VMDIR_ERROR(dwError); if(entryArray.iSize > 0) { for (i = 0; i < entryArray.iSize; i++) { pAttrUPN = VmDirFindAttrByName(&entryArray.pEntry[i], ATTR_KRB_UPN); if (pAttrUPN) { PSTR pPc = NULL; dwError = VmDirAllocateStringA(pAttrUPN->vals[0].lberbv_val, &pPc); dequePush(&computers, pPc); } dwError = VmDirDeleteEntry(&entryArray.pEntry[i]); BAIL_ON_VMDIR_ERROR(dwError); } } VmDirFreeEntryArrayContent(&entryArray); /* Delete all entries in the subtree under Configuration container * (e.g. under cn=Configuration,dc=vmware,dc=com). * This will remove the old replication topology */ dwError = VmDirAllocateStringPrintf(&pszConfigurationContainerDn, "cn=%s,%s", VMDIR_CONFIGURATION_CONTAINER_NAME, gVmdirServerGlobals.systemDomainDN.lberbv_val); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSimpleEqualFilterInternalSearch(pszConfigurationContainerDn, LDAP_SCOPE_SUBTREE, ATTR_OBJECT_CLASS, OC_DIR_SERVER, &entryArray); BAIL_ON_VMDIR_ERROR(dwError); if (entryArray.iSize > 0) { for (i = 0; i < entryArray.iSize; i++) { /* Delete all replication agreement entries for a server and * the server it self under the configuration/site container */ dwError = VmDirInternalDeleteTree(entryArray.pEntry[i].dn.lberbv_val); BAIL_ON_VMDIR_ERROR(dwError); } } VmDirFreeEntryArrayContent(&entryArray); //Delete ManagedServiceAccount entries that are associated with any of the domain controllers dwError = VmDirAllocateStringPrintf(&pszManagedServiceAccountContainerDn, "cn=%s,%s", VMDIR_MSAS_RDN_VAL, gVmdirServerGlobals.systemDomainDN.lberbv_val); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSimpleEqualFilterInternalSearch(pszManagedServiceAccountContainerDn, LDAP_SCOPE_ONE, ATTR_OBJECT_CLASS, OC_MANAGED_SERVICE_ACCOUNT, &entryArray); BAIL_ON_VMDIR_ERROR(dwError); if (entryArray.iSize > 0) { for (i = 0; i < entryArray.iSize; i++) { PDEQUE_NODE p = NULL; pAttrUPN = VmDirFindAttrByName(&entryArray.pEntry[i], ATTR_KRB_UPN); for(p = computers.pHead; p != NULL; p = p->pNext) { if (VmDirStringCaseStrA(pAttrUPN->vals[0].lberbv_val, p->pElement) != NULL) { dwError = VmDirDeleteEntry(&entryArray.pEntry[i]); BAIL_ON_VMDIR_ERROR(dwError); break; } } } } dwError = VmDirSchemaCtxAcquire(&pSchemaCtx ); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSrvCreateServerObj(pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); //Create server and replication entries for the current instance // on top of the (cleaned up) foreign database. dwError = VmDirSrvCreateReplAgrsContainer(pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); dwError = _VmDirPatchDSERoot(pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); VmDirSchemaCtxRelease(pSchemaCtx); pSchemaCtx = NULL; dwError = LoadServerGlobals(&bWriteInvocationId); BAIL_ON_VMDIR_ERROR(dwError); cleanup: if (pSchemaCtx) { VmDirSchemaCtxRelease(pSchemaCtx); } VmDirFreeEntryArrayContent(&entryArray); VMDIR_SAFE_FREE_MEMORY(pszConfigurationContainerDn); VMDIR_SAFE_FREE_MEMORY(pszDomainControllerContainerDn); while(!dequeIsEmpty(&computers)) { dequePopLeft(&computers, (PVOID*)&pszComputer); VMDIR_SAFE_FREE_MEMORY(pszComputer); } return dwError; error: goto cleanup; }
static int _VmDirSwapDB( PCSTR dbHomeDir, BOOLEAN bHasXlog) { int retVal = LDAP_SUCCESS; char dbExistingName[VMDIR_MAX_FILE_NAME_LEN] = {0}; char dbNewName[VMDIR_MAX_FILE_NAME_LEN] = {0}; PSTR pszLocalErrorMsg = NULL; int errorCode = 0; BOOLEAN bLegacyDataLoaded = FALSE; PVDIR_BACKEND_INTERFACE pBE = NULL; #ifndef _WIN32 const char fileSeperator = '/'; #else const char fileSeperator = '\\'; #endif // Shutdown backend pBE = VmDirBackendSelect(NULL); assert(pBE); VmDirdStateSet(VMDIRD_STATE_SHUTDOWN); VmDirIndexLibShutdown(); VmDirSchemaLibShutdown(); pBE->pfnBEShutdown(); VmDirBackendContentFree(pBE); // move .mdb files retVal = VmDirStringPrintFA( dbExistingName, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s%c%s", dbHomeDir, fileSeperator, LOCAL_PARTNER_DIR, fileSeperator, VMDIR_MDB_DATA_FILE_NAME); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirSwapDB: VmDirStringPrintFA() call failed with error: %d", retVal ); retVal = VmDirStringPrintFA( dbNewName, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s", dbHomeDir, fileSeperator, VMDIR_MDB_DATA_FILE_NAME ); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirSwapDB: VmDirStringPrintFA() call failed with error: %d", retVal ); #ifdef WIN32 if (MoveFileEx(dbExistingName, dbNewName, MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING) == 0) { retVal = LDAP_OPERATIONS_ERROR; errorCode = GetLastError(); #else if (rename(dbExistingName, dbNewName) != 0) { retVal = LDAP_OPERATIONS_ERROR; errorCode = errno; #endif BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirSwapDB: rename file from %s to %s failed, errno %d", dbExistingName, dbNewName, errorCode ); } retVal = VmDirStringPrintFA(dbNewName, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s%c%s", dbHomeDir, fileSeperator, VMDIR_MDB_XLOGS_DIR_NAME); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirSwapDB: VmDirStringPrintFA() call failed with error: %d", retVal ); if (bHasXlog) { //move xlog directory retVal = VmDirStringPrintFA(dbExistingName, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s%c%s", dbHomeDir, fileSeperator, LOCAL_PARTNER_DIR, fileSeperator, VMDIR_MDB_XLOGS_DIR_NAME); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirSwapDB: VmDirStringPrintFA() call failed with error: %d", retVal ); #ifdef WIN32 if (MoveFileEx(dbExistingName, dbNewName, MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING) == 0) { retVal = LDAP_OPERATIONS_ERROR; errorCode = GetLastError(); #else if (rmdir(dbNewName) != 0) { retVal = LDAP_OPERATIONS_ERROR; errorCode = errno; BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg), "_VmDirSwapDB cannot remove directory %s, errno %d", dbNewName, errorCode); } if (rename(dbExistingName, dbNewName) != 0) { retVal = LDAP_OPERATIONS_ERROR; errorCode = errno; #endif BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg), "_VmDirSwapDB cannot move directory from %s to %s, errno %d", dbNewName, dbExistingName, errorCode); } } retVal = VmDirStringPrintFA(dbExistingName, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s", dbHomeDir, fileSeperator, LOCAL_PARTNER_DIR); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirSwapDB: VmDirStringPrintFA() call failed with error: %d", retVal ); #ifdef WIN32 if (RemoveDirectory(dbExistingName)==0) { errorCode = GetLastError(); #else if (rmdir(dbExistingName)) { errorCode = errno; #endif VMDIR_LOG_WARNING(VMDIR_LOG_MASK_ALL, "cannot remove directory %s errno %d", dbExistingName, errorCode); } VmDirdStateSet(VMDIRD_STATE_STARTUP); retVal = VmDirInitBackend(&bLegacyDataLoaded); BAIL_ON_VMDIR_ERROR(retVal); if (bLegacyDataLoaded) { retVal = VmDirPatchLocalSubSchemaSubEntry(); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrorMsg, "_VmDirSwapDB: failed to patch subschema subentry: %d", retVal ); retVal = VmDirWriteSchemaObjects(); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrorMsg, "_VmDirSwapDB: failed to create schema tree: %d", retVal ); } VmDirdStateSet(VMDIRD_STATE_NORMAL); cleanup: VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg); return retVal; error: retVal = LDAP_OPERATIONS_ERROR; VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s", VDIR_SAFE_STRING(pszLocalErrorMsg) ); goto cleanup; } static int _VmDirWrapUpFirstReplicationCycle( PCSTR pszHostname, VMDIR_REPLICATION_AGREEMENT * pReplAgr) { int retVal = LDAP_SUCCESS; PVDIR_ENTRY pPartnerServerEntry = NULL; PVDIR_ATTRIBUTE pAttrUpToDateVector = NULL; PVDIR_ATTRIBUTE pAttrInvocationId = NULL; USN localUsn = 0; USN partnerLocalUsn = 0; char partnerlocalUsnStr[VMDIR_MAX_USN_STR_LEN]; VDIR_BACKEND_CTX beCtx = {0}; struct berval syncDoneCtrlVal = {0}; PVDIR_SCHEMA_CTX pSchemaCtx = NULL; VDIR_OPERATION searchOp = {0}; PVDIR_FILTER pSearchFilter = NULL; PSTR pszSeparator = NULL; retVal = VmDirSchemaCtxAcquire(&pSchemaCtx); BAIL_ON_VMDIR_ERROR( retVal ); retVal = VmDirInitStackOperation( &searchOp, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_SEARCH, pSchemaCtx ); BAIL_ON_VMDIR_ERROR(retVal); searchOp.pBEIF = VmDirBackendSelect(NULL); assert(searchOp.pBEIF); searchOp.reqDn.lberbv.bv_val = ""; searchOp.reqDn.lberbv.bv_len = 0; searchOp.request.searchReq.scope = LDAP_SCOPE_SUBTREE; retVal = VmDirConcatTwoFilters(searchOp.pSchemaCtx, ATTR_CN, (PSTR) pszHostname, ATTR_OBJECT_CLASS, OC_DIR_SERVER, &pSearchFilter); BAIL_ON_VMDIR_ERROR(retVal); searchOp.request.searchReq.filter = pSearchFilter; retVal = VmDirInternalSearch(&searchOp); BAIL_ON_VMDIR_ERROR(retVal); if (searchOp.internalSearchEntryArray.iSize != 1) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "_VmDirWrapUpFirstReplicationCycle: Unexpected (not 1) number of partner server entries found (%d)", searchOp.internalSearchEntryArray.iSize ); retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR(retVal); } pPartnerServerEntry = searchOp.internalSearchEntryArray.pEntry; pAttrUpToDateVector = VmDirEntryFindAttribute( ATTR_UP_TO_DATE_VECTOR, pPartnerServerEntry ); pAttrInvocationId = VmDirEntryFindAttribute( ATTR_INVOCATION_ID, pPartnerServerEntry ); assert( pAttrInvocationId != NULL ); beCtx.pBE = VmDirBackendSelect(NULL); assert(beCtx.pBE); if ((retVal = beCtx.pBE->pfnBEGetNextUSN( &beCtx, &localUsn )) != 0) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "_VmDirWrapUpFirstReplicationCycle: pfnBEGetNextUSN failed with error code: %d, " "error message: %s", retVal, VDIR_SAFE_STRING(beCtx.pszBEErrorMsg) ); BAIL_ON_VMDIR_ERROR( retVal ); } retVal = _VmGetHighestCommittedUSN(localUsn, &partnerLocalUsn); BAIL_ON_VMDIR_ERROR( retVal ); VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "_VmDirWrapUpFirstReplicationCycle: partnerLocalUsn %llu locaUsn %llu", partnerLocalUsn, localUsn); if ((retVal = VmDirStringNPrintFA( partnerlocalUsnStr, sizeof(partnerlocalUsnStr), sizeof(partnerlocalUsnStr) - 1, "%" PRId64, partnerLocalUsn)) != 0) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "_VmDirWrapUpFirstReplicationCycle: VmDirStringNPrintFA failed with error code: %d", retVal ); BAIL_ON_VMDIR_ERROR( retVal ); } if (pAttrUpToDateVector) { if (VmDirStringEndsWith( pAttrUpToDateVector->vals[0].lberbv.bv_val, ",", FALSE)) { pszSeparator = ""; } else { pszSeparator = ","; } // <partnerLocalUSN>,<partner up-to-date vector>,<partner server GUID>:<partnerLocalUSN>, retVal = VmDirAllocateStringPrintf( &(syncDoneCtrlVal.bv_val), "%s,%s%s%s:%s,", partnerlocalUsnStr, pAttrUpToDateVector->vals[0].lberbv.bv_val, pszSeparator, pAttrInvocationId->vals[0].lberbv.bv_val, partnerlocalUsnStr); BAIL_ON_VMDIR_ERROR(retVal); } else { // <partnerLocalUSN>,<partner server GUID>:<partnerLocalUSN>, retVal = VmDirAllocateStringPrintf( &(syncDoneCtrlVal.bv_val), "%s,%s:%s,", partnerlocalUsnStr, pAttrInvocationId->vals[0].lberbv.bv_val, partnerlocalUsnStr); BAIL_ON_VMDIR_ERROR(retVal); } VmDirSetACLMode(); syncDoneCtrlVal.bv_len = VmDirStringLenA(syncDoneCtrlVal.bv_val); if ((retVal = VmDirReplUpdateCookies( pSchemaCtx, &(syncDoneCtrlVal), pReplAgr )) != LDAP_SUCCESS) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "vdirReplicationThrFun: UpdateCookies failed. Error: %d", retVal ); BAIL_ON_VMDIR_ERROR( retVal ); } if ((retVal = _VmDirPatchDSERoot(pSchemaCtx)) != LDAP_SUCCESS) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "vdirReplicationThrFun: _VmDirPatchDSERoot failed. Error: %d", retVal ); BAIL_ON_VMDIR_ERROR( retVal ); } cleanup: VmDirFreeOperationContent(&searchOp); VmDirBackendCtxContentFree(&beCtx); VMDIR_SAFE_FREE_MEMORY(syncDoneCtrlVal.bv_val); VmDirSchemaCtxRelease(pSchemaCtx); return retVal; error: retVal = LDAP_OPERATIONS_ERROR; goto cleanup; } #ifndef VDIR_PSC_VERSION #define VDIR_PSC_VERSION "6.7.0" #endif static int _VmDirPatchDSERoot( PVDIR_SCHEMA_CTX pSchemaCtx) { int retVal = LDAP_SUCCESS; VDIR_OPERATION op = {0}; VDIR_BERVALUE bvDSERootDN = VDIR_BERVALUE_INIT; VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "_VmDirPatchDSERoot: Begin" ); bvDSERootDN.lberbv.bv_val = PERSISTED_DSE_ROOT_DN; bvDSERootDN.lberbv.bv_len = VmDirStringLenA( bvDSERootDN.lberbv.bv_val ); retVal = VmDirInitStackOperation( &op, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_MODIFY, pSchemaCtx ); BAIL_ON_VMDIR_ERROR(retVal); retVal = VmDirNormalizeDN( &bvDSERootDN, pSchemaCtx); BAIL_ON_VMDIR_ERROR(retVal); retVal = VmDirBervalContentDup( &bvDSERootDN, &op.reqDn ); BAIL_ON_VMDIR_ERROR(retVal); op.pBEIF = VmDirBackendSelect(op.reqDn.lberbv.bv_val); assert(op.pBEIF); if (VmDirBervalContentDup( &op.reqDn, &op.request.modifyReq.dn ) != 0) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "_VmDirPatchDSERoot: BervalContentDup failed." ); BAIL_ON_VMDIR_ERROR( retVal ); } retVal = VmDirAppendAMod( &op, MOD_OP_REPLACE, ATTR_DC_ACCOUNT_UPN, ATTR_DC_ACCOUNT_UPN_LEN, gVmdirServerGlobals.dcAccountUPN.lberbv.bv_val, gVmdirServerGlobals.dcAccountUPN.lberbv.bv_len ); BAIL_ON_VMDIR_ERROR( retVal ); retVal = VmDirAppendAMod( &op, MOD_OP_REPLACE, ATTR_DC_ACCOUNT_DN, ATTR_DC_ACCOUNT_DN_LEN, gVmdirServerGlobals.dcAccountDN.lberbv.bv_val, gVmdirServerGlobals.dcAccountDN.lberbv.bv_len ); BAIL_ON_VMDIR_ERROR( retVal ); retVal = VmDirAppendAMod( &op, MOD_OP_REPLACE, ATTR_SERVER_NAME, ATTR_SERVER_NAME_LEN, gVmdirServerGlobals.serverObjDN.lberbv.bv_val, gVmdirServerGlobals.serverObjDN.lberbv.bv_len ); BAIL_ON_VMDIR_ERROR( retVal ); retVal = VmDirAppendAMod( &op, MOD_OP_REPLACE, ATTR_SITE_NAME, ATTR_SITE_NAME_LEN, gVmdirServerGlobals.pszSiteName, VmDirStringLenA(gVmdirServerGlobals.pszSiteName) ); BAIL_ON_VMDIR_ERROR( retVal ); retVal = VmDirAppendAMod( &op, MOD_OP_REPLACE, ATTR_PSC_VERSION, ATTR_PSC_VERSION_LEN, VDIR_PSC_VERSION, VmDirStringLenA(VDIR_PSC_VERSION) ); BAIL_ON_VMDIR_ERROR( retVal ); retVal = VmDirAppendAMod( &op, MOD_OP_REPLACE, ATTR_MAX_DOMAIN_FUNCTIONAL_LEVEL, ATTR_MAX_DOMAIN_FUNCTIONAL_LEVEL_LEN, VMDIR_MAX_DFL_STRING, VmDirStringLenA(VMDIR_MAX_DFL_STRING) ); BAIL_ON_VMDIR_ERROR( retVal ); if ((retVal = VmDirInternalModifyEntry( &op )) != 0) { // If VmDirInternall call failed, reset retVal to LDAP level error space (for B/C) retVal = op.ldapResult.errCode; VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "_VmDirPatchDSERoot: InternalModifyEntry failed. " "Error code: %d, Error string: %s", retVal, VDIR_SAFE_STRING( op.ldapResult.pszErrMsg ) ); BAIL_ON_VMDIR_ERROR( retVal ); } cleanup: VmDirFreeOperationContent(&op); VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "_VmDirPatchDSERoot: End" ); return retVal; error: retVal = LDAP_OPERATIONS_ERROR; goto cleanup; }
DWORD VmDirIndexLibInit( PVMDIR_MUTEX pModMutex ) { static VDIR_DEFAULT_INDEX_CFG defIdx[] = VDIR_INDEX_INITIALIZER; DWORD dwError = 0; DWORD i = 0; PSTR pszLastOffset = NULL; ENTRYID maxEId = 0; VDIR_BACKEND_CTX beCtx = {0}; BOOLEAN bHasTxn = FALSE; PVDIR_INDEX_CFG pIndexCfg = NULL; PVDIR_SCHEMA_CTX pSchemaCtx = NULL; PVDIR_SCHEMA_AT_DESC pATDesc = NULL; if (!pModMutex) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } // pModMutex refers to gVdirSchemaGlobals.cacheModMutex, // so do not free it during shutdown gVdirIndexGlobals.mutex = pModMutex; dwError = VmDirAllocateCondition(&gVdirIndexGlobals.cond); BAIL_ON_VMDIR_ERROR(dwError); dwError = LwRtlCreateHashMap( &gVdirIndexGlobals.pIndexCfgMap, LwRtlHashDigestPstrCaseless, LwRtlHashEqualPstrCaseless, NULL); BAIL_ON_VMDIR_ERROR(dwError); beCtx.pBE = VmDirBackendSelect(NULL); dwError = beCtx.pBE->pfnBETxnBegin(&beCtx, VDIR_BACKEND_TXN_WRITE); BAIL_ON_VMDIR_ERROR(dwError); bHasTxn = TRUE; // get fields to continue indexing from where it left last time dwError = beCtx.pBE->pfnBEUniqKeyGetValue( &beCtx, INDEX_LAST_OFFSET_KEY, &pszLastOffset); if (dwError) { dwError = beCtx.pBE->pfnBEMaxEntryId(&maxEId); BAIL_ON_VMDIR_ERROR(dwError); if (maxEId == ENTRY_ID_SEQ_INITIAL_VALUE) { gVdirIndexGlobals.bFirstboot = TRUE; } else { gVdirIndexGlobals.bLegacyDB = TRUE; } // set index_last_offset = -1 to indicate indexing has started gVdirIndexGlobals.offset = -1; dwError = beCtx.pBE->pfnBEUniqKeySetValue( &beCtx, INDEX_LAST_OFFSET_KEY, "-1"); BAIL_ON_VMDIR_ERROR(dwError); } else { dwError = VmDirStringToINT64(pszLastOffset, NULL, &gVdirIndexGlobals.offset); BAIL_ON_VMDIR_ERROR(dwError); } dwError = beCtx.pBE->pfnBETxnCommit(&beCtx); BAIL_ON_VMDIR_ERROR(dwError); bHasTxn = FALSE; dwError = VmDirSchemaCtxAcquire(&pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); // open default indices for (i = 0; defIdx[i].pszAttrName; i++) { dwError = VmDirDefaultIndexCfgInit(&defIdx[i], &pIndexCfg); BAIL_ON_VMDIR_ERROR(dwError); // update attribute types in schema cache with their index info dwError = VmDirSchemaAttrNameToDescriptor( pSchemaCtx, pIndexCfg->pszAttrName, &pATDesc); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirIndexCfgGetAllScopesInStrArray( pIndexCfg, &pATDesc->ppszUniqueScopes); BAIL_ON_VMDIR_ERROR(dwError); pATDesc->dwSearchFlags |= 1; // for free later pATDesc->pLdapAt->ppszUniqueScopes = pATDesc->ppszUniqueScopes; pATDesc->pLdapAt->dwSearchFlags = pATDesc->dwSearchFlags; dwError = VmDirIndexOpen(pIndexCfg); BAIL_ON_VMDIR_ERROR(dwError); pIndexCfg = NULL; } // VMIT support dwError = VmDirIndexLibInitVMIT(); BAIL_ON_VMDIR_ERROR(dwError); dwError = InitializeIndexingThread(); BAIL_ON_VMDIR_ERROR(dwError); cleanup: if (bHasTxn) { beCtx.pBE->pfnBETxnAbort(&beCtx); } VmDirBackendCtxContentFree(&beCtx); VmDirSchemaCtxRelease(pSchemaCtx); VMDIR_SAFE_FREE_MEMORY(pszLastOffset); return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s failed, error (%d)", __FUNCTION__, dwError); VmDirFreeIndexCfg(pIndexCfg); goto cleanup; }
/* * 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; }
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; }
void VmDirFreeOperationContent( PVDIR_OPERATION op ) { DWORD dwError = ERROR_SUCCESS; if (op) { if (op->pSchemaCtx) { VmDirSchemaCtxRelease(op->pSchemaCtx); } if (op->syncDoneCtrl) { PLW_HASHTABLE_NODE pNode = NULL; LW_HASHTABLE_ITER iter = LW_HASHTABLE_ITER_INIT; UptoDateVectorEntry * pUtdVectorEntry = NULL; SyncDoneControlValue * syncDoneCtrlVal = &op->syncDoneCtrl->value.syncDoneCtrlVal; while ((pNode = LwRtlHashTableIterate(syncDoneCtrlVal->htUtdVector, &iter))) { dwError = LwRtlHashTableRemove(syncDoneCtrlVal->htUtdVector, pNode); assert( dwError == 0 ); pUtdVectorEntry = LW_STRUCT_FROM_FIELD(pNode, UptoDateVectorEntry, Node); VmDirFreeBervalContent( &pUtdVectorEntry->invocationId ); VMDIR_SAFE_FREE_MEMORY( pUtdVectorEntry ); } LwRtlFreeHashTable(&syncDoneCtrlVal->htUtdVector); assert( syncDoneCtrlVal->htUtdVector == NULL ); VMDIR_SAFE_FREE_MEMORY( op->syncDoneCtrl ); } if (op->pCondWriteCtrl) { VMDIR_SAFE_FREE_MEMORY(op->pCondWriteCtrl->value.condWriteCtrlVal.pszFilter); } if (op->reqControls) { DeleteControls(&(op->reqControls)); } switch (op->reqCode) { case LDAP_REQ_BIND: VmDirFreeBindRequest(&op->request.bindReq, FALSE); if (op->ldapResult.replyInfo.type == REP_SASL) { VmDirFreeBervalContent( &(op->ldapResult.replyInfo.replyData.bvSaslReply) ); } break; case LDAP_REQ_ADD: VmDirFreeAddRequest(&op->request.addReq, FALSE); break; case LDAP_REQ_SEARCH: VmDirFreeSearchRequest(&op->request.searchReq, FALSE); break; case LDAP_REQ_MODIFY: case LDAP_REQ_MODDN: VmDirFreeModifyRequest(&op->request.modifyReq, FALSE); break; case LDAP_REQ_DELETE: VmDirFreeDeleteRequest(&op->request.deleteReq, FALSE); if (op->request.modifyReq.numMods > 0) { //A raft follower needs to create a modifyReq for Delete OP VmDirFreeModifyRequest(&op->request.modifyReq, FALSE); } break; default: break; } VmDirFreeEntryArrayContent(&(op->internalSearchEntryArray)); VmDirFreeBervalContent( &(op->reqDn) ); VMDIR_SAFE_FREE_MEMORY(op->ldapResult.pszErrMsg); VmDirBackendCtxFree(op->pBECtx); VMDIR_SAFE_FREE_MEMORY(op->pszFilters); if ( op->opType == VDIR_OPERATION_TYPE_INTERNAL ) { // internal op owns dummy conn for ACL check VmDirDeleteConnection( &(op->conn)); // passing &conn to be freed seems a bit strange } } }
/* * 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; }