Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/lib/kadm5/clnt/client_init.c
39566 views
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
/*
3
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
4
*/
5
6
/*
7
* Copyright (C) 1998 by the FundsXpress, INC.
8
*
9
* All rights reserved.
10
*
11
* Export of this software from the United States of America may require
12
* a specific license from the United States Government. It is the
13
* responsibility of any person or organization contemplating export to
14
* obtain such a license before exporting.
15
*
16
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
17
* distribute this software and its documentation for any purpose and
18
* without fee is hereby granted, provided that the above copyright
19
* notice appear in all copies and that both that copyright notice and
20
* this permission notice appear in supporting documentation, and that
21
* the name of FundsXpress. not be used in advertising or publicity pertaining
22
* to distribution of the software without specific, written prior
23
* permission. FundsXpress makes no representations about the suitability of
24
* this software for any purpose. It is provided "as is" without express
25
* or implied warranty.
26
*
27
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
28
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
29
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30
*/
31
32
#include <k5-int.h>
33
#include <netdb.h>
34
#include <com_err.h>
35
#include <sys/types.h>
36
#include <sys/socket.h>
37
#include <netinet/in.h>
38
#include <fake-addrinfo.h>
39
#include <krb5.h>
40
41
#include <kadm5/admin.h>
42
#include <kadm5/kadm_rpc.h>
43
#include "client_internal.h"
44
#include <iprop_hdr.h>
45
#include "iprop.h"
46
47
#include <gssrpc/rpc.h>
48
#include <gssapi/gssapi.h>
49
#include <gssapi/gssapi_krb5.h>
50
#include <gssrpc/auth_gssapi.h>
51
52
#define ADM_CCACHE "/tmp/ovsec_adm.XXXXXX"
53
54
enum init_type { INIT_PASS, INIT_SKEY, INIT_CREDS, INIT_ANONYMOUS };
55
56
static kadm5_ret_t
57
init_any(krb5_context context, char *client_name, enum init_type init_type,
58
char *pass, krb5_ccache ccache_in, char *service_name,
59
kadm5_config_params *params, krb5_ui_4 struct_version,
60
krb5_ui_4 api_version, char **db_args, void **server_handle);
61
62
static kadm5_ret_t
63
get_init_creds(kadm5_server_handle_t handle, krb5_principal client,
64
enum init_type init_type, char *pass, krb5_ccache ccache_in,
65
char *svcname_in, char *realm, krb5_principal *server_out);
66
67
static kadm5_ret_t
68
gic_iter(kadm5_server_handle_t handle, enum init_type init_type,
69
krb5_ccache ccache, krb5_principal client, char *pass,
70
char *svcname, char *realm, krb5_principal *server_out);
71
72
static kadm5_ret_t
73
connect_to_server(const char *hostname, int port, int *fd);
74
75
static kadm5_ret_t
76
setup_gss(kadm5_server_handle_t handle, kadm5_config_params *params_in,
77
krb5_principal client, krb5_principal server);
78
79
static void
80
rpc_auth(kadm5_server_handle_t handle, kadm5_config_params *params_in,
81
gss_cred_id_t gss_client_creds, gss_name_t gss_target);
82
83
kadm5_ret_t
84
kadm5_init_with_creds(krb5_context context, char *client_name,
85
krb5_ccache ccache, char *service_name,
86
kadm5_config_params *params, krb5_ui_4 struct_version,
87
krb5_ui_4 api_version, char **db_args,
88
void **server_handle)
89
{
90
return init_any(context, client_name, INIT_CREDS, NULL, ccache,
91
service_name, params, struct_version, api_version, db_args,
92
server_handle);
93
}
94
95
kadm5_ret_t
96
kadm5_init_with_password(krb5_context context, char *client_name,
97
char *pass, char *service_name,
98
kadm5_config_params *params, krb5_ui_4 struct_version,
99
krb5_ui_4 api_version, char **db_args,
100
void **server_handle)
101
{
102
return init_any(context, client_name, INIT_PASS, pass, NULL, service_name,
103
params, struct_version, api_version, db_args,
104
server_handle);
105
}
106
107
kadm5_ret_t
108
kadm5_init_anonymous(krb5_context context, char *client_name,
109
char *service_name, kadm5_config_params *params,
110
krb5_ui_4 struct_version, krb5_ui_4 api_version,
111
char **db_args, void **server_handle)
112
{
113
return init_any(context, client_name, INIT_ANONYMOUS, NULL, NULL,
114
service_name, params, struct_version, api_version,
115
db_args, server_handle);
116
}
117
118
kadm5_ret_t
119
kadm5_init(krb5_context context, char *client_name, char *pass,
120
char *service_name, kadm5_config_params *params,
121
krb5_ui_4 struct_version, krb5_ui_4 api_version, char **db_args,
122
void **server_handle)
123
{
124
return init_any(context, client_name, INIT_PASS, pass, NULL, service_name,
125
params, struct_version, api_version, db_args,
126
server_handle);
127
}
128
129
kadm5_ret_t
130
kadm5_init_with_skey(krb5_context context, char *client_name,
131
char *keytab, char *service_name,
132
kadm5_config_params *params, krb5_ui_4 struct_version,
133
krb5_ui_4 api_version, char **db_args,
134
void **server_handle)
135
{
136
return init_any(context, client_name, INIT_SKEY, keytab, NULL,
137
service_name, params, struct_version, api_version, db_args,
138
server_handle);
139
}
140
141
static kadm5_ret_t
142
free_handle(kadm5_server_handle_t handle)
143
{
144
kadm5_ret_t ret = 0;
145
OM_uint32 minor_stat;
146
krb5_ccache ccache;
147
148
if (handle == NULL)
149
return 0;
150
151
if (handle->destroy_cache && handle->cache_name != NULL) {
152
ret = krb5_cc_resolve(handle->context, handle->cache_name, &ccache);
153
if (!ret)
154
ret = krb5_cc_destroy(handle->context, ccache);
155
}
156
free(handle->cache_name);
157
(void)gss_release_cred(&minor_stat, &handle->cred);
158
if (handle->clnt != NULL && handle->clnt->cl_auth != NULL)
159
AUTH_DESTROY(handle->clnt->cl_auth);
160
if (handle->clnt != NULL)
161
clnt_destroy(handle->clnt);
162
if (handle->client_socket != -1)
163
close(handle->client_socket);
164
free(handle->lhandle);
165
kadm5_free_config_params(handle->context, &handle->params);
166
free(handle);
167
168
return ret;
169
}
170
171
static kadm5_ret_t
172
init_any(krb5_context context, char *client_name, enum init_type init_type,
173
char *pass, krb5_ccache ccache_in, char *service_name,
174
kadm5_config_params *params_in, krb5_ui_4 struct_version,
175
krb5_ui_4 api_version, char **db_args, void **server_handle)
176
{
177
int fd = -1;
178
krb5_boolean iprop_enable;
179
int port;
180
rpcprog_t rpc_prog;
181
rpcvers_t rpc_vers;
182
krb5_principal client = NULL, server = NULL;
183
struct timeval timeout;
184
185
kadm5_server_handle_t handle = NULL;
186
kadm5_config_params params_local;
187
188
krb5_error_code code;
189
generic_ret r = { 0, 0 };
190
191
initialize_ovk_error_table();
192
initialize_ovku_error_table();
193
194
if (server_handle == NULL || client_name == NULL)
195
return EINVAL;
196
197
CHECK_VERSIONS(struct_version, api_version, KADM5_OLD_LIB_API_VERSION,
198
KADM5_NEW_LIB_API_VERSION);
199
200
handle = k5alloc(sizeof(*handle), &code);
201
if (handle == NULL)
202
goto cleanup;
203
handle->lhandle = k5alloc(sizeof(*handle), &code);
204
if (handle->lhandle == NULL)
205
goto cleanup;
206
207
handle->magic_number = KADM5_SERVER_HANDLE_MAGIC;
208
handle->struct_version = struct_version;
209
handle->api_version = api_version;
210
handle->clnt = 0;
211
handle->client_socket = -1;
212
handle->cache_name = 0;
213
handle->destroy_cache = 0;
214
handle->context = 0;
215
handle->cred = GSS_C_NO_CREDENTIAL;
216
*handle->lhandle = *handle;
217
handle->lhandle->api_version = KADM5_API_VERSION_4;
218
handle->lhandle->struct_version = KADM5_STRUCT_VERSION;
219
handle->lhandle->lhandle = handle->lhandle;
220
221
handle->context = context;
222
223
memset(&params_local, 0, sizeof(params_local));
224
225
code = kadm5_get_config_params(handle->context, 0, params_in,
226
&handle->params);
227
if (code)
228
goto cleanup;
229
230
#define REQUIRED_PARAMS (KADM5_CONFIG_REALM | \
231
KADM5_CONFIG_ADMIN_SERVER | \
232
KADM5_CONFIG_KADMIND_PORT)
233
234
if ((handle->params.mask & REQUIRED_PARAMS) != REQUIRED_PARAMS) {
235
code = KADM5_MISSING_KRB5_CONF_PARAMS;
236
goto cleanup;
237
}
238
239
/*
240
* Parse the client name. If it has an empty realm, it is almost certainly
241
* a host-based principal using DNS fallback processing or the referral
242
* realm, so give it the appropriate name type for canonicalization. Also
243
* check for iprop client principals as kpropd sets the realm on the
244
* sn2princ result.
245
*/
246
code = krb5_parse_name(handle->context, client_name, &client);
247
if (code)
248
goto cleanup;
249
if ((init_type == INIT_SKEY && client->realm.length == 0) ||
250
(client->length == 2 &&
251
data_eq_string(client->data[0], KIPROP_SVC_NAME)))
252
client->type = KRB5_NT_SRV_HST;
253
254
/*
255
* Get credentials. Also does some fallbacks in case kadmin/fqdn
256
* principal doesn't exist.
257
*/
258
code = get_init_creds(handle, client, init_type, pass, ccache_in,
259
service_name, handle->params.realm, &server);
260
if (code)
261
goto cleanup;
262
263
/* If the service_name and client_name are iprop-centric, use the iprop
264
* port and RPC identifiers. */
265
iprop_enable = (service_name != NULL &&
266
strstr(service_name, KIPROP_SVC_NAME) != NULL &&
267
strstr(client_name, KIPROP_SVC_NAME) != NULL);
268
if (iprop_enable) {
269
port = handle->params.iprop_port;
270
rpc_prog = KRB5_IPROP_PROG;
271
rpc_vers = KRB5_IPROP_VERS;
272
} else {
273
port = handle->params.kadmind_port;
274
rpc_prog = KADM;
275
rpc_vers = KADMVERS;
276
}
277
278
code = connect_to_server(handle->params.admin_server, port, &fd);
279
if (code)
280
goto cleanup;
281
282
handle->clnt = clnttcp_create(NULL, rpc_prog, rpc_vers, &fd, 0, 0);
283
if (handle->clnt == NULL) {
284
code = KADM5_RPC_ERROR;
285
#ifdef DEBUG
286
clnt_pcreateerror("clnttcp_create");
287
#endif
288
goto cleanup;
289
}
290
291
/* Set a one-hour timeout. */
292
timeout.tv_sec = 3600;
293
timeout.tv_usec = 0;
294
(void)clnt_control(handle->clnt, CLSET_TIMEOUT, &timeout);
295
296
handle->client_socket = fd;
297
handle->lhandle->clnt = handle->clnt;
298
handle->lhandle->client_socket = fd;
299
300
/*
301
* The RPC connection is open; establish the GSS-API
302
* authentication context.
303
*/
304
code = setup_gss(handle, params_in,
305
(init_type == INIT_CREDS) ? client : NULL, server);
306
if (code)
307
goto cleanup;
308
309
/*
310
* Bypass the remainder of the code and return straight away
311
* if the gss service requested is kiprop
312
*/
313
if (iprop_enable) {
314
code = 0;
315
*server_handle = handle;
316
handle = NULL;
317
goto cleanup;
318
}
319
320
if (init_2(&handle->api_version, &r, handle->clnt)) {
321
code = KADM5_RPC_ERROR;
322
#ifdef DEBUG
323
clnt_perror(handle->clnt, "init_2 null resp");
324
#endif
325
goto cleanup;
326
}
327
/* Drop down to v3 wire protocol if server does not support v4 */
328
if (r.code == KADM5_NEW_SERVER_API_VERSION &&
329
handle->api_version == KADM5_API_VERSION_4) {
330
handle->api_version = KADM5_API_VERSION_3;
331
memset(&r, 0, sizeof(generic_ret));
332
if (init_2(&handle->api_version, &r, handle->clnt)) {
333
code = KADM5_RPC_ERROR;
334
goto cleanup;
335
}
336
}
337
/* Drop down to v2 wire protocol if server does not support v3 */
338
if (r.code == KADM5_NEW_SERVER_API_VERSION &&
339
handle->api_version == KADM5_API_VERSION_3) {
340
handle->api_version = KADM5_API_VERSION_2;
341
memset(&r, 0, sizeof(generic_ret));
342
if (init_2(&handle->api_version, &r, handle->clnt)) {
343
code = KADM5_RPC_ERROR;
344
goto cleanup;
345
}
346
}
347
if (r.code) {
348
code = r.code;
349
goto cleanup;
350
}
351
352
*server_handle = handle;
353
handle = NULL;
354
355
cleanup:
356
krb5_free_principal(context, client);
357
krb5_free_principal(context, server);
358
(void)free_handle(handle);
359
360
return code;
361
}
362
363
/* Get initial credentials for authenticating to server. Perform fallback from
364
* kadmin/fqdn to kadmin/admin if svcname_in is NULL. */
365
static kadm5_ret_t
366
get_init_creds(kadm5_server_handle_t handle, krb5_principal client,
367
enum init_type init_type, char *pass, krb5_ccache ccache_in,
368
char *svcname_in, char *realm, krb5_principal *server_out)
369
{
370
kadm5_ret_t code;
371
krb5_ccache ccache = NULL;
372
char *svcname, svcbuf[BUFSIZ];
373
374
*server_out = NULL;
375
376
/*
377
* Acquire a service ticket for svcname@realm for client, using password
378
* pass (which could be NULL), and create a ccache to store them in. If
379
* INIT_CREDS, use the ccache we were provided instead.
380
*/
381
if (init_type == INIT_CREDS) {
382
ccache = ccache_in;
383
if (asprintf(&handle->cache_name, "%s:%s",
384
krb5_cc_get_type(handle->context, ccache),
385
krb5_cc_get_name(handle->context, ccache)) < 0) {
386
handle->cache_name = NULL;
387
code = ENOMEM;
388
goto error;
389
}
390
} else {
391
static int counter = 0;
392
393
if (asprintf(&handle->cache_name, "MEMORY:kadm5_%u", counter++) < 0) {
394
handle->cache_name = NULL;
395
code = ENOMEM;
396
goto error;
397
}
398
code = krb5_cc_resolve(handle->context, handle->cache_name,
399
&ccache);
400
if (code)
401
goto error;
402
403
code = krb5_cc_initialize (handle->context, ccache, client);
404
if (code)
405
goto error;
406
407
handle->destroy_cache = 1;
408
}
409
handle->lhandle->cache_name = handle->cache_name;
410
411
svcname = (svcname_in != NULL) ? svcname_in : KADM5_ADMIN_SERVICE;
412
code = gic_iter(handle, init_type, ccache, client, pass, svcname, realm,
413
server_out);
414
if ((code == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
415
|| code == KRB5_CC_NOTFOUND) && svcname_in == NULL) {
416
/* Retry with host-based service principal. */
417
code = kadm5_get_admin_service_name(handle->context,
418
handle->params.realm,
419
svcbuf, sizeof(svcbuf));
420
if (code)
421
goto error;
422
code = gic_iter(handle, init_type, ccache, client, pass, svcbuf, realm,
423
server_out);
424
}
425
/* Improved error messages */
426
if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) code = KADM5_BAD_PASSWORD;
427
if (code == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN)
428
code = KADM5_SECURE_PRINC_MISSING;
429
430
error:
431
if (ccache != NULL && init_type != INIT_CREDS)
432
krb5_cc_close(handle->context, ccache);
433
return code;
434
}
435
436
/* Perform one iteration of attempting to get credentials. This includes
437
* searching existing ccache for requested service if INIT_CREDS. */
438
static kadm5_ret_t
439
gic_iter(kadm5_server_handle_t handle, enum init_type init_type,
440
krb5_ccache ccache, krb5_principal client, char *pass, char *svcname,
441
char *realm, krb5_principal *server_out)
442
{
443
kadm5_ret_t code;
444
krb5_context ctx;
445
krb5_keytab kt;
446
krb5_get_init_creds_opt *opt = NULL;
447
krb5_creds mcreds, outcreds;
448
449
*server_out = NULL;
450
ctx = handle->context;
451
kt = NULL;
452
memset(&opt, 0, sizeof(opt));
453
memset(&mcreds, 0, sizeof(mcreds));
454
memset(&outcreds, 0, sizeof(outcreds));
455
456
/* Credentials for kadmin don't need to be forwardable or proxiable. */
457
if (init_type != INIT_CREDS) {
458
code = krb5_get_init_creds_opt_alloc(ctx, &opt);
459
if (code)
460
goto error;
461
462
krb5_get_init_creds_opt_set_forwardable(opt, 0);
463
krb5_get_init_creds_opt_set_proxiable(opt, 0);
464
krb5_get_init_creds_opt_set_out_ccache(ctx, opt, ccache);
465
if (init_type == INIT_ANONYMOUS)
466
krb5_get_init_creds_opt_set_anonymous(opt, 1);
467
}
468
469
if (init_type == INIT_PASS || init_type == INIT_ANONYMOUS) {
470
code = krb5_get_init_creds_password(ctx, &outcreds, client, pass,
471
krb5_prompter_posix,
472
NULL, 0, svcname, opt);
473
if (code)
474
goto error;
475
} else if (init_type == INIT_SKEY) {
476
if (pass) {
477
code = krb5_kt_resolve(ctx, pass, &kt);
478
if (code)
479
goto error;
480
}
481
code = krb5_get_init_creds_keytab(ctx, &outcreds, client, kt,
482
0, svcname, opt);
483
if (pass)
484
krb5_kt_close(ctx, kt);
485
if (code)
486
goto error;
487
} else if (init_type == INIT_CREDS) {
488
mcreds.client = client;
489
code = krb5_parse_name_flags(ctx, svcname,
490
KRB5_PRINCIPAL_PARSE_IGNORE_REALM,
491
&mcreds.server);
492
if (code)
493
goto error;
494
code = krb5_set_principal_realm(ctx, mcreds.server, realm);
495
if (code)
496
goto error;
497
code = krb5_cc_retrieve_cred(ctx, ccache, 0,
498
&mcreds, &outcreds);
499
krb5_free_principal(ctx, mcreds.server);
500
if (code)
501
goto error;
502
} else {
503
code = EINVAL;
504
goto error;
505
}
506
507
/* Steal the server principal of the creds we acquired and return it to the
508
* caller, which needs to knows what service to authenticate to. */
509
*server_out = outcreds.server;
510
outcreds.server = NULL;
511
512
error:
513
krb5_free_cred_contents(ctx, &outcreds);
514
if (opt)
515
krb5_get_init_creds_opt_free(ctx, opt);
516
return code;
517
}
518
519
/* Set *fd to a socket connected to hostname and port. */
520
static kadm5_ret_t
521
connect_to_server(const char *hostname, int port, int *fd)
522
{
523
struct addrinfo hint, *addrs, *a;
524
char portbuf[32];
525
int err, s;
526
kadm5_ret_t code;
527
528
/* Look up the server's addresses. */
529
(void) snprintf(portbuf, sizeof(portbuf), "%d", port);
530
memset(&hint, 0, sizeof(hint));
531
hint.ai_socktype = SOCK_STREAM;
532
hint.ai_flags = AI_ADDRCONFIG;
533
#ifdef AI_NUMERICSERV
534
hint.ai_flags |= AI_NUMERICSERV;
535
#endif
536
err = getaddrinfo(hostname, portbuf, &hint, &addrs);
537
if (err != 0)
538
return KADM5_CANT_RESOLVE;
539
540
/* Try to connect to each address until we succeed. */
541
for (a = addrs; a != NULL; a = a->ai_next) {
542
s = socket(a->ai_family, a->ai_socktype, 0);
543
if (s == -1) {
544
code = KADM5_FAILURE;
545
goto cleanup;
546
}
547
err = connect(s, a->ai_addr, a->ai_addrlen);
548
if (err == 0) {
549
*fd = s;
550
code = 0;
551
goto cleanup;
552
}
553
close(s);
554
}
555
556
/* We didn't succeed on any address. */
557
code = KADM5_RPC_ERROR;
558
cleanup:
559
freeaddrinfo(addrs);
560
return code;
561
}
562
563
/* Acquire GSSAPI credentials and set up RPC auth flavor. */
564
static kadm5_ret_t
565
setup_gss(kadm5_server_handle_t handle, kadm5_config_params *params_in,
566
krb5_principal client, krb5_principal server)
567
{
568
OM_uint32 gssstat, minor_stat;
569
gss_buffer_desc buf;
570
gss_name_t gss_client;
571
gss_name_t gss_target;
572
const char *c_ccname_orig;
573
char *ccname_orig;
574
575
ccname_orig = NULL;
576
gss_client = gss_target = GSS_C_NO_NAME;
577
578
/* Temporarily use the kadm5 cache. */
579
gssstat = gss_krb5_ccache_name(&minor_stat, handle->cache_name,
580
&c_ccname_orig);
581
if (gssstat != GSS_S_COMPLETE)
582
goto error;
583
if (c_ccname_orig)
584
ccname_orig = strdup(c_ccname_orig);
585
else
586
ccname_orig = 0;
587
588
buf.value = &server;
589
buf.length = sizeof(server);
590
gssstat = gss_import_name(&minor_stat, &buf,
591
(gss_OID)gss_nt_krb5_principal, &gss_target);
592
if (gssstat != GSS_S_COMPLETE)
593
goto error;
594
595
if (client != NULL) {
596
buf.value = &client;
597
buf.length = sizeof(client);
598
gssstat = gss_import_name(&minor_stat, &buf,
599
(gss_OID)gss_nt_krb5_principal, &gss_client);
600
} else gss_client = GSS_C_NO_NAME;
601
602
if (gssstat != GSS_S_COMPLETE)
603
goto error;
604
605
gssstat = gss_acquire_cred(&minor_stat, gss_client, 0,
606
GSS_C_NULL_OID_SET, GSS_C_INITIATE,
607
&handle->cred, NULL, NULL);
608
if (gssstat != GSS_S_COMPLETE)
609
goto error;
610
611
/*
612
* Do actual creation of RPC auth handle. Implements auth flavor
613
* fallback.
614
*/
615
rpc_auth(handle, params_in, handle->cred, gss_target);
616
617
error:
618
if (gss_client)
619
gss_release_name(&minor_stat, &gss_client);
620
if (gss_target)
621
gss_release_name(&minor_stat, &gss_target);
622
623
/* Revert to prior gss_krb5 ccache. */
624
if (ccname_orig) {
625
gssstat = gss_krb5_ccache_name(&minor_stat, ccname_orig, NULL);
626
if (gssstat) {
627
return KADM5_GSS_ERROR;
628
}
629
free(ccname_orig);
630
} else {
631
gssstat = gss_krb5_ccache_name(&minor_stat, NULL, NULL);
632
if (gssstat) {
633
return KADM5_GSS_ERROR;
634
}
635
}
636
637
if (handle->clnt->cl_auth == NULL) {
638
return KADM5_GSS_ERROR;
639
}
640
return 0;
641
}
642
643
/* Create RPC auth handle. Do auth flavor fallback if needed. */
644
static void
645
rpc_auth(kadm5_server_handle_t handle, kadm5_config_params *params_in,
646
gss_cred_id_t gss_client_creds, gss_name_t gss_target)
647
{
648
OM_uint32 gssstat, minor_stat;
649
struct rpc_gss_sec sec;
650
651
/* Allow unauthenticated option for testing. */
652
if (params_in != NULL && (params_in->mask & KADM5_CONFIG_NO_AUTH))
653
return;
654
655
/* Use RPCSEC_GSS by default. */
656
if (params_in == NULL ||
657
!(params_in->mask & KADM5_CONFIG_OLD_AUTH_GSSAPI)) {
658
sec.mech = (gss_OID)gss_mech_krb5;
659
sec.qop = GSS_C_QOP_DEFAULT;
660
sec.svc = RPCSEC_GSS_SVC_PRIVACY;
661
sec.cred = gss_client_creds;
662
sec.req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
663
664
handle->clnt->cl_auth = authgss_create(handle->clnt,
665
gss_target, &sec);
666
if (handle->clnt->cl_auth != NULL)
667
return;
668
}
669
670
if (params_in != NULL && (params_in->mask & KADM5_CONFIG_AUTH_NOFALLBACK))
671
return;
672
673
/* Fall back to old AUTH_GSSAPI. */
674
handle->clnt->cl_auth = auth_gssapi_create(handle->clnt,
675
&gssstat,
676
&minor_stat,
677
gss_client_creds,
678
gss_target,
679
(gss_OID) gss_mech_krb5,
680
GSS_C_MUTUAL_FLAG
681
| GSS_C_REPLAY_FLAG,
682
0, NULL, NULL, NULL);
683
}
684
685
kadm5_ret_t
686
kadm5_destroy(void *server_handle)
687
{
688
CHECK_HANDLE(server_handle);
689
return free_handle(server_handle);
690
}
691
/* not supported on client */
692
kadm5_ret_t kadm5_lock(void *server_handle)
693
{
694
return EINVAL;
695
}
696
697
/* not supported on client */
698
kadm5_ret_t kadm5_unlock(void *server_handle)
699
{
700
return EINVAL;
701
}
702
703
kadm5_ret_t kadm5_flush(void *server_handle)
704
{
705
return KADM5_OK;
706
}
707
708
int _kadm5_check_handle(void *handle)
709
{
710
CHECK_HANDLE(handle);
711
return 0;
712
}
713
714
krb5_error_code kadm5_init_krb5_context (krb5_context *ctx)
715
{
716
return krb5_init_context(ctx);
717
}
718
719
/*
720
* Stub function for kadmin. It was created to eliminate the dependency on
721
* libkdb's ulog functions. The srv equivalent makes the actual calls.
722
*/
723
krb5_error_code
724
kadm5_init_iprop(void *handle, char **db_args)
725
{
726
return (0);
727
}
728
729