static int VmDirSASL2PATH( PSTR *ppszPath ) { DWORD dwError = 0; PSTR pszLocalPath = NULL; #ifdef _WIN32 char sasl2SearchPathBuf[MAX_PATH] = {0}; char vmdirInstallPathBuf[MAX_PATH] = {0}; // base sasl lib path dwError = VmDirGetRegKeyValue( VDMIR_CONFIG_SASL2_KEY_PATH, "SearchPath", sasl2SearchPathBuf, MAX_PATH ); BAIL_ON_VMDIR_ERROR(dwError); // vmdir specific sasl lib path dwError = VmDirGetRegKeyValue( VMDIR_CONFIG_SOFTWARE_KEY_PATH, "InstallPath", vmdirInstallPathBuf, MAX_PATH ); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateStringAVsnprintf( &pszLocalPath, "%s;%s\\sasl2", sasl2SearchPathBuf, vmdirInstallPathBuf); #else dwError = VmDirAllocateStringAVsnprintf( &pszLocalPath, "%s:%s/sasl2", VMDIR_CONFIG_SASL2_LIB_PATH, VMDIR_LIB_DIR); #endif BAIL_ON_VMDIR_ERROR(dwError); *ppszPath = pszLocalPath; VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "SASL2PATH=%s", pszLocalPath); cleanup: return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "VmDirSASL2PATH failed (%d)", dwError); VMDIR_SAFE_FREE_MEMORY( pszLocalPath ); goto cleanup; }
static DWORD VmDirSrvCreateUserDN( PCSTR pszUsername, PCSTR pszParentDN, PSTR* ppszUserDN ) { DWORD dwError = 0; PSTR pszUserDN = NULL; dwError = VmDirAllocateStringAVsnprintf( &pszUserDN, "cn=%s,%s", pszUsername, pszParentDN); BAIL_ON_VMDIR_ERROR(dwError); *ppszUserDN = pszUserDN; cleanup: return dwError; error: *ppszUserDN = NULL; 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; }
DWORD VmDirUPNToAccountDN( PCSTR pszUPNName, PCSTR pszAccountRDNAttr, PCSTR pszAccountRDNValue, PSTR* ppszAccountDN ) { DWORD dwError = 0; PSTR pszRealm = NULL; PSTR pszLocalDomainDN = NULL; PSTR pszLocalAccountDN = NULL; if ( IsNullOrEmptyString(pszUPNName) || IsNullOrEmptyString(pszAccountRDNAttr) || IsNullOrEmptyString(pszAccountRDNValue) || (ppszAccountDN == NULL) ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } pszRealm = VmDirStringRChrA(pszUPNName, VMDIR_UPN_REALM_SEPARATOR); if (pszRealm == NULL || pszRealm[1] == '\0') { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirFQDNToDN(pszRealm+1, &pszLocalDomainDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateStringAVsnprintf( &pszLocalAccountDN, "%s=%s,%s,%s", pszAccountRDNAttr, pszAccountRDNValue, DEFAULT_USER_CONTAINER_RDN, pszLocalDomainDN); BAIL_ON_VMDIR_ERROR(dwError); *ppszAccountDN = pszLocalAccountDN; cleanup: VMDIR_SAFE_FREE_MEMORY(pszLocalDomainDN); return dwError; error: VMDIR_SAFE_FREE_MEMORY(pszLocalAccountDN); goto cleanup; }
void TestVmDirSASLClient( void ) { DWORD dwError = 0; char pszServerHost[256] = {0}; PSTR pszLDAPURI = NULL; PSTR pszLDAPSURI = NULL; printf( "Please entry LDAP server host:"); scanf("%s", pszServerHost); dwError = VmDirAllocateStringAVsnprintf( &pszLDAPURI, "ldap://%s:389", pszServerHost[0] != '\0' ? pszServerHost : "localhost"); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateStringAVsnprintf( &pszLDAPSURI, "ldaps://%s", pszServerHost[0] != '\0' ? pszServerHost : "localhost"); BAIL_ON_VMDIR_ERROR(dwError); _VmDirClientTestSimpleBind( pszLDAPURI ); _VmDirClientTestSimpleSSLBind( pszLDAPSURI ); _VmDirClientTestGSSAPIBind( pszLDAPURI ); cleanup: VMDIR_SAFE_FREE_MEMORY(pszLDAPURI); VMDIR_SAFE_FREE_MEMORY(pszLDAPSURI); return; error: printf("TestVmDirSASLClient failed. (%d)\n", dwError); goto cleanup; }
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; }
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; }
PSTR GenerateString( VOID ) { static DWORD i = 0; PSTR pszString = NULL; DWORD dwError = 0; // // This is a unit test so we assume that the allocation succeeds. // dwError = VmDirAllocateStringAVsnprintf( &pszString, "Test String #%d", i++); ASSERT(dwError == 0); return pszString; }
PCSTR VmDirSchemaAttrIdToName( PVDIR_SCHEMA_CTX pCtx, USHORT usId ) { DWORD dwError = 0; PVDIR_SCHEMA_AT_DESC pResult = NULL; if (!pCtx) { return NULL; } if (usId >= pCtx->pSchema->ats.usNextId) { pCtx->dwErrorCode = ERROR_INVALID_PARAMETER; VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg); dwError = VmDirAllocateStringAVsnprintf( &pCtx->pszErrorMsg, "Lookup id(%d) > max id(%d)", usId, pCtx->pSchema->ats.usNextId - 1); BAIL_ON_VMDIR_ERROR(dwError); return NULL; } pResult = pCtx->pSchema->ats.ppATSortIdMap[usId - 1]; cleanup: return pResult ? pResult->pszName : NULL; error: goto cleanup; }
DWORD VmDirCleanupData( VOID ) { #ifndef _WIN32 return VmDirRun(VMDIR_CLEANUP_DATA); #else DWORD dwError = 0; PSTR pszPath[MAX_PATH+1] = {0}; PSTR pszCmd = NULL; dwError = VmDirGetRegKeyValue( VMDIR_CONFIG_SOFTWARE_KEY_PATH, VMDIR_REG_KEY_DATA_PATH, (PSTR)pszPath, MAX_PATH ); BAIL_ON_VMDIR_ERROR( dwError ); dwError = VmDirAllocateStringAVsnprintf( &pszCmd, "del /q \"%s\"", pszPath ); BAIL_ON_VMDIR_ERROR(dwError) dwError = VmDirRun( pszCmd ); BAIL_ON_VMDIR_ERROR(dwError); cleanup: VMDIR_SAFE_FREE_MEMORY(pszCmd); return dwError; error: goto cleanup; #endif }
VOID VdcadminTestSASLClient( VOID ) { DWORD dwError = 0; char pszServerHost[SIZE_256] = {0}; char pszServerPort[SIZE_256] = {0}; char pszServerSSLPort[SIZE_256] = {0}; char pszBindDN[SIZE_256] = {0}; char pszBindUPN[SIZE_256] = {0}; char pszPassword[SIZE_256] = {0}; PSTR pszLDAPURI = NULL; PSTR pszLDAPSURI = NULL; VmDirReadString( "Please enter LDAP server host: ", pszServerHost, SIZE_256, FALSE); VmDirReadString( "Please enter LDAP server port: ", pszServerPort, SIZE_256, FALSE); VmDirReadString( "Please enter LDAP server SSL port: ", pszServerSSLPort, SIZE_256, FALSE); VmDirReadString( "Please enter LDAP Bind DN: ", pszBindDN, SIZE_256, FALSE); VmDirReadString( "Please enter LDAP Bind UPN: ", pszBindUPN, SIZE_256, FALSE); VmDirReadString( "Please enter LDAP Bind password: "******"\n"); dwError = VmDirAllocateStringAVsnprintf( &pszLDAPURI, "ldap://%s:%s", pszServerHost[0] != '\0' ? pszServerHost : "localhost", pszServerPort); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateStringAVsnprintf( &pszLDAPSURI, "ldaps://%s:%s", pszServerHost[0] != '\0' ? pszServerHost : "localhost", pszServerSSLPort); BAIL_ON_VMDIR_ERROR(dwError); _VdcadminClientTestSimpleBind( pszLDAPURI, pszBindDN, pszPassword ); _VdcadminClientTestSimpleSSLBind( pszLDAPSURI, pszBindDN, pszPassword ); _VdcadminClientTestSRPBind( pszLDAPURI, pszBindUPN, pszPassword ); _VdcadminClientTestGSSAPIBind( pszLDAPURI ); cleanup: memset(pszPassword, 0, sizeof(pszPassword)); VMDIR_SAFE_FREE_MEMORY(pszLDAPURI); VMDIR_SAFE_FREE_MEMORY(pszLDAPSURI); return; error: printf("TestVdcadminSASLClient failed. (%d)\n", dwError); goto cleanup; }
static DWORD VmDirSrvSetupDomainInstance( PVDIR_SCHEMA_CTX pSchemaCtx, BOOLEAN bSetupHost, BOOLEAN bFirstNodeBootstrap, PCSTR pszFQDomainName, PCSTR pszDomainDN, PCSTR pszUsername, PCSTR pszPassword ) { DWORD dwError = 0; PCSTR pszUsersContainerName = "Users"; PCSTR pszBuiltInContainerName = "Builtin"; PCSTR pszFSPsContainerName = FSP_CONTAINER_RDN_ATTR_VALUE; PCSTR pszBuiltInUsersGroupName = "Users"; PCSTR pszBuiltInAdministratorsGroupName = "Administrators"; PSTR pszUsersContainerDN = NULL; // CN=Users,<domain DN> PSTR pszBuiltInContainerDN = NULL; // CN=BuiltIn,<domain DN> PSTR pszFSPsContainerDN = NULL; // CN=ForeignSecurityPrincipals,<domain DN> PSTR pszUserDN = NULL; PSTR pszBuiltInUsersGroupDN = NULL; PSTR pszBuiltInAdministratorsGroupDN = NULL; PSTR pszDefaultPasswdLockoutPolicyDN = NULL; PSTR pszDCGroupDN = NULL; PSTR pszDCClientGroupDN = NULL; PSTR pszCertGroupDN = NULL; PSTR pszTenantRealmName = NULL; PSECURITY_DESCRIPTOR_RELATIVE pSecDescRel = NULL; ULONG ulSecDescRel = 0; SECURITY_INFORMATION SecInfo = 0; PSTR pszAdminSid = NULL; PSTR pszBuiltInUsersGroupSid = NULL; PSTR pszAdminsGroupSid = NULL; PSTR pszAdminUserKrbUPN = NULL; int i = 0; int startOfRdnInd = 0; // Create host/tenant domain dwError = VmDirSrvCreateDomain(pSchemaCtx, bSetupHost, pszDomainDN); BAIL_ON_VMDIR_ERROR(dwError); // Create Users container dwError = VmDirSrvCreateDN( pszUsersContainerName, pszDomainDN, &pszUsersContainerDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSrvCreateContainer( pSchemaCtx, pszUsersContainerDN, pszUsersContainerName); BAIL_ON_VMDIR_ERROR(dwError); // Create Builtin container dwError = VmDirSrvCreateDN( pszBuiltInContainerName, pszDomainDN, &pszBuiltInContainerDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSrvCreateBuiltinContainer( pSchemaCtx, pszBuiltInContainerDN, pszBuiltInContainerName ); BAIL_ON_VMDIR_ERROR(dwError); // Create ForeignSecurityPrincipals container dwError = VmDirSrvCreateDN( pszFSPsContainerName, pszDomainDN, &pszFSPsContainerDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSrvCreateContainer( pSchemaCtx, pszFSPsContainerDN, pszFSPsContainerName); BAIL_ON_VMDIR_ERROR(dwError); if (bSetupHost) { // only do this for the very first node startup. if (bFirstNodeBootstrap) { dwError = VmDirSrvInitKrb(pSchemaCtx, pszFQDomainName, pszDomainDN); BAIL_ON_VMDIR_ERROR(dwError); // prepare administrator krb UPN for the very first node dwError = VmDirAllocateStringAVsnprintf( &pszAdminUserKrbUPN, "%s@%s", pszUsername, gVmdirKrbGlobals.pszRealm); BAIL_ON_VMDIR_ERROR(dwError); } } else { // setup tenant scenario. // Though we only support system domain kdc, we need UPN for SRP to function. dwError = VmDirKrbRealmNameNormalize(pszFQDomainName, &pszTenantRealmName); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateStringAVsnprintf( &pszAdminUserKrbUPN, "%s@%s", pszUsername, pszTenantRealmName); BAIL_ON_VMDIR_ERROR(dwError); } // Create Admin user dwError = VmDirSrvCreateUserDN( pszUsername, pszUsersContainerDN, &pszUserDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirGenerateWellknownSid(pszDomainDN, VMDIR_DOMAIN_USER_RID_ADMIN, &pszAdminSid); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSrvCreateUser( pSchemaCtx, (bSetupHost && bFirstNodeBootstrap) ? DEFAULT_ADMINISTRATOR_ENTRY_ID : 0, pszUsername, pszUsername, pszFQDomainName, pszUsername, pszPassword, pszUserDN, pszAdminSid, pszAdminUserKrbUPN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSetAdministratorPasswordNeverExpires(); BAIL_ON_VMDIR_ERROR(dwError); // Create BuiltInUsers group dwError = VmDirAllocateStringAVsnprintf( &pszBuiltInUsersGroupDN, "cn=%s,%s", pszBuiltInUsersGroupName, pszBuiltInContainerDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirGenerateWellknownSid(pszDomainDN, VMDIR_DOMAIN_ALIAS_RID_USERS, &pszBuiltInUsersGroupSid); BAIL_ON_VMDIR_ERROR(dwError); // // Create the user group for tenant setup or for first host setup. // if (bSetupHost == FALSE || bFirstNodeBootstrap == TRUE) { dwError = VmDirSrvCreateBuiltInUsersGroup( pSchemaCtx, pszBuiltInUsersGroupName, pszBuiltInUsersGroupDN, pszUserDN, pszBuiltInUsersGroupSid); BAIL_ON_VMDIR_ERROR(dwError); } // Create BuiltInAdministrators group dwError = VmDirAllocateStringAVsnprintf( &pszBuiltInAdministratorsGroupDN, "cn=%s,%s", pszBuiltInAdministratorsGroupName, pszBuiltInContainerDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirGenerateWellknownSid(pszDomainDN, VMDIR_DOMAIN_ALIAS_RID_ADMINS, &pszAdminsGroupSid); BAIL_ON_VMDIR_ERROR(dwError); // // Create the admin group for tenant setup or for first host setup. // if (bSetupHost == FALSE || bFirstNodeBootstrap == TRUE) { dwError = VmDirSrvCreateBuiltInAdminGroup( pSchemaCtx, pszBuiltInAdministratorsGroupName, pszBuiltInAdministratorsGroupDN, pszUserDN, pszAdminsGroupSid ); BAIL_ON_VMDIR_ERROR(dwError); } // // Create DCadmins/DCClients/CERTAdmins groups only for the very first // host setup. // if ( bSetupHost && bFirstNodeBootstrap ) { // create DCAdmins Group dwError = VmDirAllocateStringAVsnprintf( &pszDCGroupDN, "cn=%s,%s", VMDIR_DC_GROUP_NAME, pszBuiltInContainerDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = _VmDirSrvCreateBuiltInGroup( pSchemaCtx, VMDIR_DC_GROUP_NAME, pszDCGroupDN); BAIL_ON_VMDIR_ERROR(dwError); // create DCClients Group dwError = VmDirAllocateStringAVsnprintf( &pszDCClientGroupDN, "cn=%s,%s", VMDIR_DCCLIENT_GROUP_NAME, pszBuiltInContainerDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = _VmDirSrvCreateBuiltInGroup( pSchemaCtx, VMDIR_DCCLIENT_GROUP_NAME, pszDCClientGroupDN); BAIL_ON_VMDIR_ERROR(dwError); // create CertAdmins Group dwError = VmDirAllocateStringAVsnprintf( &pszCertGroupDN, "cn=%s,%s", VMDIR_CERT_GROUP_NAME, pszBuiltInContainerDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = _VmDirSrvCreateBuiltInCertGroup( pSchemaCtx, VMDIR_CERT_GROUP_NAME, pszCertGroupDN, pszUserDN, // member: default administrator pszDCGroupDN, // member: DCAdmins group pszDCClientGroupDN); // member: DCClients group BAIL_ON_VMDIR_ERROR(dwError); } // Set up SD for the entries created during instance set up // Default allows administrator VMDIR_ENTRY_ALL_ACCESS, // oneself VMDIR_ENTRY_GENERIC_WRITE dwError = VmDirSrvCreateDefaultSecDescRel( pszUserDN, pszAdminsGroupSid, &pSecDescRel, &ulSecDescRel, &SecInfo); BAIL_ON_VMDIR_ERROR(dwError); // add the same sd for all the objects created during instance set-up // Set SD for the Domain objects for (i = (int) VmDirStringLenA(pszDomainDN) - 1; i >= 0; i-- ) { if (i == 0 || pszDomainDN[i] == RDN_SEPARATOR_CHAR) { startOfRdnInd = (i == 0) ? 0 : i + 1 /* for , */; dwError = VmDirSetSecurityDescriptorForDn( (PSTR)pszDomainDN + startOfRdnInd, SecInfo, pSecDescRel, ulSecDescRel); BAIL_ON_VMDIR_ERROR(dwError); } } dwError = VmDirSetSecurityDescriptorForDn( (PSTR)pszDomainDN, SecInfo, pSecDescRel, ulSecDescRel); BAIL_ON_VMDIR_ERROR(dwError); // Set SD for the administrator object dwError = VmDirSetSecurityDescriptorForDn( pszUserDN, SecInfo, pSecDescRel, ulSecDescRel); BAIL_ON_VMDIR_ERROR(dwError); // Set SD for Users container dwError = VmDirSetSecurityDescriptorForDn( pszUsersContainerDN, SecInfo, pSecDescRel, ulSecDescRel); BAIL_ON_VMDIR_ERROR(dwError); // Set SD for Builtin container dwError = VmDirSetSecurityDescriptorForDn( pszBuiltInContainerDN, SecInfo, pSecDescRel, ulSecDescRel); BAIL_ON_VMDIR_ERROR(dwError); // Set SD for ForeignSecurityPrincipals container dwError = VmDirSetSecurityDescriptorForDn( pszFSPsContainerDN, SecInfo, pSecDescRel, ulSecDescRel); BAIL_ON_VMDIR_ERROR(dwError); if (bSetupHost == FALSE || bFirstNodeBootstrap == TRUE) { // Set SD for BuiltInUsers group dwError = VmDirSetSecurityDescriptorForDn( pszBuiltInUsersGroupDN, SecInfo, pSecDescRel, ulSecDescRel); BAIL_ON_VMDIR_ERROR(dwError); // Set SD for BuiltInAdministrators group dwError = VmDirSetSecurityDescriptorForDn( pszBuiltInAdministratorsGroupDN, SecInfo, pSecDescRel, ulSecDescRel); BAIL_ON_VMDIR_ERROR(dwError); } if ( bSetupHost && bFirstNodeBootstrap ) { // Set SD for BuiltIn DC group dwError = VmDirSetSecurityDescriptorForDn( pszDCGroupDN, SecInfo, pSecDescRel, ulSecDescRel); BAIL_ON_VMDIR_ERROR(dwError); // Set SD for BuiltIn DCClients group dwError = VmDirSetSecurityDescriptorForDn(pszDCClientGroupDN, SecInfo, pSecDescRel, ulSecDescRel); BAIL_ON_VMDIR_ERROR(dwError); // Set SD for BuiltIn Cert group dwError = VmDirSetSecurityDescriptorForDn( pszCertGroupDN, SecInfo, pSecDescRel, ulSecDescRel); BAIL_ON_VMDIR_ERROR(dwError); } // Create default password and lockout policy dwError = VmDirSrvCreateDN( PASSWD_LOCKOUT_POLICY_DEFAULT_CN, pszDomainDN, &pszDefaultPasswdLockoutPolicyDN ); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSrvCreateDefaultPasswdPolicy(pSchemaCtx, pszDefaultPasswdLockoutPolicyDN); BAIL_ON_VMDIR_ERROR(dwError); // Set SD for Password lockout policy object dwError = VmDirSetSecurityDescriptorForDn( pszDefaultPasswdLockoutPolicyDN, SecInfo, pSecDescRel, ulSecDescRel); BAIL_ON_VMDIR_ERROR(dwError); cleanup: VMDIR_SAFE_FREE_MEMORY(pszUsersContainerDN); VMDIR_SAFE_FREE_MEMORY(pszBuiltInContainerDN); VMDIR_SAFE_FREE_MEMORY(pszFSPsContainerDN); VMDIR_SAFE_FREE_MEMORY(pszUserDN); VMDIR_SAFE_FREE_MEMORY(pszBuiltInUsersGroupDN); VMDIR_SAFE_FREE_MEMORY(pszBuiltInAdministratorsGroupDN); VMDIR_SAFE_FREE_MEMORY(pszDefaultPasswdLockoutPolicyDN); VMDIR_SAFE_FREE_MEMORY(pszDCGroupDN); VMDIR_SAFE_FREE_MEMORY(pszDCClientGroupDN); VMDIR_SAFE_FREE_MEMORY(pszCertGroupDN); VMDIR_SAFE_FREE_MEMORY(pszTenantRealmName); VMDIR_SAFE_FREE_MEMORY(pSecDescRel); VMDIR_SAFE_FREE_MEMORY(pszAdminSid); VMDIR_SAFE_FREE_MEMORY(pszBuiltInUsersGroupSid); VMDIR_SAFE_FREE_MEMORY(pszAdminsGroupSid); VMDIR_SAFE_FREE_MEMORY(pszAdminUserKrbUPN); return dwError; error: VmDirLog(LDAP_DEBUG_ANY, "VmDirSrvSetupDomainInstance 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; }
static DWORD VmDirSrvInitKrb( PVDIR_SCHEMA_CTX pSchemaCtx, PCSTR pszFQDomainName, PCSTR pszDomainDN ) { DWORD dwError = 0; PSTR pszRealmName = NULL; PBYTE pMasterKey = NULL; DWORD dwMasterKeyLen = 0; PBYTE pEncMasterKey = NULL; DWORD dwEncMasterKeyLen = 0; PSTR pszTgtUPN = NULL; PSTR pszTgtCN = NULL; PSTR pszTgtPasswd = NULL; PSTR pszKMUPN = NULL; PSTR pszKMPasswd = NULL; PSTR pszKMDN = NULL; VDIR_BERVALUE bervMKey = VDIR_BERVALUE_INIT; VDIR_BERVALUE bervEncMKey = VDIR_BERVALUE_INIT; assert (pSchemaCtx && pszFQDomainName && pszDomainDN ); dwError = VmDirKrbRealmNameNormalize(pszFQDomainName, &pszRealmName); BAIL_ON_VMDIR_ERROR(dwError); // create krb master key dwError = VmKdcGenerateMasterKey( &pMasterKey, &dwMasterKeyLen, &pEncMasterKey, &dwEncMasterKeyLen); BAIL_ON_VMDIR_ERROR(dwError); bervMKey.lberbv.bv_val = pMasterKey; bervMKey.lberbv.bv_len = dwMasterKeyLen; bervEncMKey.lberbv.bv_val = pEncMasterKey; bervEncMKey.lberbv.bv_len = dwEncMasterKeyLen; // add krb master key to domain entry dwError = VmDirInternalEntryAttributeReplace( pSchemaCtx, pszDomainDN, ATTR_KRB_MASTER_KEY, &bervMKey); BAIL_ON_VMDIR_ERROR(dwError); // init gVmdirKrbGlobals (to cache krbMKey), which is needed in VmDirCreateAccount below. dwError = VmDirKrbInit(); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateStringAVsnprintf( &pszTgtUPN, "krbtgt/%s@%s", pszRealmName, pszRealmName); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateStringAVsnprintf( &pszTgtCN, "krbtgt/%s", pszRealmName); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmKdcGenerateRandomPassword( VMDIR_KDC_RANDOM_PWD_LEN, &pszTgtPasswd); BAIL_ON_VMDIR_ERROR(dwError); // create krbtgt principal dwError = VmDirCreateAccount( pszTgtUPN, pszTgtCN, pszTgtPasswd, NULL); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateStringAVsnprintf( &pszKMUPN, "K/M@%s", pszRealmName); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmKdcGenerateRandomPassword( VMDIR_KDC_RANDOM_PWD_LEN, &pszKMPasswd); BAIL_ON_VMDIR_ERROR(dwError); // create K/M principal dwError = VmDirCreateAccount( pszKMUPN, "K/M", // TODO, cn=k/M for now pszKMPasswd, NULL); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirUPNToAccountDN( pszKMUPN, "cn", "K/M", &pszKMDN); BAIL_ON_VMDIR_ERROR(dwError); // K/M principal need special ATTR_KRB_PRINCIPAL - encoded master key/pEncMasterKey dwError = VmDirInternalEntryAttributeReplace( pSchemaCtx, pszKMDN, ATTR_KRB_PRINCIPAL_KEY, &bervEncMKey); BAIL_ON_VMDIR_ERROR(dwError); cleanup: VMDIR_SAFE_FREE_MEMORY(pMasterKey); VMDIR_SAFE_FREE_MEMORY(pEncMasterKey); VMDIR_SAFE_FREE_MEMORY(pszTgtUPN); VMDIR_SAFE_FREE_MEMORY(pszTgtCN); VMDIR_SAFE_FREE_MEMORY(pszTgtPasswd); VMDIR_SAFE_FREE_MEMORY(pszKMUPN); VMDIR_SAFE_FREE_MEMORY(pszKMPasswd); VMDIR_SAFE_FREE_MEMORY(pszRealmName); VMDIR_SAFE_FREE_MEMORY(pszKMDN); return dwError; error: goto cleanup; }
int main(int argc, char* argv[]) { DWORD dwError = 0; const int ldapVer = LDAP_VERSION3; PVMDIR_QUERY_ARGS pArgs = NULL; PSTR pszLdapURL = NULL; LDAP* pLd = NULL; BerValue ldapBindPwd = {0}; LDAPMessage* pResult = NULL; PSTR pszDN = NULL; dwError = VmDirQueryParseArgs(argc, argv, &pArgs); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateStringAVsnprintf( &pszLdapURL, "ldap://%s", pArgs->pszHostname); BAIL_ON_VMDIR_ERROR(dwError); #if 0 dwError = ldap_initialize(&pLd, pszLdapURL); BAIL_ON_VMDIR_ERROR(dwError); #else pLd = ldap_open(pArgs->pszHostname, 389); if (!pLd) { dwError = VMDIR_ERROR_SERVER_DOWN; BAIL_ON_VMDIR_ERROR(dwError); } #endif dwError = ldap_set_option(pLd, LDAP_OPT_PROTOCOL_VERSION, &ldapVer); BAIL_ON_VMDIR_ERROR(dwError); dwError = ldap_set_option(pLd, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); BAIL_ON_VMDIR_ERROR(dwError); ldapBindPwd.bv_val = pArgs->pszPassword; ldapBindPwd.bv_len = strlen(pArgs->pszPassword); #if 0 dwError = ldap_sasl_bind_s( pLd, pArgs->pszBindDN, LDAP_SASL_SIMPLE, &ldapBindPwd, NULL, NULL, NULL); BAIL_ON_VMDIR_ERROR(dwError); #else dwError = ldap_bind_s( pLd, pArgs->pszBindDN, pArgs->pszPassword, LDAP_AUTH_SIMPLE); BAIL_ON_VMDIR_ERROR(dwError); #endif #if 0 dwError = ldap_search_ext_s( pLd, pArgs->pszBaseDN, LDAP_SCOPE_SUBTREE, pArgs->pszFilter, NULL, TRUE, NULL, // server ctrls NULL, // client ctrls NULL, // timeout -1, // size limit, &pResult); BAIL_ON_VMDIR_ERROR(dwError); #else dwError = ldap_search_s( pLd, pArgs->pszBaseDN, LDAP_SCOPE_SUBTREE, pArgs->pszFilter, NULL, TRUE, &pResult); BAIL_ON_VMDIR_ERROR(dwError); #endif if (ldap_count_entries(pLd, pResult) > 0) { LDAPMessage* pEntry = ldap_first_entry(pLd, pResult); for (; pEntry != NULL; pEntry = ldap_next_entry(pLd, pEntry)) { if (pszDN) { ldap_memfree(pszDN); pszDN = NULL; } pszDN = ldap_get_dn(pLd, pEntry); if (IsNullOrEmptyString(pszDN)) { dwError = VMDIR_ERROR_INVALID_DN; BAIL_ON_VMDIR_ERROR(dwError); } fprintf(stdout, "DN : %s\n", pszDN); } } cleanup: if (pArgs) { VmDirFreeArgs(pArgs); } VMDIR_SAFE_FREE_MEMORY(pszLdapURL); if (pResult) { ldap_msgfree(pResult); } if (pszDN) { ldap_memfree(pszDN); } if (pLd) { ldap_unbind_ext_s(pLd, NULL, NULL); } return dwError; error: goto cleanup; }
/* * 1. must have objectclass value * 2. must have structural objectclass (done in schemaCheckStructure) * 3. must match contentrule allowed auxiliary objectclass definition * 4. must have all MUST attributes * 5. may have allowed MAY attributes */ static DWORD _VmDirSchemaCheckStructure( PVDIR_SCHEMA_CTX pCtx, PVDIR_ENTRY pEntry ) { DWORD dwError = 0; USHORT usCnt = 0; BOOLEAN* pbPresentList = NULL; DWORD numAttrs = 0; PVDIR_ATTRIBUTE pTmpAttr = NULL; VDIR_ATTRIBUTE* pOCAttr = NULL; for (pTmpAttr = pEntry->attrs; pTmpAttr != NULL; pTmpAttr = pTmpAttr->next) { numAttrs++; } if (numAttrs == 0) { pCtx->dwErrorCode = ERROR_INVALID_ENTRY; VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg); dwError = VmDirAllocateStringA( "Entry has no attributes", &pCtx->pszErrorMsg); dwError = ERROR_INVALID_ENTRY; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirAllocateMemory( sizeof(BOOLEAN) * numAttrs, (PVOID*)&pbPresentList); BAIL_ON_VMDIR_ERROR(dwError); pOCAttr = _VmDirchemaCheckFindObjectClass(pCtx, pEntry); if (!pOCAttr || pOCAttr->numVals < 1) { pCtx->dwErrorCode = ERROR_INVALID_ENTRY; VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg); dwError = VmDirAllocateStringA("Entry has no objectclass",&pCtx->pszErrorMsg); dwError = ERROR_INVALID_ENTRY; BAIL_ON_VMDIR_ERROR(dwError); } dwError = _VmDirSchemaCheckEntryStructure( pCtx, pEntry, pOCAttr, pbPresentList); BAIL_ON_VMDIR_ERROR(dwError); { // all VDIR_ATTRIBUTE_USER_APPLICATION attribute should be marked PVDIR_ATTRIBUTE pAttr = NULL; for (usCnt = 0, pAttr = pEntry->attrs; usCnt < numAttrs; usCnt++, pAttr = pAttr->next) { if (!pbPresentList[usCnt] && pAttr->pATDesc->usage == VDIR_ATTRIBUTETYPE_USER_APPLICATIONS) { VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg); dwError = VmDirAllocateStringAVsnprintf( &pCtx->pszErrorMsg, "Attribute (%s) not allowed", VDIR_SAFE_STRING(pAttr->type.lberbv.bv_val)); dwError = pCtx->dwErrorCode = ERROR_INVALID_ENTRY; BAIL_ON_VMDIR_ERROR(dwError); } } } cleanup: VMDIR_SAFE_FREE_MEMORY(pbPresentList); return dwError; error: goto cleanup; }
/* * 1. entry must have one and only one structure object class (from same oc tree) * 2. auxiliary object class content rule compliance * 3. entry must have all MUST attributes * 4. entry may have allowed MAY attributes */ static DWORD _VmDirSchemaCheckEntryStructure( PVDIR_SCHEMA_CTX pCtx, PVDIR_ENTRY pEntry, PVDIR_ATTRIBUTE pOCAttr, BOOLEAN* pbPresentList ) { DWORD dwError = 0; unsigned int iCnt = 0; int iNumAuxOCs = 0; BOOLEAN bHasStructuralOC = FALSE; PVDIR_SCHEMA_OC_DESC pStructOCDesc = NULL; // leaf structural OC PVDIR_SCHEMA_OC_DESC* ppAuxOCDesc = NULL; assert(pCtx && pEntry && pOCAttr && pbPresentList); dwError = VmDirAllocateMemory( sizeof(PVDIR_SCHEMA_OC_DESC*) * (pOCAttr->numVals), (PVOID)&ppAuxOCDesc); BAIL_ON_VMDIR_ERROR(dwError); // walk through objectclass value to collect structure and aux ocs info for (iCnt = 0; iCnt < pOCAttr->numVals; iCnt++) { PVDIR_SCHEMA_OC_DESC pOCDesc = _VmDirSchemaCheckOCDescLookup(pCtx, pOCAttr->vals[iCnt].lberbv.bv_val); if (!pOCDesc) { VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg); VmDirAllocateStringAVsnprintf( &pCtx->pszErrorMsg, "Objectclass (%s) is not defined in schema", VDIR_SAFE_STRING(pOCAttr->vals[iCnt].lberbv.bv_val)); VmDirLog( LDAP_DEBUG_ANY, "schemaCheckStructure: (%s)", VDIR_SAFE_STRING(pCtx->pszErrorMsg)); dwError = pCtx->dwErrorCode = ERROR_INVALID_ENTRY; BAIL_ON_VMDIR_ERROR(dwError); } switch (pOCDesc->type) { case VDIR_OC_STRUCTURAL: bHasStructuralOC = TRUE; if (!pStructOCDesc) { pStructOCDesc = pOCDesc; pEntry->pszStructureOC = pOCAttr->vals[iCnt].lberbv.bv_val; } else { // make sure they are from the same structure tree PVDIR_SCHEMA_OC_DESC pTmpOCDesc = pStructOCDesc; for (; pTmpOCDesc; pTmpOCDesc = pTmpOCDesc->pStructSupOC) { if (pTmpOCDesc == pOCDesc) { break; } } if (!pTmpOCDesc) // pOCDesc is NOT ancestor of pStructOCDesc { for (pTmpOCDesc = pOCDesc; pTmpOCDesc; pTmpOCDesc = pTmpOCDesc->pStructSupOC) { if (pTmpOCDesc == pStructOCDesc) { // reset pStructOCDesc pStructOCDesc = pOCDesc; pEntry->pszStructureOC = pOCAttr->vals[iCnt].lberbv.bv_val; break; } } } if (!pTmpOCDesc) { VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg); VmDirAllocateStringAVsnprintf( &pCtx->pszErrorMsg, "Entry can have only one structure objectclass.", VDIR_SAFE_STRING(pOCDesc->pszName)); dwError = pCtx->dwErrorCode = ERROR_INVALID_ENTRY; BAIL_ON_VMDIR_ERROR(dwError); } } break; case VDIR_OC_AUXILIARY: ppAuxOCDesc[iNumAuxOCs] = pOCDesc; iNumAuxOCs++; break; default: // ABSTRACT object class break; } } // must have one structure oc if (bHasStructuralOC == FALSE) { VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg); VmDirAllocateStringA( "Entry has no structural objectclass", &pCtx->pszErrorMsg); dwError = pCtx->dwErrorCode = ERROR_INVALID_ENTRY; BAIL_ON_VMDIR_ERROR(dwError); } // enforce obejctclass value storing order structureOC->parentOC->...->TOP(not included)->AUXOC.... dwError = _VmDirSchemaReorderObjectClassAttr( pOCAttr, pStructOCDesc, ppAuxOCDesc); BAIL_ON_VMDIR_ERROR(dwError); // enforce nameform (RDN) dwError = _VmDirSchemaCheckNameform( pCtx, pEntry, pStructOCDesc); BAIL_ON_VMDIR_ERROR(dwError); // content rule auxiliary constraint check if (iNumAuxOCs > 0) { dwError = _VmDirSchemaCheckContentRuleAuxOC( pCtx, pStructOCDesc, ppAuxOCDesc); BAIL_ON_VMDIR_ERROR(dwError); } { // must attributes check dwError = _VmDirSchemaCheckMustAttrPresent( pCtx, pStructOCDesc, pEntry, pbPresentList); BAIL_ON_VMDIR_ERROR(dwError); for (iCnt = 0; ppAuxOCDesc[iCnt]; iCnt++) { dwError = _VmDirSchemaCheckMustAttrPresent( pCtx, ppAuxOCDesc[iCnt], pEntry, pbPresentList); BAIL_ON_VMDIR_ERROR(dwError); } } { // may attributes check dwError = _VmDirSchemaCheckMayAttrPresent( pCtx, pStructOCDesc->ppAllMayATs, pEntry, pbPresentList); BAIL_ON_VMDIR_ERROR(dwError); for (iCnt = 0; ppAuxOCDesc[iCnt]; iCnt++) { dwError = _VmDirSchemaCheckMayAttrPresent( pCtx, ppAuxOCDesc[iCnt]->ppAllMayATs, pEntry, pbPresentList); BAIL_ON_VMDIR_ERROR(dwError); } } cleanup: VMDIR_SAFE_FREE_MEMORY(ppAuxOCDesc); return dwError; error: goto cleanup; }
/* * Per structure objectclass, verify contentrule auxiliary object class */ static DWORD _VmDirSchemaCheckContentRuleAuxOC( PVDIR_SCHEMA_CTX pCtx, PVDIR_SCHEMA_OC_DESC pStructureOCDesc, PVDIR_SCHEMA_OC_DESC* ppAuxOCDesc ) { DWORD dwError = 0; int iCnt = 0; BOOLEAN bHasAllowedAuxOC = FALSE; assert(pCtx && pStructureOCDesc && ppAuxOCDesc); if (pCtx->pSchema->contentRules.usNumContents == 0) { // schema no content rule support goto cleanup; } bHasAllowedAuxOC = pStructureOCDesc->ppAllowedAuxOCs ? TRUE : FALSE; if (!bHasAllowedAuxOC && ppAuxOCDesc[0]) { // entry structure oc has NO allowedAuxOCs but entry now has aux ocs dwError = ERROR_INVALID_ENTRY; BAIL_ON_VMDIR_ERROR(dwError); } for (; ppAuxOCDesc[iCnt]; iCnt++) { int iIdx = 0; for (;pStructureOCDesc->ppAllowedAuxOCs[iIdx]; iIdx++) { if (pStructureOCDesc->ppAllowedAuxOCs[iIdx] == ppAuxOCDesc[iCnt]) { break; } } if (pStructureOCDesc->ppAllowedAuxOCs[iIdx] == NULL) { // entry aux oc not found in allowed list from content rule dwError = ERROR_INVALID_ENTRY; BAIL_ON_VMDIR_ERROR(dwError); } } cleanup: return dwError; error: pCtx->dwErrorCode = ERROR_INVALID_ENTRY; VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg); VmDirAllocateStringAVsnprintf( &pCtx->pszErrorMsg, "Aux objectclass (%s) is not allowed.", VDIR_SAFE_STRING(ppAuxOCDesc[iCnt]->pszName)); VmDirLog( LDAP_DEBUG_ANY, "%s", VDIR_SAFE_STRING(pCtx->pszErrorMsg)); goto cleanup; }
static DWORD _VmDirSchemaCheckSyntaxAndDimension( PVDIR_SCHEMA_CTX pCtx, PVDIR_ENTRY pEntry ) { DWORD dwError = 0; VDIR_ATTRIBUTE* pAttr = NULL; for (pAttr = pEntry->attrs; pAttr; pAttr = pAttr->next) { USHORT usCnt = 0; if (pAttr->pATDesc->bSingleValue && pAttr->numVals != 1) { pCtx->dwErrorCode = ERROR_INVALID_ENTRY; VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg); dwError = VmDirAllocateStringAVsnprintf( &pCtx->pszErrorMsg, "Attribute (%s) can have at most one value", VDIR_SAFE_STRING(pAttr->type.lberbv.bv_val)); dwError = ERROR_INVALID_ENTRY; BAIL_ON_VMDIR_ERROR(dwError); } for (usCnt = 0; usCnt < pAttr->numVals; usCnt++) { if (pAttr->pATDesc->uiMaxSize > 0) { //TODO, for server control/manipulate attribute, we should exclude this restriction // as they no longer in their original form. (e.g. userPassword) if (pAttr->vals[usCnt].lberbv.bv_len > pAttr->pATDesc->uiMaxSize) { VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg); VmDirAllocateStringAVsnprintf( // ignore error &pCtx->pszErrorMsg, "Attribute (%s) value too long, max (%d) allowed.", VDIR_SAFE_STRING(pAttr->type.lberbv.bv_val), pAttr->pATDesc->uiMaxSize); dwError = pCtx->dwErrorCode = LDAP_CONSTRAINT_VIOLATION; BAIL_ON_VMDIR_ERROR(dwError); } } dwError = VmDirSchemaBervalSyntaxCheck( pCtx, pAttr->pATDesc, &pAttr->vals[usCnt]); BAIL_ON_VMDIR_ERROR(dwError); } } cleanup: return dwError; error: VmDirLog( LDAP_DEBUG_ANY, "%s", VDIR_SAFE_STRING(pCtx->pszErrorMsg)); goto cleanup; }
/* * Entry schema check dit structure rule */ DWORD VmDirSchemaCheckDITStructure( PVDIR_SCHEMA_CTX pCtx, PVDIR_ENTRY pParentEntry, PVDIR_ENTRY pEntry ) { DWORD dwError = 0; unsigned int iCnt = 0; BOOLEAN bParentAllowed = FALSE; PVDIR_ATTRIBUTE pParentOCAttr = NULL; PVDIR_SCHEMA_OC_DESC pStructureOCDesc = NULL; VDIR_SCHEMA_OC_DESC ocKey = {0}; assert(pCtx && pEntry); // BUBBUG - bypass checking until we define castle structure rules goto cleanup; if (pCtx->pSchema->structureRules.usNumStructures == 0) { // schema has no structure rule defined goto cleanup; } if (!pEntry->pszStructureOC) { VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg); dwError = VmDirAllocateStringAVsnprintf( &pCtx->pszErrorMsg, "Entry has no structure objectclass/pszStructureOC."); dwError = pCtx->dwErrorCode = ERROR_INVALID_ENTRY; BAIL_ON_VMDIR_ERROR(dwError); } ocKey.pszName = pEntry->pszStructureOC; pStructureOCDesc = (PVDIR_SCHEMA_OC_DESC) bsearch( &ocKey, pCtx->pSchema->ocs.pOCSortName, pCtx->pSchema->ocs.usNumOCs, sizeof(VDIR_SCHEMA_OC_DESC), VdirSchemaPOCNameCmp); if (!pStructureOCDesc) { VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg); dwError = VmDirAllocateStringAVsnprintf( &pCtx->pszErrorMsg, "Structure oc (%s) not defined.", VDIR_SAFE_STRING(pEntry->pszStructureOC)); dwError = pCtx->dwErrorCode = ERROR_INVALID_ENTRY; BAIL_ON_VMDIR_ERROR(dwError); } if (pParentEntry) { pParentOCAttr = _VmDirchemaCheckFindObjectClass(pCtx, pParentEntry); } if (pParentOCAttr) { if (pStructureOCDesc->ppszAllowedParentOCs) { // loop through parent object class to check allowedParentsOCs //TODO, we can arrange structure object class to be the first to eliminate loop. for (iCnt = 0; iCnt < pParentOCAttr->numVals; iCnt++) { int iIdx = 0; for (;pStructureOCDesc->ppszAllowedParentOCs[iIdx]; iIdx++) { if (VmDirStringCompareA(pParentOCAttr->vals[iCnt].lberbv.bv_val, pStructureOCDesc->ppszAllowedParentOCs[iIdx], FALSE) == 0) { // allowed under this parent bParentAllowed = TRUE; break; } } if (pStructureOCDesc->ppszAllowedParentOCs[iIdx] != NULL) { break; } } } } else { if (pStructureOCDesc->bAllowedParentRoot == TRUE) { // allowed under root bParentAllowed = TRUE; } } if (!bParentAllowed) { VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg); dwError = VmDirAllocateStringAVsnprintf( &pCtx->pszErrorMsg, "(%s) not allowed under its parent", VDIR_SAFE_STRING(pEntry->pszStructureOC)); dwError = pCtx->dwErrorCode = ERROR_INVALID_ENTRY; BAIL_ON_VMDIR_ERROR(dwError); } cleanup: return dwError; error: goto cleanup; }
/* * Tweak indices entry to append building flag to newly added values. * e.g. user add a new index attribute "myuid eq unique" * we want to save it as "myuid eq unique (buildingflag)" instead. */ DWORD VdirIndexingEntryAppendFlag( VDIR_MODIFICATION* pMods, PVDIR_ENTRY pEntry) { DWORD dwError = 0; DWORD dwCnt = 0; PSTR pszNewStr = NULL; PVDIR_ATTRIBUTE pAttr = NULL; assert(pMods && pEntry && pEntry->allocType == ENTRY_STORAGE_FORMAT_NORMAL); // unpack entry, so we can manipulate its contents. dwError = VmDirEntryUnpack(pEntry); BAIL_ON_VMDIR_ERROR(dwError); pAttr = VmDirFindAttrByName(pEntry, ATTR_INDEX_DESC); if (!pAttr) { dwError = ERROR_INVALID_ENTRY; BAIL_ON_VMDIR_ERROR(dwError); } for (dwCnt = 0; dwCnt < pAttr->numVals; dwCnt++) { DWORD iIdx = 0; for (iIdx = 0; iIdx < pMods->attr.numVals; iIdx++) { if (0 == VmDirStringCompareA(pAttr->vals[dwCnt].lberbv.bv_val, pMods->attr.vals[iIdx].lberbv.bv_val, FALSE)) { dwError = VmDirAllocateStringAVsnprintf( &pszNewStr, "%s %s", pAttr->vals[dwCnt].lberbv.bv_val, ATTR_INDEX_BUILDING_FLAG); BAIL_ON_VMDIR_ERROR(dwError); VmDirFreeBervalArrayContent(&pAttr->vals[dwCnt], 1); pAttr->vals[dwCnt].lberbv.bv_val = pszNewStr; pszNewStr = NULL; pAttr->vals[dwCnt].bOwnBvVal = TRUE; pAttr->vals[dwCnt].lberbv.bv_len = VmDirStringLenA(pAttr->vals[dwCnt].lberbv.bv_val); dwError = VmDirSchemaBervalNormalize( pEntry->pSchemaCtx, pAttr->pATDesc, &pAttr->vals[dwCnt]); BAIL_ON_VMDIR_ERROR(dwError); } } } cleanup: return dwError; error: VMDIR_SAFE_FREE_MEMORY(pszNewStr); goto cleanup; }
static DWORD _VmDirSASLGetCtxProps( PVDIR_SASL_BIND_INFO pSaslBindInfo ) { DWORD dwError = 0; PCSTR pszBindUPN = NULL; PCSTR pszBindRealm = NULL; sasl_ssf_t* pLocalSaslSSF = NULL; // pSaslCtx owns pszBindUPN dwError = sasl_getprop(pSaslBindInfo->pSaslCtx, SASL_USERNAME, (const void**)&pszBindUPN); BAIL_ON_SASL_ERROR(dwError); // pSaslCtx owns pszBindRealm dwError = sasl_getprop(pSaslBindInfo->pSaslCtx, SASL_DEFUSERREALM, (const void**)&pszBindRealm); BAIL_ON_SASL_ERROR(dwError); ////////////////////////////////////////////////////////////////////////////////////////////// // BUGBUG, Not clear how to get the realm part in GSSAPI bind. // BUGBUG, In this case SASL_USERNAME has NO realm portion and SASL_DEFUSERREALM is NULL. // BUGBUG, Thus, use gVmdirKrbGlobals.pszRealm for now. // BUGBUG, This will not work if we have to support multiple realms scenario. ////////////////////////////////////////////////////////////////////////////////////////////// // In SRP case, SASL_USERNAME has full UPN and SASL_DEFUSERREALM is NULL. ////////////////////////////////////////////////////////////////////////////////////////////// if ( pszBindRealm == NULL && VmDirStringCompareA( pSaslBindInfo->bvMechnism.lberbv.bv_val, SASL_GSSAPI_MECH, FALSE ) == 0 ) { pszBindRealm = gVmdirKrbGlobals.pszRealm; } VMDIR_SAFE_FREE_MEMORY( pSaslBindInfo->pszBindUserName ); dwError = VmDirAllocateStringAVsnprintf( &pSaslBindInfo->pszBindUserName, "%s%s%s", VDIR_SAFE_STRING(pszBindUPN), pszBindRealm ? "@" : "", VDIR_SAFE_STRING(pszBindRealm)); BAIL_ON_VMDIR_ERROR(dwError); dwError = sasl_getprop( pSaslBindInfo->pSaslCtx, SASL_SSF, (const void**)&pLocalSaslSSF ); BAIL_ON_SASL_ERROR(dwError); pSaslBindInfo->saslSSF = *pLocalSaslSSF; cleanup: return dwError; error: goto cleanup; sasl_error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "_VmDirSASLGetCtxProps: sasl error (%d)(%s)", dwError, VDIR_SAFE_STRING(sasl_errdetail(pSaslBindInfo->pSaslCtx)) ); dwError = _VmDirSASLToLDAPError(dwError); goto error; }