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