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