~ubuntu-branches/ubuntu/maverick/krb5/maverick

« back to all changes in this revision

Viewing changes to src/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c

  • Committer: Bazaar Package Importer
  • Author(s): Sam Hartman, Russ Allbery, Sam Hartman
  • Date: 2008-08-21 10:41:41 UTC
  • mfrom: (11.1.15 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080821104141-a0f9c4o4cpo8xd0o
Tags: 1.6.dfsg.4~beta1-4
[ Russ Allbery ]
* Translation updates:
  - Swedish, thanks Martin Bagge.  (Closes: #487669, #491774)
  - Italian, thanks Luca Monducci.  (Closes: #493962)

[ Sam Hartman ]
* Translation Updates:
    - Dutch, Thanks Vincent Zweije, Closes: #495733

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * lib/kdb/kdb_ldap/ldap_tkt_policy.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 "kdb_ldap.h"
 
33
#include "ldap_tkt_policy.h"
 
34
#include "ldap_err.h"
 
35
 
 
36
/* Ticket policy object management */
 
37
 
 
38
/*
 
39
 * create the Ticket policy object in Directory.
 
40
 */
 
41
krb5_error_code
 
42
krb5_ldap_create_policy(context, policy, mask)
 
43
    krb5_context                context;
 
44
    krb5_ldap_policy_params     *policy;
 
45
    int                         mask;
 
46
{
 
47
    krb5_error_code             st=0;
 
48
    LDAP                        *ld=NULL;
 
49
    char                        *strval[3]={NULL}, *policy_dn = NULL;
 
50
    LDAPMod                     **mods=NULL;
 
51
    kdb5_dal_handle             *dal_handle=NULL;
 
52
    krb5_ldap_context           *ldap_context=NULL;
 
53
    krb5_ldap_server_handle     *ldap_server_handle=NULL;
 
54
 
 
55
    /* validate the input parameters */
 
56
    if (policy == NULL || policy->policy == NULL) {
 
57
        st = EINVAL;
 
58
        krb5_set_error_message (context, st, "Ticket Policy Name missing");
 
59
        goto cleanup;
 
60
    }
 
61
 
 
62
    SETUP_CONTEXT();
 
63
    GET_HANDLE();
 
64
 
 
65
    if ((st = krb5_ldap_name_to_policydn (context, policy->policy, &policy_dn)) != 0)
 
66
        goto cleanup;
 
67
 
 
68
    memset(strval, 0, sizeof(strval));
 
69
    strval[0] = policy->policy;
 
70
    if ((st=krb5_add_str_mem_ldap_mod(&mods, "cn", LDAP_MOD_ADD, strval)) != 0)
 
71
        goto cleanup;
 
72
 
 
73
    memset(strval, 0, sizeof(strval));
 
74
    strval[0] = "krbTicketPolicy";
 
75
    strval[1] = "krbTicketPolicyaux";
 
76
    if ((st=krb5_add_str_mem_ldap_mod(&mods, "objectclass", LDAP_MOD_ADD, strval)) != 0)
 
77
        goto cleanup;
 
78
 
 
79
    if (mask & LDAP_POLICY_MAXTKTLIFE) {
 
80
        if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbmaxticketlife", LDAP_MOD_ADD,
 
81
                                          policy->maxtktlife)) != 0)
 
82
            goto cleanup;
 
83
    }
 
84
 
 
85
    if (mask & LDAP_POLICY_MAXRENEWLIFE) {
 
86
        if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbmaxrenewableage", LDAP_MOD_ADD,
 
87
                                          policy->maxrenewlife)) != 0)
 
88
            goto cleanup;
 
89
    }
 
90
 
 
91
    if (mask & LDAP_POLICY_TKTFLAGS) {
 
92
        if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbticketflags", LDAP_MOD_ADD,
 
93
                                          policy->tktflags)) != 0)
 
94
            goto cleanup;
 
95
    }
 
96
 
 
97
    /* ldap add operation */
 
98
    if ((st=ldap_add_ext_s(ld, policy_dn, mods, NULL, NULL)) != LDAP_SUCCESS) {
 
99
        st = set_ldap_error (context, st, OP_ADD);
 
100
        goto cleanup;
 
101
    }
 
102
 
 
103
cleanup:
 
104
    if (policy_dn != NULL)
 
105
        free(policy_dn);
 
106
 
 
107
    ldap_mods_free(mods, 1);
 
108
    krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
 
109
    return st;
 
110
}
 
111
 
 
112
 
 
113
/*
 
114
 * modify the Ticket policy object in Directory.
 
115
 */
 
116
 
 
117
krb5_error_code
 
118
krb5_ldap_modify_policy(context, policy, mask)
 
119
    krb5_context                context;
 
120
    krb5_ldap_policy_params     *policy;
 
121
    int                         mask;
 
122
{
 
123
    int                         objectmask=0;
 
124
    krb5_error_code             st=0;
 
125
    LDAP                        *ld=NULL;
 
126
    char                        *attrvalues[]={"krbTicketPolicy", "krbTicketPolicyAux", NULL}, *strval[2]={NULL};
 
127
    char                        *policy_dn = NULL;
 
128
    LDAPMod                     **mods=NULL;
 
129
    kdb5_dal_handle             *dal_handle=NULL;
 
130
    krb5_ldap_context           *ldap_context=NULL;
 
131
    krb5_ldap_server_handle     *ldap_server_handle=NULL;
 
132
 
 
133
    /* validate the input parameters */
 
134
    if (policy == NULL || policy->policy==NULL) {
 
135
        st = EINVAL;
 
136
        krb5_set_error_message (context, st, "Ticket Policy Name missing");
 
137
        goto cleanup;
 
138
    }
 
139
 
 
140
    SETUP_CONTEXT();
 
141
    GET_HANDLE();
 
142
 
 
143
    if ((st = krb5_ldap_name_to_policydn (context, policy->policy, &policy_dn)) != 0)
 
144
        goto cleanup;
 
145
 
 
146
    /* the policydn object should be of the krbTicketPolicy object class */
 
147
    st = checkattributevalue(ld, policy_dn, "objectClass", attrvalues, &objectmask);
 
148
    CHECK_CLASS_VALIDITY(st, objectmask, "ticket policy object: ");
 
149
 
 
150
    if ((objectmask & 0x02) == 0) { /* add krbticketpolicyaux to the object class list */
 
151
        memset(strval, 0, sizeof(strval));
 
152
        strval[0] = "krbTicketPolicyAux";
 
153
        if ((st=krb5_add_str_mem_ldap_mod(&mods, "objectclass", LDAP_MOD_ADD, strval)) != 0)
 
154
            goto cleanup;
 
155
    }
 
156
 
 
157
    if (mask & LDAP_POLICY_MAXTKTLIFE) {
 
158
        if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbmaxticketlife", LDAP_MOD_REPLACE,
 
159
                                          policy->maxtktlife)) != 0)
 
160
            goto cleanup;
 
161
    }
 
162
 
 
163
    if (mask & LDAP_POLICY_MAXRENEWLIFE) {
 
164
        if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbmaxrenewableage", LDAP_MOD_REPLACE,
 
165
                                          policy->maxrenewlife)) != 0)
 
166
            goto cleanup;
 
167
    }
 
168
 
 
169
    if (mask & LDAP_POLICY_TKTFLAGS) {
 
170
        if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbticketflags", LDAP_MOD_REPLACE,
 
171
                                          policy->tktflags)) != 0)
 
172
            goto cleanup;
 
173
    }
 
174
 
 
175
    if ((st=ldap_modify_ext_s(ld, policy_dn, mods, NULL, NULL)) != LDAP_SUCCESS) {
 
176
        st = set_ldap_error (context, st, OP_MOD);
 
177
        goto cleanup;
 
178
    }
 
179
 
 
180
cleanup:
 
181
    if (policy_dn != NULL)
 
182
        free(policy_dn);
 
183
 
 
184
    ldap_mods_free(mods, 1);
 
185
    krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
 
186
    return st;
 
187
}
 
188
 
 
189
 
 
190
/*
 
191
 * Read the policy object from the Directory and populate the krb5_ldap_policy_params
 
192
 * structure.
 
193
 */
 
194
 
 
195
krb5_error_code
 
196
krb5_ldap_read_policy(context, policyname, policy, omask)
 
197
    krb5_context                context;
 
198
    char                        *policyname;
 
199
    krb5_ldap_policy_params     **policy;
 
200
    int                         *omask;
 
201
{
 
202
    krb5_error_code             st=0, tempst=0;
 
203
    int                         objectmask=0;
 
204
    LDAP                        *ld=NULL;
 
205
    LDAPMessage                 *result=NULL,*ent=NULL;
 
206
    char                        *attributes[] = { "krbMaxTicketLife", "krbMaxRenewableAge", "krbTicketFlags", NULL};
 
207
    char                        *attrvalues[] = { "krbTicketPolicy", NULL}, *policy_dn = NULL;
 
208
    krb5_ldap_policy_params     *lpolicy=NULL;
 
209
    kdb5_dal_handle             *dal_handle=NULL;
 
210
    krb5_ldap_context           *ldap_context=NULL;
 
211
    krb5_ldap_server_handle     *ldap_server_handle=NULL;
 
212
 
 
213
    /* validate the input parameters */
 
214
    if (policyname == NULL  || policy == NULL) {
 
215
        st = EINVAL;
 
216
        krb5_set_error_message(context, st, "Ticket Policy Object information missing");
 
217
        goto cleanup;
 
218
    }
 
219
 
 
220
    SETUP_CONTEXT();
 
221
    GET_HANDLE();
 
222
 
 
223
    if ((st = krb5_ldap_name_to_policydn (context, policyname, &policy_dn)) != 0)
 
224
        goto cleanup;
 
225
 
 
226
    /* the policydn object should be of the krbTicketPolicy object class */
 
227
    st = checkattributevalue(ld, policy_dn, "objectClass", attrvalues, &objectmask);
 
228
    CHECK_CLASS_VALIDITY(st, objectmask, "ticket policy object: ");
 
229
 
 
230
    /* Initialize ticket policy structure */
 
231
    lpolicy =(krb5_ldap_policy_params *) malloc(sizeof(krb5_ldap_policy_params));
 
232
    CHECK_NULL(lpolicy);
 
233
    memset(lpolicy, 0, sizeof(krb5_ldap_policy_params));
 
234
 
 
235
    if ((lpolicy->policy = strdup (policyname)) == NULL) {
 
236
        st = ENOMEM;
 
237
        goto cleanup;
 
238
    }
 
239
 
 
240
    lpolicy->tl_data = calloc (1, sizeof(*lpolicy->tl_data));
 
241
    CHECK_NULL(lpolicy->tl_data);
 
242
    lpolicy->tl_data->tl_data_type = KDB_TL_USER_INFO;
 
243
 
 
244
    LDAP_SEARCH(policy_dn, LDAP_SCOPE_BASE, "(objectclass=krbTicketPolicy)", attributes);
 
245
 
 
246
    *omask = 0;
 
247
 
 
248
    ent=ldap_first_entry(ld, result);
 
249
    if (ent != NULL) {
 
250
        if (krb5_ldap_get_value(ld, ent, "krbmaxticketlife", (int *) &(lpolicy->maxtktlife)) == 0)
 
251
            *omask |= LDAP_POLICY_MAXTKTLIFE;
 
252
 
 
253
        if (krb5_ldap_get_value(ld, ent, "krbmaxrenewableage", (int *) &(lpolicy->maxrenewlife)) == 0)
 
254
            *omask |= LDAP_POLICY_MAXRENEWLIFE;
 
255
 
 
256
        if (krb5_ldap_get_value(ld, ent, "krbticketflags", (int *) &(lpolicy->tktflags)) == 0)
 
257
            *omask |= LDAP_POLICY_TKTFLAGS;
 
258
    }
 
259
    ldap_msgfree(result);
 
260
 
 
261
    lpolicy->mask = *omask;
 
262
    store_tl_data(lpolicy->tl_data, KDB_TL_MASK, omask);
 
263
    *policy = lpolicy;
 
264
 
 
265
cleanup:
 
266
    if (st != 0) {
 
267
        krb5_ldap_free_policy(context, lpolicy);
 
268
        *policy = NULL;
 
269
    }
 
270
    krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
 
271
    return st;
 
272
}
 
273
 
 
274
 
 
275
/*
 
276
 * Function to delete ticket policy object from the directory.  Before
 
277
 * calling this function krb5_ldap_read_policy should be called to
 
278
 * check the existence of the object.  This serves one major purpose,
 
279
 * i.e., if the object to be is anything other than the ticket policy
 
280
 * object then the krb5_ldap_read_policy returns an error and thus is
 
281
 * not accidently deleted in this function.
 
282
 *
 
283
 * NOTE: Other kerberos objects (user/realm object) might be having
 
284
 * references to the policy object to be deleted. This situation is
 
285
 * not handled here, instead is taken care of at all the places where
 
286
 * the deleted policy object is read, to ignore a return status of
 
287
 * LDAP_NO_SUCH_OBJECT and continue.
 
288
 */
 
289
 
 
290
krb5_error_code
 
291
krb5_ldap_delete_policy(context, policyname)
 
292
    krb5_context                context;
 
293
    char                        *policyname;
 
294
{
 
295
        int                         refcount = 0;
 
296
        char                        *policy_dn = NULL;
 
297
    krb5_error_code             st = 0;
 
298
    LDAP                        *ld = NULL;
 
299
    kdb5_dal_handle             *dal_handle=NULL;
 
300
    krb5_ldap_context           *ldap_context=NULL;
 
301
    krb5_ldap_server_handle     *ldap_server_handle=NULL;
 
302
 
 
303
        if (policyname == NULL) {
 
304
        st = EINVAL;
 
305
        prepend_err_str (context,"Ticket Policy Object DN missing",st,st);
 
306
        goto cleanup;
 
307
    }
 
308
 
 
309
 
 
310
    SETUP_CONTEXT();
 
311
    GET_HANDLE();
 
312
 
 
313
    if ((st = krb5_ldap_name_to_policydn (context, policyname, &policy_dn)) != 0)
 
314
        goto cleanup;
 
315
 
 
316
    /* Checking for policy count for 0 and will not permit delete if
 
317
     * it is greater than 0.  */
 
318
 
 
319
    if ((st = krb5_ldap_get_reference_count (context, policy_dn,
 
320
                    "krbTicketPolicyReference", &refcount, ld)) != 0)
 
321
        goto cleanup;
 
322
 
 
323
    if (refcount == 0) {
 
324
        if ((st=ldap_delete_ext_s(ld, policy_dn, NULL, NULL)) != 0) {
 
325
            prepend_err_str (context,ldap_err2string(st),st,st);
 
326
 
 
327
            goto cleanup;
 
328
        }
 
329
    } else {
 
330
        st = EINVAL;
 
331
        prepend_err_str (context,"Delete Failed: One or more Principals associated with the Ticket Policy",st,st);
 
332
        goto cleanup;
 
333
    }
 
334
 
 
335
cleanup:
 
336
    if (policy_dn != NULL)
 
337
        free (policy_dn);
 
338
    krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
 
339
    return st;
 
340
}
 
341
 
 
342
 
 
343
/*
 
344
 * list policy objects from Directory
 
345
 */
 
346
 
 
347
krb5_error_code
 
348
krb5_ldap_list_policy(context, containerdn, policy)
 
349
    krb5_context                context;
 
350
    char                        *containerdn;
 
351
    char                        ***policy;
 
352
{
 
353
    int                         i, j, count;
 
354
    char                        **list = NULL;
 
355
    char                        *policycontainerdn = containerdn;
 
356
    kdb5_dal_handle             *dal_handle=NULL;
 
357
    krb5_ldap_context           *ldap_context=NULL;
 
358
    krb5_error_code             st=0;
 
359
 
 
360
    SETUP_CONTEXT();
 
361
    if (policycontainerdn == NULL) {
 
362
        policycontainerdn = ldap_context->lrparams->realmdn;
 
363
    }
 
364
 
 
365
    if ((st = krb5_ldap_list(context, &list, "krbTicketPolicy", policycontainerdn)) != 0)
 
366
        goto cleanup;
 
367
 
 
368
    for (i = 0; list[i] != NULL; i++);
 
369
 
 
370
    count = i;
 
371
 
 
372
    *policy = (char **) calloc ((unsigned) count + 1, sizeof(char *));
 
373
    if (*policy == NULL) {
 
374
        st = ENOMEM;
 
375
        goto cleanup;
 
376
    }
 
377
 
 
378
    for (i = 0, j = 0; list[i] != NULL; i++, j++) {
 
379
        int ret;
 
380
        ret = krb5_ldap_policydn_to_name (context, list[i], &(*policy)[i]);
 
381
        if (ret != 0)
 
382
            j--;
 
383
    }
 
384
 
 
385
cleanup:
 
386
    return st;
 
387
}
 
388
 
 
389
/*
 
390
 * Function to free the ticket policy object structure.
 
391
 * Note: this function assumes that memory of the policy structure is dynamically allocated and hence the whole
 
392
 * structure is freed up. Care should be taken not to call this function on a static structure
 
393
 */
 
394
 
 
395
krb5_error_code
 
396
krb5_ldap_free_policy(context, policy)
 
397
    krb5_context                context;
 
398
    krb5_ldap_policy_params    *policy;
 
399
{
 
400
 
 
401
    krb5_error_code st=0;
 
402
 
 
403
    if (policy == NULL)
 
404
        return st;
 
405
 
 
406
    if (policy->policy)
 
407
        free (policy->policy);
 
408
 
 
409
    if (policy->tl_data) {
 
410
        if (policy->tl_data->tl_data_contents)
 
411
            free (policy->tl_data->tl_data_contents);
 
412
        free (policy->tl_data);
 
413
    }
 
414
    free (policy);
 
415
 
 
416
    return st;
 
417
}
 
418
 
 
419
/*
 
420
 * This function is general object listing routine.  It is currently
 
421
 * used for ticket policy object listing.
 
422
 */
 
423
 
 
424
krb5_error_code
 
425
krb5_ldap_list(context, list, objectclass, containerdn)
 
426
    krb5_context                context;
 
427
    char                        ***list;
 
428
    char                        *objectclass;
 
429
    char                        *containerdn;
 
430
{
 
431
    char                        *filter=NULL, *dn=NULL;
 
432
    krb5_error_code             st=0, tempst=0;
 
433
    int                         i=0, count=0, filterlen=0;
 
434
    LDAP                        *ld=NULL;
 
435
    LDAPMessage                 *result=NULL,*ent=NULL;
 
436
    kdb5_dal_handle             *dal_handle=NULL;
 
437
    krb5_ldap_context           *ldap_context=NULL;
 
438
    krb5_ldap_server_handle     *ldap_server_handle=NULL;
 
439
 
 
440
    SETUP_CONTEXT();
 
441
    GET_HANDLE();
 
442
 
 
443
    /* check if the containerdn exists */
 
444
    if (containerdn) {
 
445
        if ((st=checkattributevalue(ld, containerdn, NULL, NULL, NULL)) != 0) {
 
446
            prepend_err_str (context, "Error reading container object: ", st, st);
 
447
            goto cleanup;
 
448
        }
 
449
    }
 
450
 
 
451
    /* set the filter for the search operation */
 
452
    filterlen = strlen("(objectclass=") + strlen(objectclass) + 1 + 1;
 
453
    filter = malloc ((unsigned) filterlen);
 
454
    if (filter == NULL) {
 
455
        st = ENOMEM;
 
456
        goto cleanup;
 
457
    }
 
458
    snprintf(filter, (unsigned) filterlen,"(objectclass=%s)",objectclass);
 
459
 
 
460
    LDAP_SEARCH(containerdn, LDAP_SCOPE_SUBTREE, filter, NULL);
 
461
 
 
462
    count = ldap_count_entries(ld, result);
 
463
    if (count == -1) {
 
464
        ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &st);
 
465
        st = set_ldap_error(context, st, OP_SEARCH);
 
466
        goto cleanup;
 
467
    }
 
468
    *list = (char **) calloc ((unsigned) count+1, sizeof(char *));
 
469
    if (*list == NULL) {
 
470
        st = ENOMEM;
 
471
        goto cleanup;
 
472
    }
 
473
 
 
474
    for (ent=ldap_first_entry(ld, result), count=0; ent != NULL; ent=ldap_next_entry(ld, ent), ++count) {
 
475
        if ((dn=ldap_get_dn(ld, ent)) == NULL)
 
476
            continue;
 
477
        if (((*list)[count] = strdup(dn)) == NULL) {
 
478
            ldap_memfree (dn);
 
479
            st = ENOMEM;
 
480
            goto cleanup;
 
481
        }
 
482
        ldap_memfree(dn);
 
483
    }
 
484
    ldap_msgfree(result);
 
485
 
 
486
cleanup:
 
487
    if (filter)
 
488
        free (filter);
 
489
 
 
490
    /* some error, free up all the memory */
 
491
    if (st != 0) {
 
492
        if (*list) {
 
493
            for (i=0; (*list)[i]; ++i)
 
494
                free ((*list)[i]);
 
495
            free (*list);
 
496
            *list = NULL;
 
497
        }
 
498
    }
 
499
    krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
 
500
    return st;
 
501
}