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()
890 struct rpc_pipe *pipe = gss_pipe->pipe; in gss_pipe_dentry_destroy()
892 if (pipe->dentry != NULL) { in gss_pipe_dentry_destroy()
893 rpc_unlink(pipe->dentry); in gss_pipe_dentry_destroy()
894 pipe->dentry = NULL; in gss_pipe_dentry_destroy()
901 struct gss_pipe *p = pdo->pdo_data; in gss_pipe_dentry_create()
904 dentry = rpc_mkpipe_dentry(dir, p->name, p->clnt, p->pipe); in gss_pipe_dentry_create()
907 p->pipe->dentry = dentry; in gss_pipe_dentry_create()
921 int err = -ENOMEM; in gss_pipe_alloc()
926 p->pipe = rpc_mkpipe_data(upcall_ops, RPC_PIPE_WAIT_FOR_OPEN); in gss_pipe_alloc()
927 if (IS_ERR(p->pipe)) { in gss_pipe_alloc()
928 err = PTR_ERR(p->pipe); in gss_pipe_alloc()
931 p->name = name; in gss_pipe_alloc()
932 p->clnt = clnt; in gss_pipe_alloc()
933 kref_init(&p->kref); in gss_pipe_alloc()
934 rpc_init_pipe_dir_object(&p->pdo, in gss_pipe_alloc()
955 if (pdo->pdo_ops != &gss_pipe_dir_object_ops) in gss_pipe_match_pdo()
958 if (strcmp(gss_pipe->name, args->name) != 0) in gss_pipe_match_pdo()
960 if (!kref_get_unless_zero(&gss_pipe->kref)) in gss_pipe_match_pdo()
970 gss_pipe = gss_pipe_alloc(args->clnt, args->name, args->upcall_ops); in gss_pipe_alloc_pdo()
972 return &gss_pipe->pdo; in gss_pipe_alloc_pdo()
989 &clnt->cl_pipedir_objects, in gss_pipe_get()
995 return ERR_PTR(-ENOMEM); in gss_pipe_get()
1000 struct rpc_clnt *clnt = p->clnt; in __gss_pipe_free()
1004 &clnt->cl_pipedir_objects, in __gss_pipe_free()
1005 &p->pdo); in __gss_pipe_free()
1006 rpc_destroy_pipe_data(p->pipe); in __gss_pipe_free()
1020 kref_put(&p->kref, __gss_pipe_release); in gss_pipe_free()
1030 rpc_authflavor_t flavor = args->pseudoflavor; in gss_create_new()
1034 int err = -ENOMEM; /* XXX? */ in gss_create_new()
1040 INIT_HLIST_NODE(&gss_auth->hash); in gss_create_new()
1041 gss_auth->target_name = NULL; in gss_create_new()
1042 if (args->target_name) { in gss_create_new()
1043 gss_auth->target_name = kstrdup(args->target_name, GFP_KERNEL); in gss_create_new()
1044 if (gss_auth->target_name == NULL) in gss_create_new()
1047 gss_auth->client = clnt; in gss_create_new()
1048 gss_auth->net = get_net_track(rpc_net_ns(clnt), &gss_auth->ns_tracker, in gss_create_new()
1050 err = -EINVAL; in gss_create_new()
1051 gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor); in gss_create_new()
1052 if (!gss_auth->mech) in gss_create_new()
1054 gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor); in gss_create_new()
1055 if (gss_auth->service == 0) in gss_create_new()
1057 if (!gssd_running(gss_auth->net)) in gss_create_new()
1059 auth = &gss_auth->rpc_auth; in gss_create_new()
1060 auth->au_cslack = GSS_CRED_SLACK >> 2; in gss_create_new()
1062 auth->au_rslack = GSS_KRB5_MAX_SLACK_NEEDED >> 2; in gss_create_new()
1063 auth->au_verfsize = GSS_VERF_SLACK >> 2; in gss_create_new()
1064 auth->au_ralign = GSS_VERF_SLACK >> 2; in gss_create_new()
1065 __set_bit(RPCAUTH_AUTH_UPDATE_SLACK, &auth->au_flags); in gss_create_new()
1066 auth->au_ops = &authgss_ops; in gss_create_new()
1067 auth->au_flavor = flavor; in gss_create_new()
1068 if (gss_pseudoflavor_to_datatouch(gss_auth->mech, flavor)) in gss_create_new()
1069 __set_bit(RPCAUTH_AUTH_DATATOUCH, &auth->au_flags); in gss_create_new()
1070 refcount_set(&auth->au_count, 1); in gss_create_new()
1071 kref_init(&gss_auth->kref); in gss_create_new()
1087 gss_auth->gss_pipe[1] = gss_pipe; in gss_create_new()
1089 gss_pipe = gss_pipe_get(clnt, gss_auth->mech->gm_name, in gss_create_new()
1095 gss_auth->gss_pipe[0] = gss_pipe; in gss_create_new()
1099 gss_pipe_free(gss_auth->gss_pipe[1]); in gss_create_new()
1103 gss_mech_put(gss_auth->mech); in gss_create_new()
1105 put_net_track(gss_auth->net, &gss_auth->ns_tracker); in gss_create_new()
1107 kfree(gss_auth->target_name); in gss_create_new()
1118 gss_pipe_free(gss_auth->gss_pipe[0]); in gss_free()
1119 gss_pipe_free(gss_auth->gss_pipe[1]); in gss_free()
1120 gss_mech_put(gss_auth->mech); in gss_free()
1121 put_net_track(gss_auth->net, &gss_auth->ns_tracker); in gss_free()
1122 kfree(gss_auth->target_name); in gss_free()
1139 kref_put(&gss_auth->kref, gss_free_callback); in gss_put_auth()
1148 if (hash_hashed(&gss_auth->hash)) { in gss_destroy()
1150 hash_del(&gss_auth->hash); in gss_destroy()
1154 gss_pipe_free(gss_auth->gss_pipe[0]); in gss_destroy()
1155 gss_auth->gss_pipe[0] = NULL; in gss_destroy()
1156 gss_pipe_free(gss_auth->gss_pipe[1]); in gss_destroy()
1157 gss_auth->gss_pipe[1] = NULL; in gss_destroy()
1185 if (gss_auth->client != clnt) in gss_auth_find_or_add_hashed()
1187 if (gss_auth->rpc_auth.au_flavor != args->pseudoflavor) in gss_auth_find_or_add_hashed()
1189 if (gss_auth->target_name != args->target_name) { in gss_auth_find_or_add_hashed()
1190 if (gss_auth->target_name == NULL) in gss_auth_find_or_add_hashed()
1192 if (args->target_name == NULL) in gss_auth_find_or_add_hashed()
1194 if (strcmp(gss_auth->target_name, args->target_name)) in gss_auth_find_or_add_hashed()
1197 if (!refcount_inc_not_zero(&gss_auth->rpc_auth.au_count)) in gss_auth_find_or_add_hashed()
1202 hash_add(gss_auth_hash_table, &new->hash, hashval); in gss_auth_find_or_add_hashed()
1224 gss_destroy(&new->rpc_auth); in gss_create_hashed()
1233 struct rpc_xprt_switch *xps = rcu_access_pointer(clnt->cl_xpi.xpi_xpswitch); in gss_create()
1235 while (clnt != clnt->cl_parent) { in gss_create()
1236 struct rpc_clnt *parent = clnt->cl_parent; in gss_create()
1238 if (rcu_access_pointer(parent->cl_xpi.xpi_xpswitch) != xps) in gss_create()
1246 return &gss_auth->rpc_auth; in gss_create()
1258 .cred = gss_cred->gc_base.cr_cred, in gss_dup_cred()
1261 rcu_dereference_protected(gss_cred->gc_ctx, 1); in gss_dup_cred()
1263 rpcauth_init_cred(&new->gc_base, &acred, in gss_dup_cred()
1264 &gss_auth->rpc_auth, in gss_dup_cred()
1266 new->gc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE; in gss_dup_cred()
1267 new->gc_service = gss_cred->gc_service; in gss_dup_cred()
1268 new->gc_principal = gss_cred->gc_principal; in gss_dup_cred()
1269 kref_get(&gss_auth->kref); in gss_dup_cred()
1270 rcu_assign_pointer(new->gc_ctx, ctx); in gss_dup_cred()
1286 struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth); in gss_send_destroy_context()
1287 struct gss_cl_ctx *ctx = rcu_dereference_protected(gss_cred->gc_ctx, 1); in gss_send_destroy_context()
1293 ctx->gc_proc = RPC_GSS_PROC_DESTROY; in gss_send_destroy_context()
1296 task = rpc_call_null(gss_auth->client, &new->gc_base, in gss_send_destroy_context()
1301 put_rpccred(&new->gc_base); in gss_send_destroy_context()
1311 gss_delete_sec_context(&ctx->gc_gss_ctx); in gss_do_free_ctx()
1312 kfree(ctx->gc_wire_ctx.data); in gss_do_free_ctx()
1313 kfree(ctx->gc_acceptor.data); in gss_do_free_ctx()
1327 call_rcu(&ctx->gc_rcu, gss_free_ctx_callback); in gss_free_ctx()
1347 struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth); in gss_destroy_nullcred()
1348 struct gss_cl_ctx *ctx = rcu_dereference_protected(gss_cred->gc_ctx, 1); in gss_destroy_nullcred()
1350 RCU_INIT_POINTER(gss_cred->gc_ctx, NULL); in gss_destroy_nullcred()
1351 put_cred(cred->cr_cred); in gss_destroy_nullcred()
1352 call_rcu(&cred->cr_rcu, gss_free_cred_callback); in gss_destroy_nullcred()
1361 if (test_and_clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0) in gss_destroy_cred()
1369 return hash_64(from_kuid(&init_user_ns, acred->cred->fsuid), hashbits); in gss_hash_cred()
1387 int err = -ENOMEM; in gss_create_cred()
1392 rpcauth_init_cred(&cred->gc_base, acred, auth, &gss_credops); in gss_create_cred()
1397 cred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_NEW; in gss_create_cred()
1398 cred->gc_service = gss_auth->service; in gss_create_cred()
1399 cred->gc_principal = acred->principal; in gss_create_cred()
1400 kref_get(&gss_auth->kref); in gss_create_cred()
1401 return &cred->gc_base; in gss_create_cred()
1416 } while (err == -EAGAIN); in gss_cred_init()
1430 ctx = rcu_dereference(gss_cred->gc_ctx); in gss_stringify_acceptor()
1434 len = ctx->gc_acceptor.len; in gss_stringify_acceptor()
1446 ctx = rcu_dereference(gss_cred->gc_ctx); in gss_stringify_acceptor()
1449 if (!ctx || !ctx->gc_acceptor.len) { in gss_stringify_acceptor()
1455 acceptor = &ctx->gc_acceptor; in gss_stringify_acceptor()
1461 if (len < acceptor->len) { in gss_stringify_acceptor()
1462 len = acceptor->len; in gss_stringify_acceptor()
1468 memcpy(string, acceptor->data, acceptor->len); in gss_stringify_acceptor()
1469 string[acceptor->len] = '\0'; in gss_stringify_acceptor()
1476 * Returns -EACCES if GSS context is NULL or will expire within the
1488 ctx = rcu_dereference(gss_cred->gc_ctx); in gss_key_timeout()
1489 if (!ctx || time_after(timeout, ctx->gc_expiry)) in gss_key_timeout()
1490 ret = -EACCES; in gss_key_timeout()
1503 if (test_bit(RPCAUTH_CRED_NEW, &rc->cr_flags)) in gss_match()
1507 ctx = rcu_dereference(gss_cred->gc_ctx); in gss_match()
1508 if (!ctx || time_after(jiffies, ctx->gc_expiry)) { in gss_match()
1513 if (!test_bit(RPCAUTH_CRED_UPTODATE, &rc->cr_flags)) in gss_match()
1516 if (acred->principal != NULL) { in gss_match()
1517 if (gss_cred->gc_principal == NULL) in gss_match()
1519 ret = strcmp(acred->principal, gss_cred->gc_principal) == 0; in gss_match()
1521 if (gss_cred->gc_principal != NULL) in gss_match()
1523 ret = uid_eq(rc->cr_cred->fsuid, acred->cred->fsuid); in gss_match()
1532 * pre-computed version of the verifier because the seqno, which
1533 * is different every time, is included in the MIC.
1537 struct rpc_rqst *req = task->tk_rqstp; in gss_marshal()
1538 struct rpc_cred *cred = req->rq_cred; in gss_marshal()
1544 struct xdr_netobj mic; in gss_marshal() local
1552 ctx->gc_wire_ctx.len); in gss_marshal()
1558 spin_lock(&ctx->gc_seq_lock); in gss_marshal()
1559 req->rq_seqno = (ctx->gc_seq < MAXSEQ) ? ctx->gc_seq++ : MAXSEQ; in gss_marshal()
1560 spin_unlock(&ctx->gc_seq_lock); in gss_marshal()
1561 if (req->rq_seqno == MAXSEQ) in gss_marshal()
1566 *p++ = cpu_to_be32(ctx->gc_proc); in gss_marshal()
1567 *p++ = cpu_to_be32(req->rq_seqno); in gss_marshal()
1568 *p++ = cpu_to_be32(gss_cred->gc_service); in gss_marshal()
1569 p = xdr_encode_netobj(p, &ctx->gc_wire_ctx); in gss_marshal()
1570 *cred_len = cpu_to_be32((p - (cred_len + 1)) << 2); in gss_marshal()
1574 /* We compute the checksum for the verifier over the xdr-encoded bytes in gss_marshal()
1576 iov.iov_base = req->rq_snd_buf.head[0].iov_base; in gss_marshal()
1577 iov.iov_len = (u8 *)p - (u8 *)iov.iov_base; in gss_marshal()
1584 mic.data = (u8 *)(p + 1); in gss_marshal()
1585 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &verf_buf, &mic); in gss_marshal()
1590 if (xdr_stream_encode_opaque_inline(xdr, (void **)&p, mic.len) < 0) in gss_marshal()
1597 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in gss_marshal()
1598 status = -EKEYEXPIRED; in gss_marshal()
1601 status = -EMSGSIZE; in gss_marshal()
1605 status = -EIO; in gss_marshal()
1611 struct rpc_cred *oldcred = task->tk_rqstp->rq_cred; in gss_renew_cred()
1615 struct rpc_auth *auth = oldcred->cr_auth; in gss_renew_cred()
1617 .cred = oldcred->cr_cred, in gss_renew_cred()
1618 .principal = gss_cred->gc_principal, in gss_renew_cred()
1626 task->tk_rqstp->rq_cred = new; in gss_renew_cred()
1633 if (test_bit(RPCAUTH_CRED_NEGATIVE, &cred->cr_flags)) { in gss_cred_is_negative_entry()
1639 begin = gss_cred->gc_upcall_timestamp; in gss_cred_is_negative_entry()
1649 * Refresh credentials. XXX - finish
1654 struct rpc_cred *cred = task->tk_rqstp->rq_cred; in gss_refresh()
1658 return -EKEYEXPIRED; in gss_refresh()
1660 if (!test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) && in gss_refresh()
1661 !test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags)) { in gss_refresh()
1665 cred = task->tk_rqstp->rq_cred; in gss_refresh()
1668 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags)) in gss_refresh()
1684 struct rpc_cred *cred = task->tk_rqstp->rq_cred; in gss_validate()
1689 struct xdr_netobj mic; in gss_validate() local
1708 *seq = cpu_to_be32(task->tk_rqstp->rq_seqno); in gss_validate()
1712 mic.data = (u8 *)p; in gss_validate()
1713 mic.len = len; in gss_validate()
1714 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic); in gss_validate()
1716 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in gss_validate()
1722 if (test_bit(RPCAUTH_AUTH_UPDATE_SLACK, &cred->cr_auth->au_flags)) in gss_validate()
1723 cred->cr_auth->au_verfsize = XDR_QUADLEN(len) + 2; in gss_validate()
1731 status = -EIO; in gss_validate()
1735 status = -EACCES; in gss_validate()
1743 struct rpc_rqst *rqstp = task->tk_rqstp; in gss_wrap_req_integ()
1744 struct xdr_buf integ_buf, *snd_buf = &rqstp->rq_snd_buf; in gss_wrap_req_integ()
1745 struct xdr_netobj mic; in gss_wrap_req_integ() local
1753 *p = cpu_to_be32(rqstp->rq_seqno); in gss_wrap_req_integ()
1758 offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; in gss_wrap_req_integ()
1760 offset, snd_buf->len - offset)) in gss_wrap_req_integ()
1767 mic.data = (u8 *)(p + 1); in gss_wrap_req_integ()
1768 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &integ_buf, &mic); in gss_wrap_req_integ()
1770 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in gss_wrap_req_integ()
1773 /* Check that the trailing MIC fit in the buffer, after the fact */ in gss_wrap_req_integ()
1774 if (xdr_stream_encode_opaque_inline(xdr, (void **)&p, mic.len) < 0) in gss_wrap_req_integ()
1778 return -EMSGSIZE; in gss_wrap_req_integ()
1781 return -EIO; in gss_wrap_req_integ()
1789 for (i=0; i < rqstp->rq_enc_pages_num; i++) in priv_release_snd_buf()
1790 __free_page(rqstp->rq_enc_pages[i]); in priv_release_snd_buf()
1791 kfree(rqstp->rq_enc_pages); in priv_release_snd_buf()
1792 rqstp->rq_release_snd_buf = NULL; in priv_release_snd_buf()
1798 struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; in alloc_enc_pages()
1801 if (rqstp->rq_release_snd_buf) in alloc_enc_pages()
1802 rqstp->rq_release_snd_buf(rqstp); in alloc_enc_pages()
1804 if (snd_buf->page_len == 0) { in alloc_enc_pages()
1805 rqstp->rq_enc_pages_num = 0; in alloc_enc_pages()
1809 first = snd_buf->page_base >> PAGE_SHIFT; in alloc_enc_pages()
1810 last = (snd_buf->page_base + snd_buf->page_len - 1) >> PAGE_SHIFT; in alloc_enc_pages()
1811 rqstp->rq_enc_pages_num = last - first + 1 + 1; in alloc_enc_pages()
1812 rqstp->rq_enc_pages in alloc_enc_pages()
1813 = kmalloc_array(rqstp->rq_enc_pages_num, in alloc_enc_pages()
1816 if (!rqstp->rq_enc_pages) in alloc_enc_pages()
1818 for (i=0; i < rqstp->rq_enc_pages_num; i++) { in alloc_enc_pages()
1819 rqstp->rq_enc_pages[i] = alloc_page(GFP_KERNEL); in alloc_enc_pages()
1820 if (rqstp->rq_enc_pages[i] == NULL) in alloc_enc_pages()
1823 rqstp->rq_release_snd_buf = priv_release_snd_buf; in alloc_enc_pages()
1826 rqstp->rq_enc_pages_num = i; in alloc_enc_pages()
1829 return -EAGAIN; in alloc_enc_pages()
1836 struct rpc_rqst *rqstp = task->tk_rqstp; in gss_wrap_req_priv()
1837 struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; in gss_wrap_req_priv()
1845 status = -EIO; in gss_wrap_req_priv()
1850 *p = cpu_to_be32(rqstp->rq_seqno); in gss_wrap_req_priv()
1858 first = snd_buf->page_base >> PAGE_SHIFT; in gss_wrap_req_priv()
1859 inpages = snd_buf->pages + first; in gss_wrap_req_priv()
1860 snd_buf->pages = rqstp->rq_enc_pages; in gss_wrap_req_priv()
1861 snd_buf->page_base -= first << PAGE_SHIFT; in gss_wrap_req_priv()
1868 if (snd_buf->page_len || snd_buf->tail[0].iov_len) { in gss_wrap_req_priv()
1871 tmp = page_address(rqstp->rq_enc_pages[rqstp->rq_enc_pages_num - 1]); in gss_wrap_req_priv()
1872 memcpy(tmp, snd_buf->tail[0].iov_base, snd_buf->tail[0].iov_len); in gss_wrap_req_priv()
1873 snd_buf->tail[0].iov_base = tmp; in gss_wrap_req_priv()
1875 offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; in gss_wrap_req_priv()
1876 maj_stat = gss_wrap(ctx->gc_gss_ctx, offset, snd_buf, inpages); in gss_wrap_req_priv()
1878 if (unlikely(snd_buf->len > snd_buf->buflen)) { in gss_wrap_req_priv()
1879 status = -EIO; in gss_wrap_req_priv()
1885 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in gss_wrap_req_priv()
1889 *opaque_len = cpu_to_be32(snd_buf->len - offset); in gss_wrap_req_priv()
1891 if (snd_buf->page_len || snd_buf->tail[0].iov_len) in gss_wrap_req_priv()
1892 iov = snd_buf->tail; in gss_wrap_req_priv()
1894 iov = snd_buf->head; in gss_wrap_req_priv()
1895 p = iov->iov_base + iov->iov_len; in gss_wrap_req_priv()
1896 pad = xdr_pad_size(snd_buf->len - offset); in gss_wrap_req_priv()
1898 iov->iov_len += pad; in gss_wrap_req_priv()
1899 snd_buf->len += pad; in gss_wrap_req_priv()
1906 return -EIO; in gss_wrap_req_priv()
1911 struct rpc_cred *cred = task->tk_rqstp->rq_cred; in gss_wrap_req()
1917 status = -EIO; in gss_wrap_req()
1918 if (ctx->gc_proc != RPC_GSS_PROC_DATA) { in gss_wrap_req()
1925 switch (gss_cred->gc_service) { in gss_wrap_req()
1936 status = -EIO; in gss_wrap_req()
1944 * gss_update_rslack - Possibly update RPC receive buffer size estimates
1954 struct rpc_auth *auth = cred->cr_auth; in gss_update_rslack()
1956 if (test_and_clear_bit(RPCAUTH_AUTH_UPDATE_SLACK, &auth->au_flags)) { in gss_update_rslack()
1957 auth->au_ralign = auth->au_verfsize + before; in gss_update_rslack()
1958 auth->au_rslack = auth->au_verfsize + after; in gss_update_rslack()
1988 struct xdr_buf gss_data, *rcv_buf = &rqstp->rq_rcv_buf; in gss_unwrap_resp_integ()
1990 struct xdr_netobj mic; in gss_unwrap_resp_integ() local
1993 ret = -EIO; in gss_unwrap_resp_integ()
1994 mic.data = NULL; in gss_unwrap_resp_integ()
2001 offset = rcv_buf->len - xdr_stream_remaining(xdr); in gss_unwrap_resp_integ()
2004 if (seqno != rqstp->rq_seqno) in gss_unwrap_resp_integ()
2022 if (offset + len > rcv_buf->len) in gss_unwrap_resp_integ()
2024 mic.len = len; in gss_unwrap_resp_integ()
2025 mic.data = kmalloc(len, GFP_KERNEL); in gss_unwrap_resp_integ()
2026 if (ZERO_OR_NULL_PTR(mic.data)) in gss_unwrap_resp_integ()
2028 if (read_bytes_from_xdr_buf(rcv_buf, offset, mic.data, mic.len)) in gss_unwrap_resp_integ()
2031 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &gss_data, &mic); in gss_unwrap_resp_integ()
2033 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in gss_unwrap_resp_integ()
2037 gss_update_rslack(task, cred, 2, 2 + 1 + XDR_QUADLEN(mic.len)); in gss_unwrap_resp_integ()
2041 kfree(mic.data); in gss_unwrap_resp_integ()
2048 trace_rpcgss_bad_seqno(task, rqstp->rq_seqno, seqno); in gss_unwrap_resp_integ()
2060 struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf; in gss_unwrap_resp_priv()
2061 struct kvec *head = rqstp->rq_rcv_buf.head; in gss_unwrap_resp_priv()
2069 offset = (u8 *)(p) - (u8 *)head->iov_base; in gss_unwrap_resp_priv()
2070 if (offset + opaque_len > rcv_buf->len) in gss_unwrap_resp_priv()
2073 maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, in gss_unwrap_resp_priv()
2076 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in gss_unwrap_resp_priv()
2080 if (be32_to_cpup(p++) != rqstp->rq_seqno) in gss_unwrap_resp_priv()
2088 gss_update_rslack(task, cred, 2 + ctx->gc_gss_ctx->align, in gss_unwrap_resp_priv()
2089 2 + ctx->gc_gss_ctx->slack); in gss_unwrap_resp_priv()
2094 return -EIO; in gss_unwrap_resp_priv()
2096 trace_rpcgss_bad_seqno(task, rqstp->rq_seqno, be32_to_cpup(--p)); in gss_unwrap_resp_priv()
2097 return -EIO; in gss_unwrap_resp_priv()
2100 return -EIO; in gss_unwrap_resp_priv()
2106 return (s32)(new - old) > 0; in gss_seq_is_newer()
2112 struct rpc_rqst *req = task->tk_rqstp; in gss_xmit_need_reencode()
2113 struct rpc_cred *cred = req->rq_cred; in gss_xmit_need_reencode()
2121 if (gss_seq_is_newer(req->rq_seqno, READ_ONCE(ctx->gc_seq))) in gss_xmit_need_reencode()
2124 seq_xmit = READ_ONCE(ctx->gc_seq_xmit); in gss_xmit_need_reencode()
2125 while (gss_seq_is_newer(req->rq_seqno, seq_xmit)) { in gss_xmit_need_reencode()
2128 seq_xmit = cmpxchg(&ctx->gc_seq_xmit, tmp, req->rq_seqno); in gss_xmit_need_reencode()
2135 win = ctx->gc_win; in gss_xmit_need_reencode()
2137 ret = !gss_seq_is_newer(req->rq_seqno, seq_xmit - win); in gss_xmit_need_reencode()
2149 struct rpc_rqst *rqstp = task->tk_rqstp; in gss_unwrap_resp()
2150 struct rpc_cred *cred = rqstp->rq_cred; in gss_unwrap_resp()
2154 int status = -EIO; in gss_unwrap_resp()
2156 if (ctx->gc_proc != RPC_GSS_PROC_DATA) in gss_unwrap_resp()
2158 switch (gss_cred->gc_service) { in gss_unwrap_resp()
2284 MODULE_ALIAS("rpc-auth-6");