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 (*refresh)(struct ptlrpc_cred *cred);
124 int (*match) (struct ptlrpc_cred *cred,
125 struct ptlrpc_request *req,
126 struct vfs_cred *vcred);
127 int (*sign) (struct ptlrpc_cred *cred, struct ptlrpc_request *req);
128 int (*verify) (struct ptlrpc_cred *cred, struct ptlrpc_request *req);
129 int (*seal) (struct ptlrpc_cred *cred, struct ptlrpc_request *req);
130 int (*unseal) (struct ptlrpc_cred *cred, struct ptlrpc_request *req);
131 void (*destroy)(struct ptlrpc_cred *cred);
134 #define PTLRPC_CRED_UPTODATE 0x00000001
135 #define PTLRPC_CRED_DEAD 0x00000002
138 struct list_head pc_hash; /* linked into hash table */
139 atomic_t pc_refcount;
140 struct ptlrpc_sec *pc_sec;
141 struct ptlrpc_credops *pc_ops;
142 struct ptlrpc_request *pc_req;
143 unsigned long pc_expire;
145 /* XXX maybe should not be here */
150 struct ptlrpc_secops {
151 struct ptlrpc_sec * (*create_sec) (ptlrpcs_flavor_t *flavor,
152 const char *pipe_dir,
154 void (*destroy_sec) (struct ptlrpc_sec *sec);
155 struct ptlrpc_cred * (*create_cred) (struct ptlrpc_sec *sec,
156 struct ptlrpc_request *req,
157 struct vfs_cred *vcred);
158 /* buffer manipulation */
159 int (*alloc_reqbuf) (struct ptlrpc_sec *sec,
160 struct ptlrpc_request *req,
161 int lustre_msg_size);
162 int (*alloc_repbuf) (struct ptlrpc_sec *sec,
163 struct ptlrpc_request *req,
164 int lustre_msg_size);
165 void (*free_reqbuf) (struct ptlrpc_sec *sec,
166 struct ptlrpc_request *req);
167 void (*free_repbuf) (struct ptlrpc_sec *sec,
168 struct ptlrpc_request *req);
169 /* security payload size estimation */
170 int (*est_req_payload)(struct ptlrpc_sec *sec,
172 int (*est_rep_payload)(struct ptlrpc_sec *sec,
176 struct ptlrpc_sec_type {
177 struct module *pst_owner;
179 atomic_t pst_inst; /* instance, debug only */
180 ptlrpcs_flavor_t pst_flavor;
181 struct ptlrpc_secops *pst_ops;
184 #define PTLRPC_CREDCACHE_NR 8
185 #define PTLRPC_CREDCACHE_MASK (PTLRPC_CREDCACHE_NR - 1)
188 struct ptlrpc_sec_type *ps_type;
189 struct list_head ps_credcache[PTLRPC_CREDCACHE_NR];
190 spinlock_t ps_lock; /* protect cred cache */
192 ptlrpcs_flavor_t ps_flavor;
193 atomic_t ps_refcount;
194 atomic_t ps_credcount;
195 struct obd_import *ps_import;
196 /* actual security model need initialize following fields */
197 unsigned long ps_expire; /* cache expire interval */
198 unsigned long ps_nextgc; /* next gc time */
199 unsigned int ps_flags;
203 int ptlrpcs_register(struct ptlrpc_sec_type *type);
204 int ptlrpcs_unregister(struct ptlrpc_sec_type *type);
206 struct ptlrpc_sec * ptlrpcs_sec_create(ptlrpcs_flavor_t *flavor,
207 struct obd_import *import,
208 const char *pipe_dir,
210 void ptlrpcs_sec_put(struct ptlrpc_sec *sec);
211 void ptlrpcs_sec_invalidate_cache(struct ptlrpc_sec *sec);
213 struct ptlrpc_cred * ptlrpcs_cred_lookup(struct ptlrpc_sec *sec,
214 struct vfs_cred *vcred);
215 void ptlrpcs_cred_put(struct ptlrpc_cred *cred, int sync);
217 static inline void ptlrpcs_cred_get(struct ptlrpc_cred *cred)
219 LASSERT(atomic_read(&cred->pc_refcount));
220 atomic_inc(&cred->pc_refcount);
223 static inline int ptlrpcs_cred_is_uptodate(struct ptlrpc_cred *cred)
226 LASSERT(atomic_read(&cred->pc_refcount));
227 return (cred->pc_flags & PTLRPC_CRED_UPTODATE);
229 static inline int ptlrpcs_cred_refresh(struct ptlrpc_cred *cred)
232 LASSERT(atomic_read(&cred->pc_refcount));
233 LASSERT(cred->pc_ops);
234 LASSERT(cred->pc_ops->refresh);
235 return cred->pc_ops->refresh(cred);
237 static inline void ptlrpcs_cred_die(struct ptlrpc_cred *cred)
239 LASSERT(atomic_read(&cred->pc_refcount));
240 LASSERT(cred->pc_sec);
241 if (!(cred->pc_flags & PTLRPC_CRED_DEAD)) {
242 spin_lock(&cred->pc_sec->ps_lock);
243 cred->pc_flags |= PTLRPC_CRED_DEAD;
244 cred->pc_flags &= ~PTLRPC_CRED_UPTODATE;
245 list_del_init(&cred->pc_hash);
246 spin_unlock(&cred->pc_sec->ps_lock);
249 static inline int ptlrpcs_cred_is_dead(struct ptlrpc_cred *cred)
251 return(cred->pc_flags & PTLRPC_CRED_DEAD);
254 static inline int ptlrpcs_est_req_payload(struct ptlrpc_sec *sec,
257 struct ptlrpc_secops *ops;
260 LASSERT(sec->ps_type);
261 LASSERT(sec->ps_type->pst_ops);
263 ops = sec->ps_type->pst_ops;
264 if (ops->est_req_payload)
265 return ops->est_req_payload(sec, datasize);
270 static inline int ptlrpcs_est_rep_payload(struct ptlrpc_sec *sec,
273 struct ptlrpc_secops *ops;
276 LASSERT(sec->ps_type);
277 LASSERT(sec->ps_type->pst_ops);
279 ops = sec->ps_type->pst_ops;
280 if (ops->est_rep_payload)
281 return ops->est_rep_payload(sec, datasize);
286 int ptlrpcs_cli_wrap_request(struct ptlrpc_request *req);
287 int ptlrpcs_cli_unwrap_reply(struct ptlrpc_request *req);
288 int ptlrpcs_cli_alloc_reqbuf(struct ptlrpc_request *req, int msgsize);
289 int ptlrpcs_cli_alloc_repbuf(struct ptlrpc_request *req, int msgsize);
290 void ptlrpcs_cli_free_reqbuf(struct ptlrpc_request *req);
291 void ptlrpcs_cli_free_repbuf(struct ptlrpc_request *req);
293 /* higher interface */
294 int ptlrpcs_import_get_sec(struct obd_import *imp);
295 void ptlrpcs_import_drop_sec(struct obd_import *imp);
296 int ptlrpcs_req_get_cred(struct ptlrpc_request *req);
297 void ptlrpcs_req_drop_cred(struct ptlrpc_request *req);
298 int ptlrpcs_req_replace_dead_cred(struct ptlrpc_request *req);
299 int ptlrpcs_req_refresh_cred(struct ptlrpc_request *req);
301 /* internal helpers */
302 int sec_alloc_reqbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req,
303 int msgsize, int secsize);
304 void sec_free_reqbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req);
307 int ptlrpcs_null_init(void);
308 int ptlrpcs_null_exit(void);
310 /**********************************************************
312 **********************************************************/
314 struct ptlrpc_reply_state;
316 struct ptlrpc_svcsec {
317 struct module *pss_owner;
319 ptlrpcs_flavor_t pss_flavor;
322 int (*accept) (struct ptlrpc_request *req,
323 enum ptlrpcs_error *res);
324 int (*authorize) (struct ptlrpc_request *req);
325 int (*alloc_repbuf)(struct ptlrpc_svcsec *svcsec,
326 struct ptlrpc_request *req,
328 void (*free_repbuf) (struct ptlrpc_svcsec *svcsec,
329 struct ptlrpc_reply_state *rs);
330 void (*cleanup_req) (struct ptlrpc_svcsec *svcsec,
331 struct ptlrpc_request *req);
335 #define SVC_COMPLETE 2
340 int svcsec_register(struct ptlrpc_svcsec *ss);
341 int svcsec_unregister(struct ptlrpc_svcsec *ss);
342 int svcsec_accept(struct ptlrpc_request *req, enum ptlrpcs_error *res);
343 int svcsec_authorize(struct ptlrpc_request *req);
344 int svcsec_alloc_repbuf(struct ptlrpc_svcsec *svcsec,
345 struct ptlrpc_request *req, int msgsize);
346 void svcsec_cleanup_req(struct ptlrpc_request *req);
348 struct ptlrpc_svcsec * svcsec_get(struct ptlrpc_svcsec *sec);
349 void svcsec_put(struct ptlrpc_svcsec *sec);
351 /* internal helpers */
352 int svcsec_alloc_reply_state(struct ptlrpc_request *req,
353 int msgsize, int secsize);
354 void svcsec_free_reply_state(struct ptlrpc_reply_state *rs);
357 int svcsec_null_init(void);
358 int svcsec_null_exit(void);
360 #endif /* __LINUX_SEC_H_ */