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