~ubuntu-branches/ubuntu/trusty/libuser/trusty

1 by Ghe Rivero
Import upstream version 0.54.dfsg.1
1
/*
2
 * Copyright (C) 2000-2002, 2005 Red Hat, Inc.
3
 *
4
 * This is free software; you can redistribute it and/or modify it under
5
 * the terms of the GNU Library General Public License as published by
6
 * the Free Software Foundation; either version 2 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful, but
10
 * WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Library General Public
15
 * License along with this program; if not, write to the Free Software
16
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
 */
18
1.1.4 by Ghe Rivero
Import upstream version 0.56.8.dfsg.1
19
#include <config.h>
1 by Ghe Rivero
Import upstream version 0.54.dfsg.1
20
#include <sys/stat.h>
21
#include <sys/types.h>
22
#include <errno.h>
23
#include <fcntl.h>
24
#include <limits.h>
25
#include <stdio.h>
26
#include <string.h>
27
#include <unistd.h>
28
#include <krb5.h>
29
#include <krb5/kdb.h>
30
#include <kadm5/admin.h>
31
#include "../lib/user_private.h"
32
33
#define LU_KRB5_REALM 0
34
#define LU_KRB5_PRINC 1
35
#define LU_KRB5_PASSWORD 2
36
#define LU_KRBPASSWORD "*K*"
37
38
#ifndef KRB5_SUCCESS
39
#define KRB5_SUCCESS 0
40
#endif
41
42
struct lu_krb5_context {
43
	struct lu_prompt prompts[3];
44
	void *handle;
45
};
46
47
static const char *
48
get_default_realm(struct lu_context *context)
49
{
50
	krb5_context kcontext;
51
	const char *ret = "";
52
	char *realm;
53
54
	g_assert(context != NULL);
55
56
	if (krb5_init_secure_context(&kcontext) == 0) {
57
		if (krb5_get_default_realm(kcontext, &realm) == 0) {
58
			ret =
59
			    context->scache->cache(context->scache, realm);
60
			krb5_free_default_realm(kcontext, realm);
61
		}
62
		krb5_free_context(kcontext);
63
	}
64
65
	ret = lu_cfg_read_single(context, "krb5/realm", ret);
66
67
	return ret;
68
}
69
70
static void *
71
create_server_handle(struct lu_krb5_context *context,
72
		     struct lu_error **error)
73
{
74
	kadm5_config_params params;
75
	void *handle = NULL;
76
	int ret;
77
	char *service = NULL;
78
79
	g_assert(context != NULL);
80
81
	memset(&params, 0, sizeof(params));
82
	params.mask = KADM5_CONFIG_REALM;
83
	params.realm = context->prompts[LU_KRB5_REALM].value;
84
	if (strstr(context->prompts[LU_KRB5_PRINC].value, "/")) {
85
		service = KADM5_ADMIN_SERVICE;
86
	} else {
87
		service = KADM5_CHANGEPW_SERVICE;
88
	}
89
	ret = kadm5_init(context->prompts[LU_KRB5_PRINC].value,
90
			 context->prompts[LU_KRB5_PASSWORD].value,
91
			 service,
92
			 &params,
93
			 KADM5_STRUCT_VERSION,
94
			 KADM5_API_VERSION_2, &handle);
95
	if (ret == KADM5_OK) {
96
		return handle;
97
	} else {
98
		lu_error_new(error, lu_error_generic,
99
			     _
100
			     ("error connecting to the kadm5 server for service `%s' in realm `%s': %s"),
101
			     service, params.realm, error_message(ret));
102
		return NULL;
103
	}
104
}
105
106
static void
107
free_server_handle(void *handle)
108
{
109
	if (handle != NULL) {
110
		kadm5_destroy(handle);
111
	}
112
}
113
114
static gboolean
115
lu_krb5_user_lookup_name(struct lu_module *module, gconstpointer name,
116
			 struct lu_ent *ent, struct lu_error **error)
117
{
118
	krb5_context context = NULL;
119
	krb5_principal principal = NULL;
120
	kadm5_principal_ent_rec principal_rec;
121
	struct lu_krb5_context *ctx = NULL;
122
	gboolean ret = FALSE;
123
124
	g_assert(module != NULL);
125
	g_assert(name != NULL);
126
	g_assert(strlen((char *) name) > 0);
127
128
	ctx = (struct lu_krb5_context *) module->module_context;
129
130
	if (krb5_init_secure_context(&context) != 0) {
131
		lu_error_new(error, lu_error_init,
132
			     _("error initializing kerberos library"));
133
		return FALSE;
134
	}
135
136
	if (krb5_parse_name(context, (const char *) name, &principal) != 0) {
137
		lu_error_new(error, lu_error_init,
138
			     _
139
			     ("error parsing user name `%s' for kerberos"),
140
			     (const char *) name);
141
		krb5_free_context(context);
142
		return FALSE;
143
	}
144
145
	if (kadm5_get_principal(ctx->handle, principal, &principal_rec, 0)
146
	    == KADM5_OK) {
147
		ret = TRUE;
148
	}
149
150
	krb5_free_principal(context, principal);
151
	krb5_free_context(context);
152
153
	return ret;
154
}
155
156
static gboolean
157
lu_krb5_user_lookup_id(struct lu_module *module, gconstpointer uid,
158
		       struct lu_ent *ent, struct lu_error **error)
159
{
160
	return FALSE;
161
}
162
163
static gboolean
164
lu_krb5_group_lookup_name(struct lu_module *module, gconstpointer name,
165
			  struct lu_ent *ent, struct lu_error **error)
166
{
167
	return FALSE;
168
}
169
170
static gboolean
171
lu_krb5_group_lookup_id(struct lu_module *module, gconstpointer gid,
172
			struct lu_ent *ent, struct lu_error **error)
173
{
174
	return FALSE;
175
}
176
177
static gboolean
178
lu_krb5_user_add(struct lu_module *module, struct lu_ent *ent,
179
		 struct lu_error **error)
180
{
181
	krb5_context context = NULL;
182
	kadm5_principal_ent_rec principal;
183
	GList *name, *pass, *i;
184
	char *password;
185
	int err;
186
	gboolean ret = FALSE;
187
	struct lu_krb5_context *ctx;
188
189
	g_assert(module != NULL);
190
	g_assert(name != NULL);
191
	g_assert(ent != NULL);
192
	g_assert(ent->magic == LU_ENT_MAGIC);
193
194
	ctx = (struct lu_krb5_context *) module->module_context;
195
196
	if (krb5_init_secure_context(&context) != 0) {
197
		lu_error_new(error, lu_error_init,
198
			     _("error initializing kerberos library"));
199
		return FALSE;
200
	}
201
202
	name = lu_ent_get(ent, LU_KRBNAME);
203
	if (name == NULL) {
204
		name = lu_ent_get(ent, LU_USERNAME);
205
	}
206
	if (name == NULL) {
207
		lu_error_new(error, lu_error_generic,
208
			     _
209
			     ("entity structure has no %s or %s attributes"),
210
			     LU_KRBNAME, LU_USERNAME);
211
		krb5_free_context(context);
212
		return FALSE;
213
	}
214
215
	if (krb5_parse_name(context, name->data, &principal.principal) !=
216
	    0) {
217
		lu_error_new(error, lu_error_init,
218
			     _
219
			     ("error parsing user name `%s' for kerberos"),
220
			     (const char *) name->data);
221
		krb5_free_context(context);
222
		return FALSE;
223
	}
224
225
	/* screen out pre-hashed passwords */
226
	pass = lu_ent_get(ent, LU_USERPASSWORD);
227
	for (i = pass; i; i = g_list_next(i)) {
228
		password = i->data;
1.1.1 by Pierre Habouzit
Import upstream version 0.54.6-2.1.dfsg.1
229
		if (password && !g_str_has_prefix(password, "{crypt}")) {
1 by Ghe Rivero
Import upstream version 0.54.dfsg.1
230
			/* we can use this one */
231
			break;
232
		}
233
		password = NULL;
234
	}
235
	/* screen out non-plain passwords (this catches all sorts of stuff, including {md5} and {sha1} */
236
	if (password == NULL) {
237
		pass = lu_ent_get(ent, LU_USERPASSWORD);
238
		for (i = pass; i; i = g_list_next(i)) {
239
			password = i->data;
1.1.1 by Pierre Habouzit
Import upstream version 0.54.6-2.1.dfsg.1
240
			if (password
241
			    && !g_str_has_prefix(password, "{") != 0) {
1 by Ghe Rivero
Import upstream version 0.54.dfsg.1
242
				/* we can use this one */
243
				break;
244
			}
245
			password = NULL;
246
		}
247
	}
248
249
	/* Note that we tried to create the account. */
250
	ret = FALSE;
251
	if (password != NULL) {
252
		err =
253
		    kadm5_create_principal(ctx->handle, &principal,
254
					   KADM5_PRINCIPAL, password);
255
		if (err == KADM5_OK) {
256
			char *unparsed = NULL;
257
			/* Change the password field so that a subsequent information add will note that
258
			 * the user is Kerberized. */
259
			lu_ent_set(ent, LU_USERPASSWORD, LU_KRBPASSWORD);
260
			if (krb5_unparse_name
261
			    (context, principal.principal,
262
			     &unparsed) == KRB5_SUCCESS) {
263
				char *tmp;
264
				tmp =
265
				    g_strconcat("{KERBEROS}", unparsed,
266
						NULL);
267
				lu_ent_add(ent, LU_USERPASSWORD, tmp);
268
				g_free(tmp);
269
				krb5_free_unparsed_name(context, unparsed);
270
			}
271
			/* Hey, it worked! */
272
			ret = TRUE;
273
		}
274
	}
275
276
	return ret;
277
}
278
279
static gboolean
280
lu_krb5_user_mod(struct lu_module *module, struct lu_ent *ent,
281
		 struct lu_error **error)
282
{
283
	krb5_context context = NULL;
284
	krb5_principal principal = NULL, old_principal = NULL;
285
	GList *name, *old_name;
286
	gboolean ret = TRUE;
287
	struct lu_krb5_context *ctx;
288
289
	g_assert(module != NULL);
290
	g_assert(ent != NULL);
291
	g_assert(ent->magic == LU_ENT_MAGIC);
292
293
	ctx = (struct lu_krb5_context *) module->module_context;
294
295
	if (krb5_init_secure_context(&context) != 0) {
296
		lu_error_new(error, lu_error_init,
297
			     _("error initializing kerberos library"));
298
		return FALSE;
299
	}
300
301
	name = lu_ent_get(ent, LU_KRBNAME);
302
	if (name == NULL) {
303
		name = lu_ent_get(ent, LU_USERNAME);
304
	}
305
	if (name == NULL) {
306
		lu_error_new(error, lu_error_generic,
307
			     _("entity has no %s or %s attributes"),
308
			     LU_KRBNAME, LU_USERNAME);
309
		krb5_free_context(context);
310
		return FALSE;
311
	}
312
313
	old_name = lu_ent_get_original(ent, LU_KRBNAME);
314
	if (old_name == NULL) {
315
		old_name = lu_ent_get_original(ent, LU_USERNAME);
316
	}
317
	if (old_name == NULL) {
318
		lu_error_new(error, lu_error_generic,
319
			     _
320
			     ("entity was created with no %s or %s attributes"),
321
			     LU_KRBNAME, LU_USERNAME);
322
		krb5_free_context(context);
323
		return FALSE;
324
	}
325
326
	if (krb5_parse_name(context, name->data, &principal) != 0) {
327
		lu_error_new(error, lu_error_generic,
328
			     _
329
			     ("error parsing user name `%s' for kerberos"),
330
			     (const char *) name->data);
331
		krb5_free_context(context);
332
		return FALSE;
333
	}
334
	if (krb5_parse_name(context, old_name->data, &old_principal) != 0) {
335
		lu_error_new(error, lu_error_generic,
336
			     _
337
			     ("error parsing user name `%s' for kerberos"),
338
			     (const char *) old_name->data);
339
		krb5_free_principal(context, principal);
340
		krb5_free_context(context);
341
		return FALSE;
342
	}
343
344
	/* If we need to rename the principal, do it. */
345
	if (krb5_principal_compare(context, principal, old_principal) ==
346
	    FALSE) {
347
		ret = FALSE;
348
		if (kadm5_rename_principal
349
		    (ctx->handle, old_principal, principal) == KADM5_OK) {
350
			ret = TRUE;
351
		}
352
	} else {
353
		/* Note that the user uses Kerberos. */
354
		lu_ent_set(ent, LU_USERPASSWORD, LU_KRBPASSWORD);
355
		/* We don't know how to do anything else, so just nod our
356
		 * heads and smile. */
357
		ret = TRUE;
358
	}
359
360
	krb5_free_principal(context, principal);
361
	krb5_free_principal(context, old_principal);
362
	krb5_free_context(context);
363
364
	return ret;
365
}
366
367
static gboolean
368
lu_krb5_user_del(struct lu_module *module, struct lu_ent *ent,
369
		 struct lu_error **error)
370
{
371
	krb5_context context = NULL;
372
	krb5_principal principal;
373
	GList *name;
374
	gboolean ret = FALSE;
375
	struct lu_krb5_context *ctx;
376
377
	g_assert(module != NULL);
378
	g_assert(ent != NULL);
379
	g_assert(ent->magic == LU_ENT_MAGIC);
380
381
	ctx = (struct lu_krb5_context *) module->module_context;
382
383
	if (krb5_init_secure_context(&context) != 0) {
384
		lu_error_new(error, lu_error_init,
385
			     _("error initializing kerberos library"));
386
		return FALSE;
387
	}
388
389
	name = lu_ent_get(ent, LU_KRBNAME);
390
	if (name == NULL) {
391
		name = lu_ent_get(ent, LU_USERNAME);
392
	}
393
	if (name == NULL) {
394
		lu_error_new(error, lu_error_generic,
395
			     _
396
			     ("entity structure has no %s or %s attributes"),
397
			     LU_KRBNAME, LU_USERNAME);
398
		krb5_free_context(context);
399
		return FALSE;
400
	}
401
402
	if (krb5_parse_name(context, name->data, &principal) != 0) {
403
		lu_error_new(error, lu_error_generic,
404
			     _
405
			     ("error parsing user name `%s' for kerberos"),
406
			     (const char *) name->data);
407
		krb5_free_context(context);
408
		return FALSE;
409
	}
410
411
	ret = (kadm5_delete_principal(ctx->handle, principal) == KADM5_OK);
412
413
	krb5_free_principal(context, principal);
414
	krb5_free_context(context);
415
416
	return ret;
417
}
418
419
static gboolean
420
lu_krb5_user_do_lock(struct lu_module *module, struct lu_ent *ent,
421
		     gboolean lck, struct lu_error **error)
422
{
423
	krb5_context context = NULL;
424
	kadm5_principal_ent_rec principal;
425
	GList *name;
426
	gboolean ret = FALSE;
427
	struct lu_krb5_context *ctx;
428
429
	g_assert(module != NULL);
430
	g_assert(ent != NULL);
431
	g_assert(ent->magic == LU_ENT_MAGIC);
432
433
	ctx = (struct lu_krb5_context *) module->module_context;
434
435
	if (krb5_init_secure_context(&context) != 0) {
436
		lu_error_new(error, lu_error_init,
437
			     _("error initializing kerberos library"));
438
		return FALSE;
439
	}
440
441
	name = lu_ent_get(ent, LU_KRBNAME);
442
	if (name == NULL) {
443
		name = lu_ent_get(ent, LU_USERNAME);
444
	}
445
	if (name == NULL) {
446
		lu_error_new(error, lu_error_generic,
447
			     _
448
			     ("entity structure has no %s or %s attributes"),
449
			     LU_KRBNAME, LU_USERNAME);
450
		krb5_free_context(context);
451
		return FALSE;
452
	}
453
454
	if (krb5_parse_name(context, name->data, &principal.principal) !=
455
	    0) {
456
		lu_error_new(error, lu_error_generic,
457
			     _
458
			     ("error parsing user name `%s' for kerberos"),
459
			     (const char *) name->data);
460
		krb5_free_context(context);
461
		return FALSE;
462
	}
463
464
	ret =
465
	    (kadm5_get_principal
466
	     (ctx->handle, principal.principal, &principal,
467
	      KADM5_PRINCIPAL | KADM5_ATTRIBUTES) == KADM5_OK);
468
	if (ret == FALSE) {
469
		lu_error_new(error, lu_error_generic,
470
			     _
471
			     ("error reading information for `%s' from kerberos"),
472
			     (const char *) name->data);
473
		krb5_free_principal(context, principal.principal);
474
		krb5_free_context(context);
475
		return FALSE;
476
	} else {
477
		if (lck) {
478
			principal.attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
479
		} else {
480
			principal.attributes &= ~KRB5_KDB_DISALLOW_ALL_TIX;
481
		}
482
		ret =
483
		    (kadm5_modify_principal
484
		     (ctx->handle, &principal,
485
		      KADM5_PRINCIPAL | KADM5_ATTRIBUTES) == KADM5_OK);
486
	}
487
488
	krb5_free_principal(context, principal.principal);
489
490
	return ret;
491
}
492
493
static gboolean
494
lu_krb5_user_lock(struct lu_module *module, struct lu_ent *ent,
495
		  struct lu_error **error)
496
{
497
	return lu_krb5_user_do_lock(module, ent, TRUE, error);
498
}
499
500
static gboolean
501
lu_krb5_user_unlock(struct lu_module *module, struct lu_ent *ent,
502
		    struct lu_error **error)
503
{
504
	return lu_krb5_user_do_lock(module, ent, FALSE, error);
505
}
506
507
static gboolean
508
lu_krb5_user_islocked(struct lu_module *module, struct lu_ent *ent,
509
		      struct lu_error **error)
510
{
511
	krb5_context context = NULL;
512
	kadm5_principal_ent_rec principal;
513
	GList *name;
514
	gboolean ret = FALSE;
515
	struct lu_krb5_context *ctx;
516
517
	g_assert(module != NULL);
518
	g_assert(ent != NULL);
519
	g_assert(ent->magic == LU_ENT_MAGIC);
520
521
	ctx = (struct lu_krb5_context *) module->module_context;
522
523
	if (krb5_init_secure_context(&context) != 0) {
524
		lu_error_new(error, lu_error_init,
525
			     _("error initializing kerberos library"));
526
		return FALSE;
527
	}
528
529
	name = lu_ent_get(ent, LU_KRBNAME);
530
	if (name == NULL) {
531
		name = lu_ent_get(ent, LU_USERNAME);
532
	}
533
	if (name == NULL) {
534
		lu_error_new(error, lu_error_generic,
535
			     _
536
			     ("entity structure has no %s or %s attributes"),
537
			     LU_KRBNAME, LU_USERNAME);
538
		krb5_free_context(context);
539
		return FALSE;
540
	}
541
542
	if (krb5_parse_name(context, name->data, &principal.principal) !=
543
	    0) {
544
		lu_error_new(error, lu_error_generic,
545
			     _
546
			     ("error parsing user name `%s' for kerberos"),
547
			     (const char *) name->data);
548
		krb5_free_context(context);
549
		return FALSE;
550
	}
551
552
	ret =
553
	    (kadm5_get_principal
554
	     (ctx->handle, principal.principal, &principal,
555
	      KADM5_PRINCIPAL | KADM5_ATTRIBUTES) == KADM5_OK);
556
	if (ret == FALSE) {
557
		lu_error_new(error, lu_error_generic,
558
			     _
559
			     ("error reading information for `%s' from kerberos"),
560
			     (const char *) name->data);
561
		krb5_free_principal(context, principal.principal);
562
		krb5_free_context(context);
563
		return FALSE;
564
	} else {
565
		ret =
566
		    (principal.attributes & KRB5_KDB_DISALLOW_ALL_TIX) ==
567
		    KRB5_KDB_DISALLOW_ALL_TIX;
568
	}
569
570
	return ret;
571
}
572
573
static gboolean
574
lu_krb5_user_setpass(struct lu_module *module, struct lu_ent *ent,
575
		     const char *password, struct lu_error **error)
576
{
577
	krb5_context context = NULL;
578
	krb5_principal principal = NULL;
579
	GList *name;
580
	gboolean ret = TRUE;
581
	struct lu_krb5_context *ctx;
582
583
	g_assert(module != NULL);
584
	g_assert(ent != NULL);
585
	g_assert(ent->magic == LU_ENT_MAGIC);
586
587
	ctx = (struct lu_krb5_context *) module->module_context;
588
589
	if (krb5_init_secure_context(&context) != 0) {
590
		lu_error_new(error, lu_error_init,
591
			     _("error initializing kerberos library"));
592
		return FALSE;
593
	}
594
595
	if (name == NULL) {
596
		name = lu_ent_get(ent, LU_USERNAME);
597
	}
598
	if (name == NULL) {
599
		lu_error_new(error, lu_error_generic,
600
			     _("entity has no %s attribute"), LU_USERNAME);
601
		krb5_free_context(context);
602
		return FALSE;
603
	}
604
605
	if (krb5_parse_name(context, name->data, &principal) != 0) {
606
		lu_error_new(error, lu_error_generic,
607
			     _
608
			     ("error parsing user name `%s' for kerberos"),
609
			     (const char *) name->data);
610
		krb5_free_context(context);
611
		return FALSE;
612
	}
613
614
	/* Now try to change the password. */
615
	if (password != NULL) {
616
#ifdef DEBUG
617
		g_print("Working password for %s is `%s'.\n", name->data,
618
			password);
619
		g_print("Changing password for %s.\n", name->data);
620
#endif
621
		if (kadm5_chpass_principal
622
		    (ctx->handle, principal,
623
		     (char *) password) == KADM5_OK) {
624
#ifdef DEBUG
625
			g_print("...succeeded.\n");
626
#endif
627
			/* Change the password field so
628
			 * that a subsequent information
629
			 * modify will note that the
630
			 * user is Kerberized. */
631
			lu_ent_set(ent, LU_USERPASSWORD, LU_KRBPASSWORD);
632
			ret = TRUE;
633
		} else {
634
#ifdef DEBUG
635
			g_print("...failed.\n");
636
#endif
637
			lu_error_new(error, lu_error_generic,
638
				     _("error setting password for `%s'"),
639
				     (const char *) name->data);
640
		}
641
	}
642
643
	krb5_free_principal(context, principal);
644
	krb5_free_context(context);
645
646
	return ret;
647
}
648
649
static gboolean
650
lu_krb5_group_add(struct lu_module *module, struct lu_ent *ent,
651
		  struct lu_error **error)
652
{
653
	return FALSE;
654
}
655
656
static gboolean
657
lu_krb5_group_mod(struct lu_module *module, struct lu_ent *ent,
658
		  struct lu_error **error)
659
{
660
	return FALSE;
661
}
662
663
static gboolean
664
lu_krb5_group_del(struct lu_module *module, struct lu_ent *ent,
665
		  struct lu_error **error)
666
{
667
	return FALSE;
668
}
669
670
static gboolean
671
lu_krb5_group_lock(struct lu_module *module, struct lu_ent *ent,
672
		   struct lu_error **error)
673
{
674
	return FALSE;
675
}
676
677
static gboolean
678
lu_krb5_group_unlock(struct lu_module *module, struct lu_ent *ent,
679
		     struct lu_error **error)
680
{
681
	return FALSE;
682
}
683
684
static gboolean
685
lu_krb5_group_islocked(struct lu_module *module, struct lu_ent *ent,
686
		       struct lu_error **error)
687
{
688
	return FALSE;
689
}
690
691
static gboolean
692
lu_krb5_group_setpass(struct lu_module *module, struct lu_ent *ent,
693
		      const char *password, struct lu_error **error)
694
{
695
	return FALSE;
696
}
697
698
static GList *
699
lu_krb5_users_enumerate(struct lu_module *module, const char *pattern,
700
			struct lu_error **error)
701
{
702
	return NULL;
703
}
704
705
static GList *
706
lu_krb5_groups_enumerate(struct lu_module *module, const char *pattern,
707
			 struct lu_error **error)
708
{
709
	return NULL;
710
}
711
712
static GList *
713
lu_krb5_users_enumerate_by_group(struct lu_module *module,
714
				 const char *group, gid_t gid,
715
				 struct lu_error **error)
716
{
717
	return NULL;
718
}
719
720
static GList *
721
lu_krb5_groups_enumerate_by_user(struct lu_module *module,
722
				 const char *user, struct lu_error **error)
723
{
724
	return NULL;
725
}
726
727
static gboolean
728
lu_krb5_close_module(struct lu_module *module)
729
{
730
	struct lu_krb5_context *ctx = NULL;
731
732
	g_assert(module != NULL);
733
734
	ctx = (struct lu_krb5_context *) module->module_context;
735
	free_server_handle(ctx->handle);
736
	memset(ctx, 0, sizeof(*ctx));
737
	g_free(ctx);
738
739
	module->scache->free(module->scache);
740
	memset(module, 0, sizeof(struct lu_module));
741
	g_free(module);
742
743
	return TRUE;
744
}
745
746
struct lu_module *
747
lu_krb5_init(struct lu_context *context, struct lu_error **error)
748
{
749
	struct lu_module *ret = NULL;
750
	struct lu_krb5_context *ctx = NULL;
751
	void *handle = NULL;
752
	char *tmp;
753
754
	g_assert(context != NULL);
755
	initialize_krb5_error_table();
756
	initialize_kadm_error_table();
757
758
	/* Verify that we can connect to the kadmind server. */
759
	g_assert(context->prompter != NULL);
760
761
	ctx = g_malloc0(sizeof(struct lu_krb5_context));
762
763
	ctx->prompts[LU_KRB5_REALM].key = "krb5/realm";
764
	ctx->prompts[LU_KRB5_REALM].prompt = N_("Kerberos Realm");
765
	ctx->prompts[LU_KRB5_REALM].visible = TRUE;
766
	ctx->prompts[LU_KRB5_REALM].default_value =
767
	    lu_cfg_read_single(context, "krb5/realm",
768
			       get_default_realm(context));
769
770
	ctx->prompts[LU_KRB5_PRINC].key = "krb5/principal";
771
	ctx->prompts[LU_KRB5_PRINC].prompt = N_("Kerberos Admin Principal");
772
	ctx->prompts[LU_KRB5_PRINC].visible = TRUE;
773
	if (context->auth_name) {
774
		tmp = g_strconcat(context->auth_name, "/admin", NULL);
775
		ctx->prompts[LU_KRB5_PRINC].default_value =
776
		    context->scache->cache(context->scache, tmp);
777
		g_free(tmp);
778
	} else {
779
		tmp =
780
		    g_strconcat(getlogin(), "/admin@",
781
				ctx->prompts[LU_KRB5_REALM].default_value,
782
				NULL);
783
		ctx->prompts[LU_KRB5_PRINC].default_value =
784
		    context->scache->cache(context->scache, tmp);
785
		g_free(tmp);
786
	}
787
	ctx->prompts[LU_KRB5_PRINC].default_value =
788
	    lu_cfg_read_single(context, "krb5/principal",
789
			       ctx->prompts[LU_KRB5_PRINC].default_value);
790
791
	ctx->prompts[LU_KRB5_PASSWORD].key = "krb5/password";
792
	ctx->prompts[LU_KRB5_PASSWORD].prompt =
793
	    N_("Kerberos Password for Admin Principal");
794
	ctx->prompts[LU_KRB5_PASSWORD].visible = FALSE;
795
796
	if ((context->prompter == NULL)
797
	    || (context->
798
		prompter(ctx->prompts, 3, context->prompter_data,
799
			 error) == FALSE)) {
800
		g_free(ctx);
801
		return NULL;
802
	}
803
804
	handle = create_server_handle(ctx, error);
805
	if (handle == NULL) {
806
		g_free(ctx);
807
		return NULL;
808
	}
809
	ctx->handle = handle;
810
811
	/* Allocate the method structure. */
812
	ret = g_malloc0(sizeof(struct lu_module));
813
	ret->version = LU_MODULE_VERSION;
814
	ret->scache = lu_string_cache_new(TRUE);
815
	ret->name = ret->scache->cache(ret->scache, "krb5");
816
	ret->module_context = ctx;
817
818
	/* Set the method pointers. */
819
	ret->user_lookup_name = lu_krb5_user_lookup_name;
820
	ret->user_lookup_id = lu_krb5_user_lookup_id;
821
822
	ret->user_add = lu_krb5_user_add;
823
	ret->user_mod = lu_krb5_user_mod;
824
	ret->user_del = lu_krb5_user_del;
825
	ret->user_lock = lu_krb5_user_lock;
826
	ret->user_unlock = lu_krb5_user_unlock;
827
	ret->user_islocked = lu_krb5_user_islocked;
828
	ret->user_setpass = lu_krb5_user_setpass;
829
	ret->users_enumerate = lu_krb5_users_enumerate;
830
	ret->users_enumerate_by_group = lu_krb5_users_enumerate_by_group;
831
832
	ret->group_lookup_name = lu_krb5_group_lookup_name;
833
	ret->group_lookup_id = lu_krb5_group_lookup_id;
834
835
	ret->group_add = lu_krb5_group_add;
836
	ret->group_mod = lu_krb5_group_mod;
837
	ret->group_del = lu_krb5_group_del;
838
	ret->group_lock = lu_krb5_group_lock;
839
	ret->group_unlock = lu_krb5_group_unlock;
840
	ret->group_islocked = lu_krb5_group_islocked;
841
	ret->group_setpass = lu_krb5_group_setpass;
842
	ret->groups_enumerate = lu_krb5_groups_enumerate;
843
	ret->groups_enumerate_by_user = lu_krb5_groups_enumerate_by_user;
844
845
	ret->close = lu_krb5_close_module;
846
847
	/* Done. */
848
	return ret;
849
}