xref: /onnv-gate/usr/src/cmd/krb5/ldap_util/kdb5_ldap_policy.c (revision 8092:19771b16f0a8)
14960Swillf 
24960Swillf /*
34960Swillf  * kadmin/ldap_util/kdb5_ldap_policy.c
44960Swillf  */
54960Swillf 
6*8092SMark.Phalan@Sun.COM /*
7*8092SMark.Phalan@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
8*8092SMark.Phalan@Sun.COM  * Use is subject to license terms.
9*8092SMark.Phalan@Sun.COM  */
10*8092SMark.Phalan@Sun.COM 
114960Swillf /* Copyright (c) 2004-2005, Novell, Inc.
124960Swillf  * All rights reserved.
134960Swillf  *
144960Swillf  * Redistribution and use in source and binary forms, with or without
154960Swillf  * modification, are permitted provided that the following conditions are met:
164960Swillf  *
174960Swillf  *   * Redistributions of source code must retain the above copyright notice,
184960Swillf  *       this list of conditions and the following disclaimer.
194960Swillf  *   * Redistributions in binary form must reproduce the above copyright
204960Swillf  *       notice, this list of conditions and the following disclaimer in the
214960Swillf  *       documentation and/or other materials provided with the distribution.
224960Swillf  *   * The copyright holder's name is not used to endorse or promote products
234960Swillf  *       derived from this software without specific prior written permission.
244960Swillf  *
254960Swillf  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
264960Swillf  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
274960Swillf  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
284960Swillf  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
294960Swillf  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
304960Swillf  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
314960Swillf  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
324960Swillf  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
334960Swillf  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
344960Swillf  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
354960Swillf  * POSSIBILITY OF SUCH DAMAGE.
364960Swillf  */
374960Swillf 
384960Swillf /*
394960Swillf  * Create / Delete / Modify / View / List policy objects.
404960Swillf  */
414960Swillf 
424960Swillf #include <stdio.h>
434960Swillf #include <time.h>
444960Swillf #include <k5-int.h>
454960Swillf #include <kadm5/admin.h>
464960Swillf #include <libintl.h>
474960Swillf #include <locale.h>
484960Swillf #include "kdb5_ldap_util.h"
494960Swillf #include "kdb5_ldap_list.h"
504960Swillf #include "ldap_tkt_policy.h"
514960Swillf extern time_t get_date(char *); /* kadmin/cli/getdate.o */
524960Swillf 
534960Swillf static void print_policy_params(krb5_ldap_policy_params *policyparams, int mask);
544960Swillf static char *strdur(time_t duration);
554960Swillf 
564960Swillf extern char *yes;
574960Swillf extern kadm5_config_params global_params;
58*8092SMark.Phalan@Sun.COM 
init_ldap_realm(int argc,char * argv[])594960Swillf static krb5_error_code init_ldap_realm (int argc, char *argv[]) {
604960Swillf     /* This operation is being performed in the context of a realm. So,
614960Swillf      * initialize the realm */
624960Swillf     int mask = 0;
634960Swillf     krb5_error_code retval = 0;
644960Swillf     kdb5_dal_handle *dal_handle = NULL;
654960Swillf     krb5_ldap_context *ldap_context=NULL;
664960Swillf 
674960Swillf     dal_handle = (kdb5_dal_handle *) util_context->db_context;
684960Swillf     ldap_context = (krb5_ldap_context *) dal_handle->db_context;
694960Swillf     if (!ldap_context) {
704960Swillf         retval = EINVAL;
714960Swillf         goto cleanup;
724960Swillf     }
734960Swillf 
744960Swillf     if (ldap_context->krbcontainer == NULL) {
754960Swillf         retval = krb5_ldap_read_krbcontainer_params (util_context,
764960Swillf                 &(ldap_context->krbcontainer));
774960Swillf         if (retval != 0) {
78*8092SMark.Phalan@Sun.COM 	    /* Solaris Kerberos */
79*8092SMark.Phalan@Sun.COM             com_err(progname, retval, gettext("while reading kerberos container information"));
804960Swillf             goto cleanup;
814960Swillf         }
824960Swillf     }
834960Swillf 
844960Swillf     if (ldap_context->lrparams == NULL) {
854960Swillf         retval = krb5_ldap_read_realm_params(util_context,
864960Swillf                 global_params.realm,
874960Swillf                 &(ldap_context->lrparams),
884960Swillf                 &mask);
894960Swillf 
904960Swillf         if (retval != 0) {
914960Swillf             goto cleanup;
924960Swillf         }
934960Swillf     }
944960Swillf cleanup:
954960Swillf     return retval;
964960Swillf }
974960Swillf 
984960Swillf /*
994960Swillf  * This function will create a ticket policy object with the
1004960Swillf  * specified attributes.
1014960Swillf  */
1024960Swillf void
kdb5_ldap_create_policy(argc,argv)1034960Swillf kdb5_ldap_create_policy(argc, argv)
1044960Swillf     int argc;
1054960Swillf     char *argv[];
1064960Swillf {
107*8092SMark.Phalan@Sun.COM     /* Solaris Kerberos */
108*8092SMark.Phalan@Sun.COM     char *me = progname;
109*8092SMark.Phalan@Sun.COM 
1104960Swillf     krb5_error_code retval = 0;
1114960Swillf     krb5_ldap_policy_params *policyparams = NULL;
1124960Swillf     krb5_boolean print_usage = FALSE;
1134960Swillf     krb5_boolean no_msg = FALSE;
1144960Swillf     int mask = 0;
1154960Swillf     time_t date = 0;
1164960Swillf     time_t now = 0;
1174960Swillf     int i = 0;
1184960Swillf 
1194960Swillf     /* Check for number of arguments */
1204960Swillf     if ((argc < 2) || (argc > 16)) {
1214960Swillf 	goto err_usage;
1224960Swillf     }
1234960Swillf 
1244960Swillf     /* Allocate memory for policy parameters structure */
1254960Swillf     policyparams = (krb5_ldap_policy_params*) calloc(1, sizeof(krb5_ldap_policy_params));
1264960Swillf     if (policyparams == NULL) {
1274960Swillf 	retval = ENOMEM;
1284960Swillf 	goto cleanup;
1294960Swillf     }
1304960Swillf 
1314960Swillf     /* Get current time */
1324960Swillf     time (&now);
1334960Swillf 
1344960Swillf     /* Parse all arguments */
1354960Swillf     for (i = 1; i < argc; i++) {
1364960Swillf 	if (!strcmp(argv[i], "-maxtktlife")) {
1374960Swillf 	    if (++i > argc - 1)
1384960Swillf 		goto err_usage;
1394960Swillf 
1404960Swillf 	    date = get_date(argv[i]);
1414960Swillf 	    if (date == (time_t)(-1)) {
1424960Swillf 		retval = EINVAL;
1434960Swillf 		com_err (me, retval, gettext("while providing time specification"));
1444960Swillf 		goto err_nomsg;
1454960Swillf 	    }
1464960Swillf 
1474960Swillf 	    policyparams->maxtktlife = date - now;
1484960Swillf 
1494960Swillf 	    mask |= LDAP_POLICY_MAXTKTLIFE;
1504960Swillf 	} else if (!strcmp(argv[i], "-maxrenewlife")) {
1514960Swillf 	    if (++i > argc - 1)
1524960Swillf 		goto err_usage;
1534960Swillf 
1544960Swillf 	    date = get_date(argv[i]);
1554960Swillf 	    if (date == (time_t)(-1)) {
1564960Swillf 		retval = EINVAL;
1574960Swillf 		com_err (me, retval, gettext("while providing time specification"));
1584960Swillf 		goto err_nomsg;
1594960Swillf 	    }
1604960Swillf 
1614960Swillf 	    policyparams->maxrenewlife = date - now;
1624960Swillf 
1634960Swillf 	    mask |= LDAP_POLICY_MAXRENEWLIFE;
1644960Swillf 	} else if (!strcmp((argv[i] + 1), "allow_postdated")) {
1654960Swillf 	    if (*(argv[i]) == '+')
1664960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_POSTDATED);
1674960Swillf 	    else if (*(argv[i]) == '-')
1684960Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_POSTDATED;
1694960Swillf 	    else
1704960Swillf 		goto err_usage;
1714960Swillf 
1724960Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
1734960Swillf 	} else if (!strcmp((argv[i] + 1), "allow_forwardable")) {
1744960Swillf 	    if (*(argv[i]) == '+')
1754960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_FORWARDABLE);
1764960Swillf 	    else if (*(argv[i]) == '-')
1774960Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_FORWARDABLE;
1784960Swillf 	    else
1794960Swillf 		goto err_usage;
1804960Swillf 
1814960Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
1824960Swillf 	} else if (!strcmp((argv[i] + 1), "allow_renewable")) {
1834960Swillf 	    if (*(argv[i]) == '+')
1844960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_RENEWABLE);
1854960Swillf 	    else if (*(argv[i]) == '-')
1864960Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_RENEWABLE;
1874960Swillf 	    else
1884960Swillf 		goto err_usage;
1894960Swillf 
1904960Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
1914960Swillf 	} else if (!strcmp((argv[i] + 1), "allow_proxiable")) {
1924960Swillf 	    if (*(argv[i]) == '+')
1934960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_PROXIABLE);
1944960Swillf 	    else if (*(argv[i]) == '-')
1954960Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_PROXIABLE;
1964960Swillf 	    else
1974960Swillf 		goto err_usage;
1984960Swillf 
1994960Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
2004960Swillf 	} else if (!strcmp((argv[i] + 1), "allow_dup_skey")) {
2014960Swillf 	    if (*(argv[i]) == '+')
2024960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_DUP_SKEY);
2034960Swillf 	    else if (*(argv[i]) == '-')
2044960Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_DUP_SKEY;
2054960Swillf 	    else
2064960Swillf 		goto err_usage;
2074960Swillf 
2084960Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
2094960Swillf 	} else if (!strcmp((argv[i] + 1), "requires_preauth")) {
2104960Swillf 	    if (*(argv[i]) == '+')
2114960Swillf 		policyparams->tktflags |= KRB5_KDB_REQUIRES_PRE_AUTH;
2124960Swillf 	    else if (*(argv[i]) == '-')
2134960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_PRE_AUTH);
2144960Swillf 	    else
2154960Swillf 		goto err_usage;
2164960Swillf 
2174960Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
2184960Swillf 	} else if (!strcmp((argv[i] + 1), "requires_hwauth")) {
2194960Swillf 	    if (*(argv[i]) == '+')
2204960Swillf 		policyparams->tktflags |= KRB5_KDB_REQUIRES_HW_AUTH;
2214960Swillf 	    else if (*(argv[i]) == '-')
2224960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_HW_AUTH);
2234960Swillf 	    else
2244960Swillf 		goto err_usage;
2254960Swillf 
2264960Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
2274960Swillf 	} else if (!strcmp((argv[i] + 1), "allow_svr")) {
2284960Swillf 	    if (*(argv[i]) == '+')
2294960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_SVR);
2304960Swillf 	    else if (*(argv[i]) == '-')
2314960Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_SVR;
2324960Swillf 	    else
2334960Swillf 		goto err_usage;
2344960Swillf 
2354960Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
2364960Swillf 	} else if (!strcmp((argv[i] + 1), "allow_tgs_req")) {
2374960Swillf 	    if (*(argv[i]) == '+')
2384960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_TGT_BASED);
2394960Swillf 	    else if (*(argv[i]) == '-')
2404960Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_TGT_BASED;
2414960Swillf 	    else
2424960Swillf 		goto err_usage;
2434960Swillf 
2444960Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
2454960Swillf 	} else if (!strcmp((argv[i] + 1), "allow_tix")) {
2464960Swillf 	    if (*(argv[i]) == '+')
2474960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_ALL_TIX);
2484960Swillf 	    else if (*(argv[i]) == '-')
2494960Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_ALL_TIX;
2504960Swillf 	    else
2514960Swillf 		goto err_usage;
2524960Swillf 
2534960Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
2544960Swillf 	} else if (!strcmp((argv[i] + 1), "needchange")) {
2554960Swillf 	    if (*(argv[i]) == '+')
2564960Swillf 		policyparams->tktflags |= KRB5_KDB_REQUIRES_PWCHANGE;
2574960Swillf 	    else if (*(argv[i]) == '-')
2584960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_PWCHANGE);
2594960Swillf 	    else
2604960Swillf 		goto err_usage;
2614960Swillf 
2624960Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
2634960Swillf 	} else if (!strcmp((argv[i] + 1), "password_changing_service")) {
2644960Swillf 	    if (*(argv[i]) == '+')
2654960Swillf 		policyparams->tktflags |= KRB5_KDB_PWCHANGE_SERVICE;
2664960Swillf 	    else if (*(argv[i]) == '-')
2674960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_PWCHANGE_SERVICE);
2684960Swillf 	    else
2694960Swillf 		goto err_usage;
2704960Swillf 
2714960Swillf 	    mask |= LDAP_POLICY_TKTFLAGS;
2724960Swillf 	} else { /* Any other argument must be policy DN */
2734960Swillf 	    /* First check if policy DN is already provided --
2744960Swillf 	       if so, there's a usage error */
2754960Swillf             if (policyparams->policy != NULL)
2764960Swillf 		goto err_usage;
2774960Swillf 
2784960Swillf 	    /* If not present already, fill up policy DN */
2794960Swillf             policyparams->policy = strdup(argv[i]);
2804960Swillf             if (policyparams->policy == NULL) {
2814960Swillf 		retval = ENOMEM;
2824960Swillf 		com_err(me, retval, gettext("while creating policy object"));
2834960Swillf 		goto err_nomsg;
2844960Swillf 	    }
2854960Swillf 	}
2864960Swillf     }
2874960Swillf 
2884960Swillf     /* policy DN is a mandatory argument. If not provided, print usage */
2894960Swillf     if (policyparams->policy == NULL)
2904960Swillf 	goto err_usage;
2914960Swillf 
2924960Swillf     if ((retval = init_ldap_realm (argc, argv))) {
2934960Swillf         com_err(me, retval, gettext("while reading realm information"));
2944960Swillf         goto err_nomsg;
2954960Swillf     }
2964960Swillf 
2974960Swillf     /* Create object with all attributes provided */
2984960Swillf     if ((retval = krb5_ldap_create_policy(util_context, policyparams, mask)) != 0)
2994960Swillf 	goto cleanup;
3004960Swillf 
3014960Swillf     goto cleanup;
3024960Swillf 
3034960Swillf err_usage:
3044960Swillf     print_usage = TRUE;
3054960Swillf 
3064960Swillf err_nomsg:
3074960Swillf     no_msg = TRUE;
3084960Swillf 
3094960Swillf cleanup:
3104960Swillf     /* Clean-up structure */
3114960Swillf     krb5_ldap_free_policy (util_context, policyparams);
3124960Swillf 
3134960Swillf     if (print_usage)
3144960Swillf 	db_usage(CREATE_POLICY);
3154960Swillf 
3164960Swillf     if (retval) {
3174960Swillf 	if (!no_msg)
3184960Swillf 	    com_err(me, retval, gettext("while creating policy object"));
3194960Swillf 
3204960Swillf 	exit_status++;
3214960Swillf     }
3224960Swillf 
3234960Swillf     return;
3244960Swillf }
3254960Swillf 
3264960Swillf 
3274960Swillf /*
3284960Swillf  * This function will destroy the specified ticket policy
3294960Swillf  * object interactively, unless forced through an option.
3304960Swillf  */
3314960Swillf void
kdb5_ldap_destroy_policy(argc,argv)3324960Swillf kdb5_ldap_destroy_policy(argc, argv)
3334960Swillf     int argc;
3344960Swillf     char *argv[];
3354960Swillf {
336*8092SMark.Phalan@Sun.COM     /* Solaris Kerberos */
337*8092SMark.Phalan@Sun.COM     char *me = progname;
338*8092SMark.Phalan@Sun.COM 
3394960Swillf     krb5_error_code retval = 0;
3404960Swillf     krb5_ldap_policy_params *policyparams = NULL;
3414960Swillf     krb5_boolean print_usage = FALSE;
3424960Swillf     krb5_boolean no_msg = FALSE;
3434960Swillf     char *policy = NULL;
3444960Swillf     unsigned int mask = 0;
3454960Swillf     int force = 0;
3464960Swillf     char buf[5] = {0};
3474960Swillf     int i = 0;
3484960Swillf 
3494960Swillf     if ((argc < 2) || (argc > 3)) {
3504960Swillf 	goto err_usage;
3514960Swillf     }
3524960Swillf 
3534960Swillf     for (i = 1; i < argc; i++) {
3544960Swillf 	if (strcmp(argv[i], "-force") == 0) {
3554960Swillf 	    force++;
3564960Swillf 	} else { /* Any other argument must be policy DN */
3574960Swillf 	    /* First check if policy DN is already provided --
3584960Swillf 	       if so, there's a usage error */
3594960Swillf             if (policy != NULL)
3604960Swillf 		goto err_usage;
3614960Swillf 
3624960Swillf 	    /* If not present already, fill up policy DN */
3634960Swillf             policy = strdup(argv[i]);
3644960Swillf             if (policy == NULL) {
3654960Swillf 		retval = ENOMEM;
3664960Swillf 		com_err(me, retval, gettext("while destroying policy object"));
3674960Swillf 		goto err_nomsg;
3684960Swillf 	    }
3694960Swillf 	}
3704960Swillf     }
3714960Swillf 
3724960Swillf     if (policy == NULL)
3734960Swillf 	goto err_usage;
3744960Swillf 
3754960Swillf     if (!force) {
3764960Swillf         printf(gettext("This will delete the policy object '%s', are you sure?\n"), policy);
3774960Swillf 	printf(gettext("(type 'yes' to confirm)? "));
3784960Swillf 
3794960Swillf 	if (fgets(buf, sizeof(buf), stdin) == NULL) {
3804960Swillf 	    retval = EINVAL;
3814960Swillf 	    goto cleanup;
3824960Swillf 	}
3834960Swillf 
3844960Swillf 	if (strcmp(buf, yes)) {
3854960Swillf 	    exit_status++;
3864960Swillf 	    goto cleanup;
3874960Swillf 	}
3884960Swillf     }
3894960Swillf 
3904960Swillf     if ((retval = init_ldap_realm (argc, argv)))
3914960Swillf         goto err_nomsg;
3924960Swillf 
3934960Swillf     if ((retval = krb5_ldap_read_policy(util_context, policy, &policyparams, &mask)))
3944960Swillf 	goto cleanup;
3954960Swillf 
3964960Swillf 
3974960Swillf     if ((retval = krb5_ldap_delete_policy(util_context, policy)))
3984960Swillf 	goto cleanup;
3994960Swillf 
4004960Swillf     printf(gettext("** policy object '%s' deleted.\n"), policy);
4014960Swillf     goto cleanup;
4024960Swillf 
4034960Swillf 
4044960Swillf err_usage:
4054960Swillf     print_usage = TRUE;
4064960Swillf 
4074960Swillf err_nomsg:
4084960Swillf     no_msg = TRUE;
4094960Swillf 
4104960Swillf cleanup:
4114960Swillf     /* Clean-up structure */
4124960Swillf     krb5_ldap_free_policy (util_context, policyparams);
4134960Swillf 
4144960Swillf     if (policy) {
4154960Swillf 	free (policy);
4164960Swillf     }
4174960Swillf 
4184960Swillf     if (print_usage) {
4194960Swillf 	db_usage(DESTROY_POLICY);
4204960Swillf     }
4214960Swillf 
4224960Swillf     if (retval) {
4234960Swillf 	if (!no_msg)
4244960Swillf 	    com_err(me, retval, gettext("while destroying policy object"));
4254960Swillf 
4264960Swillf 	exit_status++;
4274960Swillf     }
4284960Swillf 
4294960Swillf     return;
4304960Swillf }
4314960Swillf 
4324960Swillf 
4334960Swillf /*
4344960Swillf  * This function will modify the attributes of a given ticket
4354960Swillf  * policy object.
4364960Swillf  */
4374960Swillf void
kdb5_ldap_modify_policy(argc,argv)4384960Swillf kdb5_ldap_modify_policy(argc, argv)
4394960Swillf     int argc;
4404960Swillf     char *argv[];
4414960Swillf {
442*8092SMark.Phalan@Sun.COM     /* Solaris Kerberos */
443*8092SMark.Phalan@Sun.COM     char *me = progname;
444*8092SMark.Phalan@Sun.COM 
4454960Swillf     krb5_error_code retval = 0;
4464960Swillf     krb5_ldap_policy_params *policyparams = NULL;
4474960Swillf     krb5_boolean print_usage = FALSE;
4484960Swillf     krb5_boolean no_msg = FALSE;
4494960Swillf     char *policy = NULL;
4504960Swillf     unsigned int in_mask = 0, out_mask = 0;
4514960Swillf     time_t date = 0;
4524960Swillf     time_t now = 0;
4534960Swillf     int i = 0;
4544960Swillf 
4554960Swillf     /* Check for number of arguments -- minimum is 3
4564960Swillf        since atleast one parameter should be given in
4574960Swillf        addition to 'modify_policy' and policy DN */
4584960Swillf     if ((argc < 3) || (argc > 16)) {
4594960Swillf 	goto err_usage;
4604960Swillf     }
4614960Swillf 
4624960Swillf     /* Parse all arguments, only to pick up policy DN (Pass 1) */
4634960Swillf     for (i = 1; i < argc; i++) {
4644960Swillf 	/* Skip arguments next to 'maxtktlife'
4654960Swillf 	   and 'maxrenewlife' arguments */
4664960Swillf 	if (!strcmp(argv[i], "-maxtktlife")) {
4674960Swillf 	    ++i;
4684960Swillf 	} else if (!strcmp(argv[i], "-maxrenewlife")) {
4694960Swillf 	    ++i;
4704960Swillf 	}
4714960Swillf 	/* Do nothing for ticket flag arguments */
4724960Swillf 	else if (!strcmp((argv[i] + 1), "allow_postdated") ||
4734960Swillf 		 !strcmp((argv[i] + 1), "allow_forwardable") ||
4744960Swillf 		 !strcmp((argv[i] + 1), "allow_renewable") ||
4754960Swillf 		 !strcmp((argv[i] + 1), "allow_proxiable") ||
4764960Swillf 		 !strcmp((argv[i] + 1), "allow_dup_skey") ||
4774960Swillf 		 !strcmp((argv[i] + 1), "requires_preauth") ||
4784960Swillf 		 !strcmp((argv[i] + 1), "requires_hwauth") ||
4794960Swillf 		 !strcmp((argv[i] + 1), "allow_svr") ||
4804960Swillf 		 !strcmp((argv[i] + 1), "allow_tgs_req") ||
4814960Swillf 		 !strcmp((argv[i] + 1), "allow_tix") ||
4824960Swillf 		 !strcmp((argv[i] + 1), "needchange") ||
4834960Swillf 		 !strcmp((argv[i] + 1), "password_changing_service")) {
4844960Swillf 	} else { /* Any other argument must be policy DN */
4854960Swillf 	    /* First check if policy DN is already provided --
4864960Swillf 	       if so, there's a usage error */
4874960Swillf             if (policy != NULL)
4884960Swillf 		goto err_usage;
4894960Swillf 
4904960Swillf 	    /* If not present already, fill up policy DN */
4914960Swillf             policy = strdup(argv[i]);
4924960Swillf             if (policy == NULL) {
4934960Swillf 		retval = ENOMEM;
4944960Swillf 		com_err(me, retval, gettext("while modifying policy object"));
4954960Swillf 		goto err_nomsg;
4964960Swillf 	    }
4974960Swillf 	}
4984960Swillf     }
4994960Swillf 
5004960Swillf     if (policy == NULL)
5014960Swillf 	goto err_usage;
5024960Swillf 
5034960Swillf     if ((retval = init_ldap_realm (argc, argv)))
5044960Swillf 	goto cleanup;
5054960Swillf 
5064960Swillf     retval = krb5_ldap_read_policy(util_context, policy, &policyparams, &in_mask);
5074960Swillf     if (retval) {
5084960Swillf         com_err(me, retval, gettext("while reading information of policy '%s'"), policy);
5094960Swillf 	goto err_nomsg;
5104960Swillf     }
5114960Swillf 
5124960Swillf     /* Get current time */
5134960Swillf     time (&now);
5144960Swillf 
5154960Swillf     /* Parse all arguments, but skip policy DN (Pass 2) */
5164960Swillf     for (i = 1; i < argc; i++) {
5174960Swillf 	if (!strcmp(argv[i], "-maxtktlife")) {
5184960Swillf 	    if (++i > argc - 1)
5194960Swillf 		goto err_usage;
5204960Swillf 
5214960Swillf 	    date = get_date(argv[i]);
5224960Swillf 	    if (date == (time_t)(-1)) {
5234960Swillf 		retval = EINVAL;
5244960Swillf 		com_err (me, retval, gettext("while providing time specification"));
5254960Swillf 		goto err_nomsg;
5264960Swillf 	    }
5274960Swillf 
5284960Swillf 	    policyparams->maxtktlife = date - now;
5294960Swillf 
5304960Swillf 	    out_mask |= LDAP_POLICY_MAXTKTLIFE;
5314960Swillf 	} else if (!strcmp(argv[i], "-maxrenewlife")) {
5324960Swillf 	    if (++i > argc - 1)
5334960Swillf 		goto err_usage;
5344960Swillf 
5354960Swillf 	    date = get_date(argv[i]);
5364960Swillf 	    if (date == (time_t)(-1)) {
5374960Swillf 		retval = EINVAL;
5384960Swillf 		com_err (me, retval, gettext("while providing time specification"));
5394960Swillf 		goto err_nomsg;
5404960Swillf 	    }
5414960Swillf 
5424960Swillf 	    policyparams->maxrenewlife = date - now;
5434960Swillf 
5444960Swillf 	    out_mask |= LDAP_POLICY_MAXRENEWLIFE;
5454960Swillf 	} else if (!strcmp((argv[i] + 1), "allow_postdated")) {
5464960Swillf 	    if (*(argv[i]) == '+')
5474960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_POSTDATED);
5484960Swillf 	    else if (*(argv[i]) == '-')
5494960Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_POSTDATED;
5504960Swillf 	    else
5514960Swillf 		goto err_usage;
5524960Swillf 
5534960Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
5544960Swillf 	} else if (!strcmp((argv[i] + 1), "allow_forwardable")) {
5554960Swillf 	    if (*(argv[i]) == '+')
5564960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_FORWARDABLE);
5574960Swillf 	    else if (*(argv[i]) == '-')
5584960Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_FORWARDABLE;
5594960Swillf 	    else
5604960Swillf 		goto err_usage;
5614960Swillf 
5624960Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
5634960Swillf 	} else if (!strcmp((argv[i] + 1), "allow_renewable")) {
5644960Swillf 	    if (*(argv[i]) == '+')
5654960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_RENEWABLE);
5664960Swillf 	    else if (*(argv[i]) == '-')
5674960Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_RENEWABLE;
5684960Swillf 	    else
5694960Swillf 		goto err_usage;
5704960Swillf 
5714960Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
5724960Swillf 	} else if (!strcmp((argv[i] + 1), "allow_proxiable")) {
5734960Swillf 	    if (*(argv[i]) == '+')
5744960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_PROXIABLE);
5754960Swillf 	    else if (*(argv[i]) == '-')
5764960Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_PROXIABLE;
5774960Swillf 	    else
5784960Swillf 		goto err_usage;
5794960Swillf 
5804960Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
5814960Swillf 	} else if (!strcmp((argv[i] + 1), "allow_dup_skey")) {
5824960Swillf 	    if (*(argv[i]) == '+')
5834960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_DUP_SKEY);
5844960Swillf 	    else if (*(argv[i]) == '-')
5854960Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_DUP_SKEY;
5864960Swillf 	    else
5874960Swillf 		goto err_usage;
5884960Swillf 
5894960Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
5904960Swillf 	} else if (!strcmp((argv[i] + 1), "requires_preauth")) {
5914960Swillf 	    if (*(argv[i]) == '+')
5924960Swillf 		policyparams->tktflags |= KRB5_KDB_REQUIRES_PRE_AUTH;
5934960Swillf 	    else if (*(argv[i]) == '-')
5944960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_PRE_AUTH);
5954960Swillf 	    else
5964960Swillf 		goto err_usage;
5974960Swillf 
5984960Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
5994960Swillf 	} else if (!strcmp((argv[i] + 1), "requires_hwauth")) {
6004960Swillf 	    if (*(argv[i]) == '+')
6014960Swillf 		policyparams->tktflags |= KRB5_KDB_REQUIRES_HW_AUTH;
6024960Swillf 	    else if (*(argv[i]) == '-')
6034960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_HW_AUTH);
6044960Swillf 	    else
6054960Swillf 		goto err_usage;
6064960Swillf 
6074960Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
6084960Swillf 	} else if (!strcmp((argv[i] + 1), "allow_svr")) {
6094960Swillf 	    if (*(argv[i]) == '+')
6104960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_SVR);
6114960Swillf 	    else if (*(argv[i]) == '-')
6124960Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_SVR;
6134960Swillf 	    else
6144960Swillf 		goto err_usage;
6154960Swillf 
6164960Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
6174960Swillf 	} else if (!strcmp((argv[i] + 1), "allow_tgs_req")) {
6184960Swillf 	    if (*(argv[i]) == '+')
6194960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_TGT_BASED);
6204960Swillf 	    else if (*(argv[i]) == '-')
6214960Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_TGT_BASED;
6224960Swillf 	    else
6234960Swillf 		goto err_usage;
6244960Swillf 
6254960Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
6264960Swillf 	} else if (!strcmp((argv[i] + 1), "allow_tix")) {
6274960Swillf 	    if (*(argv[i]) == '+')
6284960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_ALL_TIX);
6294960Swillf 	    else if (*(argv[i]) == '-')
6304960Swillf 		policyparams->tktflags |= KRB5_KDB_DISALLOW_ALL_TIX;
6314960Swillf 	    else
6324960Swillf 		goto err_usage;
6334960Swillf 
6344960Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
6354960Swillf 	} else if (!strcmp((argv[i] + 1), "needchange")) {
6364960Swillf 	    if (*(argv[i]) == '+')
6374960Swillf 		policyparams->tktflags |= KRB5_KDB_REQUIRES_PWCHANGE;
6384960Swillf 	    else if (*(argv[i]) == '-')
6394960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_PWCHANGE);
6404960Swillf 	    else
6414960Swillf 		goto err_usage;
6424960Swillf 
6434960Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
6444960Swillf 	} else if (!strcmp((argv[i] + 1), "password_changing_service")) {
6454960Swillf 	    if (*(argv[i]) == '+')
6464960Swillf 		policyparams->tktflags |= KRB5_KDB_PWCHANGE_SERVICE;
6474960Swillf 	    else if (*(argv[i]) == '-')
6484960Swillf 		policyparams->tktflags &= (int)(~KRB5_KDB_PWCHANGE_SERVICE);
6494960Swillf 	    else
6504960Swillf 		goto err_usage;
6514960Swillf 
6524960Swillf 	    out_mask |= LDAP_POLICY_TKTFLAGS;
6534960Swillf 	} else {
6544960Swillf 	    /* Any other argument must be policy DN
6554960Swillf 	       -- skip it */
6564960Swillf 	}
6574960Swillf     }
6584960Swillf 
6594960Swillf     /* Modify attributes of object */
6604960Swillf     if ((retval = krb5_ldap_modify_policy(util_context, policyparams, out_mask)))
6614960Swillf 	goto cleanup;
6624960Swillf 
6634960Swillf     goto cleanup;
6644960Swillf 
6654960Swillf err_usage:
6664960Swillf     print_usage = TRUE;
6674960Swillf 
6684960Swillf err_nomsg:
6694960Swillf     no_msg = TRUE;
6704960Swillf 
6714960Swillf cleanup:
6724960Swillf     /* Clean-up structure */
6734960Swillf     krb5_ldap_free_policy (util_context, policyparams);
6744960Swillf 
6754960Swillf     if (policy)
6764960Swillf         free (policy);
6774960Swillf 
6784960Swillf     if (print_usage)
6794960Swillf 	db_usage(MODIFY_POLICY);
6804960Swillf 
6814960Swillf     if (retval) {
6824960Swillf 	if (!no_msg)
6834960Swillf 	    com_err(me, retval, gettext("while modifying policy object"));
6844960Swillf 
6854960Swillf 	exit_status++;
6864960Swillf     }
6874960Swillf 
6884960Swillf     return;
6894960Swillf }
6904960Swillf 
6914960Swillf 
6924960Swillf /*
6934960Swillf  * This function will display information about the given policy object,
6944960Swillf  * fetching the information from the LDAP Server.
6954960Swillf  */
6964960Swillf void
kdb5_ldap_view_policy(argc,argv)6974960Swillf kdb5_ldap_view_policy(argc, argv)
6984960Swillf     int argc;
6994960Swillf     char *argv[];
7004960Swillf {
701*8092SMark.Phalan@Sun.COM     /* Solaris Kerberos */
702*8092SMark.Phalan@Sun.COM     char *me = progname;
703*8092SMark.Phalan@Sun.COM 
7044960Swillf     krb5_ldap_policy_params *policyparams = NULL;
7054960Swillf     krb5_error_code retval = 0;
7064960Swillf     krb5_boolean print_usage = FALSE;
7074960Swillf     char *policy = NULL;
7084960Swillf     unsigned int mask = 0;
7094960Swillf 
7104960Swillf     if (argc != 2) {
7114960Swillf 	goto err_usage;
7124960Swillf     }
7134960Swillf 
7144960Swillf     policy = strdup(argv[1]);
7154960Swillf     if (policy == NULL) {
7164960Swillf 	com_err(me, ENOMEM, gettext("while viewing policy"));
7174960Swillf 	exit_status++;
7184960Swillf 	goto cleanup;
7194960Swillf     }
7204960Swillf 
7214960Swillf     if ((retval = init_ldap_realm (argc, argv)))
7224960Swillf         goto cleanup;
7234960Swillf 
7244960Swillf     if ((retval = krb5_ldap_read_policy(util_context, policy, &policyparams, &mask))) {
7254960Swillf 	com_err(me, retval, gettext("while viewing policy '%s'"), policy);
7264960Swillf 	exit_status++;
7274960Swillf 	goto cleanup;
7284960Swillf     }
7294960Swillf 
7304960Swillf     print_policy_params (policyparams, mask);
7314960Swillf 
7324960Swillf     goto cleanup;
7334960Swillf 
7344960Swillf err_usage:
7354960Swillf     print_usage = TRUE;
7364960Swillf 
7374960Swillf cleanup:
7384960Swillf     krb5_ldap_free_policy (util_context, policyparams);
7394960Swillf 
7404960Swillf     if (policy)
7414960Swillf 	free (policy);
7424960Swillf 
7434960Swillf     if (print_usage) {
7444960Swillf 	db_usage(VIEW_POLICY);
7454960Swillf     }
7464960Swillf 
7474960Swillf     return;
7484960Swillf }
7494960Swillf 
7504960Swillf 
7514960Swillf /*
7524960Swillf  * This function will print the policy object information to the
7534960Swillf  * standard output.
7544960Swillf  */
7554960Swillf static void
print_policy_params(policyparams,mask)7564960Swillf print_policy_params(policyparams, mask)
7574960Swillf     krb5_ldap_policy_params *policyparams;
7584960Swillf     int mask;
7594960Swillf {
7604960Swillf     /* Print the policy DN */
7614960Swillf     printf("%25s: %s\n", gettext("Ticket policy"), policyparams->policy);
7624960Swillf 
7634960Swillf     /* Print max. ticket life and max. renewable life, if present */
7644960Swillf     if (mask & LDAP_POLICY_MAXTKTLIFE)
7654960Swillf 	printf("%25s: %s\n", gettext("Maximum ticket life"), strdur(policyparams->maxtktlife));
7664960Swillf     if (mask & LDAP_POLICY_MAXRENEWLIFE)
7674960Swillf 	printf("%25s: %s\n", gettext("Maximum renewable life"), strdur(policyparams->maxrenewlife));
7684960Swillf 
7694960Swillf     /* Service flags are printed */
7704960Swillf     printf("%25s: ", gettext("Ticket flags"));
7714960Swillf     if (mask & LDAP_POLICY_TKTFLAGS) {
7724960Swillf 	int ticketflags = policyparams->tktflags;
7734960Swillf 
7744960Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_POSTDATED)
7754960Swillf 	    printf("%s ","DISALLOW_POSTDATED");
7764960Swillf 
7774960Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_FORWARDABLE)
7784960Swillf 	    printf("%s ","DISALLOW_FORWARDABLE");
7794960Swillf 
7804960Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_RENEWABLE)
7814960Swillf 	    printf("%s ","DISALLOW_RENEWABLE");
7824960Swillf 
7834960Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_PROXIABLE)
7844960Swillf 	    printf("%s ","DISALLOW_PROXIABLE");
7854960Swillf 
7864960Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_DUP_SKEY)
7874960Swillf 	    printf("%s ","DISALLOW_DUP_SKEY");
7884960Swillf 
7894960Swillf 	if (ticketflags & KRB5_KDB_REQUIRES_PRE_AUTH)
7904960Swillf 	    printf("%s ","REQUIRES_PRE_AUTH");
7914960Swillf 
7924960Swillf 	if (ticketflags & KRB5_KDB_REQUIRES_HW_AUTH)
7934960Swillf 	    printf("%s ","REQUIRES_HW_AUTH");
7944960Swillf 
7954960Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_SVR)
7964960Swillf 	    printf("%s ","DISALLOW_SVR");
7974960Swillf 
7984960Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_TGT_BASED)
7994960Swillf 	    printf("%s ","DISALLOW_TGT_BASED");
8004960Swillf 
8014960Swillf 	if (ticketflags & KRB5_KDB_DISALLOW_ALL_TIX)
8024960Swillf 	    printf("%s ","DISALLOW_ALL_TIX");
8034960Swillf 
8044960Swillf 	if (ticketflags & KRB5_KDB_REQUIRES_PWCHANGE)
8054960Swillf 	    printf("%s ","REQUIRES_PWCHANGE");
8064960Swillf 
8074960Swillf 	if (ticketflags & KRB5_KDB_PWCHANGE_SERVICE)
8084960Swillf 	    printf("%s ","PWCHANGE_SERVICE");
8094960Swillf     }
8104960Swillf     printf("\n");
8114960Swillf 
8124960Swillf     return;
8134960Swillf }
8144960Swillf 
8154960Swillf 
8164960Swillf /*
8174960Swillf  * This function will list the DNs of policy objects under a specific
8184960Swillf  * sub-tree (entire tree by default)
8194960Swillf  */
kdb5_ldap_list_policies(argc,argv)8204960Swillf void kdb5_ldap_list_policies(argc, argv)
8214960Swillf     int argc;
8224960Swillf     char *argv[];
8234960Swillf {
824*8092SMark.Phalan@Sun.COM     /* Solaris Kerberos */
825*8092SMark.Phalan@Sun.COM     char *me = progname;
826*8092SMark.Phalan@Sun.COM 
8274960Swillf     krb5_error_code retval = 0;
8284960Swillf     krb5_boolean print_usage = FALSE;
8294960Swillf     char *basedn = NULL;
8304960Swillf     char **list = NULL;
8314960Swillf     char **plist = NULL;
8324960Swillf 
8334960Swillf     /* Check for number of arguments */
8344960Swillf     if ((argc != 1) && (argc != 3)) {
8354960Swillf 	goto err_usage;
8364960Swillf     }
8374960Swillf 
8384960Swillf     if ((retval = init_ldap_realm (argc, argv)))
8394960Swillf 	goto cleanup;
8404960Swillf 
8414960Swillf     retval = krb5_ldap_list_policy(util_context, basedn, &list);
8424960Swillf     if ((retval != 0) || (list == NULL))
8434960Swillf 	goto cleanup;
8444960Swillf 
8454960Swillf     for (plist = list; *plist != NULL; plist++) {
8464960Swillf 	printf("%s\n", *plist);
8474960Swillf     }
8484960Swillf 
8494960Swillf     goto cleanup;
8504960Swillf 
8514960Swillf err_usage:
8524960Swillf     print_usage = TRUE;
8534960Swillf 
8544960Swillf cleanup:
8554960Swillf     if (list != NULL) {
8564960Swillf 	krb5_free_list_entries (list);
8574960Swillf 	free (list);
8584960Swillf     }
8594960Swillf 
8604960Swillf     if (basedn)
8614960Swillf 	free (basedn);
8624960Swillf 
8634960Swillf     if (print_usage) {
8644960Swillf 	db_usage(LIST_POLICY);
8654960Swillf     }
8664960Swillf 
8674960Swillf     if (retval) {
8684960Swillf 	com_err(me, retval, gettext("while listing policy objects"));
8694960Swillf 	exit_status++;
8704960Swillf     }
8714960Swillf 
8724960Swillf     return;
8734960Swillf }
8744960Swillf 
8754960Swillf 
8764960Swillf /* Reproduced from kadmin.c, instead of linking
8774960Swillf    the entire kadmin.o */
strdur(duration)8784960Swillf static char *strdur(duration)
8794960Swillf     time_t duration;
8804960Swillf {
8814960Swillf     static char out[50];
8824960Swillf     int neg, days, hours, minutes, seconds;
8834960Swillf 
8844960Swillf     if (duration < 0) {
8854960Swillf 	duration *= -1;
8864960Swillf 	neg = 1;
8874960Swillf     } else
8884960Swillf 	neg = 0;
8894960Swillf     days = duration / (24 * 3600);
8904960Swillf     duration %= 24 * 3600;
8914960Swillf     hours = duration / 3600;
8924960Swillf     duration %= 3600;
8934960Swillf     minutes = duration / 60;
8944960Swillf     duration %= 60;
8954960Swillf     seconds = duration;
8964960Swillf     snprintf(out, sizeof(out), "%s%d %s %02d:%02d:%02d", neg ? "-" : "",
8974960Swillf 	    days, days == 1 ? gettext("day") : gettext("days"),
8984960Swillf 	    hours, minutes, seconds);
8994960Swillf     return out;
9004960Swillf }
901