Whamcloud - gitweb
- make HEAD from b_post_cmd3
[fs/lustre-release.git] / lustre / ptlrpc / gss / gss_internal.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Modified from NFSv4 project for Lustre
5  * Copyright 2004 - 2006, Cluster File Systems, Inc.
6  * All rights reserved
7  * Author: Eric Mei <ericm@clusterfs.com>
8  */
9
10 #ifndef __PTLRPC_GSS_GSS_INTERNAL_H_
11 #define __PTLRPC_GSS_GSS_INTERNAL_H_
12
13 #include <lustre_sec.h>
14
15 /*
16  * rawobj stuff
17  */
18 typedef struct netobj_s {
19         __u32           len;
20         __u8            data[0];
21 } netobj_t;
22
23 #define NETOBJ_EMPTY    ((netobj_t) { 0 })
24
25 typedef struct rawobj_s {
26         __u32           len;
27         __u8           *data;
28 } rawobj_t;
29
30 #define RAWOBJ_EMPTY    ((rawobj_t) { 0, NULL })
31
32 typedef struct rawobj_buf_s {
33         __u32           dataoff;
34         __u32           datalen;
35         __u32           buflen;
36         __u8           *buf;
37 } rawobj_buf_t;
38
39 int rawobj_alloc(rawobj_t *obj, char *buf, int len);
40 void rawobj_free(rawobj_t *obj);
41 int rawobj_equal(rawobj_t *a, rawobj_t *b);
42 int rawobj_dup(rawobj_t *dest, rawobj_t *src);
43 int rawobj_serialize(rawobj_t *obj, __u32 **buf, __u32 *buflen);
44 int rawobj_extract(rawobj_t *obj, __u32 **buf, __u32 *buflen);
45 int rawobj_extract_alloc(rawobj_t *obj, __u32 **buf, __u32 *buflen);
46 int rawobj_extract_local(rawobj_t *obj, __u32 **buf, __u32 *buflen);
47 int rawobj_from_netobj(rawobj_t *rawobj, netobj_t *netobj);
48 int rawobj_from_netobj_alloc(rawobj_t *obj, netobj_t *netobj);
49
50
51 /*
52  * several timeout values. client refresh upcall timeout we using
53  * default in pipefs implemnetation.
54  */
55 #define __TIMEOUT_DELTA                 (10)
56
57 #define GSS_SECINIT_RPC_TIMEOUT                                         \
58         (obd_timeout < __TIMEOUT_DELTA ?                                \
59          __TIMEOUT_DELTA : obd_timeout - __TIMEOUT_DELTA)
60
61 #define GSS_SECFINI_RPC_TIMEOUT         (__TIMEOUT_DELTA)
62 #define GSS_SECSVC_UPCALL_TIMEOUT       (GSS_SECINIT_RPC_TIMEOUT)
63
64 static inline
65 unsigned long gss_round_ctx_expiry(unsigned long expiry,
66                                    unsigned long sec_flags)
67 {
68         if (sec_flags & PTLRPC_SEC_FL_REVERSE)
69                 return expiry;
70
71         if (get_seconds() + __TIMEOUT_DELTA <= expiry)
72                 return expiry - __TIMEOUT_DELTA;
73
74         return expiry;
75 }
76
77 /* we try to force reconnect import 20m eariler than real expiry.
78  * kerberos 5 usually allow 5m time skew, but which is adjustable,
79  * so if we set krb5 to allow > 20m time skew, we have chance that
80  * server's reverse ctx expired but client still hasn't start to
81  * refresh it -- it's BAD. So here we actually put a limit on the
82  * enviroment of krb5 (or other authentication mechanism)
83  */
84 #define GSS_MAX_TIME_SKEW       (20 * 60)
85
86 static inline
87 unsigned long gss_round_imp_reconnect(unsigned long expiry)
88 {
89         unsigned long now = get_seconds();
90         unsigned long nice = GSS_MAX_TIME_SKEW + __TIMEOUT_DELTA;
91
92         while (nice && (now + nice >= expiry))
93                 nice = nice / 2;
94
95         return (expiry - nice);
96 }
97
98 /*
99  * Max encryption element in block cipher algorithms.
100  */
101 #define GSS_MAX_CIPHER_BLOCK               (16)
102
103 /*
104  * XXX make it visible of kernel and lgssd/lsvcgssd
105  */
106 #define GSSD_INTERFACE_VERSION          (1)
107
108 #define PTLRPC_GSS_VERSION              (1)
109
110
111 enum ptlrpc_gss_proc {
112         PTLRPC_GSS_PROC_DATA            = 0,
113         PTLRPC_GSS_PROC_INIT            = 1,
114         PTLRPC_GSS_PROC_CONTINUE_INIT   = 2,
115         PTLRPC_GSS_PROC_DESTROY         = 3,
116         PTLRPC_GSS_PROC_ERR             = 4,
117 };
118
119 enum ptlrpc_gss_svc {
120         PTLRPC_GSS_SVC_NONE             = 1,
121         PTLRPC_GSS_SVC_INTEGRITY        = 2,
122         PTLRPC_GSS_SVC_PRIVACY          = 3,
123 };
124
125 enum ptlrpc_gss_tgt {
126         LUSTRE_GSS_TGT_MDS              = 0,
127         LUSTRE_GSS_TGT_OSS              = 1,
128 };
129
130 /*
131  * following 3 header must have the same size and offset
132  */
133 struct gss_header {
134         __u32                   gh_version;     /* gss version */
135         __u32                   gh_flags;       /* wrap flags */
136         __u32                   gh_proc;        /* proc */
137         __u32                   gh_seq;         /* sequence */
138         __u32                   gh_svc;         /* service */
139         __u32                   gh_pad1;
140         __u32                   gh_pad2;
141         __u32                   gh_pad3;
142         netobj_t                gh_handle;      /* context handle */
143 };
144
145 struct gss_rep_header {
146         __u32                   gh_version;
147         __u32                   gh_flags;
148         __u32                   gh_proc;
149         __u32                   gh_major;
150         __u32                   gh_minor;
151         __u32                   gh_seqwin;
152         __u32                   gh_pad2;
153         __u32                   gh_pad3;
154         netobj_t                gh_handle;
155 };
156
157 struct gss_err_header {
158         __u32                   gh_version;
159         __u32                   gh_flags;
160         __u32                   gh_proc;
161         __u32                   gh_major;
162         __u32                   gh_minor;
163         __u32                   gh_pad1;
164         __u32                   gh_pad2;
165         __u32                   gh_pad3;
166         netobj_t                gh_handle;
167 };
168
169 /*
170  * part of wire context information send from client which be saved and
171  * used later by server.
172  */
173 struct gss_wire_ctx {
174         __u32                   gw_proc;
175         __u32                   gw_seq;
176         __u32                   gw_svc;
177         rawobj_t                gw_handle;
178 };
179
180 #define PTLRPC_GSS_MAX_HANDLE_SIZE      (8)
181 #define PTLRPC_GSS_HEADER_SIZE          (sizeof(struct gss_header) + \
182                                          PTLRPC_GSS_MAX_HANDLE_SIZE)
183
184
185 #define GSS_SEQ_WIN                     (256)
186 #define GSS_SEQ_WIN_MAIN                GSS_SEQ_WIN
187 #define GSS_SEQ_WIN_BACK                (64)
188 #define GSS_SEQ_REPACK_THRESHOLD        (GSS_SEQ_WIN_MAIN / 2)
189
190 struct gss_svc_seq_data {
191         spinlock_t              ssd_lock;
192         /*
193          * highest sequence number seen so far, for main and back window
194          */
195         __u32                   ssd_max_main;
196         __u32                   ssd_max_back;
197         /*
198          * main and back window
199          * for i such that ssd_max - GSS_SEQ_WIN < i <= ssd_max, the i-th bit
200          * of ssd_win is nonzero iff sequence number i has been seen already.
201          */
202         unsigned long           ssd_win_main[GSS_SEQ_WIN_MAIN/BITS_PER_LONG];
203         unsigned long           ssd_win_back[GSS_SEQ_WIN_BACK/BITS_PER_LONG];
204 };
205
206 struct gss_svc_ctx {
207         unsigned int            gsc_usr_root:1,
208                                 gsc_usr_mds:1,
209                                 gsc_remote:1;
210         uid_t                   gsc_uid;
211         gid_t                   gsc_gid;
212         uid_t                   gsc_mapped_uid;
213         rawobj_t                gsc_rvs_hdl;
214         struct gss_svc_seq_data gsc_seqdata;
215         struct gss_ctx         *gsc_mechctx;
216 };
217
218 struct gss_svc_reqctx {
219         struct ptlrpc_svc_ctx   src_base;
220         struct gss_wire_ctx     src_wirectx;
221         struct gss_svc_ctx     *src_ctx;
222         unsigned int            src_init:1,
223                                 src_init_continue:1,
224                                 src_err_notify:1;
225         int                     src_reserve_len;
226 };
227
228 struct gss_cli_ctx {
229         struct ptlrpc_cli_ctx   gc_base;
230         __u32                   gc_flavor;
231         __u32                   gc_proc;
232         __u32                   gc_win;
233         atomic_t                gc_seq;
234         rawobj_t                gc_handle;
235         struct gss_ctx         *gc_mechctx;
236 };
237
238 struct gss_sec {
239         struct ptlrpc_sec       gs_base;
240         struct gss_api_mech    *gs_mech;
241         spinlock_t              gs_lock;
242         __u64                   gs_rvs_hdl;
243 };
244
245 #define GSS_CTX_INIT_MAX_LEN            (1024)
246
247 /*
248  * This only guaranteed be enough for current krb5 des-cbc-crc . We might
249  * adjust this when new enc type or mech added in.
250  */
251 #define GSS_PRIVBUF_PREFIX_LEN         (32)
252 #define GSS_PRIVBUF_SUFFIX_LEN         (32)
253
254 static inline
255 struct gss_svc_reqctx *gss_svc_ctx2reqctx(struct ptlrpc_svc_ctx *ctx)
256 {
257         LASSERT(ctx);
258         return container_of(ctx, struct gss_svc_reqctx, src_base);
259 }
260
261 /* sec_gss.c */
262 struct gss_header *gss_swab_header(struct lustre_msg *msg, int segment);
263 netobj_t *gss_swab_netobj(struct lustre_msg *msg, int segment);
264
265 void gss_cli_ctx_uptodate(struct gss_cli_ctx *gctx);
266 int gss_pack_err_notify(struct ptlrpc_request *req, __u32 major, __u32 minor);
267 int gss_check_seq_num(struct gss_svc_seq_data *sd, __u32 seq_num, int set);
268
269 /* gss_bulk.c */
270 int gss_cli_ctx_wrap_bulk(struct ptlrpc_cli_ctx *ctx,
271                           struct ptlrpc_request *req,
272                           struct ptlrpc_bulk_desc *desc);
273 int gss_cli_ctx_unwrap_bulk(struct ptlrpc_cli_ctx *ctx,
274                             struct ptlrpc_request *req,
275                             struct ptlrpc_bulk_desc *desc);
276 int gss_svc_unwrap_bulk(struct ptlrpc_request *req,
277                         struct ptlrpc_bulk_desc *desc);
278 int gss_svc_wrap_bulk(struct ptlrpc_request *req,
279                       struct ptlrpc_bulk_desc *desc);
280
281 /* gss_mech_switch.c */
282 int init_kerberos_module(void);
283 void cleanup_kerberos_module(void);
284
285 /* gss_generic_token.c */
286 int g_token_size(rawobj_t *mech, unsigned int body_size);
287 void g_make_token_header(rawobj_t *mech, int body_size, unsigned char **buf);
288 __u32 g_verify_token_header(rawobj_t *mech, int *body_size,
289                             unsigned char **buf_in, int toksize);
290
291
292 /* gss_upcall.c */
293 int gss_do_ctx_init_rpc(char *buffer, unsigned long count);
294 int gss_do_ctx_fini_rpc(struct gss_cli_ctx *gctx);
295 int gss_ctx_refresh_pipefs(struct ptlrpc_cli_ctx *ctx);
296 int gss_sec_upcall_init(struct gss_sec *gsec);
297 void gss_sec_upcall_cleanup(struct gss_sec *gsec);
298 int __init gss_init_upcall(void);
299 void __exit gss_exit_upcall(void);
300
301 /* gss_svc_upcall.c */
302 __u64 gss_get_next_ctx_index(void);
303 int gss_svc_upcall_install_rvs_ctx(struct obd_import *imp,
304                                    struct gss_sec *gsec,
305                                    struct gss_cli_ctx *gctx);
306 int gss_svc_upcall_handle_init(struct ptlrpc_request *req,
307                                struct gss_svc_reqctx *grctx,
308                                struct gss_wire_ctx *gw,
309                                struct obd_device *target,
310                                __u32 lustre_svc,
311                                rawobj_t *rvs_hdl,
312                                rawobj_t *in_token);
313 struct gss_svc_ctx *gss_svc_upcall_get_ctx(struct ptlrpc_request *req,
314                                            struct gss_wire_ctx *gw);
315 void gss_svc_upcall_put_ctx(struct gss_svc_ctx *ctx);
316 void gss_svc_upcall_destroy_ctx(struct gss_svc_ctx *ctx);
317
318 int  __init gss_svc_init_upcall(void);
319 void __exit gss_svc_exit_upcall(void);
320
321 /* lproc_gss.c */
322 void gss_stat_oos_record_cli(int behind);
323 void gss_stat_oos_record_svc(int phase, int replay);
324 int  gss_init_lproc(void);
325 void gss_exit_lproc(void);
326
327 /* gss_krb5_mech.c */
328 int __init init_kerberos_module(void);
329 void __exit cleanup_kerberos_module(void);
330
331
332 /* debug */
333 static inline
334 void __dbg_memdump(char *name, void *ptr, int size)
335 {
336         char *buf, *p = (char *) ptr;
337         int bufsize = size * 2 + 1, i;
338
339         OBD_ALLOC(buf, bufsize);
340         if (!buf) {
341                 printk("DUMP ERROR: can't alloc %d bytes\n", bufsize);
342                 return;
343         }
344
345         for (i = 0; i < size; i++)
346                 sprintf(&buf[i+i], "%02x", (__u8) p[i]);
347         buf[size + size] = '\0';
348         printk("DUMP %s@%p(%d): %s\n", name, ptr, size, buf);
349         OBD_FREE(buf, bufsize);
350 }
351
352 #endif /* __PTLRPC_GSS_GSS_INTERNAL_H_ */