1*54925bf6Swillf /*
2*54925bf6Swillf  * lib/kdb/kdb_ldap/ldap_pwd_policy.c
3*54925bf6Swillf  *
4*54925bf6Swillf  * Copyright (c) 2004-2005, Novell, Inc.
5*54925bf6Swillf  * All rights reserved.
6*54925bf6Swillf  *
7*54925bf6Swillf  * Redistribution and use in source and binary forms, with or without
8*54925bf6Swillf  * modification, are permitted provided that the following conditions are met:
9*54925bf6Swillf  *
10*54925bf6Swillf  *   * Redistributions of source code must retain the above copyright notice,
11*54925bf6Swillf  *       this list of conditions and the following disclaimer.
12*54925bf6Swillf  *   * Redistributions in binary form must reproduce the above copyright
13*54925bf6Swillf  *       notice, this list of conditions and the following disclaimer in the
14*54925bf6Swillf  *       documentation and/or other materials provided with the distribution.
15*54925bf6Swillf  *   * The copyright holder's name is not used to endorse or promote products
16*54925bf6Swillf  *       derived from this software without specific prior written permission.
17*54925bf6Swillf  *
18*54925bf6Swillf  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19*54925bf6Swillf  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20*54925bf6Swillf  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21*54925bf6Swillf  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22*54925bf6Swillf  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23*54925bf6Swillf  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24*54925bf6Swillf  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25*54925bf6Swillf  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26*54925bf6Swillf  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27*54925bf6Swillf  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28*54925bf6Swillf  * POSSIBILITY OF SUCH DAMAGE.
29*54925bf6Swillf  */
30*54925bf6Swillf /*
31*54925bf6Swillf  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
32*54925bf6Swillf  * Use is subject to license terms.
33*54925bf6Swillf  */
34*54925bf6Swillf 
35*54925bf6Swillf #include "ldap_main.h"
36*54925bf6Swillf #include "kdb_ldap.h"
37*54925bf6Swillf #include "ldap_pwd_policy.h"
38*54925bf6Swillf #include "ldap_err.h"
39*54925bf6Swillf #include <libintl.h>
40*54925bf6Swillf 
41*54925bf6Swillf static char *password_policy_attributes[] = { "cn", "krbmaxpwdlife", "krbminpwdlife",
42*54925bf6Swillf 					      "krbpwdmindiffchars", "krbpwdminlength",
43*54925bf6Swillf 					      "krbpwdhistorylength", NULL };
44*54925bf6Swillf 
45*54925bf6Swillf /*
46*54925bf6Swillf  * Function to create password policy object.
47*54925bf6Swillf  */
48*54925bf6Swillf 
49*54925bf6Swillf krb5_error_code
krb5_ldap_create_password_policy(context,policy)50*54925bf6Swillf krb5_ldap_create_password_policy (context, policy)
51*54925bf6Swillf     krb5_context                context;
52*54925bf6Swillf     osa_policy_ent_t            policy;
53*54925bf6Swillf {
54*54925bf6Swillf     krb5_error_code 	        st=0;
55*54925bf6Swillf     LDAP  		        *ld=NULL;
56*54925bf6Swillf     LDAPMod 		        **mods={NULL};
57*54925bf6Swillf     kdb5_dal_handle             *dal_handle=NULL;
58*54925bf6Swillf     krb5_ldap_context           *ldap_context=NULL;
59*54925bf6Swillf     krb5_ldap_server_handle     *ldap_server_handle=NULL;
60*54925bf6Swillf     char                        **rdns=NULL, *strval[2]={NULL}, *policy_dn;
61*54925bf6Swillf 
62*54925bf6Swillf     /* Clear the global error string */
63*54925bf6Swillf     krb5_clear_error_message(context);
64*54925bf6Swillf 
65*54925bf6Swillf     /* validate the input parameters */
66*54925bf6Swillf     if (policy == NULL || policy->name == NULL)
67*54925bf6Swillf 	return EINVAL;
68*54925bf6Swillf 
69*54925bf6Swillf     SETUP_CONTEXT();
70*54925bf6Swillf     GET_HANDLE();
71*54925bf6Swillf 
72*54925bf6Swillf     st = krb5_ldap_name_to_policydn (context, policy->name, &policy_dn);
73*54925bf6Swillf     if (st != 0)
74*54925bf6Swillf 	goto cleanup;
75*54925bf6Swillf 
76*54925bf6Swillf     /* get the first component of the dn to set the cn attribute */
77*54925bf6Swillf     rdns = ldap_explode_dn(policy_dn, 1);
78*54925bf6Swillf     if (rdns == NULL) {
79*54925bf6Swillf 	st = EINVAL;
80*54925bf6Swillf 	krb5_set_error_message(context, st, gettext("Invalid password policy DN syntax"));
81*54925bf6Swillf 	goto cleanup;
82*54925bf6Swillf     }
83*54925bf6Swillf 
84*54925bf6Swillf     strval[0] = rdns[0];
85*54925bf6Swillf     if ((st=krb5_add_str_mem_ldap_mod(&mods, "cn", LDAP_MOD_ADD, strval)) != 0)
86*54925bf6Swillf 	goto cleanup;
87*54925bf6Swillf 
88*54925bf6Swillf     strval[0] = "krbPwdPolicy";
89*54925bf6Swillf     if ((st=krb5_add_str_mem_ldap_mod(&mods, "objectclass", LDAP_MOD_ADD, strval)) != 0)
90*54925bf6Swillf 	goto cleanup;
91*54925bf6Swillf 
92*54925bf6Swillf     if (((st=krb5_add_int_mem_ldap_mod(&mods, "krbmaxpwdlife", LDAP_MOD_ADD,
93*54925bf6Swillf 				       (signed) policy->pw_max_life)) != 0)
94*54925bf6Swillf 	|| ((st=krb5_add_int_mem_ldap_mod(&mods, "krbminpwdlife", LDAP_MOD_ADD,
95*54925bf6Swillf 					  (signed) policy->pw_min_life)) != 0)
96*54925bf6Swillf 	|| ((st=krb5_add_int_mem_ldap_mod(&mods, "krbpwdmindiffchars", LDAP_MOD_ADD,
97*54925bf6Swillf 					  (signed) policy->pw_min_classes)) != 0)
98*54925bf6Swillf 	|| ((st=krb5_add_int_mem_ldap_mod(&mods, "krbpwdminlength", LDAP_MOD_ADD,
99*54925bf6Swillf 					  (signed) policy->pw_min_length)) != 0)
100*54925bf6Swillf 	|| ((st=krb5_add_int_mem_ldap_mod(&mods, "krbpwdhistorylength", LDAP_MOD_ADD,
101*54925bf6Swillf 					  (signed) policy->pw_history_num)) != 0))
102*54925bf6Swillf 	goto cleanup;
103*54925bf6Swillf 
104*54925bf6Swillf     /* password policy object creation */
105*54925bf6Swillf     if ((st=ldap_add_ext_s(ld, policy_dn, mods, NULL, NULL)) != LDAP_SUCCESS) {
106*54925bf6Swillf 	st = set_ldap_error (context, st, OP_ADD);
107*54925bf6Swillf 	goto cleanup;
108*54925bf6Swillf     }
109*54925bf6Swillf 
110*54925bf6Swillf cleanup:
111*54925bf6Swillf     if (rdns)
112*54925bf6Swillf 	ldap_value_free(rdns);
113*54925bf6Swillf 
114*54925bf6Swillf     if (policy_dn != NULL)
115*54925bf6Swillf 	free (policy_dn);
116*54925bf6Swillf     ldap_mods_free(mods, 1);
117*54925bf6Swillf     krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
118*54925bf6Swillf     return(st);
119*54925bf6Swillf }
120*54925bf6Swillf 
121*54925bf6Swillf /*
122*54925bf6Swillf  * Function to modify password policy object.
123*54925bf6Swillf  */
124*54925bf6Swillf 
125*54925bf6Swillf krb5_error_code
krb5_ldap_put_password_policy(context,policy)126*54925bf6Swillf krb5_ldap_put_password_policy (context, policy)
127*54925bf6Swillf     krb5_context                context;
128*54925bf6Swillf     osa_policy_ent_t            policy;
129*54925bf6Swillf {
130*54925bf6Swillf     char                        *policy_dn;
131*54925bf6Swillf     krb5_error_code 	        st=0;
132*54925bf6Swillf     LDAP  		        *ld=NULL;
133*54925bf6Swillf     LDAPMod 		        **mods=NULL;
134*54925bf6Swillf     kdb5_dal_handle             *dal_handle=NULL;
135*54925bf6Swillf     krb5_ldap_context           *ldap_context=NULL;
136*54925bf6Swillf     krb5_ldap_server_handle     *ldap_server_handle=NULL;
137*54925bf6Swillf 
138*54925bf6Swillf     /* Clear the global error string */
139*54925bf6Swillf     krb5_clear_error_message(context);
140*54925bf6Swillf 
141*54925bf6Swillf     /* validate the input parameters */
142*54925bf6Swillf     if (policy == NULL || policy->name == NULL)
143*54925bf6Swillf 	return EINVAL;
144*54925bf6Swillf 
145*54925bf6Swillf     SETUP_CONTEXT();
146*54925bf6Swillf     GET_HANDLE();
147*54925bf6Swillf 
148*54925bf6Swillf     st = krb5_ldap_name_to_policydn (context, policy->name, &policy_dn);
149*54925bf6Swillf     if (st != 0)
150*54925bf6Swillf 	goto cleanup;
151*54925bf6Swillf 
152*54925bf6Swillf     if (((st=krb5_add_int_mem_ldap_mod(&mods, "krbmaxpwdlife", LDAP_MOD_REPLACE,
153*54925bf6Swillf 				       (signed) policy->pw_max_life)) != 0)
154*54925bf6Swillf 	|| ((st=krb5_add_int_mem_ldap_mod(&mods, "krbminpwdlife", LDAP_MOD_REPLACE,
155*54925bf6Swillf 					  (signed) policy->pw_min_life)) != 0)
156*54925bf6Swillf 	|| ((st=krb5_add_int_mem_ldap_mod(&mods, "krbpwdmindiffchars", LDAP_MOD_REPLACE,
157*54925bf6Swillf 					  (signed) policy->pw_min_classes)) != 0)
158*54925bf6Swillf 	|| ((st=krb5_add_int_mem_ldap_mod(&mods, "krbpwdminlength", LDAP_MOD_REPLACE,
159*54925bf6Swillf 					  (signed) policy->pw_min_length)) != 0)
160*54925bf6Swillf 	|| ((st=krb5_add_int_mem_ldap_mod(&mods, "krbpwdhistorylength", LDAP_MOD_REPLACE,
161*54925bf6Swillf 					  (signed) policy->pw_history_num)) != 0))
162*54925bf6Swillf 	goto cleanup;
163*54925bf6Swillf 
164*54925bf6Swillf     /* modify the password policy object. */
165*54925bf6Swillf     /*
166*54925bf6Swillf      * This will fail if the 'policy_dn' is anywhere other than under the realm
167*54925bf6Swillf      * container. This is correct behaviour. 'kdb5_ldap_util' will support
168*54925bf6Swillf      * management of only such policy objects.
169*54925bf6Swillf      */
170*54925bf6Swillf     if ((st=ldap_modify_ext_s(ld, policy_dn, mods, NULL, NULL)) != LDAP_SUCCESS) {
171*54925bf6Swillf 	st = set_ldap_error (context, st, OP_MOD);
172*54925bf6Swillf 	goto cleanup;
173*54925bf6Swillf     }
174*54925bf6Swillf 
175*54925bf6Swillf cleanup:
176*54925bf6Swillf     if (policy_dn != NULL)
177*54925bf6Swillf 	free (policy_dn);
178*54925bf6Swillf     ldap_mods_free(mods, 1);
179*54925bf6Swillf     krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
180*54925bf6Swillf     return(st);
181*54925bf6Swillf }
182*54925bf6Swillf 
183*54925bf6Swillf krb5_error_code
populate_policy(krb5_context context,LDAP * ld,LDAPMessage * ent,char * pol_name,osa_policy_ent_t pol_entry)184*54925bf6Swillf populate_policy(krb5_context context,
185*54925bf6Swillf     LDAP *ld,
186*54925bf6Swillf     LDAPMessage *ent,
187*54925bf6Swillf     char *pol_name,
188*54925bf6Swillf     osa_policy_ent_t pol_entry)
189*54925bf6Swillf {
190*54925bf6Swillf     int st = 0;
191*54925bf6Swillf     char *pol_dn;
192*54925bf6Swillf 
193*54925bf6Swillf     pol_entry->name = strdup(pol_name);
194*54925bf6Swillf     CHECK_NULL(pol_entry->name);
195*54925bf6Swillf     pol_entry->version = 1;
196*54925bf6Swillf 
197*54925bf6Swillf     krb5_ldap_get_value(ld, ent, "krbmaxpwdlife", (int *)&(pol_entry->pw_max_life));
198*54925bf6Swillf     krb5_ldap_get_value(ld, ent, "krbminpwdlife", (int *)&(pol_entry->pw_min_life));
199*54925bf6Swillf     krb5_ldap_get_value(ld, ent, "krbpwdmindiffchars", (int *)&(pol_entry->pw_min_classes));
200*54925bf6Swillf     krb5_ldap_get_value(ld, ent, "krbpwdminlength", (int *)&(pol_entry->pw_min_length));
201*54925bf6Swillf     krb5_ldap_get_value(ld, ent, "krbpwdhistorylength", (int *)&(pol_entry->pw_history_num));
202*54925bf6Swillf 
203*54925bf6Swillf     /* Get the reference count */
204*54925bf6Swillf     pol_dn = ldap_get_dn(ld, ent);
205*54925bf6Swillf     st = krb5_ldap_get_reference_count (context, pol_dn, "krbPwdPolicyReference",
206*54925bf6Swillf 	    (int *)&(pol_entry->policy_refcnt), ld);
207*54925bf6Swillf     ldap_memfree(pol_dn);
208*54925bf6Swillf 
209*54925bf6Swillf cleanup:
210*54925bf6Swillf     /* Solaris Kerberos: trying to avoid memory leaks */
211*54925bf6Swillf     if (st != 0) {
212*54925bf6Swillf 	free(pol_entry->name);
213*54925bf6Swillf 	pol_entry->name = NULL;
214*54925bf6Swillf     }
215*54925bf6Swillf     return st;
216*54925bf6Swillf }
217*54925bf6Swillf 
218*54925bf6Swillf krb5_error_code
krb5_ldap_get_password_policy_from_dn(krb5_context context,char * pol_name,char * pol_dn,osa_policy_ent_t * policy,int * cnt)219*54925bf6Swillf krb5_ldap_get_password_policy_from_dn (krb5_context context,
220*54925bf6Swillf     char *pol_name,
221*54925bf6Swillf     char *pol_dn,
222*54925bf6Swillf     osa_policy_ent_t *policy,
223*54925bf6Swillf     int *cnt)
224*54925bf6Swillf {
225*54925bf6Swillf     krb5_error_code             st=0, tempst=0;
226*54925bf6Swillf     LDAP  		        *ld=NULL;
227*54925bf6Swillf     LDAPMessage                 *result=NULL,*ent=NULL;
228*54925bf6Swillf     kdb5_dal_handle             *dal_handle=NULL;
229*54925bf6Swillf     krb5_ldap_context           *ldap_context=NULL;
230*54925bf6Swillf     krb5_ldap_server_handle     *ldap_server_handle=NULL;
231*54925bf6Swillf 
232*54925bf6Swillf     /* Clear the global error string */
233*54925bf6Swillf     krb5_clear_error_message(context);
234*54925bf6Swillf 
235*54925bf6Swillf     /* validate the input parameters */
236*54925bf6Swillf     if (pol_dn == NULL)
237*54925bf6Swillf 	return EINVAL;
238*54925bf6Swillf 
239*54925bf6Swillf     *policy = NULL;
240*54925bf6Swillf     SETUP_CONTEXT();
241*54925bf6Swillf     GET_HANDLE();
242*54925bf6Swillf 
243*54925bf6Swillf     *cnt = 0;
244*54925bf6Swillf     *(policy) = (osa_policy_ent_t) malloc(sizeof(osa_policy_ent_rec));
245*54925bf6Swillf     if (*policy == NULL) {
246*54925bf6Swillf 	st = ENOMEM;
247*54925bf6Swillf 	goto cleanup;
248*54925bf6Swillf     }
249*54925bf6Swillf     memset(*policy, 0, sizeof(osa_policy_ent_rec));
250*54925bf6Swillf 
251*54925bf6Swillf     LDAP_SEARCH(pol_dn, LDAP_SCOPE_BASE, "(objectclass=krbPwdPolicy)", password_policy_attributes);
252*54925bf6Swillf     *cnt = 1;
253*54925bf6Swillf #if 0 /************** Begin IFDEF'ed OUT *******************************/
254*54925bf6Swillf     (*policy)->name = strdup(name);
255*54925bf6Swillf     CHECK_NULL((*policy)->name);
256*54925bf6Swillf     (*policy)->version = 1;
257*54925bf6Swillf #endif /**************** END IFDEF'ed OUT *******************************/
258*54925bf6Swillf 
259*54925bf6Swillf     ent=ldap_first_entry(ld, result);
260*54925bf6Swillf     if (ent != NULL) {
261*54925bf6Swillf 	if ((st = populate_policy(context, ld, ent, pol_name, *policy)) != 0)
262*54925bf6Swillf 	    goto cleanup;
263*54925bf6Swillf #if 0 /************** Begin IFDEF'ed OUT *******************************/
264*54925bf6Swillf 	krb5_ldap_get_value(ld, ent, "krbmaxpwdlife", &((*policy)->pw_max_life));
265*54925bf6Swillf 	krb5_ldap_get_value(ld, ent, "krbminpwdlife", &((*policy)->pw_min_life));
266*54925bf6Swillf 	krb5_ldap_get_value(ld, ent, "krbpwdmindiffchars", &((*policy)->pw_min_classes));
267*54925bf6Swillf 	krb5_ldap_get_value(ld, ent, "krbpwdminlength", &((*policy)->pw_min_length));
268*54925bf6Swillf 	krb5_ldap_get_value(ld, ent, "krbpwdhistorylength", &((*policy)->pw_history_num));
269*54925bf6Swillf 
270*54925bf6Swillf 	/* Get the reference count */
271*54925bf6Swillf 	st = krb5_ldap_get_reference_count (context,
272*54925bf6Swillf 					    name,
273*54925bf6Swillf 					    "krbPwdPolicyReference",
274*54925bf6Swillf 					    &(*policy)->policy_refcnt,
275*54925bf6Swillf 					    ld);
276*54925bf6Swillf #endif /**************** END IFDEF'ed OUT *******************************/
277*54925bf6Swillf     }
278*54925bf6Swillf 
279*54925bf6Swillf cleanup:
280*54925bf6Swillf     ldap_msgfree(result);
281*54925bf6Swillf     if (st != 0) {
282*54925bf6Swillf 	if (*policy != NULL) {
283*54925bf6Swillf 	    krb5_ldap_free_password_policy(context, *policy);
284*54925bf6Swillf 	    *policy = NULL;
285*54925bf6Swillf 	}
286*54925bf6Swillf     }
287*54925bf6Swillf 
288*54925bf6Swillf     krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
289*54925bf6Swillf     return st;
290*54925bf6Swillf }
291*54925bf6Swillf 
292*54925bf6Swillf /*
293*54925bf6Swillf  * Convert 'name' into a directory DN and call
294*54925bf6Swillf  * 'krb5_ldap_get_password_policy_from_dn'
295*54925bf6Swillf  */
296*54925bf6Swillf krb5_error_code
krb5_ldap_get_password_policy(context,name,policy,cnt)297*54925bf6Swillf krb5_ldap_get_password_policy (context, name, policy, cnt)
298*54925bf6Swillf     krb5_context                context;
299*54925bf6Swillf     char                        *name;
300*54925bf6Swillf     osa_policy_ent_t            *policy;
301*54925bf6Swillf     int                         *cnt;
302*54925bf6Swillf {
303*54925bf6Swillf     krb5_error_code             st = 0;
304*54925bf6Swillf     char                        *policy_dn = NULL;
305*54925bf6Swillf 
306*54925bf6Swillf     /* Clear the global error string */
307*54925bf6Swillf     krb5_clear_error_message(context);
308*54925bf6Swillf 
309*54925bf6Swillf     /* validate the input parameters */
310*54925bf6Swillf     if (name == NULL) {
311*54925bf6Swillf 	st = EINVAL;
312*54925bf6Swillf 	goto cleanup;
313*54925bf6Swillf     }
314*54925bf6Swillf 
315*54925bf6Swillf     st = krb5_ldap_name_to_policydn(context, name, &policy_dn);
316*54925bf6Swillf     if (st != 0)
317*54925bf6Swillf 	goto cleanup;
318*54925bf6Swillf 
319*54925bf6Swillf     st = krb5_ldap_get_password_policy_from_dn(context, name, policy_dn, policy, cnt);
320*54925bf6Swillf 
321*54925bf6Swillf cleanup:
322*54925bf6Swillf     if (policy_dn != NULL)
323*54925bf6Swillf 	free (policy_dn);
324*54925bf6Swillf     return st;
325*54925bf6Swillf }
326*54925bf6Swillf 
327*54925bf6Swillf krb5_error_code
krb5_ldap_delete_password_policy(context,policy)328*54925bf6Swillf krb5_ldap_delete_password_policy (context, policy)
329*54925bf6Swillf     krb5_context                context;
330*54925bf6Swillf     char                        *policy;
331*54925bf6Swillf {
332*54925bf6Swillf     int                         mask = 0;
333*54925bf6Swillf     char                        *policy_dn = NULL, *class[] = {"krbpwdpolicy", NULL};
334*54925bf6Swillf     krb5_error_code             st=0;
335*54925bf6Swillf     LDAP                        *ld=NULL;
336*54925bf6Swillf     kdb5_dal_handle             *dal_handle=NULL;
337*54925bf6Swillf     krb5_ldap_context           *ldap_context=NULL;
338*54925bf6Swillf     krb5_ldap_server_handle     *ldap_server_handle=NULL;
339*54925bf6Swillf 
340*54925bf6Swillf     /* Clear the global error string */
341*54925bf6Swillf     krb5_clear_error_message(context);
342*54925bf6Swillf 
343*54925bf6Swillf     /* validate the input parameters */
344*54925bf6Swillf     if (policy == NULL)
345*54925bf6Swillf 	return EINVAL;
346*54925bf6Swillf 
347*54925bf6Swillf     SETUP_CONTEXT();
348*54925bf6Swillf     GET_HANDLE();
349*54925bf6Swillf 
350*54925bf6Swillf     st = krb5_ldap_name_to_policydn (context, policy, &policy_dn);
351*54925bf6Swillf     if (st != 0)
352*54925bf6Swillf 	goto cleanup;
353*54925bf6Swillf 
354*54925bf6Swillf     /* Ensure that the object is a password policy */
355*54925bf6Swillf     if ((st=checkattributevalue(ld, policy_dn, "objectclass", class, &mask)) != 0)
356*54925bf6Swillf 	goto cleanup;
357*54925bf6Swillf 
358*54925bf6Swillf     if (mask == 0) {
359*54925bf6Swillf 	st = KRB5_KDB_NOENTRY;
360*54925bf6Swillf 	goto cleanup;
361*54925bf6Swillf     }
362*54925bf6Swillf 
363*54925bf6Swillf     if ((st=ldap_delete_ext_s(ld, policy_dn, NULL, NULL)) != LDAP_SUCCESS) {
364*54925bf6Swillf 	st = set_ldap_error (context, st, OP_DEL);
365*54925bf6Swillf 	goto cleanup;
366*54925bf6Swillf     }
367*54925bf6Swillf 
368*54925bf6Swillf cleanup:
369*54925bf6Swillf     krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
370*54925bf6Swillf     if (policy_dn != NULL)
371*54925bf6Swillf 	free (policy_dn);
372*54925bf6Swillf 
373*54925bf6Swillf     return st;
374*54925bf6Swillf }
375*54925bf6Swillf 
376*54925bf6Swillf krb5_error_code
krb5_ldap_iterate_password_policy(context,match_expr,func,func_arg)377*54925bf6Swillf krb5_ldap_iterate_password_policy(context, match_expr, func, func_arg)
378*54925bf6Swillf     krb5_context                context;
379*54925bf6Swillf     char                        *match_expr;
380*54925bf6Swillf     void                        (*func) (krb5_pointer, osa_policy_ent_t);
381*54925bf6Swillf     krb5_pointer                func_arg;
382*54925bf6Swillf {
383*54925bf6Swillf     osa_policy_ent_rec          *entry=NULL;
384*54925bf6Swillf     char		        *policy=NULL;
385*54925bf6Swillf     krb5_error_code             st=0, tempst=0;
386*54925bf6Swillf     LDAP		        *ld=NULL;
387*54925bf6Swillf     LDAPMessage	                *result=NULL, *ent=NULL;
388*54925bf6Swillf     kdb5_dal_handle             *dal_handle=NULL;
389*54925bf6Swillf     krb5_ldap_context           *ldap_context=NULL;
390*54925bf6Swillf     krb5_ldap_server_handle     *ldap_server_handle=NULL;
391*54925bf6Swillf 
392*54925bf6Swillf     /* Clear the global error string */
393*54925bf6Swillf     krb5_clear_error_message(context);
394*54925bf6Swillf 
395*54925bf6Swillf     SETUP_CONTEXT();
396*54925bf6Swillf     GET_HANDLE();
397*54925bf6Swillf 
398*54925bf6Swillf     if (ldap_context->lrparams->realmdn == NULL) {
399*54925bf6Swillf 	st = EINVAL;
400*54925bf6Swillf 	goto cleanup;
401*54925bf6Swillf     }
402*54925bf6Swillf 
403*54925bf6Swillf     LDAP_SEARCH(ldap_context->lrparams->realmdn, LDAP_SCOPE_ONELEVEL, "(objectclass=krbpwdpolicy)", password_policy_attributes);
404*54925bf6Swillf     for (ent=ldap_first_entry(ld, result); ent != NULL; ent=ldap_next_entry(ld, ent)) {
405*54925bf6Swillf 	krb5_boolean attr_present;
406*54925bf6Swillf 
407*54925bf6Swillf 	st = krb5_ldap_get_string(ld, ent, "cn", &policy, &attr_present);
408*54925bf6Swillf 	if (st != 0)
409*54925bf6Swillf 	    goto cleanup;
410*54925bf6Swillf 	if (attr_present == FALSE)
411*54925bf6Swillf 	    continue;
412*54925bf6Swillf 
413*54925bf6Swillf 	entry = (osa_policy_ent_t) malloc(sizeof(osa_policy_ent_rec));
414*54925bf6Swillf 	CHECK_NULL(entry);
415*54925bf6Swillf 	memset(entry, 0, sizeof(osa_policy_ent_rec));
416*54925bf6Swillf 	if ((st = populate_policy(context, ld, ent, policy, entry)) != 0)
417*54925bf6Swillf 	    goto cleanup;
418*54925bf6Swillf #if 0 /************** Begin IFDEF'ed OUT *******************************/
419*54925bf6Swillf 	entry->name = policy;
420*54925bf6Swillf 	entry->version = 1;
421*54925bf6Swillf 
422*54925bf6Swillf 	krb5_ldap_get_value(ld, ent, "krbmaxpwdlife", &(entry->pw_max_life));
423*54925bf6Swillf 	krb5_ldap_get_value(ld, ent, "krbminpwdlife", &(entry->pw_min_life));
424*54925bf6Swillf 	krb5_ldap_get_value(ld, ent, "krbpwdmindiffchars", &(entry->pw_min_classes));
425*54925bf6Swillf 	krb5_ldap_get_value(ld, ent, "krbpwdminlength", &(entry->pw_min_length));
426*54925bf6Swillf 	krb5_ldap_get_value(ld, ent, "krbpwdhistorylength", &(entry->pw_history_num));
427*54925bf6Swillf 
428*54925bf6Swillf 	/* Get the reference count */
429*54925bf6Swillf 	st = krb5_ldap_get_reference_count (context,
430*54925bf6Swillf 					    policy,
431*54925bf6Swillf 					    "krbPwdPolicyReference",
432*54925bf6Swillf 					    &(entry->policy_refcnt),
433*54925bf6Swillf 					    ld);
434*54925bf6Swillf #endif /**************** END IFDEF'ed OUT *******************************/
435*54925bf6Swillf 
436*54925bf6Swillf 	(*func)(func_arg, entry);
437*54925bf6Swillf 	/* XXX this will free policy so don't free it */
438*54925bf6Swillf 	krb5_ldap_free_password_policy(context, entry);
439*54925bf6Swillf 	entry = NULL;
440*54925bf6Swillf     }
441*54925bf6Swillf     ldap_msgfree(result);
442*54925bf6Swillf 
443*54925bf6Swillf cleanup:
444*54925bf6Swillf     if (entry)
445*54925bf6Swillf 	free (entry);
446*54925bf6Swillf 
447*54925bf6Swillf     krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
448*54925bf6Swillf     return st;
449*54925bf6Swillf }
450*54925bf6Swillf 
451*54925bf6Swillf void
krb5_ldap_free_password_policy(context,entry)452*54925bf6Swillf krb5_ldap_free_password_policy (context, entry)
453*54925bf6Swillf     krb5_context                context;
454*54925bf6Swillf     osa_policy_ent_t            entry;
455*54925bf6Swillf {
456*54925bf6Swillf     if (entry) {
457*54925bf6Swillf 	if (entry->name)
458*54925bf6Swillf 	    free(entry->name);
459*54925bf6Swillf 	free(entry);
460*54925bf6Swillf     }
461*54925bf6Swillf     return;
462*54925bf6Swillf }
463