Lines Matching +full:mic +full:- +full:offset

1 // SPDX-License-Identifier: BSD-3-Clause
54 * using integrity (two 4-byte integers): */
79 * for the new text-based upcall; dentry[0] is named after the
81 * backwards-compatibility with older gssd's.
100 refcount_inc(&ctx->count); in gss_get_ctx()
107 if (refcount_dec_and_test(&ctx->count)) in gss_put_ctx()
114 * and a new one is protected by the pipe->lock.
121 if (!test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags)) in gss_cred_set_ctx()
124 rcu_assign_pointer(gss_cred->gc_ctx, ctx); in gss_cred_set_ctx()
125 set_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in gss_cred_set_ctx()
127 clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags); in gss_cred_set_ctx()
137 ctx = rcu_dereference(gss_cred->gc_ctx); in gss_cred_get_ctx()
151 ctx->gc_proc = RPC_GSS_PROC_DATA; in gss_alloc_context()
152 ctx->gc_seq = 1; /* NetApp 6.4R1 doesn't accept seq. no. 0 */ in gss_alloc_context()
153 spin_lock_init(&ctx->gc_seq_lock); in gss_alloc_context()
154 refcount_set(&ctx->count,1); in gss_alloc_context()
171 * credential - e.g. the remaining TGT lifetime for Kerberos or in gss_fill_context()
172 * the -t value passed to GSSD. in gss_fill_context()
179 ctx->gc_expiry = now + ((unsigned long)timeout * HZ); in gss_fill_context()
186 ctx->gc_win = window_size; in gss_fill_context()
187 /* gssd signals an error by passing ctx->gc_win = 0: */ in gss_fill_context()
188 if (ctx->gc_win == 0) { in gss_fill_context()
191 * than -EKEYEXPIRED gets converted to -EACCES. in gss_fill_context()
195 p = (ret == -EKEYEXPIRED) ? ERR_PTR(-EKEYEXPIRED) : in gss_fill_context()
196 ERR_PTR(-EACCES); in gss_fill_context()
200 p = simple_get_netobj(p, end, &ctx->gc_wire_ctx); in gss_fill_context()
209 p = ERR_PTR(-EFAULT); in gss_fill_context()
212 ret = gss_import_sec_context(p, seclen, gm, &ctx->gc_gss_ctx, NULL, GFP_KERNEL); in gss_fill_context()
226 p = simple_get_netobj(q, end, &ctx->gc_acceptor); in gss_fill_context()
230 trace_rpcgss_context(window_size, ctx->gc_expiry, now, timeout, in gss_fill_context()
231 ctx->gc_acceptor.len, ctx->gc_acceptor.data); in gss_fill_context()
263 if (sn->pipe_version >= 0) { in get_pipe_version()
264 atomic_inc(&sn->pipe_users); in get_pipe_version()
265 ret = sn->pipe_version; in get_pipe_version()
267 ret = -EAGAIN; in get_pipe_version()
276 if (atomic_dec_and_lock(&sn->pipe_users, &pipe_version_lock)) { in put_pipe_version()
277 sn->pipe_version = -1; in put_pipe_version()
285 struct net *net = gss_msg->auth->net; in gss_release_msg()
286 if (!refcount_dec_and_test(&gss_msg->count)) in gss_release_msg()
289 BUG_ON(!list_empty(&gss_msg->list)); in gss_release_msg()
290 if (gss_msg->ctx != NULL) in gss_release_msg()
291 gss_put_ctx(gss_msg->ctx); in gss_release_msg()
292 rpc_destroy_wait_queue(&gss_msg->rpc_waitqueue); in gss_release_msg()
293 gss_put_auth(gss_msg->auth); in gss_release_msg()
294 kfree_const(gss_msg->service_name); in gss_release_msg()
302 list_for_each_entry(pos, &pipe->in_downcall, list) { in __gss_find_upcall()
303 if (!uid_eq(pos->uid, uid)) in __gss_find_upcall()
305 if (auth && pos->auth->service != auth->service) in __gss_find_upcall()
307 refcount_inc(&pos->count); in __gss_find_upcall()
320 struct rpc_pipe *pipe = gss_msg->pipe; in gss_add_msg()
323 spin_lock(&pipe->lock); in gss_add_msg()
324 old = __gss_find_upcall(pipe, gss_msg->uid, gss_msg->auth); in gss_add_msg()
326 refcount_inc(&gss_msg->count); in gss_add_msg()
327 list_add(&gss_msg->list, &pipe->in_downcall); in gss_add_msg()
330 spin_unlock(&pipe->lock); in gss_add_msg()
337 list_del_init(&gss_msg->list); in __gss_unhash_msg()
338 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno); in __gss_unhash_msg()
339 wake_up_all(&gss_msg->waitqueue); in __gss_unhash_msg()
340 refcount_dec(&gss_msg->count); in __gss_unhash_msg()
346 struct rpc_pipe *pipe = gss_msg->pipe; in gss_unhash_msg()
348 if (list_empty(&gss_msg->list)) in gss_unhash_msg()
350 spin_lock(&pipe->lock); in gss_unhash_msg()
351 if (!list_empty(&gss_msg->list)) in gss_unhash_msg()
353 spin_unlock(&pipe->lock); in gss_unhash_msg()
359 switch (gss_msg->msg.errno) { in gss_handle_downcall_result()
361 if (gss_msg->ctx == NULL) in gss_handle_downcall_result()
363 clear_bit(RPCAUTH_CRED_NEGATIVE, &gss_cred->gc_base.cr_flags); in gss_handle_downcall_result()
364 gss_cred_set_ctx(&gss_cred->gc_base, gss_msg->ctx); in gss_handle_downcall_result()
366 case -EKEYEXPIRED: in gss_handle_downcall_result()
367 set_bit(RPCAUTH_CRED_NEGATIVE, &gss_cred->gc_base.cr_flags); in gss_handle_downcall_result()
369 gss_cred->gc_upcall_timestamp = jiffies; in gss_handle_downcall_result()
370 gss_cred->gc_upcall = NULL; in gss_handle_downcall_result()
371 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno); in gss_handle_downcall_result()
377 struct gss_cred *gss_cred = container_of(task->tk_rqstp->rq_cred, in gss_upcall_callback()
379 struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall; in gss_upcall_callback()
380 struct rpc_pipe *pipe = gss_msg->pipe; in gss_upcall_callback()
382 spin_lock(&pipe->lock); in gss_upcall_callback()
384 spin_unlock(&pipe->lock); in gss_upcall_callback()
385 task->tk_status = gss_msg->msg.errno; in gss_upcall_callback()
392 struct user_namespace *userns = cred->user_ns; in gss_encode_v0_msg()
394 uid_t uid = from_kuid_munged(userns, gss_msg->uid); in gss_encode_v0_msg()
395 memcpy(gss_msg->databuf, &uid, sizeof(uid)); in gss_encode_v0_msg()
396 gss_msg->msg.data = gss_msg->databuf; in gss_encode_v0_msg()
397 gss_msg->msg.len = sizeof(uid); in gss_encode_v0_msg()
399 BUILD_BUG_ON(sizeof(uid) > sizeof(gss_msg->databuf)); in gss_encode_v0_msg()
409 if (msg->copied == 0) in gss_v0_upcall()
410 gss_encode_v0_msg(gss_msg, file->f_cred); in gss_v0_upcall()
419 struct user_namespace *userns = cred->user_ns; in gss_encode_v1_msg()
420 struct gss_api_mech *mech = gss_msg->auth->mech; in gss_encode_v1_msg()
421 char *p = gss_msg->databuf; in gss_encode_v1_msg()
422 size_t buflen = sizeof(gss_msg->databuf); in gss_encode_v1_msg()
425 len = scnprintf(p, buflen, "mech=%s uid=%d", mech->gm_name, in gss_encode_v1_msg()
426 from_kuid_munged(userns, gss_msg->uid)); in gss_encode_v1_msg()
427 buflen -= len; in gss_encode_v1_msg()
429 gss_msg->msg.len = len; in gss_encode_v1_msg()
437 buflen -= len; in gss_encode_v1_msg()
439 gss_msg->msg.len += len; in gss_encode_v1_msg()
461 (int)(c - service_name), in gss_encode_v1_msg()
463 buflen -= len; in gss_encode_v1_msg()
465 gss_msg->msg.len += len; in gss_encode_v1_msg()
468 if (mech->gm_upcall_enctypes) { in gss_encode_v1_msg()
470 mech->gm_upcall_enctypes); in gss_encode_v1_msg()
471 buflen -= len; in gss_encode_v1_msg()
473 gss_msg->msg.len += len; in gss_encode_v1_msg()
475 trace_rpcgss_upcall_msg(gss_msg->databuf); in gss_encode_v1_msg()
479 gss_msg->msg.len += len; in gss_encode_v1_msg()
480 gss_msg->msg.data = gss_msg->databuf; in gss_encode_v1_msg()
484 return -ENOMEM; in gss_encode_v1_msg()
495 if (msg->copied == 0) { in gss_v1_upcall()
497 gss_msg->service_name, in gss_v1_upcall()
498 gss_msg->auth->target_name, in gss_v1_upcall()
499 file->f_cred); in gss_v1_upcall()
512 int err = -ENOMEM; in gss_alloc_msg()
517 vers = get_pipe_version(gss_auth->net); in gss_alloc_msg()
521 gss_msg->pipe = gss_auth->gss_pipe[vers]->pipe; in gss_alloc_msg()
522 INIT_LIST_HEAD(&gss_msg->list); in gss_alloc_msg()
523 rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); in gss_alloc_msg()
524 init_waitqueue_head(&gss_msg->waitqueue); in gss_alloc_msg()
525 refcount_set(&gss_msg->count, 1); in gss_alloc_msg()
526 gss_msg->uid = uid; in gss_alloc_msg()
527 gss_msg->auth = gss_auth; in gss_alloc_msg()
528 kref_get(&gss_auth->kref); in gss_alloc_msg()
530 gss_msg->service_name = kstrdup_const(service_name, GFP_KERNEL); in gss_alloc_msg()
531 if (!gss_msg->service_name) { in gss_alloc_msg()
532 err = -ENOMEM; in gss_alloc_msg()
538 put_pipe_version(gss_auth->net); in gss_alloc_msg()
551 kuid_t uid = cred->cr_cred->fsuid; in gss_setup_upcall()
553 gss_new = gss_alloc_msg(gss_auth, uid, gss_cred->gc_principal); in gss_setup_upcall()
559 refcount_inc(&gss_msg->count); in gss_setup_upcall()
560 res = rpc_queue_upcall(gss_new->pipe, &gss_new->msg); in gss_setup_upcall()
563 refcount_dec(&gss_msg->count); in gss_setup_upcall()
580 struct rpc_cred *cred = task->tk_rqstp->rq_cred; in gss_refresh_upcall()
581 struct gss_auth *gss_auth = container_of(cred->cr_auth, in gss_refresh_upcall()
590 if (PTR_ERR(gss_msg) == -EAGAIN) { in gss_refresh_upcall()
596 err = -EAGAIN; in gss_refresh_upcall()
603 pipe = gss_msg->pipe; in gss_refresh_upcall()
604 spin_lock(&pipe->lock); in gss_refresh_upcall()
605 if (gss_cred->gc_upcall != NULL) in gss_refresh_upcall()
606 rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL); in gss_refresh_upcall()
607 else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) { in gss_refresh_upcall()
608 gss_cred->gc_upcall = gss_msg; in gss_refresh_upcall()
610 refcount_inc(&gss_msg->count); in gss_refresh_upcall()
611 rpc_sleep_on(&gss_msg->rpc_waitqueue, task, gss_upcall_callback); in gss_refresh_upcall()
614 err = gss_msg->msg.errno; in gss_refresh_upcall()
616 spin_unlock(&pipe->lock); in gss_refresh_upcall()
620 cred->cr_cred->fsuid), err); in gss_refresh_upcall()
627 struct net *net = gss_auth->net; in gss_create_upcall()
630 struct rpc_cred *cred = &gss_cred->gc_base; in gss_create_upcall()
640 err = -EACCES; in gss_create_upcall()
644 if (PTR_ERR(gss_msg) == -EAGAIN) { in gss_create_upcall()
646 sn->pipe_version >= 0, 15 * HZ); in gss_create_upcall()
647 if (sn->pipe_version < 0) { in gss_create_upcall()
649 err = -EACCES; in gss_create_upcall()
659 pipe = gss_msg->pipe; in gss_create_upcall()
661 prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_KILLABLE); in gss_create_upcall()
662 spin_lock(&pipe->lock); in gss_create_upcall()
663 if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) { in gss_create_upcall()
666 spin_unlock(&pipe->lock); in gss_create_upcall()
668 err = -ERESTARTSYS; in gss_create_upcall()
673 if (gss_msg->ctx) { in gss_create_upcall()
675 gss_cred_set_ctx(cred, gss_msg->ctx); in gss_create_upcall()
677 err = gss_msg->msg.errno; in gss_create_upcall()
679 spin_unlock(&pipe->lock); in gss_create_upcall()
681 finish_wait(&gss_msg->waitqueue, &wait); in gss_create_upcall()
685 cred->cr_cred->fsuid), err); in gss_create_upcall()
697 struct rpc_pipe *pipe = RPC_I(file_inode(filp))->pipe; in gss_pipe_downcall()
701 ssize_t err = -EFBIG; in gss_pipe_downcall()
705 err = -ENOMEM; in gss_pipe_downcall()
710 err = -EFAULT; in gss_pipe_downcall()
723 err = -EINVAL; in gss_pipe_downcall()
727 err = -ENOMEM; in gss_pipe_downcall()
732 err = -ENOENT; in gss_pipe_downcall()
734 spin_lock(&pipe->lock); in gss_pipe_downcall()
737 spin_unlock(&pipe->lock); in gss_pipe_downcall()
740 list_del_init(&gss_msg->list); in gss_pipe_downcall()
741 spin_unlock(&pipe->lock); in gss_pipe_downcall()
743 p = gss_fill_context(p, end, ctx, gss_msg->auth->mech); in gss_pipe_downcall()
747 case -EACCES: in gss_pipe_downcall()
748 case -EKEYEXPIRED: in gss_pipe_downcall()
749 gss_msg->msg.errno = err; in gss_pipe_downcall()
752 case -EFAULT: in gss_pipe_downcall()
753 case -ENOMEM: in gss_pipe_downcall()
754 case -EINVAL: in gss_pipe_downcall()
755 case -ENOSYS: in gss_pipe_downcall()
756 gss_msg->msg.errno = -EAGAIN; in gss_pipe_downcall()
761 gss_msg->msg.errno = -EIO; in gss_pipe_downcall()
765 gss_msg->ctx = gss_get_ctx(ctx); in gss_pipe_downcall()
769 spin_lock(&pipe->lock); in gss_pipe_downcall()
771 spin_unlock(&pipe->lock); in gss_pipe_downcall()
783 struct net *net = inode->i_sb->s_fs_info; in gss_pipe_open()
788 if (sn->pipe_version < 0) { in gss_pipe_open()
790 sn->pipe_version = new_version; in gss_pipe_open()
793 } else if (sn->pipe_version != new_version) { in gss_pipe_open()
795 ret = -EBUSY; in gss_pipe_open()
798 atomic_inc(&sn->pipe_users); in gss_pipe_open()
818 struct net *net = inode->i_sb->s_fs_info; in gss_pipe_release()
819 struct rpc_pipe *pipe = RPC_I(inode)->pipe; in gss_pipe_release()
823 spin_lock(&pipe->lock); in gss_pipe_release()
824 list_for_each_entry(gss_msg, &pipe->in_downcall, list) { in gss_pipe_release()
826 if (!list_empty(&gss_msg->msg.list)) in gss_pipe_release()
828 gss_msg->msg.errno = -EPIPE; in gss_pipe_release()
829 refcount_inc(&gss_msg->count); in gss_pipe_release()
831 spin_unlock(&pipe->lock); in gss_pipe_release()
835 spin_unlock(&pipe->lock); in gss_pipe_release()
845 if (msg->errno < 0) { in gss_pipe_destroy_msg()
846 refcount_inc(&gss_msg->count); in gss_pipe_destroy_msg()
848 if (msg->errno == -ETIMEDOUT) in gss_pipe_destroy_msg()
858 struct gss_pipe *gss_pipe = pdo->pdo_data; in gss_pipe_dentry_destroy()
859 struct rpc_pipe *pipe = gss_pipe->pipe; in gss_pipe_dentry_destroy()
861 if (pipe->dentry != NULL) { in gss_pipe_dentry_destroy()
862 rpc_unlink(pipe->dentry); in gss_pipe_dentry_destroy()
863 pipe->dentry = NULL; in gss_pipe_dentry_destroy()
870 struct gss_pipe *p = pdo->pdo_data; in gss_pipe_dentry_create()
873 dentry = rpc_mkpipe_dentry(dir, p->name, p->clnt, p->pipe); in gss_pipe_dentry_create()
876 p->pipe->dentry = dentry; in gss_pipe_dentry_create()
890 int err = -ENOMEM; in gss_pipe_alloc()
895 p->pipe = rpc_mkpipe_data(upcall_ops, RPC_PIPE_WAIT_FOR_OPEN); in gss_pipe_alloc()
896 if (IS_ERR(p->pipe)) { in gss_pipe_alloc()
897 err = PTR_ERR(p->pipe); in gss_pipe_alloc()
900 p->name = name; in gss_pipe_alloc()
901 p->clnt = clnt; in gss_pipe_alloc()
902 kref_init(&p->kref); in gss_pipe_alloc()
903 rpc_init_pipe_dir_object(&p->pdo, in gss_pipe_alloc()
924 if (pdo->pdo_ops != &gss_pipe_dir_object_ops) in gss_pipe_match_pdo()
927 if (strcmp(gss_pipe->name, args->name) != 0) in gss_pipe_match_pdo()
929 if (!kref_get_unless_zero(&gss_pipe->kref)) in gss_pipe_match_pdo()
939 gss_pipe = gss_pipe_alloc(args->clnt, args->name, args->upcall_ops); in gss_pipe_alloc_pdo()
941 return &gss_pipe->pdo; in gss_pipe_alloc_pdo()
958 &clnt->cl_pipedir_objects, in gss_pipe_get()
964 return ERR_PTR(-ENOMEM); in gss_pipe_get()
969 struct rpc_clnt *clnt = p->clnt; in __gss_pipe_free()
973 &clnt->cl_pipedir_objects, in __gss_pipe_free()
974 &p->pdo); in __gss_pipe_free()
975 rpc_destroy_pipe_data(p->pipe); in __gss_pipe_free()
989 kref_put(&p->kref, __gss_pipe_release); in gss_pipe_free()
999 rpc_authflavor_t flavor = args->pseudoflavor; in gss_create_new()
1003 int err = -ENOMEM; /* XXX? */ in gss_create_new()
1009 INIT_HLIST_NODE(&gss_auth->hash); in gss_create_new()
1010 gss_auth->target_name = NULL; in gss_create_new()
1011 if (args->target_name) { in gss_create_new()
1012 gss_auth->target_name = kstrdup(args->target_name, GFP_KERNEL); in gss_create_new()
1013 if (gss_auth->target_name == NULL) in gss_create_new()
1016 gss_auth->client = clnt; in gss_create_new()
1017 gss_auth->net = get_net_track(rpc_net_ns(clnt), &gss_auth->ns_tracker, in gss_create_new()
1019 err = -EINVAL; in gss_create_new()
1020 gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor); in gss_create_new()
1021 if (!gss_auth->mech) in gss_create_new()
1023 gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor); in gss_create_new()
1024 if (gss_auth->service == 0) in gss_create_new()
1026 if (!gssd_running(gss_auth->net)) in gss_create_new()
1028 auth = &gss_auth->rpc_auth; in gss_create_new()
1029 auth->au_cslack = GSS_CRED_SLACK >> 2; in gss_create_new()
1030 auth->au_rslack = GSS_KRB5_MAX_SLACK_NEEDED >> 2; in gss_create_new()
1031 auth->au_verfsize = GSS_VERF_SLACK >> 2; in gss_create_new()
1032 auth->au_ralign = GSS_VERF_SLACK >> 2; in gss_create_new()
1033 __set_bit(RPCAUTH_AUTH_UPDATE_SLACK, &auth->au_flags); in gss_create_new()
1034 auth->au_ops = &authgss_ops; in gss_create_new()
1035 auth->au_flavor = flavor; in gss_create_new()
1036 if (gss_pseudoflavor_to_datatouch(gss_auth->mech, flavor)) in gss_create_new()
1037 __set_bit(RPCAUTH_AUTH_DATATOUCH, &auth->au_flags); in gss_create_new()
1038 refcount_set(&auth->au_count, 1); in gss_create_new()
1039 kref_init(&gss_auth->kref); in gss_create_new()
1055 gss_auth->gss_pipe[1] = gss_pipe; in gss_create_new()
1057 gss_pipe = gss_pipe_get(clnt, gss_auth->mech->gm_name, in gss_create_new()
1063 gss_auth->gss_pipe[0] = gss_pipe; in gss_create_new()
1067 gss_pipe_free(gss_auth->gss_pipe[1]); in gss_create_new()
1071 gss_mech_put(gss_auth->mech); in gss_create_new()
1073 put_net_track(gss_auth->net, &gss_auth->ns_tracker); in gss_create_new()
1075 kfree(gss_auth->target_name); in gss_create_new()
1086 gss_pipe_free(gss_auth->gss_pipe[0]); in gss_free()
1087 gss_pipe_free(gss_auth->gss_pipe[1]); in gss_free()
1088 gss_mech_put(gss_auth->mech); in gss_free()
1089 put_net_track(gss_auth->net, &gss_auth->ns_tracker); in gss_free()
1090 kfree(gss_auth->target_name); in gss_free()
1107 kref_put(&gss_auth->kref, gss_free_callback); in gss_put_auth()
1116 if (hash_hashed(&gss_auth->hash)) { in gss_destroy()
1118 hash_del(&gss_auth->hash); in gss_destroy()
1122 gss_pipe_free(gss_auth->gss_pipe[0]); in gss_destroy()
1123 gss_auth->gss_pipe[0] = NULL; in gss_destroy()
1124 gss_pipe_free(gss_auth->gss_pipe[1]); in gss_destroy()
1125 gss_auth->gss_pipe[1] = NULL; in gss_destroy()
1153 if (gss_auth->client != clnt) in gss_auth_find_or_add_hashed()
1155 if (gss_auth->rpc_auth.au_flavor != args->pseudoflavor) in gss_auth_find_or_add_hashed()
1157 if (gss_auth->target_name != args->target_name) { in gss_auth_find_or_add_hashed()
1158 if (gss_auth->target_name == NULL) in gss_auth_find_or_add_hashed()
1160 if (args->target_name == NULL) in gss_auth_find_or_add_hashed()
1162 if (strcmp(gss_auth->target_name, args->target_name)) in gss_auth_find_or_add_hashed()
1165 if (!refcount_inc_not_zero(&gss_auth->rpc_auth.au_count)) in gss_auth_find_or_add_hashed()
1170 hash_add(gss_auth_hash_table, &new->hash, hashval); in gss_auth_find_or_add_hashed()
1192 gss_destroy(&new->rpc_auth); in gss_create_hashed()
1201 struct rpc_xprt_switch *xps = rcu_access_pointer(clnt->cl_xpi.xpi_xpswitch); in gss_create()
1203 while (clnt != clnt->cl_parent) { in gss_create()
1204 struct rpc_clnt *parent = clnt->cl_parent; in gss_create()
1206 if (rcu_access_pointer(parent->cl_xpi.xpi_xpswitch) != xps) in gss_create()
1214 return &gss_auth->rpc_auth; in gss_create()
1226 .cred = gss_cred->gc_base.cr_cred, in gss_dup_cred()
1229 rcu_dereference_protected(gss_cred->gc_ctx, 1); in gss_dup_cred()
1231 rpcauth_init_cred(&new->gc_base, &acred, in gss_dup_cred()
1232 &gss_auth->rpc_auth, in gss_dup_cred()
1234 new->gc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE; in gss_dup_cred()
1235 new->gc_service = gss_cred->gc_service; in gss_dup_cred()
1236 new->gc_principal = gss_cred->gc_principal; in gss_dup_cred()
1237 kref_get(&gss_auth->kref); in gss_dup_cred()
1238 rcu_assign_pointer(new->gc_ctx, ctx); in gss_dup_cred()
1254 struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth); in gss_send_destroy_context()
1255 struct gss_cl_ctx *ctx = rcu_dereference_protected(gss_cred->gc_ctx, 1); in gss_send_destroy_context()
1261 ctx->gc_proc = RPC_GSS_PROC_DESTROY; in gss_send_destroy_context()
1264 task = rpc_call_null(gss_auth->client, &new->gc_base, in gss_send_destroy_context()
1269 put_rpccred(&new->gc_base); in gss_send_destroy_context()
1279 gss_delete_sec_context(&ctx->gc_gss_ctx); in gss_do_free_ctx()
1280 kfree(ctx->gc_wire_ctx.data); in gss_do_free_ctx()
1281 kfree(ctx->gc_acceptor.data); in gss_do_free_ctx()
1295 call_rcu(&ctx->gc_rcu, gss_free_ctx_callback); in gss_free_ctx()
1315 struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth); in gss_destroy_nullcred()
1316 struct gss_cl_ctx *ctx = rcu_dereference_protected(gss_cred->gc_ctx, 1); in gss_destroy_nullcred()
1318 RCU_INIT_POINTER(gss_cred->gc_ctx, NULL); in gss_destroy_nullcred()
1319 put_cred(cred->cr_cred); in gss_destroy_nullcred()
1320 call_rcu(&cred->cr_rcu, gss_free_cred_callback); in gss_destroy_nullcred()
1329 if (test_and_clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0) in gss_destroy_cred()
1337 return hash_64(from_kuid(&init_user_ns, acred->cred->fsuid), hashbits); in gss_hash_cred()
1355 int err = -ENOMEM; in gss_create_cred()
1360 rpcauth_init_cred(&cred->gc_base, acred, auth, &gss_credops); in gss_create_cred()
1365 cred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_NEW; in gss_create_cred()
1366 cred->gc_service = gss_auth->service; in gss_create_cred()
1367 cred->gc_principal = acred->principal; in gss_create_cred()
1368 kref_get(&gss_auth->kref); in gss_create_cred()
1369 return &cred->gc_base; in gss_create_cred()
1384 } while (err == -EAGAIN); in gss_cred_init()
1398 ctx = rcu_dereference(gss_cred->gc_ctx); in gss_stringify_acceptor()
1402 len = ctx->gc_acceptor.len; in gss_stringify_acceptor()
1414 ctx = rcu_dereference(gss_cred->gc_ctx); in gss_stringify_acceptor()
1417 if (!ctx || !ctx->gc_acceptor.len) { in gss_stringify_acceptor()
1423 acceptor = &ctx->gc_acceptor; in gss_stringify_acceptor()
1429 if (len < acceptor->len) { in gss_stringify_acceptor()
1430 len = acceptor->len; in gss_stringify_acceptor()
1436 memcpy(string, acceptor->data, acceptor->len); in gss_stringify_acceptor()
1437 string[acceptor->len] = '\0'; in gss_stringify_acceptor()
1444 * Returns -EACCES if GSS context is NULL or will expire within the
1456 ctx = rcu_dereference(gss_cred->gc_ctx); in gss_key_timeout()
1457 if (!ctx || time_after(timeout, ctx->gc_expiry)) in gss_key_timeout()
1458 ret = -EACCES; in gss_key_timeout()
1471 if (test_bit(RPCAUTH_CRED_NEW, &rc->cr_flags)) in gss_match()
1475 ctx = rcu_dereference(gss_cred->gc_ctx); in gss_match()
1476 if (!ctx || time_after(jiffies, ctx->gc_expiry)) { in gss_match()
1481 if (!test_bit(RPCAUTH_CRED_UPTODATE, &rc->cr_flags)) in gss_match()
1484 if (acred->principal != NULL) { in gss_match()
1485 if (gss_cred->gc_principal == NULL) in gss_match()
1487 ret = strcmp(acred->principal, gss_cred->gc_principal) == 0; in gss_match()
1489 if (gss_cred->gc_principal != NULL) in gss_match()
1491 ret = uid_eq(rc->cr_cred->fsuid, acred->cred->fsuid); in gss_match()
1500 * pre-computed version of the verifier because the seqno, which
1501 * is different every time, is included in the MIC.
1505 struct rpc_rqst *req = task->tk_rqstp; in gss_marshal()
1506 struct rpc_cred *cred = req->rq_cred; in gss_marshal()
1512 struct xdr_netobj mic; in gss_marshal() local
1520 ctx->gc_wire_ctx.len); in gss_marshal()
1526 spin_lock(&ctx->gc_seq_lock); in gss_marshal()
1527 req->rq_seqno = (ctx->gc_seq < MAXSEQ) ? ctx->gc_seq++ : MAXSEQ; in gss_marshal()
1528 spin_unlock(&ctx->gc_seq_lock); in gss_marshal()
1529 if (req->rq_seqno == MAXSEQ) in gss_marshal()
1534 *p++ = cpu_to_be32(ctx->gc_proc); in gss_marshal()
1535 *p++ = cpu_to_be32(req->rq_seqno); in gss_marshal()
1536 *p++ = cpu_to_be32(gss_cred->gc_service); in gss_marshal()
1537 p = xdr_encode_netobj(p, &ctx->gc_wire_ctx); in gss_marshal()
1538 *cred_len = cpu_to_be32((p - (cred_len + 1)) << 2); in gss_marshal()
1542 /* We compute the checksum for the verifier over the xdr-encoded bytes in gss_marshal()
1544 iov.iov_base = req->rq_snd_buf.head[0].iov_base; in gss_marshal()
1545 iov.iov_len = (u8 *)p - (u8 *)iov.iov_base; in gss_marshal()
1552 mic.data = (u8 *)(p + 1); in gss_marshal()
1553 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &verf_buf, &mic); in gss_marshal()
1558 if (xdr_stream_encode_opaque_inline(xdr, (void **)&p, mic.len) < 0) in gss_marshal()
1565 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in gss_marshal()
1566 status = -EKEYEXPIRED; in gss_marshal()
1569 status = -EMSGSIZE; in gss_marshal()
1573 status = -EIO; in gss_marshal()
1579 struct rpc_cred *oldcred = task->tk_rqstp->rq_cred; in gss_renew_cred()
1583 struct rpc_auth *auth = oldcred->cr_auth; in gss_renew_cred()
1585 .cred = oldcred->cr_cred, in gss_renew_cred()
1586 .principal = gss_cred->gc_principal, in gss_renew_cred()
1594 task->tk_rqstp->rq_cred = new; in gss_renew_cred()
1601 if (test_bit(RPCAUTH_CRED_NEGATIVE, &cred->cr_flags)) { in gss_cred_is_negative_entry()
1607 begin = gss_cred->gc_upcall_timestamp; in gss_cred_is_negative_entry()
1617 * Refresh credentials. XXX - finish
1622 struct rpc_cred *cred = task->tk_rqstp->rq_cred; in gss_refresh()
1626 return -EKEYEXPIRED; in gss_refresh()
1628 if (!test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) && in gss_refresh()
1629 !test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags)) { in gss_refresh()
1633 cred = task->tk_rqstp->rq_cred; in gss_refresh()
1636 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags)) in gss_refresh()
1652 struct rpc_cred *cred = task->tk_rqstp->rq_cred; in gss_validate()
1657 struct xdr_netobj mic; in gss_validate() local
1676 *seq = cpu_to_be32(task->tk_rqstp->rq_seqno); in gss_validate()
1680 mic.data = (u8 *)p; in gss_validate()
1681 mic.len = len; in gss_validate()
1682 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic); in gss_validate()
1684 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in gss_validate()
1690 if (test_bit(RPCAUTH_AUTH_UPDATE_SLACK, &cred->cr_auth->au_flags)) in gss_validate()
1691 cred->cr_auth->au_verfsize = XDR_QUADLEN(len) + 2; in gss_validate()
1699 status = -EIO; in gss_validate()
1703 status = -EACCES; in gss_validate()
1711 struct rpc_rqst *rqstp = task->tk_rqstp; in gss_wrap_req_integ()
1712 struct xdr_buf integ_buf, *snd_buf = &rqstp->rq_snd_buf; in gss_wrap_req_integ()
1713 struct xdr_netobj mic; in gss_wrap_req_integ() local
1715 u32 offset, maj_stat; in gss_wrap_req_integ() local
1721 *p = cpu_to_be32(rqstp->rq_seqno); in gss_wrap_req_integ()
1726 offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; in gss_wrap_req_integ()
1728 offset, snd_buf->len - offset)) in gss_wrap_req_integ()
1735 mic.data = (u8 *)(p + 1); in gss_wrap_req_integ()
1736 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &integ_buf, &mic); in gss_wrap_req_integ()
1738 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in gss_wrap_req_integ()
1741 /* Check that the trailing MIC fit in the buffer, after the fact */ in gss_wrap_req_integ()
1742 if (xdr_stream_encode_opaque_inline(xdr, (void **)&p, mic.len) < 0) in gss_wrap_req_integ()
1746 return -EMSGSIZE; in gss_wrap_req_integ()
1749 return -EIO; in gss_wrap_req_integ()
1757 for (i=0; i < rqstp->rq_enc_pages_num; i++) in priv_release_snd_buf()
1758 __free_page(rqstp->rq_enc_pages[i]); in priv_release_snd_buf()
1759 kfree(rqstp->rq_enc_pages); in priv_release_snd_buf()
1760 rqstp->rq_release_snd_buf = NULL; in priv_release_snd_buf()
1766 struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; in alloc_enc_pages()
1769 if (rqstp->rq_release_snd_buf) in alloc_enc_pages()
1770 rqstp->rq_release_snd_buf(rqstp); in alloc_enc_pages()
1772 if (snd_buf->page_len == 0) { in alloc_enc_pages()
1773 rqstp->rq_enc_pages_num = 0; in alloc_enc_pages()
1777 first = snd_buf->page_base >> PAGE_SHIFT; in alloc_enc_pages()
1778 last = (snd_buf->page_base + snd_buf->page_len - 1) >> PAGE_SHIFT; in alloc_enc_pages()
1779 rqstp->rq_enc_pages_num = last - first + 1 + 1; in alloc_enc_pages()
1780 rqstp->rq_enc_pages in alloc_enc_pages()
1781 = kmalloc_array(rqstp->rq_enc_pages_num, in alloc_enc_pages()
1784 if (!rqstp->rq_enc_pages) in alloc_enc_pages()
1786 for (i=0; i < rqstp->rq_enc_pages_num; i++) { in alloc_enc_pages()
1787 rqstp->rq_enc_pages[i] = alloc_page(GFP_KERNEL); in alloc_enc_pages()
1788 if (rqstp->rq_enc_pages[i] == NULL) in alloc_enc_pages()
1791 rqstp->rq_release_snd_buf = priv_release_snd_buf; in alloc_enc_pages()
1794 rqstp->rq_enc_pages_num = i; in alloc_enc_pages()
1797 return -EAGAIN; in alloc_enc_pages()
1804 struct rpc_rqst *rqstp = task->tk_rqstp; in gss_wrap_req_priv()
1805 struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; in gss_wrap_req_priv()
1806 u32 pad, offset, maj_stat; in gss_wrap_req_priv() local
1813 status = -EIO; in gss_wrap_req_priv()
1818 *p = cpu_to_be32(rqstp->rq_seqno); in gss_wrap_req_priv()
1826 first = snd_buf->page_base >> PAGE_SHIFT; in gss_wrap_req_priv()
1827 inpages = snd_buf->pages + first; in gss_wrap_req_priv()
1828 snd_buf->pages = rqstp->rq_enc_pages; in gss_wrap_req_priv()
1829 snd_buf->page_base -= first << PAGE_SHIFT; in gss_wrap_req_priv()
1836 if (snd_buf->page_len || snd_buf->tail[0].iov_len) { in gss_wrap_req_priv()
1839 tmp = page_address(rqstp->rq_enc_pages[rqstp->rq_enc_pages_num - 1]); in gss_wrap_req_priv()
1840 memcpy(tmp, snd_buf->tail[0].iov_base, snd_buf->tail[0].iov_len); in gss_wrap_req_priv()
1841 snd_buf->tail[0].iov_base = tmp; in gss_wrap_req_priv()
1843 offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; in gss_wrap_req_priv()
1844 maj_stat = gss_wrap(ctx->gc_gss_ctx, offset, snd_buf, inpages); in gss_wrap_req_priv()
1846 if (unlikely(snd_buf->len > snd_buf->buflen)) in gss_wrap_req_priv()
1851 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in gss_wrap_req_priv()
1855 *opaque_len = cpu_to_be32(snd_buf->len - offset); in gss_wrap_req_priv()
1857 if (snd_buf->page_len || snd_buf->tail[0].iov_len) in gss_wrap_req_priv()
1858 iov = snd_buf->tail; in gss_wrap_req_priv()
1860 iov = snd_buf->head; in gss_wrap_req_priv()
1861 p = iov->iov_base + iov->iov_len; in gss_wrap_req_priv()
1862 pad = xdr_pad_size(snd_buf->len - offset); in gss_wrap_req_priv()
1864 iov->iov_len += pad; in gss_wrap_req_priv()
1865 snd_buf->len += pad; in gss_wrap_req_priv()
1872 return -EIO; in gss_wrap_req_priv()
1877 struct rpc_cred *cred = task->tk_rqstp->rq_cred; in gss_wrap_req()
1883 status = -EIO; in gss_wrap_req()
1884 if (ctx->gc_proc != RPC_GSS_PROC_DATA) { in gss_wrap_req()
1891 switch (gss_cred->gc_service) { in gss_wrap_req()
1902 status = -EIO; in gss_wrap_req()
1910 * gss_update_rslack - Possibly update RPC receive buffer size estimates
1920 struct rpc_auth *auth = cred->cr_auth; in gss_update_rslack()
1922 if (test_and_clear_bit(RPCAUTH_AUTH_UPDATE_SLACK, &auth->au_flags)) { in gss_update_rslack()
1923 auth->au_ralign = auth->au_verfsize + before; in gss_update_rslack()
1924 auth->au_rslack = auth->au_verfsize + after; in gss_update_rslack()
1954 struct xdr_buf gss_data, *rcv_buf = &rqstp->rq_rcv_buf; in gss_unwrap_resp_integ()
1955 u32 len, offset, seqno, maj_stat; in gss_unwrap_resp_integ() local
1956 struct xdr_netobj mic; in gss_unwrap_resp_integ() local
1959 ret = -EIO; in gss_unwrap_resp_integ()
1960 mic.data = NULL; in gss_unwrap_resp_integ()
1967 offset = rcv_buf->len - xdr_stream_remaining(xdr); in gss_unwrap_resp_integ()
1970 if (seqno != rqstp->rq_seqno) in gss_unwrap_resp_integ()
1972 if (xdr_buf_subsegment(rcv_buf, &gss_data, offset, len)) in gss_unwrap_resp_integ()
1984 offset += len; in gss_unwrap_resp_integ()
1985 if (xdr_decode_word(rcv_buf, offset, &len)) in gss_unwrap_resp_integ()
1987 offset += sizeof(__be32); in gss_unwrap_resp_integ()
1988 if (offset + len > rcv_buf->len) in gss_unwrap_resp_integ()
1990 mic.len = len; in gss_unwrap_resp_integ()
1991 mic.data = kmalloc(len, GFP_KERNEL); in gss_unwrap_resp_integ()
1992 if (ZERO_OR_NULL_PTR(mic.data)) in gss_unwrap_resp_integ()
1994 if (read_bytes_from_xdr_buf(rcv_buf, offset, mic.data, mic.len)) in gss_unwrap_resp_integ()
1997 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &gss_data, &mic); in gss_unwrap_resp_integ()
1999 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in gss_unwrap_resp_integ()
2003 gss_update_rslack(task, cred, 2, 2 + 1 + XDR_QUADLEN(mic.len)); in gss_unwrap_resp_integ()
2007 kfree(mic.data); in gss_unwrap_resp_integ()
2014 trace_rpcgss_bad_seqno(task, rqstp->rq_seqno, seqno); in gss_unwrap_resp_integ()
2026 struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf; in gss_unwrap_resp_priv()
2027 struct kvec *head = rqstp->rq_rcv_buf.head; in gss_unwrap_resp_priv()
2028 u32 offset, opaque_len, maj_stat; in gss_unwrap_resp_priv() local
2035 offset = (u8 *)(p) - (u8 *)head->iov_base; in gss_unwrap_resp_priv()
2036 if (offset + opaque_len > rcv_buf->len) in gss_unwrap_resp_priv()
2039 maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, in gss_unwrap_resp_priv()
2040 offset + opaque_len, rcv_buf); in gss_unwrap_resp_priv()
2042 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); in gss_unwrap_resp_priv()
2046 if (be32_to_cpup(p++) != rqstp->rq_seqno) in gss_unwrap_resp_priv()
2054 gss_update_rslack(task, cred, 2 + ctx->gc_gss_ctx->align, in gss_unwrap_resp_priv()
2055 2 + ctx->gc_gss_ctx->slack); in gss_unwrap_resp_priv()
2060 return -EIO; in gss_unwrap_resp_priv()
2062 trace_rpcgss_bad_seqno(task, rqstp->rq_seqno, be32_to_cpup(--p)); in gss_unwrap_resp_priv()
2063 return -EIO; in gss_unwrap_resp_priv()
2066 return -EIO; in gss_unwrap_resp_priv()
2072 return (s32)(new - old) > 0; in gss_seq_is_newer()
2078 struct rpc_rqst *req = task->tk_rqstp; in gss_xmit_need_reencode()
2079 struct rpc_cred *cred = req->rq_cred; in gss_xmit_need_reencode()
2087 if (gss_seq_is_newer(req->rq_seqno, READ_ONCE(ctx->gc_seq))) in gss_xmit_need_reencode()
2090 seq_xmit = READ_ONCE(ctx->gc_seq_xmit); in gss_xmit_need_reencode()
2091 while (gss_seq_is_newer(req->rq_seqno, seq_xmit)) { in gss_xmit_need_reencode()
2094 seq_xmit = cmpxchg(&ctx->gc_seq_xmit, tmp, req->rq_seqno); in gss_xmit_need_reencode()
2101 win = ctx->gc_win; in gss_xmit_need_reencode()
2103 ret = !gss_seq_is_newer(req->rq_seqno, seq_xmit - win); in gss_xmit_need_reencode()
2115 struct rpc_rqst *rqstp = task->tk_rqstp; in gss_unwrap_resp()
2116 struct rpc_cred *cred = rqstp->rq_cred; in gss_unwrap_resp()
2120 int status = -EIO; in gss_unwrap_resp()
2122 if (ctx->gc_proc != RPC_GSS_PROC_DATA) in gss_unwrap_resp()
2124 switch (gss_cred->gc_service) { in gss_unwrap_resp()
2250 MODULE_ALIAS("rpc-auth-6");