1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2004 Cluster File Systems, Inc.
6 * This file is part of Lustre, http://www.lustre.org.
8 * Lustre is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU General Public
10 * License as published by the Free Software Foundation.
12 * Lustre is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Lustre; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #ifndef __LINUX_SEC_H_
23 #define __LINUX_SEC_H_
25 /* forward declaration */
27 struct ptlrpc_request;
29 struct ptlrpc_credops;
33 #define PTLRPC_SEC_MAX_FLAVORS (4)
35 typedef struct ptlrpcs_flavor_s {
40 enum ptlrpcs_security_type {
41 PTLRPC_SEC_TYPE_NONE = 0, /* no security */
42 PTLRPC_SEC_TYPE_AUTH = 1, /* authentication */
43 PTLRPC_SEC_TYPE_PRIV = 2, /* privacy */
47 * This header is prepended at any on-wire ptlrpc packets
49 struct ptlrpcs_wire_hdr {
57 struct ptlrpcs_wire_hdr *buf_to_sec_hdr(void *buf)
59 return (struct ptlrpcs_wire_hdr *) buf;
63 struct lustre_msg *buf_to_lustre_msg(void *buf)
65 return (struct lustre_msg *)
66 ((char *) buf + sizeof(struct ptlrpcs_wire_hdr));
70 __u8 *buf_to_sec_data(void *buf)
72 struct ptlrpcs_wire_hdr *hdr = buf_to_sec_hdr(buf);
73 return (__u8 *) (buf + sizeof(*hdr) + hdr->msg_len);
76 enum ptlrpcs_flavors {
81 #define PTLRPC_SEC_GSS_VERSION (1)
83 enum ptlrpcs_gss_subflavors {
84 PTLRPC_SEC_GSS_KRB5 = 0,
85 PTLRPC_SEC_GSS_KRB5I = 1,
86 PTLRPC_SEC_GSS_KRB5P = 2,
89 enum ptlrpcs_gss_proc {
90 PTLRPC_GSS_PROC_DATA = 0,
91 PTLRPC_GSS_PROC_INIT = 1,
92 PTLRPC_GSS_PROC_CONTINUE_INIT = 2,
93 PTLRPC_GSS_PROC_DESTROY = 3,
94 PTLRPC_GSS_PROC_ERR = 4,
97 enum ptlrpcs_gss_svc {
98 PTLRPC_GSS_SVC_NONE = 1,
99 PTLRPC_GSS_SVC_INTEGRITY = 2,
100 PTLRPC_GSS_SVC_PRIVACY = 3,
106 PTLRPCS_REJECTEDCRED = 2,
108 PTLRPCS_REJECTEDVERF = 4,
111 PTLRPCS_GSS_CREDPROBLEM = 13,
112 PTLRPCS_GSS_CTXPROBLEM = 14,
119 struct group_info *vc_ginfo;
122 struct ptlrpc_credops {
123 int (*match) (struct ptlrpc_cred *cred, struct vfs_cred *vcred);
124 int (*refresh)(struct ptlrpc_cred *cred);
125 void (*destroy)(struct ptlrpc_cred *cred);
126 int (*sign) (struct ptlrpc_cred *cred,
127 struct ptlrpc_request *req);
128 int (*verify) (struct ptlrpc_cred *cred,
129 struct ptlrpc_request *req);
130 int (*seal) (struct ptlrpc_cred *cred,
131 struct ptlrpc_request *req);
132 int (*unseal) (struct ptlrpc_cred *cred,
133 struct ptlrpc_request *req);
136 #define PTLRPC_CRED_UPTODATE 0x00000001 /* uptodate */
137 #define PTLRPC_CRED_DEAD 0x00000002 /* mark expired gracefully */
138 #define PTLRPC_CRED_ERROR 0x00000004 /* fatal error (refresh, etc.) */
139 #define PTLRPC_CRED_FLAGS_MASK 0x00000007
142 struct list_head pc_hash; /* linked into hash table */
143 atomic_t pc_refcount;
144 struct ptlrpc_sec *pc_sec;
145 struct ptlrpc_credops *pc_ops;
146 unsigned long pc_expire;
148 /* XXX maybe should not be here */
153 struct ptlrpc_secops {
154 struct ptlrpc_sec * (*create_sec) (ptlrpcs_flavor_t *flavor,
155 const char *pipe_dir,
157 void (*destroy_sec) (struct ptlrpc_sec *sec);
158 struct ptlrpc_cred * (*create_cred) (struct ptlrpc_sec *sec,
159 struct vfs_cred *vcred);
160 /* buffer manipulation */
161 int (*alloc_reqbuf) (struct ptlrpc_sec *sec,
162 struct ptlrpc_request *req,
163 int lustre_msg_size);
164 int (*alloc_repbuf) (struct ptlrpc_sec *sec,
165 struct ptlrpc_request *req,
166 int lustre_msg_size);
167 void (*free_reqbuf) (struct ptlrpc_sec *sec,
168 struct ptlrpc_request *req);
169 void (*free_repbuf) (struct ptlrpc_sec *sec,
170 struct ptlrpc_request *req);
171 /* security payload size estimation */
172 int (*est_req_payload)(struct ptlrpc_sec *sec,
174 int (*est_rep_payload)(struct ptlrpc_sec *sec,
178 struct ptlrpc_sec_type {
179 struct module *pst_owner;
181 atomic_t pst_inst; /* instance, debug only */
182 ptlrpcs_flavor_t pst_flavor;
183 struct ptlrpc_secops *pst_ops;
186 #define PTLRPC_CREDCACHE_NR 8
187 #define PTLRPC_CREDCACHE_MASK (PTLRPC_CREDCACHE_NR - 1)
190 struct ptlrpc_sec_type *ps_type;
191 struct list_head ps_credcache[PTLRPC_CREDCACHE_NR];
192 spinlock_t ps_lock; /* protect cred cache */
194 ptlrpcs_flavor_t ps_flavor;
195 atomic_t ps_refcount;
196 atomic_t ps_credcount;
197 struct obd_import *ps_import;
198 /* actual security model need initialize following fields */
199 unsigned long ps_expire; /* cache expire interval */
200 unsigned long ps_nextgc; /* next gc time */
201 unsigned int ps_flags;
205 int ptlrpcs_register(struct ptlrpc_sec_type *type);
206 int ptlrpcs_unregister(struct ptlrpc_sec_type *type);
208 struct ptlrpc_sec * ptlrpcs_sec_create(ptlrpcs_flavor_t *flavor,
209 struct obd_import *import,
210 const char *pipe_dir,
212 void ptlrpcs_sec_put(struct ptlrpc_sec *sec);
213 void ptlrpcs_sec_invalidate_cache(struct ptlrpc_sec *sec);
215 struct ptlrpc_cred * ptlrpcs_cred_lookup(struct ptlrpc_sec *sec,
216 struct vfs_cred *vcred);
217 void ptlrpcs_cred_put(struct ptlrpc_cred *cred, int sync);
219 static inline void ptlrpcs_cred_get(struct ptlrpc_cred *cred)
221 LASSERT(atomic_read(&cred->pc_refcount));
222 atomic_inc(&cred->pc_refcount);
225 static inline int ptlrpcs_cred_is_uptodate(struct ptlrpc_cred *cred)
228 LASSERT(atomic_read(&cred->pc_refcount));
229 return ((cred->pc_flags & PTLRPC_CRED_FLAGS_MASK) ==
230 PTLRPC_CRED_UPTODATE);
232 static inline int ptlrpcs_cred_refresh(struct ptlrpc_cred *cred)
235 LASSERT(atomic_read(&cred->pc_refcount));
236 LASSERT(cred->pc_ops);
237 LASSERT(cred->pc_ops->refresh);
238 return cred->pc_ops->refresh(cred);
240 static inline void ptlrpcs_cred_die(struct ptlrpc_cred *cred)
242 LASSERT(atomic_read(&cred->pc_refcount));
243 LASSERT(cred->pc_sec);
244 if (!(cred->pc_flags & PTLRPC_CRED_DEAD)) {
245 spin_lock(&cred->pc_sec->ps_lock);
246 cred->pc_flags |= PTLRPC_CRED_DEAD;
247 cred->pc_flags &= ~PTLRPC_CRED_UPTODATE;
248 list_del_init(&cred->pc_hash);
249 spin_unlock(&cred->pc_sec->ps_lock);
252 static inline int ptlrpcs_cred_is_dead(struct ptlrpc_cred *cred)
254 return(cred->pc_flags & PTLRPC_CRED_DEAD);
257 static inline int ptlrpcs_est_req_payload(struct ptlrpc_sec *sec,
260 struct ptlrpc_secops *ops;
263 LASSERT(sec->ps_type);
264 LASSERT(sec->ps_type->pst_ops);
266 ops = sec->ps_type->pst_ops;
267 if (ops->est_req_payload)
268 return ops->est_req_payload(sec, datasize);
273 static inline int ptlrpcs_est_rep_payload(struct ptlrpc_sec *sec,
276 struct ptlrpc_secops *ops;
279 LASSERT(sec->ps_type);
280 LASSERT(sec->ps_type->pst_ops);
282 ops = sec->ps_type->pst_ops;
283 if (ops->est_rep_payload)
284 return ops->est_rep_payload(sec, datasize);
289 int ptlrpcs_cli_wrap_request(struct ptlrpc_request *req);
290 int ptlrpcs_cli_unwrap_reply(struct ptlrpc_request *req);
291 int ptlrpcs_cli_alloc_reqbuf(struct ptlrpc_request *req, int msgsize);
292 int ptlrpcs_cli_alloc_repbuf(struct ptlrpc_request *req, int msgsize);
293 void ptlrpcs_cli_free_reqbuf(struct ptlrpc_request *req);
294 void ptlrpcs_cli_free_repbuf(struct ptlrpc_request *req);
296 /* higher interface */
297 int ptlrpcs_import_get_sec(struct obd_import *imp);
298 void ptlrpcs_import_drop_sec(struct obd_import *imp);
299 int ptlrpcs_req_get_cred(struct ptlrpc_request *req);
300 void ptlrpcs_req_drop_cred(struct ptlrpc_request *req);
301 int ptlrpcs_req_replace_dead_cred(struct ptlrpc_request *req);
302 int ptlrpcs_req_refresh_cred(struct ptlrpc_request *req);
304 /* internal helpers */
305 int sec_alloc_reqbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req,
306 int msgsize, int secsize);
307 void sec_free_reqbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req);
310 int ptlrpcs_null_init(void);
311 int ptlrpcs_null_exit(void);
313 /**********************************************************
315 **********************************************************/
317 struct ptlrpc_reply_state;
319 struct ptlrpc_svcsec {
320 struct module *pss_owner;
322 ptlrpcs_flavor_t pss_flavor;
325 int (*accept) (struct ptlrpc_request *req,
326 enum ptlrpcs_error *res);
327 int (*authorize) (struct ptlrpc_request *req);
328 int (*alloc_repbuf)(struct ptlrpc_svcsec *svcsec,
329 struct ptlrpc_request *req,
331 void (*free_repbuf) (struct ptlrpc_svcsec *svcsec,
332 struct ptlrpc_reply_state *rs);
333 void (*cleanup_req) (struct ptlrpc_svcsec *svcsec,
334 struct ptlrpc_request *req);
338 #define SVC_COMPLETE 2
343 int svcsec_register(struct ptlrpc_svcsec *ss);
344 int svcsec_unregister(struct ptlrpc_svcsec *ss);
345 int svcsec_accept(struct ptlrpc_request *req, enum ptlrpcs_error *res);
346 int svcsec_authorize(struct ptlrpc_request *req);
347 int svcsec_alloc_repbuf(struct ptlrpc_svcsec *svcsec,
348 struct ptlrpc_request *req, int msgsize);
349 void svcsec_cleanup_req(struct ptlrpc_request *req);
351 struct ptlrpc_svcsec * svcsec_get(struct ptlrpc_svcsec *sec);
352 void svcsec_put(struct ptlrpc_svcsec *sec);
354 /* internal helpers */
355 int svcsec_alloc_reply_state(struct ptlrpc_request *req,
356 int msgsize, int secsize);
357 void svcsec_free_reply_state(struct ptlrpc_reply_state *rs);
360 int svcsec_null_init(void);
361 int svcsec_null_exit(void);
363 #endif /* __LINUX_SEC_H_ */