static void test_cread_attrs(void) { SCHANNEL_CRED schannel_cred; SECURITY_STATUS status; CredHandle cred; status = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND, NULL, NULL, NULL, NULL, &cred, NULL); ok(status == SEC_E_OK, "AcquireCredentialsHandleA failed: %x\n", status); test_supported_protocols(&cred, 0); test_supported_algs(&cred); status = pQueryCredentialsAttributesA(&cred, SECPKG_ATTR_SUPPORTED_PROTOCOLS, NULL); ok(status == SEC_E_INTERNAL_ERROR, "QueryCredentialsAttributes failed: %08x, expected SEC_E_INTERNAL_ERROR\n", status); status = pQueryCredentialsAttributesA(&cred, SECPKG_ATTR_SUPPORTED_ALGS, NULL); ok(status == SEC_E_INTERNAL_ERROR, "QueryCredentialsAttributes failed: %08x, expected SEC_E_INTERNAL_ERROR\n", status); pFreeCredentialsHandle(&cred); init_cred(&schannel_cred); schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT; status = pAcquireCredentialsHandleA(NULL, unisp_name_a, SECPKG_CRED_OUTBOUND, NULL, &schannel_cred, NULL, NULL, &cred, NULL); ok(status == SEC_E_OK, "AcquireCredentialsHandleA failed: %x\n", status); test_supported_protocols(&cred, SP_PROT_TLS1_CLIENT); test_supported_algs(&cred); pFreeCredentialsHandle(&cred); }
/* * Create new allocation. */ PJ_DEF(pj_status_t) pj_turn_allocation_create(pj_turn_transport *transport, const pj_sockaddr_t *src_addr, unsigned src_addr_len, const pj_stun_rx_data *rdata, pj_stun_session *srv_sess, pj_turn_allocation **p_alloc) { pj_turn_srv *srv = transport->listener->server; const pj_stun_msg *msg = rdata->msg; pj_pool_t *pool; alloc_request req; pj_turn_allocation *alloc; pj_stun_session_cb sess_cb; char str_tmp[80]; pj_status_t status; /* Parse ALLOCATE request */ status = parse_allocate_req(&req, srv_sess, rdata, src_addr, src_addr_len); if (status != PJ_SUCCESS) return status; pool = pj_pool_create(srv->core.pf, "alloc%p", 1000, 1000, NULL); /* Init allocation structure */ alloc = PJ_POOL_ZALLOC_T(pool, pj_turn_allocation); alloc->pool = pool; alloc->obj_name = pool->obj_name; alloc->relay.tp.sock = PJ_INVALID_SOCKET; alloc->server = transport->listener->server; alloc->bandwidth = req.bandwidth; /* Set transport */ alloc->transport = transport; pj_turn_transport_add_ref(transport, alloc); alloc->hkey.tp_type = transport->listener->tp_type; pj_memcpy(&alloc->hkey.clt_addr, src_addr, src_addr_len); status = pj_lock_create_recursive_mutex(pool, alloc->obj_name, &alloc->lock); if (status != PJ_SUCCESS) { goto on_error; } /* Create peer hash table */ alloc->peer_table = pj_hash_create(pool, PEER_TABLE_SIZE); /* Create channel hash table */ alloc->ch_table = pj_hash_create(pool, PEER_TABLE_SIZE); /* Print info */ pj_ansi_strcpy(alloc->info, pj_turn_tp_type_name(transport->listener->tp_type)); alloc->info[3] = ':'; pj_sockaddr_print(src_addr, alloc->info+4, sizeof(alloc->info)-4, 3); /* Create STUN session to handle STUN communication with client */ pj_bzero(&sess_cb, sizeof(sess_cb)); sess_cb.on_send_msg = &stun_on_send_msg; sess_cb.on_rx_request = &stun_on_rx_request; sess_cb.on_rx_indication = &stun_on_rx_indication; status = pj_stun_session_create(&srv->core.stun_cfg, alloc->obj_name, &sess_cb, PJ_FALSE, NULL, &alloc->sess); if (status != PJ_SUCCESS) { goto on_error; } /* Attach to STUN session */ pj_stun_session_set_user_data(alloc->sess, alloc); /* Init authentication credential */ status = init_cred(alloc, msg); if (status != PJ_SUCCESS) { goto on_error; } /* Attach authentication credential to STUN session */ pj_stun_session_set_credential(alloc->sess, PJ_STUN_AUTH_LONG_TERM, &alloc->cred); /* Create the relay resource */ status = create_relay(srv, alloc, msg, &req, &alloc->relay); if (status != PJ_SUCCESS) { goto on_error; } /* Register this allocation */ pj_turn_srv_register_allocation(srv, alloc); /* Respond to ALLOCATE request */ status = send_allocate_response(alloc, srv_sess, transport, rdata); if (status != PJ_SUCCESS) goto on_error; /* Done */ pj_sockaddr_print(&alloc->relay.hkey.addr, str_tmp, sizeof(str_tmp), 3); PJ_LOG(4,(alloc->obj_name, "Client %s created, relay addr=%s:%s", alloc->info, pj_turn_tp_type_name(req.tp_type), str_tmp)); /* Success */ *p_alloc = alloc; return PJ_SUCCESS; on_error: /* Send reply to the ALLOCATE request */ pj_strerror(status, str_tmp, sizeof(str_tmp)); pj_stun_session_respond(srv_sess, rdata, PJ_STUN_SC_BAD_REQUEST, str_tmp, transport, PJ_TRUE, src_addr, src_addr_len); /* Cleanup */ destroy_allocation(alloc); return status; }
static void test_communication(void) { int ret; WSADATA wsa_data; SOCKET sock; struct hostent *host; struct sockaddr_in addr; SECURITY_STATUS status; ULONG attrs; SCHANNEL_CRED cred; CredHandle cred_handle; CtxtHandle context; SecPkgCredentials_NamesA names; SecPkgContext_StreamSizes sizes; SecPkgContext_ConnectionInfo conn_info; CERT_CONTEXT *cert; SecBufferDesc buffers[2]; SecBuffer *buf; unsigned buf_size = 4000; unsigned char *data; unsigned data_size; if (!pAcquireCredentialsHandleA || !pFreeCredentialsHandle || !pInitializeSecurityContextA || !pDeleteSecurityContext || !pQueryContextAttributesA || !pDecryptMessage || !pEncryptMessage) { skip("Required secur32 functions not available\n"); return; } /* Create a socket and connect to www.winehq.org */ ret = WSAStartup(0x0202, &wsa_data); if (ret) { skip("Can't init winsock 2.2\n"); return; } host = gethostbyname("www.winehq.org"); if (!host) { skip("Can't resolve www.winehq.org\n"); return; } addr.sin_family = host->h_addrtype; addr.sin_addr = *(struct in_addr *)host->h_addr_list[0]; addr.sin_port = htons(443); sock = socket(host->h_addrtype, SOCK_STREAM, 0); if (sock == SOCKET_ERROR) { skip("Can't create socket\n"); return; } ret = connect(sock, (struct sockaddr *)&addr, sizeof(addr)); if (ret == SOCKET_ERROR) { skip("Can't connect to www.winehq.org\n"); return; } /* Create client credentials */ init_cred(&cred); cred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT; cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS|SCH_CRED_MANUAL_CRED_VALIDATION; status = pAcquireCredentialsHandleA(NULL, (SEC_CHAR *)UNISP_NAME_A, SECPKG_CRED_OUTBOUND, NULL, &cred, NULL, NULL, &cred_handle, NULL); ok(status == SEC_E_OK, "AcquireCredentialsHandleA failed: %08x\n", status); if (status != SEC_E_OK) return; /* Initialize the connection */ init_buffers(&buffers[0], 4, buf_size); init_buffers(&buffers[1], 4, buf_size); buffers[0].pBuffers[0].BufferType = SECBUFFER_TOKEN; status = pInitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost", ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM, 0, 0, NULL, 0, &context, &buffers[0], &attrs, NULL); ok(status == SEC_I_CONTINUE_NEEDED, "Expected SEC_I_CONTINUE_NEEDED, got %08x\n", status); buffers[1].cBuffers = 1; buffers[1].pBuffers[0].BufferType = SECBUFFER_TOKEN; buffers[0].pBuffers[0].cbBuffer = 1; memset(buffers[1].pBuffers[0].pvBuffer, 0xfa, buf_size); status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost", ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM, 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL); todo_wine ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status); todo_wine ok(buffers[0].pBuffers[0].cbBuffer == 0, "Output buffer size was not set to 0.\n"); buffers[1].cBuffers = 1; buffers[1].pBuffers[0].BufferType = SECBUFFER_TOKEN; buffers[0].pBuffers[0].cbBuffer = 1; memset(buffers[1].pBuffers[0].pvBuffer, 0, buf_size); status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost", ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM, 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL); ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status); todo_wine ok(buffers[0].pBuffers[0].cbBuffer == 0, "Output buffer size was not set to 0.\n"); buffers[0].pBuffers[0].cbBuffer = 0; status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost", ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM, 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL); todo_wine ok(status == SEC_E_INSUFFICIENT_MEMORY || status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INSUFFICIENT_MEMORY or SEC_E_INVALID_TOKEN, got %08x\n", status); buffers[0].pBuffers[0].cbBuffer = buf_size; status = pInitializeSecurityContextA(&cred_handle, NULL, (SEC_CHAR *)"localhost", ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM, 0, 0, NULL, 0, &context, &buffers[0], &attrs, NULL); ok(status == SEC_I_CONTINUE_NEEDED, "Expected SEC_I_CONTINUE_NEEDED, got %08x\n", status); buf = &buffers[0].pBuffers[0]; send(sock, buf->pvBuffer, buf->cbBuffer, 0); buf->cbBuffer = buf_size; status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost", ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM, 0, 0, NULL, 0, NULL, &buffers[0], &attrs, NULL); ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#x.\n", status); ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n"); ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n"); buffers[1].cBuffers = 4; buffers[1].pBuffers[0].cbBuffer = 0; status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost", ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM, 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL); ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#x.\n", status); ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n"); ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n"); buf = &buffers[1].pBuffers[0]; buf->cbBuffer = buf_size; ret = receive_data(sock, buf); if (ret == -1) return; buffers[1].pBuffers[0].cbBuffer = 4; status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost", ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM, 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL); ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#x.\n", status); ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n"); ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n"); buffers[1].pBuffers[0].cbBuffer = 5; status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost", ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM, 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL); ok(status == SEC_E_INCOMPLETE_MESSAGE, "Got unexpected status %#x.\n", status); ok(buffers[0].pBuffers[0].cbBuffer == buf_size, "Output buffer size changed.\n"); ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_TOKEN, "Output buffer type changed.\n"); buffers[1].pBuffers[0].cbBuffer = ret; status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost", ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM, 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL); buffers[1].pBuffers[0].cbBuffer = buf_size; while (status == SEC_I_CONTINUE_NEEDED) { buf = &buffers[0].pBuffers[0]; send(sock, buf->pvBuffer, buf->cbBuffer, 0); buf->cbBuffer = buf_size; buf = &buffers[1].pBuffers[0]; ret = receive_data(sock, buf); if (ret == -1) return; buf->BufferType = SECBUFFER_TOKEN; status = pInitializeSecurityContextA(&cred_handle, &context, (SEC_CHAR *)"localhost", ISC_REQ_CONFIDENTIALITY|ISC_REQ_STREAM, 0, 0, &buffers[1], 0, NULL, &buffers[0], &attrs, NULL); buffers[1].pBuffers[0].cbBuffer = buf_size; } ok(status == SEC_E_OK || broken(status == SEC_E_INVALID_TOKEN) /* WinNT */, "InitializeSecurityContext failed: %08x\n", status); if(status != SEC_E_OK) { win_skip("Handshake failed\n"); return; } status = pQueryCredentialsAttributesA(&cred_handle, SECPKG_CRED_ATTR_NAMES, &names); ok(status == SEC_E_NO_CREDENTIALS || status == SEC_E_UNSUPPORTED_FUNCTION /* before Vista */, "expected SEC_E_NO_CREDENTIALS, got %08x\n", status); status = pQueryContextAttributesA(&context, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (void*)&cert); ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_REMOTE_CERT_CONTEXT) failed: %08x\n", status); if(status == SEC_E_OK) { test_remote_cert(cert); CertFreeCertificateContext(cert); } status = pQueryContextAttributesA(&context, SECPKG_ATTR_CONNECTION_INFO, (void*)&conn_info); ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_CONNECTION_INFO) failed: %08x\n", status); if(status == SEC_E_OK) { ok(conn_info.dwCipherStrength >= 128, "conn_info.dwCipherStrength = %d\n", conn_info.dwCipherStrength); ok(conn_info.dwHashStrength >= 128, "conn_info.dwHashStrength = %d\n", conn_info.dwHashStrength); } status = pQueryContextAttributesA(&context, SECPKG_ATTR_STREAM_SIZES, &sizes); ok(status == SEC_E_OK, "QueryContextAttributesW(SECPKG_ATTR_STREAM_SIZES) failed: %08x\n", status); reset_buffers(&buffers[0]); /* Send a simple request so we get data for testing DecryptMessage */ buf = &buffers[0].pBuffers[0]; data = buf->pvBuffer; buf->BufferType = SECBUFFER_STREAM_HEADER; buf->cbBuffer = sizes.cbHeader; ++buf; buf->BufferType = SECBUFFER_DATA; buf->pvBuffer = data + sizes.cbHeader; buf->cbBuffer = sizeof(http_request) - 1; memcpy(buf->pvBuffer, http_request, sizeof(http_request) - 1); ++buf; buf->BufferType = SECBUFFER_STREAM_TRAILER; buf->pvBuffer = data + sizes.cbHeader + sizeof(http_request) -1; buf->cbBuffer = sizes.cbTrailer; status = pEncryptMessage(&context, 0, &buffers[0], 0); ok(status == SEC_E_OK, "EncryptMessage failed: %08x\n", status); if (status != SEC_E_OK) return; buf = &buffers[0].pBuffers[0]; send(sock, buf->pvBuffer, buffers[0].pBuffers[0].cbBuffer + buffers[0].pBuffers[1].cbBuffer + buffers[0].pBuffers[2].cbBuffer, 0); reset_buffers(&buffers[0]); buf->cbBuffer = buf_size; data_size = receive_data(sock, buf); /* Too few buffers */ --buffers[0].cBuffers; status = pDecryptMessage(&context, &buffers[0], 0, NULL); ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status); /* No data buffer */ ++buffers[0].cBuffers; status = pDecryptMessage(&context, &buffers[0], 0, NULL); ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status); /* Two data buffers */ buffers[0].pBuffers[0].BufferType = SECBUFFER_DATA; buffers[0].pBuffers[1].BufferType = SECBUFFER_DATA; status = pDecryptMessage(&context, &buffers[0], 0, NULL); ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status); /* Too few empty buffers */ buffers[0].pBuffers[1].BufferType = SECBUFFER_EXTRA; status = pDecryptMessage(&context, &buffers[0], 0, NULL); ok(status == SEC_E_INVALID_TOKEN, "Expected SEC_E_INVALID_TOKEN, got %08x\n", status); /* Incomplete data */ buffers[0].pBuffers[1].BufferType = SECBUFFER_EMPTY; buffers[0].pBuffers[0].cbBuffer = (data[3]<<8) | data[4]; status = pDecryptMessage(&context, &buffers[0], 0, NULL); ok(status == SEC_E_INCOMPLETE_MESSAGE, "Expected SEC_E_INCOMPLETE_MESSAGE, got %08x\n", status); ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_MISSING, "Expected first buffer to be SECBUFFER_MISSING\n"); ok(buffers[0].pBuffers[0].cbBuffer == 5, "Expected first buffer to be a five bytes\n"); buffers[0].pBuffers[0].cbBuffer = data_size; buffers[0].pBuffers[0].BufferType = SECBUFFER_DATA; buffers[0].pBuffers[1].BufferType = SECBUFFER_EMPTY; status = pDecryptMessage(&context, &buffers[0], 0, NULL); ok(status == SEC_E_OK, "DecryptMessage failed: %08x\n", status); if (status == SEC_E_OK) { ok(buffers[0].pBuffers[0].BufferType == SECBUFFER_STREAM_HEADER, "Expected first buffer to be SECBUFFER_STREAM_HEADER\n"); ok(buffers[0].pBuffers[1].BufferType == SECBUFFER_DATA, "Expected second buffer to be SECBUFFER_DATA\n"); ok(buffers[0].pBuffers[2].BufferType == SECBUFFER_STREAM_TRAILER, "Expected third buffer to be SECBUFFER_STREAM_TRAILER\n"); data = buffers[0].pBuffers[1].pvBuffer; data[buffers[0].pBuffers[1].cbBuffer] = 0; } pDeleteSecurityContext(&context); pFreeCredentialsHandle(&cred_handle); free_buffers(&buffers[0]); free_buffers(&buffers[1]); closesocket(sock); }
static krb5_error_code get_init_creds_common(krb5_context context, krb5_principal client, krb5_deltat start_time, krb5_get_init_creds_opt *options, krb5_init_creds_context ctx) { krb5_get_init_creds_opt *default_opt = NULL; krb5_error_code ret; krb5_enctype *etypes; krb5_preauthtype *pre_auth_types; memset(ctx, 0, sizeof(*ctx)); if (options == NULL) { const char *realm = krb5_principal_get_realm(context, client); krb5_get_init_creds_opt_alloc (context, &default_opt); options = default_opt; krb5_get_init_creds_opt_set_default_flags(context, NULL, realm, options); } if (options->opt_private) { if (options->opt_private->password) { ret = krb5_init_creds_set_password(context, ctx, options->opt_private->password); if (ret) goto out; } ctx->keyproc = options->opt_private->key_proc; ctx->req_pac = options->opt_private->req_pac; ctx->pk_init_ctx = options->opt_private->pk_init_ctx; ctx->ic_flags = options->opt_private->flags; } else ctx->req_pac = KRB5_INIT_CREDS_TRISTATE_UNSET; if (ctx->keyproc == NULL) ctx->keyproc = default_s2k_func; /* Enterprise name implicitly turns on canonicalize */ if ((ctx->ic_flags & KRB5_INIT_CREDS_CANONICALIZE) || krb5_principal_get_type(context, client) == KRB5_NT_ENTERPRISE_PRINCIPAL) ctx->flags.canonicalize = 1; ctx->pre_auth_types = NULL; ctx->addrs = NULL; ctx->etypes = NULL; ctx->pre_auth_types = NULL; ret = init_cred(context, &ctx->cred, client, start_time, options); if (ret) { if (default_opt) krb5_get_init_creds_opt_free(context, default_opt); return ret; } ret = krb5_init_creds_set_service(context, ctx, NULL); if (ret) goto out; if (options->flags & KRB5_GET_INIT_CREDS_OPT_FORWARDABLE) ctx->flags.forwardable = options->forwardable; if (options->flags & KRB5_GET_INIT_CREDS_OPT_PROXIABLE) ctx->flags.proxiable = options->proxiable; if (start_time) ctx->flags.postdated = 1; if (ctx->cred.times.renew_till) ctx->flags.renewable = 1; if (options->flags & KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST) { ctx->addrs = options->address_list; } else if (options->opt_private) { switch (options->opt_private->addressless) { case KRB5_INIT_CREDS_TRISTATE_UNSET: #if KRB5_ADDRESSLESS_DEFAULT == TRUE ctx->addrs = &no_addrs; #else ctx->addrs = NULL; #endif break; case KRB5_INIT_CREDS_TRISTATE_FALSE: ctx->addrs = NULL; break; case KRB5_INIT_CREDS_TRISTATE_TRUE: ctx->addrs = &no_addrs; break; } } if (options->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST) { etypes = malloc((options->etype_list_length + 1) * sizeof(krb5_enctype)); if (etypes == NULL) { ret = ENOMEM; krb5_set_error_message(context, ret, N_("malloc: out of memory", "")); goto out; } memcpy (etypes, options->etype_list, options->etype_list_length * sizeof(krb5_enctype)); etypes[options->etype_list_length] = ETYPE_NULL; ctx->etypes = etypes; } if (options->flags & KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST) { pre_auth_types = malloc((options->preauth_list_length + 1) * sizeof(krb5_preauthtype)); if (pre_auth_types == NULL) { ret = ENOMEM; krb5_set_error_message(context, ret, N_("malloc: out of memory", "")); goto out; } memcpy (pre_auth_types, options->preauth_list, options->preauth_list_length * sizeof(krb5_preauthtype)); pre_auth_types[options->preauth_list_length] = KRB5_PADATA_NONE; ctx->pre_auth_types = pre_auth_types; } if (options->flags & KRB5_GET_INIT_CREDS_OPT_ANONYMOUS) ctx->flags.request_anonymous = options->anonymous; if (default_opt) krb5_get_init_creds_opt_free(context, default_opt); return 0; out: if (default_opt) krb5_get_init_creds_opt_free(context, default_opt); return ret; }