154925bf6Swillf 
254925bf6Swillf /*
354925bf6Swillf  * kadmin/ldap_util/kdb5_ldap_policy.c
454925bf6Swillf  */
554925bf6Swillf 
6*dd9ccd46S /*
7*dd9ccd46S  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
8*dd9ccd46S  * Use is subject to license terms.
9*dd9ccd46S  */
10*dd9ccd46S 
1154925bf6Swillf /* Copyright (c) 2004-2005, Novell, Inc.
1254925bf6Swillf  * All rights reserved.
1354925bf6Swillf  *
1454925bf6Swillf  * Redistribution and use in source and binary forms, with or without
1554925bf6Swillf  * modification, are permitted provided that the following conditions are met:
1654925bf6Swillf  *
1754925bf6Swillf  *   * Redistributions of source code must retain the above copyright notice,
1854925bf6Swillf  *       this list of conditions and the following disclaimer.
1954925bf6Swillf  *   * Redistributions in binary form must reproduce the above copyright
2054925bf6Swillf  *       notice, this list of conditions and the following disclaimer in the
2154925bf6Swillf  *       documentation and/or other materials provided with the distribution.
2254925bf6Swillf  *   * The copyright holder's name is not used to endorse or promote products
2354925bf6Swillf  *       derived from this software without specific prior written permission.
2454925bf6Swillf  *
2554925bf6Swillf  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2654925bf6Swillf  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2754925bf6Swillf  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2854925bf6Swillf  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2954925bf6Swillf  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3054925bf6Swillf  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3154925bf6Swillf  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3254925bf6Swillf  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3354925bf6Swillf  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3454925bf6Swillf  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3554925bf6Swillf  * POSSIBILITY OF SUCH DAMAGE.
3654925bf6Swillf  */
3754925bf6Swillf 
3854925bf6Swillf /*
3954925bf6Swillf  * Create / Delete / Modify / View / List policy objects.
4054925bf6Swillf  */
4154925bf6Swillf 
4254925bf6Swillf #include <stdio.h>
4354925bf6Swillf #include <time.h>
4454925bf6Swillf #include <k5-int.h>
4554925bf6Swillf #include <kadm5/admin.h>
4654925bf6Swillf #include <libintl.h>
4754925bf6Swillf #include <locale.h>
4854925bf6Swillf #include "kdb5_ldap_util.h"
4954925bf6Swillf #include "kdb5_ldap_list.h"
5054925bf6Swillf #include "ldap_tkt_policy.h"
5154925bf6Swillf extern time_t get_date(char *); /* kadmin/cli/getdate.o */
5254925bf6Swillf 
5354925bf6Swillf static void print_policy_params(krb5_ldap_policy_params *policyparams, int mask);
5454925bf6Swillf static char *strdur(time_t duration);
5554925bf6Swillf 
5654925bf6Swillf extern char *yes;
5754925bf6Swillf extern kadm5_config_params global_params;
58*dd9ccd46S 
5954925bf6Swillf static krb5_error_code init_ldap_realm (int argc, char *argv[]) {
6054925bf6Swillf     /* This operation is being performed in the context of a realm. So,
6154925bf6Swillf      * initialize the realm */
6254925bf6Swillf     int mask = 0;
6354925bf6Swillf     krb5_error_code retval = 0;
6454925bf6Swillf     kdb5_dal_handle *dal_handle = NULL;
6554925bf6Swillf     krb5_ldap_context *ldap_context=NULL;
6654925bf6Swillf 
6754925bf6Swillf     dal_handle = (kdb5_dal_handle *) util_context->db_context;
6854925bf6Swillf     ldap_context = (krb5_ldap_context *) dal_handle->db_context;
6954925bf6Swillf     if (!ldap_context) {
7054925bf6Swillf         retval = EINVAL;
7154925bf6Swillf         goto cleanup;
7254925bf6Swillf     }
7354925bf6Swillf 
7454925bf6Swillf     if (ldap_context->krbcontainer == NULL) {
7554925bf6Swillf         retval = krb5_ldap_read_krbcontainer_params (util_context,
7654925bf6Swillf                 &(ldap_context->krbcontainer));
7754925bf6Swillf         if (retval != 0) {
78*dd9ccd46S 	    /* Solaris Kerberos */
79*dd9ccd46S             com_err(progname, retval, gettext("while reading kerberos container information"));
8054925bf6Swillf             goto cleanup;
8154925bf6Swillf         }
8254925bf6Swillf     }
8354925bf6Swillf 
8454925bf6Swillf     if (ldap_context->lrparams == NULL) {
8554925bf6Swillf         retval = krb5_ldap_read_realm_params(util_context,
8654925bf6Swillf                 global_params.realm,
8754925bf6Swillf                 &(ldap_context->lrparams),
8854925bf6Swillf                 &mask);
8954925bf6Swillf 
9054925bf6Swillf         if (retval != 0) {
9154925bf6Swillf             goto cleanup;
9254925bf6Swillf         }
9354925bf6Swillf     }
9454925bf6Swillf cleanup:
9554925bf6Swillf     return retval;
9654925bf6Swillf }
9754925bf6Swillf 
9854925bf6Swillf /*
9954925bf6Swillf  * This function will create a ticket policy object with the
10054925bf6Swillf  * specified attributes.
10154925bf6Swillf  */
10254925bf6Swillf void
10354925bf6Swillf kdb5_ldap_create_policy(argc, argv)
10454925bf6Swillf     int argc;
10554925bf6Swillf     char *argv[];
10654925bf6Swillf {
107*dd9ccd46S     /* Solaris Kerberos */
108*dd9ccd46S     char *me = progname;
109*dd9ccd46S 
11054925bf6Swillf     krb5_error_code retval = 0;
11154925bf6Swillf     krb5_ldap_policy_params *policyparams = NULL;
11254925bf6Swillf     krb5_boolean print_usage = FALSE;
11354925bf6Swillf     krb5_boolean no_msg = FALSE;
11454925bf6Swillf     int mask = 0;
11554925bf6Swillf     time_t date = 0;
11654925bf6Swillf     time_t now = 0;
11754925bf6Swillf     int i = 0;
11854925bf6Swillf 
11954925bf6Swillf     /* Check for number of arguments */
12054925bf6Swillf     if ((argc < 2) || (argc > 16)) {
12154925bf6Swillf 	goto err_usage;
12254925bf6Swillf     }
12354925bf6Swillf 
12454925bf6Swillf     /* Allocate memory for policy parameters structure */
12554925bf6Swillf     policyparams = (krb5_ldap_policy_params*) calloc(1, sizeof(krb5_ldap_policy_params));
12654925bf6Swillf     if (policyparams == NULL) {
12754925bf6Swillf 	retval = ENOMEM;
12854925bf6Swillf 	goto cleanup;
12954925bf6Swillf     }
13054925bf6Swillf 
13154925bf6Swillf     /* Get current time */
13254925bf6Swillf     time (&now);
13354925bf6Swillf 
13454925bf6Swillf     /* Parse all arguments */
13554925bf6Swillf     for (i = 1; i < argc; i++) {
13654925bf6Swillf 	if (!strcmp(argv[i], "-maxtktlife")) {
13754925bf6Swillf 	    if (++i > argc - 1)
13854925bf6Swillf 		goto err_usage;
13954925bf6Swillf 
14054925bf6Swillf 	    date = get_date(argv[i]);
14154925bf6Swillf 	    if (date == (time_t)(-1)) {
14254925bf6Swillf 		retval = EINVAL;
14354925bf6Swillf 		com_err (me, retval, gettext("while providing time specification"));
14454925bf6Swillf 		goto err_nomsg;
14554925bf6Swillf 	    }
14654925bf6Swillf 
14754925bf6Swillf 	    policyparams->maxtktlife = date - now;
14854925bf6Swillf 
14954925bf6Swillf 	    mask |= LDAP_POLICY_MAXTKTLIFE;
15054925bf6Swillf 	} else if (!strcmp(argv[i], "-maxrenewlife")) {
15154925bf6Swillf 	    if (++i > argc - 1)
15254925bf6Swillf 		goto err_usage;
15354925bf6Swillf 
15454925bf6Swillf 	    date = get_date(argv[i]);
15554925bf6Swillf 	    if (date == (time_t)(-1)) {
15654925bf6Swillf 		retval = EINVAL;
15754925bf6Swillf 		com_err (me, retval, gettext("while providing time specification"));
15854925bf6Swillf 		goto err_nomsg;
15954925bf6Swillf 	    }
16054925bf6Swillf 
16154925bf6Swillf 	    policyparams->maxrenewlife = date - now;
16254925bf6Swillf 
16354925bf6Swillf 	    mask |= LDAP_POLICY_MAXRENEWLIFE;
16454925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "allow_postdated")) {
16554925bf6Swillf 	    if (*(argv[i]) == '+')
16654925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_POSTDATED);
16754925bf6Swillf 	    else if (*(argv[i]) == '-')
16854925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_POSTDATED;
16954925bf6Swillf 	    else
17054925bf6Swillf 		goto err_usage;
17154925bf6Swillf 
17254925bf6Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
17354925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "allow_forwardable")) {
17454925bf6Swillf 	    if (*(argv[i]) == '+')
17554925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_FORWARDABLE);
17654925bf6Swillf 	    else if (*(argv[i]) == '-')
17754925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_FORWARDABLE;
17854925bf6Swillf 	    else
17954925bf6Swillf 		goto err_usage;
18054925bf6Swillf 
18154925bf6Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
18254925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "allow_renewable")) {
18354925bf6Swillf 	    if (*(argv[i]) == '+')
18454925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_RENEWABLE);
18554925bf6Swillf 	    else if (*(argv[i]) == '-')
18654925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_RENEWABLE;
18754925bf6Swillf 	    else
18854925bf6Swillf 		goto err_usage;
18954925bf6Swillf 
19054925bf6Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
19154925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "allow_proxiable")) {
19254925bf6Swillf 	    if (*(argv[i]) == '+')
19354925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_PROXIABLE);
19454925bf6Swillf 	    else if (*(argv[i]) == '-')
19554925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_PROXIABLE;
19654925bf6Swillf 	    else
19754925bf6Swillf 		goto err_usage;
19854925bf6Swillf 
19954925bf6Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
20054925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "allow_dup_skey")) {
20154925bf6Swillf 	    if (*(argv[i]) == '+')
20254925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_DUP_SKEY);
20354925bf6Swillf 	    else if (*(argv[i]) == '-')
20454925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_DUP_SKEY;
20554925bf6Swillf 	    else
20654925bf6Swillf 		goto err_usage;
20754925bf6Swillf 
20854925bf6Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
20954925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "requires_preauth")) {
21054925bf6Swillf 	    if (*(argv[i]) == '+')
21154925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_REQUIRES_PRE_AUTH;
21254925bf6Swillf 	    else if (*(argv[i]) == '-')
21354925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_PRE_AUTH);
21454925bf6Swillf 	    else
21554925bf6Swillf 		goto err_usage;
21654925bf6Swillf 
21754925bf6Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
21854925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "requires_hwauth")) {
21954925bf6Swillf 	    if (*(argv[i]) == '+')
22054925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_REQUIRES_HW_AUTH;
22154925bf6Swillf 	    else if (*(argv[i]) == '-')
22254925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_HW_AUTH);
22354925bf6Swillf 	    else
22454925bf6Swillf 		goto err_usage;
22554925bf6Swillf 
22654925bf6Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
22754925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "allow_svr")) {
22854925bf6Swillf 	    if (*(argv[i]) == '+')
22954925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_SVR);
23054925bf6Swillf 	    else if (*(argv[i]) == '-')
23154925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_SVR;
23254925bf6Swillf 	    else
23354925bf6Swillf 		goto err_usage;
23454925bf6Swillf 
23554925bf6Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
23654925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "allow_tgs_req")) {
23754925bf6Swillf 	    if (*(argv[i]) == '+')
23854925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_TGT_BASED);
23954925bf6Swillf 	    else if (*(argv[i]) == '-')
24054925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_TGT_BASED;
24154925bf6Swillf 	    else
24254925bf6Swillf 		goto err_usage;
24354925bf6Swillf 
24454925bf6Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
24554925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "allow_tix")) {
24654925bf6Swillf 	    if (*(argv[i]) == '+')
24754925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_ALL_TIX);
24854925bf6Swillf 	    else if (*(argv[i]) == '-')
24954925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_ALL_TIX;
25054925bf6Swillf 	    else
25154925bf6Swillf 		goto err_usage;
25254925bf6Swillf 
25354925bf6Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
25454925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "needchange")) {
25554925bf6Swillf 	    if (*(argv[i]) == '+')
25654925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_REQUIRES_PWCHANGE;
25754925bf6Swillf 	    else if (*(argv[i]) == '-')
25854925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_PWCHANGE);
25954925bf6Swillf 	    else
26054925bf6Swillf 		goto err_usage;
26154925bf6Swillf 
26254925bf6Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
26354925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "password_changing_service")) {
26454925bf6Swillf 	    if (*(argv[i]) == '+')
26554925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_PWCHANGE_SERVICE;
26654925bf6Swillf 	    else if (*(argv[i]) == '-')
26754925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_PWCHANGE_SERVICE);
26854925bf6Swillf 	    else
26954925bf6Swillf 		goto err_usage;
27054925bf6Swillf 
27154925bf6Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
27254925bf6Swillf 	} else { /* Any other argument must be policy DN */
27354925bf6Swillf 	    /* First check if policy DN is already provided --
27454925bf6Swillf 	       if so, there's a usage error */
27554925bf6Swillf             if (policyparams->policy != NULL)
27654925bf6Swillf 		goto err_usage;
27754925bf6Swillf 
27854925bf6Swillf 	    /* If not present already, fill up policy DN */
27954925bf6Swillf             policyparams->policy = strdup(argv[i]);
28054925bf6Swillf             if (policyparams->policy == NULL) {
28154925bf6Swillf 		retval = ENOMEM;
28254925bf6Swillf 		com_err(me, retval, gettext("while creating policy object"));
28354925bf6Swillf 		goto err_nomsg;
28454925bf6Swillf 	    }
28554925bf6Swillf 	}
28654925bf6Swillf     }
28754925bf6Swillf 
28854925bf6Swillf     /* policy DN is a mandatory argument. If not provided, print usage */
28954925bf6Swillf     if (policyparams->policy == NULL)
29054925bf6Swillf 	goto err_usage;
29154925bf6Swillf 
29254925bf6Swillf     if ((retval = init_ldap_realm (argc, argv))) {
29354925bf6Swillf         com_err(me, retval, gettext("while reading realm information"));
29454925bf6Swillf         goto err_nomsg;
29554925bf6Swillf     }
29654925bf6Swillf 
29754925bf6Swillf     /* Create object with all attributes provided */
29854925bf6Swillf     if ((retval = krb5_ldap_create_policy(util_context, policyparams, mask)) != 0)
29954925bf6Swillf 	goto cleanup;
30054925bf6Swillf 
30154925bf6Swillf     goto cleanup;
30254925bf6Swillf 
30354925bf6Swillf err_usage:
30454925bf6Swillf     print_usage = TRUE;
30554925bf6Swillf 
30654925bf6Swillf err_nomsg:
30754925bf6Swillf     no_msg = TRUE;
30854925bf6Swillf 
30954925bf6Swillf cleanup:
31054925bf6Swillf     /* Clean-up structure */
31154925bf6Swillf     krb5_ldap_free_policy (util_context, policyparams);
31254925bf6Swillf 
31354925bf6Swillf     if (print_usage)
31454925bf6Swillf 	db_usage(CREATE_POLICY);
31554925bf6Swillf 
31654925bf6Swillf     if (retval) {
31754925bf6Swillf 	if (!no_msg)
31854925bf6Swillf 	    com_err(me, retval, gettext("while creating policy object"));
31954925bf6Swillf 
32054925bf6Swillf 	exit_status++;
32154925bf6Swillf     }
32254925bf6Swillf 
32354925bf6Swillf     return;
32454925bf6Swillf }
32554925bf6Swillf 
32654925bf6Swillf 
32754925bf6Swillf /*
32854925bf6Swillf  * This function will destroy the specified ticket policy
32954925bf6Swillf  * object interactively, unless forced through an option.
33054925bf6Swillf  */
33154925bf6Swillf void
33254925bf6Swillf kdb5_ldap_destroy_policy(argc, argv)
33354925bf6Swillf     int argc;
33454925bf6Swillf     char *argv[];
33554925bf6Swillf {
336*dd9ccd46S     /* Solaris Kerberos */
337*dd9ccd46S     char *me = progname;
338*dd9ccd46S 
33954925bf6Swillf     krb5_error_code retval = 0;
34054925bf6Swillf     krb5_ldap_policy_params *policyparams = NULL;
34154925bf6Swillf     krb5_boolean print_usage = FALSE;
34254925bf6Swillf     krb5_boolean no_msg = FALSE;
34354925bf6Swillf     char *policy = NULL;
34454925bf6Swillf     unsigned int mask = 0;
34554925bf6Swillf     int force = 0;
34654925bf6Swillf     char buf[5] = {0};
34754925bf6Swillf     int i = 0;
34854925bf6Swillf 
34954925bf6Swillf     if ((argc < 2) || (argc > 3)) {
35054925bf6Swillf 	goto err_usage;
35154925bf6Swillf     }
35254925bf6Swillf 
35354925bf6Swillf     for (i = 1; i < argc; i++) {
35454925bf6Swillf 	if (strcmp(argv[i], "-force") == 0) {
35554925bf6Swillf 	    force++;
35654925bf6Swillf 	} else { /* Any other argument must be policy DN */
35754925bf6Swillf 	    /* First check if policy DN is already provided --
35854925bf6Swillf 	       if so, there's a usage error */
35954925bf6Swillf             if (policy != NULL)
36054925bf6Swillf 		goto err_usage;
36154925bf6Swillf 
36254925bf6Swillf 	    /* If not present already, fill up policy DN */
36354925bf6Swillf             policy = strdup(argv[i]);
36454925bf6Swillf             if (policy == NULL) {
36554925bf6Swillf 		retval = ENOMEM;
36654925bf6Swillf 		com_err(me, retval, gettext("while destroying policy object"));
36754925bf6Swillf 		goto err_nomsg;
36854925bf6Swillf 	    }
36954925bf6Swillf 	}
37054925bf6Swillf     }
37154925bf6Swillf 
37254925bf6Swillf     if (policy == NULL)
37354925bf6Swillf 	goto err_usage;
37454925bf6Swillf 
37554925bf6Swillf     if (!force) {
37654925bf6Swillf         printf(gettext("This will delete the policy object '%s', are you sure?\n"), policy);
37754925bf6Swillf 	printf(gettext("(type 'yes' to confirm)? "));
37854925bf6Swillf 
37954925bf6Swillf 	if (fgets(buf, sizeof(buf), stdin) == NULL) {
38054925bf6Swillf 	    retval = EINVAL;
38154925bf6Swillf 	    goto cleanup;
38254925bf6Swillf 	}
38354925bf6Swillf 
38454925bf6Swillf 	if (strcmp(buf, yes)) {
38554925bf6Swillf 	    exit_status++;
38654925bf6Swillf 	    goto cleanup;
38754925bf6Swillf 	}
38854925bf6Swillf     }
38954925bf6Swillf 
39054925bf6Swillf     if ((retval = init_ldap_realm (argc, argv)))
39154925bf6Swillf         goto err_nomsg;
39254925bf6Swillf 
39354925bf6Swillf     if ((retval = krb5_ldap_read_policy(util_context, policy, &policyparams, &mask)))
39454925bf6Swillf 	goto cleanup;
39554925bf6Swillf 
39654925bf6Swillf 
39754925bf6Swillf     if ((retval = krb5_ldap_delete_policy(util_context, policy)))
39854925bf6Swillf 	goto cleanup;
39954925bf6Swillf 
40054925bf6Swillf     printf(gettext("** policy object '%s' deleted.\n"), policy);
40154925bf6Swillf     goto cleanup;
40254925bf6Swillf 
40354925bf6Swillf 
40454925bf6Swillf err_usage:
40554925bf6Swillf     print_usage = TRUE;
40654925bf6Swillf 
40754925bf6Swillf err_nomsg:
40854925bf6Swillf     no_msg = TRUE;
40954925bf6Swillf 
41054925bf6Swillf cleanup:
41154925bf6Swillf     /* Clean-up structure */
41254925bf6Swillf     krb5_ldap_free_policy (util_context, policyparams);
41354925bf6Swillf 
41454925bf6Swillf     if (policy) {
41554925bf6Swillf 	free (policy);
41654925bf6Swillf     }
41754925bf6Swillf 
41854925bf6Swillf     if (print_usage) {
41954925bf6Swillf 	db_usage(DESTROY_POLICY);
42054925bf6Swillf     }
42154925bf6Swillf 
42254925bf6Swillf     if (retval) {
42354925bf6Swillf 	if (!no_msg)
42454925bf6Swillf 	    com_err(me, retval, gettext("while destroying policy object"));
42554925bf6Swillf 
42654925bf6Swillf 	exit_status++;
42754925bf6Swillf     }
42854925bf6Swillf 
42954925bf6Swillf     return;
43054925bf6Swillf }
43154925bf6Swillf 
43254925bf6Swillf 
43354925bf6Swillf /*
43454925bf6Swillf  * This function will modify the attributes of a given ticket
43554925bf6Swillf  * policy object.
43654925bf6Swillf  */
43754925bf6Swillf void
43854925bf6Swillf kdb5_ldap_modify_policy(argc, argv)
43954925bf6Swillf     int argc;
44054925bf6Swillf     char *argv[];
44154925bf6Swillf {
442*dd9ccd46S     /* Solaris Kerberos */
443*dd9ccd46S     char *me = progname;
444*dd9ccd46S 
44554925bf6Swillf     krb5_error_code retval = 0;
44654925bf6Swillf     krb5_ldap_policy_params *policyparams = NULL;
44754925bf6Swillf     krb5_boolean print_usage = FALSE;
44854925bf6Swillf     krb5_boolean no_msg = FALSE;
44954925bf6Swillf     char *policy = NULL;
45054925bf6Swillf     unsigned int in_mask = 0, out_mask = 0;
45154925bf6Swillf     time_t date = 0;
45254925bf6Swillf     time_t now = 0;
45354925bf6Swillf     int i = 0;
45454925bf6Swillf 
45554925bf6Swillf     /* Check for number of arguments -- minimum is 3
45654925bf6Swillf        since atleast one parameter should be given in
45754925bf6Swillf        addition to 'modify_policy' and policy DN */
45854925bf6Swillf     if ((argc < 3) || (argc > 16)) {
45954925bf6Swillf 	goto err_usage;
46054925bf6Swillf     }
46154925bf6Swillf 
46254925bf6Swillf     /* Parse all arguments, only to pick up policy DN (Pass 1) */
46354925bf6Swillf     for (i = 1; i < argc; i++) {
46454925bf6Swillf 	/* Skip arguments next to 'maxtktlife'
46554925bf6Swillf 	   and 'maxrenewlife' arguments */
46654925bf6Swillf 	if (!strcmp(argv[i], "-maxtktlife")) {
46754925bf6Swillf 	    ++i;
46854925bf6Swillf 	} else if (!strcmp(argv[i], "-maxrenewlife")) {
46954925bf6Swillf 	    ++i;
47054925bf6Swillf 	}
47154925bf6Swillf 	/* Do nothing for ticket flag arguments */
47254925bf6Swillf 	else if (!strcmp((argv[i] + 1), "allow_postdated") ||
47354925bf6Swillf 		 !strcmp((argv[i] + 1), "allow_forwardable") ||
47454925bf6Swillf 		 !strcmp((argv[i] + 1), "allow_renewable") ||
47554925bf6Swillf 		 !strcmp((argv[i] + 1), "allow_proxiable") ||
47654925bf6Swillf 		 !strcmp((argv[i] + 1), "allow_dup_skey") ||
47754925bf6Swillf 		 !strcmp((argv[i] + 1), "requires_preauth") ||
47854925bf6Swillf 		 !strcmp((argv[i] + 1), "requires_hwauth") ||
47954925bf6Swillf 		 !strcmp((argv[i] + 1), "allow_svr") ||
48054925bf6Swillf 		 !strcmp((argv[i] + 1), "allow_tgs_req") ||
48154925bf6Swillf 		 !strcmp((argv[i] + 1), "allow_tix") ||
48254925bf6Swillf 		 !strcmp((argv[i] + 1), "needchange") ||
48354925bf6Swillf 		 !strcmp((argv[i] + 1), "password_changing_service")) {
48454925bf6Swillf 	} else { /* Any other argument must be policy DN */
48554925bf6Swillf 	    /* First check if policy DN is already provided --
48654925bf6Swillf 	       if so, there's a usage error */
48754925bf6Swillf             if (policy != NULL)
48854925bf6Swillf 		goto err_usage;
48954925bf6Swillf 
49054925bf6Swillf 	    /* If not present already, fill up policy DN */
49154925bf6Swillf             policy = strdup(argv[i]);
49254925bf6Swillf             if (policy == NULL) {
49354925bf6Swillf 		retval = ENOMEM;
49454925bf6Swillf 		com_err(me, retval, gettext("while modifying policy object"));
49554925bf6Swillf 		goto err_nomsg;
49654925bf6Swillf 	    }
49754925bf6Swillf 	}
49854925bf6Swillf     }
49954925bf6Swillf 
50054925bf6Swillf     if (policy == NULL)
50154925bf6Swillf 	goto err_usage;
50254925bf6Swillf 
50354925bf6Swillf     if ((retval = init_ldap_realm (argc, argv)))
50454925bf6Swillf 	goto cleanup;
50554925bf6Swillf 
50654925bf6Swillf     retval = krb5_ldap_read_policy(util_context, policy, &policyparams, &in_mask);
50754925bf6Swillf     if (retval) {
50854925bf6Swillf         com_err(me, retval, gettext("while reading information of policy '%s'"), policy);
50954925bf6Swillf 	goto err_nomsg;
51054925bf6Swillf     }
51154925bf6Swillf 
51254925bf6Swillf     /* Get current time */
51354925bf6Swillf     time (&now);
51454925bf6Swillf 
51554925bf6Swillf     /* Parse all arguments, but skip policy DN (Pass 2) */
51654925bf6Swillf     for (i = 1; i < argc; i++) {
51754925bf6Swillf 	if (!strcmp(argv[i], "-maxtktlife")) {
51854925bf6Swillf 	    if (++i > argc - 1)
51954925bf6Swillf 		goto err_usage;
52054925bf6Swillf 
52154925bf6Swillf 	    date = get_date(argv[i]);
52254925bf6Swillf 	    if (date == (time_t)(-1)) {
52354925bf6Swillf 		retval = EINVAL;
52454925bf6Swillf 		com_err (me, retval, gettext("while providing time specification"));
52554925bf6Swillf 		goto err_nomsg;
52654925bf6Swillf 	    }
52754925bf6Swillf 
52854925bf6Swillf 	    policyparams->maxtktlife = date - now;
52954925bf6Swillf 
53054925bf6Swillf 	    out_mask |= LDAP_POLICY_MAXTKTLIFE;
53154925bf6Swillf 	} else if (!strcmp(argv[i], "-maxrenewlife")) {
53254925bf6Swillf 	    if (++i > argc - 1)
53354925bf6Swillf 		goto err_usage;
53454925bf6Swillf 
53554925bf6Swillf 	    date = get_date(argv[i]);
53654925bf6Swillf 	    if (date == (time_t)(-1)) {
53754925bf6Swillf 		retval = EINVAL;
53854925bf6Swillf 		com_err (me, retval, gettext("while providing time specification"));
53954925bf6Swillf 		goto err_nomsg;
54054925bf6Swillf 	    }
54154925bf6Swillf 
54254925bf6Swillf 	    policyparams->maxrenewlife = date - now;
54354925bf6Swillf 
54454925bf6Swillf 	    out_mask |= LDAP_POLICY_MAXRENEWLIFE;
54554925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "allow_postdated")) {
54654925bf6Swillf 	    if (*(argv[i]) == '+')
54754925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_POSTDATED);
54854925bf6Swillf 	    else if (*(argv[i]) == '-')
54954925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_POSTDATED;
55054925bf6Swillf 	    else
55154925bf6Swillf 		goto err_usage;
55254925bf6Swillf 
55354925bf6Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
55454925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "allow_forwardable")) {
55554925bf6Swillf 	    if (*(argv[i]) == '+')
55654925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_FORWARDABLE);
55754925bf6Swillf 	    else if (*(argv[i]) == '-')
55854925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_FORWARDABLE;
55954925bf6Swillf 	    else
56054925bf6Swillf 		goto err_usage;
56154925bf6Swillf 
56254925bf6Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
56354925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "allow_renewable")) {
56454925bf6Swillf 	    if (*(argv[i]) == '+')
56554925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_RENEWABLE);
56654925bf6Swillf 	    else if (*(argv[i]) == '-')
56754925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_RENEWABLE;
56854925bf6Swillf 	    else
56954925bf6Swillf 		goto err_usage;
57054925bf6Swillf 
57154925bf6Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
57254925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "allow_proxiable")) {
57354925bf6Swillf 	    if (*(argv[i]) == '+')
57454925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_PROXIABLE);
57554925bf6Swillf 	    else if (*(argv[i]) == '-')
57654925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_PROXIABLE;
57754925bf6Swillf 	    else
57854925bf6Swillf 		goto err_usage;
57954925bf6Swillf 
58054925bf6Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
58154925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "allow_dup_skey")) {
58254925bf6Swillf 	    if (*(argv[i]) == '+')
58354925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_DUP_SKEY);
58454925bf6Swillf 	    else if (*(argv[i]) == '-')
58554925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_DUP_SKEY;
58654925bf6Swillf 	    else
58754925bf6Swillf 		goto err_usage;
58854925bf6Swillf 
58954925bf6Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
59054925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "requires_preauth")) {
59154925bf6Swillf 	    if (*(argv[i]) == '+')
59254925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_REQUIRES_PRE_AUTH;
59354925bf6Swillf 	    else if (*(argv[i]) == '-')
59454925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_PRE_AUTH);
59554925bf6Swillf 	    else
59654925bf6Swillf 		goto err_usage;
59754925bf6Swillf 
59854925bf6Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
59954925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "requires_hwauth")) {
60054925bf6Swillf 	    if (*(argv[i]) == '+')
60154925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_REQUIRES_HW_AUTH;
60254925bf6Swillf 	    else if (*(argv[i]) == '-')
60354925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_HW_AUTH);
60454925bf6Swillf 	    else
60554925bf6Swillf 		goto err_usage;
60654925bf6Swillf 
60754925bf6Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
60854925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "allow_svr")) {
60954925bf6Swillf 	    if (*(argv[i]) == '+')
61054925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_SVR);
61154925bf6Swillf 	    else if (*(argv[i]) == '-')
61254925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_SVR;
61354925bf6Swillf 	    else
61454925bf6Swillf 		goto err_usage;
61554925bf6Swillf 
61654925bf6Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
61754925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "allow_tgs_req")) {
61854925bf6Swillf 	    if (*(argv[i]) == '+')
61954925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_TGT_BASED);
62054925bf6Swillf 	    else if (*(argv[i]) == '-')
62154925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_TGT_BASED;
62254925bf6Swillf 	    else
62354925bf6Swillf 		goto err_usage;
62454925bf6Swillf 
62554925bf6Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
62654925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "allow_tix")) {
62754925bf6Swillf 	    if (*(argv[i]) == '+')
62854925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_ALL_TIX);
62954925bf6Swillf 	    else if (*(argv[i]) == '-')
63054925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_ALL_TIX;
63154925bf6Swillf 	    else
63254925bf6Swillf 		goto err_usage;
63354925bf6Swillf 
63454925bf6Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
63554925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "needchange")) {
63654925bf6Swillf 	    if (*(argv[i]) == '+')
63754925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_REQUIRES_PWCHANGE;
63854925bf6Swillf 	    else if (*(argv[i]) == '-')
63954925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_PWCHANGE);
64054925bf6Swillf 	    else
64154925bf6Swillf 		goto err_usage;
64254925bf6Swillf 
64354925bf6Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
64454925bf6Swillf 	} else if (!strcmp((argv[i] + 1), "password_changing_service")) {
64554925bf6Swillf 	    if (*(argv[i]) == '+')
64654925bf6Swillf 		policyparams->tktflags |= KRB5_KDB_PWCHANGE_SERVICE;
64754925bf6Swillf 	    else if (*(argv[i]) == '-')
64854925bf6Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_PWCHANGE_SERVICE);
64954925bf6Swillf 	    else
65054925bf6Swillf 		goto err_usage;
65154925bf6Swillf 
65254925bf6Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
65354925bf6Swillf 	} else {
65454925bf6Swillf 	    /* Any other argument must be policy DN
65554925bf6Swillf 	       -- skip it */
65654925bf6Swillf 	}
65754925bf6Swillf     }
65854925bf6Swillf 
65954925bf6Swillf     /* Modify attributes of object */
66054925bf6Swillf     if ((retval = krb5_ldap_modify_policy(util_context, policyparams, out_mask)))
66154925bf6Swillf 	goto cleanup;
66254925bf6Swillf 
66354925bf6Swillf     goto cleanup;
66454925bf6Swillf 
66554925bf6Swillf err_usage:
66654925bf6Swillf     print_usage = TRUE;
66754925bf6Swillf 
66854925bf6Swillf err_nomsg:
66954925bf6Swillf     no_msg = TRUE;
67054925bf6Swillf 
67154925bf6Swillf cleanup:
67254925bf6Swillf     /* Clean-up structure */
67354925bf6Swillf     krb5_ldap_free_policy (util_context, policyparams);
67454925bf6Swillf 
67554925bf6Swillf     if (policy)
67654925bf6Swillf         free (policy);
67754925bf6Swillf 
67854925bf6Swillf     if (print_usage)
67954925bf6Swillf 	db_usage(MODIFY_POLICY);
68054925bf6Swillf 
68154925bf6Swillf     if (retval) {
68254925bf6Swillf 	if (!no_msg)
68354925bf6Swillf 	    com_err(me, retval, gettext("while modifying policy object"));
68454925bf6Swillf 
68554925bf6Swillf 	exit_status++;
68654925bf6Swillf     }
68754925bf6Swillf 
68854925bf6Swillf     return;
68954925bf6Swillf }
69054925bf6Swillf 
69154925bf6Swillf 
69254925bf6Swillf /*
69354925bf6Swillf  * This function will display information about the given policy object,
69454925bf6Swillf  * fetching the information from the LDAP Server.
69554925bf6Swillf  */
69654925bf6Swillf void
69754925bf6Swillf kdb5_ldap_view_policy(argc, argv)
69854925bf6Swillf     int argc;
69954925bf6Swillf     char *argv[];
70054925bf6Swillf {
701*dd9ccd46S     /* Solaris Kerberos */
702*dd9ccd46S     char *me = progname;
703*dd9ccd46S 
70454925bf6Swillf     krb5_ldap_policy_params *policyparams = NULL;
70554925bf6Swillf     krb5_error_code retval = 0;
70654925bf6Swillf     krb5_boolean print_usage = FALSE;
70754925bf6Swillf     char *policy = NULL;
70854925bf6Swillf     unsigned int mask = 0;
70954925bf6Swillf 
71054925bf6Swillf     if (argc != 2) {
71154925bf6Swillf 	goto err_usage;
71254925bf6Swillf     }
71354925bf6Swillf 
71454925bf6Swillf     policy = strdup(argv[1]);
71554925bf6Swillf     if (policy == NULL) {
71654925bf6Swillf 	com_err(me, ENOMEM, gettext("while viewing policy"));
71754925bf6Swillf 	exit_status++;
71854925bf6Swillf 	goto cleanup;
71954925bf6Swillf     }
72054925bf6Swillf 
72154925bf6Swillf     if ((retval = init_ldap_realm (argc, argv)))
72254925bf6Swillf         goto cleanup;
72354925bf6Swillf 
72454925bf6Swillf     if ((retval = krb5_ldap_read_policy(util_context, policy, &policyparams, &mask))) {
72554925bf6Swillf 	com_err(me, retval, gettext("while viewing policy '%s'"), policy);
72654925bf6Swillf 	exit_status++;
72754925bf6Swillf 	goto cleanup;
72854925bf6Swillf     }
72954925bf6Swillf 
73054925bf6Swillf     print_policy_params (policyparams, mask);
73154925bf6Swillf 
73254925bf6Swillf     goto cleanup;
73354925bf6Swillf 
73454925bf6Swillf err_usage:
73554925bf6Swillf     print_usage = TRUE;
73654925bf6Swillf 
73754925bf6Swillf cleanup:
73854925bf6Swillf     krb5_ldap_free_policy (util_context, policyparams);
73954925bf6Swillf 
74054925bf6Swillf     if (policy)
74154925bf6Swillf 	free (policy);
74254925bf6Swillf 
74354925bf6Swillf     if (print_usage) {
74454925bf6Swillf 	db_usage(VIEW_POLICY);
74554925bf6Swillf     }
74654925bf6Swillf 
74754925bf6Swillf     return;
74854925bf6Swillf }
74954925bf6Swillf 
75054925bf6Swillf 
75154925bf6Swillf /*
75254925bf6Swillf  * This function will print the policy object information to the
75354925bf6Swillf  * standard output.
75454925bf6Swillf  */
75554925bf6Swillf static void
75654925bf6Swillf print_policy_params(policyparams, mask)
75754925bf6Swillf     krb5_ldap_policy_params *policyparams;
75854925bf6Swillf     int mask;
75954925bf6Swillf {
76054925bf6Swillf     /* Print the policy DN */
76154925bf6Swillf     printf("%25s: %s\n", gettext("Ticket policy"), policyparams->policy);
76254925bf6Swillf 
76354925bf6Swillf     /* Print max. ticket life and max. renewable life, if present */
76454925bf6Swillf     if (mask & LDAP_POLICY_MAXTKTLIFE)
76554925bf6Swillf 	printf("%25s: %s\n", gettext("Maximum ticket life"), strdur(policyparams->maxtktlife));
76654925bf6Swillf     if (mask & LDAP_POLICY_MAXRENEWLIFE)
76754925bf6Swillf 	printf("%25s: %s\n", gettext("Maximum renewable life"), strdur(policyparams->maxrenewlife));
76854925bf6Swillf 
76954925bf6Swillf     /* Service flags are printed */
77054925bf6Swillf     printf("%25s: ", gettext("Ticket flags"));
77154925bf6Swillf     if (mask & LDAP_POLICY_TKTFLAGS) {
77254925bf6Swillf 	int ticketflags = policyparams->tktflags;
77354925bf6Swillf 
77454925bf6Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_POSTDATED)
77554925bf6Swillf 	    printf("%s ","DISALLOW_POSTDATED");
77654925bf6Swillf 
77754925bf6Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_FORWARDABLE)
77854925bf6Swillf 	    printf("%s ","DISALLOW_FORWARDABLE");
77954925bf6Swillf 
78054925bf6Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_RENEWABLE)
78154925bf6Swillf 	    printf("%s ","DISALLOW_RENEWABLE");
78254925bf6Swillf 
78354925bf6Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_PROXIABLE)
78454925bf6Swillf 	    printf("%s ","DISALLOW_PROXIABLE");
78554925bf6Swillf 
78654925bf6Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_DUP_SKEY)
78754925bf6Swillf 	    printf("%s ","DISALLOW_DUP_SKEY");
78854925bf6Swillf 
78954925bf6Swillf 	if (ticketflags & KRB5_KDB_REQUIRES_PRE_AUTH)
79054925bf6Swillf 	    printf("%s ","REQUIRES_PRE_AUTH");
79154925bf6Swillf 
79254925bf6Swillf 	if (ticketflags & KRB5_KDB_REQUIRES_HW_AUTH)
79354925bf6Swillf 	    printf("%s ","REQUIRES_HW_AUTH");
79454925bf6Swillf 
79554925bf6Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_SVR)
79654925bf6Swillf 	    printf("%s ","DISALLOW_SVR");
79754925bf6Swillf 
79854925bf6Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_TGT_BASED)
79954925bf6Swillf 	    printf("%s ","DISALLOW_TGT_BASED");
80054925bf6Swillf 
80154925bf6Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_ALL_TIX)
80254925bf6Swillf 	    printf("%s ","DISALLOW_ALL_TIX");
80354925bf6Swillf 
80454925bf6Swillf 	if (ticketflags & KRB5_KDB_REQUIRES_PWCHANGE)
80554925bf6Swillf 	    printf("%s ","REQUIRES_PWCHANGE");
80654925bf6Swillf 
80754925bf6Swillf 	if (ticketflags & KRB5_KDB_PWCHANGE_SERVICE)
80854925bf6Swillf 	    printf("%s ","PWCHANGE_SERVICE");
80954925bf6Swillf     }
81054925bf6Swillf     printf("\n");
81154925bf6Swillf 
81254925bf6Swillf     return;
81354925bf6Swillf }
81454925bf6Swillf 
81554925bf6Swillf 
81654925bf6Swillf /*
81754925bf6Swillf  * This function will list the DNs of policy objects under a specific
81854925bf6Swillf  * sub-tree (entire tree by default)
81954925bf6Swillf  */
82054925bf6Swillf void kdb5_ldap_list_policies(argc, argv)
82154925bf6Swillf     int argc;
82254925bf6Swillf     char *argv[];
82354925bf6Swillf {
824*dd9ccd46S     /* Solaris Kerberos */
825*dd9ccd46S     char *me = progname;
826*dd9ccd46S 
82754925bf6Swillf     krb5_error_code retval = 0;
82854925bf6Swillf     krb5_boolean print_usage = FALSE;
82954925bf6Swillf     char *basedn = NULL;
83054925bf6Swillf     char **list = NULL;
83154925bf6Swillf     char **plist = NULL;
83254925bf6Swillf 
83354925bf6Swillf     /* Check for number of arguments */
83454925bf6Swillf     if ((argc != 1) && (argc != 3)) {
83554925bf6Swillf 	goto err_usage;
83654925bf6Swillf     }
83754925bf6Swillf 
83854925bf6Swillf     if ((retval = init_ldap_realm (argc, argv)))
83954925bf6Swillf 	goto cleanup;
84054925bf6Swillf 
84154925bf6Swillf     retval = krb5_ldap_list_policy(util_context, basedn, &list);
84254925bf6Swillf     if ((retval != 0) || (list == NULL))
84354925bf6Swillf 	goto cleanup;
84454925bf6Swillf 
84554925bf6Swillf     for (plist = list; *plist != NULL; plist++) {
84654925bf6Swillf 	printf("%s\n", *plist);
84754925bf6Swillf     }
84854925bf6Swillf 
84954925bf6Swillf     goto cleanup;
85054925bf6Swillf 
85154925bf6Swillf err_usage:
85254925bf6Swillf     print_usage = TRUE;
85354925bf6Swillf 
85454925bf6Swillf cleanup:
85554925bf6Swillf     if (list != NULL) {
85654925bf6Swillf 	krb5_free_list_entries (list);
85754925bf6Swillf 	free (list);
85854925bf6Swillf     }
85954925bf6Swillf 
86054925bf6Swillf     if (basedn)
86154925bf6Swillf 	free (basedn);
86254925bf6Swillf 
86354925bf6Swillf     if (print_usage) {
86454925bf6Swillf 	db_usage(LIST_POLICY);
86554925bf6Swillf     }
86654925bf6Swillf 
86754925bf6Swillf     if (retval) {
86854925bf6Swillf 	com_err(me, retval, gettext("while listing policy objects"));
86954925bf6Swillf 	exit_status++;
87054925bf6Swillf     }
87154925bf6Swillf 
87254925bf6Swillf     return;
87354925bf6Swillf }
87454925bf6Swillf 
87554925bf6Swillf 
87654925bf6Swillf /* Reproduced from kadmin.c, instead of linking
87754925bf6Swillf    the entire kadmin.o */
87854925bf6Swillf static char *strdur(duration)
87954925bf6Swillf     time_t duration;
88054925bf6Swillf {
88154925bf6Swillf     static char out[50];
88254925bf6Swillf     int neg, days, hours, minutes, seconds;
88354925bf6Swillf 
88454925bf6Swillf     if (duration < 0) {
88554925bf6Swillf 	duration *= -1;
88654925bf6Swillf 	neg = 1;
88754925bf6Swillf     } else
88854925bf6Swillf 	neg = 0;
88954925bf6Swillf     days = duration / (24 * 3600);
89054925bf6Swillf     duration %= 24 * 3600;
89154925bf6Swillf     hours = duration / 3600;
89254925bf6Swillf     duration %= 3600;
89354925bf6Swillf     minutes = duration / 60;
89454925bf6Swillf     duration %= 60;
89554925bf6Swillf     seconds = duration;
89654925bf6Swillf     snprintf(out, sizeof(out), "%s%d %s %02d:%02d:%02d", neg ? "-" : "",
89754925bf6Swillf 	    days, days == 1 ? gettext("day") : gettext("days"),
89854925bf6Swillf 	    hours, minutes, seconds);
89954925bf6Swillf     return out;
90054925bf6Swillf }
901