Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/rpc/rpcsec_gss.h
39536 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2008 Doug Rabson
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*/
28
29
#ifndef _RPCSEC_GSS_H
30
#define _RPCSEC_GSS_H
31
32
#include <kgssapi/gssapi.h>
33
34
#ifndef MAX_GSS_MECH
35
#define MAX_GSS_MECH 64
36
#endif
37
38
/*
39
* Define the types of security service required for rpc_gss_seccreate().
40
*/
41
typedef enum {
42
rpc_gss_svc_default = 0,
43
rpc_gss_svc_none = 1,
44
rpc_gss_svc_integrity = 2,
45
rpc_gss_svc_privacy = 3
46
} rpc_gss_service_t;
47
48
/*
49
* Structure containing options for rpc_gss_seccreate().
50
*/
51
typedef struct {
52
int req_flags; /* GSS request bits */
53
int time_req; /* requested credential lifetime */
54
gss_cred_id_t my_cred; /* GSS credential */
55
gss_channel_bindings_t input_channel_bindings;
56
} rpc_gss_options_req_t;
57
58
/*
59
* Structure containing options returned by rpc_gss_seccreate().
60
*/
61
typedef struct {
62
int major_status;
63
int minor_status;
64
u_int rpcsec_version;
65
int ret_flags;
66
int time_req;
67
gss_ctx_id_t gss_context;
68
char actual_mechanism[MAX_GSS_MECH];
69
} rpc_gss_options_ret_t;
70
71
/*
72
* Client principal type. Used as an argument to
73
* rpc_gss_get_principal_name(). Also referenced by the
74
* rpc_gss_rawcred_t structure.
75
*/
76
typedef struct {
77
int len;
78
char name[1];
79
} *rpc_gss_principal_t;
80
81
/*
82
* Structure for raw credentials used by rpc_gss_getcred() and
83
* rpc_gss_set_callback().
84
*/
85
typedef struct {
86
u_int version; /* RPC version number */
87
const char *mechanism; /* security mechanism */
88
const char *qop; /* quality of protection */
89
rpc_gss_principal_t client_principal; /* client name */
90
const char *svc_principal; /* server name */
91
rpc_gss_service_t service; /* service type */
92
} rpc_gss_rawcred_t;
93
94
/*
95
* Unix credentials derived from raw credentials. Returned by
96
* rpc_gss_getcred().
97
*/
98
typedef struct {
99
uid_t uid; /* user ID */
100
gid_t gid; /* group ID */
101
short gidlen;
102
gid_t *gidlist; /* list of groups */
103
} rpc_gss_ucred_t;
104
105
/*
106
* Structure used to enforce a particular QOP and service.
107
*/
108
typedef struct {
109
bool_t locked;
110
rpc_gss_rawcred_t *raw_cred;
111
} rpc_gss_lock_t;
112
113
/*
114
* Callback structure used by rpc_gss_set_callback().
115
*/
116
typedef struct {
117
u_int program; /* RPC program number */
118
u_int version; /* RPC version number */
119
/* user defined callback */
120
bool_t (*callback)(struct svc_req *req,
121
gss_cred_id_t deleg,
122
gss_ctx_id_t gss_context,
123
rpc_gss_lock_t *lock,
124
void **cookie);
125
} rpc_gss_callback_t;
126
127
/*
128
* Structure used to return error information by rpc_gss_get_error()
129
*/
130
typedef struct {
131
int rpc_gss_error;
132
int system_error; /* same as errno */
133
} rpc_gss_error_t;
134
135
/*
136
* Values for rpc_gss_error
137
*/
138
#define RPC_GSS_ER_SUCCESS 0 /* no error */
139
#define RPC_GSS_ER_SYSTEMERROR 1 /* system error */
140
141
__BEGIN_DECLS
142
143
#ifdef _KERNEL
144
/*
145
* Set up a structure of entry points for the kgssapi module and inline
146
* functions named rpc_gss_XXX_call() to use them, so that the kgssapi
147
* module doesn't need to be loaded for the NFS modules to work using
148
* AUTH_SYS. The kgssapi modules will be loaded by the gssd(8) daemon
149
* when it is started up and the entry points will then be filled in.
150
*/
151
typedef AUTH *rpc_gss_secfind_ftype(CLIENT *clnt, struct ucred *cred,
152
const char *principal, gss_OID mech_oid,
153
rpc_gss_service_t service);
154
typedef void rpc_gss_secpurge_ftype(CLIENT *clnt);
155
typedef AUTH *rpc_gss_seccreate_ftype(CLIENT *clnt, struct ucred *cred,
156
const char *clnt_principal, const char *principal,
157
const char *mechanism, rpc_gss_service_t service,
158
const char *qop, rpc_gss_options_req_t *options_req,
159
rpc_gss_options_ret_t *options_ret);
160
typedef bool_t rpc_gss_set_defaults_ftype(AUTH *auth,
161
rpc_gss_service_t service, const char *qop);
162
typedef int rpc_gss_max_data_length_ftype(AUTH *handle,
163
int max_tp_unit_len);
164
typedef void rpc_gss_get_error_ftype(rpc_gss_error_t *error);
165
typedef bool_t rpc_gss_mech_to_oid_ftype(const char *mech, gss_OID *oid_ret);
166
typedef bool_t rpc_gss_oid_to_mech_ftype(gss_OID oid, const char **mech_ret);
167
typedef bool_t rpc_gss_qop_to_num_ftype(const char *qop, const char *mech,
168
u_int *num_ret);
169
typedef const char **rpc_gss_get_mechanisms_ftype(void);
170
typedef bool_t rpc_gss_get_versions_ftype(u_int *vers_hi, u_int *vers_lo);
171
typedef bool_t rpc_gss_is_installed_ftype(const char *mech);
172
typedef bool_t rpc_gss_set_svc_name_ftype(const char *principal,
173
const char *mechanism, u_int req_time, u_int program,
174
u_int version);
175
typedef void rpc_gss_clear_svc_name_ftype(u_int program, u_int version);
176
typedef bool_t rpc_gss_getcred_ftype(struct svc_req *req,
177
rpc_gss_rawcred_t **rcred,
178
rpc_gss_ucred_t **ucred, void **cookie);
179
typedef bool_t rpc_gss_set_callback_ftype(rpc_gss_callback_t *cb);
180
typedef void rpc_gss_clear_callback_ftype(rpc_gss_callback_t *cb);
181
typedef bool_t rpc_gss_get_principal_name_ftype(rpc_gss_principal_t *principal,
182
const char *mech, const char *name, const char *node,
183
const char *domain);
184
typedef int rpc_gss_svc_max_data_length_ftype(struct svc_req *req,
185
int max_tp_unit_len);
186
typedef void rpc_gss_refresh_auth_ftype(AUTH *auth);
187
typedef bool_t rpc_gss_ip_to_srv_principal_ftype(char *ip_addr,
188
const char *srv_name, char *dns_name);
189
190
struct rpc_gss_entries {
191
rpc_gss_secfind_ftype *rpc_gss_secfind;
192
rpc_gss_secpurge_ftype *rpc_gss_secpurge;
193
rpc_gss_seccreate_ftype *rpc_gss_seccreate;
194
rpc_gss_set_defaults_ftype *rpc_gss_set_defaults;
195
rpc_gss_max_data_length_ftype *rpc_gss_max_data_length;
196
rpc_gss_get_error_ftype *rpc_gss_get_error;
197
rpc_gss_mech_to_oid_ftype *rpc_gss_mech_to_oid;
198
rpc_gss_oid_to_mech_ftype *rpc_gss_oid_to_mech;
199
rpc_gss_qop_to_num_ftype *rpc_gss_qop_to_num;
200
rpc_gss_get_mechanisms_ftype *rpc_gss_get_mechanisms;
201
rpc_gss_get_versions_ftype *rpc_gss_get_versions;
202
rpc_gss_is_installed_ftype *rpc_gss_is_installed;
203
rpc_gss_set_svc_name_ftype *rpc_gss_set_svc_name;
204
rpc_gss_clear_svc_name_ftype *rpc_gss_clear_svc_name;
205
rpc_gss_getcred_ftype *rpc_gss_getcred;
206
rpc_gss_set_callback_ftype *rpc_gss_set_callback;
207
rpc_gss_clear_callback_ftype *rpc_gss_clear_callback;
208
rpc_gss_get_principal_name_ftype *rpc_gss_get_principal_name;
209
rpc_gss_svc_max_data_length_ftype *rpc_gss_svc_max_data_length;
210
rpc_gss_refresh_auth_ftype *rpc_gss_refresh_auth;
211
rpc_gss_ip_to_srv_principal_ftype *rpc_gss_ip_to_srv_principal;
212
};
213
extern struct rpc_gss_entries rpc_gss_entries;
214
215
/* Functions to access the entry points. */
216
static __inline AUTH *
217
rpc_gss_secfind_call(CLIENT *clnt, struct ucred *cred, const char *principal,
218
gss_OID mech_oid, rpc_gss_service_t service)
219
{
220
AUTH *ret = NULL;
221
222
if (rpc_gss_entries.rpc_gss_secfind != NULL)
223
ret = (*rpc_gss_entries.rpc_gss_secfind)(clnt, cred, principal,
224
mech_oid, service);
225
return (ret);
226
}
227
228
static __inline void
229
rpc_gss_secpurge_call(CLIENT *clnt)
230
{
231
232
if (rpc_gss_entries.rpc_gss_secpurge != NULL)
233
(*rpc_gss_entries.rpc_gss_secpurge)(clnt);
234
}
235
236
static __inline AUTH *
237
rpc_gss_seccreate_call(CLIENT *clnt, struct ucred *cred,
238
const char *clnt_principal, const char *principal, const char *mechanism,
239
rpc_gss_service_t service, const char *qop,
240
rpc_gss_options_req_t *options_req, rpc_gss_options_ret_t *options_ret)
241
{
242
AUTH *ret = NULL;
243
244
if (rpc_gss_entries.rpc_gss_seccreate != NULL)
245
ret = (*rpc_gss_entries.rpc_gss_seccreate)(clnt, cred,
246
clnt_principal, principal, mechanism, service, qop,
247
options_req, options_ret);
248
return (ret);
249
}
250
251
static __inline bool_t
252
rpc_gss_set_defaults_call(AUTH *auth, rpc_gss_service_t service,
253
const char *qop)
254
{
255
bool_t ret = 1;
256
257
if (rpc_gss_entries.rpc_gss_set_defaults != NULL)
258
ret = (*rpc_gss_entries.rpc_gss_set_defaults)(auth, service,
259
qop);
260
return (ret);
261
}
262
263
static __inline int
264
rpc_gss_max_data_length_call(AUTH *handle, int max_tp_unit_len)
265
{
266
int ret = 0;
267
268
if (rpc_gss_entries.rpc_gss_max_data_length != NULL)
269
ret = (*rpc_gss_entries.rpc_gss_max_data_length)(handle,
270
max_tp_unit_len);
271
return (ret);
272
}
273
274
static __inline void
275
rpc_gss_get_error_call(rpc_gss_error_t *error)
276
{
277
278
if (rpc_gss_entries.rpc_gss_get_error != NULL)
279
(*rpc_gss_entries.rpc_gss_get_error)(error);
280
}
281
282
static __inline bool_t
283
rpc_gss_mech_to_oid_call(const char *mech, gss_OID *oid_ret)
284
{
285
bool_t ret = 1;
286
287
if (rpc_gss_entries.rpc_gss_mech_to_oid != NULL)
288
ret = (*rpc_gss_entries.rpc_gss_mech_to_oid)(mech, oid_ret);
289
return (ret);
290
}
291
292
static __inline bool_t
293
rpc_gss_oid_to_mech_call(gss_OID oid, const char **mech_ret)
294
{
295
bool_t ret = 1;
296
297
if (rpc_gss_entries.rpc_gss_oid_to_mech != NULL)
298
ret = (*rpc_gss_entries.rpc_gss_oid_to_mech)(oid, mech_ret);
299
return (ret);
300
}
301
302
static __inline bool_t
303
rpc_gss_qop_to_num_call(const char *qop, const char *mech, u_int *num_ret)
304
{
305
bool_t ret = 1;
306
307
if (rpc_gss_entries.rpc_gss_qop_to_num != NULL)
308
ret = (*rpc_gss_entries.rpc_gss_qop_to_num)(qop, mech, num_ret);
309
return (ret);
310
}
311
312
static __inline const char **
313
rpc_gss_get_mechanisms_call(void)
314
{
315
const char **ret = NULL;
316
317
if (rpc_gss_entries.rpc_gss_get_mechanisms != NULL)
318
ret = (*rpc_gss_entries.rpc_gss_get_mechanisms)();
319
return (ret);
320
}
321
322
static __inline bool_t
323
rpc_gss_get_versions_call(u_int *vers_hi, u_int *vers_lo)
324
{
325
bool_t ret = 1;
326
327
if (rpc_gss_entries.rpc_gss_get_versions != NULL)
328
ret = (*rpc_gss_entries.rpc_gss_get_versions)(vers_hi, vers_lo);
329
return (ret);
330
}
331
332
static __inline bool_t
333
rpc_gss_is_installed_call(const char *mech)
334
{
335
bool_t ret = 1;
336
337
if (rpc_gss_entries.rpc_gss_is_installed != NULL)
338
ret = (*rpc_gss_entries.rpc_gss_is_installed)(mech);
339
return (ret);
340
}
341
342
static __inline bool_t
343
rpc_gss_set_svc_name_call(const char *principal, const char *mechanism,
344
u_int req_time, u_int program, u_int version)
345
{
346
bool_t ret = 1;
347
348
if (rpc_gss_entries.rpc_gss_set_svc_name != NULL)
349
ret = (*rpc_gss_entries.rpc_gss_set_svc_name)(principal,
350
mechanism, req_time, program, version);
351
return (ret);
352
}
353
354
static __inline void
355
rpc_gss_clear_svc_name_call(u_int program, u_int version)
356
{
357
358
if (rpc_gss_entries.rpc_gss_clear_svc_name != NULL)
359
(*rpc_gss_entries.rpc_gss_clear_svc_name)(program, version);
360
}
361
362
static __inline bool_t
363
rpc_gss_getcred_call(struct svc_req *req, rpc_gss_rawcred_t **rcred,
364
rpc_gss_ucred_t **ucred, void **cookie)
365
{
366
bool_t ret = 1;
367
368
if (rpc_gss_entries.rpc_gss_getcred != NULL)
369
ret = (*rpc_gss_entries.rpc_gss_getcred)(req, rcred, ucred,
370
cookie);
371
return (ret);
372
}
373
374
static __inline bool_t
375
rpc_gss_set_callback_call(rpc_gss_callback_t *cb)
376
{
377
bool_t ret = 1;
378
379
if (rpc_gss_entries.rpc_gss_set_callback != NULL)
380
ret = (*rpc_gss_entries.rpc_gss_set_callback)(cb);
381
return (ret);
382
}
383
384
static __inline void
385
rpc_gss_clear_callback_call(rpc_gss_callback_t *cb)
386
{
387
388
if (rpc_gss_entries.rpc_gss_clear_callback != NULL)
389
(*rpc_gss_entries.rpc_gss_clear_callback)(cb);
390
}
391
392
static __inline bool_t
393
rpc_gss_get_principal_name_call(rpc_gss_principal_t *principal,
394
const char *mech, const char *name, const char *node, const char *domain)
395
{
396
bool_t ret = 1;
397
398
if (rpc_gss_entries.rpc_gss_get_principal_name != NULL)
399
ret = (*rpc_gss_entries.rpc_gss_get_principal_name)(principal,
400
mech, name, node, domain);
401
return (ret);
402
}
403
404
static __inline int
405
rpc_gss_svc_max_data_length_call(struct svc_req *req, int max_tp_unit_len)
406
{
407
int ret = 0;
408
409
if (rpc_gss_entries.rpc_gss_svc_max_data_length != NULL)
410
ret = (*rpc_gss_entries.rpc_gss_svc_max_data_length)(req,
411
max_tp_unit_len);
412
return (ret);
413
}
414
415
static __inline void
416
rpc_gss_refresh_auth_call(AUTH *auth)
417
{
418
419
if (rpc_gss_entries.rpc_gss_refresh_auth != NULL)
420
(*rpc_gss_entries.rpc_gss_refresh_auth)(auth);
421
}
422
423
static __inline bool_t
424
rpc_gss_ip_to_srv_principal_call(char *ip_addr, const char *srv_name,
425
char *dns_name)
426
{
427
bool_t ret = FALSE;
428
429
if (rpc_gss_entries.rpc_gss_ip_to_srv_principal != NULL)
430
ret = (*rpc_gss_entries.rpc_gss_ip_to_srv_principal)(ip_addr,
431
srv_name, dns_name);
432
return (ret);
433
}
434
435
AUTH *rpc_gss_secfind(CLIENT *clnt, struct ucred *cred,
436
const char *principal, gss_OID mech_oid, rpc_gss_service_t service);
437
void rpc_gss_secpurge(CLIENT *clnt);
438
void rpc_gss_refresh_auth(AUTH *auth);
439
AUTH *rpc_gss_seccreate(CLIENT *clnt, struct ucred *cred,
440
const char *clnt_principal, const char *principal,
441
const char *mechanism, rpc_gss_service_t service,
442
const char *qop, rpc_gss_options_req_t *options_req,
443
rpc_gss_options_ret_t *options_ret);
444
#else /* !_KERNEL */
445
AUTH *rpc_gss_seccreate(CLIENT *clnt, struct ucred *cred,
446
const char *principal, const char *mechanism, rpc_gss_service_t service,
447
const char *qop, rpc_gss_options_req_t *options_req,
448
rpc_gss_options_ret_t *options_ret);
449
#endif /* _KERNEL */
450
bool_t rpc_gss_set_defaults(AUTH *auth, rpc_gss_service_t service,
451
const char *qop);
452
int rpc_gss_max_data_length(AUTH *handle, int max_tp_unit_len);
453
void rpc_gss_get_error(rpc_gss_error_t *error);
454
455
bool_t rpc_gss_mech_to_oid(const char *mech, gss_OID *oid_ret);
456
bool_t rpc_gss_oid_to_mech(gss_OID oid, const char **mech_ret);
457
bool_t rpc_gss_qop_to_num(const char *qop, const char *mech, u_int *num_ret);
458
const char **rpc_gss_get_mechanisms(void);
459
const char **rpc_gss_get_mech_info(const char *mech, rpc_gss_service_t *service);
460
bool_t rpc_gss_get_versions(u_int *vers_hi, u_int *vers_lo);
461
bool_t rpc_gss_is_installed(const char *mech);
462
463
bool_t rpc_gss_set_svc_name(const char *principal, const char *mechanism,
464
u_int req_time, u_int program, u_int version);
465
void rpc_gss_clear_svc_name(u_int program, u_int version);
466
bool_t rpc_gss_getcred(struct svc_req *req, rpc_gss_rawcred_t **rcred,
467
rpc_gss_ucred_t **ucred, void **cookie);
468
bool_t rpc_gss_set_callback(rpc_gss_callback_t *cb);
469
void rpc_gss_clear_callback(rpc_gss_callback_t *cb);
470
bool_t rpc_gss_get_principal_name(rpc_gss_principal_t *principal,
471
const char *mech, const char *name, const char *node, const char *domain);
472
int rpc_gss_svc_max_data_length(struct svc_req *req, int max_tp_unit_len);
473
bool_t rpc_gss_ip_to_srv_principal(char *ip_addr, const char *srv_name,
474
char *dns_name);
475
476
/*
477
* Internal interface from the RPC implementation.
478
*/
479
#ifndef _KERNEL
480
bool_t __rpc_gss_wrap(AUTH *auth, void *header, size_t headerlen,
481
XDR* xdrs, xdrproc_t xdr_args, void *args_ptr);
482
bool_t __rpc_gss_unwrap(AUTH *auth, XDR* xdrs, xdrproc_t xdr_args,
483
void *args_ptr);
484
#endif
485
bool_t __rpc_gss_set_error(int rpc_gss_error, int system_error);
486
487
__END_DECLS
488
489
#endif /* !_RPCSEC_GSS_H */
490
491