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