2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
8 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
10 * Openvision retains the copyright to derivative works of
11 * this source code. Do *NOT* create a derivative of this
12 * source code before consulting with your legal department.
13 * Do *NOT* integrate *ANY* of this source code into another
14 * product before consulting with your legal department.
16 * For further information, read the top-level Openvision
17 * copyright which is contained in the top-level MIT Kerberos
20 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
26 * kadmin/v5server/srv_acl.c
28 * Copyright 1995 by the Massachusetts Institute of Technology.
29 * All Rights Reserved.
31 * Export of this software from the United States of America may
32 * require a specific license from the United States Government.
33 * It is the responsibility of any person or organization contemplating
34 * export to obtain such a license before exporting.
36 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
37 * distribute this software and its documentation for any purpose and
38 * without fee is hereby granted, provided that the above copyright
39 * notice appear in all copies and that both that copyright notice and
40 * this permission notice appear in supporting documentation, and that
41 * the name of M.I.T. not be used in advertising or publicity pertaining
42 * to distribution of the software without specific, written prior
43 * permission. Furthermore if you modify this software you must label
44 * your software as modified software and not distribute it in such a
45 * fashion that it might be confused with the original M.I.T. software.
46 * M.I.T. makes no representations about the suitability of
47 * this software for any purpose. It is provided "as is" without express
48 * or implied warranty.
53 * srv_acl.c - Handle Kerberos ACL related functions.
57 #include <sys/param.h>
59 #include <gssapi_krb5.h>
60 #include <kadm5/server_internal.h>
61 #include <kadm5/admin.h>
62 #include <adm_proto.h> /* SUNWresync121 XXX */
63 #include "server_acl.h"
65 #include <libintl.h> /* SUNWresync121 XXX */
67 typedef struct _acl_op_table
{
72 typedef struct _acl_entry
{
73 struct _acl_entry
*ae_next
;
75 krb5_boolean ae_name_bad
;
76 krb5_principal ae_principal
;
77 krb5_int32 ae_op_allowed
;
79 krb5_boolean ae_target_bad
;
80 krb5_principal ae_target_princ
;
81 char *ae_restriction_string
;
82 /* eg: "-maxlife 3h -service +proxiable" */
83 krb5_boolean ae_restriction_bad
;
84 restriction_t
*ae_restrictions
;
87 static const aop_t acl_op_table
[] = {
91 { 'c', ACL_CHANGEPW
},
94 { 'p', ACL_IPROP
}, /* SUNW IProp */
96 { 'u', ACL_MIGRATE
}, /* pam_krb5_migrate */
97 { 'x', ACL_ALL_MASK
},
98 { '*', ACL_ALL_MASK
},
102 typedef struct _wildstate
{
104 krb5_data
*backref
[9];
107 static aent_t
*acl_list_head
= (aent_t
*) NULL
;
108 static aent_t
*acl_list_tail
= (aent_t
*) NULL
;
110 static const char *acl_acl_file
= (char *) NULL
;
111 static int acl_inited
= 0;
112 static int acl_debug_level
= 0;
114 * This is the catchall entry. If nothing else appropriate is found, or in
115 * the case where the ACL file is not present, this entry controls what can
118 static const char *acl_catchall_entry
= NULL
;
120 /* Solaris Kerberos */
121 #define ACL_LINE2LONG_MSG dgettext(TEXT_DOMAIN, \
122 "%s: line %d too long, truncated\n")
123 #define ACL_OP_BAD_MSG dgettext(TEXT_DOMAIN, \
124 "Unrecognized ACL operation '%c' in %s\n")
125 #define ACL_SYN_ERR_MSG dgettext(TEXT_DOMAIN, \
126 "%s: syntax error at line %d <%10s...>\n")
127 #define ACL_CANTOPEN_MSG dgettext(TEXT_DOMAIN, \
128 "\007cannot open ACL file")
132 * kadm5int_acl_get_line() - Get a line from the ACL file.
133 * Lines ending with \ are continued on the next line
136 kadm5int_acl_get_line(fp
, lnp
)
138 int *lnp
; /* caller should set to 1 before first call */
141 static int line_incr
= 0;
142 static char acl_buf
[BUFSIZ
];
146 for (domore
= 1; domore
&& !feof(fp
); ) {
147 /* Copy in the line, with continuations */
148 for (i
=0; ((i
< sizeof acl_buf
) && !feof(fp
)); i
++ ) {
149 acl_buf
[i
] = fgetc(fp
);
150 if (acl_buf
[i
] == (char)EOF
) {
151 if (i
> 0 && acl_buf
[i
-1] == '\\')
153 break; /* it gets nulled-out below */
155 else if (acl_buf
[i
] == '\n') {
156 if (i
== 0 || acl_buf
[i
-1] != '\\')
157 break; /* empty line or normal end of line */
159 i
-= 2; /* back up over "\\\n" and continue */
164 /* Check if we exceeded our buffer size */
165 if (i
== sizeof acl_buf
&& (i
--, !feof(fp
))) {
166 int c1
= acl_buf
[i
], c2
;
168 krb5_klog_syslog(LOG_ERR
, ACL_LINE2LONG_MSG
, acl_acl_file
, *lnp
);
169 while ((c2
= fgetc(fp
)) != EOF
) {
179 if (acl_buf
[0] == (char) EOF
) /* ptooey */
183 if ((acl_buf
[0] != '#') && (acl_buf
[0] != '\0'))
186 if (domore
|| (strlen(acl_buf
) == 0))
187 return((char *) NULL
);
193 * kadm5int_acl_parse_line() - Parse the contents of an ACL line.
196 kadm5int_acl_parse_line(lp
)
199 static char acle_principal
[BUFSIZ
];
200 static char acle_ops
[BUFSIZ
];
201 static char acle_object
[BUFSIZ
];
202 static char acle_restrictions
[BUFSIZ
];
205 int t
, found
, opok
, nmatch
;
207 DPRINT(DEBUG_CALLS
, acl_debug_level
,
208 ("* kadm5int_acl_parse_line(line=%20s)\n", lp
));
210 * Format is still simple:
211 * entry ::= [<whitespace>] <principal> <whitespace> <opstring>
212 * [<whitespace> <target> [<whitespace> <restrictions>
215 acle
= (aent_t
*) NULL
;
216 acle_object
[0] = '\0';
217 nmatch
= sscanf(lp
, "%s %s %s %[^\n]", acle_principal
, acle_ops
,
218 acle_object
, acle_restrictions
);
220 acle
= (aent_t
*) malloc(sizeof(aent_t
));
222 acle
->ae_next
= (aent_t
*) NULL
;
223 acle
->ae_op_allowed
= (krb5_int32
) 0;
225 (nmatch
>= 3) ? strdup(acle_object
) : (char *) NULL
;
226 acle
->ae_target_bad
= 0;
227 acle
->ae_target_princ
= (krb5_principal
) NULL
;
229 for (op
=acle_ops
; *op
; op
++) {
232 rop
= (isupper((unsigned char) *op
)) ? tolower((unsigned char) *op
) : *op
;
234 for (t
=0; acl_op_table
[t
].ao_op
; t
++) {
235 if (rop
== acl_op_table
[t
].ao_op
) {
238 acle
->ae_op_allowed
|= acl_op_table
[t
].ao_mask
;
240 acle
->ae_op_allowed
&= ~acl_op_table
[t
].ao_mask
;
244 krb5_klog_syslog(LOG_ERR
, ACL_OP_BAD_MSG
, *op
, lp
);
249 acle
->ae_name
= (char *) malloc(strlen(acle_principal
)+1);
251 strcpy(acle
->ae_name
, acle_principal
);
252 acle
->ae_principal
= (krb5_principal
) NULL
;
253 acle
->ae_name_bad
= 0;
254 DPRINT(DEBUG_ACL
, acl_debug_level
,
255 ("A ACL entry %s -> opmask %x\n",
256 acle
->ae_name
, acle
->ae_op_allowed
));
260 free(acle
->ae_target
);
262 acle
= (aent_t
*) NULL
;
267 free(acle
->ae_target
);
269 acle
= (aent_t
*) NULL
;
274 trailing
= &acle_restrictions
[strlen(acle_restrictions
)-1];
275 while ( isspace((int) *trailing
) )
278 acle
->ae_restriction_string
= strdup(acle_restrictions
);
281 acle
->ae_restriction_string
= (char *) NULL
;
283 acle
->ae_restriction_bad
= 0;
284 acle
->ae_restrictions
= (restriction_t
*) NULL
;
287 DPRINT(DEBUG_CALLS
, acl_debug_level
,
288 ("X kadm5int_acl_parse_line() = %x\n", (long) acle
));
293 * kadm5int_acl_parse_restrictions() - Parse optional restrictions field
295 * Allowed restrictions are:
296 * [+-]flagname (recognized by krb5_string_to_flags)
297 * flag is forced to indicated value
298 * -clearpolicy policy is forced clear
299 * -policy pol policy is forced to be "pol"
300 * -{expire,pwexpire,maxlife,maxrenewlife} deltat
301 * associated value will be forced to
302 * MIN(deltat, requested value)
304 * Returns: 0 on success, or system errors
306 static krb5_error_code
307 kadm5int_acl_parse_restrictions(s
, rpp
)
312 static const char *delims
= "\t\n\f\v\r ,";
315 krb5_error_code code
;
317 DPRINT(DEBUG_CALLS
, acl_debug_level
,
318 ("* kadm5int_acl_parse_restrictions(s=%20s, rpp=0x%08x)\n", s
, (long)rpp
));
320 *rpp
= (restriction_t
*) NULL
;
323 if (!(sp
= strdup(s
)) /* Don't munge the original */
324 || !(*rpp
= (restriction_t
*) malloc(sizeof(restriction_t
)))) {
327 memset(*rpp
, 0, sizeof(**rpp
));
328 for (tp
=strtok(sp
, delims
); tp
; tp
=strtok((char *)NULL
, delims
)) {
330 if (!krb5_string_to_flags(tp
, "+", "-", &flag
)) {
331 /* OK, but was it in the positive or negative sense? */
333 (*rpp
)->require_attrs
|= flag
;
336 (void) krb5_string_to_flags(tp
, "+", "-", &flag
);
337 (*rpp
)->forbid_attrs
|= ~flag
;
339 (*rpp
)->mask
|= KADM5_ATTRIBUTES
;
340 } else if (!strcmp(tp
, "-clearpolicy")) {
341 (*rpp
)->mask
|= KADM5_POLICY_CLR
;
343 /* everything else needs an argument ... */
344 if (!(ap
= strtok((char *)NULL
, delims
))) {
348 if (!strcmp(tp
, "-policy")) {
349 if (!((*rpp
)->policy
= strdup(ap
))) {
353 (*rpp
)->mask
|= KADM5_POLICY
;
355 /* all other arguments must be a deltat ... */
356 if (krb5_string_to_deltat(ap
, &dt
)) {
360 if (!strcmp(tp
, "-expire")) {
361 (*rpp
)->princ_lifetime
= dt
;
362 (*rpp
)->mask
|= KADM5_PRINC_EXPIRE_TIME
;
363 } else if (!strcmp(tp
, "-pwexpire")) {
364 (*rpp
)->pw_lifetime
= dt
;
365 (*rpp
)->mask
|= KADM5_PW_EXPIRATION
;
366 } else if (!strcmp(tp
, "-maxlife")) {
367 (*rpp
)->max_life
= dt
;
368 (*rpp
)->mask
|= KADM5_MAX_LIFE
;
369 } else if (!strcmp(tp
, "-maxrenewlife")) {
370 (*rpp
)->max_renewable_life
= dt
;
371 (*rpp
)->mask
|= KADM5_MAX_RLIFE
;
385 free((*rpp
)->policy
);
387 *rpp
= (restriction_t
*) NULL
;
389 DPRINT(DEBUG_CALLS
, acl_debug_level
,
390 ("X kadm5int_acl_parse_restrictions() = %d, mask=0x%08x\n",
391 code
, (*rpp
) ? (*rpp
)->mask
: 0));
396 * kadm5int_acl_impose_restrictions() - impose restrictions, modifying *recp, *maskp
398 * Returns: 0 on success;
399 * malloc or timeofday errors
402 kadm5int_acl_impose_restrictions(kcontext
, recp
, maskp
, rp
)
403 krb5_context kcontext
;
404 kadm5_principal_ent_rec
*recp
;
408 krb5_error_code code
;
411 DPRINT(DEBUG_CALLS
, acl_debug_level
,
412 ("* kadm5int_acl_impose_restrictions(..., *maskp=0x%08x, rp=0x%08x)\n",
416 if (rp
->mask
& (KADM5_PRINC_EXPIRE_TIME
|KADM5_PW_EXPIRATION
))
417 if ((code
= krb5_timeofday(kcontext
, &now
)))
420 if (rp
->mask
& KADM5_ATTRIBUTES
) {
421 recp
->attributes
|= rp
->require_attrs
;
422 recp
->attributes
&= ~(rp
->forbid_attrs
);
423 *maskp
|= KADM5_ATTRIBUTES
;
425 if (rp
->mask
& KADM5_POLICY_CLR
) {
426 *maskp
&= ~KADM5_POLICY
;
427 *maskp
|= KADM5_POLICY_CLR
;
428 } else if (rp
->mask
& KADM5_POLICY
) {
429 if (recp
->policy
&& strcmp(recp
->policy
, rp
->policy
)) {
431 recp
->policy
= (char *) NULL
;
434 recp
->policy
= strdup(rp
->policy
); /* XDR will free it */
438 *maskp
|= KADM5_POLICY
;
440 if (rp
->mask
& KADM5_PRINC_EXPIRE_TIME
) {
441 if (!(*maskp
& KADM5_PRINC_EXPIRE_TIME
)
442 || (recp
->princ_expire_time
> (now
+ rp
->princ_lifetime
)))
443 recp
->princ_expire_time
= now
+ rp
->princ_lifetime
;
444 *maskp
|= KADM5_PRINC_EXPIRE_TIME
;
446 if (rp
->mask
& KADM5_PW_EXPIRATION
) {
447 if (!(*maskp
& KADM5_PW_EXPIRATION
)
448 || (recp
->pw_expiration
> (now
+ rp
->pw_lifetime
)))
449 recp
->pw_expiration
= now
+ rp
->pw_lifetime
;
450 *maskp
|= KADM5_PW_EXPIRATION
;
452 if (rp
->mask
& KADM5_MAX_LIFE
) {
453 if (!(*maskp
& KADM5_MAX_LIFE
)
454 || (recp
->max_life
> rp
->max_life
))
455 recp
->max_life
= rp
->max_life
;
456 *maskp
|= KADM5_MAX_LIFE
;
458 if (rp
->mask
& KADM5_MAX_RLIFE
) {
459 if (!(*maskp
& KADM5_MAX_RLIFE
)
460 || (recp
->max_renewable_life
> rp
->max_renewable_life
))
461 recp
->max_renewable_life
= rp
->max_renewable_life
;
462 *maskp
|= KADM5_MAX_RLIFE
;
464 DPRINT(DEBUG_CALLS
, acl_debug_level
,
465 ("X kadm5int_acl_impose_restrictions() = 0, *maskp=0x%08x\n", *maskp
));
470 * kadm5int_acl_free_entries() - Free all ACL entries.
473 kadm5int_acl_free_entries()
478 DPRINT(DEBUG_CALLS
, acl_debug_level
, ("* kadm5int_acl_free_entries()\n"));
479 for (ap
=acl_list_head
; ap
; ap
= np
) {
482 if (ap
->ae_principal
)
483 krb5_free_principal((krb5_context
) NULL
, ap
->ae_principal
);
486 if (ap
->ae_target_princ
)
487 krb5_free_principal((krb5_context
) NULL
, ap
->ae_target_princ
);
488 if (ap
->ae_restriction_string
)
489 free(ap
->ae_restriction_string
);
490 if (ap
->ae_restrictions
) {
491 if (ap
->ae_restrictions
->policy
)
492 free(ap
->ae_restrictions
->policy
);
493 free(ap
->ae_restrictions
);
498 acl_list_head
= acl_list_tail
= (aent_t
*) NULL
;
500 DPRINT(DEBUG_CALLS
, acl_debug_level
, ("X kadm5int_acl_free_entries()\n"));
504 * kadm5int_acl_load_acl_file() - Open and parse the ACL file.
507 kadm5int_acl_load_acl_file()
515 DPRINT(DEBUG_CALLS
, acl_debug_level
, ("* kadm5int_acl_load_acl_file()\n"));
516 /* Open the ACL file for read */
517 afp
= fopen(acl_acl_file
, "rF"); /* Solaris Kerberos */
520 aentpp
= &acl_list_head
;
522 /* Get a non-comment line */
523 while ((alinep
= kadm5int_acl_get_line(afp
, &alineno
))) {
525 *aentpp
= kadm5int_acl_parse_line(alinep
);
526 /* If syntax error, then fall out */
528 krb5_klog_syslog(LOG_ERR
, ACL_SYN_ERR_MSG
,
529 acl_acl_file
, alineno
, alinep
);
533 acl_list_tail
= *aentpp
;
534 aentpp
= &(*aentpp
)->ae_next
;
539 if (acl_catchall_entry
) {
540 *aentpp
= kadm5int_acl_parse_line(acl_catchall_entry
);
542 acl_list_tail
= *aentpp
;
546 DPRINT(DEBUG_OPERATION
, acl_debug_level
,
547 ("> catchall acl entry (%s) load failed\n",
548 acl_catchall_entry
));
553 krb5_klog_syslog(LOG_ERR
, ACL_CANTOPEN_MSG
,
554 error_message(errno
), acl_acl_file
);
555 if (acl_catchall_entry
&&
556 (acl_list_head
= kadm5int_acl_parse_line((char *)acl_catchall_entry
))) {
557 acl_list_tail
= acl_list_head
;
561 DPRINT(DEBUG_OPERATION
, acl_debug_level
,
562 ("> catchall acl entry (%s) load failed\n",
563 acl_catchall_entry
));
568 kadm5int_acl_free_entries();
570 DPRINT(DEBUG_CALLS
, acl_debug_level
,
571 ("X kadm5int_acl_load_acl_file() = %d\n", retval
));
576 * kadm5int_acl_match_data() - See if two data entries match.
578 * Wildcarding is only supported for a whole component.
581 kadm5int_acl_match_data(e1
, e2
, targetflag
, ws
)
588 DPRINT(DEBUG_CALLS
, acl_debug_level
,
589 ("* acl_match_entry(%s, %s)\n", e1
->data
, e2
->data
));
591 if (!strncmp(e1
->data
, "*", e1
->length
)) {
593 if (ws
&& !targetflag
) {
594 if (ws
->nwild
>= 9) {
595 /* Solaris Kerberos */
596 DPRINT(DEBUG_ACL
, acl_debug_level
,
597 ("Too many wildcards in ACL entry %s\n", e1
->data
));
600 ws
->backref
[ws
->nwild
++] = e2
;
603 else if (ws
&& targetflag
&& (e1
->length
== 2) && (e1
->data
[0] == '*') &&
604 (e1
->data
[1] >= '1') && (e1
->data
[1] <= '9')) {
605 int n
= e1
->data
[1] - '1';
606 if (n
>= ws
->nwild
) {
607 /* Solaris Kerberos */
608 DPRINT(DEBUG_ACL
, acl_debug_level
,
609 ("Too many backrefs in ACL entry %s\n", e1
->data
));
611 else if ((ws
->backref
[n
]->length
== e2
->length
) &&
612 (!strncmp(ws
->backref
[n
]->data
, e2
->data
, e2
->length
)))
617 if ((e1
->length
== e2
->length
) &&
618 (!strncmp(e1
->data
, e2
->data
, e1
->length
)))
621 DPRINT(DEBUG_CALLS
, acl_debug_level
, ("X acl_match_entry()=%d\n",retval
));
626 * kadm5int_acl_find_entry() - Find a matching entry.
629 kadm5int_acl_find_entry(kcontext
, principal
, dest_princ
)
630 krb5_context kcontext
;
631 krb5_principal principal
;
632 krb5_principal dest_princ
;
635 krb5_error_code kret
;
640 DPRINT(DEBUG_CALLS
, acl_debug_level
, ("* kadm5int_acl_find_entry()\n"));
641 memset((char *)&state
, 0, sizeof state
);
642 for (entry
=acl_list_head
; entry
; entry
= entry
->ae_next
) {
643 if (entry
->ae_name_bad
)
645 if (!strcmp(entry
->ae_name
, "*")) {
646 DPRINT(DEBUG_ACL
, acl_debug_level
, ("A wildcard ACL match\n"));
650 if (!entry
->ae_principal
&& !entry
->ae_name_bad
) {
651 kret
= krb5_parse_name(kcontext
,
653 &entry
->ae_principal
);
655 entry
->ae_name_bad
= 1;
657 if (entry
->ae_name_bad
) {
658 DPRINT(DEBUG_ACL
, acl_debug_level
,
659 ("Bad ACL entry %s\n", entry
->ae_name
));
663 if (kadm5int_acl_match_data(&entry
->ae_principal
->realm
,
664 &principal
->realm
, 0, (wildstate_t
*)0) &&
665 (entry
->ae_principal
->length
== principal
->length
)) {
667 for (i
=0; i
<principal
->length
; i
++) {
668 if (!kadm5int_acl_match_data(&entry
->ae_principal
->data
[i
],
669 &principal
->data
[i
], 0, &state
)) {
679 /* We've matched the principal. If we have a target, then try it */
680 if (entry
->ae_target
&& strcmp(entry
->ae_target
, "*")) {
681 if (!entry
->ae_target_princ
&& !entry
->ae_target_bad
) {
682 kret
= krb5_parse_name(kcontext
, entry
->ae_target
,
683 &entry
->ae_target_princ
);
685 entry
->ae_target_bad
= 1;
687 if (entry
->ae_target_bad
) {
688 DPRINT(DEBUG_ACL
, acl_debug_level
,
689 ("Bad target in ACL entry for %s\n", entry
->ae_name
));
690 entry
->ae_name_bad
= 1;
695 else if (entry
->ae_target_princ
&& dest_princ
) {
696 if (kadm5int_acl_match_data(&entry
->ae_target_princ
->realm
,
697 &dest_princ
->realm
, 1, (wildstate_t
*)0) &&
698 (entry
->ae_target_princ
->length
== dest_princ
->length
)) {
699 for (i
=0; i
<dest_princ
->length
; i
++) {
700 if (!kadm5int_acl_match_data(&entry
->ae_target_princ
->data
[i
],
701 &dest_princ
->data
[i
], 1, &state
)) {
714 if (entry
->ae_restriction_string
715 && !entry
->ae_restriction_bad
716 && !entry
->ae_restrictions
717 && kadm5int_acl_parse_restrictions(entry
->ae_restriction_string
,
718 &entry
->ae_restrictions
)) {
719 DPRINT(DEBUG_ACL
, acl_debug_level
,
720 ("Bad restrictions in ACL entry for %s\n", entry
->ae_name
));
721 entry
->ae_restriction_bad
= 1;
723 if (entry
->ae_restriction_bad
) {
724 entry
->ae_name_bad
= 1;
729 DPRINT(DEBUG_CALLS
, acl_debug_level
, ("X kadm5int_acl_find_entry()=%x\n",entry
));
734 * kadm5int_acl_init() - Initialize ACL context.
737 kadm5int_acl_init(kcontext
, debug_level
, acl_file
)
738 krb5_context kcontext
;
742 krb5_error_code kret
;
745 acl_debug_level
= debug_level
;
746 DPRINT(DEBUG_CALLS
, acl_debug_level
,
747 ("* kadm5int_acl_init(afile=%s)\n",
748 ((acl_file
) ? acl_file
: "(null)")));
749 acl_acl_file
= (acl_file
) ? acl_file
: (char *) KRB5_DEFAULT_ADMIN_ACL
;
750 acl_inited
= kadm5int_acl_load_acl_file();
752 DPRINT(DEBUG_CALLS
, acl_debug_level
, ("X kadm5int_acl_init() = %d\n", kret
));
757 * kadm5int_acl_finish - Terminate ACL context.
760 kadm5int_acl_finish(kcontext
, debug_level
)
761 krb5_context kcontext
;
764 DPRINT(DEBUG_CALLS
, acl_debug_level
, ("* kadm5int_acl_finish()\n"));
765 kadm5int_acl_free_entries();
766 DPRINT(DEBUG_CALLS
, acl_debug_level
, ("X kadm5int_acl_finish()\n"));
770 * kadm5int_acl_check() - Is this operation permitted for this principal?
771 * this code used not to be based on gssapi. In order
772 * to minimize porting hassles, I've put all the
773 * gssapi hair in this function. This might not be
774 * the best medium-term solution. (The best long-term
775 * solution is, of course, a real authorization service.)
778 kadm5int_acl_check(kcontext
, caller
, opmask
, principal
, restrictions
)
779 krb5_context kcontext
;
782 krb5_principal principal
;
783 restriction_t
**restrictions
;
787 gss_buffer_desc caller_buf
;
789 OM_uint32 emaj
, emin
;
790 krb5_error_code code
;
791 krb5_principal caller_princ
;
793 DPRINT(DEBUG_CALLS
, acl_debug_level
, ("* acl_op_permitted()\n"));
795 /* Solaris Kerberos */
797 *restrictions
= NULL
;
799 if (GSS_ERROR(emaj
= gss_display_name(&emin
, caller
, &caller_buf
,
803 code
= krb5_parse_name(kcontext
, (char *) caller_buf
.value
,
806 gss_release_buffer(&emin
, &caller_buf
);
813 aentry
= kadm5int_acl_find_entry(kcontext
, caller_princ
, principal
);
815 if ((aentry
->ae_op_allowed
& opmask
) == opmask
) {
819 (aentry
->ae_restrictions
&& aentry
->ae_restrictions
->mask
)
820 ? aentry
->ae_restrictions
821 : (restriction_t
*) NULL
;
826 krb5_free_principal(kcontext
, caller_princ
);
828 DPRINT(DEBUG_CALLS
, acl_debug_level
, ("X acl_op_permitted()=%d\n",
834 kadm5_get_privs(void *server_handle
, long *privs
)
836 CHECK_HANDLE(server_handle
);
838 /* this is impossible to do with the current interface. For now,
839 return all privs, which will confuse some clients, but not
840 deny any access to users of "smart" clients which try to cache */
847 /* SUNWresync121 (SEAM1.0) XXX */
849 __kadm5_get_priv(void *server_handle
, long *privs
, gss_name_t client
)
853 gss_buffer_desc caller_buff
;
855 krb5_principal caller_principal
;
856 OM_uint32 minor
, major
;
857 krb5_error_code k_error
;
858 kadm5_ret_t retval
= KADM5_FAILURE
;
860 kadm5_server_handle_t handle
= server_handle
;
862 CHECK_HANDLE(server_handle
);
864 if (GSS_ERROR(major
= gss_display_name(&minor
, client
, &caller_buff
,
867 k_error
= krb5_parse_name(handle
->context
,
868 (char *) caller_buff
.value
,
870 gss_release_buffer(&minor
, &caller_buff
);
875 if (aentry
= kadm5int_acl_find_entry(handle
->context
, caller_principal
,
876 (krb5_principal
)NULL
))
877 *privs
= aentry
->ae_op_allowed
;
878 krb5_free_principal(handle
->context
, caller_principal
);