xref: /illumos-gate/usr/src/lib/krb5/plugins/kdb/ldap/libkdb_ldap/ldap_service_rights.c (revision 54925bf60766fbb4f1f2d7c843721406a7b7a3fb)
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 
41 static 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 
77 static 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 
119 static 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 
145 static 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 
187 static 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 
234 static 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 
265 static char *security_container[][2] = {
266     {"1#subtree#","#[Entry Rights]"},
267     {"2#subtree#","#krbContainerReference"},
268     { "", "" }
269 };
270 
271 static 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 
290 krb5_error_code
291 krb5_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 
610 cleanup:
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 
635 krb5_error_code
636 krb5_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 
893 cleanup:
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