1 /*
2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 /*
7 * kadmin/ldap_util/kdb5_ldap_realm.c
8 *
9 * Copyright 1990,1991,2001, 2002 by the Massachusetts Institute of Technology.
10 * All Rights Reserved.
11 *
12 * Export of this software from the United States of America may
13 * require a specific license from the United States Government.
14 * It is the responsibility of any person or organization contemplating
15 * export to obtain such a license before exporting.
16 *
17 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
18 * distribute this software and its documentation for any purpose and
19 * without fee is hereby granted, provided that the above copyright
20 * notice appear in all copies and that both that copyright notice and
21 * this permission notice appear in supporting documentation, and that
22 * the name of M.I.T. not be used in advertising or publicity pertaining
23 * to distribution of the software without specific, written prior
24 * permission. Furthermore if you modify this software you must label
25 * your software as modified software and not distribute it in such a
26 * fashion that it might be confused with the original M.I.T. software.
27 * M.I.T. makes no representations about the suitability of
28 * this software for any purpose. It is provided "as is" without express
29 * or implied warranty.
30 */
31
32 /*
33 * Copyright (C) 1998 by the FundsXpress, INC.
34 *
35 * All rights reserved.
36 *
37 * Export of this software from the United States of America may require
38 * a specific license from the United States Government. It is the
39 * responsibility of any person or organization contemplating export to
40 * obtain such a license before exporting.
41 *
42 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
43 * distribute this software and its documentation for any purpose and
44 * without fee is hereby granted, provided that the above copyright
45 * notice appear in all copies and that both that copyright notice and
46 * this permission notice appear in supporting documentation, and that
47 * the name of FundsXpress. not be used in advertising or publicity pertaining
48 * to distribution of the software without specific, written prior
49 * permission. FundsXpress makes no representations about the suitability of
50 * this software for any purpose. It is provided "as is" without express
51 * or implied warranty.
52 *
53 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
54 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
55 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
56 */
57
58 /* Copyright (c) 2004-2005, Novell, Inc.
59 * All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions are met:
63 *
64 * * Redistributions of source code must retain the above copyright notice,
65 * this list of conditions and the following disclaimer.
66 * * Redistributions in binary form must reproduce the above copyright
67 * notice, this list of conditions and the following disclaimer in the
68 * documentation and/or other materials provided with the distribution.
69 * * The copyright holder's name is not used to endorse or promote products
70 * derived from this software without specific prior written permission.
71 *
72 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
73 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
74 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
75 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
76 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
77 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
78 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
79 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
80 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
81 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
82 * POSSIBILITY OF SUCH DAMAGE.
83 */
84
85 /*
86 * Create / Modify / Destroy / View / List realm(s)
87 */
88
89 /* Needed for getting the definition of KRB5_TL_DB_ARGS */
90 #define SECURID
91
92 #include <stdio.h>
93 #include <k5-int.h>
94 #include <kadm5/admin.h>
95 #include <libintl.h>
96 #include <locale.h>
97 #include "kdb5_ldap_util.h"
98 #include "kdb5_ldap_list.h"
99 #include <ldap_principal.h>
100 #include <ldap_krbcontainer.h>
101 extern time_t get_date(char *); /* kadmin/cli/getdate.o */
102
103 char *yes = "yes\n"; /* \n to compare against result of fgets */
104 krb5_key_salt_tuple def_kslist = {ENCTYPE_DES_CBC_CRC, KRB5_KDB_SALTTYPE_NORMAL};
105
106 struct realm_info rblock = {
107 KRB5_KDB_MAX_LIFE,
108 KRB5_KDB_MAX_RLIFE,
109 KRB5_KDB_EXPIRATION,
110 KRB5_KDB_DEF_FLAGS,
111 (krb5_keyblock *) NULL,
112 1,
113 &def_kslist
114 };
115
116 krb5_data tgt_princ_entries[] = {
117 {0, KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME},
118 {0, 0, 0} };
119
120 krb5_data db_creator_entries[] = {
121 {0, sizeof("db_creation")-1, "db_creation"} };
122
123
124 static krb5_principal_data db_create_princ = {
125 0, /* magic number */
126 {0, 0, 0}, /* krb5_data realm */
127 db_creator_entries, /* krb5_data *data */
128 1, /* int length */
129 KRB5_NT_SRV_INST /* int type */
130 };
131
132 extern char *mkey_password;
133 extern char *progname;
134 extern kadm5_config_params global_params;
135
136 static void print_realm_params(krb5_ldap_realm_params *rparams, int mask);
137 static int kdb_ldap_create_principal (krb5_context context, krb5_principal
138 princ, enum ap_op op, struct realm_info *pblock);
139
140
141 static char *strdur(time_t duration);
142 static int get_ticket_policy(krb5_ldap_realm_params *rparams, int *i, char *argv[],int argc);
143 static krb5_error_code krb5_dbe_update_mod_princ_data_new (krb5_context context, krb5_db_entry *entry, krb5_timestamp mod_date, krb5_const_principal mod_princ);
144 static krb5_error_code krb5_dbe_update_tl_data_new ( krb5_context context, krb5_db_entry *entry, krb5_tl_data *new_tl_data);
145
146 #define ADMIN_LIFETIME 60*60*3 /* 3 hours */
147 #define CHANGEPW_LIFETIME 60*5 /* 5 minutes */
148
get_ticket_policy(rparams,i,argv,argc)149 static int get_ticket_policy(rparams,i,argv,argc)
150 krb5_ldap_realm_params *rparams;
151 int *i;
152 char *argv[];
153 int argc;
154 {
155 time_t date;
156 time_t now;
157 int mask = 0;
158 krb5_error_code retval = 0;
159 krb5_boolean no_msg = FALSE;
160
161 krb5_boolean print_usage = FALSE;
162 /* Solaris Kerberos */
163 char *me = progname;
164
165 time(&now);
166 if (!strcmp(argv[*i], "-maxtktlife")) {
167 if (++(*i) > argc-1)
168 goto err_usage;
169 date = get_date(argv[*i]);
170 if (date == (time_t)(-1)) {
171 retval = EINVAL;
172 com_err (me, retval, gettext("while providing time specification"));
173 goto err_nomsg;
174 }
175 rparams->max_life = date-now;
176 mask |= LDAP_REALM_MAXTICKETLIFE;
177 }
178
179
180 else if (!strcmp(argv[*i], "-maxrenewlife")) {
181 if (++(*i) > argc-1)
182 goto err_usage;
183
184 date = get_date(argv[*i]);
185 if (date == (time_t)(-1)) {
186 retval = EINVAL;
187 com_err (me, retval, gettext("while providing time specification"));
188 goto err_nomsg;
189 }
190 rparams->max_renewable_life = date-now;
191 mask |= LDAP_REALM_MAXRENEWLIFE;
192 } else if (!strcmp((argv[*i] + 1), "allow_postdated")) {
193 if (*(argv[*i]) == '+')
194 rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_POSTDATED);
195 else if (*(argv[*i]) == '-')
196 rparams->tktflags |= KRB5_KDB_DISALLOW_POSTDATED;
197 else
198 goto err_usage;
199
200 mask |= LDAP_REALM_KRBTICKETFLAGS;
201 } else if (!strcmp((argv[*i] + 1), "allow_forwardable")) {
202 if (*(argv[*i]) == '+')
203 rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_FORWARDABLE);
204
205 else if (*(argv[*i]) == '-')
206 rparams->tktflags |= KRB5_KDB_DISALLOW_FORWARDABLE;
207 else
208 goto err_usage;
209
210 mask |= LDAP_REALM_KRBTICKETFLAGS;
211 } else if (!strcmp((argv[*i] + 1), "allow_renewable")) {
212 if (*(argv[*i]) == '+')
213 rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_RENEWABLE);
214 else if (*(argv[*i]) == '-')
215 rparams->tktflags |= KRB5_KDB_DISALLOW_RENEWABLE;
216 else
217 goto err_usage;
218
219 mask |= LDAP_REALM_KRBTICKETFLAGS;
220 } else if (!strcmp((argv[*i] + 1), "allow_proxiable")) {
221 if (*(argv[*i]) == '+')
222 rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_PROXIABLE);
223 else if (*(argv[*i]) == '-')
224 rparams->tktflags |= KRB5_KDB_DISALLOW_PROXIABLE;
225 else
226 goto err_usage;
227
228 mask |= LDAP_REALM_KRBTICKETFLAGS;
229 } else if (!strcmp((argv[*i] + 1), "allow_dup_skey")) {
230 if (*(argv[*i]) == '+')
231 rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_DUP_SKEY);
232 else if (*(argv[*i]) == '-')
233 rparams->tktflags |= KRB5_KDB_DISALLOW_DUP_SKEY;
234 else
235 goto err_usage;
236
237 mask |= LDAP_REALM_KRBTICKETFLAGS;
238 }
239
240 else if (!strcmp((argv[*i] + 1), "requires_preauth")) {
241 if (*(argv[*i]) == '+')
242 rparams->tktflags |= KRB5_KDB_REQUIRES_PRE_AUTH;
243 else if (*(argv[*i]) == '-')
244 rparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_PRE_AUTH);
245 else
246 goto err_usage;
247
248 mask |= LDAP_REALM_KRBTICKETFLAGS;
249 } else if (!strcmp((argv[*i] + 1), "requires_hwauth")) {
250 if (*(argv[*i]) == '+')
251 rparams->tktflags |= KRB5_KDB_REQUIRES_HW_AUTH;
252 else if (*(argv[*i]) == '-')
253 rparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_HW_AUTH);
254 else
255 goto err_usage;
256
257 mask |= LDAP_REALM_KRBTICKETFLAGS;
258 } else if (!strcmp((argv[*i] + 1), "allow_svr")) {
259 if (*(argv[*i]) == '+')
260 rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_SVR);
261 else if (*(argv[*i]) == '-')
262 rparams->tktflags |= KRB5_KDB_DISALLOW_SVR;
263 else
264 goto err_usage;
265
266 mask |= LDAP_REALM_KRBTICKETFLAGS;
267 } else if (!strcmp((argv[*i] + 1), "allow_tgs_req")) {
268 if (*(argv[*i]) == '+')
269 rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_TGT_BASED);
270 else if (*(argv[*i]) == '-')
271 rparams->tktflags |= KRB5_KDB_DISALLOW_TGT_BASED;
272 else
273 goto err_usage;
274
275 mask |= LDAP_REALM_KRBTICKETFLAGS;
276 } else if (!strcmp((argv[*i] + 1), "allow_tix")) {
277 if (*(argv[*i]) == '+')
278 rparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_ALL_TIX);
279 else if (*(argv[*i]) == '-')
280 rparams->tktflags |= KRB5_KDB_DISALLOW_ALL_TIX;
281 else
282 goto err_usage;
283
284 mask |= LDAP_REALM_KRBTICKETFLAGS;
285 } else if (!strcmp((argv[*i] + 1), "needchange")) {
286 if (*(argv[*i]) == '+')
287 rparams->tktflags |= KRB5_KDB_REQUIRES_PWCHANGE;
288 else if (*(argv[*i]) == '-')
289 rparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_PWCHANGE);
290 else
291 goto err_usage;
292
293 mask |= LDAP_REALM_KRBTICKETFLAGS;
294 } else if (!strcmp((argv[*i] + 1), "password_changing_service")) {
295 if (*(argv[*i]) == '+')
296 rparams->tktflags |= KRB5_KDB_PWCHANGE_SERVICE;
297 else if (*(argv[*i]) == '-')
298 rparams->tktflags &= (int)(~KRB5_KDB_PWCHANGE_SERVICE);
299 else
300 goto err_usage;
301
302 mask |=LDAP_REALM_KRBTICKETFLAGS;
303 }
304 err_usage:
305 print_usage = TRUE;
306
307 err_nomsg:
308 no_msg = TRUE;
309
310 return mask;
311 }
312
313 /*
314 * This function will create a realm on the LDAP Server, with
315 * the specified attributes.
316 */
kdb5_ldap_create(argc,argv)317 void kdb5_ldap_create(argc, argv)
318 int argc;
319 char *argv[];
320 {
321 krb5_error_code retval = 0;
322 krb5_keyblock master_keyblock;
323 krb5_ldap_realm_params *rparams = NULL;
324 krb5_principal master_princ = NULL;
325 kdb5_dal_handle *dal_handle = NULL;
326 krb5_ldap_context *ldap_context=NULL;
327 krb5_boolean realm_obj_created = FALSE;
328 krb5_boolean create_complete = FALSE;
329 krb5_boolean print_usage = FALSE;
330 krb5_boolean no_msg = FALSE;
331 char *oldcontainerref=NULL;
332 char pw_str[1024];
333 int do_stash = 0;
334 int i = 0;
335 int mask = 0, ret_mask = 0;
336 char **list = NULL;
337 #ifdef HAVE_EDIRECTORY
338 int rightsmask = 0;
339 #endif
340
341 memset(&master_keyblock, 0, sizeof(master_keyblock));
342
343 rparams = (krb5_ldap_realm_params *)malloc(
344 sizeof(krb5_ldap_realm_params));
345 if (rparams == NULL) {
346 retval = ENOMEM;
347 goto cleanup;
348 }
349 memset(rparams, 0, sizeof(krb5_ldap_realm_params));
350
351 /* Parse the arguments */
352 for (i = 1; i < argc; i++) {
353 if (!strcmp(argv[i], "-subtrees")) {
354 if (++i > argc-1)
355 goto err_usage;
356
357 if(strncmp(argv[i], "", strlen(argv[i]))!=0) {
358 list = (char **) calloc(MAX_LIST_ENTRIES, sizeof(char *));
359 if (list == NULL) {
360 retval = ENOMEM;
361 goto cleanup;
362 }
363 if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
364 free(list);
365 list = NULL;
366 goto cleanup;
367 }
368
369 rparams->subtreecount=0;
370 while(list[rparams->subtreecount]!=NULL)
371 (rparams->subtreecount)++;
372 rparams->subtree = list;
373 } else if(strncmp(argv[i], "", strlen(argv[i]))==0) {
374 /* dont allow subtree value to be set at the root(NULL, "") of the tree */
375 /* Solaris Kerberos */
376 com_err(progname, EINVAL,
377 gettext("for subtree while creating realm '%s'"),
378 global_params.realm);
379 goto err_nomsg;
380 }
381 rparams->subtree[rparams->subtreecount] = NULL;
382 mask |= LDAP_REALM_SUBTREE;
383 } else if (!strcmp(argv[i], "-containerref")) {
384 if (++i > argc-1)
385 goto err_usage;
386 if(strncmp(argv[i], "", strlen(argv[i]))==0) {
387 /* dont allow containerref value to be set at the root(NULL, "") of the tree */
388 /* Solaris Kerberos */
389 com_err(progname, EINVAL,
390 gettext("for container reference while creating realm '%s'"),
391 global_params.realm);
392 goto err_nomsg;
393 }
394 rparams->containerref = strdup(argv[i]);
395 if (rparams->containerref == NULL) {
396 retval = ENOMEM;
397 goto cleanup;
398 }
399 mask |= LDAP_REALM_CONTREF;
400 } else if (!strcmp(argv[i], "-sscope")) {
401 if (++i > argc-1)
402 goto err_usage;
403 /* Possible values for search scope are
404 * one (or 1) and sub (or 2)
405 */
406 if (!strcasecmp(argv[i], "one")) {
407 rparams->search_scope = 1;
408 } else if (!strcasecmp(argv[i], "sub")) {
409 rparams->search_scope = 2;
410 } else {
411 rparams->search_scope = atoi(argv[i]);
412 if ((rparams->search_scope != 1) &&
413 (rparams->search_scope != 2)) {
414 /* Solaris Kerberos */
415 com_err(progname, EINVAL,
416 gettext("invalid search scope while creating realm '%s'"),
417 global_params.realm);
418 goto err_nomsg;
419 }
420 }
421 mask |= LDAP_REALM_SEARCHSCOPE;
422 }
423 #ifdef HAVE_EDIRECTORY
424 else if (!strcmp(argv[i], "-kdcdn")) {
425 if (++i > argc-1)
426 goto err_usage;
427 rparams->kdcservers = (char **)malloc(
428 sizeof(char *) * MAX_LIST_ENTRIES);
429 if (rparams->kdcservers == NULL) {
430 retval = ENOMEM;
431 goto cleanup;
432 }
433 memset(rparams->kdcservers, 0, sizeof(char*)*MAX_LIST_ENTRIES);
434 if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER,
435 rparams->kdcservers))) {
436 goto cleanup;
437 }
438 mask |= LDAP_REALM_KDCSERVERS;
439 } else if (!strcmp(argv[i], "-admindn")) {
440 if (++i > argc-1)
441 goto err_usage;
442 rparams->adminservers = (char **)malloc(
443 sizeof(char *) * MAX_LIST_ENTRIES);
444 if (rparams->adminservers == NULL) {
445 retval = ENOMEM;
446 goto cleanup;
447 }
448 memset(rparams->adminservers, 0, sizeof(char*)*MAX_LIST_ENTRIES);
449 if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER,
450 rparams->adminservers))) {
451 goto cleanup;
452 }
453 mask |= LDAP_REALM_ADMINSERVERS;
454 } else if (!strcmp(argv[i], "-pwddn")) {
455 if (++i > argc-1)
456 goto err_usage;
457 rparams->passwdservers = (char **)malloc(
458 sizeof(char *) * MAX_LIST_ENTRIES);
459 if (rparams->passwdservers == NULL) {
460 retval = ENOMEM;
461 goto cleanup;
462 }
463 memset(rparams->passwdservers, 0, sizeof(char*)*MAX_LIST_ENTRIES);
464 if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER,
465 rparams->passwdservers))) {
466 goto cleanup;
467 }
468 mask |= LDAP_REALM_PASSWDSERVERS;
469 }
470 #endif
471 else if (!strcmp(argv[i], "-s")) {
472 do_stash = 1;
473 } else if ((ret_mask= get_ticket_policy(rparams,&i,argv,argc)) !=0) {
474 mask|=ret_mask;
475 }
476
477 else {
478 printf(gettext("'%s' is an invalid option\n"), argv[i]);
479 goto err_usage;
480 }
481 }
482
483 /* If the default enctype/salttype is not provided, use the
484 * default values and also add to the list of supported
485 * enctypes/salttype
486 */
487
488 rblock.max_life = global_params.max_life;
489 rblock.max_rlife = global_params.max_rlife;
490 rblock.expiration = global_params.expiration;
491 rblock.flags = global_params.flags;
492 rblock.nkslist = global_params.num_keysalts;
493 rblock.kslist = global_params.keysalts;
494
495 krb5_princ_set_realm_data(util_context, &db_create_princ, global_params.realm);
496 krb5_princ_set_realm_length(util_context, &db_create_princ, strlen(global_params.realm));
497
498 printf(gettext("Initializing database for realm '%s'\n"), global_params.realm);
499
500 if (!mkey_password) {
501 unsigned int pw_size;
502 printf(gettext("You will be prompted for the database Master Password.\n"));
503 printf(gettext("It is important that you NOT FORGET this password.\n"));
504 fflush(stdout);
505
506 pw_size = sizeof (pw_str);
507 memset(pw_str, 0, pw_size);
508
509 retval = krb5_read_password(util_context, KRB5_KDC_MKEY_1, KRB5_KDC_MKEY_2,
510 pw_str, &pw_size);
511 if (retval) {
512 /* Solaris Kerberos */
513 com_err(progname, retval, gettext("while reading master key from keyboard"));
514 goto err_nomsg;
515 }
516 mkey_password = pw_str;
517 }
518
519 rparams->mkey.enctype = global_params.enctype;
520 /* We are sure that 'mkey_password' is a regular string ... */
521 rparams->mkey.length = strlen(mkey_password) + 1;
522 rparams->mkey.contents = (krb5_octet *)strdup(mkey_password);
523 if (rparams->mkey.contents == NULL) {
524 retval = ENOMEM;
525 goto cleanup;
526 }
527
528 rparams->realm_name = strdup(global_params.realm);
529 if (rparams->realm_name == NULL) {
530 retval = ENOMEM;
531 /* Solaris Kerberos */
532 com_err(progname, ENOMEM, gettext("while creating realm '%s'"),
533 global_params.realm);
534 goto err_nomsg;
535 }
536
537 dal_handle = (kdb5_dal_handle *) util_context->db_context;
538 ldap_context = (krb5_ldap_context *) dal_handle->db_context;
539 if (!ldap_context) {
540 retval = EINVAL;
541 goto cleanup;
542 }
543
544 /* read the kerberos container */
545 if ((retval=krb5_ldap_read_krbcontainer_params (util_context,
546 &(ldap_context->krbcontainer))) == KRB5_KDB_NOENTRY) {
547 /* Prompt the user for entering the DN of Kerberos container */
548 char krb_location[MAX_KRB_CONTAINER_LEN];
549 krb5_ldap_krbcontainer_params kparams;
550 int krb_location_len = 0;
551 memset(&kparams, 0, sizeof(kparams));
552
553 /* Read the kerberos container location from configuration file */
554 if (ldap_context->conf_section) {
555 if ((retval=profile_get_string(util_context->profile,
556 KDB_MODULE_SECTION, ldap_context->conf_section,
557 "ldap_kerberos_container_dn", NULL,
558 &kparams.DN)) != 0) {
559 goto cleanup;
560 }
561 }
562 if (kparams.DN == NULL) {
563 if ((retval=profile_get_string(util_context->profile,
564 KDB_MODULE_DEF_SECTION,
565 "ldap_kerberos_container_dn", NULL,
566 NULL, &kparams.DN)) != 0) {
567 goto cleanup;
568 }
569 }
570
571 printf(gettext("\nKerberos container is missing. Creating now...\n"));
572 if (kparams.DN == NULL) {
573 #ifdef HAVE_EDIRECTORY
574 printf(gettext("Enter DN of Kerberos container [cn=Kerberos,cn=Security]: "));
575 #else
576 printf(gettext("Enter DN of Kerberos container: "));
577 #endif
578 if (fgets(krb_location, MAX_KRB_CONTAINER_LEN, stdin) != NULL) {
579 /* Remove the newline character at the end */
580 krb_location_len = strlen(krb_location);
581 if ((krb_location[krb_location_len - 1] == '\n') ||
582 (krb_location[krb_location_len - 1] == '\r')) {
583 krb_location[krb_location_len - 1] = '\0';
584 krb_location_len--;
585 }
586 /* If the user has not given any input, take the default location */
587 else if (krb_location[0] == '\0')
588 kparams.DN = NULL;
589 else
590 kparams.DN = krb_location;
591 } else
592 kparams.DN = NULL;
593 }
594
595 /* create the kerberos container */
596 retval = krb5_ldap_create_krbcontainer(util_context,
597 ((kparams.DN != NULL) ? &kparams : NULL));
598 if (retval)
599 goto cleanup;
600
601 retval = krb5_ldap_read_krbcontainer_params(util_context,
602 &(ldap_context->krbcontainer));
603 if (retval) {
604 /* Solaris Kerberos */
605 com_err(progname, retval, gettext("while reading kerberos container information"));
606 goto cleanup;
607 }
608 } else if (retval) {
609 /* Solaris Kerberos */
610 com_err(progname, retval, gettext("while reading kerberos container information"));
611 goto cleanup;
612 }
613
614 if ((retval = krb5_ldap_create_realm(util_context,
615 /* global_params.realm, */ rparams, mask))) {
616 goto cleanup;
617 }
618
619 /* We just created the Realm container. Here starts our transaction tracking */
620 realm_obj_created = TRUE;
621
622 if ((retval = krb5_ldap_read_realm_params(util_context,
623 global_params.realm,
624 &(ldap_context->lrparams),
625 &mask))) {
626 /* Solaris Kerberos */
627 com_err(progname, retval, gettext("while reading information of realm '%s'"),
628 global_params.realm);
629 goto err_nomsg;
630 }
631 ldap_context->lrparams->realm_name = strdup(global_params.realm);
632 if (ldap_context->lrparams->realm_name == NULL) {
633 retval = ENOMEM;
634 goto cleanup;
635 }
636
637 /* assemble & parse the master key name */
638 if ((retval = krb5_db_setup_mkey_name(util_context,
639 global_params.mkey_name,
640 global_params.realm,
641 0, &master_princ))) {
642 /* Solaris Kerberos */
643 com_err(progname, retval, gettext("while setting up master key name"));
644 goto err_nomsg;
645 }
646
647 /* Obtain master key from master password */
648 {
649 krb5_data master_salt, pwd;
650
651 pwd.data = mkey_password;
652 pwd.length = strlen(mkey_password);
653 retval = krb5_principal2salt(util_context, master_princ, &master_salt);
654 if (retval) {
655 /* Solaris Kerberos */
656 com_err(progname, retval, gettext("while calculating master key salt"));
657 goto err_nomsg;
658 }
659
660 retval = krb5_c_string_to_key(util_context, rparams->mkey.enctype,
661 &pwd, &master_salt, &master_keyblock);
662
663 if (master_salt.data)
664 free(master_salt.data);
665
666 if (retval) {
667 /* Solaris Kerberos */
668 com_err(progname, retval, gettext("while transforming master key from password"));
669 goto err_nomsg;
670 }
671
672 }
673
674 rblock.key = &master_keyblock;
675 ldap_context->lrparams->mkey = master_keyblock;
676 ldap_context->lrparams->mkey.contents = (krb5_octet *) malloc
677 (master_keyblock.length);
678 if (ldap_context->lrparams->mkey.contents == NULL) {
679 retval = ENOMEM;
680 goto cleanup;
681 }
682 memcpy (ldap_context->lrparams->mkey.contents, master_keyblock.contents,
683 master_keyblock.length);
684
685 /* Create special principals inside the realm subtree */
686 {
687 char princ_name[MAX_PRINC_SIZE];
688 krb5_principal_data tgt_princ = {
689 0, /* magic number */
690 {0, 0, 0}, /* krb5_data realm */
691 tgt_princ_entries, /* krb5_data *data */
692 2, /* int length */
693 KRB5_NT_SRV_INST /* int type */
694 };
695 krb5_principal p, temp_p=NULL;
696
697 krb5_princ_set_realm_data(util_context, &tgt_princ, global_params.realm);
698 krb5_princ_set_realm_length(util_context, &tgt_princ, strlen(global_params.realm));
699 krb5_princ_component(util_context, &tgt_princ,1)->data = global_params.realm;
700 krb5_princ_component(util_context, &tgt_princ,1)->length = strlen(global_params.realm);
701 /* The container reference value is set to NULL, to avoid service principals
702 * getting created within the container reference at realm creation */
703 if (ldap_context->lrparams->containerref != NULL) {
704 oldcontainerref = ldap_context->lrparams->containerref;
705 ldap_context->lrparams->containerref = NULL;
706 }
707
708 /* Create 'K/M' ... */
709 rblock.flags |= KRB5_KDB_DISALLOW_ALL_TIX;
710 if ((retval = kdb_ldap_create_principal(util_context, master_princ, MASTER_KEY, &rblock))) {
711 /* Solaris Kerberos */
712 com_err(progname, retval, gettext("while adding entries to the database"));
713 goto err_nomsg;
714 }
715
716 /* Create 'krbtgt' ... */
717 rblock.flags = 0; /* reset the flags */
718 if ((retval = kdb_ldap_create_principal(util_context, &tgt_princ, TGT_KEY, &rblock))) {
719 /* Solaris Kerberos */
720 com_err(progname, retval, gettext("while adding entries to the database"));
721 goto err_nomsg;
722 }
723 /*
724 * Solaris Kerberos:
725 * The kadmin/admin principal is unused on Solaris. This principal is used
726 * in AUTH_GSSAPI but Solaris doesn't support AUTH_GSSAPI. RPCSEC_GSS can only
727 * be used with host-based principals.
728 *
729 */
730 #if 0 /* ************ Begin IFDEF'ed OUT ***************************** */
731 /* Create 'kadmin/admin' ... */
732 snprintf(princ_name, sizeof(princ_name), "%s@%s", KADM5_ADMIN_SERVICE, global_params.realm);
733 if ((retval = krb5_parse_name(util_context, princ_name, &p))) {
734 /* Solaris Kerberos */
735 com_err(progname, retval, gettext("while adding entries to the database"));
736 goto err_nomsg;
737 }
738 rblock.max_life = ADMIN_LIFETIME;
739 rblock.flags = KRB5_KDB_DISALLOW_TGT_BASED;
740 if ((retval = kdb_ldap_create_principal(util_context, p, TGT_KEY, &rblock))) {
741 krb5_free_principal(util_context, p);
742 /* Solaris Kerberos */
743 com_err(progname, retval, gettext("while adding entries to the database"));
744 goto err_nomsg;
745 }
746 krb5_free_principal(util_context, p);
747 #endif /* ************** END IFDEF'ed OUT ***************************** */
748
749 /* Create 'kadmin/changepw' ... */
750 snprintf(princ_name, sizeof(princ_name), "%s@%s", KADM5_CHANGEPW_SERVICE, global_params.realm);
751 if ((retval = krb5_parse_name(util_context, princ_name, &p))) {
752 /* Solaris Kerberos */
753 com_err(progname, retval, gettext("while adding entries to the database"));
754 goto err_nomsg;
755 }
756 rblock.max_life = CHANGEPW_LIFETIME;
757 rblock.flags = KRB5_KDB_DISALLOW_TGT_BASED | KRB5_KDB_PWCHANGE_SERVICE;
758 if ((retval = kdb_ldap_create_principal(util_context, p, TGT_KEY, &rblock))) {
759 krb5_free_principal(util_context, p);
760 /* Solaris Kerberos */
761 com_err(progname, retval, gettext("while adding entries to the database"));
762 goto err_nomsg;
763 }
764 krb5_free_principal(util_context, p);
765
766 /* Create 'kadmin/history' ... */
767 snprintf(princ_name, sizeof(princ_name), "%s@%s", KADM5_HIST_PRINCIPAL, global_params.realm);
768 if ((retval = krb5_parse_name(util_context, princ_name, &p))) {
769 /* Solaris Kerberos */
770 com_err(progname, retval, gettext("while adding entries to the database"));
771 goto err_nomsg;
772 }
773 rblock.max_life = global_params.max_life;
774 rblock.flags = 0;
775 if ((retval = kdb_ldap_create_principal(util_context, p, TGT_KEY, &rblock))) {
776 krb5_free_principal(util_context, p);
777 /* Solaris Kerberos */
778 com_err(progname, retval, gettext("while adding entries to the database"));
779 goto err_nomsg;
780 }
781 krb5_free_principal(util_context, p);
782
783 /* Create 'kadmin/<hostname>' ... */
784 if ((retval=krb5_sname_to_principal(util_context, NULL, KADM5_ADMIN_HOST_SERVICE, KRB5_NT_SRV_HST, &p))) {
785 /* Solaris Kerberos */
786 com_err(progname, retval, gettext("krb5_sname_to_principal, while adding entries to the database"));
787 goto err_nomsg;
788 }
789
790 if ((retval=krb5_copy_principal(util_context, p, &temp_p))) {
791 /* Solaris Kerberos */
792 com_err(progname, retval, gettext("krb5_copy_principal, while adding entries to the database"));
793 goto err_nomsg;
794 }
795
796 /* change the realm portion to the default realm */
797 free(temp_p->realm.data);
798 temp_p->realm.length = strlen(util_context->default_realm);
799 temp_p->realm.data = strdup(util_context->default_realm);
800 if (temp_p->realm.data == NULL) {
801 /* Solaris Kerberos */
802 com_err(progname, ENOMEM, gettext("while adding entries to the database"));
803 goto err_nomsg;
804 }
805
806 rblock.max_life = ADMIN_LIFETIME;
807 rblock.flags = KRB5_KDB_DISALLOW_TGT_BASED;
808 if ((retval = kdb_ldap_create_principal(util_context, temp_p, TGT_KEY, &rblock))) {
809 krb5_free_principal(util_context, p);
810 /* Solaris Kerberos */
811 com_err(progname, retval, gettext("while adding entries to the database"));
812 goto err_nomsg;
813 }
814 krb5_free_principal(util_context, temp_p);
815 krb5_free_principal(util_context, p);
816
817 /* Solaris Kerberos: Create 'changepw/<hostname>' ... */
818 if ((retval=krb5_sname_to_principal(util_context, NULL, KADM5_CHANGEPW_HOST_SERVICE, KRB5_NT_SRV_HST, &p))) {
819 /* Solaris Kerberos */
820 com_err(progname, retval, gettext("krb5_sname_to_principal, while adding entries to the database"));
821 goto err_nomsg;
822 }
823
824 if ((retval=krb5_copy_principal(util_context, p, &temp_p))) {
825 /* Solaris Kerberos */
826 com_err(progname, retval, gettext("krb5_copy_principal, while adding entries to the database"));
827 goto err_nomsg;
828 }
829
830 /* change the realm portion to the default realm */
831 free(temp_p->realm.data);
832 temp_p->realm.length = strlen(util_context->default_realm);
833 temp_p->realm.data = strdup(util_context->default_realm);
834 if (temp_p->realm.data == NULL) {
835 /* Solaris Kerberos */
836 com_err(progname, ENOMEM, gettext("while adding entries to the database"));
837 goto err_nomsg;
838 }
839
840 rblock.max_life = ADMIN_LIFETIME;
841 rblock.flags = KRB5_KDB_DISALLOW_TGT_BASED | KRB5_KDB_PWCHANGE_SERVICE;
842 if ((retval = kdb_ldap_create_principal(util_context, temp_p, TGT_KEY, &rblock))) {
843 krb5_free_principal(util_context, p);
844 /* Solaris Kerberos */
845 com_err(progname, retval, gettext("while adding entries to the database"));
846 goto err_nomsg;
847 }
848 krb5_free_principal(util_context, temp_p);
849 krb5_free_principal(util_context, p);
850
851 if (oldcontainerref != NULL) {
852 ldap_context->lrparams->containerref = oldcontainerref;
853 oldcontainerref=NULL;
854 }
855 }
856
857 #ifdef HAVE_EDIRECTORY
858 if ((mask & LDAP_REALM_KDCSERVERS) || (mask & LDAP_REALM_ADMINSERVERS) ||
859 (mask & LDAP_REALM_PASSWDSERVERS)) {
860
861 printf(gettext("Changing rights for the service object. Please wait ... "));
862 fflush(stdout);
863
864 rightsmask =0;
865 rightsmask |= LDAP_REALM_RIGHTS;
866 rightsmask |= LDAP_SUBTREE_RIGHTS;
867 if ((rparams != NULL) && (rparams->kdcservers != NULL)) {
868 for (i=0; (rparams->kdcservers[i] != NULL); i++) {
869 if ((retval=krb5_ldap_add_service_rights(util_context,
870 LDAP_KDC_SERVICE, rparams->kdcservers[i],
871 rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
872 printf(gettext("failed\n"));
873 /* Solaris Kerberos */
874 com_err(progname, retval, gettext("while assigning rights to '%s'"),
875 rparams->realm_name);
876 goto err_nomsg;
877 }
878 }
879 }
880
881 rightsmask = 0;
882 rightsmask |= LDAP_REALM_RIGHTS;
883 rightsmask |= LDAP_SUBTREE_RIGHTS;
884 if ((rparams != NULL) && (rparams->adminservers != NULL)) {
885 for (i=0; (rparams->adminservers[i] != NULL); i++) {
886 if ((retval=krb5_ldap_add_service_rights(util_context,
887 LDAP_ADMIN_SERVICE, rparams->adminservers[i],
888 rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
889 printf(gettext("failed\n"));
890 /* Solaris Kerberos */
891 com_err(progname, retval, gettext("while assigning rights to '%s'"),
892 rparams->realm_name);
893 goto err_nomsg;
894 }
895 }
896 }
897
898 rightsmask = 0;
899 rightsmask |= LDAP_REALM_RIGHTS;
900 rightsmask |= LDAP_SUBTREE_RIGHTS;
901 if ((rparams != NULL) && (rparams->passwdservers != NULL)) {
902 for (i=0; (rparams->passwdservers[i] != NULL); i++) {
903 if ((retval=krb5_ldap_add_service_rights(util_context,
904 LDAP_PASSWD_SERVICE, rparams->passwdservers[i],
905 rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
906 printf(gettext("failed\n"));
907 /* Solaris Kerberos */
908 com_err(progname, retval, gettext("while assigning rights to '%s'"),
909 rparams->realm_name);
910 goto err_nomsg;
911 }
912 }
913 }
914
915 printf(gettext("done\n"));
916 }
917 #endif
918 /* The Realm creation is completed. Here is the end of transaction */
919 create_complete = TRUE;
920
921 /* Stash the master key only if '-s' option is specified */
922 if (do_stash || global_params.mask & KADM5_CONFIG_STASH_FILE) {
923 retval = krb5_def_store_mkey(util_context,
924 global_params.stash_file,
925 master_princ,
926 &master_keyblock, NULL);
927 if (retval) {
928 /* Solaris Kerberos */
929 com_err(progname, errno, gettext("while storing key"));
930 printf(gettext("Warning: couldn't stash master key.\n"));
931 }
932 }
933
934 goto cleanup;
935
936
937 err_usage:
938 print_usage = TRUE;
939
940 err_nomsg:
941 no_msg = TRUE;
942
943 cleanup:
944 /* If the Realm creation is not complete, do the roll-back here */
945 if ((realm_obj_created) && (!create_complete))
946 krb5_ldap_delete_realm(util_context, global_params.realm);
947
948 if (rparams)
949 krb5_ldap_free_realm_params(rparams);
950
951 memset (pw_str, 0, sizeof (pw_str));
952
953 if (print_usage)
954 db_usage(CREATE_REALM);
955
956 if (retval) {
957 if (!no_msg) {
958 /* Solaris Kerberos */
959 com_err(progname, retval, gettext("while creating realm '%s'"),
960 global_params.realm);
961 }
962 exit_status++;
963 }
964
965 return;
966 }
967
968
969 /*
970 * This function will modify the attributes of a given realm object
971 */
kdb5_ldap_modify(argc,argv)972 void kdb5_ldap_modify(argc, argv)
973 int argc;
974 char *argv[];
975 {
976 krb5_error_code retval = 0;
977 krb5_ldap_realm_params *rparams = NULL;
978 krb5_boolean print_usage = FALSE;
979 krb5_boolean no_msg = FALSE;
980 kdb5_dal_handle *dal_handle = NULL;
981 krb5_ldap_context *ldap_context=NULL;
982 int i = 0;
983 int mask = 0, rmask = 0, ret_mask = 0;
984 char **slist = {NULL};
985 #ifdef HAVE_EDIRECTORY
986 int j = 0;
987 char *list[MAX_LIST_ENTRIES];
988 int existing_entries = 0, list_entries = 0;
989 int newkdcdn = 0, newadmindn = 0, newpwddn = 0;
990 char **tempstr = NULL;
991 char **oldkdcdns = NULL;
992 char **oldadmindns = NULL;
993 char **oldpwddns = NULL;
994 char **newkdcdns = NULL;
995 char **newsubtrees = NULL;
996 char **newadmindns = NULL;
997 char **newpwddns = NULL;
998 char **oldsubtrees = {NULL};
999 int rightsmask = 0;
1000 int subtree_changed = 0;
1001 #endif
1002
1003 dal_handle = (kdb5_dal_handle *) util_context->db_context;
1004 ldap_context = (krb5_ldap_context *) dal_handle->db_context;
1005 if (!(ldap_context)) {
1006 retval = EINVAL;
1007 goto cleanup;
1008 }
1009
1010 if ((retval = krb5_ldap_read_krbcontainer_params(util_context,
1011 &(ldap_context->krbcontainer)))) {
1012 /* Solaris Kerberos */
1013 com_err(progname, retval, gettext("while reading Kerberos container information"));
1014 goto err_nomsg;
1015 }
1016
1017 retval = krb5_ldap_read_realm_params(util_context,
1018 global_params.realm, &rparams, &rmask);
1019 if (retval)
1020 goto cleanup;
1021 /* Parse the arguments */
1022 for (i = 1; i < argc; i++) {
1023 int k = 0;
1024 if (!strcmp(argv[i], "-subtrees")) {
1025 if (++i > argc-1)
1026 goto err_usage;
1027
1028 if (rmask & LDAP_REALM_SUBTREE) {
1029 if (rparams->subtree) {
1030 #ifdef HAVE_EDIRECTORY
1031 oldsubtrees = (char **) calloc(rparams->subtreecount+1, sizeof(char *));
1032 if (oldsubtrees == NULL) {
1033 retval = ENOMEM;
1034 goto cleanup;
1035 }
1036 for(k=0; rparams->subtree[k]!=NULL && rparams->subtreecount; k++) {
1037 oldsubtrees[k] = strdup(rparams->subtree[k]);
1038 if( oldsubtrees[k] == NULL ) {
1039 retval = ENOMEM;
1040 goto cleanup;
1041 }
1042 }
1043 #endif
1044 for(k=0; k<rparams->subtreecount && rparams->subtree[k]; k++)
1045 free(rparams->subtree[k]);
1046 rparams->subtreecount=0;
1047 }
1048 }
1049 if (strncmp(argv[i] ,"", strlen(argv[i]))!=0) {
1050 slist = (char **) calloc(MAX_LIST_ENTRIES, sizeof(char *));
1051 if (slist == NULL) {
1052 retval = ENOMEM;
1053 goto cleanup;
1054 }
1055 if (( retval = krb5_parse_list(argv[i], LIST_DELIMITER, slist))) {
1056 free(slist);
1057 slist = NULL;
1058 goto cleanup;
1059 }
1060
1061 rparams->subtreecount=0;
1062 while(slist[rparams->subtreecount]!=NULL)
1063 (rparams->subtreecount)++;
1064 rparams->subtree = slist;
1065 } else if(strncmp(argv[i], "", strlen(argv[i]))==0) {
1066 /* dont allow subtree value to be set at the root(NULL, "") of the tree */
1067 /* Solaris Kerberos */
1068 com_err(progname, EINVAL,
1069 gettext("for subtree while modifying realm '%s'"),
1070 global_params.realm);
1071 goto err_nomsg;
1072 }
1073 rparams->subtree[rparams->subtreecount] = NULL;
1074 mask |= LDAP_REALM_SUBTREE;
1075 } else if (!strncmp(argv[i], "-containerref", strlen(argv[i]))) {
1076 if (++i > argc-1)
1077 goto err_usage;
1078 if(strncmp(argv[i], "", strlen(argv[i]))==0) {
1079 /* dont allow containerref value to be set at the root(NULL, "") of the tree */
1080 /* Solaris Kerberos */
1081 com_err(progname, EINVAL,
1082 gettext("for container reference while modifying realm '%s'"),
1083 global_params.realm);
1084 goto err_nomsg;
1085 }
1086 rparams->containerref = strdup(argv[i]);
1087 if (rparams->containerref == NULL) {
1088 retval = ENOMEM;
1089 goto cleanup;
1090 }
1091 mask |= LDAP_REALM_CONTREF;
1092 } else if (!strcmp(argv[i], "-sscope")) {
1093 if (++i > argc-1)
1094 goto err_usage;
1095 /* Possible values for search scope are
1096 * one (or 1) and sub (or 2)
1097 */
1098 if (strcasecmp(argv[i], "one") == 0) {
1099 rparams->search_scope = 1;
1100 } else if (strcasecmp(argv[i], "sub") == 0) {
1101 rparams->search_scope = 2;
1102 } else {
1103 rparams->search_scope = atoi(argv[i]);
1104 if ((rparams->search_scope != 1) &&
1105 (rparams->search_scope != 2)) {
1106 retval = EINVAL;
1107 /* Solaris Kerberos */
1108 com_err(progname, retval,
1109 gettext("specified for search scope while modifying information of realm '%s'"),
1110 global_params.realm);
1111 goto err_nomsg;
1112 }
1113 }
1114 mask |= LDAP_REALM_SEARCHSCOPE;
1115 }
1116 #ifdef HAVE_EDIRECTORY
1117 else if (!strcmp(argv[i], "-kdcdn")) {
1118 if (++i > argc-1)
1119 goto err_usage;
1120
1121 if ((rmask & LDAP_REALM_KDCSERVERS) && (rparams->kdcservers)) {
1122 if (!oldkdcdns) {
1123 /* Store the old kdc dns list for removing rights */
1124 oldkdcdns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
1125 if (oldkdcdns == NULL) {
1126 retval = ENOMEM;
1127 goto cleanup;
1128 }
1129
1130 for (j=0; rparams->kdcservers[j] != NULL; j++) {
1131 oldkdcdns[j] = strdup(rparams->kdcservers[j]);
1132 if (oldkdcdns[j] == NULL) {
1133 retval = ENOMEM;
1134 goto cleanup;
1135 }
1136 }
1137 oldkdcdns[j] = NULL;
1138 }
1139
1140 krb5_free_list_entries(rparams->kdcservers);
1141 free(rparams->kdcservers);
1142 }
1143
1144 rparams->kdcservers = (char **)malloc(
1145 sizeof(char *) * MAX_LIST_ENTRIES);
1146 if (rparams->kdcservers == NULL) {
1147 retval = ENOMEM;
1148 goto cleanup;
1149 }
1150 memset(rparams->kdcservers, 0, sizeof(char *)*MAX_LIST_ENTRIES);
1151 if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER,
1152 rparams->kdcservers))) {
1153 goto cleanup;
1154 }
1155 mask |= LDAP_REALM_KDCSERVERS;
1156 /* Going to replace the existing value by this new value. Hence
1157 * setting flag indicating that add or clear options will be ignored
1158 */
1159 newkdcdn = 1;
1160 } else if (!strcmp(argv[i], "-clearkdcdn")) {
1161 if (++i > argc-1)
1162 goto err_usage;
1163 if ((!newkdcdn) && (rmask & LDAP_REALM_KDCSERVERS) && (rparams->kdcservers)) {
1164 if (!oldkdcdns) {
1165 /* Store the old kdc dns list for removing rights */
1166 oldkdcdns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
1167 if (oldkdcdns == NULL) {
1168 retval = ENOMEM;
1169 goto cleanup;
1170 }
1171
1172 for (j=0; rparams->kdcservers[j] != NULL; j++) {
1173 oldkdcdns[j] = strdup(rparams->kdcservers[j]);
1174 if (oldkdcdns[j] == NULL) {
1175 retval = ENOMEM;
1176 goto cleanup;
1177 }
1178 }
1179 oldkdcdns[j] = NULL;
1180 }
1181
1182 memset(list, 0, sizeof(char *) * MAX_LIST_ENTRIES);
1183 if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
1184 goto cleanup;
1185 }
1186 list_modify_str_array(&rparams->kdcservers, (const char **)list,
1187 LIST_MODE_DELETE);
1188 mask |= LDAP_REALM_KDCSERVERS;
1189 krb5_free_list_entries(list);
1190 }
1191 } else if (!strcmp(argv[i], "-addkdcdn")) {
1192 if (++i > argc-1)
1193 goto err_usage;
1194 if (!newkdcdn) {
1195 if ((rmask & LDAP_REALM_KDCSERVERS) && (rparams->kdcservers) && (!oldkdcdns)) {
1196 /* Store the old kdc dns list for removing rights */
1197 oldkdcdns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
1198 if (oldkdcdns == NULL) {
1199 retval = ENOMEM;
1200 goto cleanup;
1201 }
1202
1203 for (j = 0; rparams->kdcservers[j] != NULL; j++) {
1204 oldkdcdns[j] = strdup(rparams->kdcservers[j]);
1205 if (oldkdcdns[j] == NULL) {
1206 retval = ENOMEM;
1207 goto cleanup;
1208 }
1209 }
1210 oldkdcdns[j] = NULL;
1211 }
1212
1213 memset(list, 0, sizeof(char *) * MAX_LIST_ENTRIES);
1214 if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
1215 goto cleanup;
1216 }
1217 existing_entries = list_count_str_array(rparams->kdcservers);
1218 list_entries = list_count_str_array(list);
1219 if (rmask & LDAP_REALM_KDCSERVERS) {
1220 tempstr = (char **)realloc(
1221 rparams->kdcservers,
1222 sizeof(char *) * (existing_entries+list_entries+1));
1223 if (tempstr == NULL) {
1224 retval = ENOMEM;
1225 goto cleanup;
1226 }
1227 rparams->kdcservers = tempstr;
1228 } else {
1229 rparams->kdcservers = (char **)malloc(sizeof(char *) * (list_entries+1));
1230 if (rparams->kdcservers == NULL) {
1231 retval = ENOMEM;
1232 goto cleanup;
1233 }
1234 memset(rparams->kdcservers, 0, sizeof(char *) * (list_entries+1));
1235 }
1236 list_modify_str_array(&rparams->kdcservers, (const char **)list,
1237 LIST_MODE_ADD);
1238 mask |= LDAP_REALM_KDCSERVERS;
1239 }
1240 } else if (!strcmp(argv[i], "-admindn")) {
1241 if (++i > argc-1)
1242 goto err_usage;
1243
1244 if ((rmask & LDAP_REALM_ADMINSERVERS) && (rparams->adminservers)) {
1245 if (!oldadmindns) {
1246 /* Store the old admin dns list for removing rights */
1247 oldadmindns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
1248 if (oldadmindns == NULL) {
1249 retval = ENOMEM;
1250 goto cleanup;
1251 }
1252
1253 for (j=0; rparams->adminservers[j] != NULL; j++) {
1254 oldadmindns[j] = strdup(rparams->adminservers[j]);
1255 if (oldadmindns[j] == NULL) {
1256 retval = ENOMEM;
1257 goto cleanup;
1258 }
1259 }
1260 oldadmindns[j] = NULL;
1261 }
1262
1263 krb5_free_list_entries(rparams->adminservers);
1264 free(rparams->adminservers);
1265 }
1266
1267 rparams->adminservers = (char **)malloc(
1268 sizeof(char *) * MAX_LIST_ENTRIES);
1269 if (rparams->adminservers == NULL) {
1270 retval = ENOMEM;
1271 goto cleanup;
1272 }
1273 memset(rparams->adminservers, 0, sizeof(char *)*MAX_LIST_ENTRIES);
1274 if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER,
1275 rparams->adminservers))) {
1276 goto cleanup;
1277 }
1278 mask |= LDAP_REALM_ADMINSERVERS;
1279 /* Going to replace the existing value by this new value. Hence
1280 * setting flag indicating that add or clear options will be ignored
1281 */
1282 newadmindn = 1;
1283 } else if (!strcmp(argv[i], "-clearadmindn")) {
1284 if (++i > argc-1)
1285 goto err_usage;
1286
1287 if ((!newadmindn) && (rmask & LDAP_REALM_ADMINSERVERS) && (rparams->adminservers)) {
1288 if (!oldadmindns) {
1289 /* Store the old admin dns list for removing rights */
1290 oldadmindns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
1291 if (oldadmindns == NULL) {
1292 retval = ENOMEM;
1293 goto cleanup;
1294 }
1295
1296 for (j=0; rparams->adminservers[j] != NULL; j++) {
1297 oldadmindns[j] = strdup(rparams->adminservers[j]);
1298 if (oldadmindns[j] == NULL) {
1299 retval = ENOMEM;
1300 goto cleanup;
1301 }
1302 }
1303 oldadmindns[j] = NULL;
1304 }
1305
1306 memset(list, 0, sizeof(char *) * MAX_LIST_ENTRIES);
1307 if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
1308 goto cleanup;
1309 }
1310 list_modify_str_array(&rparams->adminservers, (const char **)list,
1311 LIST_MODE_DELETE);
1312 mask |= LDAP_REALM_ADMINSERVERS;
1313 krb5_free_list_entries(list);
1314 }
1315 } else if (!strcmp(argv[i], "-addadmindn")) {
1316 if (++i > argc-1)
1317 goto err_usage;
1318 if (!newadmindn) {
1319 if ((rmask & LDAP_REALM_ADMINSERVERS) && (rparams->adminservers) && (!oldadmindns)) {
1320 /* Store the old admin dns list for removing rights */
1321 oldadmindns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
1322 if (oldadmindns == NULL) {
1323 retval = ENOMEM;
1324 goto cleanup;
1325 }
1326
1327 for (j=0; rparams->adminservers[j] != NULL; j++) {
1328 oldadmindns[j] = strdup(rparams->adminservers[j]);
1329 if (oldadmindns[j] == NULL) {
1330 retval = ENOMEM;
1331 goto cleanup;
1332 }
1333 }
1334 oldadmindns[j] = NULL;
1335 }
1336
1337 memset(list, 0, sizeof(char *) * MAX_LIST_ENTRIES);
1338 if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
1339 goto cleanup;
1340 }
1341 existing_entries = list_count_str_array(rparams->adminservers);
1342 list_entries = list_count_str_array(list);
1343 if (rmask & LDAP_REALM_ADMINSERVERS) {
1344 tempstr = (char **)realloc(
1345 rparams->adminservers,
1346 sizeof(char *) * (existing_entries+list_entries+1));
1347 if (tempstr == NULL) {
1348 retval = ENOMEM;
1349 goto cleanup;
1350 }
1351 rparams->adminservers = tempstr;
1352 } else {
1353 rparams->adminservers = (char **)malloc(sizeof(char *) * (list_entries+1));
1354 if (rparams->adminservers == NULL) {
1355 retval = ENOMEM;
1356 goto cleanup;
1357 }
1358 memset(rparams->adminservers, 0, sizeof(char *) * (list_entries+1));
1359 }
1360 list_modify_str_array(&rparams->adminservers, (const char **)list,
1361 LIST_MODE_ADD);
1362 mask |= LDAP_REALM_ADMINSERVERS;
1363 }
1364 } else if (!strcmp(argv[i], "-pwddn")) {
1365 if (++i > argc-1)
1366 goto err_usage;
1367
1368 if ((rmask & LDAP_REALM_PASSWDSERVERS) && (rparams->passwdservers)) {
1369 if (!oldpwddns) {
1370 /* Store the old pwd dns list for removing rights */
1371 oldpwddns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
1372 if (oldpwddns == NULL) {
1373 retval = ENOMEM;
1374 goto cleanup;
1375 }
1376
1377 for (j=0; rparams->passwdservers[j] != NULL; j++) {
1378 oldpwddns[j] = strdup(rparams->passwdservers[j]);
1379 if (oldpwddns[j] == NULL) {
1380 retval = ENOMEM;
1381 goto cleanup;
1382 }
1383 }
1384 oldpwddns[j] = NULL;
1385 }
1386
1387 krb5_free_list_entries(rparams->passwdservers);
1388 free(rparams->passwdservers);
1389 }
1390
1391 rparams->passwdservers = (char **)malloc(
1392 sizeof(char *) * MAX_LIST_ENTRIES);
1393 if (rparams->passwdservers == NULL) {
1394 retval = ENOMEM;
1395 goto cleanup;
1396 }
1397 memset(rparams->passwdservers, 0, sizeof(char *)*MAX_LIST_ENTRIES);
1398 if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER,
1399 rparams->passwdservers))) {
1400 goto cleanup;
1401 }
1402 mask |= LDAP_REALM_PASSWDSERVERS;
1403 /* Going to replace the existing value by this new value. Hence
1404 * setting flag indicating that add or clear options will be ignored
1405 */
1406 newpwddn = 1;
1407 } else if (!strcmp(argv[i], "-clearpwddn")) {
1408 if (++i > argc-1)
1409 goto err_usage;
1410
1411 if ((!newpwddn) && (rmask & LDAP_REALM_PASSWDSERVERS) && (rparams->passwdservers)) {
1412 if (!oldpwddns) {
1413 /* Store the old pwd dns list for removing rights */
1414 oldpwddns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
1415 if (oldpwddns == NULL) {
1416 retval = ENOMEM;
1417 goto cleanup;
1418 }
1419
1420 for (j=0; rparams->passwdservers[j] != NULL; j++) {
1421 oldpwddns[j] = strdup(rparams->passwdservers[j]);
1422 if (oldpwddns[j] == NULL) {
1423 retval = ENOMEM;
1424 goto cleanup;
1425 }
1426 }
1427 oldpwddns[j] = NULL;
1428 }
1429
1430 memset(list, 0, sizeof(char *) * MAX_LIST_ENTRIES);
1431 if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
1432 goto cleanup;
1433 }
1434 list_modify_str_array(&rparams->passwdservers, (const char**)list,
1435 LIST_MODE_DELETE);
1436 mask |= LDAP_REALM_PASSWDSERVERS;
1437 krb5_free_list_entries(list);
1438 }
1439 } else if (!strcmp(argv[i], "-addpwddn")) {
1440 if (++i > argc-1)
1441 goto err_usage;
1442 if (!newpwddn) {
1443 if ((rmask & LDAP_REALM_PASSWDSERVERS) && (rparams->passwdservers) && (!oldpwddns)) {
1444 /* Store the old pwd dns list for removing rights */
1445 oldpwddns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
1446 if (oldpwddns == NULL) {
1447 retval = ENOMEM;
1448 goto cleanup;
1449 }
1450
1451 for (j=0; rparams->passwdservers[j] != NULL; j++) {
1452 oldpwddns[j] = strdup(rparams->passwdservers[j]);
1453 if (oldpwddns[j] == NULL) {
1454 retval = ENOMEM;
1455 goto cleanup;
1456 }
1457 }
1458 oldpwddns[j] = NULL;
1459 }
1460
1461 memset(list, 0, sizeof(char *) * MAX_LIST_ENTRIES);
1462 if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
1463 goto cleanup;
1464 }
1465 existing_entries = list_count_str_array(rparams->passwdservers);
1466 list_entries = list_count_str_array(list);
1467 if (rmask & LDAP_REALM_PASSWDSERVERS) {
1468 tempstr = (char **)realloc(
1469 rparams->passwdservers,
1470 sizeof(char *) * (existing_entries+list_entries+1));
1471 if (tempstr == NULL) {
1472 retval = ENOMEM;
1473 goto cleanup;
1474 }
1475 rparams->passwdservers = tempstr;
1476 } else {
1477 rparams->passwdservers = (char **)malloc(sizeof(char *) * (list_entries+1));
1478 if (rparams->passwdservers == NULL) {
1479 retval = ENOMEM;
1480 goto cleanup;
1481 }
1482 memset(rparams->passwdservers, 0, sizeof(char *) * (list_entries+1));
1483 }
1484 list_modify_str_array(&rparams->passwdservers, (const char**)list,
1485 LIST_MODE_ADD);
1486 mask |= LDAP_REALM_PASSWDSERVERS;
1487 }
1488 }
1489 #endif
1490 else if ((ret_mask= get_ticket_policy(rparams,&i,argv,argc)) !=0) {
1491 mask|=ret_mask;
1492 } else {
1493 printf(gettext("'%s' is an invalid option\n"), argv[i]);
1494 goto err_usage;
1495 }
1496 }
1497
1498 if ((retval = krb5_ldap_modify_realm(util_context,
1499 /* global_params.realm, */ rparams, mask))) {
1500 goto cleanup;
1501 }
1502
1503 #ifdef HAVE_EDIRECTORY
1504 if ((mask & LDAP_REALM_SUBTREE) || (mask & LDAP_REALM_KDCSERVERS) ||
1505 (mask & LDAP_REALM_ADMINSERVERS) || (mask & LDAP_REALM_PASSWDSERVERS)) {
1506
1507 printf(gettext("Changing rights for the service object. Please wait ... "));
1508 fflush(stdout);
1509
1510 if (!(mask & LDAP_REALM_SUBTREE)) {
1511 if (rparams->subtree != NULL) {
1512 for(i=0; rparams->subtree[i]!=NULL;i++) {
1513 oldsubtrees[i] = strdup(rparams->subtree[i]);
1514 if( oldsubtrees[i] == NULL ) {
1515 retval = ENOMEM;
1516 goto cleanup;
1517 }
1518 }
1519 }
1520 }
1521
1522 if ((mask & LDAP_REALM_SUBTREE)) {
1523 int check_subtree = 1;
1524
1525 newsubtrees = (char**) calloc(rparams->subtreecount, sizeof(char*));
1526
1527 if (newsubtrees == NULL) {
1528 retval = ENOMEM;
1529 goto cleanup;
1530 }
1531
1532 if ( (rparams != NULL) && (rparams->subtree != NULL) ) {
1533 for (j=0; j<rparams->subtreecount && rparams->subtree[j]!= NULL; j++) {
1534 newsubtrees[j] = strdup(rparams->subtree[j]);
1535 if (newsubtrees[j] == NULL) {
1536 retval = ENOMEM;
1537 goto cleanup;
1538 }
1539 }
1540 newsubtrees[j] = NULL;
1541 }
1542 for(j=0;oldsubtrees[j]!=NULL;j++) {
1543 check_subtree = 1;
1544 for(i=0; ( (oldsubtrees[j] && !rparams->subtree[i]) ||
1545 (!oldsubtrees[j] && rparams->subtree[i])); i++) {
1546 if(strcasecmp( oldsubtrees[j], rparams->subtree[i]) == 0) {
1547 check_subtree = 0;
1548 continue;
1549 }
1550 }
1551 if (check_subtree != 0) {
1552 subtree_changed=1;
1553 break;
1554 }
1555 }
1556 /* this will return list of the disjoint members */
1557 disjoint_members( oldsubtrees, newsubtrees);
1558 }
1559
1560 if ((mask & LDAP_REALM_SUBTREE) || (mask & LDAP_REALM_KDCSERVERS)) {
1561
1562 newkdcdns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
1563 if (newkdcdns == NULL) {
1564 retval = ENOMEM;
1565 goto cleanup;
1566 }
1567
1568 if ((rparams != NULL) && (rparams->kdcservers != NULL)) {
1569 for (j=0; rparams->kdcservers[j]!= NULL; j++) {
1570 newkdcdns[j] = strdup(rparams->kdcservers[j]);
1571 if (newkdcdns[j] == NULL) {
1572 retval = ENOMEM;
1573 goto cleanup;
1574 }
1575 }
1576 newkdcdns[j] = NULL;
1577 }
1578
1579 if (!subtree_changed) {
1580 disjoint_members(oldkdcdns, newkdcdns);
1581 } else { /* Only the subtrees was changed. Remove the rights on the old subtrees. */
1582 if (!(mask & LDAP_REALM_KDCSERVERS)) {
1583
1584 oldkdcdns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
1585 if (oldkdcdns == NULL) {
1586 retval = ENOMEM;
1587 goto cleanup;
1588 }
1589
1590 if ((rparams != NULL) && (rparams->kdcservers != NULL)) {
1591 for (j=0; rparams->kdcservers[j]!= NULL; j++) {
1592 oldkdcdns[j] = strdup(rparams->kdcservers[j]);
1593 if (oldkdcdns[j] == NULL) {
1594 retval = ENOMEM;
1595 goto cleanup;
1596 }
1597 }
1598 oldkdcdns[j] = NULL;
1599 }
1600 }
1601 }
1602
1603 rightsmask =0;
1604 rightsmask |= LDAP_REALM_RIGHTS;
1605 rightsmask |= LDAP_SUBTREE_RIGHTS;
1606 /* Remove the rights on the old subtrees */
1607 if (oldkdcdns) {
1608 for (i=0; (oldkdcdns[i] != NULL); i++) {
1609 if ((retval=krb5_ldap_delete_service_rights(util_context,
1610 LDAP_KDC_SERVICE, oldkdcdns[i],
1611 rparams->realm_name, oldsubtrees, rightsmask)) != 0) {
1612 printf(gettext("failed\n"));
1613 /* Solaris Kerberos */
1614 com_err(progname, retval, gettext("while assigning rights '%s'"),
1615 rparams->realm_name);
1616 goto err_nomsg;
1617 }
1618 }
1619 }
1620
1621 rightsmask =0;
1622 rightsmask |= LDAP_REALM_RIGHTS;
1623 rightsmask |= LDAP_SUBTREE_RIGHTS;
1624 if (newkdcdns) {
1625 for (i=0; (newkdcdns[i] != NULL); i++) {
1626
1627 if ((retval=krb5_ldap_add_service_rights(util_context,
1628 LDAP_KDC_SERVICE, newkdcdns[i], rparams->realm_name,
1629 rparams->subtree, rightsmask)) != 0) {
1630 printf(gettext("failed\n"));
1631 /* Solaris Kerberos */
1632 com_err(progname, retval, gettext("while assigning rights to '%s'"),
1633 rparams->realm_name);
1634 goto err_nomsg;
1635 }
1636 }
1637 }
1638 }
1639
1640 if ((mask & LDAP_REALM_SUBTREE) || (mask & LDAP_REALM_ADMINSERVERS)) {
1641
1642 newadmindns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
1643 if (newadmindns == NULL) {
1644 retval = ENOMEM;
1645 goto cleanup;
1646 }
1647
1648 if ((rparams != NULL) && (rparams->adminservers != NULL)) {
1649 for (j=0; rparams->adminservers[j]!= NULL; j++) {
1650 newadmindns[j] = strdup(rparams->adminservers[j]);
1651 if (newadmindns[j] == NULL) {
1652 retval = ENOMEM;
1653 goto cleanup;
1654 }
1655 }
1656 newadmindns[j] = NULL;
1657 }
1658
1659 if (!subtree_changed) {
1660 disjoint_members(oldadmindns, newadmindns);
1661 } else { /* Only the subtrees was changed. Remove the rights on the old subtrees. */
1662 if (!(mask & LDAP_REALM_ADMINSERVERS)) {
1663
1664 oldadmindns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
1665 if (oldadmindns == NULL) {
1666 retval = ENOMEM;
1667 goto cleanup;
1668 }
1669
1670 if ((rparams != NULL) && (rparams->adminservers != NULL)) {
1671 for (j=0; rparams->adminservers[j]!= NULL; j++) {
1672 oldadmindns[j] = strdup(rparams->adminservers[j]);
1673 if (oldadmindns[j] == NULL) {
1674 retval = ENOMEM;
1675 goto cleanup;
1676 }
1677 }
1678 oldadmindns[j] = NULL;
1679 }
1680 }
1681 }
1682
1683 rightsmask = 0;
1684 rightsmask |= LDAP_REALM_RIGHTS;
1685 rightsmask |= LDAP_SUBTREE_RIGHTS;
1686 /* Remove the rights on the old subtrees */
1687 if (oldadmindns) {
1688 for (i=0; (oldadmindns[i] != NULL); i++) {
1689
1690 if ((retval=krb5_ldap_delete_service_rights(util_context,
1691 LDAP_ADMIN_SERVICE, oldadmindns[i],
1692 rparams->realm_name, oldsubtrees, rightsmask)) != 0) {
1693 printf(gettext("failed\n"));
1694 /* Solaris Kerberos */
1695 com_err(progname, retval, gettext("while assigning rights '%s'"),
1696 rparams->realm_name);
1697 goto err_nomsg;
1698 }
1699 }
1700 }
1701
1702 rightsmask = 0;
1703 rightsmask |= LDAP_REALM_RIGHTS;
1704 rightsmask |= LDAP_SUBTREE_RIGHTS;
1705 /* Add rights on the new subtree for all the kdc dns */
1706 if (newadmindns) {
1707 for (i=0; (newadmindns[i] != NULL); i++) {
1708
1709 if ((retval=krb5_ldap_add_service_rights(util_context,
1710 LDAP_ADMIN_SERVICE, newadmindns[i],
1711 rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
1712 printf(gettext("failed\n"));
1713 /* Solaris Kerberos */
1714 com_err(progname, retval, gettext("while assigning rights to '%s'"),
1715 rparams->realm_name);
1716 goto err_nomsg;
1717 }
1718 }
1719 }
1720 }
1721
1722
1723 if ((mask & LDAP_REALM_SUBTREE) || (mask & LDAP_REALM_PASSWDSERVERS)) {
1724
1725 newpwddns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
1726 if (newpwddns == NULL) {
1727 retval = ENOMEM;
1728 goto cleanup;
1729 }
1730
1731 if ((rparams != NULL) && (rparams->passwdservers != NULL)) {
1732 for (j=0; rparams->passwdservers[j]!= NULL; j++) {
1733 newpwddns[j] = strdup(rparams->passwdservers[j]);
1734 if (newpwddns[j] == NULL) {
1735 retval = ENOMEM;
1736 goto cleanup;
1737 }
1738 }
1739 newpwddns[j] = NULL;
1740 }
1741
1742 if (!subtree_changed) {
1743 disjoint_members(oldpwddns, newpwddns);
1744 } else { /* Only the subtrees was changed. Remove the rights on the old subtrees. */
1745 if (!(mask & LDAP_REALM_ADMINSERVERS)) {
1746
1747 oldpwddns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
1748 if (oldpwddns == NULL) {
1749 retval = ENOMEM;
1750 goto cleanup;
1751 }
1752
1753 if ((rparams != NULL) && (rparams->passwdservers != NULL)) {
1754 for (j=0; rparams->passwdservers[j]!= NULL; j++) {
1755 oldpwddns[j] = strdup(rparams->passwdservers[j]);
1756 if (oldpwddns[j] == NULL) {
1757 retval = ENOMEM;
1758 goto cleanup;
1759 }
1760 }
1761 oldpwddns[j] = NULL;
1762 }
1763 }
1764 }
1765
1766 rightsmask =0;
1767 rightsmask |= LDAP_REALM_RIGHTS;
1768 rightsmask |= LDAP_SUBTREE_RIGHTS;
1769 /* Remove the rights on the old subtrees */
1770 if (oldpwddns) {
1771 for (i=0; (oldpwddns[i] != NULL); i++) {
1772 if ((retval = krb5_ldap_delete_service_rights(util_context,
1773 LDAP_PASSWD_SERVICE, oldpwddns[i],
1774 rparams->realm_name, oldsubtrees, rightsmask))) {
1775 printf(gettext("failed\n"));
1776 /* Solaris Kerberos */
1777 com_err(progname, retval, gettext("while assigning rights '%s'"),
1778 rparams->realm_name);
1779 goto err_nomsg;
1780 }
1781 }
1782 }
1783
1784 rightsmask =0;
1785 rightsmask |= LDAP_REALM_RIGHTS;
1786 rightsmask |= LDAP_SUBTREE_RIGHTS;
1787 /* Add rights on the new subtree for all the kdc dns */
1788 if (newpwddns) {
1789 for (i=0; (newpwddns[i] != NULL); i++) {
1790 if ((retval = krb5_ldap_add_service_rights(util_context,
1791 LDAP_PASSWD_SERVICE, newpwddns[i],
1792 rparams->realm_name, rparams->subtree, rightsmask))) {
1793 printf(gettext("failed\n"));
1794 /* Solaris Kerberos */
1795 com_err(progname, retval, gettext("while assigning rights to '%s'"),
1796 rparams->realm_name);
1797 goto err_nomsg;
1798 }
1799 }
1800 }
1801 }
1802
1803 printf(gettext("done\n"));
1804 }
1805 #endif
1806
1807 goto cleanup;
1808
1809 err_usage:
1810 print_usage = TRUE;
1811
1812 err_nomsg:
1813 no_msg = TRUE;
1814
1815 cleanup:
1816 krb5_ldap_free_realm_params(rparams);
1817
1818
1819 #ifdef HAVE_EDIRECTORY
1820 if (oldkdcdns) {
1821 for (i=0; oldkdcdns[i] != NULL; i++)
1822 free(oldkdcdns[i]);
1823 free(oldkdcdns);
1824 }
1825 if (oldpwddns) {
1826 for (i=0; oldpwddns[i] != NULL; i++)
1827 free(oldpwddns[i]);
1828 free(oldpwddns);
1829 }
1830 if (oldadmindns) {
1831 for (i=0; oldadmindns[i] != NULL; i++)
1832 free(oldadmindns[i]);
1833 free(oldadmindns);
1834 }
1835 if (newkdcdns) {
1836 for (i=0; newkdcdns[i] != NULL; i++)
1837 free(newkdcdns[i]);
1838 free(newkdcdns);
1839 }
1840 if (newpwddns) {
1841 for (i=0; newpwddns[i] != NULL; i++)
1842 free(newpwddns[i]);
1843 free(newpwddns);
1844 }
1845 if (newadmindns) {
1846 for (i=0; newadmindns[i] != NULL; i++)
1847 free(newadmindns[i]);
1848 free(newadmindns);
1849 }
1850 if (oldsubtrees) {
1851 for (i=0;oldsubtrees[i]!=NULL; i++)
1852 free(oldsubtrees[i]);
1853 free(oldsubtrees);
1854 }
1855 if (newsubtrees) {
1856 for (i=0;newsubtrees[i]!=NULL; i++)
1857 free(newsubtrees[i]);
1858 free(oldsubtrees);
1859 }
1860 #endif
1861 if (print_usage) {
1862 db_usage(MODIFY_REALM);
1863 }
1864
1865 if (retval) {
1866 if (!no_msg) {
1867 /* Solaris Kerberos */
1868 com_err(progname, retval, gettext("while modifying information of realm '%s'"),
1869 global_params.realm);
1870 }
1871 exit_status++;
1872 }
1873
1874 return;
1875 }
1876
1877
1878
1879 /*
1880 * This function displays the attributes of a Realm
1881 */
kdb5_ldap_view(argc,argv)1882 void kdb5_ldap_view(argc, argv)
1883 int argc;
1884 char *argv[];
1885 {
1886 krb5_ldap_realm_params *rparams = NULL;
1887 krb5_error_code retval = 0;
1888 kdb5_dal_handle *dal_handle=NULL;
1889 krb5_ldap_context *ldap_context=NULL;
1890 int mask = 0;
1891
1892 dal_handle = (kdb5_dal_handle *) util_context->db_context;
1893 ldap_context = (krb5_ldap_context *) dal_handle->db_context;
1894 if (!(ldap_context)) {
1895 retval = EINVAL;
1896 /* Solaris Kerberos */
1897 com_err(progname, retval, gettext("while initializing database"));
1898 exit_status++;
1899 return;
1900 }
1901
1902 /* Read the kerberos container information */
1903 if ((retval = krb5_ldap_read_krbcontainer_params(util_context,
1904 &(ldap_context->krbcontainer))) != 0) {
1905 /* Solaris Kerberos */
1906 com_err(progname, retval, gettext("while reading kerberos container information"));
1907 exit_status++;
1908 return;
1909 }
1910
1911 if ((retval = krb5_ldap_read_realm_params(util_context,
1912 global_params.realm, &rparams, &mask)) || (!rparams)) {
1913 /* Solaris Kerberos */
1914 com_err(progname, retval, gettext("while reading information of realm '%s'"),
1915 global_params.realm);
1916 exit_status++;
1917 return;
1918 }
1919 print_realm_params(rparams, mask);
1920 krb5_ldap_free_realm_params(rparams);
1921
1922 return;
1923 }
1924
strdur(duration)1925 static char *strdur(duration)
1926 time_t duration;
1927 {
1928 static char out[50];
1929 int neg, days, hours, minutes, seconds;
1930
1931 if (duration < 0) {
1932 duration *= -1;
1933 neg = 1;
1934 } else
1935 neg = 0;
1936 days = duration / (24 * 3600);
1937 duration %= 24 * 3600;
1938 hours = duration / 3600;
1939 duration %= 3600;
1940 minutes = duration / 60;
1941 duration %= 60;
1942 seconds = duration;
1943 snprintf(out, sizeof(out), "%s%d %s %02d:%02d:%02d", neg ? "-" : "",
1944 days, days == 1 ? gettext("day") : gettext("days"),
1945 hours, minutes, seconds);
1946 return out;
1947 }
1948
1949 /*
1950 * This function prints the attributes of a given realm to the
1951 * standard output.
1952 */
print_realm_params(krb5_ldap_realm_params * rparams,int mask)1953 static void print_realm_params(krb5_ldap_realm_params *rparams, int mask)
1954 {
1955 char **slist = NULL;
1956 int num_entry_printed = 0, i = 0;
1957
1958 /* Print the Realm Attributes on the standard output */
1959 printf("%25s: %-50s\n", gettext("Realm Name"), global_params.realm);
1960 if (mask & LDAP_REALM_SUBTREE) {
1961 for (i=0; rparams->subtree[i]!=NULL; i++)
1962 printf("%25s: %-50s\n", gettext("Subtree"), rparams->subtree[i]);
1963 }
1964 if (mask & LDAP_REALM_CONTREF)
1965 printf("%25s: %-50s\n", gettext("Principal Container Reference"), rparams->containerref);
1966 if (mask & LDAP_REALM_SEARCHSCOPE) {
1967 if ((rparams->search_scope != 1) &&
1968 (rparams->search_scope != 2)) {
1969 printf("%25s: %-50s\n", gettext("SearchScope"), gettext("Invalid !"));
1970 } else {
1971 printf("%25s: %-50s\n", gettext("SearchScope"),
1972 (rparams->search_scope == 1) ? gettext("ONE") : gettext("SUB"));
1973 }
1974 }
1975 if (mask & LDAP_REALM_KDCSERVERS) {
1976 printf("%25s:", gettext("KDC Services"));
1977 if (rparams->kdcservers != NULL) {
1978 num_entry_printed = 0;
1979 for (slist = rparams->kdcservers; *slist != NULL; slist++) {
1980 if (num_entry_printed)
1981 printf(" %25s %-50s\n", " ", *slist);
1982 else
1983 printf(" %-50s\n", *slist);
1984 num_entry_printed++;
1985 }
1986 }
1987 if (num_entry_printed == 0)
1988 printf("\n");
1989 }
1990 if (mask & LDAP_REALM_ADMINSERVERS) {
1991 printf("%25s:", gettext("Admin Services"));
1992 if (rparams->adminservers != NULL) {
1993 num_entry_printed = 0;
1994 for (slist = rparams->adminservers; *slist != NULL; slist++) {
1995 if (num_entry_printed)
1996 printf(" %25s %-50s\n", " ", *slist);
1997 else
1998 printf(" %-50s\n", *slist);
1999 num_entry_printed++;
2000 }
2001 }
2002 if (num_entry_printed == 0)
2003 printf("\n");
2004 }
2005 if (mask & LDAP_REALM_PASSWDSERVERS) {
2006 printf("%25s:", gettext("Passwd Services"));
2007 if (rparams->passwdservers != NULL) {
2008 num_entry_printed = 0;
2009 for (slist = rparams->passwdservers; *slist != NULL; slist++) {
2010 if (num_entry_printed)
2011 printf(" %25s %-50s\n", " ", *slist);
2012 else
2013 printf(" %-50s\n", *slist);
2014 num_entry_printed++;
2015 }
2016 }
2017 if (num_entry_printed == 0)
2018 printf("\n");
2019 }
2020 if (mask & LDAP_REALM_MAXTICKETLIFE) {
2021 printf("%25s:", gettext("Maximum Ticket Life"));
2022 printf(" %s \n", strdur(rparams->max_life));
2023 }
2024
2025 if (mask & LDAP_REALM_MAXRENEWLIFE) {
2026 printf("%25s:", gettext("Maximum Renewable Life"));
2027 printf(" %s \n", strdur(rparams->max_renewable_life));
2028 }
2029
2030 if (mask & LDAP_REALM_KRBTICKETFLAGS) {
2031 int ticketflags = rparams->tktflags;
2032
2033 printf("%25s: ", gettext("Ticket flags"));
2034 if (ticketflags & KRB5_KDB_DISALLOW_POSTDATED)
2035 printf("%s ","DISALLOW_POSTDATED");
2036
2037 if (ticketflags & KRB5_KDB_DISALLOW_FORWARDABLE)
2038 printf("%s ","DISALLOW_FORWARDABLE");
2039
2040 if (ticketflags & KRB5_KDB_DISALLOW_RENEWABLE)
2041 printf("%s ","DISALLOW_RENEWABLE");
2042
2043 if (ticketflags & KRB5_KDB_DISALLOW_PROXIABLE)
2044 printf("%s ","DISALLOW_PROXIABLE");
2045
2046 if (ticketflags & KRB5_KDB_DISALLOW_DUP_SKEY)
2047 printf("%s ","DISALLOW_DUP_SKEY");
2048
2049 if (ticketflags & KRB5_KDB_REQUIRES_PRE_AUTH)
2050 printf("%s ","REQUIRES_PRE_AUTH");
2051
2052 if (ticketflags & KRB5_KDB_REQUIRES_HW_AUTH)
2053 printf("%s ","REQUIRES_HW_AUTH");
2054
2055 if (ticketflags & KRB5_KDB_DISALLOW_SVR)
2056 printf("%s ","DISALLOW_SVR");
2057
2058 if (ticketflags & KRB5_KDB_DISALLOW_TGT_BASED)
2059 printf("%s ","DISALLOW_TGT_BASED");
2060
2061 if (ticketflags & KRB5_KDB_DISALLOW_ALL_TIX)
2062 printf("%s ","DISALLOW_ALL_TIX");
2063
2064 if (ticketflags & KRB5_KDB_REQUIRES_PWCHANGE)
2065 printf("%s ","REQUIRES_PWCHANGE");
2066
2067 if (ticketflags & KRB5_KDB_PWCHANGE_SERVICE)
2068 printf("%s ","PWCHANGE_SERVICE");
2069
2070 printf("\n");
2071 }
2072
2073
2074 return;
2075 }
2076
2077
2078
2079 /*
2080 * This function lists the Realm(s) present under the Kerberos container
2081 * on the LDAP Server.
2082 */
kdb5_ldap_list(argc,argv)2083 void kdb5_ldap_list(argc, argv)
2084 int argc;
2085 char *argv[];
2086 {
2087 char **list = NULL;
2088 char **plist = NULL;
2089 krb5_error_code retval = 0;
2090 kdb5_dal_handle *dal_handle=NULL;
2091 krb5_ldap_context *ldap_context=NULL;
2092
2093 dal_handle = (kdb5_dal_handle *)util_context->db_context;
2094 ldap_context = (krb5_ldap_context *) dal_handle->db_context;
2095 if (!(ldap_context)) {
2096 retval = EINVAL;
2097 exit_status++;
2098 return;
2099 }
2100
2101 /* Read the kerberos container information */
2102 if ((retval = krb5_ldap_read_krbcontainer_params(util_context,
2103 &(ldap_context->krbcontainer))) != 0) {
2104 /* Solaris Kerberos */
2105 com_err(progname, retval, gettext("while reading kerberos container information"));
2106 exit_status++;
2107 return;
2108 }
2109
2110 retval = krb5_ldap_list_realm(util_context, &list);
2111 if (retval != 0) {
2112 krb5_ldap_free_krbcontainer_params(ldap_context->krbcontainer);
2113 ldap_context->krbcontainer = NULL;
2114 /* Solaris Kerberos */
2115 com_err (progname, retval, gettext("while listing realms"));
2116 exit_status++;
2117 return;
2118 }
2119 /* This is to handle the case of realm not present */
2120 if (list == NULL) {
2121 krb5_ldap_free_krbcontainer_params(ldap_context->krbcontainer);
2122 ldap_context->krbcontainer = NULL;
2123 return;
2124 }
2125
2126 for (plist = list; *plist != NULL; plist++) {
2127 printf("%s\n", *plist);
2128 }
2129 krb5_ldap_free_krbcontainer_params(ldap_context->krbcontainer);
2130 ldap_context->krbcontainer = NULL;
2131 krb5_free_list_entries(list);
2132 free(list);
2133
2134 return;
2135 }
2136
2137 /*
2138 * Duplicating the following two functions here because
2139 * 'krb5_dbe_update_tl_data' uses backend specific memory allocation. The catch
2140 * here is that the backend is not initialized - kdb5_ldap_util doesn't go
2141 * through DAL.
2142 * 1. krb5_dbe_update_tl_data
2143 * 2. krb5_dbe_update_mod_princ_data
2144 */
2145
2146 /* Start duplicate code ... */
2147
2148 static krb5_error_code
krb5_dbe_update_tl_data_new(context,entry,new_tl_data)2149 krb5_dbe_update_tl_data_new(context, entry, new_tl_data)
2150 krb5_context context;
2151 krb5_db_entry *entry;
2152 krb5_tl_data *new_tl_data;
2153 {
2154 krb5_tl_data *tl_data = NULL;
2155 krb5_octet *tmp;
2156
2157 /* copy the new data first, so we can fail cleanly if malloc()
2158 * fails */
2159 /*
2160 if ((tmp =
2161 (krb5_octet *) krb5_db_alloc(context, NULL,
2162 new_tl_data->tl_data_length)) == NULL)
2163 */
2164 if ((tmp = (krb5_octet *) malloc (new_tl_data->tl_data_length)) == NULL)
2165 return (ENOMEM);
2166
2167 /* Find an existing entry of the specified type and point at
2168 * it, or NULL if not found */
2169
2170 if (new_tl_data->tl_data_type != KRB5_TL_DB_ARGS) { /* db_args can be multiple */
2171 for (tl_data = entry->tl_data; tl_data;
2172 tl_data = tl_data->tl_data_next)
2173 if (tl_data->tl_data_type == new_tl_data->tl_data_type)
2174 break;
2175 }
2176
2177 /* if necessary, chain a new record in the beginning and point at it */
2178
2179 if (!tl_data) {
2180 /*
2181 if ((tl_data =
2182 (krb5_tl_data *) krb5_db_alloc(context, NULL,
2183 sizeof(krb5_tl_data)))
2184 == NULL) {
2185 */
2186 if ((tl_data = (krb5_tl_data *) malloc (sizeof(krb5_tl_data))) == NULL) {
2187 free(tmp);
2188 return (ENOMEM);
2189 }
2190 memset(tl_data, 0, sizeof(krb5_tl_data));
2191 tl_data->tl_data_next = entry->tl_data;
2192 entry->tl_data = tl_data;
2193 entry->n_tl_data++;
2194 }
2195
2196 /* fill in the record */
2197
2198 if (tl_data->tl_data_contents)
2199 krb5_db_free(context, tl_data->tl_data_contents);
2200
2201 tl_data->tl_data_type = new_tl_data->tl_data_type;
2202 tl_data->tl_data_length = new_tl_data->tl_data_length;
2203 tl_data->tl_data_contents = tmp;
2204 memcpy(tmp, new_tl_data->tl_data_contents, tl_data->tl_data_length);
2205
2206 return (0);
2207 }
2208
2209 static krb5_error_code
krb5_dbe_update_mod_princ_data_new(context,entry,mod_date,mod_princ)2210 krb5_dbe_update_mod_princ_data_new(context, entry, mod_date, mod_princ)
2211 krb5_context context;
2212 krb5_db_entry * entry;
2213 krb5_timestamp mod_date;
2214 krb5_const_principal mod_princ;
2215 {
2216 krb5_tl_data tl_data;
2217
2218 krb5_error_code retval = 0;
2219 krb5_octet * nextloc = 0;
2220 char * unparse_mod_princ = 0;
2221 unsigned int unparse_mod_princ_size;
2222
2223 if ((retval = krb5_unparse_name(context, mod_princ,
2224 &unparse_mod_princ)))
2225 return(retval);
2226
2227 unparse_mod_princ_size = strlen(unparse_mod_princ) + 1;
2228
2229 if ((nextloc = (krb5_octet *) malloc(unparse_mod_princ_size + 4))
2230 == NULL) {
2231 free(unparse_mod_princ);
2232 return(ENOMEM);
2233 }
2234
2235 tl_data.tl_data_type = KRB5_TL_MOD_PRINC;
2236 tl_data.tl_data_length = unparse_mod_princ_size + 4;
2237 tl_data.tl_data_contents = nextloc;
2238
2239 /* Mod Date */
2240 krb5_kdb_encode_int32(mod_date, nextloc);
2241
2242 /* Mod Princ */
2243 memcpy(nextloc+4, unparse_mod_princ, unparse_mod_princ_size);
2244
2245 retval = krb5_dbe_update_tl_data_new(context, entry, &tl_data);
2246
2247 free(unparse_mod_princ);
2248 free(nextloc);
2249
2250 return(retval);
2251 }
2252
2253 static krb5_error_code
kdb_ldap_tgt_keysalt_iterate(ksent,ptr)2254 kdb_ldap_tgt_keysalt_iterate(ksent, ptr)
2255 krb5_key_salt_tuple *ksent;
2256 krb5_pointer ptr;
2257 {
2258 krb5_context context;
2259 krb5_error_code kret;
2260 struct iterate_args *iargs;
2261 krb5_keyblock key;
2262 krb5_int32 ind;
2263 krb5_data pwd;
2264 krb5_db_entry *entry;
2265
2266 iargs = (struct iterate_args *) ptr;
2267 kret = 0;
2268
2269 context = iargs->ctx;
2270 entry = iargs->dbentp;
2271
2272 /*
2273 * Convert the master key password into a key for this particular
2274 * encryption system.
2275 */
2276 pwd.data = mkey_password;
2277 pwd.length = strlen(mkey_password);
2278 kret = krb5_c_random_seed(context, &pwd);
2279 if (kret)
2280 return kret;
2281
2282 /*if (!(kret = krb5_dbe_create_key_data(iargs->ctx, iargs->dbentp))) {*/
2283 if ((entry->key_data =
2284 (krb5_key_data *) realloc(entry->key_data,
2285 (sizeof(krb5_key_data) *
2286 (entry->n_key_data + 1)))) == NULL)
2287 return (ENOMEM);
2288
2289 memset(entry->key_data + entry->n_key_data, 0, sizeof(krb5_key_data));
2290 ind = entry->n_key_data++;
2291
2292 if (!(kret = krb5_c_make_random_key(context, ksent->ks_enctype,
2293 &key))) {
2294 kret = krb5_dbekd_encrypt_key_data(context,
2295 iargs->rblock->key,
2296 &key,
2297 NULL,
2298 1,
2299 &entry->key_data[ind]);
2300 krb5_free_keyblock_contents(context, &key);
2301 }
2302 /*}*/
2303
2304 return(kret);
2305 }
2306 /* End duplicate code */
2307
2308 /*
2309 * This function creates service principals when
2310 * creating the realm object.
2311 */
2312 static int
kdb_ldap_create_principal(context,princ,op,pblock)2313 kdb_ldap_create_principal (context, princ, op, pblock)
2314 krb5_context context;
2315 krb5_principal princ;
2316 enum ap_op op;
2317 struct realm_info *pblock;
2318 {
2319 int retval=0, currlen=0, princtype = 2 /* Service Principal */;
2320 unsigned char *curr=NULL;
2321 krb5_tl_data *tl_data=NULL;
2322 krb5_db_entry entry;
2323 int nentry=1;
2324 long mask = 0;
2325 krb5_keyblock key;
2326 int kvno = 0;
2327 kdb5_dal_handle *dal_handle = NULL;
2328 krb5_ldap_context *ldap_context=NULL;
2329 struct iterate_args iargs;
2330 krb5_data *pdata;
2331
2332 if ((pblock == NULL) || (context == NULL)) {
2333 retval = EINVAL;
2334 goto cleanup;
2335 }
2336 dal_handle = (kdb5_dal_handle *) context->db_context;
2337 ldap_context = (krb5_ldap_context *) dal_handle->db_context;
2338 if (!(ldap_context)) {
2339 retval = EINVAL;
2340 goto cleanup;
2341 }
2342
2343 memset(&entry, 0, sizeof(entry));
2344
2345 tl_data = malloc(sizeof(*tl_data));
2346 if (tl_data == NULL) {
2347 retval = ENOMEM;
2348 goto cleanup;
2349 }
2350 memset(tl_data, 0, sizeof(*tl_data));
2351 tl_data->tl_data_length = 1 + 2 + 2 + 1 + 2 + 4;
2352 tl_data->tl_data_type = 7; /* KDB_TL_USER_INFO */
2353 curr = tl_data->tl_data_contents = malloc(tl_data->tl_data_length);
2354 if (tl_data->tl_data_contents == NULL) {
2355 retval = ENOMEM;
2356 goto cleanup;
2357 }
2358
2359 memset(curr, 1, 1); /* Passing the mask as principal type */
2360 curr += 1;
2361 currlen = 2;
2362 STORE16_INT(curr, currlen);
2363 curr += currlen;
2364 STORE16_INT(curr, princtype);
2365 curr += currlen;
2366
2367 mask |= KADM5_PRINCIPAL;
2368 mask |= KADM5_ATTRIBUTES ;
2369 mask |= KADM5_MAX_LIFE ;
2370 mask |= KADM5_MAX_RLIFE ;
2371 mask |= KADM5_PRINC_EXPIRE_TIME ;
2372 mask |= KADM5_KEY_DATA;
2373
2374 entry.tl_data = tl_data;
2375 entry.n_tl_data += 1;
2376 /* Set the creator's name */
2377 {
2378 krb5_timestamp now;
2379 if ((retval = krb5_timeofday(context, &now)))
2380 goto cleanup;
2381 if ((retval = krb5_dbe_update_mod_princ_data_new(context, &entry,
2382 now, &db_create_princ)))
2383 goto cleanup;
2384 }
2385 entry.attributes = pblock->flags;
2386 entry.max_life = pblock->max_life;
2387 entry.max_renewable_life = pblock->max_rlife;
2388 entry.expiration = pblock->expiration;
2389 entry.mask = mask;
2390 if ((retval = krb5_copy_principal(context, princ, &entry.princ)))
2391 goto cleanup;
2392
2393
2394 switch (op) {
2395 case TGT_KEY:
2396 if ((pdata = krb5_princ_component(context, princ, 1)) &&
2397 pdata->length == strlen("history") &&
2398 !memcmp(pdata->data, "history", strlen("history"))) {
2399
2400 /* Allocate memory for storing the key */
2401 if ((entry.key_data = (krb5_key_data *) malloc(
2402 sizeof(krb5_key_data))) == NULL) {
2403 retval = ENOMEM;
2404 goto cleanup;
2405 }
2406
2407 memset(entry.key_data, 0, sizeof(krb5_key_data));
2408 entry.n_key_data++;
2409
2410 retval = krb5_c_make_random_key(context, global_params.enctype, &key);
2411 if (retval) {
2412 goto cleanup;
2413 }
2414 kvno = 1; /* New key is getting set */
2415 retval = krb5_dbekd_encrypt_key_data(context,
2416 &ldap_context->lrparams->mkey,
2417 &key, NULL, kvno,
2418 &entry.key_data[entry.n_key_data - 1]);
2419 krb5_free_keyblock_contents(context, &key);
2420 if (retval) {
2421 goto cleanup;
2422 }
2423 } else {
2424 /*retval = krb5_c_make_random_key(context, 16, &key) ;*/
2425 iargs.ctx = context;
2426 iargs.rblock = pblock;
2427 iargs.dbentp = &entry;
2428
2429 /*
2430 * create a set of random keys by iterating through the key/salt
2431 * list, ignoring salt types.
2432 */
2433 if ((retval = krb5_keysalt_iterate(pblock->kslist,
2434 pblock->nkslist,
2435 1,
2436 kdb_ldap_tgt_keysalt_iterate,
2437 (krb5_pointer) &iargs)))
2438 return retval;
2439 }
2440 break;
2441
2442 case MASTER_KEY:
2443 /* Allocate memory for storing the key */
2444 if ((entry.key_data = (krb5_key_data *) malloc(
2445 sizeof(krb5_key_data))) == NULL) {
2446 retval = ENOMEM;
2447 goto cleanup;
2448 }
2449
2450 memset(entry.key_data, 0, sizeof(krb5_key_data));
2451 entry.n_key_data++;
2452 kvno = 1; /* New key is getting set */
2453 retval = krb5_dbekd_encrypt_key_data(context, pblock->key,
2454 &ldap_context->lrparams->mkey,
2455 NULL, kvno,
2456 &entry.key_data[entry.n_key_data - 1]);
2457 if (retval) {
2458 goto cleanup;
2459 }
2460 break;
2461
2462 case NULL_KEY:
2463 default:
2464 break;
2465 } /* end of switch */
2466
2467 retval = krb5_ldap_put_principal(context, &entry, &nentry, NULL);
2468 if (retval) {
2469 com_err(NULL, retval, gettext("while adding entries to database"));
2470 goto cleanup;
2471 }
2472
2473 cleanup:
2474 krb5_dbe_free_contents(context, &entry);
2475 return retval;
2476 }
2477
2478
2479 /*
2480 * This function destroys the realm object and the associated principals
2481 */
2482 void
kdb5_ldap_destroy(argc,argv)2483 kdb5_ldap_destroy(argc, argv)
2484 int argc;
2485 char *argv[];
2486 {
2487 extern char *optarg;
2488 extern int optind;
2489 int optchar = 0;
2490 char buf[5] = {0};
2491 krb5_error_code retval = 0;
2492 int force = 0;
2493 int mask = 0;
2494 kdb5_dal_handle *dal_handle = NULL;
2495 krb5_ldap_context *ldap_context = NULL;
2496 #ifdef HAVE_EDIRECTORY
2497 int i = 0, rightsmask = 0;
2498 krb5_ldap_realm_params *rparams = NULL;
2499 #endif
2500 /* Solaris Kerberos: to remove stash file */
2501 char *stash_file = NULL;
2502 struct stat stb;
2503
2504 optind = 1;
2505 while ((optchar = getopt(argc, argv, "f")) != -1) {
2506 switch (optchar) {
2507 case 'f':
2508 force++;
2509 break;
2510 case '?':
2511 default:
2512 db_usage(DESTROY_REALM);
2513 return;
2514 /*NOTREACHED*/
2515 }
2516 }
2517
2518 if (!force) {
2519 printf(gettext("Deleting KDC database of '%s', are you sure?\n"), global_params.realm);
2520 printf(gettext("(type 'yes' to confirm)? "));
2521 if (fgets(buf, sizeof(buf), stdin) == NULL) {
2522 exit_status++;
2523 return;
2524 }
2525 if (strcmp(buf, yes)) {
2526 exit_status++;
2527 return;
2528 }
2529 printf(gettext("OK, deleting database of '%s'...\n"), global_params.realm);
2530 }
2531
2532 dal_handle = (kdb5_dal_handle *)util_context->db_context;
2533 ldap_context = (krb5_ldap_context *) dal_handle->db_context;
2534 if (!(ldap_context)) {
2535 /* Solaris Kerberos */
2536 com_err(progname, EINVAL, gettext("while initializing database"));
2537 exit_status++;
2538 return;
2539 }
2540
2541 /* Read the kerberos container from the LDAP Server */
2542 if ((retval = krb5_ldap_read_krbcontainer_params(util_context,
2543 &(ldap_context->krbcontainer))) != 0) {
2544 /* Solaris Kerberos */
2545 com_err(progname, retval, gettext("while reading kerberos container information"));
2546 exit_status++;
2547 return;
2548 }
2549
2550 /* Read the Realm information from the LDAP Server */
2551 if ((retval = krb5_ldap_read_realm_params(util_context, global_params.realm,
2552 &(ldap_context->lrparams), &mask)) != 0) {
2553 /* Solaris Kerberos */
2554 com_err(progname, retval, gettext("while reading realm information"));
2555 exit_status++;
2556 return;
2557 }
2558
2559 #ifdef HAVE_EDIRECTORY
2560 if ((mask & LDAP_REALM_KDCSERVERS) || (mask & LDAP_REALM_ADMINSERVERS) ||
2561 (mask & LDAP_REALM_PASSWDSERVERS)) {
2562
2563 printf(gettext("Changing rights for the service object. Please wait ... "));
2564 fflush(stdout);
2565
2566 rparams = ldap_context->lrparams;
2567 rightsmask = 0;
2568 rightsmask |= LDAP_REALM_RIGHTS;
2569 rightsmask |= LDAP_SUBTREE_RIGHTS;
2570 if ((rparams != NULL) && (rparams->kdcservers != NULL)) {
2571 for (i=0; (rparams->kdcservers[i] != NULL); i++) {
2572 if ((retval = krb5_ldap_delete_service_rights(util_context,
2573 LDAP_KDC_SERVICE, rparams->kdcservers[i],
2574 rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
2575 printf(gettext("failed\n"));
2576 /* Solaris Kerberos */
2577 com_err(progname, retval, gettext("while assigning rights to '%s'"),
2578 rparams->realm_name);
2579 return;
2580 }
2581 }
2582 }
2583 rightsmask = 0;
2584 rightsmask |= LDAP_REALM_RIGHTS;
2585 rightsmask |= LDAP_SUBTREE_RIGHTS;
2586 if ((rparams != NULL) && (rparams->adminservers != NULL)) {
2587 for (i=0; (rparams->adminservers[i] != NULL); i++) {
2588 if ((retval = krb5_ldap_delete_service_rights(util_context,
2589 LDAP_ADMIN_SERVICE, rparams->adminservers[i],
2590 rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
2591 printf(gettext("failed\n"));
2592 /* Solaris Kerberos */
2593 com_err(progname, retval, gettext("while assigning rights to '%s'"),
2594 rparams->realm_name);
2595 return;
2596 }
2597 }
2598 }
2599 rightsmask = 0;
2600 rightsmask |= LDAP_REALM_RIGHTS;
2601 rightsmask |= LDAP_SUBTREE_RIGHTS;
2602 if ((rparams != NULL) && (rparams->passwdservers != NULL)) {
2603 for (i=0; (rparams->passwdservers[i] != NULL); i++) {
2604 if ((retval = krb5_ldap_delete_service_rights(util_context,
2605 LDAP_PASSWD_SERVICE, rparams->passwdservers[i],
2606 rparams->realm_name, rparams->subtree, rightsmask)) != 0) {
2607 printf(gettext("failed\n"));
2608 /* Solaris Kerberos */
2609 com_err(progname, retval, gettext("while assigning rights to '%s'"),
2610 rparams->realm_name);
2611 return;
2612 }
2613 }
2614 }
2615 printf(gettext("done\n"));
2616 }
2617 #endif
2618 /* Delete the realm container and all the associated principals */
2619 retval = krb5_ldap_delete_realm(util_context, global_params.realm);
2620 if (retval) {
2621 /* Solaris Kerberos */
2622 com_err(progname, retval, gettext("deleting database of '%s'"), global_params.realm);
2623 exit_status++;
2624 return;
2625 }
2626
2627 /*
2628 * Solaris Kerberos: check for a stash file and delete it if necessary
2629 * This behavior exists in the Solaris version of kdb5_util destroy.
2630 */
2631 if (global_params.stash_file == NULL) {
2632 char stashbuf[MAXPATHLEN+1];
2633 int realm_len = strlen(global_params.realm);
2634
2635 (void) strlcpy(stashbuf, DEFAULT_KEYFILE_STUB, sizeof (stashbuf));
2636
2637 if (realm_len <= (MAXPATHLEN-strlen(stashbuf))) {
2638 (void) strncat(stashbuf, global_params.realm,
2639 (MAXPATHLEN-strlen(stashbuf)));
2640 } else {
2641 /* Solaris Kerberos */
2642 com_err(progname, EINVAL,
2643 gettext("can not determine stash file name for '%s'"),
2644 global_params.realm);
2645 exit_status++;
2646 return;
2647 }
2648 stash_file = stashbuf;
2649 } else {
2650 stash_file = global_params.stash_file;
2651 }
2652 /* Make sure stash_file is a regular file before unlinking */
2653 if (stat(stash_file, &stb) == 0) {
2654 if ((stb.st_mode & S_IFMT) == S_IFREG) {
2655 (void)unlink(stash_file);
2656 } else {
2657 /* Solaris Kerberos */
2658 com_err(progname, EINVAL,
2659 gettext("stash file '%s' not a regular file, can not delete"),
2660 stash_file);
2661 exit_status++;
2662 return;
2663 }
2664 } else if (errno != ENOENT) {
2665 /*
2666 * If the error is something other than the file doesn't exist set an
2667 * error.
2668 */
2669 /* Solaris Kerberos */
2670 com_err(progname, EINVAL,
2671 gettext("could not stat stash file '%s', could not delete"),
2672 stash_file);
2673 exit_status++;
2674 return;
2675 }
2676
2677 printf(gettext("** Database of '%s' destroyed.\n"), global_params.realm);
2678
2679 return;
2680 }
2681