1#pragma ident	"%Z%%M%	%I%	%E% SMI"
2
3/*
4 * lib/kdb/kdb_ldap/ldap_service_rights.c
5 *
6 * Copyright (c) 2004-2005, Novell, Inc.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *   * Redistributions of source code must retain the above copyright notice,
13 *       this list of conditions and the following disclaimer.
14 *   * Redistributions in binary form must reproduce the above copyright
15 *       notice, this list of conditions and the following disclaimer in the
16 *       documentation and/or other materials provided with the distribution.
17 *   * The copyright holder's name is not used to endorse or promote products
18 *       derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "ldap_main.h"
34#include "ldap_services.h"
35#include "ldap_err.h"
36
37/* NOTE: add appropriate rights for krbpasswordexpiration attribute */
38
39#ifdef HAVE_EDIRECTORY
40
41static char *kdcrights_subtree[][2] = {
42    {"1#subtree#","#[Entry Rights]"},
43    {"2#subtree#","#CN"},
44    {"6#subtree#","#ObjectClass"},
45    {"2#subtree#","#krbTicketPolicyReference"},
46    {"2#subtree#","#krbUPEnabled"},
47    {"2#subtree#","#krbHostServer"},
48    {"2#subtree#","#krbServiceFlags"},
49    {"2#subtree#","#krbRealmReferences"},
50    {"2#subtree#","#krbTicketFlags"},
51    {"2#subtree#","#krbMaxTicketLife"},
52    {"2#subtree#","#krbMaxRenewableAge"},
53    {"2#subtree#","#krbPrincipalName"},
54    {"6#subtree#","#krbPrincipalKey"},
55    {"2#subtree#","#krbPrincipalExpiration"},
56    {"2#subtree#","#krbPwdPolicyReference"},
57    {"2#subtree#","#krbMaxPwdLife"},
58    {"6#subtree#","#ModifiersName"},
59    {"2#subtree#","#PasswordExpirationTime"},
60    {"2#subtree#","#PasswordExpirationInterval"},
61    {"2#subtree#","#PasswordMinimumLength"},
62    {"2#subtree#","#PasswordAllowChange"},
63    {"2#subtree#","#LoginDisabled"},
64    {"6#subtree#","#LastLoginTime"},
65    {"2#subtree#","#LoginExpirationTime"},
66    {"6#subtree#","#LoginIntruderAttempts"},
67    {"2#subtree#","#IntruderAttemptResetInterval"},
68    {"2#subtree#","#LoginIntruderLimit"},
69    {"6#subtree#","#LoginIntruderResetTime"},
70    {"2#subtree#","#DetectIntruder"},
71    {"2#subtree#","#LockoutAfterDetection"},
72    {"6#subtree#","#LockedByIntruder"},
73    {"2#subtree#","#krbPrincipalReferences"},
74    { "", "" }
75};
76
77static char *adminrights_subtree[][2]={
78    {"15#subtree#","#[Entry Rights]"},
79    {"6#subtree#","#CN"},
80    {"6#subtree#","#ObjectClass"},
81    {"6#subtree#","#krbTicketPolicyReference"},
82    {"6#subtree#","#krbUPEnabled"},
83    {"2#subtree#","#krbHostServer"},
84    {"2#subtree#","#krbServiceFlags"},
85    {"2#subtree#","#krbRealmReferences"},
86    {"6#subtree#","#krbTicketFlags"},
87    {"6#subtree#","#krbMaxTicketLife"},
88    {"6#subtree#","#krbMaxRenewableAge"},
89    {"6#subtree#","#krbPrincipalName"},
90    {"6#subtree#","#krbPrincipalKey"},
91    {"6#subtree#","#krbPrincipalExpiration"},
92    {"6#subtree#","#ModifiersName"},
93    {"6#subtree#","#PasswordExpirationTime"},
94    {"2#subtree#","#PasswordExpirationInterval"},
95    {"6#subtree#","#PasswordMinimumLength"},
96    {"6#subtree#","#PasswordAllowChange"},
97    {"6#subtree#","#LoginDisabled"},
98    {"2#subtree#","#LastLoginTime"},
99    {"2#subtree#","#LoginExpirationTime"},
100    {"2#subtree#","#LoginIntruderAttempts"},
101    {"6#subtree#","#IntruderAttemptResetInterval"},
102    {"6#subtree#","#LoginIntruderLimit"},
103    {"6#subtree#","#LoginIntruderResetTime"},
104    {"6#subtree#","#DetectIntruder"},
105    {"6#subtree#","#LockoutAfterDetection"},
106    {"2#subtree#","#LockedByIntruder"},
107    {"2#subtree#","#krbPrincipalReferences"},
108    {"6#subtree#","#Surname"},
109    {"4#subtree#","#passwordManagement"},
110    {"6#subtree#","#krbPwdHistoryLength"},
111    {"6#subtree#","#krbMinPwdLife"},
112    {"6#subtree#","#krbMaxPwdLife"},
113    {"6#subtree#","#krbPwdMinDiffChars"},
114    {"6#subtree#","#krbPwdMinLength"},
115    {"6#subtree#","#krbPwdPolicyReference"},
116    { "","" }
117};
118
119static char *pwdrights_subtree[][2] = {
120    {"1#subtree#","#[Entry Rights]"},
121    {"2#subtree#","#CN"},
122    {"2#subtree#","#ObjectClass"},
123    {"2#subtree#","#krbTicketPolicyReference"},
124    {"2#subtree#","#krbUPEnabled"},
125    {"2#subtree#","#krbHostServer"},
126    {"2#subtree#","#krbServiceFlags"},
127    {"2#subtree#","#krbRealmReferences"},
128    {"6#subtree#","#krbTicketFlags"},
129    {"2#subtree#","#krbMaxTicketLife"},
130    {"2#subtree#","#krbMaxRenewableAge"},
131    {"2#subtree#","#krbPrincipalName"},
132    {"6#subtree#","#krbPrincipalKey"},
133    {"2#subtree#","#krbPrincipalExpiration"},
134    {"4#subtree#","#passwordManagement"},
135    {"6#subtree#","#ModifiersName"},
136    {"2#subtree#","#krbPwdHistoryLength"},
137    {"2#subtree#","#krbMinPwdLife"},
138    {"2#subtree#","#krbMaxPwdLife"},
139    {"2#subtree#","#krbPwdMinDiffChars"},
140    {"2#subtree#","#krbPwdMinLength"},
141    {"2#subtree#","#krbPwdPolicyReference"},
142    { "", "" }
143};
144
145static char *kdcrights_realmcontainer[][2]={
146    {"1#subtree#","#[Entry Rights]"},
147    {"2#subtree#","#CN"},
148    {"6#subtree#","#ObjectClass"},
149    {"2#subtree#","#krbTicketPolicyReference"},
150    {"2#subtree#","#krbMKey"},
151    {"2#subtree#","#krbUPEnabled"},
152    {"2#subtree#","#krbSubTrees"},
153    {"2#subtree#","#krbPrincContainerRef"},
154    {"2#subtree#","#krbSearchScope"},
155    {"2#subtree#","#krbLdapServers"},
156    {"2#subtree#","#krbSupportedEncSaltTypes"},
157    {"2#subtree#","#krbDefaultEncSaltTypes"},
158    {"2#subtree#","#krbKdcServers"},
159    {"2#subtree#","#krbPwdServers"},
160    {"2#subtree#","#krbTicketFlags"},
161    {"2#subtree#","#krbMaxTicketLife"},
162    {"2#subtree#","#krbMaxRenewableAge"},
163    {"2#subtree#","#krbPrincipalName"},
164    {"6#subtree#","#krbPrincipalKey"},
165    {"2#subtree#","#krbPrincipalExpiration"},
166    {"2#subtree#","#krbPwdPolicyReference"},
167    {"2#subtree#","#krbMaxPwdLife"},
168    {"6#subtree#","#ModifiersName"},
169    {"2#subtree#","#PasswordExpirationTime"},
170    {"2#subtree#","#PasswordExpirationInterval"},
171    {"2#subtree#","#PasswordMinimumLength"},
172    {"2#subtree#","#PasswordAllowChange"},
173    {"2#subtree#","#LoginDisabled"},
174    {"6#subtree#","#LastLoginTime"},
175    {"2#subtree#","#LoginExpirationTime"},
176    {"6#subtree#","#LoginIntruderAttempts"},
177    {"2#subtree#","#IntruderAttemptResetInterval"},
178    {"2#subtree#","#LoginIntruderLimit"},
179    {"6#subtree#","#LoginIntruderResetTime"},
180    {"2#subtree#","#DetectIntruder"},
181    {"2#subtree#","#LockoutAfterDetection"},
182    {"6#subtree#","#LockedByIntruder"},
183    { "", "" }
184};
185
186
187static char *adminrights_realmcontainer[][2]={
188    {"15#subtree#","#[Entry Rights]"},
189    {"6#subtree#","#CN"},
190    {"6#subtree#","#ObjectClass"},
191    {"6#subtree#","#krbTicketPolicyReference"},
192    {"2#subtree#","#krbMKey"},
193    {"6#subtree#","#krbUPEnabled"},
194    {"2#subtree#","#krbSubTrees"},
195    {"2#subtree#","#krbPrincContainerRef"},
196    {"2#subtree#","#krbSearchScope"},
197    {"2#subtree#","#krbLdapServers"},
198    {"2#subtree#","#krbSupportedEncSaltTypes"},
199    {"2#subtree#","#krbDefaultEncSaltTypes"},
200    {"2#subtree#","#krbKdcServers"},
201    {"2#subtree#","#krbPwdServers"},
202    {"6#subtree#","#krbTicketFlags"},
203    {"6#subtree#","#krbMaxTicketLife"},
204    {"6#subtree#","#krbMaxRenewableAge"},
205    {"6#subtree#","#krbPrincipalName"},
206    {"6#subtree#","#krbPrincipalKey"},
207    {"6#subtree#","#krbPrincipalExpiration"},
208    {"6#subtree#","#ModifiersName"},
209    {"6#subtree#","#PasswordExpirationTime"},
210    {"2#subtree#","#PasswordExpirationInterval"},
211    {"6#subtree#","#PasswordMinimumLength"},
212    {"6#subtree#","#PasswordAllowChange"},
213    {"6#subtree#","#LoginDisabled"},
214    {"2#subtree#","#LastLoginTime"},
215    {"2#subtree#","#LoginExpirationTime"},
216    {"2#subtree#","#LoginIntruderAttempts"},
217    {"6#subtree#","#IntruderAttemptResetInterval"},
218    {"6#subtree#","#LoginIntruderLimit"},
219    {"6#subtree#","#LoginIntruderResetTime"},
220    {"6#subtree#","#DetectIntruder"},
221    {"6#subtree#","#LockoutAfterDetection"},
222    {"2#subtree#","#LockedByIntruder"},
223    {"6#subtree#","#Surname"},
224    {"6#subtree#","#krbPwdHistoryLength"},
225    {"6#subtree#","#krbMinPwdLife"},
226    {"6#subtree#","#krbMaxPwdLife"},
227    {"6#subtree#","#krbPwdMinDiffChars"},
228    {"6#subtree#","#krbPwdMinLength"},
229    {"6#subtree#","#krbPwdPolicyReference"},
230    { "","" }
231};
232
233
234static char *pwdrights_realmcontainer[][2]={
235    {"1#subtree#","#[Entry Rights]"},
236    {"2#subtree#","#CN"},
237    {"2#subtree#","#ObjectClass"},
238    {"2#subtree#","#krbTicketPolicyReference"},
239    {"2#subtree#","#krbMKey"},
240    {"2#subtree#","#krbUPEnabled"},
241    {"2#subtree#","#krbSubTrees"},
242    {"2#subtree#","#krbPrincContainerRef"},
243    {"2#subtree#","#krbSearchScope"},
244    {"2#subtree#","#krbLdapServers"},
245    {"2#subtree#","#krbSupportedEncSaltTypes"},
246    {"2#subtree#","#krbDefaultEncSaltTypes"},
247    {"2#subtree#","#krbKdcServers"},
248    {"2#subtree#","#krbPwdServers"},
249    {"6#subtree#","#krbTicketFlags"},
250    {"2#subtree#","#krbMaxTicketLife"},
251    {"2#subtree#","#krbMaxRenewableAge"},
252    {"2#subtree#","#krbPrincipalName"},
253    {"6#subtree#","#krbPrincipalKey"},
254    {"2#subtree#","#krbPrincipalExpiration"},
255    {"6#subtree#","#ModifiersName"},
256    {"2#subtree#","#krbPwdHistoryLength"},
257    {"2#subtree#","#krbMinPwdLife"},
258    {"2#subtree#","#krbMaxPwdLife"},
259    {"2#subtree#","#krbPwdMinDiffChars"},
260    {"2#subtree#","#krbPwdMinLength"},
261    {"2#subtree#","#krbPwdPolicyReference"},
262    { "", "" }
263};
264
265static char *security_container[][2] = {
266    {"1#subtree#","#[Entry Rights]"},
267    {"2#subtree#","#krbContainerReference"},
268    { "", "" }
269};
270
271static char *kerberos_container[][2] = {
272    {"1#subtree#","#[Entry Rights]"},
273    {"2#subtree#","#krbTicketPolicyReference"},
274    { "", "" }
275};
276
277
278/*
279 * This will set the rights for the Kerberos service objects.
280 * The function will read the subtree attribute from the specified
281 * realm name and will the appropriate rights on both the realm
282 * container and the subtree. The kerberos context passed should
283 * have a valid ldap handle, with appropriate rights to write acl
284 * attributes.
285 *
286 * krb5_context - IN The Kerberos context with valid ldap handle
287 *
288 */
289
290krb5_error_code
291krb5_ldap_add_service_rights(context, servicetype, serviceobjdn, realmname, subtreeparam, mask)
292    krb5_context	context;
293    int                 servicetype;
294    char                *serviceobjdn;
295    char                *realmname;
296    char                **subtreeparam;
297    int                 mask;
298{
299
300    int                    st=0,i=0;
301    char                   *realmacls[2]={NULL}, *subtreeacls[2]={NULL}, *seccontacls[2]={NULL}, *krbcontacls[2]={NULL};
302    LDAP                   *ld;
303    LDAPMod                realmclass, subtreeclass, seccontclass, krbcontclass;
304    LDAPMod                *realmarr[3]={NULL}, *subtreearr[3]={NULL}, *seccontarr[3]={NULL}, *krbcontarr[3]={NULL};
305    char                   *realmdn=NULL, **subtree=NULL;
306    kdb5_dal_handle        *dal_handle=NULL;
307    krb5_ldap_context      *ldap_context=NULL;
308    krb5_ldap_server_handle *ldap_server_handle=NULL;
309    int                     subtreecount=0;
310
311    SETUP_CONTEXT();
312    GET_HANDLE();
313
314    if ((serviceobjdn == NULL) || (realmname == NULL) || (servicetype < 0) || (servicetype > 4)
315	|| (ldap_context->krbcontainer->DN == NULL)) {
316	st=-1;
317	goto cleanup;
318    }
319
320    subtreecount=ldap_context->lrparams->subtreecount;
321    subtree = (char **) malloc(sizeof(char *) * (subtreecount + 1));
322    if(subtree == NULL) {
323        st = ENOMEM;
324        goto cleanup;
325    }
326
327    /* If the subtree is null, set the value to root */
328    if(subtreeparam == NULL) {
329        subtree[0] = strdup("");
330        if(subtree[0] == NULL) {
331            st = ENOMEM;
332            goto cleanup;
333        }
334    }
335    else {
336        for (i=0; subtree[i] != NULL && i<subtreecount; i++) {
337            subtree[i] = strdup(subtreeparam[i]);
338            if(subtree[i] == NULL) {
339                st = ENOMEM;
340                goto cleanup;
341            }
342        }
343    }
344
345    /* Set the rights for the service object on the security container */
346    seccontclass.mod_op = LDAP_MOD_ADD;
347    seccontclass.mod_type = "ACL";
348
349    for (i=0; strcmp(security_container[i][0], "") != 0; i++) {
350
351	seccontacls[0] = (char *)malloc(strlen(security_container[i][0]) +
352					strlen(serviceobjdn) +
353					strlen(security_container[i][1]) + 1);
354	if (seccontacls[0] == NULL) {
355	    st = ENOMEM;
356	    goto cleanup;
357	}
358
359	sprintf(seccontacls[0], "%s%s%s", security_container[i][0], serviceobjdn,
360		security_container[i][1]);
361	seccontclass.mod_values = seccontacls;
362
363	seccontarr[0] = &seccontclass;
364
365	st = ldap_modify_ext_s(ld,
366			       SECURITY_CONTAINER,
367			       seccontarr,
368			       NULL,
369			       NULL);
370	if (st != LDAP_SUCCESS && st != LDAP_TYPE_OR_VALUE_EXISTS && st != LDAP_OTHER) {
371	    free(seccontacls[0]);
372	    st = set_ldap_error (context, st, OP_MOD);
373	    goto cleanup;
374	}
375	free(seccontacls[0]);
376    }
377
378
379    /* Set the rights for the service object on the kerberos container */
380    krbcontclass.mod_op = LDAP_MOD_ADD;
381    krbcontclass.mod_type = "ACL";
382
383    for (i=0; strcmp(kerberos_container[i][0], "") != 0; i++) {
384	krbcontacls[0] = (char *)malloc(strlen(kerberos_container[i][0]) + strlen(serviceobjdn)
385					+ strlen(kerberos_container[i][1]) + 1);
386	if (krbcontacls[0] == NULL) {
387	    st = ENOMEM;
388	    goto cleanup;
389	}
390	sprintf(krbcontacls[0], "%s%s%s", kerberos_container[i][0], serviceobjdn,
391		kerberos_container[i][1]);
392	krbcontclass.mod_values = krbcontacls;
393
394	krbcontarr[0] = &krbcontclass;
395
396	st = ldap_modify_ext_s(ld,
397			       ldap_context->krbcontainer->DN,
398			       krbcontarr,
399			       NULL,
400			       NULL);
401	if (st != LDAP_SUCCESS && st != LDAP_TYPE_OR_VALUE_EXISTS && st != LDAP_OTHER) {
402	    free(krbcontacls[0]);
403	    st = set_ldap_error (context, st, OP_MOD);
404	    goto cleanup;
405	}
406	free(krbcontacls[0]);
407    }
408
409    /* Set the rights for the realm */
410    if (mask & LDAP_REALM_RIGHTS) {
411
412	/* Construct the realm dn from realm name */
413	realmdn = (char *)malloc(strlen("cn=") + strlen(realmname) +
414				 strlen(ldap_context->krbcontainer->DN) + 2);
415	if (realmdn == NULL) {
416	    st = ENOMEM;
417	    goto cleanup;
418	}
419	sprintf(realmdn,"cn=%s,%s", realmname, ldap_context->krbcontainer->DN);
420
421	realmclass.mod_op = LDAP_MOD_ADD;
422	realmclass.mod_type = "ACL";
423
424	if (servicetype == LDAP_KDC_SERVICE) {
425	    for (i=0; strcmp(kdcrights_realmcontainer[i][0], "") != 0; i++) {
426		realmacls[0] = (char *)malloc(strlen(kdcrights_realmcontainer[i][0])
427					      + strlen(serviceobjdn) +
428					      strlen(kdcrights_realmcontainer[i][1]) + 1);
429		if (realmacls[0] == NULL) {
430		    st = ENOMEM;
431		    goto cleanup;
432		}
433		sprintf(realmacls[0], "%s%s%s", kdcrights_realmcontainer[i][0], serviceobjdn,
434			kdcrights_realmcontainer[i][1]);
435		realmclass.mod_values = realmacls;
436
437		realmarr[0] = &realmclass;
438
439		st = ldap_modify_ext_s(ld,
440				       realmdn,
441				       realmarr,
442				       NULL,
443				       NULL);
444		if (st != LDAP_SUCCESS && st != LDAP_TYPE_OR_VALUE_EXISTS && st != LDAP_OTHER) {
445		    free(realmacls[0]);
446		    st = set_ldap_error (context, st, OP_MOD);
447		    goto cleanup;
448		}
449		free(realmacls[0]);
450	    }
451	} else if (servicetype == LDAP_ADMIN_SERVICE) {
452	    for (i=0; strcmp(adminrights_realmcontainer[i][0], "") != 0; i++) {
453		realmacls[0] = (char *) malloc(strlen(adminrights_realmcontainer[i][0]) +
454					       strlen(serviceobjdn) +
455					       strlen(adminrights_realmcontainer[i][1]) + 1);
456		if (realmacls[0] == NULL) {
457		    st = ENOMEM;
458		    goto cleanup;
459		}
460		sprintf(realmacls[0], "%s%s%s", adminrights_realmcontainer[i][0], serviceobjdn,
461			adminrights_realmcontainer[i][1]);
462		realmclass.mod_values = realmacls;
463
464		realmarr[0] = &realmclass;
465
466		st = ldap_modify_ext_s(ld,
467				       realmdn,
468				       realmarr,
469				       NULL,
470				       NULL);
471		if (st != LDAP_SUCCESS && st != LDAP_TYPE_OR_VALUE_EXISTS && st != LDAP_OTHER) {
472		    free(realmacls[0]);
473		    st = set_ldap_error (context, st, OP_MOD);
474		    goto cleanup;
475		}
476		free(realmacls[0]);
477	    }
478	} else if (servicetype == LDAP_PASSWD_SERVICE) {
479	    for (i=0; strcmp(pwdrights_realmcontainer[i][0], "")!=0; i++) {
480		realmacls[0] = (char *) malloc(strlen(pwdrights_realmcontainer[i][0]) +
481					       strlen(serviceobjdn) +
482					       strlen(pwdrights_realmcontainer[i][1]) + 1);
483		if (realmacls[0] == NULL) {
484		    st = ENOMEM;
485		    goto cleanup;
486		}
487		sprintf(realmacls[0], "%s%s%s", pwdrights_realmcontainer[i][0], serviceobjdn,
488			pwdrights_realmcontainer[i][1]);
489		realmclass.mod_values = realmacls;
490
491		realmarr[0] = &realmclass;
492
493
494		st = ldap_modify_ext_s(ld,
495				       realmdn,
496				       realmarr,
497				       NULL,
498				       NULL);
499		if (st != LDAP_SUCCESS && st != LDAP_TYPE_OR_VALUE_EXISTS && st != LDAP_OTHER) {
500		    free(realmacls[0]);
501		    st = set_ldap_error (context, st, OP_MOD);
502		    goto cleanup;
503		}
504		free(realmacls[0]);
505	    }
506	}
507    } /* Realm rights settings ends here */
508
509
510    /* Subtree rights to be set */
511    if (mask & LDAP_SUBTREE_RIGHTS) {
512	/* Populate the acl data to be added to the subtree */
513	subtreeclass.mod_op = LDAP_MOD_ADD;
514	subtreeclass.mod_type = "ACL";
515
516	if (servicetype == LDAP_KDC_SERVICE) {
517	    for (i=0; strcmp(kdcrights_subtree[i][0], "")!=0; i++) {
518		subtreeacls[0] = (char *) malloc(strlen(kdcrights_subtree[i][0]) +
519						 strlen(serviceobjdn) +
520						 strlen(kdcrights_subtree[i][1]) + 1);
521		if (subtreeacls[0] == NULL) {
522		    st = ENOMEM;
523		    goto cleanup;
524		}
525		sprintf(subtreeacls[0], "%s%s%s", kdcrights_subtree[i][0], serviceobjdn,
526			kdcrights_subtree[i][1]);
527		subtreeclass.mod_values = subtreeacls;
528
529		subtreearr[0] = &subtreeclass;
530
531                /* set rights to a list of subtrees */
532                for(i=0; subtree[i]!=NULL && i<subtreecount;i++) {
533		    st = ldap_modify_ext_s(ld,
534                                            subtree[i],
535                                            subtreearr,
536                                            NULL,
537                                            NULL);
538		    if (st != LDAP_SUCCESS && st != LDAP_TYPE_OR_VALUE_EXISTS && st != LDAP_OTHER) {
539		        free(subtreeacls[0]);
540		        st = set_ldap_error (context, st, OP_MOD);
541		        goto cleanup;
542		    }
543                }
544		free(subtreeacls[0]);
545	    }
546	} else if (servicetype == LDAP_ADMIN_SERVICE) {
547	    for (i=0; strcmp(adminrights_subtree[i][0], "")!=0; i++) {
548		subtreeacls[0] = (char *) malloc(strlen(adminrights_subtree[i][0])
549						 + strlen(serviceobjdn)
550						 + strlen(adminrights_subtree[i][1]) + 1);
551		if (subtreeacls[0] == NULL) {
552		    st = ENOMEM;
553		    goto cleanup;
554		}
555		sprintf(subtreeacls[0], "%s%s%s", adminrights_subtree[i][0], serviceobjdn,
556			adminrights_subtree[i][1]);
557		subtreeclass.mod_values = subtreeacls;
558
559		subtreearr[0] = &subtreeclass;
560
561                /* set rights to a list of subtrees */
562                for(i=0; subtree[i]!=NULL && i<subtreecount;i++) {
563		    st = ldap_modify_ext_s(ld,
564                                            subtree[i],
565                                            subtreearr,
566                                            NULL,
567                                            NULL);
568		    if (st != LDAP_SUCCESS && st !=LDAP_TYPE_OR_VALUE_EXISTS && st != LDAP_OTHER) {
569		        free(subtreeacls[0]);
570		        st = set_ldap_error (context, st, OP_MOD);
571		        goto cleanup;
572		    }
573                }
574		free(subtreeacls[0]);
575	    }
576	} else if (servicetype == LDAP_PASSWD_SERVICE) {
577	    for (i=0; strcmp(pwdrights_subtree[i][0], "") != 0; i++) {
578		subtreeacls[0] = (char *)malloc(strlen(pwdrights_subtree[i][0])
579						+ strlen(serviceobjdn)
580						+ strlen(pwdrights_subtree[i][1]) + 1);
581		if (subtreeacls[0] == NULL) {
582		    st = ENOMEM;
583		    goto cleanup;
584		}
585		sprintf(subtreeacls[0], "%s%s%s", pwdrights_subtree[i][0], serviceobjdn,
586			pwdrights_subtree[i][1]);
587		subtreeclass.mod_values = subtreeacls;
588
589		subtreearr[0] = &subtreeclass;
590
591                /* set rights to a list of subtrees */
592                for(i=0; subtree[i]!=NULL && i<subtreecount;i++) {
593		    st = ldap_modify_ext_s(ld,
594                                            subtree[i],
595                                            subtreearr,
596                                            NULL,
597                                            NULL);
598		    if (st != LDAP_SUCCESS && st != LDAP_TYPE_OR_VALUE_EXISTS && st != LDAP_OTHER) {
599		        free(subtreeacls[0]);
600		        st = set_ldap_error (context, st, OP_MOD);
601		        goto cleanup;
602		    }
603                }
604		free(subtreeacls[0]);
605	    }
606	}
607    } /* Subtree rights settings ends here */
608    st = 0;
609
610cleanup:
611
612    if (realmdn)
613	free(realmdn);
614
615    if (subtree)
616	free(subtree);
617
618    krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
619    return st;
620}
621
622
623/*
624  This will set the rights for the Kerberos service objects.
625  The function will read the subtree attribute from the specified
626  realm name and will the appropriate rights on both the realm
627  container and the subtree. The kerberos context passed should
628  have a valid ldap handle, with appropriate rights to write acl
629  attributes.
630
631  krb5_context - IN The Kerberos context with valid ldap handle
632
633*/
634
635krb5_error_code
636krb5_ldap_delete_service_rights(context, servicetype, serviceobjdn, realmname, subtreeparam, mask)
637    krb5_context	context;
638    int             servicetype;
639    char            *serviceobjdn;
640    char            *realmname;
641    char            **subtreeparam;
642    int             mask;
643{
644
645    int                    st=0,i=0;
646    char                   *realmacls[2] = { NULL }, *subtreeacls[2] = { NULL };
647    LDAP                   *ld;
648    LDAPMod                realmclass, subtreeclass;
649    LDAPMod                *realmarr[3] = { NULL }, *subtreearr[3] = { NULL };
650    char                   *realmdn=NULL;
651    char                   **subtree=NULL;
652    kdb5_dal_handle        *dal_handle=NULL;
653    krb5_ldap_context      *ldap_context=NULL;
654    krb5_ldap_server_handle *ldap_server_handle=NULL;
655    int                     subtreecount = 0;
656
657    SETUP_CONTEXT();
658    GET_HANDLE();
659
660    if ((serviceobjdn == NULL) || (realmname == NULL) || (servicetype < 0) || (servicetype > 4)
661	|| (ldap_context->krbcontainer->DN == NULL)) {
662	st = -1;
663	goto cleanup;
664    }
665
666    subtreecount = 1;
667    while(subtreeparam[subtreecount])
668        subtreecount++;
669    subtree = (char **) malloc(sizeof(char *) * subtreecount + 1);
670    if(subtree == NULL) {
671        st = ENOMEM;
672        goto cleanup;
673    }
674
675    /* If the subtree is null, set the value to root */
676    if(subtreeparam == NULL) {
677        subtree[0] = strdup("");
678        if(subtree[0] == NULL) {
679            st = ENOMEM;
680            goto cleanup;
681        }
682    }
683    else {
684        for(i=0; subtreeparam[i]!=NULL && i<subtreecount; i++)
685        subtree[i] = strdup(subtreeparam[i]);
686        if(subtree[i] == NULL) {
687            st = ENOMEM;
688            goto cleanup;
689        }
690    }
691
692
693    /* Set the rights for the realm */
694    if (mask & LDAP_REALM_RIGHTS) {
695
696	/* Construct the realm dn from realm name */
697	realmdn = (char *) malloc(strlen("cn=") + strlen(realmname) +
698				  strlen(ldap_context->krbcontainer->DN) + 2);
699	if (realmdn == NULL) {
700	    st = ENOMEM;
701	    goto cleanup;
702	}
703	sprintf(realmdn,"cn=%s,%s", realmname, ldap_context->krbcontainer->DN);
704
705	realmclass.mod_op=LDAP_MOD_DELETE;
706	realmclass.mod_type="ACL";
707
708	if (servicetype == LDAP_KDC_SERVICE) {
709	    for (i=0; strcmp(kdcrights_realmcontainer[i][0], "") != 0; i++) {
710		realmacls[0] = (char *) malloc(strlen(kdcrights_realmcontainer[i][0])
711					       + strlen(serviceobjdn) +
712					       strlen(kdcrights_realmcontainer[i][1]) + 1);
713		if (realmacls[0] == NULL) {
714		    st = ENOMEM;
715		    goto cleanup;
716		}
717		sprintf(realmacls[0], "%s%s%s", kdcrights_realmcontainer[i][0], serviceobjdn,
718			kdcrights_realmcontainer[i][1]);
719		realmclass.mod_values= realmacls;
720
721		realmarr[0]=&realmclass;
722
723		st = ldap_modify_ext_s(ld,
724				       realmdn,
725				       realmarr,
726				       NULL,
727				       NULL);
728		if (st != LDAP_SUCCESS && st != LDAP_NO_SUCH_ATTRIBUTE) {
729		    free(realmacls[0]);
730		    st = set_ldap_error (context, st, OP_MOD);
731		    goto cleanup;
732		}
733		free(realmacls[0]);
734	    }
735	} else if (servicetype == LDAP_ADMIN_SERVICE) {
736	    for (i=0; strcmp(adminrights_realmcontainer[i][0], "") != 0; i++) {
737		realmacls[0] = (char *) malloc(strlen(adminrights_realmcontainer[i][0]) +
738					       strlen(serviceobjdn) +
739					       strlen(adminrights_realmcontainer[i][1]) + 1);
740		if (realmacls[0] == NULL) {
741		    st = ENOMEM;
742		    goto cleanup;
743		}
744		sprintf(realmacls[0], "%s%s%s", adminrights_realmcontainer[i][0], serviceobjdn,
745			adminrights_realmcontainer[i][1]);
746		realmclass.mod_values= realmacls;
747
748		realmarr[0]=&realmclass;
749
750		st = ldap_modify_ext_s(ld,
751				       realmdn,
752				       realmarr,
753				       NULL,
754				       NULL);
755		if (st != LDAP_SUCCESS && st != LDAP_NO_SUCH_ATTRIBUTE) {
756		    free(realmacls[0]);
757		    st = set_ldap_error (context, st, OP_MOD);
758		    goto cleanup;
759		}
760		free(realmacls[0]);
761	    }
762	} else if (servicetype == LDAP_PASSWD_SERVICE) {
763	    for (i=0; strcmp(pwdrights_realmcontainer[i][0], "") != 0; i++) {
764		realmacls[0]=(char *)malloc(strlen(pwdrights_realmcontainer[i][0])
765					    + strlen(serviceobjdn)
766					    + strlen(pwdrights_realmcontainer[i][1]) + 1);
767		if (realmacls[0] == NULL) {
768		    st = ENOMEM;
769		    goto cleanup;
770		}
771		sprintf(realmacls[0], "%s%s%s", pwdrights_realmcontainer[i][0], serviceobjdn,
772			pwdrights_realmcontainer[i][1]);
773		realmclass.mod_values= realmacls;
774
775		realmarr[0]=&realmclass;
776
777		st = ldap_modify_ext_s(ld,
778				       realmdn,
779				       realmarr,
780				       NULL,
781				       NULL);
782		if (st != LDAP_SUCCESS && st != LDAP_NO_SUCH_ATTRIBUTE) {
783		    free(realmacls[0]);
784		    st = set_ldap_error (context, st, OP_MOD);
785		    goto cleanup;
786		}
787		free(realmacls[0]);
788	    }
789	}
790
791    } /* Realm rights setting ends here */
792
793
794    /* Set the rights for the subtree */
795    if (mask & LDAP_SUBTREE_RIGHTS) {
796
797	/* Populate the acl data to be added to the subtree */
798	subtreeclass.mod_op=LDAP_MOD_DELETE;
799	subtreeclass.mod_type="ACL";
800
801	if (servicetype == LDAP_KDC_SERVICE) {
802	    for (i=0; strcmp(kdcrights_subtree[i][0], "")!=0; i++) {
803		subtreeacls[0] = (char *) malloc(strlen(kdcrights_subtree[i][0])
804						 + strlen(serviceobjdn)
805						 + strlen(kdcrights_subtree[i][1]) + 1);
806		if (subtreeacls[0] == NULL) {
807		    st = ENOMEM;
808		    goto cleanup;
809		}
810		sprintf(subtreeacls[0], "%s%s%s", kdcrights_subtree[i][0], serviceobjdn,
811			kdcrights_subtree[i][1]);
812		subtreeclass.mod_values= subtreeacls;
813
814		subtreearr[0]=&subtreeclass;
815
816                for(i=0; subtree[i]!=NULL && i<subtreecount; i++) {
817		    st = ldap_modify_ext_s(ld,
818                                            subtree[i],
819                                            subtreearr,
820                                            NULL,
821                                            NULL);
822		    if (st != LDAP_SUCCESS && st != LDAP_NO_SUCH_ATTRIBUTE) {
823		        free(subtreeacls[0]);
824		        st = set_ldap_error (context, st, OP_MOD);
825		        goto cleanup;
826		    }
827                }
828		free(subtreeacls[0]);
829	    }
830	} else if (servicetype == LDAP_ADMIN_SERVICE) {
831	    for (i=0; strcmp(adminrights_subtree[i][0], "") != 0; i++) {
832		subtreeacls[0] = (char *) malloc(strlen(adminrights_subtree[i][0])
833						 + strlen(serviceobjdn)
834						 + strlen(adminrights_subtree[i][1]) + 1);
835		if (subtreeacls[0] == NULL) {
836		    st = ENOMEM;
837		    goto cleanup;
838		}
839		sprintf(subtreeacls[0], "%s%s%s", adminrights_subtree[i][0], serviceobjdn,
840			adminrights_subtree[i][1]);
841		subtreeclass.mod_values= subtreeacls;
842
843		subtreearr[0]=&subtreeclass;
844
845                for(i=0; subtree[i]!=NULL && i<subtreecount; i++) {
846		    st = ldap_modify_ext_s(ld,
847                                            subtree[i],
848                                            subtreearr,
849                                            NULL,
850                                            NULL);
851		    if (st != LDAP_SUCCESS && st != LDAP_NO_SUCH_ATTRIBUTE) {
852		        free(subtreeacls[0]);
853		        st = set_ldap_error (context, st, OP_MOD);
854		        goto cleanup;
855		    }
856                }
857		free(subtreeacls[0]);
858	    }
859	} else if (servicetype == LDAP_PASSWD_SERVICE) {
860	    for (i=0; strcmp(pwdrights_subtree[i][0], "") != 0; i++) {
861		subtreeacls[0] = (char *) malloc(strlen(pwdrights_subtree[i][0])
862						 + strlen(serviceobjdn)
863						 + strlen(pwdrights_subtree[i][1]) + 1);
864		if (subtreeacls[0] == NULL) {
865		    st = ENOMEM;
866		    goto cleanup;
867		}
868		sprintf(subtreeacls[0], "%s%s%s", pwdrights_subtree[i][0], serviceobjdn,
869			pwdrights_subtree[i][1]);
870		subtreeclass.mod_values= subtreeacls;
871
872		subtreearr[0]=&subtreeclass;
873
874                for(i=0; subtree[i]!=NULL && i<subtreecount; i++) {
875		    st = ldap_modify_ext_s(ld,
876                                            subtree[i],
877                                            subtreearr,
878                                            NULL,
879                                            NULL);
880		    if (st != LDAP_SUCCESS && st != LDAP_NO_SUCH_ATTRIBUTE) {
881		        free(subtreeacls[0]);
882		        st = set_ldap_error (context, st, OP_MOD);
883		        goto cleanup;
884		    }
885                }
886		free(subtreeacls[0]);
887	    }
888	}
889    } /* Subtree rights setting ends here */
890
891    st = 0;
892
893cleanup:
894
895    if (realmdn)
896	free(realmdn);
897
898    if (subtree)
899	free(subtree);
900
901    krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
902    return st;
903}
904
905#endif
906