VOID VdcadminSetSRPAuthData( VOID ) { CHAR inBuf[512] = {0}; DWORD dwError = 0; if (pszUserName) { free(pszUserName); } if (pszDomain) { free(pszDomain); } if (pszPassword) { free(pszPassword); } VmDirReadString( "VMDIR IP address: ", inBuf, sizeof(inBuf), FALSE); if (inBuf[0]) { pszNetworkAddress = strdup(inBuf); } VmDirReadString( "SRP Username: "******"SRP Domain: ", inBuf, sizeof(inBuf), FALSE); if (inBuf[0]) { pszDomain = strdup(inBuf); } VmDirReadString( "SRP Password: "******"VmDirCreateBindingHandleAuthA: failed %x\n", dwError); } dwError = VmDirOpenServerA( pszNetworkAddress, pszUserName, pszDomain, pszPassword, 0, NULL, &g_hServer); if (dwError) { printf("VmDirOpenServerA: failed %x\n", dwError); } }
static OM_uint32 _srp_gss_auth_init( OM_uint32 *minor_status, srp_gss_ctx_id_t srp_context_handle, int state, gss_buffer_t input_token, gss_buffer_t output_token) { ber_tag_t ber_state = 0; struct berval ber_ctx = {0}; struct berval *ber_upn = NULL; struct berval *ber_bytes_A = NULL; struct berval ber_salt = {0}; struct berval ber_mda = {0}; struct berval ber_B = {0}; struct berval *flatten = NULL; BerElement *ber = NULL; BerElement *ber_resp = NULL; int berror = 0; int sts = 0; OM_uint32 maj = 0; OM_uint32 min = 0; OM_uint32 min_tmp = 0; gss_buffer_desc tmp_in_tok = {0}; gss_buffer_desc disp_name_buf = {0}; gss_buffer_t disp_name = NULL; gss_OID disp_name_OID = NULL; char *srp_upn_name = NULL; int srp_decode_mda_len = 0; int srp_decode_salt_len = 0; const unsigned char *srp_mda = NULL; const unsigned char *srp_salt = NULL; SRP_HashAlgorithm hash_alg = SRP_SHA1; SRP_NGType ng_type = SRP_NG_2048; struct SRPVerifier *ver = NULL; const unsigned char *srp_bytes_B = NULL; int srp_bytes_B_len = 0; const unsigned char *srp_session_key = NULL; unsigned char *ret_srp_session_key = NULL; int srp_session_key_len = 0; ber_int_t gss_srp_version_maj = 0; ber_int_t gss_srp_version_min = 0; PVMDIR_SERVER_CONTEXT hServer = NULL; srp_verifier_handle_t hSrp = NULL; /* aliased / cast to "ver" variable */ srp_secret_blob_data srp_data = {0}; int bUseCSRP = 0; /* Use CRP library directly */ ber_ctx.bv_val = (void *) input_token->value; ber_ctx.bv_len = input_token->length; ber = ber_init(&ber_ctx); if (!ber) { maj = GSS_S_FAILURE; goto error; } srp_debug_printf("_srp_gss_auth_init(): state=SRP_AUTH_INIT\n"); /* * ptr points to ASN.1 encoded data which is dependent on the authentication * state. The appropriate decoder format string is applied for each state */ berror = ber_scanf(ber, "t{ii", &ber_state, &gss_srp_version_maj, &gss_srp_version_min); if (berror == -1) { srp_debug_printf("_srp_gss_auth_init() ber_scanf(t{ii): failed berror=%d\n", berror); maj = GSS_S_FAILURE; goto error; } berror = ber_scanf(ber, "OO}", &ber_upn, &ber_bytes_A); if (berror == -1) { srp_debug_printf("_srp_gss_auth_init() ber_scanf(OO): failed berror=%d\n", berror); maj = GSS_S_FAILURE; goto error; } srp_debug_printf("_srp_gss_auth_init(accept_sec_context): protocol version %d.%d\n", gss_srp_version_maj, gss_srp_version_min); srp_print_hex(ber_bytes_A->bv_val, (int) ber_bytes_A->bv_len, "_srp_gss_auth_init(accept_sec_context): bytes_A"); /* * This is mostly impossible, as state IS the "t" field. * More a double check for proper decoding. */ if ((int) ber_state != state) { maj = GSS_S_FAILURE; goto error; } tmp_in_tok.value = ber_upn->bv_val; tmp_in_tok.length = ber_upn->bv_len; maj = gss_import_name(&min, &tmp_in_tok, NULL, &srp_context_handle->gss_upn_name); if (maj) { srp_debug_printf("_srp_gss_auth_init() gss_import_name failed maj=%d\n", maj); goto error; } maj = gss_display_name(&min, srp_context_handle->gss_upn_name, &disp_name_buf, &disp_name_OID); if (maj) { srp_debug_printf("_srp_gss_auth_init() gss_display_name failed maj=%d\n", maj); goto error; } disp_name = &disp_name_buf; srp_debug_printf("_srp_gss_auth_init() srp_gss_accept_sec_context: UPN name=%.*s\n", (int) disp_name_buf.length, (char *) disp_name_buf.value); srp_upn_name = calloc(disp_name_buf.length + 1, sizeof(char)); if (!srp_upn_name) { maj = GSS_S_FAILURE; min = ENOMEM; goto error; } snprintf(srp_upn_name, disp_name_buf.length+1, "%.*s", (int) disp_name_buf.length, (char *) disp_name_buf.value); maj = _srp_gss_auth_create_machine_acct_binding( &bUseCSRP, &min, &hServer); if (maj) { srp_debug_printf("_srp_gss_auth_init() _srp_gss_auth_create_machine_acct_binding failed maj=%d\n", maj); maj = GSS_S_FAILURE; goto error; } if (!bUseCSRP) { sts = cli_rpc_srp_verifier_new( hServer ? hServer->hBinding : NULL, hash_alg, ng_type, srp_upn_name, ber_bytes_A->bv_val, (int) ber_bytes_A->bv_len, &srp_bytes_B, &srp_bytes_B_len, &srp_salt, &srp_decode_salt_len, &srp_mda, &srp_decode_mda_len, NULL, NULL, /* n_hex, g_hex */ &hSrp); if (sts) { srp_debug_printf("_srp_gss_auth_init() cli_rpc_srp_verifier_new: failed sts=%d\n", sts); maj = GSS_S_FAILURE; min = sts; goto error; } ver = (struct SRPVerifier *) hSrp, hSrp = NULL; } else { sts = _get_srp_secret_decoded( srp_upn_name, &srp_data); if (sts) { srp_debug_printf("_srp_gss_auth_init() _get_srp_secret_decoded: failed sts=%d\n", sts); maj = GSS_S_FAILURE; min = sts; goto error; } /* Call SRP library implementation directly */ ver = srp_verifier_new(hash_alg, ng_type, srp_upn_name, /* SRP Salt value */ srp_data.salt, srp_data.salt_len, /* SRP "V" verifier secret */ srp_data.v, srp_data.v_len, /* SRP bytes_A */ ber_bytes_A->bv_val, (int) ber_bytes_A->bv_len, /* SRP bytes B */ &srp_bytes_B, &srp_bytes_B_len, /* SRP n_hex / g_hex */ NULL, NULL); if (!ver) { srp_debug_printf("_srp_gss_auth_init() srp_verifier_new: failed sts=%d\n", sts); maj = GSS_S_FAILURE; goto error; } srp_salt = srp_data.salt; srp_decode_salt_len = srp_data.salt_len; } if (!srp_bytes_B) { srp_debug_printf("_srp_gss_auth_init() srp_verifier_new: failed!\n"); maj = GSS_S_FAILURE; goto error; } srp_print_hex(srp_salt, srp_decode_salt_len, "_srp_gss_auth_init(accept_sec_context): srp_salt value"); srp_print_hex(srp_bytes_B, srp_bytes_B_len, "_srp_gss_auth_init(accept_sec_context): srp_B value"); ber_mda.bv_val = (unsigned char *) srp_mda; ber_mda.bv_len = srp_decode_mda_len; ber_salt.bv_val = (unsigned char *) srp_salt; ber_salt.bv_len = srp_decode_salt_len; /* * B is computed: (kv + g**b) % N */ ber_B.bv_val = (void *) srp_bytes_B; ber_B.bv_len = srp_bytes_B_len; ber_resp = ber_alloc_t(LBER_USE_DER); if (!ber_resp) { maj = GSS_S_FAILURE; min = ENOMEM; goto error; } /* * Response format: * tag | MDA | salt | B */ berror = ber_printf(ber_resp, "t{OOO}", SRP_AUTH_SALT_RESP, &ber_mda, &ber_salt, &ber_B); if (berror == -1) { srp_debug_printf("_srp_gss_auth_init() ber_printf: failed berror=%d\n", berror); maj = GSS_S_FAILURE; goto error; } berror = ber_flatten(ber_resp, &flatten); if (berror == -1) { srp_debug_printf("_srp_gss_auth_init() ber_flatten: failed berror=%d\n", berror); maj = GSS_S_FAILURE; goto error; } output_token->value = gssalloc_calloc(1, flatten->bv_len); if (!output_token->value) { maj = GSS_S_FAILURE; goto error; } output_token->length = flatten->bv_len; memcpy(output_token->value, flatten->bv_val, flatten->bv_len); if (bUseCSRP) { srp_session_key = srp_verifier_get_session_key(ver, &srp_session_key_len); } else { sts = cli_rpc_srp_verifier_get_session_key( hServer ? hServer->hBinding : NULL, ver, &srp_session_key, &srp_session_key_len); if (sts) { min = sts; maj = GSS_S_FAILURE; goto error; } } if (srp_session_key && srp_session_key_len > 0) { ret_srp_session_key = calloc(srp_session_key_len, sizeof(unsigned char)); if (!ret_srp_session_key) { maj = GSS_S_FAILURE; min = ENOMEM; goto error; } } memcpy(ret_srp_session_key, srp_session_key, srp_session_key_len); /* Set context handle/return values here; all previous calls succeeded */ maj = GSS_S_CONTINUE_NEEDED; srp_context_handle->hServer = hServer, hServer = NULL; /* Used in generating Kerberos keyblock salt value */ srp_context_handle->upn_name = srp_upn_name, srp_upn_name = NULL; srp_context_handle->srp_ver = ver, ver = NULL; /* Return the SRP session key in the context handle */ srp_context_handle->srp_session_key_len = srp_session_key_len; srp_context_handle->srp_session_key = ret_srp_session_key, ret_srp_session_key = NULL; srp_context_handle->bUseCSRP = bUseCSRP; srp_print_hex(srp_session_key, srp_session_key_len, "_srp_gss_auth_init(accept_sec_ctx) got session key"); error: if (ver) { if (bUseCSRP) { srp_verifier_delete(ver); } else { cli_rpc_srp_verifier_delete( hServer ? hServer->hBinding : NULL, (void **) &ver); } } VmDirCloseServer(hServer); if (srp_upn_name) { free(srp_upn_name); } if (ber_upn) { ber_bvfree(ber_upn); } if (ber_bytes_A) { ber_bvfree(ber_bytes_A); } ber_bvfree(flatten); ber_free(ber, 1); ber_free(ber_resp, 1); if (disp_name) { gss_release_buffer(&min_tmp, disp_name); } if (!bUseCSRP && srp_bytes_B) { free((void *) srp_bytes_B); } if (!bUseCSRP && srp_salt) { free((void *) srp_salt); } if (srp_mda) { free((void *) srp_mda); } if (!bUseCSRP && srp_session_key) { free((void *) srp_session_key); } if (bUseCSRP) { _free_srp_secret_decoded(&srp_data); } if (ret_srp_session_key) { free((void *) ret_srp_session_key); } if (maj) { if (min) { *minor_status = min; } } return maj; }
static int _VmDirGetRemoteDBUsingRPC( PCSTR pszHostname, PCSTR dbHomeDir, BOOLEAN *pbHasXlog) { DWORD retVal = 0; PSTR pszLocalErrorMsg = NULL; char dbRemoteFilename[VMDIR_MAX_FILE_NAME_LEN] = {0}; char localDir[VMDIR_MAX_FILE_NAME_LEN] = {0}; char localXlogDir[VMDIR_MAX_FILE_NAME_LEN] = {0}; char localFilename[VMDIR_MAX_FILE_NAME_LEN] = {0}; PSTR pszDcAccountPwd = NULL; PVMDIR_SERVER_CONTEXT hServer = NULL; DWORD low_xlognum = 0; DWORD high_xlognum = 0; DWORD xlognum = 0; DWORD remoteDbSizeMb = 0; DWORD remoteDbMapSizeMb = 0; PBYTE pDbPath = NULL; BOOLEAN bMdbWalEnable = FALSE; #ifndef _WIN32 const char fileSeperator = '/'; #else const char fileSeperator = '\\'; #endif retVal = VmDirAllocateMemory(VMDIR_MAX_FILE_NAME_LEN, (PVOID)&pDbPath ); BAIL_ON_VMDIR_ERROR(retVal); retVal = VmDirReadDCAccountPassword(&pszDcAccountPwd); BAIL_ON_VMDIR_ERROR( retVal ); retVal = VmDirOpenServerA(pszHostname, gVmdirServerGlobals.dcAccountUPN.lberbv_val, NULL, pszDcAccountPwd, 0, NULL, &hServer); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirGetRemoteDBUsingRPC: VmDirOpenServerA() call failed with error: %d, host name = %s", retVal, pszHostname ); VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "_VmDirGetRemoteDBUsingRPC: Connected to the replication partner (%s).", pszHostname ); VmDirGetMdbWalEnable(&bMdbWalEnable); if (bMdbWalEnable) { //Set remote server backend to KEEPXLOGS mode retVal = VmDirSetBackendState (hServer, MDB_STATE_KEEPXLOGS, &low_xlognum, &remoteDbSizeMb, &remoteDbMapSizeMb, pDbPath, VMDIR_MAX_FILE_NAME_LEN); } else { //Set remote server backend to ReadOnly mode retVal = VmDirSetBackendState (hServer, MDB_STATE_READONLY, &low_xlognum, &remoteDbSizeMb, &remoteDbMapSizeMb, pDbPath, VMDIR_MAX_FILE_NAME_LEN); } BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg), "_VmDirGetRemoteDBUsingRPC: VmDirSetBackendState failed, WalEnabled: %d, error: %d", bMdbWalEnable, retVal); retVal = VmDirStringPrintFA( localDir, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s", dbHomeDir, fileSeperator, LOCAL_PARTNER_DIR); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirGetRemoteDBUsingRPC: VmDirStringPrintFA() call failed with error: %d", retVal ); retVal = _VmDirMkdir(localDir, 0700); BAIL_ON_VMDIR_ERROR( retVal ); if (low_xlognum > 0) { retVal = VmDirStringPrintFA( localXlogDir, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s", localDir, fileSeperator, VMDIR_MDB_XLOGS_DIR_NAME); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirGetRemoteDBUsingRPC: VmDirStringPrintFA() call failed with error: %d", retVal ); retVal = _VmDirMkdir(localXlogDir, 0700); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirGetRemoteDBUsingRPC: _VmDirMkdir() call failed with error: %d %s", retVal ); } retVal = VmDirStringPrintFA( dbRemoteFilename, VMDIR_MAX_FILE_NAME_LEN, "%s/%s", (char *)pDbPath, VMDIR_MDB_DATA_FILE_NAME ); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirGetRemoteDBUsingRPC: VmDirStringPrintFA() call failed with error: %d", retVal ); retVal = VmDirStringPrintFA( localFilename, 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), "_VmDirGetRemoteDBUsingRPC: VmDirStringPrintFA() call failed with error: %d", retVal ); VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "_VmDirGetRemoteDBUsingRPC: copying remote file %s with data size %ld MB with Map size %ld MB ...", dbRemoteFilename, remoteDbSizeMb, remoteDbMapSizeMb ); retVal = _VmDirGetRemoteDBFileUsingRPC( hServer, dbRemoteFilename, localFilename, remoteDbSizeMb, remoteDbMapSizeMb ); BAIL_ON_VMDIR_ERROR( retVal ); if (low_xlognum == 0) { VMDIR_LOG_INFO(VMDIR_LOG_MASK_ALL, "_VmDirGetRemoteDBUsingRPC: complete MDB cold copy - WAL not supported by remote"); goto cleanup; } //Query current xlog number retVal = VmDirSetBackendState (hServer, MDB_STATE_GETXLOGNUM, &high_xlognum, &remoteDbSizeMb, &remoteDbMapSizeMb, pDbPath, VMDIR_MAX_FILE_NAME_LEN); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirGetRemoteDBUsingRPC: VmDirSetBackendState failed to get current xlog: %d", retVal ); VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "_VmDirGetRemoteDBUsingRPC: start transfering XLOGS from %d to %d", low_xlognum, high_xlognum); for (xlognum = low_xlognum; xlognum <= high_xlognum; xlognum++) { retVal = VmDirStringPrintFA( dbRemoteFilename, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s%c%lu", dbHomeDir, fileSeperator, VMDIR_MDB_XLOGS_DIR_NAME, fileSeperator, xlognum ); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirGetRemoteDBUsingRPC: VmDirStringPrintFA() call failed with error: %d", retVal ); retVal = VmDirStringPrintFA( localFilename, VMDIR_MAX_FILE_NAME_LEN, "%s%c%lu", localXlogDir, fileSeperator, xlognum); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirGetRemoteDBUsingRPC: VmDirStringPrintFA() call failed with error: %d", retVal ); retVal = _VmDirGetRemoteDBFileUsingRPC( hServer, dbRemoteFilename, localFilename, 0, 0); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirGetRemoteDBUsingRPC: _VmDirGetRemoteDBFileUsingRPC() call failed with error: %d", retVal ); } VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "_VmDirGetRemoteDBUsingRPC: complete transfering XLOGS from %d to %d", low_xlognum, high_xlognum); cleanup: if (hServer) { //clear backend transfering xlog files mode. VmDirSetBackendState (hServer, MDB_STATE_CLEAR, &xlognum, &remoteDbSizeMb, &remoteDbMapSizeMb, pDbPath, VMDIR_MAX_FILE_NAME_LEN); VmDirCloseServer( hServer); } VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg); VMDIR_SAFE_FREE_MEMORY(pDbPath); VMDIR_SECURE_FREE_STRINGA(pszDcAccountPwd); *pbHasXlog = (low_xlognum > 0); return retVal; error: retVal = LDAP_OPERATIONS_ERROR; VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s", VDIR_SAFE_STRING(pszLocalErrorMsg) ); goto cleanup; }
OM_uint32 srp_gss_accept_sec_context( OM_uint32 *minor_status, gss_ctx_id_t *context_handle, gss_cred_id_t verifier_cred_handle, gss_buffer_t input_token, gss_channel_bindings_t input_chan_bindings, gss_name_t *src_name, gss_OID *mech_type, gss_buffer_t output_token, OM_uint32 *ret_flags, OM_uint32 *time_rec, gss_cred_id_t *delegated_cred_handle) { int oid_len = 0; int state = 0; srp_gss_cred_id_t srp_cred = NULL; unsigned char *ptr = NULL; int ptr_len = 0; OM_uint32 maj = 0; OM_uint32 min = 0; OM_uint32 tmp_maj = 0; OM_uint32 tmp_min = 0; gss_buffer_desc input_token_srp = {0}; srp_gss_ctx_id_t srp_context_handle = NULL; krb5_error_code krb5_err = 0; gss_cred_id_t srp_cred_handle = NULL; if (minor_status == NULL || output_token == GSS_C_NO_BUFFER || context_handle == NULL) { return GSS_S_CALL_INACCESSIBLE_WRITE; } if (input_token == GSS_C_NO_BUFFER) { return GSS_S_CALL_INACCESSIBLE_READ; } if (minor_status) { *minor_status = 0; } if (output_token != GSS_C_NO_BUFFER) { output_token->length = 0; output_token->value = NULL; } if (!context_handle) { maj = GSS_S_FAILURE; goto error; } if (*context_handle) { srp_context_handle = (srp_gss_ctx_id_t) *context_handle; } else { /* First call, allocate context handle */ srp_context_handle = (srp_gss_ctx_id_t) calloc(1, sizeof(srp_gss_ctx_id_rec)); if (!srp_context_handle) { min = ENOMEM; maj = GSS_S_FAILURE; goto error; } memset(srp_context_handle, 0, sizeof(srp_gss_ctx_id_rec)); /* Needed for Kerberos AES256-SHA1 keyblock generation */ krb5_err = krb5_init_context(&srp_context_handle->krb5_ctx); if (krb5_err) { maj = GSS_S_FAILURE; min = krb5_err; goto error; } maj = srp_gss_acquire_cred( &min, GSS_C_NO_NAME, 0, NULL, GSS_C_ACCEPT, &srp_cred_handle, NULL, NULL); if (maj) { goto error; } srp_cred = (srp_gss_cred_id_t) srp_cred_handle; srp_context_handle->magic_num = SRP_MAGIC_ID; maj = srp_gss_duplicate_oid(&min, srp_cred->srp_mech_oid, &srp_context_handle->mech); if (maj) { goto error; } srp_context_handle->state = SRP_AUTH_INIT; srp_context_handle->cred = (srp_gss_cred_id_t) verifier_cred_handle; *context_handle = (gss_ctx_id_t) srp_context_handle; } ptr = (unsigned char*) input_token->value; ptr_len = (int) input_token->length; maj = srp_gss_validate_oid_header( &min, input_token, &oid_len); if (maj) { goto error; } ptr += oid_len; ptr_len -= oid_len; input_token_srp.value = ptr; input_token_srp.length = ptr_len; /* This is the "t" field of ber_scanf() */ state = SRP_AUTH_STATE_VALUE(ptr[0]); /* Verify state machine is consistent with expected state */ state = SRP_AUTH_STATE_VALUE(ptr[0]); if (state != srp_context_handle->state) { maj = GSS_S_FAILURE; goto error; } switch(state) { case SRP_AUTH_INIT: srp_debug_printf("srp_gss_accept_sec_context: state=SRP_AUTH_INIT\n"); maj = _srp_gss_auth_init(minor_status, srp_context_handle, state, &input_token_srp, output_token); if (maj) { if (maj == GSS_S_CONTINUE_NEEDED) { srp_context_handle->state = SRP_AUTH_CLIENT_VALIDATE; } goto error; } break; case SRP_AUTH_CLIENT_VALIDATE: srp_debug_printf("srp_gss_accept_sec_context: " "state=SRP_AUTH_CLIENT_VALIDATE\n"); maj = _srp_gss_validate_client(minor_status, srp_context_handle, state, &input_token_srp, output_token); if (maj != GSS_S_CONTINUE_NEEDED && maj != GSS_S_COMPLETE) { /* Hard error occurred */ goto error; } srp_context_handle->state = SRP_AUTH_COMPLETE; if (mech_type) { /* The security mechanism with which the context was established. * If the security mechanism type is not required, specify NULL * for this parameter. The gss_OID value returned for this * parameter points to a read-only structure and must not be * released by the application. */ *mech_type = srp_context_handle->mech; } if (src_name) { /* Optional: Return UPN name to caller */ tmp_maj = gss_duplicate_name( &tmp_min, srp_context_handle->gss_upn_name, src_name); if (tmp_maj) { maj = tmp_maj; *minor_status = tmp_min; goto error; } } break; /* This should never happen, but include for completeness-sake */ case SRP_AUTH_COMPLETE: srp_debug_printf("srp_gss_accept_sec_context: " "state=SRP_AUTH_COMPLETE\n"); maj = GSS_S_COMPLETE; break; default: srp_debug_printf("srp_gss_accept_sec_context: state=UNKNOWN!!!\n"); maj = GSS_S_FAILURE; goto error; break; } if (srp_context_handle->state == SRP_AUTH_COMPLETE) { PVMDIR_SERVER_CONTEXT hServer = srp_context_handle->hServer; #ifdef SRP_FIPS_ENABLED krb5_err = srp_make_enc_keyblock_FIPS(srp_context_handle); #else krb5_err = srp_make_enc_keyblock(srp_context_handle); #endif if (krb5_err) { maj = GSS_S_FAILURE; min = krb5_err; goto error; } if (srp_context_handle->bUseCSRP) { srp_verifier_delete(srp_context_handle->srp_ver); } else { /* Clean up SRP server-side memory, then close the server context */ cli_rpc_srp_verifier_delete( hServer->hBinding, (void **) &srp_context_handle->srp_ver); VmDirCloseServer(hServer); srp_context_handle->hServer = NULL; } } error: if (maj != GSS_S_CONTINUE_NEEDED && maj != GSS_S_COMPLETE) { _srp_gss_accept_sec_ctx_error_resp( minor_status, output_token); } if (srp_cred_handle) { srp_gss_release_cred(&tmp_min, &srp_cred_handle); } return maj; }