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(¶ms, 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 |
¶ms, |
|
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 |
}
|