| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *  linux/net/sunrpc/gss_mech_switch.c | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Copyright (c) 2001 The Regents of the University of Michigan. | 
					
						
							|  |  |  |  *  All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  J. Bruce Fields   <bfields@umich.edu> | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2007-02-09 15:38:13 -08:00
										 |  |  |  *  Redistribution and use in source and binary forms, with or without | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |  *  modification, are permitted provided that the following conditions | 
					
						
							|  |  |  |  *  are met: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  1. Redistributions of source code must retain the above copyright | 
					
						
							|  |  |  |  *     notice, this list of conditions and the following disclaimer. | 
					
						
							|  |  |  |  *  2. Redistributions in binary form must reproduce the above copyright | 
					
						
							| 
									
										
										
										
											2007-02-09 15:38:13 -08:00
										 |  |  |  *     notice, this list of conditions and the following disclaimer in the | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |  *     documentation and/or other materials provided with the distribution. | 
					
						
							|  |  |  |  *  3. Neither the name of the University nor the names of its | 
					
						
							|  |  |  |  *     contributors may be used to endorse or promote products derived | 
					
						
							|  |  |  |  *     from this software without specific prior written permission. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | 
					
						
							|  |  |  |  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | 
					
						
							|  |  |  |  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 
					
						
							|  |  |  |  *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 
					
						
							|  |  |  |  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 
					
						
							|  |  |  |  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 
					
						
							|  |  |  |  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | 
					
						
							|  |  |  |  *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | 
					
						
							|  |  |  |  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | 
					
						
							|  |  |  |  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 
					
						
							|  |  |  |  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <linux/types.h>
 | 
					
						
							|  |  |  | #include <linux/slab.h>
 | 
					
						
							|  |  |  | #include <linux/module.h>
 | 
					
						
							|  |  |  | #include <linux/sunrpc/msg_prot.h>
 | 
					
						
							|  |  |  | #include <linux/sunrpc/gss_asn1.h>
 | 
					
						
							|  |  |  | #include <linux/sunrpc/auth_gss.h>
 | 
					
						
							|  |  |  | #include <linux/sunrpc/svcauth_gss.h>
 | 
					
						
							|  |  |  | #include <linux/sunrpc/gss_err.h>
 | 
					
						
							|  |  |  | #include <linux/sunrpc/sched.h>
 | 
					
						
							|  |  |  | #include <linux/sunrpc/gss_api.h>
 | 
					
						
							|  |  |  | #include <linux/sunrpc/clnt.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef RPC_DEBUG
 | 
					
						
							|  |  |  | # define RPCDBG_FACILITY        RPCDBG_AUTH
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static LIST_HEAD(registered_mechs); | 
					
						
							|  |  |  | static DEFINE_SPINLOCK(registered_mechs_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | gss_mech_free(struct gss_api_mech *gm) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct pf_desc *pf; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < gm->gm_pf_num; i++) { | 
					
						
							|  |  |  | 		pf = &gm->gm_pfs[i]; | 
					
						
							| 
									
										
										
										
											2005-11-08 09:41:34 -08:00
										 |  |  | 		kfree(pf->auth_domain_name); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		pf->auth_domain_name = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline char * | 
					
						
							|  |  |  | make_auth_domain_name(char *name) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	static char	*prefix = "gss/"; | 
					
						
							|  |  |  | 	char		*new; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	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; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	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_register(struct gss_api_mech *gm) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int status; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	status = gss_mech_svc_setup(gm); | 
					
						
							|  |  |  | 	if (status) | 
					
						
							|  |  |  | 		return status; | 
					
						
							|  |  |  | 	spin_lock(®istered_mechs_lock); | 
					
						
							|  |  |  | 	list_add(&gm->gm_list, ®istered_mechs); | 
					
						
							|  |  |  | 	spin_unlock(®istered_mechs_lock); | 
					
						
							| 
									
										
										
										
											2007-01-31 12:14:05 -05:00
										 |  |  | 	dprintk("RPC:       registered gss mechanism %s\n", gm->gm_name); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-23 15:21:32 -05:00
										 |  |  | EXPORT_SYMBOL_GPL(gss_mech_register); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | gss_mech_unregister(struct gss_api_mech *gm) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	spin_lock(®istered_mechs_lock); | 
					
						
							|  |  |  | 	list_del(&gm->gm_list); | 
					
						
							|  |  |  | 	spin_unlock(®istered_mechs_lock); | 
					
						
							| 
									
										
										
										
											2007-01-31 12:14:05 -05:00
										 |  |  | 	dprintk("RPC:       unregistered gss mechanism %s\n", gm->gm_name); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	gss_mech_free(gm); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-23 15:21:32 -05:00
										 |  |  | EXPORT_SYMBOL_GPL(gss_mech_unregister); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | struct gss_api_mech * | 
					
						
							|  |  |  | gss_mech_get(struct gss_api_mech *gm) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	__module_get(gm->gm_owner); | 
					
						
							|  |  |  | 	return gm; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-23 15:21:32 -05:00
										 |  |  | EXPORT_SYMBOL_GPL(gss_mech_get); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | struct gss_api_mech * | 
					
						
							|  |  |  | gss_mech_get_by_name(const char *name) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	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_name)) { | 
					
						
							|  |  |  | 			if (try_module_get(pos->gm_owner)) | 
					
						
							|  |  |  | 				gm = pos; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	spin_unlock(®istered_mechs_lock); | 
					
						
							|  |  |  | 	return gm; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-23 15:21:32 -05:00
										 |  |  | EXPORT_SYMBOL_GPL(gss_mech_get_by_name); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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_pseudoflavor(u32 pseudoflavor) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct gss_api_mech *pos, *gm = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spin_lock(®istered_mechs_lock); | 
					
						
							|  |  |  | 	list_for_each_entry(pos, ®istered_mechs, gm_list) { | 
					
						
							|  |  |  | 		if (!mech_supports_pseudoflavor(pos, pseudoflavor)) { | 
					
						
							|  |  |  | 			module_put(pos->gm_owner); | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (try_module_get(pos->gm_owner)) | 
					
						
							|  |  |  | 			gm = pos; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	spin_unlock(®istered_mechs_lock); | 
					
						
							|  |  |  | 	return gm; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-23 15:21:32 -05:00
										 |  |  | EXPORT_SYMBOL_GPL(gss_mech_get_by_pseudoflavor); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-07-17 04:04:42 -07:00
										 |  |  | u32 | 
					
						
							|  |  |  | gss_svc_to_pseudoflavor(struct gss_api_mech *gm, u32 service) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < gm->gm_pf_num; i++) { | 
					
						
							|  |  |  | 		if (gm->gm_pfs[i].service == service) { | 
					
						
							|  |  |  | 			return gm->gm_pfs[i].pseudoflavor; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return RPC_AUTH_MAXFLAVOR; /* illegal value */ | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-23 15:21:32 -05:00
										 |  |  | EXPORT_SYMBOL_GPL(gss_svc_to_pseudoflavor); | 
					
						
							| 
									
										
										
										
											2007-07-17 04:04:42 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-23 15:21:32 -05:00
										 |  |  | EXPORT_SYMBOL_GPL(gss_pseudoflavor_to_service); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | char * | 
					
						
							|  |  |  | gss_service_to_auth_domain_name(struct gss_api_mech *gm, u32 service) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-23 15:21:32 -05:00
										 |  |  | EXPORT_SYMBOL_GPL(gss_service_to_auth_domain_name); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | gss_mech_put(struct gss_api_mech * gm) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-06-30 01:56:16 -07:00
										 |  |  | 	if (gm) | 
					
						
							|  |  |  | 		module_put(gm->gm_owner); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-23 15:21:32 -05:00
										 |  |  | EXPORT_SYMBOL_GPL(gss_mech_put); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* The mech could probably be determined from the token instead, but it's just
 | 
					
						
							|  |  |  |  * as easy for now to pass it in. */ | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | gss_import_sec_context(const void *input_token, size_t bufsize, | 
					
						
							|  |  |  | 		       struct gss_api_mech	*mech, | 
					
						
							| 
									
										
										
										
											2010-05-13 12:51:02 -04:00
										 |  |  | 		       struct gss_ctx		**ctx_id, | 
					
						
							|  |  |  | 		       gfp_t gfp_mask) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-13 12:51:02 -04:00
										 |  |  | 	if (!(*ctx_id = kzalloc(sizeof(**ctx_id), gfp_mask))) | 
					
						
							| 
									
										
										
										
											2009-12-18 16:28:12 -05:00
										 |  |  | 		return -ENOMEM; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	(*ctx_id)->mech_type = gss_mech_get(mech); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return mech->gm_ops | 
					
						
							| 
									
										
										
										
											2010-05-13 12:51:02 -04:00
										 |  |  | 		->gss_import_sec_context(input_token, bufsize, *ctx_id, gfp_mask); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* gss_get_mic: compute a mic over message and return mic_token. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | u32 | 
					
						
							|  |  |  | gss_get_mic(struct gss_ctx	*context_handle, | 
					
						
							|  |  |  | 	    struct xdr_buf	*message, | 
					
						
							|  |  |  | 	    struct xdr_netobj	*mic_token) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	 return context_handle->mech_type->gm_ops | 
					
						
							|  |  |  | 		->gss_get_mic(context_handle, | 
					
						
							|  |  |  | 			      message, | 
					
						
							|  |  |  | 			      mic_token); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* gss_verify_mic: check whether the provided mic_token verifies message. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | u32 | 
					
						
							|  |  |  | gss_verify_mic(struct gss_ctx		*context_handle, | 
					
						
							|  |  |  | 	       struct xdr_buf		*message, | 
					
						
							| 
									
										
										
										
											2005-10-13 16:55:18 -04:00
										 |  |  | 	       struct xdr_netobj	*mic_token) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	return context_handle->mech_type->gm_ops | 
					
						
							|  |  |  | 		->gss_verify_mic(context_handle, | 
					
						
							|  |  |  | 				 message, | 
					
						
							| 
									
										
										
										
											2005-10-13 16:55:18 -04:00
										 |  |  | 				 mic_token); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-17 13:02:47 -04:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * This function is called from both the client and server code. | 
					
						
							|  |  |  |  * Each makes guarantees about how much "slack" space is available | 
					
						
							|  |  |  |  * for the underlying function in "buf"'s head and tail while | 
					
						
							|  |  |  |  * performing the wrap. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The client and server code allocate RPC_MAX_AUTH_SIZE extra | 
					
						
							|  |  |  |  * space in both the head and tail which is available for use by | 
					
						
							|  |  |  |  * the wrap function. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Underlying functions should verify they do not use more than | 
					
						
							|  |  |  |  * RPC_MAX_AUTH_SIZE of extra space in either the head or tail | 
					
						
							|  |  |  |  * when performing the wrap. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2005-10-13 16:54:37 -04:00
										 |  |  | u32 | 
					
						
							|  |  |  | gss_wrap(struct gss_ctx	*ctx_id, | 
					
						
							|  |  |  | 	 int		offset, | 
					
						
							|  |  |  | 	 struct xdr_buf	*buf, | 
					
						
							|  |  |  | 	 struct page	**inpages) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return ctx_id->mech_type->gm_ops | 
					
						
							| 
									
										
										
										
											2005-10-13 16:55:18 -04:00
										 |  |  | 		->gss_wrap(ctx_id, offset, buf, inpages); | 
					
						
							| 
									
										
										
										
											2005-10-13 16:54:37 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | u32 | 
					
						
							|  |  |  | gss_unwrap(struct gss_ctx	*ctx_id, | 
					
						
							|  |  |  | 	   int			offset, | 
					
						
							|  |  |  | 	   struct xdr_buf	*buf) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return ctx_id->mech_type->gm_ops | 
					
						
							| 
									
										
										
										
											2005-10-13 16:55:18 -04:00
										 |  |  | 		->gss_unwrap(ctx_id, offset, buf); | 
					
						
							| 
									
										
										
										
											2005-10-13 16:54:37 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | /* gss_delete_sec_context: free all resources associated with context_handle.
 | 
					
						
							|  |  |  |  * Note this differs from the RFC 2744-specified prototype in that we don't | 
					
						
							|  |  |  |  * bother returning an output token, since it would never be used anyway. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | u32 | 
					
						
							|  |  |  | gss_delete_sec_context(struct gss_ctx	**context_handle) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-01-31 12:14:05 -05:00
										 |  |  | 	dprintk("RPC:       gss_delete_sec_context deleting %p\n", | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 			*context_handle); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!*context_handle) | 
					
						
							| 
									
										
										
										
											2010-09-22 20:43:57 +00:00
										 |  |  | 		return GSS_S_NO_CONTEXT; | 
					
						
							| 
									
										
										
										
											2008-03-17 22:48:03 -07:00
										 |  |  | 	if ((*context_handle)->internal_ctx_id) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		(*context_handle)->mech_type->gm_ops | 
					
						
							|  |  |  | 			->gss_delete_sec_context((*context_handle) | 
					
						
							|  |  |  | 							->internal_ctx_id); | 
					
						
							| 
									
										
										
										
											2006-06-30 01:56:16 -07:00
										 |  |  | 	gss_mech_put((*context_handle)->mech_type); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	kfree(*context_handle); | 
					
						
							|  |  |  | 	*context_handle=NULL; | 
					
						
							|  |  |  | 	return GSS_S_COMPLETE; | 
					
						
							|  |  |  | } |