Lines Matching full:client

140 	enum svc_rpc_gss_client_state cl_state;	/* client state */
144 gss_name_t cl_cname; /* client name */
186 "Size of rpc-gss client hash table");
494 struct svc_rpc_gss_client *client; in rpc_gss_getcred() local
500 client = cc->cc_client; in rpc_gss_getcred()
502 *rcred = &client->cl_rawcred; in rpc_gss_getcred()
504 *ucred = &client->cl_ucred; in rpc_gss_getcred()
506 *cookie = client->cl_cookie; in rpc_gss_getcred()
519 struct svc_rpc_gss_client *client; in rpc_gss_svc_getcred() local
526 client = cc->cc_client; in rpc_gss_svc_getcred()
529 *flavorp = client->cl_rpcflavor; in rpc_gss_svc_getcred()
531 if (client->cl_cred) { in rpc_gss_svc_getcred()
532 *crp = crhold(client->cl_cred); in rpc_gss_svc_getcred()
536 uc = &client->cl_ucred; in rpc_gss_svc_getcred()
537 cr = client->cl_cred = crget(); in rpc_gss_svc_getcred()
552 struct svc_rpc_gss_client *client = cc->cc_client; in rpc_gss_svc_max_data_length() local
558 switch (client->cl_rawcred.service) { in rpc_gss_svc_max_data_length()
576 maj_stat = gss_wrap_size_limit(&min_stat, client->cl_ctx, want_conf, in rpc_gss_svc_max_data_length()
577 client->cl_qop, max_tp_unit_len, &max); in rpc_gss_svc_max_data_length()
585 rpc_gss_log_status("gss_wrap_size_limit", client->cl_mech, in rpc_gss_svc_max_data_length()
594 struct svc_rpc_gss_client *client; in svc_rpc_gss_find_client() local
609 TAILQ_FOREACH(client, list, cl_link) { in svc_rpc_gss_find_client()
610 if (client->cl_id.ci_id == id->ci_id) { in svc_rpc_gss_find_client()
612 * Move this client to the front of the LRU in svc_rpc_gss_find_client()
615 TAILQ_REMOVE(&KGSS_VNET(svc_rpc_gss_clients), client, in svc_rpc_gss_find_client()
618 client, cl_alllink); in svc_rpc_gss_find_client()
619 refcount_acquire(&client->cl_refs); in svc_rpc_gss_find_client()
625 return (client); in svc_rpc_gss_find_client()
631 struct svc_rpc_gss_client *client; in svc_rpc_gss_create_client() local
638 client = mem_alloc(sizeof(struct svc_rpc_gss_client)); in svc_rpc_gss_create_client()
639 memset(client, 0, sizeof(struct svc_rpc_gss_client)); in svc_rpc_gss_create_client()
643 * and the other to hold onto the client structure until it expires. in svc_rpc_gss_create_client()
645 refcount_init(&client->cl_refs, 2); in svc_rpc_gss_create_client()
646 sx_init(&client->cl_lock, "GSS-client"); in svc_rpc_gss_create_client()
648 client->cl_id.ci_hostid = hostid; in svc_rpc_gss_create_client()
650 client->cl_id.ci_boottime = boottime.tv_sec; in svc_rpc_gss_create_client()
651 client->cl_id.ci_id = KGSS_VNET(svc_rpc_gss_next_clientid)++; in svc_rpc_gss_create_client()
654 * Start the client off with a short expiration time. We will in svc_rpc_gss_create_client()
655 * try to get a saner value from the client creds later. in svc_rpc_gss_create_client()
657 client->cl_state = CLIENT_NEW; in svc_rpc_gss_create_client()
658 client->cl_locked = FALSE; in svc_rpc_gss_create_client()
659 client->cl_expiration = time_uptime + 5*60; in svc_rpc_gss_create_client()
662 [client->cl_id.ci_id % svc_rpc_gss_client_hash_size]; in svc_rpc_gss_create_client()
664 TAILQ_INSERT_HEAD(list, client, cl_link); in svc_rpc_gss_create_client()
665 TAILQ_INSERT_HEAD(&KGSS_VNET(svc_rpc_gss_clients), client, cl_alllink); in svc_rpc_gss_create_client()
668 return (client); in svc_rpc_gss_create_client()
672 svc_rpc_gss_destroy_client(struct svc_rpc_gss_client *client) in svc_rpc_gss_destroy_client() argument
678 if (client->cl_ctx) in svc_rpc_gss_destroy_client()
680 &client->cl_ctx, GSS_C_NO_BUFFER); in svc_rpc_gss_destroy_client()
682 if (client->cl_cname) in svc_rpc_gss_destroy_client()
683 gss_release_name(&min_stat, &client->cl_cname); in svc_rpc_gss_destroy_client()
685 if (client->cl_rawcred.client_principal) in svc_rpc_gss_destroy_client()
686 mem_free(client->cl_rawcred.client_principal, in svc_rpc_gss_destroy_client()
687 sizeof(*client->cl_rawcred.client_principal) in svc_rpc_gss_destroy_client()
688 + client->cl_rawcred.client_principal->len); in svc_rpc_gss_destroy_client()
690 if (client->cl_cred) in svc_rpc_gss_destroy_client()
691 crfree(client->cl_cred); in svc_rpc_gss_destroy_client()
693 sx_destroy(&client->cl_lock); in svc_rpc_gss_destroy_client()
694 mem_free(client, sizeof(*client)); in svc_rpc_gss_destroy_client()
698 * Drop a reference to a client and free it if that was the last reference.
701 svc_rpc_gss_release_client(struct svc_rpc_gss_client *client) in svc_rpc_gss_release_client() argument
704 if (!refcount_release(&client->cl_refs)) in svc_rpc_gss_release_client()
706 svc_rpc_gss_destroy_client(client); in svc_rpc_gss_release_client()
710 * Remove a client from our global lists.
714 svc_rpc_gss_forget_client_locked(struct svc_rpc_gss_client *client) in svc_rpc_gss_forget_client_locked() argument
720 [client->cl_id.ci_id % svc_rpc_gss_client_hash_size]; in svc_rpc_gss_forget_client_locked()
721 TAILQ_REMOVE(list, client, cl_link); in svc_rpc_gss_forget_client_locked()
722 TAILQ_REMOVE(&KGSS_VNET(svc_rpc_gss_clients), client, cl_alllink); in svc_rpc_gss_forget_client_locked()
727 * Remove a client from our global lists and free it if we can.
730 svc_rpc_gss_forget_client(struct svc_rpc_gss_client *client) in svc_rpc_gss_forget_client() argument
736 [client->cl_id.ci_id % svc_rpc_gss_client_hash_size]; in svc_rpc_gss_forget_client()
740 * Make sure this client has not already been removed in svc_rpc_gss_forget_client()
744 if (client == tclient) { in svc_rpc_gss_forget_client()
745 svc_rpc_gss_forget_client_locked(client); in svc_rpc_gss_forget_client()
747 svc_rpc_gss_release_client(client); in svc_rpc_gss_forget_client()
757 struct svc_rpc_gss_client *client; in svc_rpc_gss_timeout_clients() local
763 * First enforce the max client limit. We keep in svc_rpc_gss_timeout_clients()
767 client = TAILQ_LAST(&KGSS_VNET(svc_rpc_gss_clients), in svc_rpc_gss_timeout_clients()
769 while (svc_rpc_gss_client_count > svc_rpc_gss_client_max && client != NULL) { in svc_rpc_gss_timeout_clients()
770 svc_rpc_gss_forget_client_locked(client); in svc_rpc_gss_timeout_clients()
772 svc_rpc_gss_release_client(client); in svc_rpc_gss_timeout_clients()
774 client = TAILQ_LAST(&KGSS_VNET(svc_rpc_gss_clients), in svc_rpc_gss_timeout_clients()
778 TAILQ_FOREACH(client, &KGSS_VNET(svc_rpc_gss_clients), cl_alllink) { in svc_rpc_gss_timeout_clients()
779 if (client->cl_state == CLIENT_STALE in svc_rpc_gss_timeout_clients()
780 || now > client->cl_expiration) { in svc_rpc_gss_timeout_clients()
781 svc_rpc_gss_forget_client_locked(client); in svc_rpc_gss_timeout_clients()
783 rpc_gss_log_debug("expiring client %p", client); in svc_rpc_gss_timeout_clients()
784 svc_rpc_gss_release_client(client); in svc_rpc_gss_timeout_clients()
869 svc_rpc_gss_build_ucred(struct svc_rpc_gss_client *client, in svc_rpc_gss_build_ucred() argument
873 rpc_gss_ucred_t *uc = &client->cl_ucred; in svc_rpc_gss_build_ucred()
878 uc->gidlist = client->cl_gid_storage; in svc_rpc_gss_build_ucred()
881 maj_stat = gss_pname_to_unix_cred(&min_stat, name, client->cl_mech, in svc_rpc_gss_build_ucred()
890 svc_rpc_gss_set_flavor(struct svc_rpc_gss_client *client) in svc_rpc_gss_set_flavor() argument
899 if (kgss_oid_equal(client->cl_mech, &krb5_mech_oid)) { in svc_rpc_gss_set_flavor()
900 switch (client->cl_rawcred.service) { in svc_rpc_gss_set_flavor()
903 client->cl_rpcflavor = RPCSEC_GSS_KRB5; in svc_rpc_gss_set_flavor()
906 client->cl_rpcflavor = RPCSEC_GSS_KRB5I; in svc_rpc_gss_set_flavor()
909 client->cl_rpcflavor = RPCSEC_GSS_KRB5P; in svc_rpc_gss_set_flavor()
913 client->cl_rpcflavor = RPCSEC_GSS; in svc_rpc_gss_set_flavor()
918 svc_rpc_gss_accept_sec_context(struct svc_rpc_gss_client *client, in svc_rpc_gss_accept_sec_context() argument
937 client->cl_state = CLIENT_STALE; in svc_rpc_gss_accept_sec_context()
946 if (!client->cl_sname) { in svc_rpc_gss_accept_sec_context()
954 &client->cl_ctx, in svc_rpc_gss_accept_sec_context()
958 &client->cl_cname, in svc_rpc_gss_accept_sec_context()
963 &client->cl_creds); in svc_rpc_gss_accept_sec_context()
974 client->cl_sname = sname; in svc_rpc_gss_accept_sec_context()
987 &client->cl_ctx, in svc_rpc_gss_accept_sec_context()
988 client->cl_sname->sn_cred, in svc_rpc_gss_accept_sec_context()
991 &client->cl_cname, in svc_rpc_gss_accept_sec_context()
1004 * reply anyway so that the client gets a chance to see what in svc_rpc_gss_accept_sec_context()
1009 rpc_gss_log_status("accept_sec_context", client->cl_mech, in svc_rpc_gss_accept_sec_context()
1011 client->cl_state = CLIENT_STALE; in svc_rpc_gss_accept_sec_context()
1015 gr->gr_handle.value = &client->cl_id; in svc_rpc_gss_accept_sec_context()
1016 gr->gr_handle.length = sizeof(client->cl_id); in svc_rpc_gss_accept_sec_context()
1019 /* Save client info. */ in svc_rpc_gss_accept_sec_context()
1020 client->cl_mech = mech; in svc_rpc_gss_accept_sec_context()
1021 client->cl_qop = GSS_C_QOP_DEFAULT; in svc_rpc_gss_accept_sec_context()
1022 client->cl_done_callback = FALSE; in svc_rpc_gss_accept_sec_context()
1028 * Change client expiration time to be near when the in svc_rpc_gss_accept_sec_context()
1029 * client creds expire (or 24 hours if we can't figure in svc_rpc_gss_accept_sec_context()
1042 client->cl_expiration = time_uptime + cred_lifetime; in svc_rpc_gss_accept_sec_context()
1047 client->cl_rawcred.version = RPCSEC_GSS_VERSION; in svc_rpc_gss_accept_sec_context()
1048 rpc_gss_oid_to_mech(mech, &client->cl_rawcred.mechanism); in svc_rpc_gss_accept_sec_context()
1049 maj_stat = gss_export_name(&min_stat, client->cl_cname, in svc_rpc_gss_accept_sec_context()
1052 rpc_gss_log_status("gss_export_name", client->cl_mech, in svc_rpc_gss_accept_sec_context()
1056 client->cl_rawcred.client_principal = in svc_rpc_gss_accept_sec_context()
1057 mem_alloc(sizeof(*client->cl_rawcred.client_principal) in svc_rpc_gss_accept_sec_context()
1059 client->cl_rawcred.client_principal->len = export_name.length; in svc_rpc_gss_accept_sec_context()
1060 memcpy(client->cl_rawcred.client_principal->name, in svc_rpc_gss_accept_sec_context()
1063 client->cl_rawcred.svc_principal = in svc_rpc_gss_accept_sec_context()
1064 client->cl_sname->sn_principal; in svc_rpc_gss_accept_sec_context()
1065 client->cl_rawcred.service = gc->gc_svc; in svc_rpc_gss_accept_sec_context()
1071 svc_rpc_gss_build_ucred(client, client->cl_cname); in svc_rpc_gss_accept_sec_context()
1072 svc_rpc_gss_set_flavor(client); in svc_rpc_gss_accept_sec_context()
1073 gss_release_name(&min_stat, &client->cl_cname); in svc_rpc_gss_accept_sec_context()
1083 client->cl_rawcred.client_principal->name, in svc_rpc_gss_accept_sec_context()
1085 client->cl_qop, client->cl_rawcred.service); in svc_rpc_gss_accept_sec_context()
1095 svc_rpc_gss_validate(struct svc_rpc_gss_client *client, struct rpc_msg *msg, in svc_rpc_gss_validate() argument
1130 maj_stat = gss_verify_mic(&min_stat, client->cl_ctx, &rpcbuf, &checksum, in svc_rpc_gss_validate()
1134 rpc_gss_log_status("gss_verify_mic", client->cl_mech, in svc_rpc_gss_validate()
1137 * A bug in some versions of the Linux client generates a in svc_rpc_gss_validate()
1145 client->cl_state = CLIENT_STALE; in svc_rpc_gss_validate()
1154 svc_rpc_gss_nextverf(struct svc_rpc_gss_client *client, in svc_rpc_gss_nextverf() argument
1168 maj_stat = gss_get_mic(&min_stat, client->cl_ctx, client->cl_qop, in svc_rpc_gss_nextverf()
1172 rpc_gss_log_status("gss_get_mic", client->cl_mech, maj_stat, min_stat); in svc_rpc_gss_nextverf()
1173 client->cl_state = CLIENT_STALE; in svc_rpc_gss_nextverf()
1190 svc_rpc_gss_callback(struct svc_rpc_gss_client *client, struct svc_req *rqst) in svc_rpc_gss_callback() argument
1210 lock.raw_cred = &client->cl_rawcred; in svc_rpc_gss_callback()
1212 client->cl_creds, in svc_rpc_gss_callback()
1213 client->cl_ctx, in svc_rpc_gss_callback()
1218 client->cl_state = CLIENT_STALE; in svc_rpc_gss_callback()
1225 * is responsible for freeing client->cl_creds in svc_rpc_gss_callback()
1228 client->cl_creds = GSS_C_NO_CREDENTIAL; in svc_rpc_gss_callback()
1229 client->cl_locked = lock.locked; in svc_rpc_gss_callback()
1230 client->cl_cookie = cookie; in svc_rpc_gss_callback()
1238 * clean up the delegated client creds, if any. in svc_rpc_gss_callback()
1240 if (client->cl_creds) { in svc_rpc_gss_callback()
1242 gss_release_cred(&min_ver, &client->cl_creds); in svc_rpc_gss_callback()
1248 svc_rpc_gss_check_replay(struct svc_rpc_gss_client *client, uint32_t seq) in svc_rpc_gss_check_replay() argument
1254 sx_xlock(&client->cl_lock); in svc_rpc_gss_check_replay()
1255 if (seq <= client->cl_seqlast) { in svc_rpc_gss_check_replay()
1263 offset = client->cl_seqlast - seq; in svc_rpc_gss_check_replay()
1270 if (client->cl_seqmask[word] & (1 << bit)) { in svc_rpc_gss_check_replay()
1278 sx_xunlock(&client->cl_lock); in svc_rpc_gss_check_replay()
1283 svc_rpc_gss_update_seq(struct svc_rpc_gss_client *client, uint32_t seq) in svc_rpc_gss_update_seq() argument
1288 sx_xlock(&client->cl_lock); in svc_rpc_gss_update_seq()
1289 if (seq > client->cl_seqlast) { in svc_rpc_gss_update_seq()
1297 offset = seq - client->cl_seqlast; in svc_rpc_gss_update_seq()
1301 client->cl_seqmask[i] = client->cl_seqmask[i-1]; in svc_rpc_gss_update_seq()
1303 client->cl_seqmask[0] = 0; in svc_rpc_gss_update_seq()
1308 newcarry = client->cl_seqmask[i] >> (32 - offset); in svc_rpc_gss_update_seq()
1309 client->cl_seqmask[i] = in svc_rpc_gss_update_seq()
1310 (client->cl_seqmask[i] << offset) | carry; in svc_rpc_gss_update_seq()
1313 client->cl_seqmask[0] |= 1; in svc_rpc_gss_update_seq()
1314 client->cl_seqlast = seq; in svc_rpc_gss_update_seq()
1316 offset = client->cl_seqlast - seq; in svc_rpc_gss_update_seq()
1319 client->cl_seqmask[word] |= (1 << bit); in svc_rpc_gss_update_seq()
1321 sx_xunlock(&client->cl_lock); in svc_rpc_gss_update_seq()
1331 struct svc_rpc_gss_client *client; in svc_rpc_gss() local
1347 /* Deserialize client credentials. */ in svc_rpc_gss()
1365 client = NULL; in svc_rpc_gss()
1373 /* Check the proc and find the client (or create it) */ in svc_rpc_gss()
1379 client = svc_rpc_gss_create_client(); in svc_rpc_gss()
1387 client = svc_rpc_gss_find_client(p); in svc_rpc_gss()
1388 if (!client) { in svc_rpc_gss()
1390 * Can't find the client - we may have in svc_rpc_gss()
1399 cc->cc_client = client; in svc_rpc_gss()
1439 if (!svc_rpc_gss_accept_sec_context(client, rqst, &gr, &gc)) { in svc_rpc_gss()
1450 if (!svc_rpc_gss_nextverf(client, rqst, gr.gr_win)) { in svc_rpc_gss()
1470 client->cl_state = CLIENT_ESTABLISHED; in svc_rpc_gss()
1477 if (!svc_rpc_gss_check_replay(client, gc.gc_seq)) { in svc_rpc_gss()
1482 if (!svc_rpc_gss_validate(client, msg, &qop, gc.gc_proc)) { in svc_rpc_gss()
1492 if (!svc_rpc_gss_nextverf(client, rqst, gc.gc_seq)) { in svc_rpc_gss()
1497 svc_rpc_gss_update_seq(client, gc.gc_seq); in svc_rpc_gss()
1504 * methods. Acquire an extra reference to the client in svc_rpc_gss()
1508 refcount_acquire(&client->cl_refs); in svc_rpc_gss()
1517 sx_xlock(&client->cl_lock); in svc_rpc_gss()
1518 if (!client->cl_done_callback) { in svc_rpc_gss()
1519 client->cl_done_callback = TRUE; in svc_rpc_gss()
1520 client->cl_qop = qop; in svc_rpc_gss()
1521 client->cl_rawcred.qop = _rpc_gss_num_to_qop( in svc_rpc_gss()
1522 client->cl_rawcred.mechanism, qop); in svc_rpc_gss()
1523 if (!svc_rpc_gss_callback(client, rqst)) { in svc_rpc_gss()
1525 sx_xunlock(&client->cl_lock); in svc_rpc_gss()
1529 sx_xunlock(&client->cl_lock); in svc_rpc_gss()
1532 * If the server has locked this client to a in svc_rpc_gss()
1536 if (client->cl_locked) { in svc_rpc_gss()
1537 if (client->cl_rawcred.service != gc.gc_svc) { in svc_rpc_gss()
1540 } else if (client->cl_qop != qop) { in svc_rpc_gss()
1550 if (client->cl_qop != qop) { in svc_rpc_gss()
1551 client->cl_qop = qop; in svc_rpc_gss()
1552 client->cl_rawcred.qop = _rpc_gss_num_to_qop( in svc_rpc_gss()
1553 client->cl_rawcred.mechanism, qop); in svc_rpc_gss()
1560 if (client->cl_rawcred.service != gc.gc_svc) { in svc_rpc_gss()
1561 client->cl_rawcred.service = gc.gc_svc; in svc_rpc_gss()
1562 svc_rpc_gss_set_flavor(client); in svc_rpc_gss()
1580 svc_rpc_gss_forget_client(client); in svc_rpc_gss()
1592 if (client) in svc_rpc_gss()
1593 svc_rpc_gss_release_client(client); in svc_rpc_gss()
1604 struct svc_rpc_gss_client *client; in svc_rpc_gss_wrap() local
1609 client = cc->cc_client; in svc_rpc_gss_wrap()
1610 if (client->cl_state != CLIENT_ESTABLISHED in svc_rpc_gss_wrap()
1616 client->cl_ctx, client->cl_qop, in svc_rpc_gss_wrap()
1624 struct svc_rpc_gss_client *client; in svc_rpc_gss_unwrap() local
1629 client = cc->cc_client; in svc_rpc_gss_unwrap()
1630 if (client->cl_state != CLIENT_ESTABLISHED in svc_rpc_gss_unwrap()
1636 client->cl_ctx, client->cl_qop, in svc_rpc_gss_unwrap()
1644 struct svc_rpc_gss_client *client; in svc_rpc_gss_release() local
1649 client = cc->cc_client; in svc_rpc_gss_release()
1650 svc_rpc_gss_release_client(client); in svc_rpc_gss_release()