Whamcloud - gitweb
94028b448d2d7fea4ab7a095ede209d4ee459f54
[fs/lustre-release.git] / lustre / include / linux / lustre_sec.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Copyright (C) 2004 Cluster File Systems, Inc.
5  *
6  *   This file is part of Lustre, http://www.lustre.org.
7  *
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.
11  *
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.
16  *
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.
20  */
21
22 #ifndef __LINUX_SEC_H_
23 #define __LINUX_SEC_H_
24
25 /* forward declaration */
26 struct obd_import;
27 struct ptlrpc_request;
28 struct ptlrpc_cred;
29 struct ptlrpc_credops;
30 struct ptlrpc_sec;
31 struct ptlrpc_secops;
32
33 #define PTLRPC_SEC_MAX_FLAVORS   (4)
34
35 typedef struct ptlrpcs_flavor_s {
36         __u32   flavor;
37         __u32   subflavor;
38 } ptlrpcs_flavor_t;
39
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 */
44 };
45
46 /*
47  * This header is prepended at any on-wire ptlrpc packets
48  */
49 struct ptlrpcs_wire_hdr {
50         __u32   flavor;
51         __u32   sectype;
52         __u32   msg_len;
53         __u32   sec_len;
54 };
55
56 static inline
57 struct ptlrpcs_wire_hdr *buf_to_sec_hdr(void *buf)
58 {
59         return (struct ptlrpcs_wire_hdr *) buf;
60 }
61
62 static inline
63 struct lustre_msg *buf_to_lustre_msg(void *buf)
64 {
65         return (struct lustre_msg *)
66                ((char *) buf + sizeof(struct ptlrpcs_wire_hdr));
67 }
68
69 static inline
70 __u8 *buf_to_sec_data(void *buf)
71 {
72         struct ptlrpcs_wire_hdr *hdr = buf_to_sec_hdr(buf);
73         return (__u8 *) (buf + sizeof(*hdr) + hdr->msg_len);
74 }
75
76 enum ptlrpcs_flavors {
77         PTLRPC_SEC_NULL = 0,
78         PTLRPC_SEC_GSS  = 1,
79 };
80
81 #define PTLRPC_SEC_GSS_VERSION (1)
82
83 enum ptlrpcs_gss_subflavors {
84         PTLRPC_SEC_GSS_KRB5  = 0,
85         PTLRPC_SEC_GSS_KRB5I = 1,
86         PTLRPC_SEC_GSS_KRB5P = 2,
87 };
88
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,
95 };
96                                                                                                                         
97 enum ptlrpcs_gss_svc {
98         PTLRPC_GSS_SVC_NONE =           1,
99         PTLRPC_GSS_SVC_INTEGRITY =      2,
100         PTLRPC_GSS_SVC_PRIVACY =        3,
101 };
102
103 enum ptlrpcs_error {
104         PTLRPCS_OK =                    0,
105         PTLRPCS_BADCRED =               1,
106         PTLRPCS_REJECTEDCRED =          2,
107         PTLRPCS_BADVERF =               3,
108         PTLRPCS_REJECTEDVERF =          4,
109         PTLRPCS_TOOWEAK =               5,
110         /* GSS errors */
111         PTLRPCS_GSS_CREDPROBLEM =       13,
112         PTLRPCS_GSS_CTXPROBLEM =        14,
113 };
114
115 struct vfs_cred {
116         __u64   vc_pag;
117         uid_t   vc_uid;
118         gid_t   vc_gid;
119         struct group_info *vc_ginfo;
120 };
121
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);
134 };
135
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
140
141 struct ptlrpc_cred {
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;
147         int                     pc_flags;
148         /* XXX maybe should not be here */
149         __u64                   pc_pag;
150         uid_t                   pc_uid;
151 };
152
153 struct ptlrpc_secops {
154         struct ptlrpc_sec *   (*create_sec)    (ptlrpcs_flavor_t *flavor,
155                                                 const char *pipe_dir,
156                                                 void *pipe_data);
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,
173                                                  int msgsize);
174         int                   (*est_rep_payload)(struct ptlrpc_sec *sec,
175                                                  int msgsize);
176 };
177
178 struct ptlrpc_sec_type {
179         struct module          *pst_owner;
180         char                   *pst_name;
181         atomic_t                pst_inst;       /* instance, debug only */
182         ptlrpcs_flavor_t        pst_flavor;
183         struct ptlrpc_secops   *pst_ops;
184 };
185
186 #define PTLRPC_CREDCACHE_NR     8
187 #define PTLRPC_CREDCACHE_MASK   (PTLRPC_CREDCACHE_NR - 1)
188
189 struct ptlrpc_sec {
190         struct ptlrpc_sec_type *ps_type;
191         struct list_head        ps_credcache[PTLRPC_CREDCACHE_NR];
192         spinlock_t              ps_lock;        /* protect cred cache */
193         __u32                   ps_sectype;
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;
202 };
203
204 /* sec.c */
205 int  ptlrpcs_register(struct ptlrpc_sec_type *type);
206 int  ptlrpcs_unregister(struct ptlrpc_sec_type *type);
207
208 struct ptlrpc_sec * ptlrpcs_sec_create(ptlrpcs_flavor_t *flavor,
209                                        struct obd_import *import,
210                                        const char *pipe_dir,
211                                        void *pipe_data);
212 void ptlrpcs_sec_put(struct ptlrpc_sec *sec);
213 void ptlrpcs_sec_invalidate_cache(struct ptlrpc_sec *sec);
214
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);
218
219 static inline void ptlrpcs_cred_get(struct ptlrpc_cred *cred)
220 {
221         LASSERT(atomic_read(&cred->pc_refcount));
222         atomic_inc(&cred->pc_refcount);
223 }
224
225 static inline int ptlrpcs_cred_is_uptodate(struct ptlrpc_cred *cred)
226 {
227         LASSERT(cred);
228         LASSERT(atomic_read(&cred->pc_refcount));
229         return ((cred->pc_flags & PTLRPC_CRED_FLAGS_MASK) ==
230                 PTLRPC_CRED_UPTODATE);
231 }
232 static inline int ptlrpcs_cred_refresh(struct ptlrpc_cred *cred)
233 {
234         LASSERT(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);
239 }
240 static inline void ptlrpcs_cred_die(struct ptlrpc_cred *cred)
241 {
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);
250         }
251 }
252 static inline int ptlrpcs_cred_is_dead(struct ptlrpc_cred *cred)
253 {
254         return(cred->pc_flags & PTLRPC_CRED_DEAD);
255 }
256
257 static inline int ptlrpcs_est_req_payload(struct ptlrpc_sec *sec,
258                                           int datasize)
259 {
260         struct ptlrpc_secops *ops;
261
262         LASSERT(sec);
263         LASSERT(sec->ps_type);
264         LASSERT(sec->ps_type->pst_ops);
265
266         ops = sec->ps_type->pst_ops;
267         if (ops->est_req_payload)
268                 return ops->est_req_payload(sec, datasize);
269         else
270                 return 0;
271 }
272
273 static inline int ptlrpcs_est_rep_payload(struct ptlrpc_sec *sec,
274                                           int datasize)
275 {
276         struct ptlrpc_secops *ops;
277
278         LASSERT(sec);
279         LASSERT(sec->ps_type);
280         LASSERT(sec->ps_type->pst_ops);
281
282         ops = sec->ps_type->pst_ops;
283         if (ops->est_rep_payload)
284                 return ops->est_rep_payload(sec, datasize);
285         else
286                 return 0;
287 }
288
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);
295
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);
303
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);
308
309 /* sec_null.c */
310 int ptlrpcs_null_init(void);
311 int ptlrpcs_null_exit(void);
312
313 /**********************************************************
314  * Server side stuff
315  **********************************************************/
316
317 struct ptlrpc_reply_state;
318
319 struct ptlrpc_svcsec {
320         struct module           *pss_owner;
321         char                    *pss_name;
322         ptlrpcs_flavor_t         pss_flavor;
323         int                      pss_sec_size;
324
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,
330                                                int msgsize);
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);
335 };
336
337 #define SVC_OK          1
338 #define SVC_COMPLETE    2
339 #define SVC_DROP        3
340 #define SVC_LOGIN       4
341 #define SVC_LOGOUT      5
342
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);
350
351 struct ptlrpc_svcsec * svcsec_get(struct ptlrpc_svcsec *sec);
352 void svcsec_put(struct ptlrpc_svcsec *sec);
353
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);
358
359 /* svcsec_null.c */
360 int svcsec_null_init(void);
361 int svcsec_null_exit(void);
362
363 #endif /* __LINUX_SEC_H_ */