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