154925bf6Swillf /*
254925bf6Swillf  * lib/kdb/kdb_ldap/ldap_tkt_policy.c
354925bf6Swillf  *
454925bf6Swillf  * Copyright (c) 2004-2005, Novell, Inc.
554925bf6Swillf  * All rights reserved.
654925bf6Swillf  *
754925bf6Swillf  * Redistribution and use in source and binary forms, with or without
854925bf6Swillf  * modification, are permitted provided that the following conditions are met:
954925bf6Swillf  *
1054925bf6Swillf  *   * Redistributions of source code must retain the above copyright notice,
1154925bf6Swillf  *       this list of conditions and the following disclaimer.
1254925bf6Swillf  *   * Redistributions in binary form must reproduce the above copyright
1354925bf6Swillf  *       notice, this list of conditions and the following disclaimer in the
1454925bf6Swillf  *       documentation and/or other materials provided with the distribution.
1554925bf6Swillf  *   * The copyright holder's name is not used to endorse or promote products
1654925bf6Swillf  *       derived from this software without specific prior written permission.
1754925bf6Swillf  *
1854925bf6Swillf  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1954925bf6Swillf  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2054925bf6Swillf  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2154925bf6Swillf  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2254925bf6Swillf  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2354925bf6Swillf  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2454925bf6Swillf  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2554925bf6Swillf  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2654925bf6Swillf  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2754925bf6Swillf  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2854925bf6Swillf  * POSSIBILITY OF SUCH DAMAGE.
2954925bf6Swillf  */
3054925bf6Swillf 
3154925bf6Swillf #include "ldap_main.h"
3254925bf6Swillf #include "kdb_ldap.h"
3354925bf6Swillf #include "ldap_tkt_policy.h"
3454925bf6Swillf #include "ldap_err.h"
3554925bf6Swillf #include <libintl.h>
3654925bf6Swillf 
3754925bf6Swillf /* Ticket policy object management */
3854925bf6Swillf 
3954925bf6Swillf /*
4054925bf6Swillf  * create the Ticket policy object in Directory.
4154925bf6Swillf  */
4254925bf6Swillf krb5_error_code
krb5_ldap_create_policy(context,policy,mask)4354925bf6Swillf krb5_ldap_create_policy(context, policy, mask)
4454925bf6Swillf     krb5_context	        context;
4554925bf6Swillf     krb5_ldap_policy_params     *policy;
4654925bf6Swillf     int                         mask;
4754925bf6Swillf {
4854925bf6Swillf     krb5_error_code             st=0;
4954925bf6Swillf     LDAP                        *ld=NULL;
5054925bf6Swillf     char                        *strval[3]={NULL}, *policy_dn = NULL;
5154925bf6Swillf     LDAPMod                     **mods=NULL;
5254925bf6Swillf     kdb5_dal_handle             *dal_handle=NULL;
5354925bf6Swillf     krb5_ldap_context           *ldap_context=NULL;
5454925bf6Swillf     krb5_ldap_server_handle     *ldap_server_handle=NULL;
5554925bf6Swillf 
5654925bf6Swillf     /* validate the input parameters */
5754925bf6Swillf     if (policy == NULL || policy->policy == NULL) {
5854925bf6Swillf 	st = EINVAL;
5954925bf6Swillf 	krb5_set_error_message (context, st, gettext("Ticket Policy Name missing"));
6054925bf6Swillf 	goto cleanup;
6154925bf6Swillf     }
6254925bf6Swillf 
6354925bf6Swillf     SETUP_CONTEXT();
6454925bf6Swillf     GET_HANDLE();
6554925bf6Swillf 
6654925bf6Swillf     if ((st = krb5_ldap_name_to_policydn (context, policy->policy, &policy_dn)) != 0)
6754925bf6Swillf 	goto cleanup;
6854925bf6Swillf 
6954925bf6Swillf     memset(strval, 0, sizeof(strval));
7054925bf6Swillf     strval[0] = policy->policy;
7154925bf6Swillf     if ((st=krb5_add_str_mem_ldap_mod(&mods, "cn", LDAP_MOD_ADD, strval)) != 0)
7254925bf6Swillf 	goto cleanup;
7354925bf6Swillf 
7454925bf6Swillf     memset(strval, 0, sizeof(strval));
7554925bf6Swillf     strval[0] = "krbTicketPolicy";
7654925bf6Swillf     strval[1] = "krbTicketPolicyaux";
7754925bf6Swillf     if ((st=krb5_add_str_mem_ldap_mod(&mods, "objectclass", LDAP_MOD_ADD, strval)) != 0)
7854925bf6Swillf 	goto cleanup;
7954925bf6Swillf 
8054925bf6Swillf     if (mask & LDAP_POLICY_MAXTKTLIFE) {
8154925bf6Swillf 	if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbmaxticketlife", LDAP_MOD_ADD,
8254925bf6Swillf 					  policy->maxtktlife)) != 0)
8354925bf6Swillf 	    goto cleanup;
8454925bf6Swillf     }
8554925bf6Swillf 
8654925bf6Swillf     if (mask & LDAP_POLICY_MAXRENEWLIFE) {
8754925bf6Swillf 	if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbmaxrenewableage", LDAP_MOD_ADD,
8854925bf6Swillf 					  policy->maxrenewlife)) != 0)
8954925bf6Swillf 	    goto cleanup;
9054925bf6Swillf     }
9154925bf6Swillf 
9254925bf6Swillf     if (mask & LDAP_POLICY_TKTFLAGS) {
9354925bf6Swillf 	if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbticketflags", LDAP_MOD_ADD,
9454925bf6Swillf 					  policy->tktflags)) != 0)
9554925bf6Swillf 	    goto cleanup;
9654925bf6Swillf     }
9754925bf6Swillf 
9854925bf6Swillf     /* ldap add operation */
9954925bf6Swillf     if ((st=ldap_add_ext_s(ld, policy_dn, mods, NULL, NULL)) != LDAP_SUCCESS) {
10054925bf6Swillf 	st = set_ldap_error (context, st, OP_ADD);
10154925bf6Swillf 	goto cleanup;
10254925bf6Swillf     }
10354925bf6Swillf 
10454925bf6Swillf cleanup:
10554925bf6Swillf     if (policy_dn != NULL)
10654925bf6Swillf 	free(policy_dn);
10754925bf6Swillf 
10854925bf6Swillf     ldap_mods_free(mods, 1);
10954925bf6Swillf     krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
11054925bf6Swillf     return st;
11154925bf6Swillf }
11254925bf6Swillf 
11354925bf6Swillf 
11454925bf6Swillf /*
11554925bf6Swillf  * modify the Ticket policy object in Directory.
11654925bf6Swillf  */
11754925bf6Swillf 
11854925bf6Swillf krb5_error_code
krb5_ldap_modify_policy(context,policy,mask)11954925bf6Swillf krb5_ldap_modify_policy(context, policy, mask)
12054925bf6Swillf     krb5_context	        context;
12154925bf6Swillf     krb5_ldap_policy_params     *policy;
12254925bf6Swillf     int                         mask;
12354925bf6Swillf {
12454925bf6Swillf     int                         objectmask=0;
12554925bf6Swillf     krb5_error_code             st=0;
12654925bf6Swillf     LDAP                        *ld=NULL;
12754925bf6Swillf     char                        *attrvalues[]={"krbTicketPolicy", "krbTicketPolicyAux", NULL}, *strval[2]={NULL};
12854925bf6Swillf     char                        *policy_dn = NULL;
12954925bf6Swillf     LDAPMod                     **mods=NULL;
13054925bf6Swillf     kdb5_dal_handle             *dal_handle=NULL;
13154925bf6Swillf     krb5_ldap_context           *ldap_context=NULL;
13254925bf6Swillf     krb5_ldap_server_handle     *ldap_server_handle=NULL;
13354925bf6Swillf 
13454925bf6Swillf     /* validate the input parameters */
13554925bf6Swillf     if (policy == NULL || policy->policy==NULL) {
13654925bf6Swillf 	st = EINVAL;
13754925bf6Swillf 	krb5_set_error_message (context, st, gettext("Ticket Policy Name missing"));
13854925bf6Swillf 	goto cleanup;
13954925bf6Swillf     }
14054925bf6Swillf 
14154925bf6Swillf     SETUP_CONTEXT();
14254925bf6Swillf     GET_HANDLE();
14354925bf6Swillf 
14454925bf6Swillf     if ((st = krb5_ldap_name_to_policydn (context, policy->policy, &policy_dn)) != 0)
14554925bf6Swillf 	goto cleanup;
14654925bf6Swillf 
14754925bf6Swillf     /* the policydn object should be of the krbTicketPolicy object class */
14854925bf6Swillf     st = checkattributevalue(ld, policy_dn, "objectClass", attrvalues, &objectmask);
14954925bf6Swillf     CHECK_CLASS_VALIDITY(st, objectmask, "ticket policy object: ");
15054925bf6Swillf 
15154925bf6Swillf     if ((objectmask & 0x02) == 0) { /* add krbticketpolicyaux to the object class list */
15254925bf6Swillf 	memset(strval, 0, sizeof(strval));
15354925bf6Swillf 	strval[0] = "krbTicketPolicyAux";
15454925bf6Swillf 	if ((st=krb5_add_str_mem_ldap_mod(&mods, "objectclass", LDAP_MOD_ADD, strval)) != 0)
15554925bf6Swillf 	    goto cleanup;
15654925bf6Swillf     }
15754925bf6Swillf 
15854925bf6Swillf     if (mask & LDAP_POLICY_MAXTKTLIFE) {
15954925bf6Swillf 	if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbmaxticketlife", LDAP_MOD_REPLACE,
16054925bf6Swillf 					  policy->maxtktlife)) != 0)
16154925bf6Swillf 	    goto cleanup;
16254925bf6Swillf     }
16354925bf6Swillf 
16454925bf6Swillf     if (mask & LDAP_POLICY_MAXRENEWLIFE) {
16554925bf6Swillf 	if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbmaxrenewableage", LDAP_MOD_REPLACE,
16654925bf6Swillf 					  policy->maxrenewlife)) != 0)
16754925bf6Swillf 	    goto cleanup;
16854925bf6Swillf     }
16954925bf6Swillf 
17054925bf6Swillf     if (mask & LDAP_POLICY_TKTFLAGS) {
17154925bf6Swillf 	if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbticketflags", LDAP_MOD_REPLACE,
17254925bf6Swillf 					  policy->tktflags)) != 0)
17354925bf6Swillf 	    goto cleanup;
17454925bf6Swillf     }
17554925bf6Swillf 
17654925bf6Swillf     if ((st=ldap_modify_ext_s(ld, policy_dn, mods, NULL, NULL)) != LDAP_SUCCESS) {
17754925bf6Swillf 	st = set_ldap_error (context, st, OP_MOD);
17854925bf6Swillf 	goto cleanup;
17954925bf6Swillf     }
18054925bf6Swillf 
18154925bf6Swillf cleanup:
18254925bf6Swillf     if (policy_dn != NULL)
18354925bf6Swillf         free(policy_dn);
18454925bf6Swillf 
18554925bf6Swillf     ldap_mods_free(mods, 1);
18654925bf6Swillf     krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
18754925bf6Swillf     return st;
18854925bf6Swillf }
18954925bf6Swillf 
19054925bf6Swillf 
19154925bf6Swillf /*
19254925bf6Swillf  * Read the policy object from the Directory and populate the krb5_ldap_policy_params
19354925bf6Swillf  * structure.
19454925bf6Swillf  */
19554925bf6Swillf 
19654925bf6Swillf krb5_error_code
krb5_ldap_read_policy(context,policyname,policy,omask)19754925bf6Swillf krb5_ldap_read_policy(context, policyname, policy, omask)
19854925bf6Swillf     krb5_context	        context;
19954925bf6Swillf     char                        *policyname;
20054925bf6Swillf     krb5_ldap_policy_params     **policy;
20154925bf6Swillf     unsigned int                *omask; /* Solaris kerberos: unsigned better for mask */
20254925bf6Swillf {
20354925bf6Swillf     krb5_error_code             st=0, tempst=0;
20454925bf6Swillf     int                         objectmask=0;
20554925bf6Swillf     LDAP                        *ld=NULL;
20654925bf6Swillf     LDAPMessage                 *result=NULL,*ent=NULL;
20754925bf6Swillf     char                        *attributes[] = { "krbMaxTicketLife", "krbMaxRenewableAge", "krbTicketFlags", NULL};
20854925bf6Swillf     char                        *attrvalues[] = { "krbTicketPolicy", NULL}, *policy_dn = NULL;
20954925bf6Swillf     krb5_ldap_policy_params     *lpolicy=NULL;
21054925bf6Swillf     kdb5_dal_handle             *dal_handle=NULL;
21154925bf6Swillf     krb5_ldap_context           *ldap_context=NULL;
21254925bf6Swillf     krb5_ldap_server_handle     *ldap_server_handle=NULL;
21354925bf6Swillf 
21454925bf6Swillf     /* validate the input parameters */
21554925bf6Swillf     if (policyname == NULL  || policy == NULL) {
21654925bf6Swillf 	st = EINVAL;
21754925bf6Swillf 	krb5_set_error_message(context, st, gettext("Ticket Policy Object information missing"));
21854925bf6Swillf 	goto cleanup;
21954925bf6Swillf     }
22054925bf6Swillf 
22154925bf6Swillf     SETUP_CONTEXT();
22254925bf6Swillf     GET_HANDLE();
22354925bf6Swillf 
22454925bf6Swillf     if ((st = krb5_ldap_name_to_policydn (context, policyname, &policy_dn)) != 0)
22554925bf6Swillf 	goto cleanup;
22654925bf6Swillf 
22754925bf6Swillf     /* the policydn object should be of the krbTicketPolicy object class */
22854925bf6Swillf     st = checkattributevalue(ld, policy_dn, "objectClass", attrvalues, &objectmask);
22954925bf6Swillf     CHECK_CLASS_VALIDITY(st, objectmask, "ticket policy object: ");
23054925bf6Swillf 
23154925bf6Swillf     /* Initialize ticket policy structure */
23254925bf6Swillf     lpolicy =(krb5_ldap_policy_params *) malloc(sizeof(krb5_ldap_policy_params));
23354925bf6Swillf     CHECK_NULL(lpolicy);
23454925bf6Swillf     memset(lpolicy, 0, sizeof(krb5_ldap_policy_params));
23554925bf6Swillf 
23654925bf6Swillf     if ((lpolicy->policy = strdup (policyname)) == NULL) {
23754925bf6Swillf 	st = ENOMEM;
23854925bf6Swillf 	goto cleanup;
23954925bf6Swillf     }
24054925bf6Swillf 
24154925bf6Swillf     lpolicy->tl_data = calloc (1, sizeof(*lpolicy->tl_data));
24254925bf6Swillf     CHECK_NULL(lpolicy->tl_data);
24354925bf6Swillf     lpolicy->tl_data->tl_data_type = KDB_TL_USER_INFO;
24454925bf6Swillf 
24554925bf6Swillf     LDAP_SEARCH(policy_dn, LDAP_SCOPE_BASE, "(objectclass=krbTicketPolicy)", attributes);
24654925bf6Swillf 
24754925bf6Swillf     *omask = 0;
24854925bf6Swillf 
24954925bf6Swillf     ent=ldap_first_entry(ld, result);
25054925bf6Swillf     if (ent != NULL) {
25154925bf6Swillf 	if (krb5_ldap_get_value(ld, ent, "krbmaxticketlife", (int *) &(lpolicy->maxtktlife)) == 0)
25254925bf6Swillf 	    *omask |= LDAP_POLICY_MAXTKTLIFE;
25354925bf6Swillf 
25454925bf6Swillf 	if (krb5_ldap_get_value(ld, ent, "krbmaxrenewableage", (int *) &(lpolicy->maxrenewlife)) == 0)
25554925bf6Swillf 	    *omask |= LDAP_POLICY_MAXRENEWLIFE;
25654925bf6Swillf 
25754925bf6Swillf 	if (krb5_ldap_get_value(ld, ent, "krbticketflags", (int *) &(lpolicy->tktflags)) == 0)
25854925bf6Swillf 	    *omask |= LDAP_POLICY_TKTFLAGS;
25954925bf6Swillf     }
26054925bf6Swillf     ldap_msgfree(result);
26154925bf6Swillf 
26254925bf6Swillf     lpolicy->mask = *omask;
26354925bf6Swillf     store_tl_data(lpolicy->tl_data, KDB_TL_MASK, omask);
26454925bf6Swillf     *policy = lpolicy;
26554925bf6Swillf 
26654925bf6Swillf cleanup:
26754925bf6Swillf     if (st != 0) {
26854925bf6Swillf 	krb5_ldap_free_policy(context, lpolicy);
26954925bf6Swillf 	*policy = NULL;
27054925bf6Swillf     }
27154925bf6Swillf     krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
27254925bf6Swillf     return st;
27354925bf6Swillf }
27454925bf6Swillf 
27554925bf6Swillf 
27654925bf6Swillf /*
27754925bf6Swillf  * Function to delete ticket policy object from the directory.  Before
27854925bf6Swillf  * calling this function krb5_ldap_read_policy should be called to
27954925bf6Swillf  * check the existence of the object.  This serves one major purpose,
28054925bf6Swillf  * i.e., if the object to be is anything other than the ticket policy
28154925bf6Swillf  * object then the krb5_ldap_read_policy returns an error and thus is
28254925bf6Swillf  * not accidently deleted in this function.
28354925bf6Swillf  *
28454925bf6Swillf  * NOTE: Other kerberos objects (user/realm object) might be having
28554925bf6Swillf  * references to the policy object to be deleted. This situation is
28654925bf6Swillf  * not handled here, instead is taken care of at all the places where
28754925bf6Swillf  * the deleted policy object is read, to ignore a return status of
28854925bf6Swillf  * LDAP_NO_SUCH_OBJECT and continue.
28954925bf6Swillf  */
29054925bf6Swillf 
29154925bf6Swillf krb5_error_code
krb5_ldap_delete_policy(context,policyname)29254925bf6Swillf krb5_ldap_delete_policy(context, policyname)
29354925bf6Swillf     krb5_context                context;
29454925bf6Swillf     char                        *policyname;
29554925bf6Swillf {
29654925bf6Swillf 	int                         refcount = 0;
29754925bf6Swillf 	char                        *policy_dn = NULL;
29854925bf6Swillf     krb5_error_code             st = 0;
29954925bf6Swillf     LDAP                        *ld = NULL;
30054925bf6Swillf     kdb5_dal_handle             *dal_handle=NULL;
30154925bf6Swillf     krb5_ldap_context           *ldap_context=NULL;
30254925bf6Swillf     krb5_ldap_server_handle     *ldap_server_handle=NULL;
30354925bf6Swillf 
304*159d09a2SMark Phalan 	if (policyname == NULL) {
30554925bf6Swillf 	st = EINVAL;
30654925bf6Swillf 	prepend_err_str (context, gettext("Ticket Policy Object DN missing"),st,st);
30754925bf6Swillf 	goto cleanup;
30854925bf6Swillf     }
30954925bf6Swillf 
31054925bf6Swillf 
31154925bf6Swillf     SETUP_CONTEXT();
31254925bf6Swillf     GET_HANDLE();
31354925bf6Swillf 
31454925bf6Swillf     if ((st = krb5_ldap_name_to_policydn (context, policyname, &policy_dn)) != 0)
31554925bf6Swillf         goto cleanup;
31654925bf6Swillf 
31754925bf6Swillf     /* Checking for policy count for 0 and will not permit delete if
31854925bf6Swillf      * it is greater than 0.  */
31954925bf6Swillf 
32054925bf6Swillf     if ((st = krb5_ldap_get_reference_count (context, policy_dn,
32154925bf6Swillf                     "krbTicketPolicyReference", &refcount, ld)) != 0)
32254925bf6Swillf         goto cleanup;
32354925bf6Swillf 
32454925bf6Swillf     if (refcount == 0) {
32554925bf6Swillf 	if ((st=ldap_delete_ext_s(ld, policy_dn, NULL, NULL)) != 0) {
32654925bf6Swillf 	    prepend_err_str (context,ldap_err2string(st),st,st);
32754925bf6Swillf 
32854925bf6Swillf 	    goto cleanup;
32954925bf6Swillf 	}
33054925bf6Swillf     } else {
33154925bf6Swillf 	st = EINVAL;
33254925bf6Swillf 	prepend_err_str (context, gettext("Delete Failed: One or more Principals associated with the Ticket Policy"),st,st);
33354925bf6Swillf 	goto cleanup;
33454925bf6Swillf     }
33554925bf6Swillf 
33654925bf6Swillf cleanup:
33754925bf6Swillf     if (policy_dn != NULL)
33854925bf6Swillf         free (policy_dn);
33954925bf6Swillf     krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
34054925bf6Swillf     return st;
34154925bf6Swillf }
34254925bf6Swillf 
34354925bf6Swillf 
34454925bf6Swillf /*
34554925bf6Swillf  * list policy objects from Directory
34654925bf6Swillf  */
34754925bf6Swillf 
34854925bf6Swillf krb5_error_code
krb5_ldap_list_policy(context,containerdn,policy)34954925bf6Swillf krb5_ldap_list_policy(context, containerdn, policy)
35054925bf6Swillf     krb5_context	        context;
35154925bf6Swillf     char                        *containerdn;
35254925bf6Swillf     char                        ***policy;
35354925bf6Swillf {
35454925bf6Swillf     int                         i, j, count;
35554925bf6Swillf     char                        **list = NULL;
35654925bf6Swillf     char                        *policycontainerdn = containerdn;
35754925bf6Swillf     kdb5_dal_handle             *dal_handle=NULL;
35854925bf6Swillf     krb5_ldap_context           *ldap_context=NULL;
35954925bf6Swillf     krb5_error_code             st=0;
36054925bf6Swillf 
36154925bf6Swillf     SETUP_CONTEXT();
36254925bf6Swillf     if (policycontainerdn == NULL) {
36354925bf6Swillf         policycontainerdn = ldap_context->lrparams->realmdn;
36454925bf6Swillf     }
36554925bf6Swillf 
36654925bf6Swillf     if ((st = krb5_ldap_list(context, &list, "krbTicketPolicy", policycontainerdn)) != 0)
36754925bf6Swillf 	goto cleanup;
36854925bf6Swillf 
36954925bf6Swillf     for (i = 0; list[i] != NULL; i++);
37054925bf6Swillf 
37154925bf6Swillf     count = i;
37254925bf6Swillf 
37354925bf6Swillf     *policy = (char **) calloc ((unsigned) count + 1, sizeof(char *));
37454925bf6Swillf     if (*policy == NULL) {
37554925bf6Swillf 	st = ENOMEM;
37654925bf6Swillf 	goto cleanup;
37754925bf6Swillf     }
37854925bf6Swillf 
37954925bf6Swillf     for (i = 0, j = 0; list[i] != NULL; i++, j++) {
38054925bf6Swillf 	int ret;
38154925bf6Swillf 	ret = krb5_ldap_policydn_to_name (context, list[i], &(*policy)[i]);
38254925bf6Swillf 	if (ret != 0)
38354925bf6Swillf 	    j--;
38454925bf6Swillf     }
38554925bf6Swillf 
38654925bf6Swillf cleanup:
38754925bf6Swillf     return st;
38854925bf6Swillf }
38954925bf6Swillf 
39054925bf6Swillf /*
39154925bf6Swillf  * Function to free the ticket policy object structure.
39254925bf6Swillf  * Note: this function assumes that memory of the policy structure is dynamically allocated and hence the whole
39354925bf6Swillf  * structure is freed up. Care should be taken not to call this function on a static structure
39454925bf6Swillf  */
39554925bf6Swillf 
39654925bf6Swillf krb5_error_code
krb5_ldap_free_policy(context,policy)39754925bf6Swillf krb5_ldap_free_policy(context, policy)
39854925bf6Swillf     krb5_context                context;
39954925bf6Swillf     krb5_ldap_policy_params    *policy;
40054925bf6Swillf {
40154925bf6Swillf 
40254925bf6Swillf     krb5_error_code st=0;
40354925bf6Swillf 
40454925bf6Swillf     if (policy == NULL)
40554925bf6Swillf 	return st;
40654925bf6Swillf 
40754925bf6Swillf     if (policy->policy)
40854925bf6Swillf 	free (policy->policy);
40954925bf6Swillf 
41054925bf6Swillf     if (policy->tl_data) {
41154925bf6Swillf 	if (policy->tl_data->tl_data_contents)
41254925bf6Swillf 	    free (policy->tl_data->tl_data_contents);
41354925bf6Swillf 	free (policy->tl_data);
41454925bf6Swillf     }
41554925bf6Swillf     free (policy);
41654925bf6Swillf 
41754925bf6Swillf     return st;
41854925bf6Swillf }
41954925bf6Swillf 
42054925bf6Swillf /*
42154925bf6Swillf  * This function is general object listing routine.  It is currently
42254925bf6Swillf  * used for ticket policy object listing.
42354925bf6Swillf  */
42454925bf6Swillf 
42554925bf6Swillf krb5_error_code
krb5_ldap_list(context,list,objectclass,containerdn)42654925bf6Swillf krb5_ldap_list(context, list, objectclass, containerdn)
42754925bf6Swillf     krb5_context	        context;
42854925bf6Swillf     char                        ***list;
42954925bf6Swillf     char                        *objectclass;
43054925bf6Swillf     char                        *containerdn;
43154925bf6Swillf {
43254925bf6Swillf     char                        *filter=NULL, *dn=NULL;
43354925bf6Swillf     krb5_error_code             st=0, tempst=0;
43454925bf6Swillf     int                         i=0, count=0, filterlen=0;
43554925bf6Swillf     LDAP                        *ld=NULL;
43654925bf6Swillf     LDAPMessage                 *result=NULL,*ent=NULL;
43754925bf6Swillf     kdb5_dal_handle             *dal_handle=NULL;
43854925bf6Swillf     krb5_ldap_context           *ldap_context=NULL;
43954925bf6Swillf     krb5_ldap_server_handle     *ldap_server_handle=NULL;
44054925bf6Swillf 
44154925bf6Swillf     SETUP_CONTEXT();
44254925bf6Swillf     GET_HANDLE();
44354925bf6Swillf 
44454925bf6Swillf     /* check if the containerdn exists */
44554925bf6Swillf     if (containerdn) {
44654925bf6Swillf 	if ((st=checkattributevalue(ld, containerdn, NULL, NULL, NULL)) != 0) {
44754925bf6Swillf 	    prepend_err_str (context, gettext("Error reading container object: "), st, st);
44854925bf6Swillf 	    goto cleanup;
44954925bf6Swillf 	}
45054925bf6Swillf     }
45154925bf6Swillf 
45254925bf6Swillf     /* set the filter for the search operation */
45354925bf6Swillf     filterlen = strlen("(objectclass=") + strlen(objectclass) + 1 + 1;
45454925bf6Swillf     filter = malloc ((unsigned) filterlen);
45554925bf6Swillf     if (filter == NULL) {
45654925bf6Swillf 	st = ENOMEM;
45754925bf6Swillf 	goto cleanup;
45854925bf6Swillf     }
45954925bf6Swillf     snprintf(filter, (unsigned) filterlen,"(objectclass=%s)",objectclass);
46054925bf6Swillf 
46154925bf6Swillf     LDAP_SEARCH(containerdn, LDAP_SCOPE_SUBTREE, filter, NULL);
46254925bf6Swillf 
46354925bf6Swillf     count = ldap_count_entries(ld, result);
46454925bf6Swillf     if (count == -1) {
46554925bf6Swillf 	ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &st);
46654925bf6Swillf 	st = set_ldap_error(context, st, OP_SEARCH);
46754925bf6Swillf 	goto cleanup;
46854925bf6Swillf     }
46954925bf6Swillf     *list = (char **) calloc ((unsigned) count+1, sizeof(char *));
47054925bf6Swillf     if (*list == NULL) {
47154925bf6Swillf 	st = ENOMEM;
47254925bf6Swillf 	goto cleanup;
47354925bf6Swillf     }
47454925bf6Swillf 
47554925bf6Swillf     for (ent=ldap_first_entry(ld, result), count=0; ent != NULL; ent=ldap_next_entry(ld, ent), ++count) {
47654925bf6Swillf 	if ((dn=ldap_get_dn(ld, ent)) == NULL)
47754925bf6Swillf 	    continue;
47854925bf6Swillf 	if (((*list)[count] = strdup(dn)) == NULL) {
47954925bf6Swillf 	    ldap_memfree (dn);
48054925bf6Swillf 	    st = ENOMEM;
48154925bf6Swillf 	    goto cleanup;
48254925bf6Swillf 	}
48354925bf6Swillf 	ldap_memfree(dn);
48454925bf6Swillf     }
48554925bf6Swillf     ldap_msgfree(result);
48654925bf6Swillf 
48754925bf6Swillf cleanup:
48854925bf6Swillf     if (filter)
48954925bf6Swillf 	free (filter);
49054925bf6Swillf 
49154925bf6Swillf     /* some error, free up all the memory */
49254925bf6Swillf     if (st != 0) {
49354925bf6Swillf 	if (*list) {
49454925bf6Swillf 	    for (i=0; (*list)[i]; ++i)
49554925bf6Swillf 		free ((*list)[i]);
49654925bf6Swillf 	    free (*list);
49754925bf6Swillf 	    *list = NULL;
49854925bf6Swillf 	}
49954925bf6Swillf     }
50054925bf6Swillf     krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
50154925bf6Swillf     return st;
50254925bf6Swillf }
503