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