1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 4*7c478bd9Sstevel@tonic-gate */ 5*7c478bd9Sstevel@tonic-gate 6*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 7*7c478bd9Sstevel@tonic-gate 8*7c478bd9Sstevel@tonic-gate /* 9*7c478bd9Sstevel@tonic-gate * lib/krb5/os/an_to_ln.c 10*7c478bd9Sstevel@tonic-gate * 11*7c478bd9Sstevel@tonic-gate * Copyright 1990,1991 by the Massachusetts Institute of Technology. 12*7c478bd9Sstevel@tonic-gate * All Rights Reserved. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may 15*7c478bd9Sstevel@tonic-gate * require a specific license from the United States Government. 16*7c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating 17*7c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting. 18*7c478bd9Sstevel@tonic-gate * 19*7c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 20*7c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 21*7c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 22*7c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 23*7c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 24*7c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining 25*7c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior 26*7c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label 27*7c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a 28*7c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software. 29*7c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of 30*7c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 31*7c478bd9Sstevel@tonic-gate * or implied warranty. 32*7c478bd9Sstevel@tonic-gate * 33*7c478bd9Sstevel@tonic-gate * 34*7c478bd9Sstevel@tonic-gate * krb5_aname_to_localname() 35*7c478bd9Sstevel@tonic-gate */ 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate /* 39*7c478bd9Sstevel@tonic-gate * We're only to AN_TO_LN rules at this point, and not doing the 40*7c478bd9Sstevel@tonic-gate * database lookup (moved from configure script) 41*7c478bd9Sstevel@tonic-gate */ 42*7c478bd9Sstevel@tonic-gate #ifndef AN_TO_LN_RULES 43*7c478bd9Sstevel@tonic-gate #define AN_TO_LN_RULES 44*7c478bd9Sstevel@tonic-gate #endif 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate #include <k5-int.h> 47*7c478bd9Sstevel@tonic-gate #include <ctype.h> 48*7c478bd9Sstevel@tonic-gate #if HAVE_REGEX_H 49*7c478bd9Sstevel@tonic-gate #include <regex.h> 50*7c478bd9Sstevel@tonic-gate #endif /* HAVE_REGEX_H */ 51*7c478bd9Sstevel@tonic-gate /* 52*7c478bd9Sstevel@tonic-gate * Use compile(3) if no regcomp present. 53*7c478bd9Sstevel@tonic-gate */ 54*7c478bd9Sstevel@tonic-gate #if !defined(HAVE_REGCOMP) && defined(HAVE_REGEXPR_H) && defined(HAVE_COMPILE) 55*7c478bd9Sstevel@tonic-gate #define RE_BUF_SIZE 1024 56*7c478bd9Sstevel@tonic-gate #include <regexpr.h> 57*7c478bd9Sstevel@tonic-gate #endif /* !HAVE_REGCOMP && HAVE_REGEXP_H && HAVE_COMPILE */ 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate #define MAX_FORMAT_BUFFER 1024 60*7c478bd9Sstevel@tonic-gate #ifndef min 61*7c478bd9Sstevel@tonic-gate #define min(a,b) ((a>b) ? b : a) 62*7c478bd9Sstevel@tonic-gate #endif /* min */ 63*7c478bd9Sstevel@tonic-gate #ifdef ANAME_DB 64*7c478bd9Sstevel@tonic-gate /* 65*7c478bd9Sstevel@tonic-gate * Use standard DBM code. 66*7c478bd9Sstevel@tonic-gate */ 67*7c478bd9Sstevel@tonic-gate #define KDBM_OPEN(db, fl, mo) dbm_open(db, fl, mo) 68*7c478bd9Sstevel@tonic-gate #define KDBM_CLOSE(db) dbm_close(db) 69*7c478bd9Sstevel@tonic-gate #define KDBM_FETCH(db, key) dbm_fetch(db, key) 70*7c478bd9Sstevel@tonic-gate #else /*ANAME_DB*/ 71*7c478bd9Sstevel@tonic-gate extern DBM *db_dbm_open KRB5_PROTOTYPE((char *, int, int)); 72*7c478bd9Sstevel@tonic-gate extern void db_dbm_close KRB5_PROTOTYPE((DBM *)); 73*7c478bd9Sstevel@tonic-gate extern datum db_dbm_fetch KRB5_PROTOTYPE((DBM *, datum)); 74*7c478bd9Sstevel@tonic-gate #define KDBM_OPEN(db, fl, mo) db_dbm_open(db, fl, mo) 75*7c478bd9Sstevel@tonic-gate #define KDBM_CLOSE(db) db_dbm_close(db) 76*7c478bd9Sstevel@tonic-gate #define KDBM_FETCH(db, key) db_dbm_fetch(db, key) 77*7c478bd9Sstevel@tonic-gate #endif /*ANAME_DB*/ 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate /* 80*7c478bd9Sstevel@tonic-gate * Find the portion of the flattened principal name that we use for mapping. 81*7c478bd9Sstevel@tonic-gate */ 82*7c478bd9Sstevel@tonic-gate static char * 83*7c478bd9Sstevel@tonic-gate aname_full_to_mapping_name(char *fprincname) 84*7c478bd9Sstevel@tonic-gate { 85*7c478bd9Sstevel@tonic-gate char *atp; 86*7c478bd9Sstevel@tonic-gate size_t mlen; 87*7c478bd9Sstevel@tonic-gate char *mname; 88*7c478bd9Sstevel@tonic-gate 89*7c478bd9Sstevel@tonic-gate mname = (char *) NULL; 90*7c478bd9Sstevel@tonic-gate if (fprincname) { 91*7c478bd9Sstevel@tonic-gate atp = strrchr(fprincname, '@'); 92*7c478bd9Sstevel@tonic-gate if (!atp) 93*7c478bd9Sstevel@tonic-gate atp = &fprincname[strlen(fprincname)]; 94*7c478bd9Sstevel@tonic-gate mlen = (size_t) (atp - fprincname); 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate if ((mname = (char *) malloc(mlen+1))) { 97*7c478bd9Sstevel@tonic-gate strncpy(mname, fprincname, mlen); 98*7c478bd9Sstevel@tonic-gate mname[mlen] = '\0'; 99*7c478bd9Sstevel@tonic-gate } 100*7c478bd9Sstevel@tonic-gate } 101*7c478bd9Sstevel@tonic-gate return(mname); 102*7c478bd9Sstevel@tonic-gate } 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate #ifdef ANAME_DB 105*7c478bd9Sstevel@tonic-gate /* 106*7c478bd9Sstevel@tonic-gate * Implementation: This version uses a DBM database, indexed by aname, 107*7c478bd9Sstevel@tonic-gate * to generate a lname. 108*7c478bd9Sstevel@tonic-gate * 109*7c478bd9Sstevel@tonic-gate * The entries in the database are normal C strings, and include the trailing 110*7c478bd9Sstevel@tonic-gate * null in the DBM datum.size. 111*7c478bd9Sstevel@tonic-gate */ 112*7c478bd9Sstevel@tonic-gate static krb5_error_code 113*7c478bd9Sstevel@tonic-gate db_an_to_ln(context, dbname, aname, lnsize, lname) 114*7c478bd9Sstevel@tonic-gate krb5_context context; 115*7c478bd9Sstevel@tonic-gate char *dbname; 116*7c478bd9Sstevel@tonic-gate krb5_const_principal aname; 117*7c478bd9Sstevel@tonic-gate const int lnsize; 118*7c478bd9Sstevel@tonic-gate char *lname; 119*7c478bd9Sstevel@tonic-gate { 120*7c478bd9Sstevel@tonic-gate #if (!defined(_MSDOS) && !defined(_WIN32) && !defined(macintosh)) 121*7c478bd9Sstevel@tonic-gate DBM *db; 122*7c478bd9Sstevel@tonic-gate krb5_error_code retval; 123*7c478bd9Sstevel@tonic-gate datum key, contents; 124*7c478bd9Sstevel@tonic-gate char *princ_name; 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate if ((retval = krb5_unparse_name(context, aname, &princ_name))) 127*7c478bd9Sstevel@tonic-gate return(retval); 128*7c478bd9Sstevel@tonic-gate key.dptr = princ_name; 129*7c478bd9Sstevel@tonic-gate key.dsize = strlen(princ_name)+1; /* need to store the NULL for 130*7c478bd9Sstevel@tonic-gate decoding */ 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate db = KDBM_OPEN(dbname, O_RDONLY, 0600); 133*7c478bd9Sstevel@tonic-gate if (!db) { 134*7c478bd9Sstevel@tonic-gate krb5_xfree(princ_name); 135*7c478bd9Sstevel@tonic-gate return KRB5_LNAME_CANTOPEN; 136*7c478bd9Sstevel@tonic-gate } 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate contents = KDBM_FETCH(db, key); 139*7c478bd9Sstevel@tonic-gate 140*7c478bd9Sstevel@tonic-gate krb5_xfree(princ_name); 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate if (contents.dptr == NULL) { 143*7c478bd9Sstevel@tonic-gate retval = KRB5_LNAME_NOTRANS; 144*7c478bd9Sstevel@tonic-gate } else { 145*7c478bd9Sstevel@tonic-gate strncpy(lname, contents.dptr, lnsize); 146*7c478bd9Sstevel@tonic-gate if (lnsize < contents.dsize) 147*7c478bd9Sstevel@tonic-gate retval = KRB5_CONFIG_NOTENUFSPACE; 148*7c478bd9Sstevel@tonic-gate else if (lname[contents.dsize-1] != '\0') 149*7c478bd9Sstevel@tonic-gate retval = KRB5_LNAME_BADFORMAT; 150*7c478bd9Sstevel@tonic-gate else 151*7c478bd9Sstevel@tonic-gate retval = 0; 152*7c478bd9Sstevel@tonic-gate } 153*7c478bd9Sstevel@tonic-gate /* can't close until we copy the contents. */ 154*7c478bd9Sstevel@tonic-gate (void) KDBM_CLOSE(db); 155*7c478bd9Sstevel@tonic-gate return retval; 156*7c478bd9Sstevel@tonic-gate #else /* !_MSDOS && !_WIN32 && !MACINTOSH */ 157*7c478bd9Sstevel@tonic-gate /* 158*7c478bd9Sstevel@tonic-gate * If we don't have support for a database mechanism, then we can't 159*7c478bd9Sstevel@tonic-gate * translate this now, can we? 160*7c478bd9Sstevel@tonic-gate */ 161*7c478bd9Sstevel@tonic-gate return KRB5_LNAME_NOTRANS; 162*7c478bd9Sstevel@tonic-gate #endif /* !_MSDOS && !_WIN32 && !MACINTOSH */ 163*7c478bd9Sstevel@tonic-gate } 164*7c478bd9Sstevel@tonic-gate #endif /*ANAME_DB*/ 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate #ifdef AN_TO_LN_RULES 167*7c478bd9Sstevel@tonic-gate /* 168*7c478bd9Sstevel@tonic-gate * Format and transform a principal name to a local name. This is particularly 169*7c478bd9Sstevel@tonic-gate * useful when Kerberos principals and local user names are formatted to 170*7c478bd9Sstevel@tonic-gate * some particular convention. 171*7c478bd9Sstevel@tonic-gate * 172*7c478bd9Sstevel@tonic-gate * There are three parts to each rule: 173*7c478bd9Sstevel@tonic-gate * First part - formulate the string to perform operations on: If not present 174*7c478bd9Sstevel@tonic-gate * then the string defaults to the fully flattened principal minus the realm 175*7c478bd9Sstevel@tonic-gate * name. Otherwise the syntax is as follows: 176*7c478bd9Sstevel@tonic-gate * "[" <ncomps> ":" <format> "]" 177*7c478bd9Sstevel@tonic-gate * Where: 178*7c478bd9Sstevel@tonic-gate * <ncomps> is the number of expected components for this 179*7c478bd9Sstevel@tonic-gate * rule. If the particular principal does not have this 180*7c478bd9Sstevel@tonic-gate * many components, then this rule does not apply. 181*7c478bd9Sstevel@tonic-gate * 182*7c478bd9Sstevel@tonic-gate * <format> is a string of <component> or verbatim 183*7c478bd9Sstevel@tonic-gate * characters to be inserted. 184*7c478bd9Sstevel@tonic-gate * 185*7c478bd9Sstevel@tonic-gate * <component> is of the form "$"<number> to select the 186*7c478bd9Sstevel@tonic-gate * <number>th component. <number> begins from 1. 187*7c478bd9Sstevel@tonic-gate * 188*7c478bd9Sstevel@tonic-gate * Second part - select rule validity: If not present, then this rule may 189*7c478bd9Sstevel@tonic-gate * apply to all selections. Otherwise the syntax is as follows: 190*7c478bd9Sstevel@tonic-gate * "(" <regexp> ")" 191*7c478bd9Sstevel@tonic-gate * Where: <regexp> is a selector regular expression. If this 192*7c478bd9Sstevel@tonic-gate * regular expression matches the whole pattern generated 193*7c478bd9Sstevel@tonic-gate * from the first part, then this rule still applies. 194*7c478bd9Sstevel@tonic-gate * 195*7c478bd9Sstevel@tonic-gate * Last part - Transform rule: If not present, then the selection string 196*7c478bd9Sstevel@tonic-gate * is passed verbatim and is matched. Otherwise, the syntax is as follows: 197*7c478bd9Sstevel@tonic-gate * <rule> ... 198*7c478bd9Sstevel@tonic-gate * Where: <rule> is of the form: 199*7c478bd9Sstevel@tonic-gate * "s/" <regexp> "/" <text> "/" ["g"] 200*7c478bd9Sstevel@tonic-gate * 201*7c478bd9Sstevel@tonic-gate * In order to be able to select rule validity, the native system must support 202*7c478bd9Sstevel@tonic-gate * one of compile(3), re_comp(3) or regcomp(3). In order to be able to 203*7c478bd9Sstevel@tonic-gate * transform (e.g. substitute), the native system must support regcomp(3) or 204*7c478bd9Sstevel@tonic-gate * compile(3). 205*7c478bd9Sstevel@tonic-gate */ 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate /* 208*7c478bd9Sstevel@tonic-gate * aname_do_match() - Does our name match the parenthesized regular 209*7c478bd9Sstevel@tonic-gate * expression? 210*7c478bd9Sstevel@tonic-gate * 211*7c478bd9Sstevel@tonic-gate * Chew up the match portion of the regular expression and update *contextp. 212*7c478bd9Sstevel@tonic-gate * If no re_comp() or regcomp(), then always return a match. 213*7c478bd9Sstevel@tonic-gate */ 214*7c478bd9Sstevel@tonic-gate static krb5_error_code 215*7c478bd9Sstevel@tonic-gate aname_do_match(char *string, char **contextp) 216*7c478bd9Sstevel@tonic-gate { 217*7c478bd9Sstevel@tonic-gate krb5_error_code kret; 218*7c478bd9Sstevel@tonic-gate char *regexp, *startp, *endp = 0; 219*7c478bd9Sstevel@tonic-gate size_t regexlen; 220*7c478bd9Sstevel@tonic-gate #if HAVE_REGCOMP 221*7c478bd9Sstevel@tonic-gate regex_t match_exp; 222*7c478bd9Sstevel@tonic-gate regmatch_t match_match; 223*7c478bd9Sstevel@tonic-gate #elif HAVE_REGEXPR_H 224*7c478bd9Sstevel@tonic-gate char regexp_buffer[RE_BUF_SIZE]; 225*7c478bd9Sstevel@tonic-gate #endif /* HAVE_REGEXP_H */ 226*7c478bd9Sstevel@tonic-gate 227*7c478bd9Sstevel@tonic-gate kret = 0; 228*7c478bd9Sstevel@tonic-gate /* 229*7c478bd9Sstevel@tonic-gate * Is this a match expression? 230*7c478bd9Sstevel@tonic-gate */ 231*7c478bd9Sstevel@tonic-gate if (**contextp == '(') { 232*7c478bd9Sstevel@tonic-gate kret = KRB5_CONFIG_BADFORMAT; 233*7c478bd9Sstevel@tonic-gate startp = (*contextp) + 1; 234*7c478bd9Sstevel@tonic-gate endp = strchr(startp, ')'); 235*7c478bd9Sstevel@tonic-gate /* Find the end of the match expression. */ 236*7c478bd9Sstevel@tonic-gate if (endp) { 237*7c478bd9Sstevel@tonic-gate regexlen = (size_t) (endp - startp); 238*7c478bd9Sstevel@tonic-gate regexp = (char *) malloc((size_t) regexlen+1); 239*7c478bd9Sstevel@tonic-gate kret = ENOMEM; 240*7c478bd9Sstevel@tonic-gate if (regexp) { 241*7c478bd9Sstevel@tonic-gate strncpy(regexp, startp, regexlen); 242*7c478bd9Sstevel@tonic-gate regexp[regexlen] = '\0'; 243*7c478bd9Sstevel@tonic-gate kret = KRB5_LNAME_NOTRANS; 244*7c478bd9Sstevel@tonic-gate /* 245*7c478bd9Sstevel@tonic-gate * Perform the match. 246*7c478bd9Sstevel@tonic-gate */ 247*7c478bd9Sstevel@tonic-gate #if HAVE_REGCOMP 248*7c478bd9Sstevel@tonic-gate if (!regcomp(&match_exp, regexp, REG_EXTENDED) && 249*7c478bd9Sstevel@tonic-gate !regexec(&match_exp, string, 1, &match_match, 0)) { 250*7c478bd9Sstevel@tonic-gate if ((match_match.rm_so == 0) && 251*7c478bd9Sstevel@tonic-gate (match_match.rm_eo == strlen(string))) 252*7c478bd9Sstevel@tonic-gate kret = 0; 253*7c478bd9Sstevel@tonic-gate } 254*7c478bd9Sstevel@tonic-gate regfree(&match_exp); 255*7c478bd9Sstevel@tonic-gate #elif HAVE_REGEXPR_H 256*7c478bd9Sstevel@tonic-gate compile(regexp, 257*7c478bd9Sstevel@tonic-gate regexp_buffer, 258*7c478bd9Sstevel@tonic-gate ®exp_buffer[RE_BUF_SIZE], 259*7c478bd9Sstevel@tonic-gate '\0'); 260*7c478bd9Sstevel@tonic-gate if (step(string, regexp_buffer)) { 261*7c478bd9Sstevel@tonic-gate if ((loc1 == string) && 262*7c478bd9Sstevel@tonic-gate (loc2 == &string[strlen(string)])) 263*7c478bd9Sstevel@tonic-gate kret = 0; 264*7c478bd9Sstevel@tonic-gate } 265*7c478bd9Sstevel@tonic-gate #elif HAVE_RE_COMP 266*7c478bd9Sstevel@tonic-gate if (!re_comp(regexp) && re_exec(string)) 267*7c478bd9Sstevel@tonic-gate kret = 0; 268*7c478bd9Sstevel@tonic-gate #else /* HAVE_RE_COMP */ 269*7c478bd9Sstevel@tonic-gate kret = 0; 270*7c478bd9Sstevel@tonic-gate #endif /* HAVE_RE_COMP */ 271*7c478bd9Sstevel@tonic-gate free(regexp); 272*7c478bd9Sstevel@tonic-gate } 273*7c478bd9Sstevel@tonic-gate endp++; 274*7c478bd9Sstevel@tonic-gate } 275*7c478bd9Sstevel@tonic-gate else 276*7c478bd9Sstevel@tonic-gate endp = startp; 277*7c478bd9Sstevel@tonic-gate } 278*7c478bd9Sstevel@tonic-gate *contextp = endp; 279*7c478bd9Sstevel@tonic-gate return(kret); 280*7c478bd9Sstevel@tonic-gate } 281*7c478bd9Sstevel@tonic-gate 282*7c478bd9Sstevel@tonic-gate /* 283*7c478bd9Sstevel@tonic-gate * do_replacement() - Replace the regular expression with the specified 284*7c478bd9Sstevel@tonic-gate * replacement. 285*7c478bd9Sstevel@tonic-gate * 286*7c478bd9Sstevel@tonic-gate * If "doall" is set, it's a global replacement, otherwise, just a oneshot 287*7c478bd9Sstevel@tonic-gate * deal. 288*7c478bd9Sstevel@tonic-gate * If no regcomp() then just return the input string verbatim in the output 289*7c478bd9Sstevel@tonic-gate * string. 290*7c478bd9Sstevel@tonic-gate */ 291*7c478bd9Sstevel@tonic-gate #define use_bytes(x) \ 292*7c478bd9Sstevel@tonic-gate out_used += (x); \ 293*7c478bd9Sstevel@tonic-gate if (out_used > MAX_FORMAT_BUFFER) goto mem_err 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate static int 296*7c478bd9Sstevel@tonic-gate do_replacement(char *regexp, char *repl, int doall, char *in, char *out) 297*7c478bd9Sstevel@tonic-gate { 298*7c478bd9Sstevel@tonic-gate size_t out_used = 0; 299*7c478bd9Sstevel@tonic-gate #if HAVE_REGCOMP 300*7c478bd9Sstevel@tonic-gate regex_t match_exp; 301*7c478bd9Sstevel@tonic-gate regmatch_t match_match; 302*7c478bd9Sstevel@tonic-gate int matched; 303*7c478bd9Sstevel@tonic-gate char *cp; 304*7c478bd9Sstevel@tonic-gate char *op; 305*7c478bd9Sstevel@tonic-gate 306*7c478bd9Sstevel@tonic-gate if (!regcomp(&match_exp, regexp, REG_EXTENDED)) { 307*7c478bd9Sstevel@tonic-gate cp = in; 308*7c478bd9Sstevel@tonic-gate op = out; 309*7c478bd9Sstevel@tonic-gate matched = 0; 310*7c478bd9Sstevel@tonic-gate do { 311*7c478bd9Sstevel@tonic-gate if (!regexec(&match_exp, cp, 1, &match_match, 0)) { 312*7c478bd9Sstevel@tonic-gate if (match_match.rm_so) { 313*7c478bd9Sstevel@tonic-gate use_bytes(match_match.rm_so); 314*7c478bd9Sstevel@tonic-gate strncpy(op, cp, match_match.rm_so); 315*7c478bd9Sstevel@tonic-gate op += match_match.rm_so; 316*7c478bd9Sstevel@tonic-gate } 317*7c478bd9Sstevel@tonic-gate use_bytes(strlen(repl)); 318*7c478bd9Sstevel@tonic-gate strncpy(op, repl, MAX_FORMAT_BUFFER - 1 - (op - out)); 319*7c478bd9Sstevel@tonic-gate op += strlen(op); 320*7c478bd9Sstevel@tonic-gate cp += match_match.rm_eo; 321*7c478bd9Sstevel@tonic-gate if (!doall) { 322*7c478bd9Sstevel@tonic-gate use_bytes(strlen(cp)); 323*7c478bd9Sstevel@tonic-gate strncpy(op, cp, MAX_FORMAT_BUFFER - 1 - (op - out)); 324*7c478bd9Sstevel@tonic-gate } 325*7c478bd9Sstevel@tonic-gate matched = 1; 326*7c478bd9Sstevel@tonic-gate } 327*7c478bd9Sstevel@tonic-gate else { 328*7c478bd9Sstevel@tonic-gate use_bytes(strlen(cp)); 329*7c478bd9Sstevel@tonic-gate strncpy(op, cp, MAX_FORMAT_BUFFER - 1 - (op - out)); 330*7c478bd9Sstevel@tonic-gate matched = 0; 331*7c478bd9Sstevel@tonic-gate } 332*7c478bd9Sstevel@tonic-gate } while (doall && matched); 333*7c478bd9Sstevel@tonic-gate regfree(&match_exp); 334*7c478bd9Sstevel@tonic-gate } 335*7c478bd9Sstevel@tonic-gate #elif HAVE_REGEXPR_H 336*7c478bd9Sstevel@tonic-gate int matched; 337*7c478bd9Sstevel@tonic-gate char *cp; 338*7c478bd9Sstevel@tonic-gate char *op; 339*7c478bd9Sstevel@tonic-gate char regexp_buffer[RE_BUF_SIZE]; 340*7c478bd9Sstevel@tonic-gate size_t sdispl, edispl; 341*7c478bd9Sstevel@tonic-gate 342*7c478bd9Sstevel@tonic-gate compile(regexp, 343*7c478bd9Sstevel@tonic-gate regexp_buffer, 344*7c478bd9Sstevel@tonic-gate ®exp_buffer[RE_BUF_SIZE], 345*7c478bd9Sstevel@tonic-gate '\0'); 346*7c478bd9Sstevel@tonic-gate cp = in; 347*7c478bd9Sstevel@tonic-gate op = out; 348*7c478bd9Sstevel@tonic-gate matched = 0; 349*7c478bd9Sstevel@tonic-gate do { 350*7c478bd9Sstevel@tonic-gate if (step(cp, regexp_buffer)) { 351*7c478bd9Sstevel@tonic-gate sdispl = (size_t) (loc1 - cp); 352*7c478bd9Sstevel@tonic-gate edispl = (size_t) (loc2 - cp); 353*7c478bd9Sstevel@tonic-gate if (sdispl) { 354*7c478bd9Sstevel@tonic-gate use_bytes(sdispl); 355*7c478bd9Sstevel@tonic-gate strncpy(op, cp, sdispl); 356*7c478bd9Sstevel@tonic-gate op += sdispl; 357*7c478bd9Sstevel@tonic-gate } 358*7c478bd9Sstevel@tonic-gate use_bytes(strlen(repl)); 359*7c478bd9Sstevel@tonic-gate strncpy(op, repl, MAX_FORMAT_BUFFER - 1 - (op - out)); 360*7c478bd9Sstevel@tonic-gate op += strlen(repl); 361*7c478bd9Sstevel@tonic-gate cp += edispl; 362*7c478bd9Sstevel@tonic-gate if (!doall) { 363*7c478bd9Sstevel@tonic-gate use_bytes(strlen(cp)); 364*7c478bd9Sstevel@tonic-gate strncpy(op, cp, MAX_FORMAT_BUFFER - 1 - (op - out)); 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate matched = 1; 367*7c478bd9Sstevel@tonic-gate } 368*7c478bd9Sstevel@tonic-gate else { 369*7c478bd9Sstevel@tonic-gate use_bytes(strlen(cp)); 370*7c478bd9Sstevel@tonic-gate strncpy(op, cp, MAX_FORMAT_BUFFER - 1 - (op - out)); 371*7c478bd9Sstevel@tonic-gate matched = 0; 372*7c478bd9Sstevel@tonic-gate } 373*7c478bd9Sstevel@tonic-gate } while (doall && matched); 374*7c478bd9Sstevel@tonic-gate #else /* HAVE_REGEXP_H */ 375*7c478bd9Sstevel@tonic-gate memcpy(out, in, MAX_FORMAT_BUFFER); 376*7c478bd9Sstevel@tonic-gate #endif /* HAVE_REGCOMP */ 377*7c478bd9Sstevel@tonic-gate return 1; 378*7c478bd9Sstevel@tonic-gate mem_err: 379*7c478bd9Sstevel@tonic-gate #ifdef HAVE_REGCMP 380*7c478bd9Sstevel@tonic-gate regfree(&match_exp); 381*7c478bd9Sstevel@tonic-gate #endif 382*7c478bd9Sstevel@tonic-gate return 0; 383*7c478bd9Sstevel@tonic-gate 384*7c478bd9Sstevel@tonic-gate } 385*7c478bd9Sstevel@tonic-gate #undef use_bytes 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate /* 388*7c478bd9Sstevel@tonic-gate * aname_replacer() - Perform the specified substitutions on the input 389*7c478bd9Sstevel@tonic-gate * string and return the result. 390*7c478bd9Sstevel@tonic-gate * 391*7c478bd9Sstevel@tonic-gate * This routine enforces the "s/<pattern>/<replacement>/[g]" syntax. 392*7c478bd9Sstevel@tonic-gate */ 393*7c478bd9Sstevel@tonic-gate static krb5_error_code 394*7c478bd9Sstevel@tonic-gate aname_replacer(char *string, char **contextp, char **result) 395*7c478bd9Sstevel@tonic-gate { 396*7c478bd9Sstevel@tonic-gate krb5_error_code kret; 397*7c478bd9Sstevel@tonic-gate char *in; 398*7c478bd9Sstevel@tonic-gate char *out; 399*7c478bd9Sstevel@tonic-gate char *cp, *ep, *tp; 400*7c478bd9Sstevel@tonic-gate char *rule, *repl; 401*7c478bd9Sstevel@tonic-gate size_t rule_size, repl_size; 402*7c478bd9Sstevel@tonic-gate int doglobal; 403*7c478bd9Sstevel@tonic-gate char sep; 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate kret = ENOMEM; 406*7c478bd9Sstevel@tonic-gate *result = (char *) NULL; 407*7c478bd9Sstevel@tonic-gate /* Allocate the formatting buffers */ 408*7c478bd9Sstevel@tonic-gate if (((in = (char *) malloc(MAX_FORMAT_BUFFER)) != NULL) && 409*7c478bd9Sstevel@tonic-gate ((out = (char *) malloc(MAX_FORMAT_BUFFER)) != NULL)) { 410*7c478bd9Sstevel@tonic-gate /* 411*7c478bd9Sstevel@tonic-gate * Prime the buffers. Copy input string to "out" to simulate it 412*7c478bd9Sstevel@tonic-gate * being the result of an initial iteration. 413*7c478bd9Sstevel@tonic-gate */ 414*7c478bd9Sstevel@tonic-gate strncpy(out, string, MAX_FORMAT_BUFFER - 1); 415*7c478bd9Sstevel@tonic-gate out[MAX_FORMAT_BUFFER - 1] = '\0'; 416*7c478bd9Sstevel@tonic-gate in[0] = '\0'; 417*7c478bd9Sstevel@tonic-gate kret = 0; 418*7c478bd9Sstevel@tonic-gate /* 419*7c478bd9Sstevel@tonic-gate * Pound through the expression until we're done. 420*7c478bd9Sstevel@tonic-gate */ 421*7c478bd9Sstevel@tonic-gate for (cp = *contextp; *cp; ) { 422*7c478bd9Sstevel@tonic-gate /* Skip leading whitespace */ 423*7c478bd9Sstevel@tonic-gate while (isspace(*cp)) 424*7c478bd9Sstevel@tonic-gate cp++; 425*7c478bd9Sstevel@tonic-gate 426*7c478bd9Sstevel@tonic-gate /* 427*7c478bd9Sstevel@tonic-gate * Find our separators. First two characters must be "s<sep>" 428*7c478bd9Sstevel@tonic-gate * We must also find another "<sep>" followed by another * "<sep>". 429*7c478bd9Sstevel@tonic-gate */ 430*7c478bd9Sstevel@tonic-gate if (cp[0] != 's') { 431*7c478bd9Sstevel@tonic-gate /* Bad syntax */ 432*7c478bd9Sstevel@tonic-gate kret = KRB5_CONFIG_BADFORMAT; 433*7c478bd9Sstevel@tonic-gate break; 434*7c478bd9Sstevel@tonic-gate } 435*7c478bd9Sstevel@tonic-gate if (strspn(cp + 1, ",/;|!%") < 1) { 436*7c478bd9Sstevel@tonic-gate /* Bad syntax */ 437*7c478bd9Sstevel@tonic-gate kret = KRB5_CONFIG_BADFORMAT; 438*7c478bd9Sstevel@tonic-gate break; 439*7c478bd9Sstevel@tonic-gate } 440*7c478bd9Sstevel@tonic-gate sep = cp[1]; 441*7c478bd9Sstevel@tonic-gate 442*7c478bd9Sstevel@tonic-gate if (((ep = strchr(&cp[2], sep)) != NULL) && 443*7c478bd9Sstevel@tonic-gate ((tp = strchr(&ep[1], sep)) != NULL)) { 444*7c478bd9Sstevel@tonic-gate 445*7c478bd9Sstevel@tonic-gate /* Figure out sizes of strings and allocate them */ 446*7c478bd9Sstevel@tonic-gate rule_size = (size_t) (ep - &cp[2]); 447*7c478bd9Sstevel@tonic-gate repl_size = (size_t) (tp - &ep[1]); 448*7c478bd9Sstevel@tonic-gate if (((rule = (char *) malloc(rule_size+1)) != NULL) && 449*7c478bd9Sstevel@tonic-gate ((repl = (char *) malloc(repl_size+1)) != NULL)) { 450*7c478bd9Sstevel@tonic-gate 451*7c478bd9Sstevel@tonic-gate /* Copy the strings */ 452*7c478bd9Sstevel@tonic-gate strncpy(rule, &cp[2], rule_size); 453*7c478bd9Sstevel@tonic-gate strncpy(repl, &ep[1], repl_size); 454*7c478bd9Sstevel@tonic-gate rule[rule_size] = repl[repl_size] = '\0'; 455*7c478bd9Sstevel@tonic-gate 456*7c478bd9Sstevel@tonic-gate /* Check for trailing "g" */ 457*7c478bd9Sstevel@tonic-gate doglobal = (tp[1] == 'g') ? 1 : 0; 458*7c478bd9Sstevel@tonic-gate if (doglobal) 459*7c478bd9Sstevel@tonic-gate tp++; 460*7c478bd9Sstevel@tonic-gate 461*7c478bd9Sstevel@tonic-gate /* Swap previous in and out buffers */ 462*7c478bd9Sstevel@tonic-gate ep = in; 463*7c478bd9Sstevel@tonic-gate in = out; 464*7c478bd9Sstevel@tonic-gate out = ep; 465*7c478bd9Sstevel@tonic-gate 466*7c478bd9Sstevel@tonic-gate /* Do the replacemenbt */ 467*7c478bd9Sstevel@tonic-gate memset(out, '\0', MAX_FORMAT_BUFFER); 468*7c478bd9Sstevel@tonic-gate if (!do_replacement(rule, repl, doglobal, in, out)) { 469*7c478bd9Sstevel@tonic-gate free(rule); 470*7c478bd9Sstevel@tonic-gate free(repl); 471*7c478bd9Sstevel@tonic-gate kret = KRB5_LNAME_NOTRANS; 472*7c478bd9Sstevel@tonic-gate break; 473*7c478bd9Sstevel@tonic-gate } 474*7c478bd9Sstevel@tonic-gate free(rule); 475*7c478bd9Sstevel@tonic-gate free(repl); 476*7c478bd9Sstevel@tonic-gate 477*7c478bd9Sstevel@tonic-gate /* If we have no output buffer left, this can't be good */ 478*7c478bd9Sstevel@tonic-gate if (strlen(out) == 0) { 479*7c478bd9Sstevel@tonic-gate kret = KRB5_LNAME_NOTRANS; 480*7c478bd9Sstevel@tonic-gate break; 481*7c478bd9Sstevel@tonic-gate } 482*7c478bd9Sstevel@tonic-gate } 483*7c478bd9Sstevel@tonic-gate else { 484*7c478bd9Sstevel@tonic-gate /* No memory for copies */ 485*7c478bd9Sstevel@tonic-gate kret = ENOMEM; 486*7c478bd9Sstevel@tonic-gate break; 487*7c478bd9Sstevel@tonic-gate } 488*7c478bd9Sstevel@tonic-gate } 489*7c478bd9Sstevel@tonic-gate else { 490*7c478bd9Sstevel@tonic-gate /* Bad syntax */ 491*7c478bd9Sstevel@tonic-gate kret = KRB5_CONFIG_BADFORMAT; 492*7c478bd9Sstevel@tonic-gate break; 493*7c478bd9Sstevel@tonic-gate } 494*7c478bd9Sstevel@tonic-gate /* Advance past trailer */ 495*7c478bd9Sstevel@tonic-gate cp = &tp[1]; 496*7c478bd9Sstevel@tonic-gate } 497*7c478bd9Sstevel@tonic-gate free(in); 498*7c478bd9Sstevel@tonic-gate if (!kret) 499*7c478bd9Sstevel@tonic-gate *result = out; 500*7c478bd9Sstevel@tonic-gate else 501*7c478bd9Sstevel@tonic-gate free(out); 502*7c478bd9Sstevel@tonic-gate } 503*7c478bd9Sstevel@tonic-gate return(kret); 504*7c478bd9Sstevel@tonic-gate } 505*7c478bd9Sstevel@tonic-gate 506*7c478bd9Sstevel@tonic-gate /* 507*7c478bd9Sstevel@tonic-gate * rule_an_to_ln() - Handle aname to lname translations for RULE rules. 508*7c478bd9Sstevel@tonic-gate * 509*7c478bd9Sstevel@tonic-gate * The initial part of this routine handles the formulation of the strings from 510*7c478bd9Sstevel@tonic-gate * the principal name. 511*7c478bd9Sstevel@tonic-gate */ 512*7c478bd9Sstevel@tonic-gate static krb5_error_code 513*7c478bd9Sstevel@tonic-gate rule_an_to_ln(krb5_context context, char *rule, 514*7c478bd9Sstevel@tonic-gate krb5_const_principal aname, const int lnsize, char *lname) 515*7c478bd9Sstevel@tonic-gate { 516*7c478bd9Sstevel@tonic-gate krb5_error_code kret; 517*7c478bd9Sstevel@tonic-gate char *current; 518*7c478bd9Sstevel@tonic-gate char *fprincname; 519*7c478bd9Sstevel@tonic-gate char *selstring = 0; 520*7c478bd9Sstevel@tonic-gate int num_comps, compind; 521*7c478bd9Sstevel@tonic-gate size_t selstring_used; 522*7c478bd9Sstevel@tonic-gate char *cout; 523*7c478bd9Sstevel@tonic-gate krb5_const krb5_data *datap; 524*7c478bd9Sstevel@tonic-gate char *outstring; 525*7c478bd9Sstevel@tonic-gate 526*7c478bd9Sstevel@tonic-gate /* 527*7c478bd9Sstevel@tonic-gate * First flatten the name. 528*7c478bd9Sstevel@tonic-gate */ 529*7c478bd9Sstevel@tonic-gate current = rule; 530*7c478bd9Sstevel@tonic-gate if (!(kret = krb5_unparse_name(context, aname, &fprincname))) { 531*7c478bd9Sstevel@tonic-gate /* 532*7c478bd9Sstevel@tonic-gate * First part. 533*7c478bd9Sstevel@tonic-gate */ 534*7c478bd9Sstevel@tonic-gate if (*current == '[') { 535*7c478bd9Sstevel@tonic-gate if (sscanf(current+1,"%d:", &num_comps) == 1) { 536*7c478bd9Sstevel@tonic-gate if (num_comps == aname->length) { 537*7c478bd9Sstevel@tonic-gate /* 538*7c478bd9Sstevel@tonic-gate * We have a match based on the number of components. 539*7c478bd9Sstevel@tonic-gate */ 540*7c478bd9Sstevel@tonic-gate current = strchr(current, ':'); 541*7c478bd9Sstevel@tonic-gate selstring = (char *) malloc(MAX_FORMAT_BUFFER); 542*7c478bd9Sstevel@tonic-gate selstring_used = 0; 543*7c478bd9Sstevel@tonic-gate if (current && selstring) { 544*7c478bd9Sstevel@tonic-gate current++; 545*7c478bd9Sstevel@tonic-gate cout = selstring; 546*7c478bd9Sstevel@tonic-gate /* 547*7c478bd9Sstevel@tonic-gate * Plow through the string. 548*7c478bd9Sstevel@tonic-gate */ 549*7c478bd9Sstevel@tonic-gate while ((*current != ']') && 550*7c478bd9Sstevel@tonic-gate (*current != '\0')) { 551*7c478bd9Sstevel@tonic-gate /* 552*7c478bd9Sstevel@tonic-gate * Expand to a component. 553*7c478bd9Sstevel@tonic-gate */ 554*7c478bd9Sstevel@tonic-gate if (*current == '$') { 555*7c478bd9Sstevel@tonic-gate if ((sscanf(current+1, "%d", &compind) == 1) && 556*7c478bd9Sstevel@tonic-gate (compind <= num_comps) && 557*7c478bd9Sstevel@tonic-gate (datap = (compind > 0) ? 558*7c478bd9Sstevel@tonic-gate krb5_princ_component(context, aname, compind-1) : 559*7c478bd9Sstevel@tonic-gate krb5_princ_realm(context, aname))) { 560*7c478bd9Sstevel@tonic-gate if ((datap->length < MAX_FORMAT_BUFFER) 561*7c478bd9Sstevel@tonic-gate && (selstring_used+datap->length 562*7c478bd9Sstevel@tonic-gate < MAX_FORMAT_BUFFER)) { 563*7c478bd9Sstevel@tonic-gate selstring_used += datap->length; 564*7c478bd9Sstevel@tonic-gate } else { 565*7c478bd9Sstevel@tonic-gate kret = KRB5_LNAME_NOTRANS; 566*7c478bd9Sstevel@tonic-gate goto errout; 567*7c478bd9Sstevel@tonic-gate } 568*7c478bd9Sstevel@tonic-gate strncpy(cout, 569*7c478bd9Sstevel@tonic-gate datap->data, 570*7c478bd9Sstevel@tonic-gate datap->length); 571*7c478bd9Sstevel@tonic-gate cout += datap->length; 572*7c478bd9Sstevel@tonic-gate *cout = '\0'; 573*7c478bd9Sstevel@tonic-gate current++; 574*7c478bd9Sstevel@tonic-gate /* Point past number */ 575*7c478bd9Sstevel@tonic-gate while (isdigit(*current)) 576*7c478bd9Sstevel@tonic-gate current++; 577*7c478bd9Sstevel@tonic-gate } 578*7c478bd9Sstevel@tonic-gate else 579*7c478bd9Sstevel@tonic-gate kret = KRB5_CONFIG_BADFORMAT; 580*7c478bd9Sstevel@tonic-gate } 581*7c478bd9Sstevel@tonic-gate else { 582*7c478bd9Sstevel@tonic-gate /* Copy in verbatim. */ 583*7c478bd9Sstevel@tonic-gate *cout = *current; 584*7c478bd9Sstevel@tonic-gate cout++; 585*7c478bd9Sstevel@tonic-gate *cout = '\0'; 586*7c478bd9Sstevel@tonic-gate current++; 587*7c478bd9Sstevel@tonic-gate } 588*7c478bd9Sstevel@tonic-gate } 589*7c478bd9Sstevel@tonic-gate 590*7c478bd9Sstevel@tonic-gate /* 591*7c478bd9Sstevel@tonic-gate * Advance past separator if appropriate. 592*7c478bd9Sstevel@tonic-gate */ 593*7c478bd9Sstevel@tonic-gate if (*current == ']') 594*7c478bd9Sstevel@tonic-gate current++; 595*7c478bd9Sstevel@tonic-gate else 596*7c478bd9Sstevel@tonic-gate kret = KRB5_CONFIG_BADFORMAT; 597*7c478bd9Sstevel@tonic-gate 598*7c478bd9Sstevel@tonic-gate errout: if (kret) 599*7c478bd9Sstevel@tonic-gate free(selstring); 600*7c478bd9Sstevel@tonic-gate } 601*7c478bd9Sstevel@tonic-gate } 602*7c478bd9Sstevel@tonic-gate else 603*7c478bd9Sstevel@tonic-gate kret = KRB5_LNAME_NOTRANS; 604*7c478bd9Sstevel@tonic-gate } 605*7c478bd9Sstevel@tonic-gate else 606*7c478bd9Sstevel@tonic-gate kret = KRB5_CONFIG_BADFORMAT; 607*7c478bd9Sstevel@tonic-gate } 608*7c478bd9Sstevel@tonic-gate else { 609*7c478bd9Sstevel@tonic-gate if (!(selstring = aname_full_to_mapping_name(fprincname))) 610*7c478bd9Sstevel@tonic-gate kret = ENOMEM; 611*7c478bd9Sstevel@tonic-gate } 612*7c478bd9Sstevel@tonic-gate krb5_xfree(fprincname); 613*7c478bd9Sstevel@tonic-gate } 614*7c478bd9Sstevel@tonic-gate if (!kret) { 615*7c478bd9Sstevel@tonic-gate /* 616*7c478bd9Sstevel@tonic-gate * Second part 617*7c478bd9Sstevel@tonic-gate */ 618*7c478bd9Sstevel@tonic-gate if (*current == '(') 619*7c478bd9Sstevel@tonic-gate kret = aname_do_match(selstring, ¤t); 620*7c478bd9Sstevel@tonic-gate 621*7c478bd9Sstevel@tonic-gate /* 622*7c478bd9Sstevel@tonic-gate * Third part. 623*7c478bd9Sstevel@tonic-gate */ 624*7c478bd9Sstevel@tonic-gate if (!kret) { 625*7c478bd9Sstevel@tonic-gate outstring = (char *) NULL; 626*7c478bd9Sstevel@tonic-gate kret = aname_replacer(selstring, ¤t, &outstring); 627*7c478bd9Sstevel@tonic-gate if (outstring) { 628*7c478bd9Sstevel@tonic-gate /* Copy out the value if there's enough room */ 629*7c478bd9Sstevel@tonic-gate if (strlen(outstring)+1 <= (size_t) lnsize) 630*7c478bd9Sstevel@tonic-gate strcpy(lname, outstring); 631*7c478bd9Sstevel@tonic-gate else 632*7c478bd9Sstevel@tonic-gate kret = KRB5_CONFIG_NOTENUFSPACE; 633*7c478bd9Sstevel@tonic-gate free(outstring); 634*7c478bd9Sstevel@tonic-gate } 635*7c478bd9Sstevel@tonic-gate } 636*7c478bd9Sstevel@tonic-gate free(selstring); 637*7c478bd9Sstevel@tonic-gate } 638*7c478bd9Sstevel@tonic-gate 639*7c478bd9Sstevel@tonic-gate return(kret); 640*7c478bd9Sstevel@tonic-gate } 641*7c478bd9Sstevel@tonic-gate #endif /* AN_TO_LN_RULES */ 642*7c478bd9Sstevel@tonic-gate 643*7c478bd9Sstevel@tonic-gate /* 644*7c478bd9Sstevel@tonic-gate * Solaris Kerberos 645*7c478bd9Sstevel@tonic-gate * Return true (1) if the princ's realm matches any of the 646*7c478bd9Sstevel@tonic-gate * 'auth_to_local_realm' relations in the default realm section. 647*7c478bd9Sstevel@tonic-gate */ 648*7c478bd9Sstevel@tonic-gate static int 649*7c478bd9Sstevel@tonic-gate an_to_ln_realm_chk( 650*7c478bd9Sstevel@tonic-gate krb5_context context, 651*7c478bd9Sstevel@tonic-gate krb5_const_principal aname, 652*7c478bd9Sstevel@tonic-gate char *def_realm, 653*7c478bd9Sstevel@tonic-gate int realm_length) 654*7c478bd9Sstevel@tonic-gate { 655*7c478bd9Sstevel@tonic-gate char **values, **cpp; 656*7c478bd9Sstevel@tonic-gate const char *realm_names[4]; 657*7c478bd9Sstevel@tonic-gate krb5_error_code retval; 658*7c478bd9Sstevel@tonic-gate 659*7c478bd9Sstevel@tonic-gate realm_names[0] = "realms"; 660*7c478bd9Sstevel@tonic-gate realm_names[1] = def_realm; 661*7c478bd9Sstevel@tonic-gate realm_names[2] = "auth_to_local_realm"; 662*7c478bd9Sstevel@tonic-gate realm_names[3] = 0; 663*7c478bd9Sstevel@tonic-gate 664*7c478bd9Sstevel@tonic-gate if (context->profile == 0) 665*7c478bd9Sstevel@tonic-gate return (0); 666*7c478bd9Sstevel@tonic-gate 667*7c478bd9Sstevel@tonic-gate retval = profile_get_values(context->profile, realm_names, 668*7c478bd9Sstevel@tonic-gate &values); 669*7c478bd9Sstevel@tonic-gate if (retval) 670*7c478bd9Sstevel@tonic-gate return (0); 671*7c478bd9Sstevel@tonic-gate 672*7c478bd9Sstevel@tonic-gate for (cpp = values; *cpp; cpp++) { 673*7c478bd9Sstevel@tonic-gate 674*7c478bd9Sstevel@tonic-gate if (((size_t) realm_length == strlen(*cpp)) && 675*7c478bd9Sstevel@tonic-gate (memcmp(*cpp, krb5_princ_realm(context, aname)->data, 676*7c478bd9Sstevel@tonic-gate realm_length) == 0)) { 677*7c478bd9Sstevel@tonic-gate 678*7c478bd9Sstevel@tonic-gate profile_free_list(values); 679*7c478bd9Sstevel@tonic-gate return (1); /* success */ 680*7c478bd9Sstevel@tonic-gate } 681*7c478bd9Sstevel@tonic-gate } 682*7c478bd9Sstevel@tonic-gate 683*7c478bd9Sstevel@tonic-gate profile_free_list(values); 684*7c478bd9Sstevel@tonic-gate return (0); 685*7c478bd9Sstevel@tonic-gate } 686*7c478bd9Sstevel@tonic-gate 687*7c478bd9Sstevel@tonic-gate /* 688*7c478bd9Sstevel@tonic-gate * Implementation: This version checks the realm to see if it is the local 689*7c478bd9Sstevel@tonic-gate * realm; if so, and there is exactly one non-realm component to the name, 690*7c478bd9Sstevel@tonic-gate * that name is returned as the lname. 691*7c478bd9Sstevel@tonic-gate */ 692*7c478bd9Sstevel@tonic-gate static krb5_error_code 693*7c478bd9Sstevel@tonic-gate default_an_to_ln(krb5_context context, krb5_const_principal aname, 694*7c478bd9Sstevel@tonic-gate const int lnsize, char *lname) 695*7c478bd9Sstevel@tonic-gate { 696*7c478bd9Sstevel@tonic-gate krb5_error_code retval; 697*7c478bd9Sstevel@tonic-gate char *def_realm; 698*7c478bd9Sstevel@tonic-gate int realm_length; 699*7c478bd9Sstevel@tonic-gate 700*7c478bd9Sstevel@tonic-gate realm_length = krb5_princ_realm(context, aname)->length; 701*7c478bd9Sstevel@tonic-gate 702*7c478bd9Sstevel@tonic-gate 703*7c478bd9Sstevel@tonic-gate if ((retval = krb5_get_default_realm(context, &def_realm))) { 704*7c478bd9Sstevel@tonic-gate return(retval); 705*7c478bd9Sstevel@tonic-gate } 706*7c478bd9Sstevel@tonic-gate 707*7c478bd9Sstevel@tonic-gate /* compare against default realm and auth_to_local_realm(s) */ 708*7c478bd9Sstevel@tonic-gate if ((((size_t) realm_length != strlen(def_realm)) || 709*7c478bd9Sstevel@tonic-gate (memcmp(def_realm, krb5_princ_realm(context, aname)->data, 710*7c478bd9Sstevel@tonic-gate realm_length))) && 711*7c478bd9Sstevel@tonic-gate !an_to_ln_realm_chk(context, aname, def_realm, 712*7c478bd9Sstevel@tonic-gate realm_length)) { 713*7c478bd9Sstevel@tonic-gate free(def_realm); 714*7c478bd9Sstevel@tonic-gate return KRB5_LNAME_NOTRANS; 715*7c478bd9Sstevel@tonic-gate } 716*7c478bd9Sstevel@tonic-gate 717*7c478bd9Sstevel@tonic-gate if (krb5_princ_size(context, aname) != 1) { 718*7c478bd9Sstevel@tonic-gate if (krb5_princ_size(context, aname) == 2 ) { 719*7c478bd9Sstevel@tonic-gate /* Check to see if 2nd component is the local realm. */ 720*7c478bd9Sstevel@tonic-gate if (strncmp(krb5_princ_component(context, aname, 1)->data, 721*7c478bd9Sstevel@tonic-gate def_realm, realm_length) || 722*7c478bd9Sstevel@tonic-gate realm_length != 723*7c478bd9Sstevel@tonic-gate krb5_princ_component(context, aname, 1)->length) 724*7c478bd9Sstevel@tonic-gate /* XXX an_to_ln_realm_chk ? */ 725*7c478bd9Sstevel@tonic-gate return KRB5_LNAME_NOTRANS; 726*7c478bd9Sstevel@tonic-gate } 727*7c478bd9Sstevel@tonic-gate else 728*7c478bd9Sstevel@tonic-gate /* no components or more than one component to non-realm part of name 729*7c478bd9Sstevel@tonic-gate --no translation. */ 730*7c478bd9Sstevel@tonic-gate return KRB5_LNAME_NOTRANS; 731*7c478bd9Sstevel@tonic-gate } 732*7c478bd9Sstevel@tonic-gate 733*7c478bd9Sstevel@tonic-gate free(def_realm); 734*7c478bd9Sstevel@tonic-gate strncpy(lname, krb5_princ_component(context, aname,0)->data, 735*7c478bd9Sstevel@tonic-gate min(krb5_princ_component(context, aname,0)->length,lnsize)); 736*7c478bd9Sstevel@tonic-gate if (lnsize <= krb5_princ_component(context, aname,0)->length ) { 737*7c478bd9Sstevel@tonic-gate retval = KRB5_CONFIG_NOTENUFSPACE; 738*7c478bd9Sstevel@tonic-gate } else { 739*7c478bd9Sstevel@tonic-gate lname[krb5_princ_component(context, aname,0)->length] = '\0'; 740*7c478bd9Sstevel@tonic-gate retval = 0; 741*7c478bd9Sstevel@tonic-gate } 742*7c478bd9Sstevel@tonic-gate return retval; 743*7c478bd9Sstevel@tonic-gate } 744*7c478bd9Sstevel@tonic-gate 745*7c478bd9Sstevel@tonic-gate /* 746*7c478bd9Sstevel@tonic-gate Converts an authentication name to a local name suitable for use by 747*7c478bd9Sstevel@tonic-gate programs wishing a translation to an environment-specific name (e.g. 748*7c478bd9Sstevel@tonic-gate user account name). 749*7c478bd9Sstevel@tonic-gate 750*7c478bd9Sstevel@tonic-gate lnsize specifies the maximum length name that is to be filled into 751*7c478bd9Sstevel@tonic-gate lname. 752*7c478bd9Sstevel@tonic-gate The translation will be null terminated in all non-error returns. 753*7c478bd9Sstevel@tonic-gate 754*7c478bd9Sstevel@tonic-gate returns system errors, NOT_ENOUGH_SPACE 755*7c478bd9Sstevel@tonic-gate */ 756*7c478bd9Sstevel@tonic-gate 757*7c478bd9Sstevel@tonic-gate krb5_error_code 758*7c478bd9Sstevel@tonic-gate krb5_aname_to_localname(krb5_context context, 759*7c478bd9Sstevel@tonic-gate krb5_const_principal aname, const int lnsize, char *lname) 760*7c478bd9Sstevel@tonic-gate { 761*7c478bd9Sstevel@tonic-gate krb5_error_code kret; 762*7c478bd9Sstevel@tonic-gate char *realm; 763*7c478bd9Sstevel@tonic-gate char *pname; 764*7c478bd9Sstevel@tonic-gate char *mname; 765*7c478bd9Sstevel@tonic-gate const char *hierarchy[5]; 766*7c478bd9Sstevel@tonic-gate char **mapping_values; 767*7c478bd9Sstevel@tonic-gate int i, nvalid; 768*7c478bd9Sstevel@tonic-gate char *cp, *s; 769*7c478bd9Sstevel@tonic-gate char *typep, *argp; 770*7c478bd9Sstevel@tonic-gate 771*7c478bd9Sstevel@tonic-gate if (lnsize < 0) 772*7c478bd9Sstevel@tonic-gate return KRB5_CONFIG_NOTENUFSPACE; 773*7c478bd9Sstevel@tonic-gate 774*7c478bd9Sstevel@tonic-gate /* 775*7c478bd9Sstevel@tonic-gate * First get the default realm. 776*7c478bd9Sstevel@tonic-gate */ 777*7c478bd9Sstevel@tonic-gate if (!(kret = krb5_get_default_realm(context, &realm))) { 778*7c478bd9Sstevel@tonic-gate /* Flatten the name */ 779*7c478bd9Sstevel@tonic-gate if (!(kret = krb5_unparse_name(context, aname, &pname))) { 780*7c478bd9Sstevel@tonic-gate if ((mname = aname_full_to_mapping_name(pname))) { 781*7c478bd9Sstevel@tonic-gate /* 782*7c478bd9Sstevel@tonic-gate * Search first for explicit mappings of the form: 783*7c478bd9Sstevel@tonic-gate * 784*7c478bd9Sstevel@tonic-gate * [realms]->realm->"auth_to_local_names"->mapping_name 785*7c478bd9Sstevel@tonic-gate */ 786*7c478bd9Sstevel@tonic-gate hierarchy[0] = "realms"; 787*7c478bd9Sstevel@tonic-gate hierarchy[1] = realm; 788*7c478bd9Sstevel@tonic-gate hierarchy[2] = "auth_to_local_names"; 789*7c478bd9Sstevel@tonic-gate hierarchy[3] = mname; 790*7c478bd9Sstevel@tonic-gate hierarchy[4] = (char *) NULL; 791*7c478bd9Sstevel@tonic-gate if (!(kret = profile_get_values(context->profile, 792*7c478bd9Sstevel@tonic-gate hierarchy, 793*7c478bd9Sstevel@tonic-gate &mapping_values))) { 794*7c478bd9Sstevel@tonic-gate /* We found one or more explicit mappings. */ 795*7c478bd9Sstevel@tonic-gate for (nvalid=0; mapping_values[nvalid]; nvalid++); 796*7c478bd9Sstevel@tonic-gate 797*7c478bd9Sstevel@tonic-gate /* Just use the last one. */ 798*7c478bd9Sstevel@tonic-gate /* Trim the value. */ 799*7c478bd9Sstevel@tonic-gate s = mapping_values[nvalid-1]; 800*7c478bd9Sstevel@tonic-gate cp = s + strlen(s); 801*7c478bd9Sstevel@tonic-gate while (cp > s) { 802*7c478bd9Sstevel@tonic-gate cp--; 803*7c478bd9Sstevel@tonic-gate if (!isspace((int)(*cp))) 804*7c478bd9Sstevel@tonic-gate break; 805*7c478bd9Sstevel@tonic-gate *cp = '\0'; 806*7c478bd9Sstevel@tonic-gate } 807*7c478bd9Sstevel@tonic-gate 808*7c478bd9Sstevel@tonic-gate /* Copy out the value if there's enough room */ 809*7c478bd9Sstevel@tonic-gate if (strlen(mapping_values[nvalid-1])+1 <= (size_t) lnsize) 810*7c478bd9Sstevel@tonic-gate strcpy(lname, mapping_values[nvalid-1]); 811*7c478bd9Sstevel@tonic-gate else 812*7c478bd9Sstevel@tonic-gate kret = KRB5_CONFIG_NOTENUFSPACE; 813*7c478bd9Sstevel@tonic-gate 814*7c478bd9Sstevel@tonic-gate /* Free residue */ 815*7c478bd9Sstevel@tonic-gate profile_free_list(mapping_values); 816*7c478bd9Sstevel@tonic-gate } 817*7c478bd9Sstevel@tonic-gate else { 818*7c478bd9Sstevel@tonic-gate /* 819*7c478bd9Sstevel@tonic-gate * OK - There's no explicit mapping. Now check for 820*7c478bd9Sstevel@tonic-gate * general auth_to_local rules of the form: 821*7c478bd9Sstevel@tonic-gate * 822*7c478bd9Sstevel@tonic-gate * [realms]->realm->"auth_to_local" 823*7c478bd9Sstevel@tonic-gate * 824*7c478bd9Sstevel@tonic-gate * This can have one or more of the following kinds of 825*7c478bd9Sstevel@tonic-gate * values: 826*7c478bd9Sstevel@tonic-gate * DB:<filename> - Look up principal in aname database. 827*7c478bd9Sstevel@tonic-gate * RULE:<sed-exp> - Formulate lname from sed-exp. 828*7c478bd9Sstevel@tonic-gate * DEFAULT - Use default rule. 829*7c478bd9Sstevel@tonic-gate * The first rule to find a match is used. 830*7c478bd9Sstevel@tonic-gate */ 831*7c478bd9Sstevel@tonic-gate hierarchy[0] = "realms"; 832*7c478bd9Sstevel@tonic-gate hierarchy[1] = realm; 833*7c478bd9Sstevel@tonic-gate hierarchy[2] = "auth_to_local"; 834*7c478bd9Sstevel@tonic-gate hierarchy[3] = (char *) NULL; 835*7c478bd9Sstevel@tonic-gate if (!(kret = profile_get_values(context->profile, 836*7c478bd9Sstevel@tonic-gate hierarchy, 837*7c478bd9Sstevel@tonic-gate &mapping_values))) { 838*7c478bd9Sstevel@tonic-gate /* 839*7c478bd9Sstevel@tonic-gate * Loop through all the mapping values. 840*7c478bd9Sstevel@tonic-gate */ 841*7c478bd9Sstevel@tonic-gate for (i=0; mapping_values[i]; i++) { 842*7c478bd9Sstevel@tonic-gate typep = mapping_values[i]; 843*7c478bd9Sstevel@tonic-gate argp = strchr(typep, ':'); 844*7c478bd9Sstevel@tonic-gate if (argp) { 845*7c478bd9Sstevel@tonic-gate *argp = '\0'; 846*7c478bd9Sstevel@tonic-gate argp++; 847*7c478bd9Sstevel@tonic-gate } 848*7c478bd9Sstevel@tonic-gate #ifdef ANAME_DB 849*7c478bd9Sstevel@tonic-gate if (!strcmp(typep, "DB") && argp) { 850*7c478bd9Sstevel@tonic-gate kret = db_an_to_ln(context, 851*7c478bd9Sstevel@tonic-gate argp, 852*7c478bd9Sstevel@tonic-gate aname, 853*7c478bd9Sstevel@tonic-gate lnsize, 854*7c478bd9Sstevel@tonic-gate lname); 855*7c478bd9Sstevel@tonic-gate if (kret != KRB5_LNAME_NOTRANS) 856*7c478bd9Sstevel@tonic-gate break; 857*7c478bd9Sstevel@tonic-gate } 858*7c478bd9Sstevel@tonic-gate else 859*7c478bd9Sstevel@tonic-gate #endif 860*7c478bd9Sstevel@tonic-gate #ifdef AN_TO_LN_RULES 861*7c478bd9Sstevel@tonic-gate if (!strcmp(typep, "RULE") && argp) { 862*7c478bd9Sstevel@tonic-gate kret = rule_an_to_ln(context, 863*7c478bd9Sstevel@tonic-gate argp, 864*7c478bd9Sstevel@tonic-gate aname, 865*7c478bd9Sstevel@tonic-gate lnsize, 866*7c478bd9Sstevel@tonic-gate lname); 867*7c478bd9Sstevel@tonic-gate if (kret != KRB5_LNAME_NOTRANS) 868*7c478bd9Sstevel@tonic-gate break; 869*7c478bd9Sstevel@tonic-gate } 870*7c478bd9Sstevel@tonic-gate else 871*7c478bd9Sstevel@tonic-gate #endif /* AN_TO_LN_RULES */ 872*7c478bd9Sstevel@tonic-gate if (!strcmp(typep, "DEFAULT") && !argp) { 873*7c478bd9Sstevel@tonic-gate kret = default_an_to_ln(context, 874*7c478bd9Sstevel@tonic-gate aname, 875*7c478bd9Sstevel@tonic-gate lnsize, 876*7c478bd9Sstevel@tonic-gate lname); 877*7c478bd9Sstevel@tonic-gate if (kret != KRB5_LNAME_NOTRANS) 878*7c478bd9Sstevel@tonic-gate break; 879*7c478bd9Sstevel@tonic-gate } 880*7c478bd9Sstevel@tonic-gate else { 881*7c478bd9Sstevel@tonic-gate kret = KRB5_CONFIG_BADFORMAT; 882*7c478bd9Sstevel@tonic-gate break; 883*7c478bd9Sstevel@tonic-gate } 884*7c478bd9Sstevel@tonic-gate } 885*7c478bd9Sstevel@tonic-gate 886*7c478bd9Sstevel@tonic-gate /* We're done, clean up the droppings. */ 887*7c478bd9Sstevel@tonic-gate profile_free_list(mapping_values); 888*7c478bd9Sstevel@tonic-gate } 889*7c478bd9Sstevel@tonic-gate else { 890*7c478bd9Sstevel@tonic-gate /* 891*7c478bd9Sstevel@tonic-gate * No profile relation found, try default mapping. 892*7c478bd9Sstevel@tonic-gate */ 893*7c478bd9Sstevel@tonic-gate kret = default_an_to_ln(context, 894*7c478bd9Sstevel@tonic-gate aname, 895*7c478bd9Sstevel@tonic-gate lnsize, 896*7c478bd9Sstevel@tonic-gate lname); 897*7c478bd9Sstevel@tonic-gate } 898*7c478bd9Sstevel@tonic-gate } 899*7c478bd9Sstevel@tonic-gate free(mname); 900*7c478bd9Sstevel@tonic-gate } 901*7c478bd9Sstevel@tonic-gate else 902*7c478bd9Sstevel@tonic-gate kret = ENOMEM; 903*7c478bd9Sstevel@tonic-gate krb5_xfree(pname); 904*7c478bd9Sstevel@tonic-gate } 905*7c478bd9Sstevel@tonic-gate krb5_xfree(realm); 906*7c478bd9Sstevel@tonic-gate } 907*7c478bd9Sstevel@tonic-gate return(kret); 908*7c478bd9Sstevel@tonic-gate } 909