17c478bd9Sstevel@tonic-gate /*
2*159d09a2SMark Phalan * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
37c478bd9Sstevel@tonic-gate * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate */
57c478bd9Sstevel@tonic-gate
67c478bd9Sstevel@tonic-gate
77c478bd9Sstevel@tonic-gate /*
87c478bd9Sstevel@tonic-gate * lib/krb5/os/an_to_ln.c
97c478bd9Sstevel@tonic-gate *
107c478bd9Sstevel@tonic-gate * Copyright 1990,1991 by the Massachusetts Institute of Technology.
117c478bd9Sstevel@tonic-gate * All Rights Reserved.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may
147c478bd9Sstevel@tonic-gate * require a specific license from the United States Government.
157c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating
167c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting.
17*159d09a2SMark Phalan *
187c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
197c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and
207c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright
217c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and
227c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that
237c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining
247c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior
257c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label
267c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a
277c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software.
287c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of
297c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express
307c478bd9Sstevel@tonic-gate * or implied warranty.
31*159d09a2SMark Phalan *
327c478bd9Sstevel@tonic-gate *
337c478bd9Sstevel@tonic-gate * krb5_aname_to_localname()
347c478bd9Sstevel@tonic-gate */
357c478bd9Sstevel@tonic-gate
367c478bd9Sstevel@tonic-gate /*
377c478bd9Sstevel@tonic-gate * We're only to AN_TO_LN rules at this point, and not doing the
387c478bd9Sstevel@tonic-gate * database lookup (moved from configure script)
397c478bd9Sstevel@tonic-gate */
407c478bd9Sstevel@tonic-gate #define AN_TO_LN_RULES
417c478bd9Sstevel@tonic-gate
42*159d09a2SMark Phalan #include "k5-int.h"
437c478bd9Sstevel@tonic-gate #include <ctype.h>
447c478bd9Sstevel@tonic-gate #if HAVE_REGEX_H
457c478bd9Sstevel@tonic-gate #include <regex.h>
467c478bd9Sstevel@tonic-gate #endif /* HAVE_REGEX_H */
47505d05c7Sgtb #include <string.h>
487c478bd9Sstevel@tonic-gate /*
497c478bd9Sstevel@tonic-gate * Use compile(3) if no regcomp present.
507c478bd9Sstevel@tonic-gate */
517c478bd9Sstevel@tonic-gate #if !defined(HAVE_REGCOMP) && defined(HAVE_REGEXPR_H) && defined(HAVE_COMPILE)
527c478bd9Sstevel@tonic-gate #define RE_BUF_SIZE 1024
537c478bd9Sstevel@tonic-gate #include <regexpr.h>
547c478bd9Sstevel@tonic-gate #endif /* !HAVE_REGCOMP && HAVE_REGEXP_H && HAVE_COMPILE */
557c478bd9Sstevel@tonic-gate
567c478bd9Sstevel@tonic-gate #define MAX_FORMAT_BUFFER 1024
577c478bd9Sstevel@tonic-gate #ifndef min
587c478bd9Sstevel@tonic-gate #define min(a,b) ((a>b) ? b : a)
597c478bd9Sstevel@tonic-gate #endif /* min */
607c478bd9Sstevel@tonic-gate #ifdef ANAME_DB
617c478bd9Sstevel@tonic-gate /*
627c478bd9Sstevel@tonic-gate * Use standard DBM code.
637c478bd9Sstevel@tonic-gate */
647c478bd9Sstevel@tonic-gate #define KDBM_OPEN(db, fl, mo) dbm_open(db, fl, mo)
657c478bd9Sstevel@tonic-gate #define KDBM_CLOSE(db) dbm_close(db)
667c478bd9Sstevel@tonic-gate #define KDBM_FETCH(db, key) dbm_fetch(db, key)
677c478bd9Sstevel@tonic-gate #endif /*ANAME_DB*/
687c478bd9Sstevel@tonic-gate
697c478bd9Sstevel@tonic-gate /*
707c478bd9Sstevel@tonic-gate * Find the portion of the flattened principal name that we use for mapping.
717c478bd9Sstevel@tonic-gate */
727c478bd9Sstevel@tonic-gate static char *
aname_full_to_mapping_name(char * fprincname)737c478bd9Sstevel@tonic-gate aname_full_to_mapping_name(char *fprincname)
747c478bd9Sstevel@tonic-gate {
757c478bd9Sstevel@tonic-gate char *atp;
767c478bd9Sstevel@tonic-gate size_t mlen;
777c478bd9Sstevel@tonic-gate char *mname;
787c478bd9Sstevel@tonic-gate
797c478bd9Sstevel@tonic-gate mname = (char *) NULL;
807c478bd9Sstevel@tonic-gate if (fprincname) {
817c478bd9Sstevel@tonic-gate atp = strrchr(fprincname, '@');
827c478bd9Sstevel@tonic-gate if (!atp)
837c478bd9Sstevel@tonic-gate atp = &fprincname[strlen(fprincname)];
847c478bd9Sstevel@tonic-gate mlen = (size_t) (atp - fprincname);
857c478bd9Sstevel@tonic-gate
867c478bd9Sstevel@tonic-gate if ((mname = (char *) malloc(mlen+1))) {
877c478bd9Sstevel@tonic-gate strncpy(mname, fprincname, mlen);
887c478bd9Sstevel@tonic-gate mname[mlen] = '\0';
897c478bd9Sstevel@tonic-gate }
907c478bd9Sstevel@tonic-gate }
917c478bd9Sstevel@tonic-gate return(mname);
927c478bd9Sstevel@tonic-gate }
937c478bd9Sstevel@tonic-gate
947c478bd9Sstevel@tonic-gate #ifdef ANAME_DB
957c478bd9Sstevel@tonic-gate /*
967c478bd9Sstevel@tonic-gate * Implementation: This version uses a DBM database, indexed by aname,
977c478bd9Sstevel@tonic-gate * to generate a lname.
987c478bd9Sstevel@tonic-gate *
997c478bd9Sstevel@tonic-gate * The entries in the database are normal C strings, and include the trailing
1007c478bd9Sstevel@tonic-gate * null in the DBM datum.size.
1017c478bd9Sstevel@tonic-gate */
1027c478bd9Sstevel@tonic-gate static krb5_error_code
db_an_to_ln(context,dbname,aname,lnsize,lname)1037c478bd9Sstevel@tonic-gate db_an_to_ln(context, dbname, aname, lnsize, lname)
1047c478bd9Sstevel@tonic-gate krb5_context context;
1057c478bd9Sstevel@tonic-gate char *dbname;
1067c478bd9Sstevel@tonic-gate krb5_const_principal aname;
107505d05c7Sgtb const unsigned int lnsize;
1087c478bd9Sstevel@tonic-gate char *lname;
1097c478bd9Sstevel@tonic-gate {
110505d05c7Sgtb #if !defined(_WIN32)
1117c478bd9Sstevel@tonic-gate DBM *db;
1127c478bd9Sstevel@tonic-gate krb5_error_code retval;
1137c478bd9Sstevel@tonic-gate datum key, contents;
1147c478bd9Sstevel@tonic-gate char *princ_name;
1157c478bd9Sstevel@tonic-gate
1167c478bd9Sstevel@tonic-gate if ((retval = krb5_unparse_name(context, aname, &princ_name)))
1177c478bd9Sstevel@tonic-gate return(retval);
1187c478bd9Sstevel@tonic-gate key.dptr = princ_name;
1197c478bd9Sstevel@tonic-gate key.dsize = strlen(princ_name)+1; /* need to store the NULL for
1207c478bd9Sstevel@tonic-gate decoding */
1217c478bd9Sstevel@tonic-gate
1227c478bd9Sstevel@tonic-gate db = KDBM_OPEN(dbname, O_RDONLY, 0600);
1237c478bd9Sstevel@tonic-gate if (!db) {
1247c478bd9Sstevel@tonic-gate krb5_xfree(princ_name);
1257c478bd9Sstevel@tonic-gate return KRB5_LNAME_CANTOPEN;
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate
1287c478bd9Sstevel@tonic-gate contents = KDBM_FETCH(db, key);
1297c478bd9Sstevel@tonic-gate
1307c478bd9Sstevel@tonic-gate krb5_xfree(princ_name);
1317c478bd9Sstevel@tonic-gate
1327c478bd9Sstevel@tonic-gate if (contents.dptr == NULL) {
1337c478bd9Sstevel@tonic-gate retval = KRB5_LNAME_NOTRANS;
1347c478bd9Sstevel@tonic-gate } else {
1357c478bd9Sstevel@tonic-gate strncpy(lname, contents.dptr, lnsize);
1367c478bd9Sstevel@tonic-gate if (lnsize < contents.dsize)
1377c478bd9Sstevel@tonic-gate retval = KRB5_CONFIG_NOTENUFSPACE;
1387c478bd9Sstevel@tonic-gate else if (lname[contents.dsize-1] != '\0')
1397c478bd9Sstevel@tonic-gate retval = KRB5_LNAME_BADFORMAT;
1407c478bd9Sstevel@tonic-gate else
1417c478bd9Sstevel@tonic-gate retval = 0;
1427c478bd9Sstevel@tonic-gate }
1437c478bd9Sstevel@tonic-gate /* can't close until we copy the contents. */
1447c478bd9Sstevel@tonic-gate (void) KDBM_CLOSE(db);
1457c478bd9Sstevel@tonic-gate return retval;
146505d05c7Sgtb #else /* !_WIN32 && !MACINTOSH */
1477c478bd9Sstevel@tonic-gate /*
1487c478bd9Sstevel@tonic-gate * If we don't have support for a database mechanism, then we can't
1497c478bd9Sstevel@tonic-gate * translate this now, can we?
1507c478bd9Sstevel@tonic-gate */
1517c478bd9Sstevel@tonic-gate return KRB5_LNAME_NOTRANS;
152505d05c7Sgtb #endif /* !_WIN32 && !MACINTOSH */
1537c478bd9Sstevel@tonic-gate }
1547c478bd9Sstevel@tonic-gate #endif /*ANAME_DB*/
1557c478bd9Sstevel@tonic-gate
1567c478bd9Sstevel@tonic-gate #ifdef AN_TO_LN_RULES
1577c478bd9Sstevel@tonic-gate /*
1587c478bd9Sstevel@tonic-gate * Format and transform a principal name to a local name. This is particularly
1597c478bd9Sstevel@tonic-gate * useful when Kerberos principals and local user names are formatted to
1607c478bd9Sstevel@tonic-gate * some particular convention.
1617c478bd9Sstevel@tonic-gate *
1627c478bd9Sstevel@tonic-gate * There are three parts to each rule:
1637c478bd9Sstevel@tonic-gate * First part - formulate the string to perform operations on: If not present
1647c478bd9Sstevel@tonic-gate * then the string defaults to the fully flattened principal minus the realm
1657c478bd9Sstevel@tonic-gate * name. Otherwise the syntax is as follows:
1667c478bd9Sstevel@tonic-gate * "[" <ncomps> ":" <format> "]"
1677c478bd9Sstevel@tonic-gate * Where:
1687c478bd9Sstevel@tonic-gate * <ncomps> is the number of expected components for this
1697c478bd9Sstevel@tonic-gate * rule. If the particular principal does not have this
1707c478bd9Sstevel@tonic-gate * many components, then this rule does not apply.
1717c478bd9Sstevel@tonic-gate *
1727c478bd9Sstevel@tonic-gate * <format> is a string of <component> or verbatim
1737c478bd9Sstevel@tonic-gate * characters to be inserted.
1747c478bd9Sstevel@tonic-gate *
1757c478bd9Sstevel@tonic-gate * <component> is of the form "$"<number> to select the
1767c478bd9Sstevel@tonic-gate * <number>th component. <number> begins from 1.
1777c478bd9Sstevel@tonic-gate *
1787c478bd9Sstevel@tonic-gate * Second part - select rule validity: If not present, then this rule may
1797c478bd9Sstevel@tonic-gate * apply to all selections. Otherwise the syntax is as follows:
1807c478bd9Sstevel@tonic-gate * "(" <regexp> ")"
1817c478bd9Sstevel@tonic-gate * Where: <regexp> is a selector regular expression. If this
1827c478bd9Sstevel@tonic-gate * regular expression matches the whole pattern generated
1837c478bd9Sstevel@tonic-gate * from the first part, then this rule still applies.
1847c478bd9Sstevel@tonic-gate *
1857c478bd9Sstevel@tonic-gate * Last part - Transform rule: If not present, then the selection string
1867c478bd9Sstevel@tonic-gate * is passed verbatim and is matched. Otherwise, the syntax is as follows:
1877c478bd9Sstevel@tonic-gate * <rule> ...
1887c478bd9Sstevel@tonic-gate * Where: <rule> is of the form:
1897c478bd9Sstevel@tonic-gate * "s/" <regexp> "/" <text> "/" ["g"]
190*159d09a2SMark Phalan *
1917c478bd9Sstevel@tonic-gate * In order to be able to select rule validity, the native system must support
1927c478bd9Sstevel@tonic-gate * one of compile(3), re_comp(3) or regcomp(3). In order to be able to
1937c478bd9Sstevel@tonic-gate * transform (e.g. substitute), the native system must support regcomp(3) or
1947c478bd9Sstevel@tonic-gate * compile(3).
1957c478bd9Sstevel@tonic-gate */
1967c478bd9Sstevel@tonic-gate
1977c478bd9Sstevel@tonic-gate /*
1987c478bd9Sstevel@tonic-gate * aname_do_match() - Does our name match the parenthesized regular
1997c478bd9Sstevel@tonic-gate * expression?
200*159d09a2SMark Phalan *
2017c478bd9Sstevel@tonic-gate * Chew up the match portion of the regular expression and update *contextp.
2027c478bd9Sstevel@tonic-gate * If no re_comp() or regcomp(), then always return a match.
2037c478bd9Sstevel@tonic-gate */
2047c478bd9Sstevel@tonic-gate static krb5_error_code
aname_do_match(char * string,char ** contextp)2057c478bd9Sstevel@tonic-gate aname_do_match(char *string, char **contextp)
2067c478bd9Sstevel@tonic-gate {
2077c478bd9Sstevel@tonic-gate krb5_error_code kret;
2087c478bd9Sstevel@tonic-gate char *regexp, *startp, *endp = 0;
2097c478bd9Sstevel@tonic-gate size_t regexlen;
2107c478bd9Sstevel@tonic-gate #if HAVE_REGCOMP
2117c478bd9Sstevel@tonic-gate regex_t match_exp;
2127c478bd9Sstevel@tonic-gate regmatch_t match_match;
2137c478bd9Sstevel@tonic-gate #elif HAVE_REGEXPR_H
2147c478bd9Sstevel@tonic-gate char regexp_buffer[RE_BUF_SIZE];
2157c478bd9Sstevel@tonic-gate #endif /* HAVE_REGEXP_H */
2167c478bd9Sstevel@tonic-gate
2177c478bd9Sstevel@tonic-gate kret = 0;
2187c478bd9Sstevel@tonic-gate /*
2197c478bd9Sstevel@tonic-gate * Is this a match expression?
2207c478bd9Sstevel@tonic-gate */
2217c478bd9Sstevel@tonic-gate if (**contextp == '(') {
2227c478bd9Sstevel@tonic-gate kret = KRB5_CONFIG_BADFORMAT;
2237c478bd9Sstevel@tonic-gate startp = (*contextp) + 1;
2247c478bd9Sstevel@tonic-gate endp = strchr(startp, ')');
2257c478bd9Sstevel@tonic-gate /* Find the end of the match expression. */
2267c478bd9Sstevel@tonic-gate if (endp) {
2277c478bd9Sstevel@tonic-gate regexlen = (size_t) (endp - startp);
2287c478bd9Sstevel@tonic-gate regexp = (char *) malloc((size_t) regexlen+1);
2297c478bd9Sstevel@tonic-gate kret = ENOMEM;
2307c478bd9Sstevel@tonic-gate if (regexp) {
2317c478bd9Sstevel@tonic-gate strncpy(regexp, startp, regexlen);
2327c478bd9Sstevel@tonic-gate regexp[regexlen] = '\0';
2337c478bd9Sstevel@tonic-gate kret = KRB5_LNAME_NOTRANS;
2347c478bd9Sstevel@tonic-gate /*
2357c478bd9Sstevel@tonic-gate * Perform the match.
2367c478bd9Sstevel@tonic-gate */
2377c478bd9Sstevel@tonic-gate #if HAVE_REGCOMP
2387c478bd9Sstevel@tonic-gate if (!regcomp(&match_exp, regexp, REG_EXTENDED) &&
2397c478bd9Sstevel@tonic-gate !regexec(&match_exp, string, 1, &match_match, 0)) {
2407c478bd9Sstevel@tonic-gate if ((match_match.rm_so == 0) &&
2417c478bd9Sstevel@tonic-gate (match_match.rm_eo == strlen(string)))
2427c478bd9Sstevel@tonic-gate kret = 0;
2437c478bd9Sstevel@tonic-gate }
2447c478bd9Sstevel@tonic-gate regfree(&match_exp);
2457c478bd9Sstevel@tonic-gate #elif HAVE_REGEXPR_H
2467c478bd9Sstevel@tonic-gate compile(regexp,
2477c478bd9Sstevel@tonic-gate regexp_buffer,
248*159d09a2SMark Phalan ®exp_buffer[RE_BUF_SIZE]);
2497c478bd9Sstevel@tonic-gate if (step(string, regexp_buffer)) {
2507c478bd9Sstevel@tonic-gate if ((loc1 == string) &&
2517c478bd9Sstevel@tonic-gate (loc2 == &string[strlen(string)]))
2527c478bd9Sstevel@tonic-gate kret = 0;
2537c478bd9Sstevel@tonic-gate }
2547c478bd9Sstevel@tonic-gate #elif HAVE_RE_COMP
2557c478bd9Sstevel@tonic-gate if (!re_comp(regexp) && re_exec(string))
2567c478bd9Sstevel@tonic-gate kret = 0;
2577c478bd9Sstevel@tonic-gate #else /* HAVE_RE_COMP */
2587c478bd9Sstevel@tonic-gate kret = 0;
2597c478bd9Sstevel@tonic-gate #endif /* HAVE_RE_COMP */
2607c478bd9Sstevel@tonic-gate free(regexp);
2617c478bd9Sstevel@tonic-gate }
2627c478bd9Sstevel@tonic-gate endp++;
2637c478bd9Sstevel@tonic-gate }
2647c478bd9Sstevel@tonic-gate else
2657c478bd9Sstevel@tonic-gate endp = startp;
2667c478bd9Sstevel@tonic-gate }
2677c478bd9Sstevel@tonic-gate *contextp = endp;
2687c478bd9Sstevel@tonic-gate return(kret);
2697c478bd9Sstevel@tonic-gate }
2707c478bd9Sstevel@tonic-gate
2717c478bd9Sstevel@tonic-gate /*
2727c478bd9Sstevel@tonic-gate * do_replacement() - Replace the regular expression with the specified
2737c478bd9Sstevel@tonic-gate * replacement.
2747c478bd9Sstevel@tonic-gate *
2757c478bd9Sstevel@tonic-gate * If "doall" is set, it's a global replacement, otherwise, just a oneshot
2767c478bd9Sstevel@tonic-gate * deal.
2777c478bd9Sstevel@tonic-gate * If no regcomp() then just return the input string verbatim in the output
2787c478bd9Sstevel@tonic-gate * string.
2797c478bd9Sstevel@tonic-gate */
2807c478bd9Sstevel@tonic-gate #define use_bytes(x) \
281*159d09a2SMark Phalan out_used += (x); \
282*159d09a2SMark Phalan if (out_used > MAX_FORMAT_BUFFER) goto mem_err
2837c478bd9Sstevel@tonic-gate
2847c478bd9Sstevel@tonic-gate static int
do_replacement(char * regexp,char * repl,int doall,char * in,char * out)2857c478bd9Sstevel@tonic-gate do_replacement(char *regexp, char *repl, int doall, char *in, char *out)
2867c478bd9Sstevel@tonic-gate {
2877c478bd9Sstevel@tonic-gate size_t out_used = 0;
2887c478bd9Sstevel@tonic-gate #if HAVE_REGCOMP
2897c478bd9Sstevel@tonic-gate regex_t match_exp;
2907c478bd9Sstevel@tonic-gate regmatch_t match_match;
2917c478bd9Sstevel@tonic-gate int matched;
2927c478bd9Sstevel@tonic-gate char *cp;
2937c478bd9Sstevel@tonic-gate char *op;
2947c478bd9Sstevel@tonic-gate
2957c478bd9Sstevel@tonic-gate if (!regcomp(&match_exp, regexp, REG_EXTENDED)) {
2967c478bd9Sstevel@tonic-gate cp = in;
2977c478bd9Sstevel@tonic-gate op = out;
2987c478bd9Sstevel@tonic-gate matched = 0;
2997c478bd9Sstevel@tonic-gate do {
3007c478bd9Sstevel@tonic-gate if (!regexec(&match_exp, cp, 1, &match_match, 0)) {
3017c478bd9Sstevel@tonic-gate if (match_match.rm_so) {
3027c478bd9Sstevel@tonic-gate use_bytes(match_match.rm_so);
3037c478bd9Sstevel@tonic-gate strncpy(op, cp, match_match.rm_so);
3047c478bd9Sstevel@tonic-gate op += match_match.rm_so;
3057c478bd9Sstevel@tonic-gate }
3067c478bd9Sstevel@tonic-gate use_bytes(strlen(repl));
3077c478bd9Sstevel@tonic-gate strncpy(op, repl, MAX_FORMAT_BUFFER - 1 - (op - out));
3087c478bd9Sstevel@tonic-gate op += strlen(op);
3097c478bd9Sstevel@tonic-gate cp += match_match.rm_eo;
3107c478bd9Sstevel@tonic-gate if (!doall) {
3117c478bd9Sstevel@tonic-gate use_bytes(strlen(cp));
3127c478bd9Sstevel@tonic-gate strncpy(op, cp, MAX_FORMAT_BUFFER - 1 - (op - out));
3137c478bd9Sstevel@tonic-gate }
3147c478bd9Sstevel@tonic-gate matched = 1;
3157c478bd9Sstevel@tonic-gate }
3167c478bd9Sstevel@tonic-gate else {
3177c478bd9Sstevel@tonic-gate use_bytes(strlen(cp));
3187c478bd9Sstevel@tonic-gate strncpy(op, cp, MAX_FORMAT_BUFFER - 1 - (op - out));
3197c478bd9Sstevel@tonic-gate matched = 0;
3207c478bd9Sstevel@tonic-gate }
3217c478bd9Sstevel@tonic-gate } while (doall && matched);
3227c478bd9Sstevel@tonic-gate regfree(&match_exp);
3237c478bd9Sstevel@tonic-gate }
3247c478bd9Sstevel@tonic-gate #elif HAVE_REGEXPR_H
3257c478bd9Sstevel@tonic-gate int matched;
3267c478bd9Sstevel@tonic-gate char *cp;
3277c478bd9Sstevel@tonic-gate char *op;
3287c478bd9Sstevel@tonic-gate char regexp_buffer[RE_BUF_SIZE];
3297c478bd9Sstevel@tonic-gate size_t sdispl, edispl;
3307c478bd9Sstevel@tonic-gate
3317c478bd9Sstevel@tonic-gate compile(regexp,
3327c478bd9Sstevel@tonic-gate regexp_buffer,
333*159d09a2SMark Phalan ®exp_buffer[RE_BUF_SIZE]);
3347c478bd9Sstevel@tonic-gate cp = in;
3357c478bd9Sstevel@tonic-gate op = out;
3367c478bd9Sstevel@tonic-gate matched = 0;
3377c478bd9Sstevel@tonic-gate do {
3387c478bd9Sstevel@tonic-gate if (step(cp, regexp_buffer)) {
3397c478bd9Sstevel@tonic-gate sdispl = (size_t) (loc1 - cp);
3407c478bd9Sstevel@tonic-gate edispl = (size_t) (loc2 - cp);
3417c478bd9Sstevel@tonic-gate if (sdispl) {
3427c478bd9Sstevel@tonic-gate use_bytes(sdispl);
3437c478bd9Sstevel@tonic-gate strncpy(op, cp, sdispl);
3447c478bd9Sstevel@tonic-gate op += sdispl;
3457c478bd9Sstevel@tonic-gate }
3467c478bd9Sstevel@tonic-gate use_bytes(strlen(repl));
3477c478bd9Sstevel@tonic-gate strncpy(op, repl, MAX_FORMAT_BUFFER - 1 - (op - out));
3487c478bd9Sstevel@tonic-gate op += strlen(repl);
3497c478bd9Sstevel@tonic-gate cp += edispl;
3507c478bd9Sstevel@tonic-gate if (!doall) {
3517c478bd9Sstevel@tonic-gate use_bytes(strlen(cp));
3527c478bd9Sstevel@tonic-gate strncpy(op, cp, MAX_FORMAT_BUFFER - 1 - (op - out));
3537c478bd9Sstevel@tonic-gate }
3547c478bd9Sstevel@tonic-gate matched = 1;
3557c478bd9Sstevel@tonic-gate }
3567c478bd9Sstevel@tonic-gate else {
3577c478bd9Sstevel@tonic-gate use_bytes(strlen(cp));
3587c478bd9Sstevel@tonic-gate strncpy(op, cp, MAX_FORMAT_BUFFER - 1 - (op - out));
3597c478bd9Sstevel@tonic-gate matched = 0;
3607c478bd9Sstevel@tonic-gate }
3617c478bd9Sstevel@tonic-gate } while (doall && matched);
3627c478bd9Sstevel@tonic-gate #else /* HAVE_REGEXP_H */
3637c478bd9Sstevel@tonic-gate memcpy(out, in, MAX_FORMAT_BUFFER);
3647c478bd9Sstevel@tonic-gate #endif /* HAVE_REGCOMP */
3657c478bd9Sstevel@tonic-gate return 1;
3667c478bd9Sstevel@tonic-gate mem_err:
3677c478bd9Sstevel@tonic-gate #ifdef HAVE_REGCMP
3687c478bd9Sstevel@tonic-gate regfree(&match_exp);
3697c478bd9Sstevel@tonic-gate #endif
3707c478bd9Sstevel@tonic-gate return 0;
3717c478bd9Sstevel@tonic-gate
3727c478bd9Sstevel@tonic-gate }
3737c478bd9Sstevel@tonic-gate #undef use_bytes
3747c478bd9Sstevel@tonic-gate
3757c478bd9Sstevel@tonic-gate /*
3767c478bd9Sstevel@tonic-gate * aname_replacer() - Perform the specified substitutions on the input
3777c478bd9Sstevel@tonic-gate * string and return the result.
3787c478bd9Sstevel@tonic-gate *
3797c478bd9Sstevel@tonic-gate * This routine enforces the "s/<pattern>/<replacement>/[g]" syntax.
3807c478bd9Sstevel@tonic-gate */
3817c478bd9Sstevel@tonic-gate static krb5_error_code
aname_replacer(char * string,char ** contextp,char ** result)3827c478bd9Sstevel@tonic-gate aname_replacer(char *string, char **contextp, char **result)
3837c478bd9Sstevel@tonic-gate {
3847c478bd9Sstevel@tonic-gate krb5_error_code kret;
3857c478bd9Sstevel@tonic-gate char *in;
3867c478bd9Sstevel@tonic-gate char *out;
3877c478bd9Sstevel@tonic-gate char *cp, *ep, *tp;
3887c478bd9Sstevel@tonic-gate char *rule, *repl;
3897c478bd9Sstevel@tonic-gate size_t rule_size, repl_size;
3907c478bd9Sstevel@tonic-gate int doglobal;
3917c478bd9Sstevel@tonic-gate char sep;
3927c478bd9Sstevel@tonic-gate
3937c478bd9Sstevel@tonic-gate kret = ENOMEM;
3947c478bd9Sstevel@tonic-gate *result = (char *) NULL;
3957c478bd9Sstevel@tonic-gate /* Allocate the formatting buffers */
396*159d09a2SMark Phalan /* Solaris Kerberos */
3977c478bd9Sstevel@tonic-gate if (((in = (char *) malloc(MAX_FORMAT_BUFFER)) != NULL) &&
3987c478bd9Sstevel@tonic-gate ((out = (char *) malloc(MAX_FORMAT_BUFFER)) != NULL)) {
3997c478bd9Sstevel@tonic-gate /*
4007c478bd9Sstevel@tonic-gate * Prime the buffers. Copy input string to "out" to simulate it
4017c478bd9Sstevel@tonic-gate * being the result of an initial iteration.
4027c478bd9Sstevel@tonic-gate */
4037c478bd9Sstevel@tonic-gate strncpy(out, string, MAX_FORMAT_BUFFER - 1);
4047c478bd9Sstevel@tonic-gate out[MAX_FORMAT_BUFFER - 1] = '\0';
4057c478bd9Sstevel@tonic-gate in[0] = '\0';
4067c478bd9Sstevel@tonic-gate kret = 0;
4077c478bd9Sstevel@tonic-gate /*
4087c478bd9Sstevel@tonic-gate * Pound through the expression until we're done.
4097c478bd9Sstevel@tonic-gate */
4107c478bd9Sstevel@tonic-gate for (cp = *contextp; *cp; ) {
4117c478bd9Sstevel@tonic-gate /* Skip leading whitespace */
412*159d09a2SMark Phalan while (isspace((int) (*cp)))
4137c478bd9Sstevel@tonic-gate cp++;
4147c478bd9Sstevel@tonic-gate
4157c478bd9Sstevel@tonic-gate /*
416*159d09a2SMark Phalan * Solaris Kerberos
4177c478bd9Sstevel@tonic-gate * Find our separators. First two characters must be "s<sep>"
4187c478bd9Sstevel@tonic-gate * We must also find another "<sep>" followed by another * "<sep>".
4197c478bd9Sstevel@tonic-gate */
4207c478bd9Sstevel@tonic-gate if (cp[0] != 's') {
4217c478bd9Sstevel@tonic-gate /* Bad syntax */
4227c478bd9Sstevel@tonic-gate kret = KRB5_CONFIG_BADFORMAT;
4237c478bd9Sstevel@tonic-gate break;
4247c478bd9Sstevel@tonic-gate }
4257c478bd9Sstevel@tonic-gate if (strspn(cp + 1, ",/;|!%") < 1) {
4267c478bd9Sstevel@tonic-gate /* Bad syntax */
4277c478bd9Sstevel@tonic-gate kret = KRB5_CONFIG_BADFORMAT;
4287c478bd9Sstevel@tonic-gate break;
4297c478bd9Sstevel@tonic-gate }
4307c478bd9Sstevel@tonic-gate sep = cp[1];
4317c478bd9Sstevel@tonic-gate
4327c478bd9Sstevel@tonic-gate if (((ep = strchr(&cp[2], sep)) != NULL) &&
4337c478bd9Sstevel@tonic-gate ((tp = strchr(&ep[1], sep)) != NULL)) {
4347c478bd9Sstevel@tonic-gate
4357c478bd9Sstevel@tonic-gate /* Figure out sizes of strings and allocate them */
4367c478bd9Sstevel@tonic-gate rule_size = (size_t) (ep - &cp[2]);
4377c478bd9Sstevel@tonic-gate repl_size = (size_t) (tp - &ep[1]);
438*159d09a2SMark Phalan /* Solaris Kerberos */
4397c478bd9Sstevel@tonic-gate if (((rule = (char *) malloc(rule_size+1)) != NULL) &&
4407c478bd9Sstevel@tonic-gate ((repl = (char *) malloc(repl_size+1)) != NULL)) {
4417c478bd9Sstevel@tonic-gate
4427c478bd9Sstevel@tonic-gate /* Copy the strings */
4437c478bd9Sstevel@tonic-gate strncpy(rule, &cp[2], rule_size);
4447c478bd9Sstevel@tonic-gate strncpy(repl, &ep[1], repl_size);
4457c478bd9Sstevel@tonic-gate rule[rule_size] = repl[repl_size] = '\0';
4467c478bd9Sstevel@tonic-gate
4477c478bd9Sstevel@tonic-gate /* Check for trailing "g" */
4487c478bd9Sstevel@tonic-gate doglobal = (tp[1] == 'g') ? 1 : 0;
4497c478bd9Sstevel@tonic-gate if (doglobal)
4507c478bd9Sstevel@tonic-gate tp++;
4517c478bd9Sstevel@tonic-gate
4527c478bd9Sstevel@tonic-gate /* Swap previous in and out buffers */
4537c478bd9Sstevel@tonic-gate ep = in;
4547c478bd9Sstevel@tonic-gate in = out;
4557c478bd9Sstevel@tonic-gate out = ep;
4567c478bd9Sstevel@tonic-gate
4577c478bd9Sstevel@tonic-gate /* Do the replacemenbt */
4587c478bd9Sstevel@tonic-gate memset(out, '\0', MAX_FORMAT_BUFFER);
4597c478bd9Sstevel@tonic-gate if (!do_replacement(rule, repl, doglobal, in, out)) {
4607c478bd9Sstevel@tonic-gate free(rule);
4617c478bd9Sstevel@tonic-gate free(repl);
4627c478bd9Sstevel@tonic-gate kret = KRB5_LNAME_NOTRANS;
4637c478bd9Sstevel@tonic-gate break;
4647c478bd9Sstevel@tonic-gate }
4657c478bd9Sstevel@tonic-gate free(rule);
4667c478bd9Sstevel@tonic-gate free(repl);
4677c478bd9Sstevel@tonic-gate
4687c478bd9Sstevel@tonic-gate /* If we have no output buffer left, this can't be good */
4697c478bd9Sstevel@tonic-gate if (strlen(out) == 0) {
4707c478bd9Sstevel@tonic-gate kret = KRB5_LNAME_NOTRANS;
4717c478bd9Sstevel@tonic-gate break;
4727c478bd9Sstevel@tonic-gate }
4737c478bd9Sstevel@tonic-gate }
4747c478bd9Sstevel@tonic-gate else {
4757c478bd9Sstevel@tonic-gate /* No memory for copies */
4767c478bd9Sstevel@tonic-gate kret = ENOMEM;
4777c478bd9Sstevel@tonic-gate break;
4787c478bd9Sstevel@tonic-gate }
4797c478bd9Sstevel@tonic-gate }
4807c478bd9Sstevel@tonic-gate else {
4817c478bd9Sstevel@tonic-gate /* Bad syntax */
4827c478bd9Sstevel@tonic-gate kret = KRB5_CONFIG_BADFORMAT;
4837c478bd9Sstevel@tonic-gate break;
4847c478bd9Sstevel@tonic-gate }
4857c478bd9Sstevel@tonic-gate /* Advance past trailer */
4867c478bd9Sstevel@tonic-gate cp = &tp[1];
4877c478bd9Sstevel@tonic-gate }
4887c478bd9Sstevel@tonic-gate free(in);
4897c478bd9Sstevel@tonic-gate if (!kret)
4907c478bd9Sstevel@tonic-gate *result = out;
4917c478bd9Sstevel@tonic-gate else
4927c478bd9Sstevel@tonic-gate free(out);
4937c478bd9Sstevel@tonic-gate }
4947c478bd9Sstevel@tonic-gate return(kret);
4957c478bd9Sstevel@tonic-gate }
4967c478bd9Sstevel@tonic-gate
4977c478bd9Sstevel@tonic-gate /*
4987c478bd9Sstevel@tonic-gate * rule_an_to_ln() - Handle aname to lname translations for RULE rules.
4997c478bd9Sstevel@tonic-gate *
5007c478bd9Sstevel@tonic-gate * The initial part of this routine handles the formulation of the strings from
5017c478bd9Sstevel@tonic-gate * the principal name.
5027c478bd9Sstevel@tonic-gate */
5037c478bd9Sstevel@tonic-gate static krb5_error_code
rule_an_to_ln(krb5_context context,char * rule,krb5_const_principal aname,const unsigned int lnsize,char * lname)504*159d09a2SMark Phalan rule_an_to_ln(krb5_context context, char *rule, krb5_const_principal aname, const unsigned int lnsize, char *lname)
5057c478bd9Sstevel@tonic-gate {
5067c478bd9Sstevel@tonic-gate krb5_error_code kret;
5077c478bd9Sstevel@tonic-gate char *current;
5087c478bd9Sstevel@tonic-gate char *fprincname;
5097c478bd9Sstevel@tonic-gate char *selstring = 0;
5107c478bd9Sstevel@tonic-gate int num_comps, compind;
5117c478bd9Sstevel@tonic-gate size_t selstring_used;
5127c478bd9Sstevel@tonic-gate char *cout;
5137c478bd9Sstevel@tonic-gate krb5_const krb5_data *datap;
5147c478bd9Sstevel@tonic-gate char *outstring;
5157c478bd9Sstevel@tonic-gate
5167c478bd9Sstevel@tonic-gate /*
5177c478bd9Sstevel@tonic-gate * First flatten the name.
5187c478bd9Sstevel@tonic-gate */
5197c478bd9Sstevel@tonic-gate current = rule;
5207c478bd9Sstevel@tonic-gate if (!(kret = krb5_unparse_name(context, aname, &fprincname))) {
5217c478bd9Sstevel@tonic-gate /*
5227c478bd9Sstevel@tonic-gate * First part.
5237c478bd9Sstevel@tonic-gate */
5247c478bd9Sstevel@tonic-gate if (*current == '[') {
5257c478bd9Sstevel@tonic-gate if (sscanf(current+1,"%d:", &num_comps) == 1) {
5267c478bd9Sstevel@tonic-gate if (num_comps == aname->length) {
5277c478bd9Sstevel@tonic-gate /*
5287c478bd9Sstevel@tonic-gate * We have a match based on the number of components.
5297c478bd9Sstevel@tonic-gate */
5307c478bd9Sstevel@tonic-gate current = strchr(current, ':');
5317c478bd9Sstevel@tonic-gate selstring = (char *) malloc(MAX_FORMAT_BUFFER);
5327c478bd9Sstevel@tonic-gate selstring_used = 0;
5337c478bd9Sstevel@tonic-gate if (current && selstring) {
5347c478bd9Sstevel@tonic-gate current++;
5357c478bd9Sstevel@tonic-gate cout = selstring;
5367c478bd9Sstevel@tonic-gate /*
5377c478bd9Sstevel@tonic-gate * Plow through the string.
5387c478bd9Sstevel@tonic-gate */
5397c478bd9Sstevel@tonic-gate while ((*current != ']') &&
5407c478bd9Sstevel@tonic-gate (*current != '\0')) {
5417c478bd9Sstevel@tonic-gate /*
5427c478bd9Sstevel@tonic-gate * Expand to a component.
5437c478bd9Sstevel@tonic-gate */
5447c478bd9Sstevel@tonic-gate if (*current == '$') {
5457c478bd9Sstevel@tonic-gate if ((sscanf(current+1, "%d", &compind) == 1) &&
5467c478bd9Sstevel@tonic-gate (compind <= num_comps) &&
547*159d09a2SMark Phalan (datap =
548*159d09a2SMark Phalan (compind > 0)
549*159d09a2SMark Phalan ? krb5_princ_component(context, aname,
550*159d09a2SMark Phalan compind-1)
551*159d09a2SMark Phalan : krb5_princ_realm(context, aname))
552*159d09a2SMark Phalan ) {
5537c478bd9Sstevel@tonic-gate if ((datap->length < MAX_FORMAT_BUFFER)
5547c478bd9Sstevel@tonic-gate && (selstring_used+datap->length
5557c478bd9Sstevel@tonic-gate < MAX_FORMAT_BUFFER)) {
5567c478bd9Sstevel@tonic-gate selstring_used += datap->length;
5577c478bd9Sstevel@tonic-gate } else {
558505d05c7Sgtb kret = ENOMEM;
5597c478bd9Sstevel@tonic-gate goto errout;
5607c478bd9Sstevel@tonic-gate }
5617c478bd9Sstevel@tonic-gate strncpy(cout,
5627c478bd9Sstevel@tonic-gate datap->data,
563505d05c7Sgtb (unsigned) datap->length);
5647c478bd9Sstevel@tonic-gate cout += datap->length;
5657c478bd9Sstevel@tonic-gate *cout = '\0';
5667c478bd9Sstevel@tonic-gate current++;
5677c478bd9Sstevel@tonic-gate /* Point past number */
568*159d09a2SMark Phalan while (isdigit((int) (*current)))
5697c478bd9Sstevel@tonic-gate current++;
5707c478bd9Sstevel@tonic-gate }
5717c478bd9Sstevel@tonic-gate else
5727c478bd9Sstevel@tonic-gate kret = KRB5_CONFIG_BADFORMAT;
5737c478bd9Sstevel@tonic-gate }
5747c478bd9Sstevel@tonic-gate else {
5757c478bd9Sstevel@tonic-gate /* Copy in verbatim. */
5767c478bd9Sstevel@tonic-gate *cout = *current;
5777c478bd9Sstevel@tonic-gate cout++;
5787c478bd9Sstevel@tonic-gate *cout = '\0';
5797c478bd9Sstevel@tonic-gate current++;
5807c478bd9Sstevel@tonic-gate }
5817c478bd9Sstevel@tonic-gate }
5827c478bd9Sstevel@tonic-gate
5837c478bd9Sstevel@tonic-gate /*
5847c478bd9Sstevel@tonic-gate * Advance past separator if appropriate.
5857c478bd9Sstevel@tonic-gate */
5867c478bd9Sstevel@tonic-gate if (*current == ']')
5877c478bd9Sstevel@tonic-gate current++;
5887c478bd9Sstevel@tonic-gate else
5897c478bd9Sstevel@tonic-gate kret = KRB5_CONFIG_BADFORMAT;
5907c478bd9Sstevel@tonic-gate
5917c478bd9Sstevel@tonic-gate errout: if (kret)
5927c478bd9Sstevel@tonic-gate free(selstring);
5937c478bd9Sstevel@tonic-gate }
5947c478bd9Sstevel@tonic-gate }
5957c478bd9Sstevel@tonic-gate else
5967c478bd9Sstevel@tonic-gate kret = KRB5_LNAME_NOTRANS;
5977c478bd9Sstevel@tonic-gate }
5987c478bd9Sstevel@tonic-gate else
5997c478bd9Sstevel@tonic-gate kret = KRB5_CONFIG_BADFORMAT;
6007c478bd9Sstevel@tonic-gate }
6017c478bd9Sstevel@tonic-gate else {
6027c478bd9Sstevel@tonic-gate if (!(selstring = aname_full_to_mapping_name(fprincname)))
6037c478bd9Sstevel@tonic-gate kret = ENOMEM;
6047c478bd9Sstevel@tonic-gate }
6057c478bd9Sstevel@tonic-gate krb5_xfree(fprincname);
6067c478bd9Sstevel@tonic-gate }
6077c478bd9Sstevel@tonic-gate if (!kret) {
6087c478bd9Sstevel@tonic-gate /*
6097c478bd9Sstevel@tonic-gate * Second part
6107c478bd9Sstevel@tonic-gate */
6117c478bd9Sstevel@tonic-gate if (*current == '(')
6127c478bd9Sstevel@tonic-gate kret = aname_do_match(selstring, ¤t);
6137c478bd9Sstevel@tonic-gate
6147c478bd9Sstevel@tonic-gate /*
6157c478bd9Sstevel@tonic-gate * Third part.
6167c478bd9Sstevel@tonic-gate */
6177c478bd9Sstevel@tonic-gate if (!kret) {
6187c478bd9Sstevel@tonic-gate outstring = (char *) NULL;
6197c478bd9Sstevel@tonic-gate kret = aname_replacer(selstring, ¤t, &outstring);
6207c478bd9Sstevel@tonic-gate if (outstring) {
6217c478bd9Sstevel@tonic-gate /* Copy out the value if there's enough room */
6227c478bd9Sstevel@tonic-gate if (strlen(outstring)+1 <= (size_t) lnsize)
6237c478bd9Sstevel@tonic-gate strcpy(lname, outstring);
6247c478bd9Sstevel@tonic-gate else
6257c478bd9Sstevel@tonic-gate kret = KRB5_CONFIG_NOTENUFSPACE;
6267c478bd9Sstevel@tonic-gate free(outstring);
6277c478bd9Sstevel@tonic-gate }
6287c478bd9Sstevel@tonic-gate }
6297c478bd9Sstevel@tonic-gate free(selstring);
6307c478bd9Sstevel@tonic-gate }
6317c478bd9Sstevel@tonic-gate
6327c478bd9Sstevel@tonic-gate return(kret);
6337c478bd9Sstevel@tonic-gate }
6347c478bd9Sstevel@tonic-gate #endif /* AN_TO_LN_RULES */
6357c478bd9Sstevel@tonic-gate
6367c478bd9Sstevel@tonic-gate /*
6377c478bd9Sstevel@tonic-gate * Solaris Kerberos
6387c478bd9Sstevel@tonic-gate * Return true (1) if the princ's realm matches any of the
6397c478bd9Sstevel@tonic-gate * 'auth_to_local_realm' relations in the default realm section.
6407c478bd9Sstevel@tonic-gate */
6417c478bd9Sstevel@tonic-gate static int
an_to_ln_realm_chk(krb5_context context,krb5_const_principal aname,char * def_realm,int realm_length)6427c478bd9Sstevel@tonic-gate an_to_ln_realm_chk(
6437c478bd9Sstevel@tonic-gate krb5_context context,
6447c478bd9Sstevel@tonic-gate krb5_const_principal aname,
6457c478bd9Sstevel@tonic-gate char *def_realm,
6467c478bd9Sstevel@tonic-gate int realm_length)
6477c478bd9Sstevel@tonic-gate {
6487c478bd9Sstevel@tonic-gate char **values, **cpp;
6497c478bd9Sstevel@tonic-gate const char *realm_names[4];
6507c478bd9Sstevel@tonic-gate krb5_error_code retval;
6517c478bd9Sstevel@tonic-gate
6527c478bd9Sstevel@tonic-gate realm_names[0] = "realms";
6537c478bd9Sstevel@tonic-gate realm_names[1] = def_realm;
6547c478bd9Sstevel@tonic-gate realm_names[2] = "auth_to_local_realm";
6557c478bd9Sstevel@tonic-gate realm_names[3] = 0;
6567c478bd9Sstevel@tonic-gate
6577c478bd9Sstevel@tonic-gate if (context->profile == 0)
6587c478bd9Sstevel@tonic-gate return (0);
6597c478bd9Sstevel@tonic-gate
6607c478bd9Sstevel@tonic-gate retval = profile_get_values(context->profile, realm_names,
6617c478bd9Sstevel@tonic-gate &values);
6627c478bd9Sstevel@tonic-gate if (retval)
6637c478bd9Sstevel@tonic-gate return (0);
6647c478bd9Sstevel@tonic-gate
6657c478bd9Sstevel@tonic-gate for (cpp = values; *cpp; cpp++) {
6667c478bd9Sstevel@tonic-gate
6677c478bd9Sstevel@tonic-gate if (((size_t) realm_length == strlen(*cpp)) &&
6687c478bd9Sstevel@tonic-gate (memcmp(*cpp, krb5_princ_realm(context, aname)->data,
6697c478bd9Sstevel@tonic-gate realm_length) == 0)) {
6707c478bd9Sstevel@tonic-gate
6717c478bd9Sstevel@tonic-gate profile_free_list(values);
6727c478bd9Sstevel@tonic-gate return (1); /* success */
6737c478bd9Sstevel@tonic-gate }
6747c478bd9Sstevel@tonic-gate }
6757c478bd9Sstevel@tonic-gate
6767c478bd9Sstevel@tonic-gate profile_free_list(values);
6777c478bd9Sstevel@tonic-gate return (0);
6787c478bd9Sstevel@tonic-gate }
6797c478bd9Sstevel@tonic-gate
6807c478bd9Sstevel@tonic-gate /*
6817c478bd9Sstevel@tonic-gate * Implementation: This version checks the realm to see if it is the local
6827c478bd9Sstevel@tonic-gate * realm; if so, and there is exactly one non-realm component to the name,
6837c478bd9Sstevel@tonic-gate * that name is returned as the lname.
6847c478bd9Sstevel@tonic-gate */
6857c478bd9Sstevel@tonic-gate static krb5_error_code
default_an_to_ln(krb5_context context,krb5_const_principal aname,const unsigned int lnsize,char * lname)686*159d09a2SMark Phalan default_an_to_ln(krb5_context context, krb5_const_principal aname, const unsigned int lnsize, char *lname)
6877c478bd9Sstevel@tonic-gate {
6887c478bd9Sstevel@tonic-gate krb5_error_code retval;
6897c478bd9Sstevel@tonic-gate char *def_realm;
690505d05c7Sgtb unsigned int realm_length;
6917c478bd9Sstevel@tonic-gate
6927c478bd9Sstevel@tonic-gate realm_length = krb5_princ_realm(context, aname)->length;
693*159d09a2SMark Phalan
6947c478bd9Sstevel@tonic-gate if ((retval = krb5_get_default_realm(context, &def_realm))) {
6957c478bd9Sstevel@tonic-gate return(retval);
6967c478bd9Sstevel@tonic-gate }
697*159d09a2SMark Phalan /* Solaris Kerberos */
6987c478bd9Sstevel@tonic-gate /* compare against default realm and auth_to_local_realm(s) */
6997c478bd9Sstevel@tonic-gate if ((((size_t) realm_length != strlen(def_realm)) ||
7007c478bd9Sstevel@tonic-gate (memcmp(def_realm, krb5_princ_realm(context, aname)->data,
7017c478bd9Sstevel@tonic-gate realm_length))) &&
7027c478bd9Sstevel@tonic-gate !an_to_ln_realm_chk(context, aname, def_realm,
7037c478bd9Sstevel@tonic-gate realm_length)) {
7047c478bd9Sstevel@tonic-gate free(def_realm);
7057c478bd9Sstevel@tonic-gate return KRB5_LNAME_NOTRANS;
7067c478bd9Sstevel@tonic-gate }
7077c478bd9Sstevel@tonic-gate
7087c478bd9Sstevel@tonic-gate if (krb5_princ_size(context, aname) != 1) {
7097c478bd9Sstevel@tonic-gate if (krb5_princ_size(context, aname) == 2 ) {
7107c478bd9Sstevel@tonic-gate /* Check to see if 2nd component is the local realm. */
711*159d09a2SMark Phalan if ( strncmp(krb5_princ_component(context, aname,1)->data,def_realm,
712*159d09a2SMark Phalan realm_length) ||
713*159d09a2SMark Phalan realm_length != krb5_princ_component(context, aname,1)->length) {
7147c478bd9Sstevel@tonic-gate /* XXX an_to_ln_realm_chk ? */
715*159d09a2SMark Phalan /* Solaris Kerberos */
716ab9b2e15Sgtb free(def_realm);
7177c478bd9Sstevel@tonic-gate return KRB5_LNAME_NOTRANS;
718ab9b2e15Sgtb }
7197c478bd9Sstevel@tonic-gate }
720ab9b2e15Sgtb else {
7217c478bd9Sstevel@tonic-gate /* no components or more than one component to non-realm part of name
7227c478bd9Sstevel@tonic-gate --no translation. */
723*159d09a2SMark Phalan /* Solaris Kerberos */
724ab9b2e15Sgtb free(def_realm);
7257c478bd9Sstevel@tonic-gate return KRB5_LNAME_NOTRANS;
726ab9b2e15Sgtb }
7277c478bd9Sstevel@tonic-gate }
7287c478bd9Sstevel@tonic-gate
7297c478bd9Sstevel@tonic-gate free(def_realm);
730*159d09a2SMark Phalan strncpy(lname, krb5_princ_component(context, aname,0)->data,
7317c478bd9Sstevel@tonic-gate min(krb5_princ_component(context, aname,0)->length,lnsize));
7327c478bd9Sstevel@tonic-gate if (lnsize <= krb5_princ_component(context, aname,0)->length ) {
7337c478bd9Sstevel@tonic-gate retval = KRB5_CONFIG_NOTENUFSPACE;
7347c478bd9Sstevel@tonic-gate } else {
7357c478bd9Sstevel@tonic-gate lname[krb5_princ_component(context, aname,0)->length] = '\0';
7367c478bd9Sstevel@tonic-gate retval = 0;
7377c478bd9Sstevel@tonic-gate }
7387c478bd9Sstevel@tonic-gate return retval;
7397c478bd9Sstevel@tonic-gate }
7407c478bd9Sstevel@tonic-gate
7417c478bd9Sstevel@tonic-gate /*
7427c478bd9Sstevel@tonic-gate Converts an authentication name to a local name suitable for use by
7437c478bd9Sstevel@tonic-gate programs wishing a translation to an environment-specific name (e.g.
7447c478bd9Sstevel@tonic-gate user account name).
7457c478bd9Sstevel@tonic-gate
7467c478bd9Sstevel@tonic-gate lnsize specifies the maximum length name that is to be filled into
7477c478bd9Sstevel@tonic-gate lname.
7487c478bd9Sstevel@tonic-gate The translation will be null terminated in all non-error returns.
7497c478bd9Sstevel@tonic-gate
7507c478bd9Sstevel@tonic-gate returns system errors, NOT_ENOUGH_SPACE
7517c478bd9Sstevel@tonic-gate */
7527c478bd9Sstevel@tonic-gate
753*159d09a2SMark Phalan krb5_error_code KRB5_CALLCONV
krb5_aname_to_localname(krb5_context context,krb5_const_principal aname,const int lnsize_in,char * lname)754*159d09a2SMark Phalan krb5_aname_to_localname(krb5_context context, krb5_const_principal aname, const int lnsize_in, char *lname)
7557c478bd9Sstevel@tonic-gate {
7567c478bd9Sstevel@tonic-gate krb5_error_code kret;
7577c478bd9Sstevel@tonic-gate char *realm;
7587c478bd9Sstevel@tonic-gate char *pname;
7597c478bd9Sstevel@tonic-gate char *mname;
7607c478bd9Sstevel@tonic-gate const char *hierarchy[5];
7617c478bd9Sstevel@tonic-gate char **mapping_values;
7627c478bd9Sstevel@tonic-gate int i, nvalid;
7637c478bd9Sstevel@tonic-gate char *cp, *s;
7647c478bd9Sstevel@tonic-gate char *typep, *argp;
765505d05c7Sgtb unsigned int lnsize;
7667c478bd9Sstevel@tonic-gate
767505d05c7Sgtb if (lnsize_in < 0)
768*159d09a2SMark Phalan return KRB5_CONFIG_NOTENUFSPACE;
7697c478bd9Sstevel@tonic-gate
770505d05c7Sgtb lnsize = lnsize_in; /* Unsigned */
771505d05c7Sgtb
7727c478bd9Sstevel@tonic-gate /*
7737c478bd9Sstevel@tonic-gate * First get the default realm.
7747c478bd9Sstevel@tonic-gate */
7757c478bd9Sstevel@tonic-gate if (!(kret = krb5_get_default_realm(context, &realm))) {
7767c478bd9Sstevel@tonic-gate /* Flatten the name */
7777c478bd9Sstevel@tonic-gate if (!(kret = krb5_unparse_name(context, aname, &pname))) {
7787c478bd9Sstevel@tonic-gate if ((mname = aname_full_to_mapping_name(pname))) {
7797c478bd9Sstevel@tonic-gate /*
7807c478bd9Sstevel@tonic-gate * Search first for explicit mappings of the form:
7817c478bd9Sstevel@tonic-gate *
7827c478bd9Sstevel@tonic-gate * [realms]->realm->"auth_to_local_names"->mapping_name
7837c478bd9Sstevel@tonic-gate */
7847c478bd9Sstevel@tonic-gate hierarchy[0] = "realms";
7857c478bd9Sstevel@tonic-gate hierarchy[1] = realm;
7867c478bd9Sstevel@tonic-gate hierarchy[2] = "auth_to_local_names";
7877c478bd9Sstevel@tonic-gate hierarchy[3] = mname;
7887c478bd9Sstevel@tonic-gate hierarchy[4] = (char *) NULL;
7897c478bd9Sstevel@tonic-gate if (!(kret = profile_get_values(context->profile,
7907c478bd9Sstevel@tonic-gate hierarchy,
7917c478bd9Sstevel@tonic-gate &mapping_values))) {
7927c478bd9Sstevel@tonic-gate /* We found one or more explicit mappings. */
7937c478bd9Sstevel@tonic-gate for (nvalid=0; mapping_values[nvalid]; nvalid++);
7947c478bd9Sstevel@tonic-gate
7957c478bd9Sstevel@tonic-gate /* Just use the last one. */
7967c478bd9Sstevel@tonic-gate /* Trim the value. */
7977c478bd9Sstevel@tonic-gate s = mapping_values[nvalid-1];
7987c478bd9Sstevel@tonic-gate cp = s + strlen(s);
7997c478bd9Sstevel@tonic-gate while (cp > s) {
8007c478bd9Sstevel@tonic-gate cp--;
8017c478bd9Sstevel@tonic-gate if (!isspace((int)(*cp)))
8027c478bd9Sstevel@tonic-gate break;
8037c478bd9Sstevel@tonic-gate *cp = '\0';
8047c478bd9Sstevel@tonic-gate }
8057c478bd9Sstevel@tonic-gate
8067c478bd9Sstevel@tonic-gate /* Copy out the value if there's enough room */
8077c478bd9Sstevel@tonic-gate if (strlen(mapping_values[nvalid-1])+1 <= (size_t) lnsize)
8087c478bd9Sstevel@tonic-gate strcpy(lname, mapping_values[nvalid-1]);
8097c478bd9Sstevel@tonic-gate else
8107c478bd9Sstevel@tonic-gate kret = KRB5_CONFIG_NOTENUFSPACE;
8117c478bd9Sstevel@tonic-gate
8127c478bd9Sstevel@tonic-gate /* Free residue */
8137c478bd9Sstevel@tonic-gate profile_free_list(mapping_values);
8147c478bd9Sstevel@tonic-gate }
8157c478bd9Sstevel@tonic-gate else {
8167c478bd9Sstevel@tonic-gate /*
8177c478bd9Sstevel@tonic-gate * OK - There's no explicit mapping. Now check for
8187c478bd9Sstevel@tonic-gate * general auth_to_local rules of the form:
8197c478bd9Sstevel@tonic-gate *
8207c478bd9Sstevel@tonic-gate * [realms]->realm->"auth_to_local"
8217c478bd9Sstevel@tonic-gate *
8227c478bd9Sstevel@tonic-gate * This can have one or more of the following kinds of
8237c478bd9Sstevel@tonic-gate * values:
8247c478bd9Sstevel@tonic-gate * DB:<filename> - Look up principal in aname database.
8257c478bd9Sstevel@tonic-gate * RULE:<sed-exp> - Formulate lname from sed-exp.
8267c478bd9Sstevel@tonic-gate * DEFAULT - Use default rule.
8277c478bd9Sstevel@tonic-gate * The first rule to find a match is used.
8287c478bd9Sstevel@tonic-gate */
8297c478bd9Sstevel@tonic-gate hierarchy[0] = "realms";
8307c478bd9Sstevel@tonic-gate hierarchy[1] = realm;
8317c478bd9Sstevel@tonic-gate hierarchy[2] = "auth_to_local";
8327c478bd9Sstevel@tonic-gate hierarchy[3] = (char *) NULL;
8337c478bd9Sstevel@tonic-gate if (!(kret = profile_get_values(context->profile,
8347c478bd9Sstevel@tonic-gate hierarchy,
8357c478bd9Sstevel@tonic-gate &mapping_values))) {
8367c478bd9Sstevel@tonic-gate /*
8377c478bd9Sstevel@tonic-gate * Loop through all the mapping values.
8387c478bd9Sstevel@tonic-gate */
8397c478bd9Sstevel@tonic-gate for (i=0; mapping_values[i]; i++) {
8407c478bd9Sstevel@tonic-gate typep = mapping_values[i];
8417c478bd9Sstevel@tonic-gate argp = strchr(typep, ':');
8427c478bd9Sstevel@tonic-gate if (argp) {
8437c478bd9Sstevel@tonic-gate *argp = '\0';
8447c478bd9Sstevel@tonic-gate argp++;
8457c478bd9Sstevel@tonic-gate }
8467c478bd9Sstevel@tonic-gate #ifdef ANAME_DB
8477c478bd9Sstevel@tonic-gate if (!strcmp(typep, "DB") && argp) {
8487c478bd9Sstevel@tonic-gate kret = db_an_to_ln(context,
8497c478bd9Sstevel@tonic-gate argp,
8507c478bd9Sstevel@tonic-gate aname,
8517c478bd9Sstevel@tonic-gate lnsize,
8527c478bd9Sstevel@tonic-gate lname);
8537c478bd9Sstevel@tonic-gate if (kret != KRB5_LNAME_NOTRANS)
8547c478bd9Sstevel@tonic-gate break;
8557c478bd9Sstevel@tonic-gate }
8567c478bd9Sstevel@tonic-gate else
8577c478bd9Sstevel@tonic-gate #endif
8587c478bd9Sstevel@tonic-gate #ifdef AN_TO_LN_RULES
8597c478bd9Sstevel@tonic-gate if (!strcmp(typep, "RULE") && argp) {
8607c478bd9Sstevel@tonic-gate kret = rule_an_to_ln(context,
8617c478bd9Sstevel@tonic-gate argp,
8627c478bd9Sstevel@tonic-gate aname,
8637c478bd9Sstevel@tonic-gate lnsize,
8647c478bd9Sstevel@tonic-gate lname);
8657c478bd9Sstevel@tonic-gate if (kret != KRB5_LNAME_NOTRANS)
8667c478bd9Sstevel@tonic-gate break;
8677c478bd9Sstevel@tonic-gate }
8687c478bd9Sstevel@tonic-gate else
8697c478bd9Sstevel@tonic-gate #endif /* AN_TO_LN_RULES */
8707c478bd9Sstevel@tonic-gate if (!strcmp(typep, "DEFAULT") && !argp) {
8717c478bd9Sstevel@tonic-gate kret = default_an_to_ln(context,
8727c478bd9Sstevel@tonic-gate aname,
8737c478bd9Sstevel@tonic-gate lnsize,
8747c478bd9Sstevel@tonic-gate lname);
8757c478bd9Sstevel@tonic-gate if (kret != KRB5_LNAME_NOTRANS)
8767c478bd9Sstevel@tonic-gate break;
8777c478bd9Sstevel@tonic-gate }
8787c478bd9Sstevel@tonic-gate else {
8797c478bd9Sstevel@tonic-gate kret = KRB5_CONFIG_BADFORMAT;
8807c478bd9Sstevel@tonic-gate break;
8817c478bd9Sstevel@tonic-gate }
8827c478bd9Sstevel@tonic-gate }
8837c478bd9Sstevel@tonic-gate
8847c478bd9Sstevel@tonic-gate /* We're done, clean up the droppings. */
8857c478bd9Sstevel@tonic-gate profile_free_list(mapping_values);
8867c478bd9Sstevel@tonic-gate }
8877c478bd9Sstevel@tonic-gate else {
8887c478bd9Sstevel@tonic-gate /*
8897c478bd9Sstevel@tonic-gate * No profile relation found, try default mapping.
8907c478bd9Sstevel@tonic-gate */
8917c478bd9Sstevel@tonic-gate kret = default_an_to_ln(context,
8927c478bd9Sstevel@tonic-gate aname,
8937c478bd9Sstevel@tonic-gate lnsize,
8947c478bd9Sstevel@tonic-gate lname);
8957c478bd9Sstevel@tonic-gate }
8967c478bd9Sstevel@tonic-gate }
8977c478bd9Sstevel@tonic-gate free(mname);
8987c478bd9Sstevel@tonic-gate }
8997c478bd9Sstevel@tonic-gate else
9007c478bd9Sstevel@tonic-gate kret = ENOMEM;
9017c478bd9Sstevel@tonic-gate krb5_xfree(pname);
9027c478bd9Sstevel@tonic-gate }
9037c478bd9Sstevel@tonic-gate krb5_xfree(realm);
9047c478bd9Sstevel@tonic-gate }
9057c478bd9Sstevel@tonic-gate return(kret);
9067c478bd9Sstevel@tonic-gate }
907*159d09a2SMark Phalan
908