include/linux/sunrpc/gss_api.h | 70 +++------ net/sunrpc/auth_gss/Makefile | 2 net/sunrpc/auth_gss/auth_gss.c | 17 +- net/sunrpc/auth_gss/gss_krb5_mech.c | 32 ++-- net/sunrpc/auth_gss/gss_mech_switch.c | 191 ++++++++++++++----------- net/sunrpc/auth_gss/gss_pseudoflavors.c | 237 -------------------------------- net/sunrpc/auth_gss/sunrpcgss_syms.c | 14 - net/sunrpc/auth_gss/svcauth_gss.c | 24 +-- 8 files changed, 179 insertions(+), 408 deletions(-) diff -u --recursive --new-file --show-c-function linux-2.6.6-08-gss_krb5_clean/include/linux/sunrpc/gss_api.h linux-2.6.6-09-gss_mech_clean/include/linux/sunrpc/gss_api.h --- linux-2.6.6-08-gss_krb5_clean/include/linux/sunrpc/gss_api.h 2004-05-16 17:08:02.000000000 -0400 +++ linux-2.6.6-09-gss_mech_clean/include/linux/sunrpc/gss_api.h 2004-05-16 17:39:33.000000000 -0400 @@ -50,46 +50,36 @@ u32 gss_verify_mic( u32 gss_delete_sec_context( struct gss_ctx **ctx_id); -/* We maintain a list of the pseudoflavors (equivalently, mechanism-qop-service - * triples) that we currently support: */ - -struct sup_sec_triple { - struct list_head triples; - u32 pseudoflavor; - struct gss_api_mech *mech; - u32 qop; - u32 service; +struct gss_api_mech * gss_mech_get_by_name(char *name); +struct gss_api_mech * gss_mech_get_by_pseudoflavor(u32 pseudoflavor); +u32 gss_pseudoflavor_to_service(struct gss_api_mech *, u32 pseudoflavor); +char *gss_service_to_auth_domain_name(struct gss_api_mech *, u32 service); + +struct pf_desc { + u32 pseudoflavor; + u32 qop; + u32 service; + char *name; + char *auth_domain_name; }; -int gss_register_triple(u32 pseudoflavor, struct gss_api_mech *mech, u32 qop, - u32 service); -int gss_unregister_triple(u32 pseudoflavor); -int gss_pseudoflavor_supported(u32 pseudoflavor); -u32 gss_cmp_triples(u32 oid_len, char *oid_data, u32 qop, u32 service); -u32 gss_get_pseudoflavor(struct gss_ctx *ctx_id, u32 qop, u32 service); -u32 gss_pseudoflavor_to_service(u32 pseudoflavor); -/* Both return NULL on failure: */ -struct gss_api_mech * gss_pseudoflavor_to_mech(u32 pseudoflavor); -int gss_pseudoflavor_to_mechOID(u32 pseudoflavor, struct xdr_netobj *mech); - /* Different mechanisms (e.g., krb5 or spkm3) may implement gss-api, and - * mechanisms may be dynamically registered or unregistered by modules. - * Our only built-in mechanism is a trivial debugging mechanism that provides - * no actual security; the following function registers that mechanism: */ - -void gss_mech_register_debug(void); + * mechanisms may be dynamically registered or unregistered by modules. */ /* Each mechanism is described by the following struct: */ struct gss_api_mech { - struct xdr_netobj gm_oid; struct list_head gm_list; - atomic_t gm_count; + struct module *gm_owner; + struct xdr_netobj gm_oid; + char *gm_name; struct gss_api_ops *gm_ops; + /* pseudoflavors supported by this mechanism: */ + int gm_pf_num; + struct pf_desc gm_pfs[]; }; /* and must provide the following operations: */ struct gss_api_ops { - char *name; u32 (*gss_import_sec_context)( struct xdr_netobj *input_token, struct gss_ctx *ctx_id); @@ -107,29 +97,25 @@ struct gss_api_ops { void *internal_ctx_id); }; -/* Returns nonzero on failure. */ -int gss_mech_register(struct xdr_netobj *, struct gss_api_ops *); - -/* Returns nonzero iff someone still has a reference to this mech. */ -int gss_mech_unregister(struct gss_api_mech *); +int gss_mech_register(struct gss_api_mech *); +void gss_mech_unregister(struct gss_api_mech *); -/* Returns nonzer iff someone still has a reference to some mech. */ -int gss_mech_unregister_all(void); - -/* returns a mechanism descriptor given an OID, an increments the mechanism's +/* returns a mechanism descriptor given an OID, and increments the mechanism's * reference count. */ struct gss_api_mech * gss_mech_get_by_OID(struct xdr_netobj *); -/* Similar, but get by name like "krb5", "spkm", etc., instead of OID. */ +/* Returns a reference to a mechanism, given a name like "krb5" etc. */ struct gss_api_mech *gss_mech_get_by_name(char *); +/* Similar, but get by pseudoflavor. */ +struct gss_api_mech *gss_mech_get_by_pseudoflavor(u32); + /* Just increments the mechanism's reference count and returns its input: */ struct gss_api_mech * gss_mech_get(struct gss_api_mech *); -/* Returns nonzero iff you've released the last reference to this mech. - * Note that for every succesful gss_get_mech call there must be exactly - * one corresponding call to gss_mech_put.*/ -int gss_mech_put(struct gss_api_mech *); +/* For every succesful gss_mech_get or gss_mech_get_by_* call there must be a + * corresponding call to gss_mech_put. */ +void gss_mech_put(struct gss_api_mech *); #endif /* __KERNEL__ */ #endif /* _LINUX_SUNRPC_GSS_API_H */ diff -u --recursive --new-file --show-c-function linux-2.6.6-08-gss_krb5_clean/net/sunrpc/auth_gss/auth_gss.c linux-2.6.6-09-gss_mech_clean/net/sunrpc/auth_gss/auth_gss.c --- linux-2.6.6-08-gss_krb5_clean/net/sunrpc/auth_gss/auth_gss.c 2004-05-16 17:39:25.000000000 -0400 +++ linux-2.6.6-09-gss_mech_clean/net/sunrpc/auth_gss/auth_gss.c 2004-05-16 17:39:33.000000000 -0400 @@ -559,7 +559,7 @@ gss_create(struct rpc_clnt *clnt, rpc_au if (!(gss_auth = kmalloc(sizeof(*gss_auth), GFP_KERNEL))) goto out_dec; - gss_auth->mech = gss_pseudoflavor_to_mech(flavor); + gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor); if (!gss_auth->mech) { printk(KERN_WARNING "%s: Pseudoflavor %d not found!", __FUNCTION__, flavor); @@ -578,7 +578,7 @@ gss_create(struct rpc_clnt *clnt, rpc_au snprintf(gss_auth->path, sizeof(gss_auth->path), "%s/%s", clnt->cl_pathname, - gss_auth->mech->gm_ops->name); + gss_auth->mech->gm_name); gss_auth->dentry = rpc_mkpipe(gss_auth->path, clnt, &gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN); if (IS_ERR(gss_auth->dentry)) goto err_free; @@ -696,7 +696,8 @@ gss_marshal(struct rpc_task *task, u32 * *p++ = htonl(RPC_AUTH_GSS); cred_len = p++; - service = gss_pseudoflavor_to_service(gss_cred->gc_flavor); + service = gss_pseudoflavor_to_service(ctx->gc_gss_ctx->mech_type, + gss_cred->gc_flavor); if (service == 0) { dprintk("RPC: %4u Bad pseudoflavor %d in gss_marshal\n", task->tk_pid, gss_cred->gc_flavor); @@ -785,7 +786,8 @@ gss_validate(struct rpc_task *task, u32 if (gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic, &qop_state)) goto out_bad; - service = gss_pseudoflavor_to_service(gss_cred->gc_flavor); + service = gss_pseudoflavor_to_service(ctx->gc_gss_ctx->mech_type, + gss_cred->gc_flavor); switch (service) { case RPC_GSS_SVC_NONE: /* verifier data, flavor, length: */ @@ -836,7 +838,8 @@ gss_wrap_req(struct rpc_task *task, status = encode(rqstp, p, obj); goto out; } - service = gss_pseudoflavor_to_service(gss_cred->gc_flavor); + service = gss_pseudoflavor_to_service(ctx->gc_gss_ctx->mech_type, + gss_cred->gc_flavor); switch (service) { case RPC_GSS_SVC_NONE: status = encode(rqstp, p, obj); @@ -908,7 +911,8 @@ gss_unwrap_resp(struct rpc_task *task, if (ctx->gc_proc != RPC_GSS_PROC_DATA) goto out_decode; - service = gss_pseudoflavor_to_service(gss_cred->gc_flavor); + service = gss_pseudoflavor_to_service(ctx->gc_gss_ctx->mech_type, + gss_cred->gc_flavor); switch (service) { case RPC_GSS_SVC_NONE: goto out_decode; @@ -999,7 +1003,6 @@ out: static void __exit exit_rpcsec_gss(void) { gss_svc_shutdown(); - gss_mech_unregister_all(); rpcauth_unregister(&authgss_ops); } diff -u --recursive --new-file --show-c-function linux-2.6.6-08-gss_krb5_clean/net/sunrpc/auth_gss/gss_krb5_mech.c linux-2.6.6-09-gss_mech_clean/net/sunrpc/auth_gss/gss_krb5_mech.c --- linux-2.6.6-08-gss_krb5_clean/net/sunrpc/auth_gss/gss_krb5_mech.c 2004-05-16 17:39:25.000000000 -0400 +++ linux-2.6.6-09-gss_mech_clean/net/sunrpc/auth_gss/gss_krb5_mech.c 2004-05-16 17:39:33.000000000 -0400 @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -217,35 +216,36 @@ gss_get_mic_kerberos(struct gss_ctx *ctx } static struct gss_api_ops gss_kerberos_ops = { - .name = "krb5", .gss_import_sec_context = gss_import_sec_context_kerberos, .gss_get_mic = gss_get_mic_kerberos, .gss_verify_mic = gss_verify_mic_kerberos, .gss_delete_sec_context = gss_delete_sec_context_kerberos, }; -/* XXX error checking? reference counting? */ +static struct gss_api_mech gss_kerberos_mech = { + .gm_name = "krb5", + .gm_owner = THIS_MODULE, + .gm_ops = &gss_kerberos_ops, + .gm_pf_num = 2, + .gm_pfs = { + {RPC_AUTH_GSS_KRB5, 0, RPC_GSS_SVC_NONE, "krb5"}, + {RPC_AUTH_GSS_KRB5I, 0, RPC_GSS_SVC_INTEGRITY, "krb5i"}, + }, +}; + static int __init init_kerberos_module(void) { - struct gss_api_mech *gm; + int status; - if (gss_mech_register(&gss_mech_krb5_oid, &gss_kerberos_ops)) + status = gss_mech_register(&gss_kerberos_mech); + if (status) printk("Failed to register kerberos gss mechanism!\n"); - gm = gss_mech_get_by_OID(&gss_mech_krb5_oid); - gss_register_triple(RPC_AUTH_GSS_KRB5 , gm, 0, RPC_GSS_SVC_NONE); - gss_register_triple(RPC_AUTH_GSS_KRB5I, gm, 0, RPC_GSS_SVC_INTEGRITY); - if (svcauth_gss_register_pseudoflavor(RPC_AUTH_GSS_KRB5, "krb5")) - printk("Failed to register %s with server!\n", "krb5"); - if (svcauth_gss_register_pseudoflavor(RPC_AUTH_GSS_KRB5I, "krb5i")) - printk("Failed to register %s with server!\n", "krb5i"); - gss_mech_put(gm); - return 0; + return status; } static void __exit cleanup_kerberos_module(void) { - gss_unregister_triple(RPC_AUTH_GSS_KRB5I); - gss_unregister_triple(RPC_AUTH_GSS_KRB5); + gss_mech_unregister(&gss_kerberos_mech); } MODULE_LICENSE("GPL"); diff -u --recursive --new-file --show-c-function linux-2.6.6-08-gss_krb5_clean/net/sunrpc/auth_gss/gss_mech_switch.c linux-2.6.6-09-gss_mech_clean/net/sunrpc/auth_gss/gss_mech_switch.c --- linux-2.6.6-08-gss_krb5_clean/net/sunrpc/auth_gss/gss_mech_switch.c 2004-05-16 17:39:25.000000000 -0400 +++ linux-2.6.6-09-gss_mech_clean/net/sunrpc/auth_gss/gss_mech_switch.c 2004-05-16 17:39:33.000000000 -0400 @@ -36,9 +36,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -51,143 +53,168 @@ static LIST_HEAD(registered_mechs); static spinlock_t registered_mechs_lock = SPIN_LOCK_UNLOCKED; -/* Reference counting: The reference count includes the reference in the - * global registered_mechs list. That reference will never diseappear - * (so the reference count will never go below 1) until after the mech - * is removed from the list. Nothing can be removed from the list without - * first getting the registered_mechs_lock, so a gss_api_mech won't diseappear - * from underneath us while we hold the registered_mech_lock. */ - -int -gss_mech_register(struct xdr_netobj * mech_type, struct gss_api_ops * ops) +static void +gss_mech_free(struct gss_api_mech *gm) { - struct gss_api_mech *gm; + struct pf_desc *pf; + int i; - if (!(gm = kmalloc(sizeof(*gm), GFP_KERNEL))) { - printk("Failed to allocate memory in gss_mech_register"); - return -1; - } - gm->gm_oid.len = mech_type->len; - if (!(gm->gm_oid.data = kmalloc(mech_type->len, GFP_KERNEL))) { - kfree(gm); - printk("Failed to allocate memory in gss_mech_register"); - return -1; - } - memcpy(gm->gm_oid.data, mech_type->data, mech_type->len); - /* We're counting the reference in the registered_mechs list: */ - atomic_set(&gm->gm_count, 1); - gm->gm_ops = ops; - - spin_lock(®istered_mechs_lock); - list_add(&gm->gm_list, ®istered_mechs); - spin_unlock(®istered_mechs_lock); - dprintk("RPC: gss_mech_register: registered mechanism with oid:\n"); - print_hexl((u32 *)mech_type->data, mech_type->len, 0); - return 0; + for (i = 0; i < gm->gm_pf_num; i++) { + pf = &gm->gm_pfs[i]; + if (pf->auth_domain_name) + kfree(pf->auth_domain_name); + pf->auth_domain_name = NULL; + } } -/* The following must be called with spinlock held: */ -int -do_gss_mech_unregister(struct gss_api_mech *gm) +static inline char * +make_auth_domain_name(char *name) { + static char *prefix = "gss/"; + char *new; - list_del(&gm->gm_list); + new = kmalloc(strlen(name) + strlen(prefix) + 1, GFP_KERNEL); + if (new) { + strcpy(new, prefix); + strcat(new, name); + } + return new; +} + +static int +gss_mech_svc_setup(struct gss_api_mech *gm) +{ + struct pf_desc *pf; + int i, status; - dprintk("RPC: unregistered mechanism with oid:\n"); - print_hexl((u32 *)gm->gm_oid.data, gm->gm_oid.len, 0); - if (!gss_mech_put(gm)) { - dprintk("RPC: We just unregistered a gss_mechanism which someone is still using.\n"); - return -1; - } else { - return 0; + for (i = 0; i < gm->gm_pf_num; i++) { + pf = &gm->gm_pfs[i]; + pf->auth_domain_name = make_auth_domain_name(pf->name); + status = -ENOMEM; + if (pf->auth_domain_name == NULL) + goto out; + status = svcauth_gss_register_pseudoflavor(pf->pseudoflavor, + pf->auth_domain_name); + if (status) + goto out; } + return 0; +out: + gss_mech_free(gm); + return status; } int -gss_mech_unregister(struct gss_api_mech *gm) +gss_mech_register(struct gss_api_mech *gm) { int status; + status = gss_mech_svc_setup(gm); + if (status) + return status; spin_lock(®istered_mechs_lock); - status = do_gss_mech_unregister(gm); + list_add(&gm->gm_list, ®istered_mechs); spin_unlock(®istered_mechs_lock); - return status; + dprintk("RPC: registered gss mechanism %s\n", gm->gm_name); + return 0; } -int -gss_mech_unregister_all(void) +void +gss_mech_unregister(struct gss_api_mech *gm) { - struct list_head *pos; - struct gss_api_mech *gm; - int status = 0; - spin_lock(®istered_mechs_lock); - while (!list_empty(®istered_mechs)) { - pos = registered_mechs.next; - gm = list_entry(pos, struct gss_api_mech, gm_list); - if (do_gss_mech_unregister(gm)) - status = -1; - } + list_del(&gm->gm_list); spin_unlock(®istered_mechs_lock); - return status; + dprintk("RPC: unregistered gss mechanism %s\n", gm->gm_name); + gss_mech_free(gm); } struct gss_api_mech * gss_mech_get(struct gss_api_mech *gm) { - atomic_inc(&gm->gm_count); + __module_get(gm->gm_owner); return gm; } struct gss_api_mech * -gss_mech_get_by_OID(struct xdr_netobj *mech_type) +gss_mech_get_by_name(char *name) { - struct gss_api_mech *pos, *gm = NULL; + struct gss_api_mech *pos, *gm = NULL; - dprintk("RPC: gss_mech_get_by_OID searching for mechanism with OID:\n"); - print_hexl((u32 *)mech_type->data, mech_type->len, 0); spin_lock(®istered_mechs_lock); list_for_each_entry(pos, ®istered_mechs, gm_list) { - if ((pos->gm_oid.len == mech_type->len) - && !memcmp(pos->gm_oid.data, mech_type->data, - mech_type->len)) { - gm = gss_mech_get(pos); + if (0 == strcmp(name, pos->gm_name)) { + if (!try_module_get(pos->gm_owner)) + continue; + gm = pos; break; } } spin_unlock(®istered_mechs_lock); - dprintk("RPC: gss_mech_get_by_OID %s it\n", gm ? "found" : "didn't find"); return gm; + +} + +static inline int +mech_supports_pseudoflavor(struct gss_api_mech *gm, u32 pseudoflavor) +{ + int i; + + for (i = 0; i < gm->gm_pf_num; i++) { + if (gm->gm_pfs[i].pseudoflavor == pseudoflavor) + return 1; + } + return 0; } struct gss_api_mech * -gss_mech_get_by_name(char *name) +gss_mech_get_by_pseudoflavor(u32 pseudoflavor) { - struct gss_api_mech *pos, *gm = NULL; + struct gss_api_mech *pos, *gm = NULL; spin_lock(®istered_mechs_lock); list_for_each_entry(pos, ®istered_mechs, gm_list) { - if (0 == strcmp(name, pos->gm_ops->name)) { - gm = gss_mech_get(pos); - break; + if (!try_module_get(pos->gm_owner)) + continue; + if (!mech_supports_pseudoflavor(pos, pseudoflavor)) { + module_put(pos->gm_owner); + continue; } + gm = pos; + break; } spin_unlock(®istered_mechs_lock); return gm; +} +u32 +gss_pseudoflavor_to_service(struct gss_api_mech *gm, u32 pseudoflavor) +{ + int i; + + for (i = 0; i < gm->gm_pf_num; i++) { + if (gm->gm_pfs[i].pseudoflavor == pseudoflavor) + return gm->gm_pfs[i].service; + } + return 0; } -int -gss_mech_put(struct gss_api_mech * gm) +char * +gss_service_to_auth_domain_name(struct gss_api_mech *gm, u32 service) { - if (atomic_dec_and_test(&gm->gm_count)) { - if (gm->gm_oid.len >0) - kfree(gm->gm_oid.data); - kfree(gm); - return 1; - } else { - return 0; + int i; + + for (i = 0; i < gm->gm_pf_num; i++) { + if (gm->gm_pfs[i].service == service) + return gm->gm_pfs[i].auth_domain_name; } + return NULL; +} + +void +gss_mech_put(struct gss_api_mech * gm) +{ + module_put(gm->gm_owner); } /* The mech could probably be determined from the token instead, but it's just diff -u --recursive --new-file --show-c-function linux-2.6.6-08-gss_krb5_clean/net/sunrpc/auth_gss/gss_pseudoflavors.c linux-2.6.6-09-gss_mech_clean/net/sunrpc/auth_gss/gss_pseudoflavors.c --- linux-2.6.6-08-gss_krb5_clean/net/sunrpc/auth_gss/gss_pseudoflavors.c 2004-05-16 17:39:25.000000000 -0400 +++ linux-2.6.6-09-gss_mech_clean/net/sunrpc/auth_gss/gss_pseudoflavors.c 1969-12-31 19:00:00.000000000 -0500 @@ -1,237 +0,0 @@ -/* - * linux/net/sunrpc/gss_union.c - * - * Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/generic code - * - * Copyright (c) 2001 The Regents of the University of Michigan. - * All rights reserved. - * - * Andy Adamson - * - */ - -/* - * Copyright 1993 by OpenVision Technologies, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appears in all copies and - * that both that copyright notice and this permission notice appear in - * supporting documentation, and that the name of OpenVision not be used - * in advertising or publicity pertaining to distribution of the software - * without specific, written prior permission. OpenVision makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF - * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include - -#ifdef RPC_DEBUG -# define RPCDBG_FACILITY RPCDBG_AUTH -#endif - -static LIST_HEAD(registered_triples); -static spinlock_t registered_triples_lock = SPIN_LOCK_UNLOCKED; - -/* The following must be called with spinlock held: */ -static struct sup_sec_triple * -do_lookup_triple_by_pseudoflavor(u32 pseudoflavor) -{ - struct sup_sec_triple *pos, *triple = NULL; - - list_for_each_entry(pos, ®istered_triples, triples) { - if (pos->pseudoflavor == pseudoflavor) { - triple = pos; - break; - } - } - return triple; -} - -/* XXX Need to think about reference counting of triples and of mechs. - * Currently we do no reference counting of triples, and I think that's - * probably OK given the reference counting on mechs, but there's probably - * a better way to do all this. */ - -int -gss_register_triple(u32 pseudoflavor, struct gss_api_mech *mech, - u32 qop, u32 service) -{ - struct sup_sec_triple *triple; - - if (!(triple = kmalloc(sizeof(*triple), GFP_KERNEL))) { - printk("Alloc failed in gss_register_triple"); - goto err; - } - triple->pseudoflavor = pseudoflavor; - triple->mech = gss_mech_get_by_OID(&mech->gm_oid); - triple->qop = qop; - triple->service = service; - - spin_lock(®istered_triples_lock); - if (do_lookup_triple_by_pseudoflavor(pseudoflavor)) { - printk(KERN_WARNING "RPC: Registered pseudoflavor %d again\n", - pseudoflavor); - goto err_unlock; - } - list_add(&triple->triples, ®istered_triples); - spin_unlock(®istered_triples_lock); - dprintk("RPC: registered pseudoflavor %d\n", pseudoflavor); - - return 0; - -err_unlock: - kfree(triple); - spin_unlock(®istered_triples_lock); -err: - return -1; -} - -int -gss_unregister_triple(u32 pseudoflavor) -{ - struct sup_sec_triple *triple; - - spin_lock(®istered_triples_lock); - if (!(triple = do_lookup_triple_by_pseudoflavor(pseudoflavor))) { - spin_unlock(®istered_triples_lock); - printk("Can't unregister unregistered pseudoflavor %d\n", - pseudoflavor); - return -1; - } - list_del(&triple->triples); - spin_unlock(®istered_triples_lock); - gss_mech_put(triple->mech); - kfree(triple); - return 0; - -} - -void -print_sec_triple(struct xdr_netobj *oid,u32 qop,u32 service) -{ - dprintk("RPC: print_sec_triple:\n"); - dprintk(" oid_len %d\n oid :\n",oid->len); - print_hexl((u32 *)oid->data,oid->len,0); - dprintk(" qop %d\n",qop); - dprintk(" service %d\n",service); -} - -/* Function: gss_get_cmp_triples - * - * Description: search sec_triples for a matching security triple - * return pseudoflavor if match, else 0 - * (Note that 0 is a valid pseudoflavor, but not for any gss pseudoflavor - * (0 means auth_null), so this shouldn't cause confusion.) - */ -u32 -gss_cmp_triples(u32 oid_len, char *oid_data, u32 qop, u32 service) -{ - struct sup_sec_triple *triple; - u32 pseudoflavor = 0; - struct xdr_netobj oid; - - oid.len = oid_len; - oid.data = oid_data; - - dprintk("RPC: gss_cmp_triples\n"); - print_sec_triple(&oid,qop,service); - - spin_lock(®istered_triples_lock); - list_for_each_entry(triple, ®istered_triples, triples) { - if((g_OID_equal(&oid, &triple->mech->gm_oid)) - && (qop == triple->qop) - && (service == triple->service)) { - pseudoflavor = triple->pseudoflavor; - break; - } - } - spin_unlock(®istered_triples_lock); - dprintk("RPC: gss_cmp_triples return %d\n", pseudoflavor); - return pseudoflavor; -} - -u32 -gss_get_pseudoflavor(struct gss_ctx *ctx, u32 qop, u32 service) -{ - return gss_cmp_triples(ctx->mech_type->gm_oid.len, - ctx->mech_type->gm_oid.data, - qop, service); -} - -/* Returns nonzero iff the given pseudoflavor is in the supported list. - * (Note that without incrementing a reference count or anything, this - * doesn't give any guarantees.) */ -int -gss_pseudoflavor_supported(u32 pseudoflavor) -{ - struct sup_sec_triple *triple; - - spin_lock(®istered_triples_lock); - triple = do_lookup_triple_by_pseudoflavor(pseudoflavor); - spin_unlock(®istered_triples_lock); - return (triple ? 1 : 0); -} - -u32 -gss_pseudoflavor_to_service(u32 pseudoflavor) -{ - struct sup_sec_triple *triple; - - spin_lock(®istered_triples_lock); - triple = do_lookup_triple_by_pseudoflavor(pseudoflavor); - spin_unlock(®istered_triples_lock); - if (!triple) { - dprintk("RPC: gss_pseudoflavor_to_service called with unsupported pseudoflavor %d\n", - pseudoflavor); - return 0; - } - return triple->service; -} - -struct gss_api_mech * -gss_pseudoflavor_to_mech(u32 pseudoflavor) { - struct sup_sec_triple *triple; - struct gss_api_mech *mech = NULL; - - spin_lock(®istered_triples_lock); - triple = do_lookup_triple_by_pseudoflavor(pseudoflavor); - spin_unlock(®istered_triples_lock); - if (triple) - mech = gss_mech_get(triple->mech); - else - dprintk("RPC: gss_pseudoflavor_to_mech called with unsupported pseudoflavor %d\n", - pseudoflavor); - return mech; -} - -int -gss_pseudoflavor_to_mechOID(u32 pseudoflavor, struct xdr_netobj * oid) -{ - struct gss_api_mech *mech; - - mech = gss_pseudoflavor_to_mech(pseudoflavor); - if (!mech) { - dprintk("RPC: gss_pseudoflavor_to_mechOID called with unsupported pseudoflavor %d\n", - pseudoflavor); - return -1; - } - oid->len = mech->gm_oid.len; - if (!(oid->data = kmalloc(oid->len, GFP_KERNEL))) - return -1; - memcpy(oid->data, mech->gm_oid.data, oid->len); - gss_mech_put(mech); - return 0; -} diff -u --recursive --new-file --show-c-function linux-2.6.6-08-gss_krb5_clean/net/sunrpc/auth_gss/Makefile linux-2.6.6-09-gss_mech_clean/net/sunrpc/auth_gss/Makefile --- linux-2.6.6-08-gss_krb5_clean/net/sunrpc/auth_gss/Makefile 2004-05-16 17:39:29.000000000 -0400 +++ linux-2.6.6-09-gss_mech_clean/net/sunrpc/auth_gss/Makefile 2004-05-16 17:39:33.000000000 -0400 @@ -4,7 +4,7 @@ obj-$(CONFIG_SUNRPC_GSS) += auth_rpcgss.o -auth_rpcgss-objs := auth_gss.o gss_pseudoflavors.o gss_generic_token.o \ +auth_rpcgss-objs := auth_gss.o gss_generic_token.o \ sunrpcgss_syms.o gss_mech_switch.o svcauth_gss.o gss_krb5_crypto.o obj-$(CONFIG_RPCSEC_GSS_KRB5) += rpcsec_gss_krb5.o diff -u --recursive --new-file --show-c-function linux-2.6.6-08-gss_krb5_clean/net/sunrpc/auth_gss/sunrpcgss_syms.c linux-2.6.6-09-gss_mech_clean/net/sunrpc/auth_gss/sunrpcgss_syms.c --- linux-2.6.6-08-gss_krb5_clean/net/sunrpc/auth_gss/sunrpcgss_syms.c 2004-05-16 17:39:29.000000000 -0400 +++ linux-2.6.6-09-gss_mech_clean/net/sunrpc/auth_gss/sunrpcgss_syms.c 2004-05-16 18:38:37.000000000 -0400 @@ -12,20 +12,18 @@ #include #include -/* sec_triples: */ -EXPORT_SYMBOL(gss_register_triple); -EXPORT_SYMBOL(gss_unregister_triple); -EXPORT_SYMBOL(gss_cmp_triples); -EXPORT_SYMBOL(gss_pseudoflavor_to_mechOID); -EXPORT_SYMBOL(gss_pseudoflavor_supported); -EXPORT_SYMBOL(gss_pseudoflavor_to_service); +/* svcauth_gss.c: */ EXPORT_SYMBOL(svcauth_gss_register_pseudoflavor); /* registering gss mechanisms to the mech switching code: */ EXPORT_SYMBOL(gss_mech_register); +EXPORT_SYMBOL(gss_mech_unregister); EXPORT_SYMBOL(gss_mech_get); -EXPORT_SYMBOL(gss_mech_get_by_OID); +EXPORT_SYMBOL(gss_mech_get_by_pseudoflavor); +EXPORT_SYMBOL(gss_mech_get_by_name); EXPORT_SYMBOL(gss_mech_put); +EXPORT_SYMBOL(gss_pseudoflavor_to_service); +EXPORT_SYMBOL(gss_service_to_auth_domain_name); /* generic functionality in gss code: */ EXPORT_SYMBOL(g_make_token_header); diff -u --recursive --new-file --show-c-function linux-2.6.6-08-gss_krb5_clean/net/sunrpc/auth_gss/svcauth_gss.c linux-2.6.6-09-gss_mech_clean/net/sunrpc/auth_gss/svcauth_gss.c --- linux-2.6.6-08-gss_krb5_clean/net/sunrpc/auth_gss/svcauth_gss.c 2004-05-16 17:39:25.000000000 -0400 +++ linux-2.6.6-09-gss_mech_clean/net/sunrpc/auth_gss/svcauth_gss.c 2004-05-16 17:39:33.000000000 -0400 @@ -617,19 +617,15 @@ struct gss_domain { u32 pseudoflavor; }; -/* XXX this should be done in gss_pseudoflavors, and shouldn't be hardcoded: */ static struct auth_domain * find_gss_auth_domain(struct gss_ctx *ctx, u32 svc) { - switch(gss_get_pseudoflavor(ctx, 0, svc)) { - case RPC_AUTH_GSS_KRB5: - return auth_domain_find("gss/krb5"); - case RPC_AUTH_GSS_KRB5I: - return auth_domain_find("gss/krb5i"); - case RPC_AUTH_GSS_KRB5P: - return auth_domain_find("gss/krb5p"); - } - return NULL; + char *name; + + name = gss_service_to_auth_domain_name(ctx->mech_type, svc); + if (!name) + return NULL; + return auth_domain_find(name); } int @@ -637,19 +633,17 @@ svcauth_gss_register_pseudoflavor(u32 ps { struct gss_domain *new; struct auth_domain *test; - static char *prefix = "gss/"; - int stat = -1; + int stat = -ENOMEM; new = kmalloc(sizeof(*new), GFP_KERNEL); if (!new) goto out; cache_init(&new->h.h); atomic_inc(&new->h.h.refcnt); - new->h.name = kmalloc(strlen(name) + strlen(prefix) + 1, GFP_KERNEL); + new->h.name = kmalloc(strlen(name) + 1, GFP_KERNEL); if (!new->h.name) goto out_free_dom; - strcpy(new->h.name, prefix); - strcat(new->h.name, name); + strcpy(new->h.name, name); new->h.flavour = RPC_AUTH_GSS; new->pseudoflavor = pseudoflavor; new->h.h.expiry_time = NEVER;