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