diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-08-26 16:44:42 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-09-01 11:12:41 -0400 |
commit | 1917228435eebdf4e3267fa95cace694b2fb4efd (patch) | |
tree | 76b6bc42be98e3db9a9b2526361df957d527fe05 /net/sunrpc | |
parent | 6739ffb754b47e6c0fa9d9e268bde828f6856528 (diff) |
RPCSEC_GSS: Switch auth_gss to use the new framework for pipefs dentries
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 181 |
1 files changed, 92 insertions, 89 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index c0d36bb87d3e..d214aecdbeef 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -71,6 +71,13 @@ static unsigned int gss_expired_cred_retry_delay = GSS_RETRY_EXPIRED; | |||
71 | * using integrity (two 4-byte integers): */ | 71 | * using integrity (two 4-byte integers): */ |
72 | #define GSS_VERF_SLACK 100 | 72 | #define GSS_VERF_SLACK 100 |
73 | 73 | ||
74 | struct gss_pipe { | ||
75 | struct rpc_pipe_dir_object pdo; | ||
76 | struct rpc_pipe *pipe; | ||
77 | struct rpc_clnt *clnt; | ||
78 | const char *name; | ||
79 | }; | ||
80 | |||
74 | struct gss_auth { | 81 | struct gss_auth { |
75 | struct kref kref; | 82 | struct kref kref; |
76 | struct rpc_auth rpc_auth; | 83 | struct rpc_auth rpc_auth; |
@@ -84,7 +91,7 @@ struct gss_auth { | |||
84 | * mechanism (for example, "krb5") and exists for | 91 | * mechanism (for example, "krb5") and exists for |
85 | * backwards-compatibility with older gssd's. | 92 | * backwards-compatibility with older gssd's. |
86 | */ | 93 | */ |
87 | struct rpc_pipe *pipe[2]; | 94 | struct gss_pipe *gss_pipe[2]; |
88 | const char *target_name; | 95 | const char *target_name; |
89 | }; | 96 | }; |
90 | 97 | ||
@@ -456,7 +463,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, | |||
456 | kfree(gss_msg); | 463 | kfree(gss_msg); |
457 | return ERR_PTR(vers); | 464 | return ERR_PTR(vers); |
458 | } | 465 | } |
459 | gss_msg->pipe = gss_auth->pipe[vers]; | 466 | gss_msg->pipe = gss_auth->gss_pipe[vers]->pipe; |
460 | INIT_LIST_HEAD(&gss_msg->list); | 467 | INIT_LIST_HEAD(&gss_msg->list); |
461 | rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); | 468 | rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); |
462 | init_waitqueue_head(&gss_msg->waitqueue); | 469 | init_waitqueue_head(&gss_msg->waitqueue); |
@@ -791,85 +798,83 @@ gss_pipe_destroy_msg(struct rpc_pipe_msg *msg) | |||
791 | } | 798 | } |
792 | } | 799 | } |
793 | 800 | ||
794 | static void gss_pipes_dentries_destroy(struct rpc_auth *auth) | 801 | static void gss_pipe_dentry_destroy(struct dentry *dir, |
802 | struct rpc_pipe_dir_object *pdo) | ||
795 | { | 803 | { |
796 | struct gss_auth *gss_auth; | 804 | struct gss_pipe *gss_pipe = pdo->pdo_data; |
805 | struct rpc_pipe *pipe = gss_pipe->pipe; | ||
797 | 806 | ||
798 | gss_auth = container_of(auth, struct gss_auth, rpc_auth); | 807 | if (pipe->dentry != NULL) { |
799 | if (gss_auth->pipe[0]->dentry) { | 808 | rpc_unlink(pipe->dentry); |
800 | rpc_unlink(gss_auth->pipe[0]->dentry); | 809 | pipe->dentry = NULL; |
801 | gss_auth->pipe[0]->dentry = NULL; | ||
802 | } | ||
803 | if (gss_auth->pipe[1]->dentry) { | ||
804 | rpc_unlink(gss_auth->pipe[1]->dentry); | ||
805 | gss_auth->pipe[1]->dentry = NULL; | ||
806 | } | 810 | } |
807 | } | 811 | } |
808 | 812 | ||
809 | static int gss_pipes_dentries_create(struct rpc_auth *auth) | 813 | static int gss_pipe_dentry_create(struct dentry *dir, |
814 | struct rpc_pipe_dir_object *pdo) | ||
810 | { | 815 | { |
811 | int err; | 816 | struct gss_pipe *p = pdo->pdo_data; |
812 | struct gss_auth *gss_auth; | ||
813 | struct rpc_clnt *clnt; | ||
814 | struct dentry *dentry; | 817 | struct dentry *dentry; |
815 | 818 | ||
816 | gss_auth = container_of(auth, struct gss_auth, rpc_auth); | 819 | dentry = rpc_mkpipe_dentry(dir, p->name, p->clnt, p->pipe); |
817 | clnt = gss_auth->client; | 820 | if (IS_ERR(dentry)) |
821 | return PTR_ERR(dentry); | ||
822 | p->pipe->dentry = dentry; | ||
823 | return 0; | ||
824 | } | ||
825 | |||
826 | static const struct rpc_pipe_dir_object_ops gss_pipe_dir_object_ops = { | ||
827 | .create = gss_pipe_dentry_create, | ||
828 | .destroy = gss_pipe_dentry_destroy, | ||
829 | }; | ||
830 | |||
831 | static struct gss_pipe *gss_pipe_alloc(struct rpc_clnt *clnt, | ||
832 | const char *name, | ||
833 | const struct rpc_pipe_ops *upcall_ops) | ||
834 | { | ||
835 | struct net *net = rpc_net_ns(clnt); | ||
836 | struct gss_pipe *p; | ||
837 | int err = -ENOMEM; | ||
818 | 838 | ||
819 | dentry = rpc_mkpipe_dentry(clnt->cl_dentry, "gssd", | 839 | p = kmalloc(sizeof(*p), GFP_KERNEL); |
820 | clnt, gss_auth->pipe[1]); | 840 | if (p == NULL) |
821 | if (IS_ERR(dentry)) { | ||
822 | err = PTR_ERR(dentry); | ||
823 | goto err; | 841 | goto err; |
842 | p->pipe = rpc_mkpipe_data(upcall_ops, RPC_PIPE_WAIT_FOR_OPEN); | ||
843 | if (IS_ERR(p->pipe)) { | ||
844 | err = PTR_ERR(p->pipe); | ||
845 | goto err_free_gss_pipe; | ||
824 | } | 846 | } |
825 | gss_auth->pipe[1]->dentry = dentry; | 847 | p->name = name; |
826 | dentry = rpc_mkpipe_dentry(clnt->cl_dentry, gss_auth->mech->gm_name, | 848 | p->clnt = clnt; |
827 | clnt, gss_auth->pipe[0]); | 849 | rpc_init_pipe_dir_object(&p->pdo, |
828 | if (IS_ERR(dentry)) { | 850 | &gss_pipe_dir_object_ops, |
829 | err = PTR_ERR(dentry); | 851 | p); |
830 | goto err_unlink_pipe_1; | 852 | err = rpc_add_pipe_dir_object(net, &clnt->cl_pipedir_objects, &p->pdo); |
831 | } | 853 | if (!err) |
832 | return 0; | 854 | return p; |
833 | 855 | rpc_destroy_pipe_data(p->pipe); | |
834 | err_unlink_pipe_1: | 856 | err_free_gss_pipe: |
835 | rpc_unlink(gss_auth->pipe[1]->dentry); | 857 | kfree(p); |
836 | gss_auth->pipe[1]->dentry = NULL; | ||
837 | err: | 858 | err: |
838 | return err; | 859 | return ERR_PTR(err); |
839 | } | 860 | } |
840 | 861 | ||
841 | static void gss_pipes_dentries_destroy_net(struct rpc_clnt *clnt, | 862 | static void __gss_pipe_free(struct gss_pipe *p) |
842 | struct rpc_auth *auth) | ||
843 | { | 863 | { |
844 | struct gss_auth *gss_auth = container_of(auth, struct gss_auth, | 864 | struct rpc_clnt *clnt = p->clnt; |
845 | rpc_auth); | 865 | struct net *net = rpc_net_ns(clnt); |
846 | struct net *net = gss_auth->net; | ||
847 | struct super_block *sb; | ||
848 | 866 | ||
849 | sb = rpc_get_sb_net(net); | 867 | rpc_remove_pipe_dir_object(net, |
850 | if (sb) { | 868 | &clnt->cl_pipedir_objects, |
851 | if (clnt->cl_dentry) | 869 | &p->pdo); |
852 | gss_pipes_dentries_destroy(auth); | 870 | rpc_destroy_pipe_data(p->pipe); |
853 | rpc_put_sb_net(net); | 871 | kfree(p); |
854 | } | ||
855 | } | 872 | } |
856 | 873 | ||
857 | static int gss_pipes_dentries_create_net(struct rpc_clnt *clnt, | 874 | static void gss_pipe_free(struct gss_pipe *p) |
858 | struct rpc_auth *auth) | ||
859 | { | 875 | { |
860 | struct gss_auth *gss_auth = container_of(auth, struct gss_auth, | 876 | if (p != NULL) |
861 | rpc_auth); | 877 | __gss_pipe_free(p); |
862 | struct net *net = gss_auth->net; | ||
863 | struct super_block *sb; | ||
864 | int err = 0; | ||
865 | |||
866 | sb = rpc_get_sb_net(net); | ||
867 | if (sb) { | ||
868 | if (clnt->cl_dentry) | ||
869 | err = gss_pipes_dentries_create(auth); | ||
870 | rpc_put_sb_net(net); | ||
871 | } | ||
872 | return err; | ||
873 | } | 878 | } |
874 | 879 | ||
875 | /* | 880 | /* |
@@ -881,6 +886,7 @@ gss_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt) | |||
881 | { | 886 | { |
882 | rpc_authflavor_t flavor = args->pseudoflavor; | 887 | rpc_authflavor_t flavor = args->pseudoflavor; |
883 | struct gss_auth *gss_auth; | 888 | struct gss_auth *gss_auth; |
889 | struct gss_pipe *gss_pipe; | ||
884 | struct rpc_auth * auth; | 890 | struct rpc_auth * auth; |
885 | int err = -ENOMEM; /* XXX? */ | 891 | int err = -ENOMEM; /* XXX? */ |
886 | 892 | ||
@@ -915,39 +921,35 @@ gss_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt) | |||
915 | atomic_set(&auth->au_count, 1); | 921 | atomic_set(&auth->au_count, 1); |
916 | kref_init(&gss_auth->kref); | 922 | kref_init(&gss_auth->kref); |
917 | 923 | ||
924 | err = rpcauth_init_credcache(auth); | ||
925 | if (err) | ||
926 | goto err_put_mech; | ||
918 | /* | 927 | /* |
919 | * Note: if we created the old pipe first, then someone who | 928 | * Note: if we created the old pipe first, then someone who |
920 | * examined the directory at the right moment might conclude | 929 | * examined the directory at the right moment might conclude |
921 | * that we supported only the old pipe. So we instead create | 930 | * that we supported only the old pipe. So we instead create |
922 | * the new pipe first. | 931 | * the new pipe first. |
923 | */ | 932 | */ |
924 | gss_auth->pipe[1] = rpc_mkpipe_data(&gss_upcall_ops_v1, | 933 | gss_pipe = gss_pipe_alloc(clnt, "gssd", &gss_upcall_ops_v1); |
925 | RPC_PIPE_WAIT_FOR_OPEN); | 934 | if (IS_ERR(gss_pipe)) { |
926 | if (IS_ERR(gss_auth->pipe[1])) { | 935 | err = PTR_ERR(gss_pipe); |
927 | err = PTR_ERR(gss_auth->pipe[1]); | 936 | goto err_destroy_credcache; |
928 | goto err_put_mech; | ||
929 | } | 937 | } |
938 | gss_auth->gss_pipe[1] = gss_pipe; | ||
930 | 939 | ||
931 | gss_auth->pipe[0] = rpc_mkpipe_data(&gss_upcall_ops_v0, | 940 | gss_pipe = gss_pipe_alloc(clnt, gss_auth->mech->gm_name, |
932 | RPC_PIPE_WAIT_FOR_OPEN); | 941 | &gss_upcall_ops_v0); |
933 | if (IS_ERR(gss_auth->pipe[0])) { | 942 | if (IS_ERR(gss_pipe)) { |
934 | err = PTR_ERR(gss_auth->pipe[0]); | 943 | err = PTR_ERR(gss_pipe); |
935 | goto err_destroy_pipe_1; | 944 | goto err_destroy_pipe_1; |
936 | } | 945 | } |
937 | err = gss_pipes_dentries_create_net(clnt, auth); | 946 | gss_auth->gss_pipe[0] = gss_pipe; |
938 | if (err) | ||
939 | goto err_destroy_pipe_0; | ||
940 | err = rpcauth_init_credcache(auth); | ||
941 | if (err) | ||
942 | goto err_unlink_pipes; | ||
943 | 947 | ||
944 | return auth; | 948 | return auth; |
945 | err_unlink_pipes: | ||
946 | gss_pipes_dentries_destroy_net(clnt, auth); | ||
947 | err_destroy_pipe_0: | ||
948 | rpc_destroy_pipe_data(gss_auth->pipe[0]); | ||
949 | err_destroy_pipe_1: | 949 | err_destroy_pipe_1: |
950 | rpc_destroy_pipe_data(gss_auth->pipe[1]); | 950 | __gss_pipe_free(gss_auth->gss_pipe[1]); |
951 | err_destroy_credcache: | ||
952 | rpcauth_destroy_credcache(auth); | ||
951 | err_put_mech: | 953 | err_put_mech: |
952 | gss_mech_put(gss_auth->mech); | 954 | gss_mech_put(gss_auth->mech); |
953 | err_put_net: | 955 | err_put_net: |
@@ -963,9 +965,8 @@ out_dec: | |||
963 | static void | 965 | static void |
964 | gss_free(struct gss_auth *gss_auth) | 966 | gss_free(struct gss_auth *gss_auth) |
965 | { | 967 | { |
966 | gss_pipes_dentries_destroy_net(gss_auth->client, &gss_auth->rpc_auth); | 968 | gss_pipe_free(gss_auth->gss_pipe[0]); |
967 | rpc_destroy_pipe_data(gss_auth->pipe[0]); | 969 | gss_pipe_free(gss_auth->gss_pipe[1]); |
968 | rpc_destroy_pipe_data(gss_auth->pipe[1]); | ||
969 | gss_mech_put(gss_auth->mech); | 970 | gss_mech_put(gss_auth->mech); |
970 | put_net(gss_auth->net); | 971 | put_net(gss_auth->net); |
971 | kfree(gss_auth->target_name); | 972 | kfree(gss_auth->target_name); |
@@ -985,14 +986,18 @@ gss_free_callback(struct kref *kref) | |||
985 | static void | 986 | static void |
986 | gss_destroy(struct rpc_auth *auth) | 987 | gss_destroy(struct rpc_auth *auth) |
987 | { | 988 | { |
988 | struct gss_auth *gss_auth; | 989 | struct gss_auth *gss_auth = container_of(auth, |
990 | struct gss_auth, rpc_auth); | ||
989 | 991 | ||
990 | dprintk("RPC: destroying GSS authenticator %p flavor %d\n", | 992 | dprintk("RPC: destroying GSS authenticator %p flavor %d\n", |
991 | auth, auth->au_flavor); | 993 | auth, auth->au_flavor); |
992 | 994 | ||
995 | gss_pipe_free(gss_auth->gss_pipe[0]); | ||
996 | gss_auth->gss_pipe[0] = NULL; | ||
997 | gss_pipe_free(gss_auth->gss_pipe[1]); | ||
998 | gss_auth->gss_pipe[1] = NULL; | ||
993 | rpcauth_destroy_credcache(auth); | 999 | rpcauth_destroy_credcache(auth); |
994 | 1000 | ||
995 | gss_auth = container_of(auth, struct gss_auth, rpc_auth); | ||
996 | kref_put(&gss_auth->kref, gss_free_callback); | 1001 | kref_put(&gss_auth->kref, gss_free_callback); |
997 | } | 1002 | } |
998 | 1003 | ||
@@ -1676,8 +1681,6 @@ static const struct rpc_authops authgss_ops = { | |||
1676 | .destroy = gss_destroy, | 1681 | .destroy = gss_destroy, |
1677 | .lookup_cred = gss_lookup_cred, | 1682 | .lookup_cred = gss_lookup_cred, |
1678 | .crcreate = gss_create_cred, | 1683 | .crcreate = gss_create_cred, |
1679 | .pipes_create = gss_pipes_dentries_create, | ||
1680 | .pipes_destroy = gss_pipes_dentries_destroy, | ||
1681 | .list_pseudoflavors = gss_mech_list_pseudoflavors, | 1684 | .list_pseudoflavors = gss_mech_list_pseudoflavors, |
1682 | .info2flavor = gss_mech_info2flavor, | 1685 | .info2flavor = gss_mech_info2flavor, |
1683 | .flavor2info = gss_mech_flavor2info, | 1686 | .flavor2info = gss_mech_flavor2info, |