Lines Matching +full:mic +full:- +full:pos

1 // SPDX-License-Identifier: BSD-3-Clause
53 * This compile-time check verifies that we will not exceed the
70 * using integrity (two 4-byte integers): */
95 * for the new text-based upcall; dentry[0] is named after the
97 * backwards-compatibility with older gssd's.
116 refcount_inc(&ctx->count); in gss_get_ctx()
123 if (refcount_dec_and_test(&ctx->count)) in gss_put_ctx()
130 * and a new one is protected by the pipe->lock.
137 if (!test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags)) in gss_cred_set_ctx()
140 rcu_assign_pointer(gss_cred->gc_ctx, ctx); in gss_cred_set_ctx()
141 set_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in gss_cred_set_ctx()
143 clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags); in gss_cred_set_ctx()
153 ctx = rcu_dereference(gss_cred->gc_ctx); in gss_cred_get_ctx()
167 ctx->gc_proc = RPC_GSS_PROC_DATA; in gss_alloc_context()
168 ctx->gc_seq = 1; /* NetApp 6.4R1 doesn't accept seq. no. 0 */ in gss_alloc_context()
169 spin_lock_init(&ctx->gc_seq_lock); in gss_alloc_context()
170 refcount_set(&ctx->count,1); in gss_alloc_context()
187 * credential - e.g. the remaining TGT lifetime for Kerberos or in gss_fill_context()
188 * the -t value passed to GSSD. in gss_fill_context()
195 ctx->gc_expiry = now + ((unsigned long)timeout * HZ); in gss_fill_context()
202 ctx->gc_win = window_size; in gss_fill_context()
203 /* gssd signals an error by passing ctx->gc_win = 0: */ in gss_fill_context()
204 if (ctx->gc_win == 0) { in gss_fill_context()
207 * than -EKEYEXPIRED gets converted to -EACCES. in gss_fill_context()
211 p = (ret == -EKEYEXPIRED) ? ERR_PTR(-EKEYEXPIRED) : in gss_fill_context()
212 ERR_PTR(-EACCES); in gss_fill_context()
216 p = simple_get_netobj(p, end, &ctx->gc_wire_ctx); in gss_fill_context()
225 p = ERR_PTR(-EFAULT); in gss_fill_context()
228 ret = gss_import_sec_context(p, seclen, gm, &ctx->gc_gss_ctx, NULL, GFP_KERNEL); in gss_fill_context()
242 p = simple_get_netobj(q, end, &ctx->gc_acceptor); in gss_fill_context()
246 trace_rpcgss_context(window_size, ctx->gc_expiry, now, timeout, in gss_fill_context()
247 ctx->gc_acceptor.len, ctx->gc_acceptor.data); in gss_fill_context()
279 if (sn->pipe_version >= 0) { in get_pipe_version()
280 atomic_inc(&sn->pipe_users); in get_pipe_version()
281 ret = sn->pipe_version; in get_pipe_version()
283 ret = -EAGAIN; in get_pipe_version()
292 if (atomic_dec_and_lock(&sn->pipe_users, &pipe_version_lock)) { in put_pipe_version()
293 sn->pipe_version = -1; in put_pipe_version()
301 struct net *net = gss_msg->auth->net; in gss_release_msg()
302 if (!refcount_dec_and_test(&gss_msg->count)) in gss_release_msg()
305 BUG_ON(!list_empty(&gss_msg->list)); in gss_release_msg()
306 if (gss_msg->ctx != NULL) in gss_release_msg()
307 gss_put_ctx(gss_msg->ctx); in gss_release_msg()
308 rpc_destroy_wait_queue(&gss_msg->rpc_waitqueue); in gss_release_msg()
309 gss_put_auth(gss_msg->auth); in gss_release_msg()
310 kfree_const(gss_msg->service_name); in gss_release_msg()
317 struct gss_upcall_msg *pos; in __gss_find_upcall() local
318 list_for_each_entry(pos, &pipe->in_downcall, list) { in __gss_find_upcall()
319 if (!uid_eq(pos->uid, uid)) in __gss_find_upcall()
321 if (pos->auth->service != auth->service) in __gss_find_upcall()
323 refcount_inc(&pos->count); in __gss_find_upcall()
324 return pos; in __gss_find_upcall()
336 struct rpc_pipe *pipe = gss_msg->pipe; in gss_add_msg()
339 spin_lock(&pipe->lock); in gss_add_msg()
340 old = __gss_find_upcall(pipe, gss_msg->uid, gss_msg->auth); in gss_add_msg()
342 refcount_inc(&gss_msg->count); in gss_add_msg()
343 list_add(&gss_msg->list, &pipe->in_downcall); in gss_add_msg()
346 spin_unlock(&pipe->lock); in gss_add_msg()
353 list_del_init(&gss_msg->list); in __gss_unhash_msg()
354 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno); in __gss_unhash_msg()
355 wake_up_all(&gss_msg->waitqueue); in __gss_unhash_msg()
356 refcount_dec(&gss_msg->count); in __gss_unhash_msg()
362 struct rpc_pipe *pipe = gss_msg->pipe; in gss_unhash_msg()
364 if (list_empty(&gss_msg->list)) in gss_unhash_msg()
366 spin_lock(&pipe->lock); in gss_unhash_msg()
367 if (!list_empty(&gss_msg->list)) in gss_unhash_msg()
369 spin_unlock(&pipe->lock); in gss_unhash_msg()
375 switch (gss_msg->msg.errno) { in gss_handle_downcall_result()
377 if (gss_msg->ctx == NULL) in gss_handle_downcall_result()
379 clear_bit(RPCAUTH_CRED_NEGATIVE, &gss_cred->gc_base.cr_flags); in gss_handle_downcall_result()
380 gss_cred_set_ctx(&gss_cred->gc_base, gss_msg->ctx); in gss_handle_downcall_result()
382 case -EKEYEXPIRED: in gss_handle_downcall_result()
383 set_bit(RPCAUTH_CRED_NEGATIVE, &gss_cred->gc_base.cr_flags); in gss_handle_downcall_result()
385 gss_cred->gc_upcall_timestamp = jiffies; in gss_handle_downcall_result()
386 gss_cred->gc_upcall = NULL; in gss_handle_downcall_result()
387 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno); in gss_handle_downcall_result()
393 struct gss_cred *gss_cred = container_of(task->tk_rqstp->rq_cred, in gss_upcall_callback()
395 struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall; in gss_upcall_callback()
396 struct rpc_pipe *pipe = gss_msg->pipe; in gss_upcall_callback()
398 spin_lock(&pipe->lock); in gss_upcall_callback()
400 spin_unlock(&pipe->lock); in gss_upcall_callback()
401 task->tk_status = gss_msg->msg.errno; in gss_upcall_callback()
408 struct user_namespace *userns = cred->user_ns; in gss_encode_v0_msg()
410 uid_t uid = from_kuid_munged(userns, gss_msg->uid); in gss_encode_v0_msg()
411 memcpy(gss_msg->databuf, &uid, sizeof(uid)); in gss_encode_v0_msg()
412 gss_msg->msg.data = gss_msg->databuf; in gss_encode_v0_msg()
413 gss_msg->msg.len = sizeof(uid); in gss_encode_v0_msg()
415 BUILD_BUG_ON(sizeof(uid) > sizeof(gss_msg->databuf)); in gss_encode_v0_msg()
425 if (msg->copied == 0) in gss_v0_upcall()
426 gss_encode_v0_msg(gss_msg, file->f_cred); in gss_v0_upcall()
435 struct user_namespace *userns = cred->user_ns; in gss_encode_v1_msg()
436 struct gss_api_mech *mech = gss_msg->auth->mech; in gss_encode_v1_msg()
437 char *p = gss_msg->databuf; in gss_encode_v1_msg()
438 size_t buflen = sizeof(gss_msg->databuf); in gss_encode_v1_msg()
441 len = scnprintf(p, buflen, "mech=%s uid=%d", mech->gm_name, in gss_encode_v1_msg()
442 from_kuid_munged(userns, gss_msg->uid)); in gss_encode_v1_msg()
443 buflen -= len; in gss_encode_v1_msg()
445 gss_msg->msg.len = len; in gss_encode_v1_msg()
453 buflen -= len; in gss_encode_v1_msg()
455 gss_msg->msg.len += len; in gss_encode_v1_msg()
477 (int)(c - service_name), in gss_encode_v1_msg()
479 buflen -= len; in gss_encode_v1_msg()
481 gss_msg->msg.len += len; in gss_encode_v1_msg()
484 if (mech->gm_upcall_enctypes) { in gss_encode_v1_msg()
486 mech->gm_upcall_enctypes); in gss_encode_v1_msg()
487 buflen -= len; in gss_encode_v1_msg()
489 gss_msg->msg.len += len; in gss_encode_v1_msg()
491 trace_rpcgss_upcall_msg(gss_msg->databuf); in gss_encode_v1_msg()
495 gss_msg->msg.len += len; in gss_encode_v1_msg()
496 gss_msg->msg.data = gss_msg->databuf; in gss_encode_v1_msg()
500 return -ENOMEM; in gss_encode_v1_msg()
511 if (msg->copied == 0) { in gss_v1_upcall()
513 gss_msg->service_name, in gss_v1_upcall()
514 gss_msg->auth->target_name, in gss_v1_upcall()
515 file->f_cred); in gss_v1_upcall()
528 int err = -ENOMEM; in gss_alloc_msg()
533 vers = get_pipe_version(gss_auth->net); in gss_alloc_msg()
537 gss_msg->pipe = gss_auth->gss_pipe[vers]->pipe; in gss_alloc_msg()
538 INIT_LIST_HEAD(&gss_msg->list); in gss_alloc_msg()
539 rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); in gss_alloc_msg()
540 init_waitqueue_head(&gss_msg->waitqueue); in gss_alloc_msg()
541 refcount_set(&gss_msg->count, 1); in gss_alloc_msg()
542 gss_msg->uid = uid; in gss_alloc_msg()
543 gss_msg->auth = gss_auth; in gss_alloc_msg()
544 kref_get(&gss_auth->kref); in gss_alloc_msg()
546 gss_msg->service_name = kstrdup_const(service_name, GFP_KERNEL); in gss_alloc_msg()
547 if (!gss_msg->service_name) { in gss_alloc_msg()
548 err = -ENOMEM; in gss_alloc_msg()
554 put_pipe_version(gss_auth->net); in gss_alloc_msg()
567 kuid_t uid = cred->cr_cred->fsuid; in gss_setup_upcall()
569 gss_new = gss_alloc_msg(gss_auth, uid, gss_cred->gc_principal); in gss_setup_upcall()
575 refcount_inc(&gss_msg->count); in gss_setup_upcall()
576 res = rpc_queue_upcall(gss_new->pipe, &gss_new->msg); in gss_setup_upcall()
579 refcount_dec(&gss_msg->count); in gss_setup_upcall()
596 struct rpc_cred *cred = task->tk_rqstp->rq_cred; in gss_refresh_upcall()
597 struct gss_auth *gss_auth = container_of(cred->cr_auth, in gss_refresh_upcall()
606 if (PTR_ERR(gss_msg) == -EAGAIN) { in gss_refresh_upcall()
612 err = -EAGAIN; in gss_refresh_upcall()
619 pipe = gss_msg->pipe; in gss_refresh_upcall()
620 spin_lock(&pipe->lock); in gss_refresh_upcall()
621 if (gss_cred->gc_upcall != NULL) in gss_refresh_upcall()
622 rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL); in gss_refresh_upcall()
623 else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) { in gss_refresh_upcall()
624 gss_cred->gc_upcall = gss_msg; in gss_refresh_upcall()
626 refcount_inc(&gss_msg->count); in gss_refresh_upcall()
627 rpc_sleep_on(&gss_msg->rpc_waitqueue, task, gss_upcall_callback); in gss_refresh_upcall()
630 err = gss_msg->msg.errno; in gss_refresh_upcall()
632 spin_unlock(&pipe->lock); in gss_refresh_upcall()
636 cred->cr_cred->fsuid), err); in gss_refresh_upcall()
643 struct net *net = gss_auth->net; in gss_create_upcall()
646 struct rpc_cred *cred = &gss_cred->gc_base; in gss_create_upcall()
656 err = -EACCES; in gss_create_upcall()
660 if (PTR_ERR(gss_msg) == -EAGAIN) { in gss_create_upcall()
662 sn->pipe_version >= 0, 15 * HZ); in gss_create_upcall()
663 if (sn->pipe_version < 0) { in gss_create_upcall()
665 err = -EACCES; in gss_create_upcall()
675 pipe = gss_msg->pipe; in gss_create_upcall()
677 prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_KILLABLE); in gss_create_upcall()
678 spin_lock(&pipe->lock); in gss_create_upcall()
679 if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) { in gss_create_upcall()
682 spin_unlock(&pipe->lock); in gss_create_upcall()
684 err = -ERESTARTSYS; in gss_create_upcall()
689 if (gss_msg->ctx) { in gss_create_upcall()
691 gss_cred_set_ctx(cred, gss_msg->ctx); in gss_create_upcall()
693 err = gss_msg->msg.errno; in gss_create_upcall()
695 spin_unlock(&pipe->lock); in gss_create_upcall()
697 finish_wait(&gss_msg->waitqueue, &wait); in gss_create_upcall()
701 cred->cr_cred->fsuid), err); in gss_create_upcall()
708 struct gss_upcall_msg *pos; in gss_find_downcall() local
709 list_for_each_entry(pos, &pipe->in_downcall, list) { in gss_find_downcall()
710 if (!uid_eq(pos->uid, uid)) in gss_find_downcall()
712 if (!rpc_msg_is_inflight(&pos->msg)) in gss_find_downcall()
714 refcount_inc(&pos->count); in gss_find_downcall()
715 return pos; in gss_find_downcall()
728 struct rpc_pipe *pipe = RPC_I(file_inode(filp))->pipe; in gss_pipe_downcall()
732 ssize_t err = -EFBIG; in gss_pipe_downcall()
736 err = -ENOMEM; in gss_pipe_downcall()
741 err = -EFAULT; in gss_pipe_downcall()
754 err = -EINVAL; in gss_pipe_downcall()
758 err = -ENOMEM; in gss_pipe_downcall()
763 err = -ENOENT; in gss_pipe_downcall()
765 spin_lock(&pipe->lock); in gss_pipe_downcall()
768 spin_unlock(&pipe->lock); in gss_pipe_downcall()
771 list_del_init(&gss_msg->list); in gss_pipe_downcall()
772 spin_unlock(&pipe->lock); in gss_pipe_downcall()
774 p = gss_fill_context(p, end, ctx, gss_msg->auth->mech); in gss_pipe_downcall()
778 case -EACCES: in gss_pipe_downcall()
779 case -EKEYEXPIRED: in gss_pipe_downcall()
780 gss_msg->msg.errno = err; in gss_pipe_downcall()
783 case -EFAULT: in gss_pipe_downcall()
784 case -ENOMEM: in gss_pipe_downcall()
785 case -EINVAL: in gss_pipe_downcall()
786 case -ENOSYS: in gss_pipe_downcall()
787 gss_msg->msg.errno = -EAGAIN; in gss_pipe_downcall()
792 gss_msg->msg.errno = -EIO; in gss_pipe_downcall()
796 gss_msg->ctx = gss_get_ctx(ctx); in gss_pipe_downcall()
800 spin_lock(&pipe->lock); in gss_pipe_downcall()
802 spin_unlock(&pipe->lock); in gss_pipe_downcall()
814 struct net *net = inode->i_sb->s_fs_info; in gss_pipe_open()
819 if (sn->pipe_version < 0) { in gss_pipe_open()
821 sn->pipe_version = new_version; in gss_pipe_open()
824 } else if (sn->pipe_version != new_version) { in gss_pipe_open()
826 ret = -EBUSY; in gss_pipe_open()
829 atomic_inc(&sn->pipe_users); in gss_pipe_open()
849 struct net *net = inode->i_sb->s_fs_info; in gss_pipe_release()
850 struct rpc_pipe *pipe = RPC_I(inode)->pipe; in gss_pipe_release()
854 spin_lock(&pipe->lock); in gss_pipe_release()
855 list_for_each_entry(gss_msg, &pipe->in_downcall, list) { in gss_pipe_release()
857 if (!list_empty(&gss_msg->msg.list)) in gss_pipe_release()
859 gss_msg->msg.errno = -EPIPE; in gss_pipe_release()
860 refcount_inc(&gss_msg->count); in gss_pipe_release()
862 spin_unlock(&pipe->lock); in gss_pipe_release()
866 spin_unlock(&pipe->lock); in gss_pipe_release()
876 if (msg->errno < 0) { in gss_pipe_destroy_msg()
877 refcount_inc(&gss_msg->count); in gss_pipe_destroy_msg()
879 if (msg->errno == -ETIMEDOUT) in gss_pipe_destroy_msg()
889 struct gss_pipe *gss_pipe = pdo->pdo_data; in gss_pipe_dentry_destroy()
891 rpc_unlink(gss_pipe->pipe); in gss_pipe_dentry_destroy()
897 struct gss_pipe *p = pdo->pdo_data; in gss_pipe_dentry_create()
899 return rpc_mkpipe_dentry(dir, p->name, p->clnt, p->pipe); in gss_pipe_dentry_create()
912 int err = -ENOMEM; in gss_pipe_alloc()
917 p->pipe = rpc_mkpipe_data(upcall_ops, RPC_PIPE_WAIT_FOR_OPEN); in gss_pipe_alloc()
918 if (IS_ERR(p->pipe)) { in gss_pipe_alloc()
919 err = PTR_ERR(p->pipe); in gss_pipe_alloc()
922 p->name = name; in gss_pipe_alloc()
923 p->clnt = clnt; in gss_pipe_alloc()
924 kref_init(&p->kref); in gss_pipe_alloc()
925 rpc_init_pipe_dir_object(&p->pdo, in gss_pipe_alloc()
946 if (pdo->pdo_ops != &gss_pipe_dir_object_ops) in gss_pipe_match_pdo()
949 if (strcmp(gss_pipe->name, args->name) != 0) in gss_pipe_match_pdo()
951 if (!kref_get_unless_zero(&gss_pipe->kref)) in gss_pipe_match_pdo()
961 gss_pipe = gss_pipe_alloc(args->clnt, args->name, args->upcall_ops); in gss_pipe_alloc_pdo()
963 return &gss_pipe->pdo; in gss_pipe_alloc_pdo()
980 &clnt->cl_pipedir_objects, in gss_pipe_get()
986 return ERR_PTR(-ENOMEM); in gss_pipe_get()
991 struct rpc_clnt *clnt = p->clnt; in __gss_pipe_free()
995 &clnt->cl_pipedir_objects, in __gss_pipe_free()
996 &p->pdo); in __gss_pipe_free()
997 rpc_destroy_pipe_data(p->pipe); in __gss_pipe_free()
1011 kref_put(&p->kref, __gss_pipe_release); in gss_pipe_free()
1021 rpc_authflavor_t flavor = args->pseudoflavor; in gss_create_new()
1025 int err = -ENOMEM; /* XXX? */ in gss_create_new()
1031 INIT_HLIST_NODE(&gss_auth->hash); in gss_create_new()
1032 gss_auth->target_name = NULL; in gss_create_new()
1033 if (args->target_name) { in gss_create_new()
1034 gss_auth->target_name = kstrdup(args->target_name, GFP_KERNEL); in gss_create_new()
1035 if (gss_auth->target_name == NULL) in gss_create_new()
1038 gss_auth->client = clnt; in gss_create_new()
1039 gss_auth->net = get_net_track(rpc_net_ns(clnt), &gss_auth->ns_tracker, in gss_create_new()
1041 err = -EINVAL; in gss_create_new()
1042 gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor); in gss_create_new()
1043 if (!gss_auth->mech) in gss_create_new()
1045 gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor); in gss_create_new()
1046 if (gss_auth->service == 0) in gss_create_new()
1048 if (!gssd_running(gss_auth->net)) in gss_create_new()
1050 auth = &gss_auth->rpc_auth; in gss_create_new()
1051 auth->au_cslack = GSS_CRED_SLACK >> 2; in gss_create_new()
1053 auth->au_rslack = GSS_KRB5_MAX_SLACK_NEEDED >> 2; in gss_create_new()
1054 auth->au_verfsize = GSS_VERF_SLACK >> 2; in gss_create_new()
1055 auth->au_ralign = GSS_VERF_SLACK >> 2; in gss_create_new()
1056 __set_bit(RPCAUTH_AUTH_UPDATE_SLACK, &auth->au_flags); in gss_create_new()
1057 auth->au_ops = &authgss_ops; in gss_create_new()
1058 auth->au_flavor = flavor; in gss_create_new()
1059 if (gss_pseudoflavor_to_datatouch(gss_auth->mech, flavor)) in gss_create_new()
1060 __set_bit(RPCAUTH_AUTH_DATATOUCH, &auth->au_flags); in gss_create_new()
1061 refcount_set(&auth->au_count, 1); in gss_create_new()
1062 kref_init(&gss_auth->kref); in gss_create_new()
1078 gss_auth->gss_pipe[1] = gss_pipe; in gss_create_new()
1080 gss_pipe = gss_pipe_get(clnt, gss_auth->mech->gm_name, in gss_create_new()
1086 gss_auth->gss_pipe[0] = gss_pipe; in gss_create_new()
1090 gss_pipe_free(gss_auth->gss_pipe[1]); in gss_create_new()
1094 gss_mech_put(gss_auth->mech); in gss_create_new()
1096 put_net_track(gss_auth->net, &gss_auth->ns_tracker); in gss_create_new()
1098 kfree(gss_auth->target_name); in gss_create_new()
1109 gss_pipe_free(gss_auth->gss_pipe[0]); in gss_free()
1110 gss_pipe_free(gss_auth->gss_pipe[1]); in gss_free()
1111 gss_mech_put(gss_auth->mech); in gss_free()
1112 put_net_track(gss_auth->net, &gss_auth->ns_tracker); in gss_free()
1113 kfree(gss_auth->target_name); in gss_free()
1130 kref_put(&gss_auth->kref, gss_free_callback); in gss_put_auth()
1139 if (hash_hashed(&gss_auth->hash)) { in gss_destroy()
1141 hash_del(&gss_auth->hash); in gss_destroy()
1145 gss_pipe_free(gss_auth->gss_pipe[0]); in gss_destroy()
1146 gss_auth->gss_pipe[0] = NULL; in gss_destroy()
1147 gss_pipe_free(gss_auth->gss_pipe[1]); in gss_destroy()
1148 gss_auth->gss_pipe[1] = NULL; in gss_destroy()
1176 if (gss_auth->client != clnt) in gss_auth_find_or_add_hashed()
1178 if (gss_auth->rpc_auth.au_flavor != args->pseudoflavor) in gss_auth_find_or_add_hashed()
1180 if (gss_auth->target_name != args->target_name) { in gss_auth_find_or_add_hashed()
1181 if (gss_auth->target_name == NULL) in gss_auth_find_or_add_hashed()
1183 if (args->target_name == NULL) in gss_auth_find_or_add_hashed()
1185 if (strcmp(gss_auth->target_name, args->target_name)) in gss_auth_find_or_add_hashed()
1188 if (!refcount_inc_not_zero(&gss_auth->rpc_auth.au_count)) in gss_auth_find_or_add_hashed()
1193 hash_add(gss_auth_hash_table, &new->hash, hashval); in gss_auth_find_or_add_hashed()
1215 gss_destroy(&new->rpc_auth); in gss_create_hashed()
1224 struct rpc_xprt_switch *xps = rcu_access_pointer(clnt->cl_xpi.xpi_xpswitch); in gss_create()
1226 while (clnt != clnt->cl_parent) { in gss_create()
1227 struct rpc_clnt *parent = clnt->cl_parent; in gss_create()
1229 if (rcu_access_pointer(parent->cl_xpi.xpi_xpswitch) != xps) in gss_create()
1237 return &gss_auth->rpc_auth; in gss_create()
1249 .cred = gss_cred->gc_base.cr_cred, in gss_dup_cred()
1252 rcu_dereference_protected(gss_cred->gc_ctx, 1); in gss_dup_cred()
1254 rpcauth_init_cred(&new->gc_base, &acred, in gss_dup_cred()
1255 &gss_auth->rpc_auth, in gss_dup_cred()
1257 new->gc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE; in gss_dup_cred()
1258 new->gc_service = gss_cred->gc_service; in gss_dup_cred()
1259 new->gc_principal = gss_cred->gc_principal; in gss_dup_cred()
1260 kref_get(&gss_auth->kref); in gss_dup_cred()
1261 rcu_assign_pointer(new->gc_ctx, ctx); in gss_dup_cred()
1277 struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth); in gss_send_destroy_context()
1278 struct gss_cl_ctx *ctx = rcu_dereference_protected(gss_cred->gc_ctx, 1); in gss_send_destroy_context()
1284 ctx->gc_proc = RPC_GSS_PROC_DESTROY; in gss_send_destroy_context()
1287 task = rpc_call_null(gss_auth->client, &new->gc_base, in gss_send_destroy_context()
1292 put_rpccred(&new->gc_base); in gss_send_destroy_context()
1302 gss_delete_sec_context(&ctx->gc_gss_ctx); in gss_do_free_ctx()
1303 kfree(ctx->gc_wire_ctx.data); in gss_do_free_ctx()
1304 kfree(ctx->gc_acceptor.data); in gss_do_free_ctx()
1318 call_rcu(&ctx->gc_rcu, gss_free_ctx_callback); in gss_free_ctx()
1338 struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth); in gss_destroy_nullcred()
1339 struct gss_cl_ctx *ctx = rcu_dereference_protected(gss_cred->gc_ctx, 1); in gss_destroy_nullcred()
1341 RCU_INIT_POINTER(gss_cred->gc_ctx, NULL); in gss_destroy_nullcred()
1342 put_cred(cred->cr_cred); in gss_destroy_nullcred()
1343 call_rcu(&cred->cr_rcu, gss_free_cred_callback); in gss_destroy_nullcred()
1352 if (test_and_clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0) in gss_destroy_cred()
1360 return hash_64(from_kuid(&init_user_ns, acred->cred->fsuid), hashbits); in gss_hash_cred()
1378 int err = -ENOMEM; in gss_create_cred()
1383 rpcauth_init_cred(&cred->gc_base, acred, auth, &gss_credops); in gss_create_cred()
1388 cred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_NEW; in gss_create_cred()
1389 cred->gc_service = gss_auth->service; in gss_create_cred()
1390 cred->gc_principal = acred->principal; in gss_create_cred()
1391 kref_get(&gss_auth->kref); in gss_create_cred()
1392 return &cred->gc_base; in gss_create_cred()
1407 } while (err == -EAGAIN); in gss_cred_init()
1421 ctx = rcu_dereference(gss_cred->gc_ctx); in gss_stringify_acceptor()
1425 len = ctx->gc_acceptor.len; in gss_stringify_acceptor()
1437 ctx = rcu_dereference(gss_cred->gc_ctx); in gss_stringify_acceptor()
1440 if (!ctx || !ctx->gc_acceptor.len) { in gss_stringify_acceptor()
1446 acceptor = &ctx->gc_acceptor; in gss_stringify_acceptor()
1452 if (len < acceptor->len) { in gss_stringify_acceptor()
1453 len = acceptor->len; in gss_stringify_acceptor()
1459 memcpy(string, acceptor->data, acceptor->len); in gss_stringify_acceptor()
1460 string[acceptor->len] = '\0'; in gss_stringify_acceptor()
1467 * Returns -EACCES if GSS context is NULL or will expire within the
1479 ctx = rcu_dereference(gss_cred->gc_ctx); in gss_key_timeout()
1480 if (!ctx || time_after(timeout, ctx->gc_expiry)) in gss_key_timeout()
1481 ret = -EACCES; in gss_key_timeout()
1494 if (test_bit(RPCAUTH_CRED_NEW, &rc->cr_flags)) in gss_match()
1498 ctx = rcu_dereference(gss_cred->gc_ctx); in gss_match()
1499 if (!ctx || time_after(jiffies, ctx->gc_expiry)) { in gss_match()
1504 if (!test_bit(RPCAUTH_CRED_UPTODATE, &rc->cr_flags)) in gss_match()
1507 if (acred->principal != NULL) { in gss_match()
1508 if (gss_cred->gc_principal == NULL) in gss_match()
1510 ret = strcmp(acred->principal, gss_cred->gc_principal) == 0; in gss_match()
1512 if (gss_cred->gc_principal != NULL) in gss_match()
1514 ret = uid_eq(rc->cr_cred->fsuid, acred->cred->fsuid); in gss_match()
1523 * pre-computed version of the verifier because the seqno, which
1524 * is different every time, is included in the MIC.
1528 struct rpc_rqst *req = task->tk_rqstp; in gss_marshal()
1529 struct rpc_cred *cred = req->rq_cred; in gss_marshal()
1535 struct xdr_netobj mic; in gss_marshal() local
1544 ctx->gc_wire_ctx.len); in gss_marshal()
1550 spin_lock(&ctx->gc_seq_lock); in gss_marshal()
1551 seqno = (ctx->gc_seq < MAXSEQ) ? ctx->gc_seq++ : MAXSEQ; in gss_marshal()
1553 spin_unlock(&ctx->gc_seq_lock); in gss_marshal()
1554 if (*req->rq_seqnos == MAXSEQ) in gss_marshal()
1559 *p++ = cpu_to_be32(ctx->gc_proc); in gss_marshal()
1560 *p++ = cpu_to_be32(*req->rq_seqnos); in gss_marshal()
1561 *p++ = cpu_to_be32(gss_cred->gc_service); in gss_marshal()
1562 p = xdr_encode_netobj(p, &ctx->gc_wire_ctx); in gss_marshal()
1563 *cred_len = cpu_to_be32((p - (cred_len + 1)) << 2); in gss_marshal()
1567 /* We compute the checksum for the verifier over the xdr-encoded bytes in gss_marshal()
1569 iov.iov_base = req->rq_snd_buf.head[0].iov_base; in gss_marshal()
1570 iov.iov_len = (u8 *)p - (u8 *)iov.iov_base; in gss_marshal()
1577 mic.data = (u8 *)(p + 1); in gss_marshal()
1578 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &verf_buf, &mic); in gss_marshal()
1583 if (xdr_stream_encode_opaque_inline(xdr, (void **)&p, mic.len) < 0) in gss_marshal()
1590 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in gss_marshal()
1591 status = -EKEYEXPIRED; in gss_marshal()
1594 status = -EMSGSIZE; in gss_marshal()
1598 status = -EIO; in gss_marshal()
1604 struct rpc_cred *oldcred = task->tk_rqstp->rq_cred; in gss_renew_cred()
1608 struct rpc_auth *auth = oldcred->cr_auth; in gss_renew_cred()
1610 .cred = oldcred->cr_cred, in gss_renew_cred()
1611 .principal = gss_cred->gc_principal, in gss_renew_cred()
1619 task->tk_rqstp->rq_cred = new; in gss_renew_cred()
1626 if (test_bit(RPCAUTH_CRED_NEGATIVE, &cred->cr_flags)) { in gss_cred_is_negative_entry()
1632 begin = gss_cred->gc_upcall_timestamp; in gss_cred_is_negative_entry()
1642 * Refresh credentials. XXX - finish
1647 struct rpc_cred *cred = task->tk_rqstp->rq_cred; in gss_refresh()
1651 return -EKEYEXPIRED; in gss_refresh()
1653 if (!test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) && in gss_refresh()
1654 !test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags)) { in gss_refresh()
1658 cred = task->tk_rqstp->rq_cred; in gss_refresh()
1661 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags)) in gss_refresh()
1679 struct xdr_netobj mic; in gss_validate_seqno_mic() local
1685 mic.data = (u8 *)p; in gss_validate_seqno_mic()
1686 mic.len = len; in gss_validate_seqno_mic()
1687 return gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic); in gss_validate_seqno_mic()
1693 struct rpc_cred *cred = task->tk_rqstp->rq_cred; in gss_validate()
1715 maj_stat = gss_validate_seqno_mic(ctx, task->tk_rqstp->rq_seqnos[0], seq, p, len); in gss_validate()
1716 /* RFC 2203 5.3.3.1 - compute the checksum of each sequence number in the cache */ in gss_validate()
1717 while (unlikely(maj_stat == GSS_S_BAD_SIG && i < task->tk_rqstp->rq_seqno_count)) in gss_validate()
1718 maj_stat = gss_validate_seqno_mic(ctx, task->tk_rqstp->rq_seqnos[i++], seq, p, len); in gss_validate()
1720 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in gss_validate()
1726 if (test_bit(RPCAUTH_AUTH_UPDATE_SLACK, &cred->cr_auth->au_flags)) in gss_validate()
1727 cred->cr_auth->au_verfsize = XDR_QUADLEN(len) + 2; in gss_validate()
1735 status = -EIO; in gss_validate()
1739 status = -EACCES; in gss_validate()
1747 struct rpc_rqst *rqstp = task->tk_rqstp; in gss_wrap_req_integ()
1748 struct xdr_buf integ_buf, *snd_buf = &rqstp->rq_snd_buf; in gss_wrap_req_integ()
1749 struct xdr_netobj mic; in gss_wrap_req_integ() local
1757 *p = cpu_to_be32(*rqstp->rq_seqnos); in gss_wrap_req_integ()
1762 offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; in gss_wrap_req_integ()
1764 offset, snd_buf->len - offset)) in gss_wrap_req_integ()
1771 mic.data = (u8 *)(p + 1); in gss_wrap_req_integ()
1772 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &integ_buf, &mic); in gss_wrap_req_integ()
1774 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in gss_wrap_req_integ()
1777 /* Check that the trailing MIC fit in the buffer, after the fact */ in gss_wrap_req_integ()
1778 if (xdr_stream_encode_opaque_inline(xdr, (void **)&p, mic.len) < 0) in gss_wrap_req_integ()
1782 return -EMSGSIZE; in gss_wrap_req_integ()
1785 return -EIO; in gss_wrap_req_integ()
1793 for (i=0; i < rqstp->rq_enc_pages_num; i++) in priv_release_snd_buf()
1794 __free_page(rqstp->rq_enc_pages[i]); in priv_release_snd_buf()
1795 kfree(rqstp->rq_enc_pages); in priv_release_snd_buf()
1796 rqstp->rq_release_snd_buf = NULL; in priv_release_snd_buf()
1802 struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; in alloc_enc_pages()
1805 if (rqstp->rq_release_snd_buf) in alloc_enc_pages()
1806 rqstp->rq_release_snd_buf(rqstp); in alloc_enc_pages()
1808 if (snd_buf->page_len == 0) { in alloc_enc_pages()
1809 rqstp->rq_enc_pages_num = 0; in alloc_enc_pages()
1813 first = snd_buf->page_base >> PAGE_SHIFT; in alloc_enc_pages()
1814 last = (snd_buf->page_base + snd_buf->page_len - 1) >> PAGE_SHIFT; in alloc_enc_pages()
1815 rqstp->rq_enc_pages_num = last - first + 1 + 1; in alloc_enc_pages()
1816 rqstp->rq_enc_pages in alloc_enc_pages()
1817 = kmalloc_array(rqstp->rq_enc_pages_num, in alloc_enc_pages()
1820 if (!rqstp->rq_enc_pages) in alloc_enc_pages()
1822 for (i=0; i < rqstp->rq_enc_pages_num; i++) { in alloc_enc_pages()
1823 rqstp->rq_enc_pages[i] = alloc_page(GFP_KERNEL); in alloc_enc_pages()
1824 if (rqstp->rq_enc_pages[i] == NULL) in alloc_enc_pages()
1827 rqstp->rq_release_snd_buf = priv_release_snd_buf; in alloc_enc_pages()
1830 rqstp->rq_enc_pages_num = i; in alloc_enc_pages()
1833 return -EAGAIN; in alloc_enc_pages()
1840 struct rpc_rqst *rqstp = task->tk_rqstp; in gss_wrap_req_priv()
1841 struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; in gss_wrap_req_priv()
1849 status = -EIO; in gss_wrap_req_priv()
1854 *p = cpu_to_be32(*rqstp->rq_seqnos); in gss_wrap_req_priv()
1862 first = snd_buf->page_base >> PAGE_SHIFT; in gss_wrap_req_priv()
1863 inpages = snd_buf->pages + first; in gss_wrap_req_priv()
1864 snd_buf->pages = rqstp->rq_enc_pages; in gss_wrap_req_priv()
1865 snd_buf->page_base -= first << PAGE_SHIFT; in gss_wrap_req_priv()
1872 if (snd_buf->page_len || snd_buf->tail[0].iov_len) { in gss_wrap_req_priv()
1875 tmp = page_address(rqstp->rq_enc_pages[rqstp->rq_enc_pages_num - 1]); in gss_wrap_req_priv()
1876 memcpy(tmp, snd_buf->tail[0].iov_base, snd_buf->tail[0].iov_len); in gss_wrap_req_priv()
1877 snd_buf->tail[0].iov_base = tmp; in gss_wrap_req_priv()
1879 offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; in gss_wrap_req_priv()
1880 maj_stat = gss_wrap(ctx->gc_gss_ctx, offset, snd_buf, inpages); in gss_wrap_req_priv()
1882 if (unlikely(snd_buf->len > snd_buf->buflen)) { in gss_wrap_req_priv()
1883 status = -EIO; in gss_wrap_req_priv()
1889 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in gss_wrap_req_priv()
1893 *opaque_len = cpu_to_be32(snd_buf->len - offset); in gss_wrap_req_priv()
1895 if (snd_buf->page_len || snd_buf->tail[0].iov_len) in gss_wrap_req_priv()
1896 iov = snd_buf->tail; in gss_wrap_req_priv()
1898 iov = snd_buf->head; in gss_wrap_req_priv()
1899 p = iov->iov_base + iov->iov_len; in gss_wrap_req_priv()
1900 pad = xdr_pad_size(snd_buf->len - offset); in gss_wrap_req_priv()
1902 iov->iov_len += pad; in gss_wrap_req_priv()
1903 snd_buf->len += pad; in gss_wrap_req_priv()
1910 return -EIO; in gss_wrap_req_priv()
1915 struct rpc_cred *cred = task->tk_rqstp->rq_cred; in gss_wrap_req()
1921 status = -EIO; in gss_wrap_req()
1922 if (ctx->gc_proc != RPC_GSS_PROC_DATA) { in gss_wrap_req()
1929 switch (gss_cred->gc_service) { in gss_wrap_req()
1940 status = -EIO; in gss_wrap_req()
1948 * gss_update_rslack - Possibly update RPC receive buffer size estimates
1958 struct rpc_auth *auth = cred->cr_auth; in gss_update_rslack()
1960 if (test_and_clear_bit(RPCAUTH_AUTH_UPDATE_SLACK, &auth->au_flags)) { in gss_update_rslack()
1961 auth->au_ralign = auth->au_verfsize + before; in gss_update_rslack()
1962 auth->au_rslack = auth->au_verfsize + after; in gss_update_rslack()
1992 struct xdr_buf gss_data, *rcv_buf = &rqstp->rq_rcv_buf; in gss_unwrap_resp_integ()
1994 struct xdr_netobj mic; in gss_unwrap_resp_integ() local
1997 ret = -EIO; in gss_unwrap_resp_integ()
1998 mic.data = NULL; in gss_unwrap_resp_integ()
2005 offset = rcv_buf->len - xdr_stream_remaining(xdr); in gss_unwrap_resp_integ()
2008 if (seqno != *rqstp->rq_seqnos) in gss_unwrap_resp_integ()
2026 if (offset + len > rcv_buf->len) in gss_unwrap_resp_integ()
2028 mic.len = len; in gss_unwrap_resp_integ()
2029 mic.data = kmalloc(len, GFP_KERNEL); in gss_unwrap_resp_integ()
2030 if (ZERO_OR_NULL_PTR(mic.data)) in gss_unwrap_resp_integ()
2032 if (read_bytes_from_xdr_buf(rcv_buf, offset, mic.data, mic.len)) in gss_unwrap_resp_integ()
2035 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &gss_data, &mic); in gss_unwrap_resp_integ()
2037 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in gss_unwrap_resp_integ()
2041 gss_update_rslack(task, cred, 2, 2 + 1 + XDR_QUADLEN(mic.len)); in gss_unwrap_resp_integ()
2045 kfree(mic.data); in gss_unwrap_resp_integ()
2052 trace_rpcgss_bad_seqno(task, *rqstp->rq_seqnos, seqno); in gss_unwrap_resp_integ()
2064 struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf; in gss_unwrap_resp_priv()
2065 struct kvec *head = rqstp->rq_rcv_buf.head; in gss_unwrap_resp_priv()
2073 offset = (u8 *)(p) - (u8 *)head->iov_base; in gss_unwrap_resp_priv()
2074 if (offset + opaque_len > rcv_buf->len) in gss_unwrap_resp_priv()
2077 maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, in gss_unwrap_resp_priv()
2080 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in gss_unwrap_resp_priv()
2084 if (be32_to_cpup(p++) != *rqstp->rq_seqnos) in gss_unwrap_resp_priv()
2092 gss_update_rslack(task, cred, 2 + ctx->gc_gss_ctx->align, in gss_unwrap_resp_priv()
2093 2 + ctx->gc_gss_ctx->slack); in gss_unwrap_resp_priv()
2098 return -EIO; in gss_unwrap_resp_priv()
2100 trace_rpcgss_bad_seqno(task, *rqstp->rq_seqnos, be32_to_cpup(--p)); in gss_unwrap_resp_priv()
2101 return -EIO; in gss_unwrap_resp_priv()
2104 return -EIO; in gss_unwrap_resp_priv()
2110 return (s32)(new - old) > 0; in gss_seq_is_newer()
2116 struct rpc_rqst *req = task->tk_rqstp; in gss_xmit_need_reencode()
2117 struct rpc_cred *cred = req->rq_cred; in gss_xmit_need_reencode()
2125 if (gss_seq_is_newer(*req->rq_seqnos, READ_ONCE(ctx->gc_seq))) in gss_xmit_need_reencode()
2128 seq_xmit = READ_ONCE(ctx->gc_seq_xmit); in gss_xmit_need_reencode()
2129 while (gss_seq_is_newer(*req->rq_seqnos, seq_xmit)) { in gss_xmit_need_reencode()
2132 seq_xmit = cmpxchg(&ctx->gc_seq_xmit, tmp, *req->rq_seqnos); in gss_xmit_need_reencode()
2139 win = ctx->gc_win; in gss_xmit_need_reencode()
2141 ret = !gss_seq_is_newer(*req->rq_seqnos, seq_xmit - win); in gss_xmit_need_reencode()
2153 struct rpc_rqst *rqstp = task->tk_rqstp; in gss_unwrap_resp()
2154 struct rpc_cred *cred = rqstp->rq_cred; in gss_unwrap_resp()
2158 int status = -EIO; in gss_unwrap_resp()
2160 if (ctx->gc_proc != RPC_GSS_PROC_DATA) in gss_unwrap_resp()
2162 switch (gss_cred->gc_service) { in gss_unwrap_resp()
2288 MODULE_ALIAS("rpc-auth-6");