1    	/*
2    	 * Copyright (c) 2012 Linux Box Corporation.
3    	 * All rights reserved.
4    	 *
5    	 * Redistribution and use in source and binary forms, with or without
6    	 * modification, are permitted provided that the following conditions
7    	 * are met:
8    	 * 1. Redistributions of source code must retain the above copyright
9    	 *    notice, this list of conditions and the following disclaimer.
10   	 * 2. Redistributions in binary form must reproduce the above copyright
11   	 *    notice, this list of conditions and the following disclaimer in the
12   	 *    documentation and/or other materials provided with the distribution.
13   	 *
14   	 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
15   	 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16   	 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17   	 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18   	 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19   	 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20   	 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21   	 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22   	 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23   	 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24   	 */
25   	
26   	#ifndef GSS_INTERNAL_H
27   	#define GSS_INTERNAL_H
28   	
29   	#include <stdint.h>
30   	#include <stdbool.h>
31   	#include <stdlib.h>
32   	#include <pthread.h>
33   	#include <reentrant.h>
34   	#include <sys/types.h>
35   	#include <rpc/rpc.h>
36   	#include <misc/rbtree_x.h>
37   	#include <misc/queue.h>
38   	#include <misc/abstract_atomic.h>
39   	#include <intrinsic.h>
40   	
41   	#ifdef HAVE_HEIMDAL
42   	#include <gssapi.h>
43   	#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
44   	#else
45   	#include <gssapi/gssapi.h>
46   	#include <gssapi/gssapi_generic.h>
47   	#include <gssapi/gssapi_ext.h>
48   	#endif
49   	#include <rpc/auth_gss.h>
50   	
51   	extern SVCAUTH svc_auth_none;
52   	
53   	#define SVCAUTH_PRIVATE(auth) \
54   		((struct svc_rpc_gss_data *)(auth)->svc_ah_private)
55   	
56   	/*
57   	 * from mit-krb5-1.2.1 mechglue/mglueP.h:
58   	 * Array of context IDs typed by mechanism OID
59   	 */
60   	struct gss_union_ctx_id {
61   		gss_OID mech_type;
62   		gss_ctx_id_t internal_ctx_id;
63   	};
64   	
65   	typedef struct gss_union_ctx_id gss_union_ctx_id_desc;
66   	typedef gss_union_ctx_id_desc *gss_union_ctx_id_t;
67   	
68   	#define SVC_RPC_GSS_FLAG_NONE    0x0000
69   	#define SVC_RPC_GSS_FLAG_MSPAC   0x0001
70   	
71   	struct svc_rpc_gss_data {
72   		struct opr_rbtree_node node_k;
73   		 TAILQ_ENTRY(svc_rpc_gss_data) lru_q;
74   		mutex_t lock;
75   		uint32_t flags;
76   		uint32_t refcnt;
77   		uint32_t gen;
78   		struct {
79   			uint32_t k;
80   		} hk;
81   		bool established;
82   		gss_ctx_id_t ctx;	/* context id */
83   		struct rpc_gss_sec sec;	/* security triple */
84   		gss_buffer_desc cname;	/* GSS client name */
85   		u_int seq;
86   		u_int win;
87   		u_int seqlast;
88   		uint32_t seqmask;
89   		gss_name_t client_name;
90   		gss_buffer_desc checksum;
91   		struct {
92   			/* extended krb5 ticket ("pac") data */
93   			gss_buffer_desc ms_pac;
94   		} pac;
95   		SVCAUTH *auth;
96   		uint32_t endtime;
97   	};
98   	
99   	bool svcauth_gss_destroy(SVCAUTH *auth);
100  	
101  	static inline struct
102  	svc_rpc_gss_data *alloc_svc_rpc_gss_data(void)
103  	{
104  		struct svc_rpc_gss_data *gd =
105  			(struct svc_rpc_gss_data *)
106  			mem_zalloc(sizeof(struct svc_rpc_gss_data));
107  	
108  		mutex_init(&gd->lock, NULL);
(1) Event missing_lock: Accessing "gd->lru_q.tqe_next" without holding lock "rbtree_x_part.mtx". Elsewhere, "svc_rpc_gss_data.lru_q.tqe_next" is accessed with "rbtree_x_part.mtx" held 4 out of 5 times.
Also see events: [example_lock][example_access][example_lock][example_access][example_lock][example_access][example_lock][example_access]
109  		TAILQ_INIT_ENTRY(gd, lru_q);
110  		gd->refcnt = 1;
111  		return (gd);
112  	}
113  	
114  	static inline void
115  	unref_svc_rpc_gss_data(struct svc_rpc_gss_data *gd)
116  	{
117  		mutex_lock(&gd->lock);
118  	
119  		/* if refcnt is 0, gd is not reachable */
120  		if (unlikely(atomic_dec_uint32_t(&gd->refcnt) == 0)) {
121  			svcauth_gss_destroy(gd->auth);
122  		}
123  	
124  		mutex_unlock(&gd->lock);
125  	}
126  	
127  	struct svc_rpc_gss_data *authgss_ctx_hash_get(struct rpc_gss_cred *gc);
128  	bool authgss_ctx_hash_set(struct svc_rpc_gss_data *gd);
129  	bool authgss_ctx_hash_del(struct svc_rpc_gss_data *gd);
130  	
131  	bool svcauth_gss_acquire_cred(void);
132  	bool svcauth_gss_release_cred(void);
133  	bool svcauth_gss_import_name(char *service);
134  	bool svcauth_gss_set_svc_name(gss_name_t name);
135  	
136  	#endif				/* GSS_INTERNAL_H */
137