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