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
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 * str_conv.c - Convert between strings and Kerberos internal data.
61 * krb5_string_to_flags() - Convert string to krb5_flags.
65 * krb5_flags_to_string() - Convert krb5_flags to string.
69 #include "admin_internal.h"
70 #include "adm_proto.h"
73 * Local data structures.
75 struct flags_lookup_entry
{
76 krb5_flags fl_flags
; /* Flag */
77 krb5_boolean fl_sense
; /* Sense of the flag */
78 const char * fl_specifier
; /* How to recognize it */
79 const char * fl_output
; /* How to spit it out */
86 static const char default_tupleseps
[] = ", \t";
87 static const char default_ksaltseps
[] = ":.";
91 static const char flags_pdate_in
[] = "postdateable";
92 static const char flags_fwd_in
[] = "forwardable";
93 static const char flags_tgtbased_in
[] = "tgt-based";
94 static const char flags_renew_in
[] = "renewable";
95 static const char flags_proxy_in
[] = "proxiable";
96 static const char flags_dup_skey_in
[] = "dup-skey";
97 static const char flags_tickets_in
[] = "allow-tickets";
98 static const char flags_preauth_in
[] = "preauth";
99 static const char flags_hwauth_in
[] = "hwauth";
100 static const char flags_pwchange_in
[] = "pwchange";
101 static const char flags_service_in
[] = "service";
102 static const char flags_pwsvc_in
[] = "pwservice";
103 static const char flags_md5_in
[] = "md5";
104 static const char flags_pdate_out
[] = "Not Postdateable";
105 static const char flags_fwd_out
[] = "Not Forwardable";
106 static const char flags_tgtbased_out
[] = "No TGT-based requests";
107 static const char flags_renew_out
[] = "Not renewable";
108 static const char flags_proxy_out
[] = "Not proxiable";
109 static const char flags_dup_skey_out
[] = "No DUP_SKEY requests";
110 static const char flags_tickets_out
[] = "All Tickets Disallowed";
111 static const char flags_preauth_out
[] = "Preauthorization required";
112 static const char flags_hwauth_out
[] = "HW Authorization required";
113 static const char flags_pwchange_out
[] = "Password Change required";
114 static const char flags_service_out
[] = "Service Disabled";
115 static const char flags_pwsvc_out
[] = "Password Changing Service";
116 static const char flags_md5_out
[] = "RSA-MD5 supported";
117 static const char flags_default_neg
[] = "-";
118 static const char flags_default_sep
[] = " ";
124 static const struct flags_lookup_entry flags_table
[] = {
125 /* flag sense input specifier output string */
126 /*----------------------------- ------- ------------------ ------------------*/
127 { KRB5_KDB_DISALLOW_POSTDATED
, 0, flags_pdate_in
, flags_pdate_out
},
128 { KRB5_KDB_DISALLOW_FORWARDABLE
,0, flags_fwd_in
, flags_fwd_out
},
129 { KRB5_KDB_DISALLOW_TGT_BASED
, 0, flags_tgtbased_in
, flags_tgtbased_out
},
130 { KRB5_KDB_DISALLOW_RENEWABLE
, 0, flags_renew_in
, flags_renew_out
},
131 { KRB5_KDB_DISALLOW_PROXIABLE
, 0, flags_proxy_in
, flags_proxy_out
},
132 { KRB5_KDB_DISALLOW_DUP_SKEY
, 0, flags_dup_skey_in
, flags_dup_skey_out
},
133 { KRB5_KDB_DISALLOW_ALL_TIX
, 0, flags_tickets_in
, flags_tickets_out
},
134 { KRB5_KDB_REQUIRES_PRE_AUTH
, 1, flags_preauth_in
, flags_preauth_out
},
135 { KRB5_KDB_REQUIRES_HW_AUTH
, 1, flags_hwauth_in
, flags_hwauth_out
},
136 { KRB5_KDB_REQUIRES_PWCHANGE
, 1, flags_pwchange_in
, flags_pwchange_out
},
137 { KRB5_KDB_DISALLOW_SVR
, 0, flags_service_in
, flags_service_out
},
138 { KRB5_KDB_PWCHANGE_SERVICE
, 1, flags_pwsvc_in
, flags_pwsvc_out
},
139 { KRB5_KDB_SUPPORT_DESMD5
, 1, flags_md5_in
, flags_md5_out
}
141 static const int flags_table_nents
= sizeof(flags_table
)/
142 sizeof(flags_table
[0]);
146 krb5_string_to_flags(string
, positive
, negative
, flagsp
)
148 const char * positive
;
149 const char * negative
;
160 /* We need to have a way to negate it. */
161 neg
= (negative
) ? negative
: flags_default_neg
;
163 psize
= (positive
) ? strlen(positive
) : 0;
167 /* First check for positive or negative sense */
168 if (!strncasecmp(neg
, string
, nsize
)) {
172 else if (psize
&& !strncasecmp(positive
, string
, psize
)) {
176 for (i
=0; i
<flags_table_nents
; i
++) {
177 if (!strcasecmp(&string
[cpos
], flags_table
[i
].fl_specifier
)) {
179 if (sense
== (int) flags_table
[i
].fl_sense
)
180 *flagsp
|= flags_table
[i
].fl_flags
;
182 *flagsp
&= ~flags_table
[i
].fl_flags
;
187 return((found
) ? 0 : EINVAL
);
191 krb5_flags_to_string(flags
, sep
, buffer
, buflen
)
199 const char *sepstring
;
202 krb5_error_code retval
;
208 sepstring
= (sep
) ? sep
: flags_default_sep
;
209 /* Blast through the table matching all we can */
210 for (i
=0; i
<flags_table_nents
; i
++) {
211 if (flags
& flags_table
[i
].fl_flags
) {
212 /* Found a match, see if it'll fit into the output buffer */
213 if ((op
+strlen(flags_table
[i
].fl_output
)+strlen(sepstring
)) <
220 strcpy(op
, flags_table
[i
].fl_output
);
221 op
+= strlen(flags_table
[i
].fl_output
);
227 /* Keep track of what we matched */
228 pflags
|= flags_table
[i
].fl_flags
;
232 /* See if there's any leftovers */
242 krb5_input_flag_to_string(flag
, buffer
, buflen
)
247 if(flag
< 0 || flag
>= flags_table_nents
) return ENOENT
; /* End of list */
248 if(strlen(flags_table
[flag
].fl_specifier
) > buflen
) return ENOMEM
;
249 strcpy(buffer
, flags_table
[flag
].fl_specifier
);
254 * krb5_keysalt_is_present() - Determine if a key/salt pair is present
255 * in a list of key/salt tuples.
257 * Salttype may be negative to indicate a search for only a enctype.
260 krb5_keysalt_is_present(ksaltlist
, nksalts
, enctype
, salttype
)
261 krb5_key_salt_tuple
*ksaltlist
;
263 krb5_enctype enctype
;
266 krb5_boolean foundit
;
271 for (i
=0; i
<nksalts
; i
++) {
272 if ((ksaltlist
[i
].ks_enctype
== enctype
) &&
273 ((ksaltlist
[i
].ks_salttype
== salttype
) ||
284 * krb5_string_to_keysalts() - Convert a string representation to a list
285 * of key/salt tuples.
288 krb5_string_to_keysalts(string
, tupleseps
, ksaltseps
, dups
, ksaltp
, nksaltp
)
290 const char *tupleseps
;
291 const char *ksaltseps
;
293 krb5_key_salt_tuple
**ksaltp
;
296 krb5_error_code kret
;
298 char sepchar
, trailchar
;
301 krb5_key_salt_tuple
*savep
;
302 const char *tseplist
;
303 const char *ksseplist
;
309 tseplist
= (tupleseps
) ? tupleseps
: default_tupleseps
;
310 ksseplist
= (ksaltseps
) ? ksaltseps
: default_ksaltseps
;
312 /* Attempt to find a separator */
316 for (ep
= strchr(kp
, (int) *septmp
);
318 ep
= strchr(kp
, (int) *septmp
));
327 * kp points to something (hopefully) of the form:
328 * <enctype><ksseplist><salttype>
333 /* Attempt to find a separator */
335 for (sp
= strchr(kp
, (int) *septmp
);
337 sp
= strchr(kp
, (int)*septmp
)); /* Solaris Kerberos */
340 /* Separate enctype from salttype */
349 * Attempt to parse enctype and salttype. If we parse well
350 * then make sure that it specifies a unique key/salt combo
352 if (!(kret
= krb5_string_to_enctype(kp
, &ktype
)) &&
353 (!sp
|| !(kret
= krb5_string_to_salttype(sp
, &stype
))) &&
355 !krb5_keysalt_is_present(*ksaltp
, *nksaltp
, ktype
, stype
))) {
357 /* Squirrel away old keysalt array */
359 len
= (size_t) *nksaltp
;
361 /* Get new keysalt array */
362 *ksaltp
= (krb5_key_salt_tuple
*)
363 malloc((len
+ 1) * sizeof(krb5_key_salt_tuple
));
366 /* Copy old keysalt if appropriate */
368 memcpy(*ksaltp
, savep
,
369 len
* sizeof(krb5_key_salt_tuple
));
373 /* Save our values */
374 (*ksaltp
)[(*nksaltp
)].ks_enctype
= ktype
;
375 (*ksaltp
)[(*nksaltp
)].ks_salttype
= stype
;
385 * If the string did not yield a valid enctype/keysalt
386 * just ignore it and continue on. MIT kerberos stops
387 * searching when if finds an unknown string.
395 /* Skip over extra separators - like spaces */
396 if (kp
&& *tseplist
) {
398 while(*septmp
&& *kp
) {
400 /* Increment string - reset separator list */
414 * krb5_keysalt_iterate() - Do something for each unique key/salt
417 * If ignoresalt set, then salttype is ignored.
420 krb5_keysalt_iterate(ksaltlist
, nksalt
, ignoresalt
, iterator
, arg
)
421 krb5_key_salt_tuple
*ksaltlist
;
423 krb5_boolean ignoresalt
;
424 krb5_error_code (*iterator
) (krb5_key_salt_tuple
*, krb5_pointer
);
428 krb5_error_code kret
;
429 krb5_key_salt_tuple scratch
;
432 for (i
=0; i
<nksalt
; i
++) {
433 scratch
.ks_enctype
= ksaltlist
[i
].ks_enctype
;
434 scratch
.ks_salttype
= (ignoresalt
) ? -1 : ksaltlist
[i
].ks_salttype
;
435 if (!krb5_keysalt_is_present(ksaltlist
,
438 scratch
.ks_salttype
)) {
439 kret
= (*iterator
)(&scratch
, arg
);