1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* plugins/kdb/ldap/ldap_util/kdb5_ldap_policy.c */
3 /* Copyright (c) 2004-2005, Novell, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  *   * Redistributions of source code must retain the above copyright notice,
10  *       this list of conditions and the following disclaimer.
11  *   * Redistributions in binary form must reproduce the above copyright
12  *       notice, this list of conditions and the following disclaimer in the
13  *       documentation and/or other materials provided with the distribution.
14  *   * The copyright holder's name is not used to endorse or promote products
15  *       derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 /*
31  * Create / Delete / Modify / View / List policy objects.
32  */
33 
34 #include <k5-int.h>
35 #include <kadm5/admin.h>
36 #include "kdb5_ldap_util.h"
37 #include "kdb5_ldap_list.h"
38 #include "ldap_tkt_policy.h"
39 extern time_t get_date(char *); /* kadmin/cli/getdate.o */
40 
41 static void print_policy_params(krb5_ldap_policy_params *policyparams, int mask);
42 static char *strdur(time_t duration);
43 
44 extern char *yes;
45 extern kadm5_config_params global_params;
46 
47 static krb5_error_code
init_ldap_realm(int argc,char * argv[])48 init_ldap_realm(int argc, char *argv[])
49 {
50     /* This operation is being performed in the context of a realm. So,
51      * initialize the realm */
52     int mask = 0;
53     krb5_error_code retval = 0;
54     kdb5_dal_handle *dal_handle = NULL;
55     krb5_ldap_context *ldap_context=NULL;
56 
57     dal_handle = util_context->dal_handle;
58     ldap_context = (krb5_ldap_context *) dal_handle->db_context;
59     if (!ldap_context) {
60         retval = EINVAL;
61         goto cleanup;
62     }
63 
64     if (ldap_context->container_dn == NULL) {
65         retval = krb5_ldap_read_krbcontainer_dn(util_context,
66                                                 &ldap_context->container_dn);
67         if (retval != 0) {
68             com_err(progname, retval,
69                     _("while reading kerberos container information"));
70             goto cleanup;
71         }
72     }
73 
74     if (ldap_context->lrparams == NULL) {
75         retval = krb5_ldap_read_realm_params(util_context,
76                                              global_params.realm,
77                                              &(ldap_context->lrparams),
78                                              &mask);
79 
80         if (retval != 0) {
81             goto cleanup;
82         }
83     }
84 cleanup:
85     return retval;
86 }
87 
88 /*
89  * This function will create a ticket policy object with the
90  * specified attributes.
91  */
92 void
kdb5_ldap_create_policy(int argc,char * argv[])93 kdb5_ldap_create_policy(int argc, char *argv[])
94 {
95     char *me = progname;
96     krb5_error_code retval = 0;
97     krb5_ldap_policy_params *policyparams = NULL;
98     krb5_boolean print_usage = FALSE;
99     krb5_boolean no_msg = FALSE;
100     int mask = 0;
101     time_t date = 0;
102     time_t now = 0;
103     int i = 0;
104 
105     /* Check for number of arguments */
106     if ((argc < 2) || (argc > 16)) {
107         goto err_usage;
108     }
109 
110     /* Allocate memory for policy parameters structure */
111     policyparams = (krb5_ldap_policy_params*) calloc(1, sizeof(krb5_ldap_policy_params));
112     if (policyparams == NULL) {
113         retval = ENOMEM;
114         goto cleanup;
115     }
116 
117     /* Get current time */
118     time (&now);
119 
120     /* Parse all arguments */
121     for (i = 1; i < argc; i++) {
122         if (!strcmp(argv[i], "-maxtktlife")) {
123             if (++i > argc - 1)
124                 goto err_usage;
125 
126             date = get_date(argv[i]);
127             if (date == (time_t)(-1)) {
128                 retval = EINVAL;
129                 com_err(me, retval, _("while providing time specification"));
130                 goto err_nomsg;
131             }
132 
133             policyparams->maxtktlife = date - now;
134 
135             mask |= LDAP_POLICY_MAXTKTLIFE;
136         } else if (!strcmp(argv[i], "-maxrenewlife")) {
137             if (++i > argc - 1)
138                 goto err_usage;
139 
140             date = get_date(argv[i]);
141             if (date == (time_t)(-1)) {
142                 retval = EINVAL;
143                 com_err(me, retval, _("while providing time specification"));
144                 goto err_nomsg;
145             }
146 
147             policyparams->maxrenewlife = date - now;
148 
149             mask |= LDAP_POLICY_MAXRENEWLIFE;
150         } else if (!strcmp((argv[i] + 1), "allow_postdated")) {
151             if (*(argv[i]) == '+')
152                 policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_POSTDATED);
153             else if (*(argv[i]) == '-')
154                 policyparams->tktflags |= KRB5_KDB_DISALLOW_POSTDATED;
155             else
156                 goto err_usage;
157 
158             mask |= LDAP_POLICY_TKTFLAGS;
159         } else if (!strcmp((argv[i] + 1), "allow_forwardable")) {
160             if (*(argv[i]) == '+')
161                 policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_FORWARDABLE);
162             else if (*(argv[i]) == '-')
163                 policyparams->tktflags |= KRB5_KDB_DISALLOW_FORWARDABLE;
164             else
165                 goto err_usage;
166 
167             mask |= LDAP_POLICY_TKTFLAGS;
168         } else if (!strcmp((argv[i] + 1), "allow_renewable")) {
169             if (*(argv[i]) == '+')
170                 policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_RENEWABLE);
171             else if (*(argv[i]) == '-')
172                 policyparams->tktflags |= KRB5_KDB_DISALLOW_RENEWABLE;
173             else
174                 goto err_usage;
175 
176             mask |= LDAP_POLICY_TKTFLAGS;
177         } else if (!strcmp((argv[i] + 1), "allow_proxiable")) {
178             if (*(argv[i]) == '+')
179                 policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_PROXIABLE);
180             else if (*(argv[i]) == '-')
181                 policyparams->tktflags |= KRB5_KDB_DISALLOW_PROXIABLE;
182             else
183                 goto err_usage;
184 
185             mask |= LDAP_POLICY_TKTFLAGS;
186         } else if (!strcmp((argv[i] + 1), "allow_dup_skey")) {
187             if (*(argv[i]) == '+')
188                 policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_DUP_SKEY);
189             else if (*(argv[i]) == '-')
190                 policyparams->tktflags |= KRB5_KDB_DISALLOW_DUP_SKEY;
191             else
192                 goto err_usage;
193 
194             mask |= LDAP_POLICY_TKTFLAGS;
195         } else if (!strcmp((argv[i] + 1), "requires_preauth")) {
196             if (*(argv[i]) == '+')
197                 policyparams->tktflags |= KRB5_KDB_REQUIRES_PRE_AUTH;
198             else if (*(argv[i]) == '-')
199                 policyparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_PRE_AUTH);
200             else
201                 goto err_usage;
202 
203             mask |= LDAP_POLICY_TKTFLAGS;
204         } else if (!strcmp((argv[i] + 1), "requires_hwauth")) {
205             if (*(argv[i]) == '+')
206                 policyparams->tktflags |= KRB5_KDB_REQUIRES_HW_AUTH;
207             else if (*(argv[i]) == '-')
208                 policyparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_HW_AUTH);
209             else
210                 goto err_usage;
211 
212             mask |= LDAP_POLICY_TKTFLAGS;
213         } else if (!strcmp((argv[i] + 1), "allow_svr")) {
214             if (*(argv[i]) == '+')
215                 policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_SVR);
216             else if (*(argv[i]) == '-')
217                 policyparams->tktflags |= KRB5_KDB_DISALLOW_SVR;
218             else
219                 goto err_usage;
220 
221             mask |= LDAP_POLICY_TKTFLAGS;
222         } else if (!strcmp((argv[i] + 1), "allow_tgs_req")) {
223             if (*(argv[i]) == '+')
224                 policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_TGT_BASED);
225             else if (*(argv[i]) == '-')
226                 policyparams->tktflags |= KRB5_KDB_DISALLOW_TGT_BASED;
227             else
228                 goto err_usage;
229 
230             mask |= LDAP_POLICY_TKTFLAGS;
231         } else if (!strcmp((argv[i] + 1), "allow_tix")) {
232             if (*(argv[i]) == '+')
233                 policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_ALL_TIX);
234             else if (*(argv[i]) == '-')
235                 policyparams->tktflags |= KRB5_KDB_DISALLOW_ALL_TIX;
236             else
237                 goto err_usage;
238 
239             mask |= LDAP_POLICY_TKTFLAGS;
240         } else if (!strcmp((argv[i] + 1), "needchange")) {
241             if (*(argv[i]) == '+')
242                 policyparams->tktflags |= KRB5_KDB_REQUIRES_PWCHANGE;
243             else if (*(argv[i]) == '-')
244                 policyparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_PWCHANGE);
245             else
246                 goto err_usage;
247 
248             mask |= LDAP_POLICY_TKTFLAGS;
249         } else if (!strcmp((argv[i] + 1), "password_changing_service")) {
250             if (*(argv[i]) == '+')
251                 policyparams->tktflags |= KRB5_KDB_PWCHANGE_SERVICE;
252             else if (*(argv[i]) == '-')
253                 policyparams->tktflags &= (int)(~KRB5_KDB_PWCHANGE_SERVICE);
254             else
255                 goto err_usage;
256 
257             mask |= LDAP_POLICY_TKTFLAGS;
258         } else { /* Any other argument must be policy DN */
259             /* First check if policy DN is already provided --
260                if so, there's a usage error */
261             if (policyparams->policy != NULL)
262                 goto err_usage;
263 
264             /* If not present already, fill up policy DN */
265             policyparams->policy = strdup(argv[i]);
266             if (policyparams->policy == NULL) {
267                 retval = ENOMEM;
268                 com_err(me, retval, _("while creating policy object"));
269                 goto err_nomsg;
270             }
271         }
272     }
273 
274     /* policy DN is a mandatory argument. If not provided, print usage */
275     if (policyparams->policy == NULL)
276         goto err_usage;
277 
278     if ((retval = init_ldap_realm (argc, argv))) {
279         com_err(me, retval, _("while reading realm information"));
280         goto err_nomsg;
281     }
282 
283     /* Create object with all attributes provided */
284     if ((retval = krb5_ldap_create_policy(util_context, policyparams, mask)) != 0)
285         goto cleanup;
286 
287     goto cleanup;
288 
289 err_usage:
290     print_usage = TRUE;
291 
292 err_nomsg:
293     no_msg = TRUE;
294 
295 cleanup:
296     /* Clean-up structure */
297     krb5_ldap_free_policy (util_context, policyparams);
298 
299     if (print_usage)
300         db_usage(CREATE_POLICY);
301 
302     if (retval) {
303         if (!no_msg)
304             com_err(me, retval, _("while creating policy object"));
305 
306         exit_status++;
307     }
308 
309     return;
310 }
311 
312 
313 /*
314  * This function will destroy the specified ticket policy
315  * object interactively, unless forced through an option.
316  */
317 void
kdb5_ldap_destroy_policy(int argc,char * argv[])318 kdb5_ldap_destroy_policy(int argc, char *argv[])
319 {
320     char *me = progname;
321     krb5_error_code retval = 0;
322     krb5_ldap_policy_params *policyparams = NULL;
323     krb5_boolean print_usage = FALSE;
324     krb5_boolean no_msg = FALSE;
325     char *policy = NULL;
326     int mask = 0;
327     int force = 0;
328     char buf[5] = {0};
329     int i = 0;
330 
331     if ((argc < 2) || (argc > 3)) {
332         goto err_usage;
333     }
334 
335     for (i = 1; i < argc; i++) {
336         if (strcmp(argv[i], "-force") == 0) {
337             force++;
338         } else { /* Any other argument must be policy DN */
339             /* First check if policy DN is already provided --
340                if so, there's a usage error */
341             if (policy != NULL)
342                 goto err_usage;
343 
344             /* If not present already, fill up policy DN */
345             policy = strdup(argv[i]);
346             if (policy == NULL) {
347                 retval = ENOMEM;
348                 com_err(me, retval, _("while destroying policy object"));
349                 goto err_nomsg;
350             }
351         }
352     }
353 
354     if (policy == NULL)
355         goto err_usage;
356 
357     if (!force) {
358         printf(_("This will delete the policy object '%s', are you sure?\n"),
359                policy);
360         printf(_("(type 'yes' to confirm)? "));
361 
362         if (fgets(buf, sizeof(buf), stdin) == NULL) {
363             retval = EINVAL;
364             goto cleanup;
365         }
366 
367         if (strcmp(buf, yes)) {
368             exit_status++;
369             goto cleanup;
370         }
371     }
372 
373     if ((retval = init_ldap_realm (argc, argv)))
374         goto err_nomsg;
375 
376     if ((retval = krb5_ldap_read_policy(util_context, policy, &policyparams, &mask)))
377         goto cleanup;
378 
379 
380     if ((retval = krb5_ldap_delete_policy(util_context, policy)))
381         goto cleanup;
382 
383     printf("** policy object '%s' deleted.\n", policy);
384     goto cleanup;
385 
386 
387 err_usage:
388     print_usage = TRUE;
389 
390 err_nomsg:
391     no_msg = TRUE;
392 
393 cleanup:
394     /* Clean-up structure */
395     krb5_ldap_free_policy (util_context, policyparams);
396 
397     if (policy) {
398         free (policy);
399     }
400 
401     if (print_usage) {
402         db_usage(DESTROY_POLICY);
403     }
404 
405     if (retval) {
406         if (!no_msg)
407             com_err(me, retval, _("while destroying policy object"));
408 
409         exit_status++;
410     }
411 
412     return;
413 }
414 
415 
416 /*
417  * This function will modify the attributes of a given ticket
418  * policy object.
419  */
420 void
kdb5_ldap_modify_policy(int argc,char * argv[])421 kdb5_ldap_modify_policy(int argc, char *argv[])
422 {
423     char *me = progname;
424     krb5_error_code retval = 0;
425     krb5_ldap_policy_params *policyparams = NULL;
426     krb5_boolean print_usage = FALSE;
427     krb5_boolean no_msg = FALSE;
428     char *policy = NULL;
429     int in_mask = 0, out_mask = 0;
430     time_t date = 0;
431     time_t now = 0;
432     int i = 0;
433 
434     /* Check for number of arguments -- minimum is 3
435        since atleast one parameter should be given in
436        addition to 'modify_policy' and policy DN */
437     if ((argc < 3) || (argc > 16)) {
438         goto err_usage;
439     }
440 
441     /* Parse all arguments, only to pick up policy DN (Pass 1) */
442     for (i = 1; i < argc; i++) {
443         /* Skip arguments next to 'maxtktlife'
444            and 'maxrenewlife' arguments */
445         if (!strcmp(argv[i], "-maxtktlife")) {
446             ++i;
447         } else if (!strcmp(argv[i], "-maxrenewlife")) {
448             ++i;
449         }
450         /* Do nothing for ticket flag arguments */
451         else if (!strcmp((argv[i] + 1), "allow_postdated") ||
452                  !strcmp((argv[i] + 1), "allow_forwardable") ||
453                  !strcmp((argv[i] + 1), "allow_renewable") ||
454                  !strcmp((argv[i] + 1), "allow_proxiable") ||
455                  !strcmp((argv[i] + 1), "allow_dup_skey") ||
456                  !strcmp((argv[i] + 1), "requires_preauth") ||
457                  !strcmp((argv[i] + 1), "requires_hwauth") ||
458                  !strcmp((argv[i] + 1), "allow_svr") ||
459                  !strcmp((argv[i] + 1), "allow_tgs_req") ||
460                  !strcmp((argv[i] + 1), "allow_tix") ||
461                  !strcmp((argv[i] + 1), "needchange") ||
462                  !strcmp((argv[i] + 1), "password_changing_service")) {
463         } else { /* Any other argument must be policy DN */
464             /* First check if policy DN is already provided --
465                if so, there's a usage error */
466             if (policy != NULL)
467                 goto err_usage;
468 
469             /* If not present already, fill up policy DN */
470             policy = strdup(argv[i]);
471             if (policy == NULL) {
472                 retval = ENOMEM;
473                 com_err(me, retval, _("while modifying policy object"));
474                 goto err_nomsg;
475             }
476         }
477     }
478 
479     if (policy == NULL)
480         goto err_usage;
481 
482     if ((retval = init_ldap_realm (argc, argv)))
483         goto cleanup;
484 
485     retval = krb5_ldap_read_policy(util_context, policy, &policyparams, &in_mask);
486     if (retval) {
487         com_err(me, retval, _("while reading information of policy '%s'"),
488                 policy);
489         goto err_nomsg;
490     }
491 
492     /* Get current time */
493     time (&now);
494 
495     /* Parse all arguments, but skip policy DN (Pass 2) */
496     for (i = 1; i < argc; i++) {
497         if (!strcmp(argv[i], "-maxtktlife")) {
498             if (++i > argc - 1)
499                 goto err_usage;
500 
501             date = get_date(argv[i]);
502             if (date == (time_t)(-1)) {
503                 retval = EINVAL;
504                 com_err(me, retval, _("while providing time specification"));
505                 goto err_nomsg;
506             }
507 
508             policyparams->maxtktlife = date - now;
509 
510             out_mask |= LDAP_POLICY_MAXTKTLIFE;
511         } else if (!strcmp(argv[i], "-maxrenewlife")) {
512             if (++i > argc - 1)
513                 goto err_usage;
514 
515             date = get_date(argv[i]);
516             if (date == (time_t)(-1)) {
517                 retval = EINVAL;
518                 com_err(me, retval, _("while providing time specification"));
519                 goto err_nomsg;
520             }
521 
522             policyparams->maxrenewlife = date - now;
523 
524             out_mask |= LDAP_POLICY_MAXRENEWLIFE;
525         } else if (!strcmp((argv[i] + 1), "allow_postdated")) {
526             if (*(argv[i]) == '+')
527                 policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_POSTDATED);
528             else if (*(argv[i]) == '-')
529                 policyparams->tktflags |= KRB5_KDB_DISALLOW_POSTDATED;
530             else
531                 goto err_usage;
532 
533             out_mask |= LDAP_POLICY_TKTFLAGS;
534         } else if (!strcmp((argv[i] + 1), "allow_forwardable")) {
535             if (*(argv[i]) == '+')
536                 policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_FORWARDABLE);
537             else if (*(argv[i]) == '-')
538                 policyparams->tktflags |= KRB5_KDB_DISALLOW_FORWARDABLE;
539             else
540                 goto err_usage;
541 
542             out_mask |= LDAP_POLICY_TKTFLAGS;
543         } else if (!strcmp((argv[i] + 1), "allow_renewable")) {
544             if (*(argv[i]) == '+')
545                 policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_RENEWABLE);
546             else if (*(argv[i]) == '-')
547                 policyparams->tktflags |= KRB5_KDB_DISALLOW_RENEWABLE;
548             else
549                 goto err_usage;
550 
551             out_mask |= LDAP_POLICY_TKTFLAGS;
552         } else if (!strcmp((argv[i] + 1), "allow_proxiable")) {
553             if (*(argv[i]) == '+')
554                 policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_PROXIABLE);
555             else if (*(argv[i]) == '-')
556                 policyparams->tktflags |= KRB5_KDB_DISALLOW_PROXIABLE;
557             else
558                 goto err_usage;
559 
560             out_mask |= LDAP_POLICY_TKTFLAGS;
561         } else if (!strcmp((argv[i] + 1), "allow_dup_skey")) {
562             if (*(argv[i]) == '+')
563                 policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_DUP_SKEY);
564             else if (*(argv[i]) == '-')
565                 policyparams->tktflags |= KRB5_KDB_DISALLOW_DUP_SKEY;
566             else
567                 goto err_usage;
568 
569             out_mask |= LDAP_POLICY_TKTFLAGS;
570         } else if (!strcmp((argv[i] + 1), "requires_preauth")) {
571             if (*(argv[i]) == '+')
572                 policyparams->tktflags |= KRB5_KDB_REQUIRES_PRE_AUTH;
573             else if (*(argv[i]) == '-')
574                 policyparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_PRE_AUTH);
575             else
576                 goto err_usage;
577 
578             out_mask |= LDAP_POLICY_TKTFLAGS;
579         } else if (!strcmp((argv[i] + 1), "requires_hwauth")) {
580             if (*(argv[i]) == '+')
581                 policyparams->tktflags |= KRB5_KDB_REQUIRES_HW_AUTH;
582             else if (*(argv[i]) == '-')
583                 policyparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_HW_AUTH);
584             else
585                 goto err_usage;
586 
587             out_mask |= LDAP_POLICY_TKTFLAGS;
588         } else if (!strcmp((argv[i] + 1), "allow_svr")) {
589             if (*(argv[i]) == '+')
590                 policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_SVR);
591             else if (*(argv[i]) == '-')
592                 policyparams->tktflags |= KRB5_KDB_DISALLOW_SVR;
593             else
594                 goto err_usage;
595 
596             out_mask |= LDAP_POLICY_TKTFLAGS;
597         } else if (!strcmp((argv[i] + 1), "allow_tgs_req")) {
598             if (*(argv[i]) == '+')
599                 policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_TGT_BASED);
600             else if (*(argv[i]) == '-')
601                 policyparams->tktflags |= KRB5_KDB_DISALLOW_TGT_BASED;
602             else
603                 goto err_usage;
604 
605             out_mask |= LDAP_POLICY_TKTFLAGS;
606         } else if (!strcmp((argv[i] + 1), "allow_tix")) {
607             if (*(argv[i]) == '+')
608                 policyparams->tktflags &= (int)(~KRB5_KDB_DISALLOW_ALL_TIX);
609             else if (*(argv[i]) == '-')
610                 policyparams->tktflags |= KRB5_KDB_DISALLOW_ALL_TIX;
611             else
612                 goto err_usage;
613 
614             out_mask |= LDAP_POLICY_TKTFLAGS;
615         } else if (!strcmp((argv[i] + 1), "needchange")) {
616             if (*(argv[i]) == '+')
617                 policyparams->tktflags |= KRB5_KDB_REQUIRES_PWCHANGE;
618             else if (*(argv[i]) == '-')
619                 policyparams->tktflags &= (int)(~KRB5_KDB_REQUIRES_PWCHANGE);
620             else
621                 goto err_usage;
622 
623             out_mask |= LDAP_POLICY_TKTFLAGS;
624         } else if (!strcmp((argv[i] + 1), "password_changing_service")) {
625             if (*(argv[i]) == '+')
626                 policyparams->tktflags |= KRB5_KDB_PWCHANGE_SERVICE;
627             else if (*(argv[i]) == '-')
628                 policyparams->tktflags &= (int)(~KRB5_KDB_PWCHANGE_SERVICE);
629             else
630                 goto err_usage;
631 
632             out_mask |= LDAP_POLICY_TKTFLAGS;
633         } else {
634             /* Any other argument must be policy DN
635                -- skip it */
636         }
637     }
638 
639     /* Modify attributes of object */
640     if ((retval = krb5_ldap_modify_policy(util_context, policyparams, out_mask)))
641         goto cleanup;
642 
643     goto cleanup;
644 
645 err_usage:
646     print_usage = TRUE;
647 
648 err_nomsg:
649     no_msg = TRUE;
650 
651 cleanup:
652     /* Clean-up structure */
653     krb5_ldap_free_policy (util_context, policyparams);
654 
655     if (policy)
656         free (policy);
657 
658     if (print_usage)
659         db_usage(MODIFY_POLICY);
660 
661     if (retval) {
662         if (!no_msg)
663             com_err(me, retval, _("while modifying policy object"));
664 
665         exit_status++;
666     }
667 
668     return;
669 }
670 
671 
672 /*
673  * This function will display information about the given policy object,
674  * fetching the information from the LDAP Server.
675  */
676 void
kdb5_ldap_view_policy(int argc,char * argv[])677 kdb5_ldap_view_policy(int argc, char *argv[])
678 {
679     char *me = progname;
680     krb5_ldap_policy_params *policyparams = NULL;
681     krb5_error_code retval = 0;
682     krb5_boolean print_usage = FALSE;
683     char *policy = NULL;
684     int mask = 0;
685 
686     if (argc != 2) {
687         goto err_usage;
688     }
689 
690     policy = strdup(argv[1]);
691     if (policy == NULL) {
692         com_err(me, ENOMEM, _("while viewing policy"));
693         exit_status++;
694         goto cleanup;
695     }
696 
697     if ((retval = init_ldap_realm (argc, argv)))
698         goto cleanup;
699 
700     if ((retval = krb5_ldap_read_policy(util_context, policy, &policyparams, &mask))) {
701         com_err(me, retval, _("while viewing policy '%s'"), policy);
702         exit_status++;
703         goto cleanup;
704     }
705 
706     print_policy_params (policyparams, mask);
707 
708     goto cleanup;
709 
710 err_usage:
711     print_usage = TRUE;
712 
713 cleanup:
714     krb5_ldap_free_policy (util_context, policyparams);
715 
716     if (policy)
717         free (policy);
718 
719     if (print_usage) {
720         db_usage(VIEW_POLICY);
721     }
722 
723     return;
724 }
725 
726 
727 /*
728  * This function will print the policy object information to the
729  * standard output.
730  */
731 static void
print_policy_params(krb5_ldap_policy_params * policyparams,int mask)732 print_policy_params(krb5_ldap_policy_params *policyparams, int mask)
733 {
734     /* Print the policy DN */
735     printf("%25s: %s\n", "Ticket policy", policyparams->policy);
736 
737     /* Print max. ticket life and max. renewable life, if present */
738     if (mask & LDAP_POLICY_MAXTKTLIFE)
739         printf("%25s: %s\n", "Maximum ticket life", strdur(policyparams->maxtktlife));
740     if (mask & LDAP_POLICY_MAXRENEWLIFE)
741         printf("%25s: %s\n", "Maximum renewable life", strdur(policyparams->maxrenewlife));
742 
743     /* Service flags are printed */
744     printf("%25s: ", "Ticket flags");
745     if (mask & LDAP_POLICY_TKTFLAGS) {
746         int ticketflags = policyparams->tktflags;
747 
748         if (ticketflags & KRB5_KDB_DISALLOW_POSTDATED)
749             printf("%s ","DISALLOW_POSTDATED");
750 
751         if (ticketflags & KRB5_KDB_DISALLOW_FORWARDABLE)
752             printf("%s ","DISALLOW_FORWARDABLE");
753 
754         if (ticketflags & KRB5_KDB_DISALLOW_RENEWABLE)
755             printf("%s ","DISALLOW_RENEWABLE");
756 
757         if (ticketflags & KRB5_KDB_DISALLOW_PROXIABLE)
758             printf("%s ","DISALLOW_PROXIABLE");
759 
760         if (ticketflags & KRB5_KDB_DISALLOW_DUP_SKEY)
761             printf("%s ","DISALLOW_DUP_SKEY");
762 
763         if (ticketflags & KRB5_KDB_REQUIRES_PRE_AUTH)
764             printf("%s ","REQUIRES_PRE_AUTH");
765 
766         if (ticketflags & KRB5_KDB_REQUIRES_HW_AUTH)
767             printf("%s ","REQUIRES_HW_AUTH");
768 
769         if (ticketflags & KRB5_KDB_DISALLOW_SVR)
770             printf("%s ","DISALLOW_SVR");
771 
772         if (ticketflags & KRB5_KDB_DISALLOW_TGT_BASED)
773             printf("%s ","DISALLOW_TGT_BASED");
774 
775         if (ticketflags & KRB5_KDB_DISALLOW_ALL_TIX)
776             printf("%s ","DISALLOW_ALL_TIX");
777 
778         if (ticketflags & KRB5_KDB_REQUIRES_PWCHANGE)
779             printf("%s ","REQUIRES_PWCHANGE");
780 
781         if (ticketflags & KRB5_KDB_PWCHANGE_SERVICE)
782             printf("%s ","PWCHANGE_SERVICE");
783     }
784     printf("\n");
785 
786     return;
787 }
788 
789 
790 /*
791  * This function will list the DNs of policy objects under a specific
792  * sub-tree (entire tree by default)
793  */
794 void
kdb5_ldap_list_policies(int argc,char * argv[])795 kdb5_ldap_list_policies(int argc, char *argv[])
796 {
797     char *me = progname;
798     krb5_error_code retval = 0;
799     krb5_boolean print_usage = FALSE;
800     char **list = NULL;
801     char **plist = NULL;
802 
803     /* Check for number of arguments */
804     if ((argc != 1) && (argc != 3)) {
805         goto err_usage;
806     }
807 
808     if ((retval = init_ldap_realm (argc, argv)))
809         goto cleanup;
810 
811     retval = krb5_ldap_list_policy(util_context, NULL, &list);
812     if ((retval != 0) || (list == NULL))
813         goto cleanup;
814 
815     for (plist = list; *plist != NULL; plist++) {
816         printf("%s\n", *plist);
817     }
818 
819     goto cleanup;
820 
821 err_usage:
822     print_usage = TRUE;
823 
824 cleanup:
825     if (list != NULL) {
826         krb5_free_list_entries (list);
827         free (list);
828     }
829 
830     if (print_usage) {
831         db_usage(LIST_POLICY);
832     }
833 
834     if (retval) {
835         com_err(me, retval, _("while listing policy objects"));
836         exit_status++;
837     }
838 
839     return;
840 }
841 
842 
843 /* Reproduced from kadmin.c, instead of linking
844    the entire kadmin.o */
845 static char *
strdur(time_t duration)846 strdur(time_t duration)
847 {
848     static char out[50];
849     int neg, days, hours, minutes, seconds;
850 
851     if (duration < 0) {
852         duration *= -1;
853         neg = 1;
854     } else
855         neg = 0;
856     days = duration / (24 * 3600);
857     duration %= 24 * 3600;
858     hours = duration / 3600;
859     duration %= 3600;
860     minutes = duration / 60;
861     duration %= 60;
862     seconds = duration;
863     snprintf(out, sizeof(out), "%s%d %s %02d:%02d:%02d", neg ? "-" : "",
864              days, days == 1 ? "day" : "days", hours, minutes, seconds);
865     return out;
866 }
867