155682Smarkm/* 2233294Sstas * Copyright (c) 1997-2007 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 555682Smarkm * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 955682Smarkm * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 1655682Smarkm * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 2055682Smarkm * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 34233294Sstas/** 35233294Sstas * @page krb5_principal_intro The principal handing functions. 36233294Sstas * 37233294Sstas * A Kerberos principal is a email address looking string that 38233294Sstas * contains to parts separeted by a @. The later part is the kerbero 39233294Sstas * realm the principal belongs to and the former is a list of 0 or 40233294Sstas * more components. For example 41233294Sstas * @verbatim 42233294Sstaslha@SU.SE 43233294Sstashost/hummel.it.su.se@SU.SE 44233294Sstashost/admin@H5L.ORG 45233294Sstas@endverbatim 46233294Sstas * 47233294Sstas * See the library functions here: @ref krb5_principal 48233294Sstas */ 49233294Sstas 5055682Smarkm#include "krb5_locl.h" 5155682Smarkm#ifdef HAVE_RES_SEARCH 5255682Smarkm#define USE_RESOLVER 5355682Smarkm#endif 5455682Smarkm#ifdef HAVE_ARPA_NAMESER_H 5555682Smarkm#include <arpa/nameser.h> 5655682Smarkm#endif 5772445Sassar#include <fnmatch.h> 5855682Smarkm#include "resolve.h" 5955682Smarkm 6055682Smarkm#define princ_num_comp(P) ((P)->name.name_string.len) 6155682Smarkm#define princ_type(P) ((P)->name.name_type) 6255682Smarkm#define princ_comp(P) ((P)->name.name_string.val) 6355682Smarkm#define princ_ncomp(P, N) ((P)->name.name_string.val[(N)]) 6455682Smarkm#define princ_realm(P) ((P)->realm) 6555682Smarkm 66233294Sstas/** 67233294Sstas * Frees a Kerberos principal allocated by the library with 68233294Sstas * krb5_parse_name(), krb5_make_principal() or any other related 69233294Sstas * principal functions. 70233294Sstas * 71233294Sstas * @param context A Kerberos context. 72233294Sstas * @param p a principal to free. 73233294Sstas * 74233294Sstas * @return An krb5 error code, see krb5_get_error_message(). 75233294Sstas * 76233294Sstas * @ingroup krb5_principal 77233294Sstas */ 78233294Sstas 79233294SstasKRB5_LIB_FUNCTION void KRB5_LIB_CALL 8055682Smarkmkrb5_free_principal(krb5_context context, 8155682Smarkm krb5_principal p) 8255682Smarkm{ 8355682Smarkm if(p){ 8455682Smarkm free_Principal(p); 8555682Smarkm free(p); 8655682Smarkm } 8755682Smarkm} 8855682Smarkm 89233294Sstas/** 90233294Sstas * Set the type of the principal 91233294Sstas * 92233294Sstas * @param context A Kerberos context. 93233294Sstas * @param principal principal to set the type for 94233294Sstas * @param type the new type 95233294Sstas * 96233294Sstas * @return An krb5 error code, see krb5_get_error_message(). 97233294Sstas * 98233294Sstas * @ingroup krb5_principal 99233294Sstas */ 100233294Sstas 101233294SstasKRB5_LIB_FUNCTION void KRB5_LIB_CALL 102178825Sdfrkrb5_principal_set_type(krb5_context context, 103178825Sdfr krb5_principal principal, 104178825Sdfr int type) 105178825Sdfr{ 106178825Sdfr princ_type(principal) = type; 107178825Sdfr} 108178825Sdfr 109233294Sstas/** 110233294Sstas * Get the type of the principal 111233294Sstas * 112233294Sstas * @param context A Kerberos context. 113233294Sstas * @param principal principal to get the type for 114233294Sstas * 115233294Sstas * @return the type of principal 116233294Sstas * 117233294Sstas * @ingroup krb5_principal 118233294Sstas */ 119233294Sstas 120233294SstasKRB5_LIB_FUNCTION int KRB5_LIB_CALL 12190926Snectarkrb5_principal_get_type(krb5_context context, 122178825Sdfr krb5_const_principal principal) 12390926Snectar{ 12490926Snectar return princ_type(principal); 12590926Snectar} 12690926Snectar 127233294Sstas/** 128233294Sstas * Get the realm of the principal 129233294Sstas * 130233294Sstas * @param context A Kerberos context. 131233294Sstas * @param principal principal to get the realm for 132233294Sstas * 133233294Sstas * @return realm of the principal, don't free or use after krb5_principal is freed 134233294Sstas * 135233294Sstas * @ingroup krb5_principal 136233294Sstas */ 137233294Sstas 138233294SstasKRB5_LIB_FUNCTION const char* KRB5_LIB_CALL 13990926Snectarkrb5_principal_get_realm(krb5_context context, 140178825Sdfr krb5_const_principal principal) 14190926Snectar{ 14290926Snectar return princ_realm(principal); 143233294Sstas} 14490926Snectar 145233294SstasKRB5_LIB_FUNCTION const char* KRB5_LIB_CALL 14690926Snectarkrb5_principal_get_comp_string(krb5_context context, 147178825Sdfr krb5_const_principal principal, 14890926Snectar unsigned int component) 14990926Snectar{ 15090926Snectar if(component >= princ_num_comp(principal)) 15190926Snectar return NULL; 15290926Snectar return princ_ncomp(principal, component); 15390926Snectar} 15490926Snectar 155233294Sstas/** 156233294Sstas * Get number of component is principal. 157233294Sstas * 158233294Sstas * @param context Kerberos 5 context 159233294Sstas * @param principal principal to query 160233294Sstas * 161233294Sstas * @return number of components in string 162233294Sstas * 163233294Sstas * @ingroup krb5_principal 164233294Sstas */ 165233294Sstas 166233294SstasKRB5_LIB_FUNCTION unsigned int KRB5_LIB_CALL 167233294Sstaskrb5_principal_get_num_comp(krb5_context context, 168233294Sstas krb5_const_principal principal) 169233294Sstas{ 170233294Sstas return princ_num_comp(principal); 171233294Sstas} 172233294Sstas 173233294Sstas/** 174233294Sstas * Parse a name into a krb5_principal structure, flags controls the behavior. 175233294Sstas * 176233294Sstas * @param context Kerberos 5 context 177233294Sstas * @param name name to parse into a Kerberos principal 178233294Sstas * @param flags flags to control the behavior 179233294Sstas * @param principal returned principal, free with krb5_free_principal(). 180233294Sstas * 181233294Sstas * @return An krb5 error code, see krb5_get_error_message(). 182233294Sstas * 183233294Sstas * @ingroup krb5_principal 184233294Sstas */ 185233294Sstas 186233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 187178825Sdfrkrb5_parse_name_flags(krb5_context context, 188178825Sdfr const char *name, 189178825Sdfr int flags, 190178825Sdfr krb5_principal *principal) 19155682Smarkm{ 19255682Smarkm krb5_error_code ret; 193178825Sdfr heim_general_string *comp; 194178825Sdfr heim_general_string realm = NULL; 19555682Smarkm int ncomp; 19655682Smarkm 197102644Snectar const char *p; 19855682Smarkm char *q; 19955682Smarkm char *s; 20055682Smarkm char *start; 20155682Smarkm 20255682Smarkm int n; 20355682Smarkm char c; 20455682Smarkm int got_realm = 0; 205178825Sdfr int first_at = 1; 206178825Sdfr int enterprise = (flags & KRB5_PRINCIPAL_PARSE_ENTERPRISE); 207233294Sstas 208178825Sdfr *principal = NULL; 209178825Sdfr 210233294Sstas#define RFLAGS (KRB5_PRINCIPAL_PARSE_NO_REALM|KRB5_PRINCIPAL_PARSE_REQUIRE_REALM) 211178825Sdfr 212178825Sdfr if ((flags & RFLAGS) == RFLAGS) { 213233294Sstas krb5_set_error_message(context, KRB5_ERR_NO_SERVICE, 214233294Sstas N_("Can't require both realm and " 215233294Sstas "no realm at the same time", "")); 216178825Sdfr return KRB5_ERR_NO_SERVICE; 217178825Sdfr } 218178825Sdfr#undef RFLAGS 219178825Sdfr 220178825Sdfr /* count number of component, 221178825Sdfr * enterprise names only have one component 222178825Sdfr */ 22355682Smarkm ncomp = 1; 224178825Sdfr if (!enterprise) { 225178825Sdfr for(p = name; *p; p++){ 226178825Sdfr if(*p=='\\'){ 227178825Sdfr if(!p[1]) { 228233294Sstas krb5_set_error_message(context, KRB5_PARSE_MALFORMED, 229233294Sstas N_("trailing \\ in principal name", "")); 230178825Sdfr return KRB5_PARSE_MALFORMED; 231178825Sdfr } 232178825Sdfr p++; 233178825Sdfr } else if(*p == '/') 234178825Sdfr ncomp++; 235178825Sdfr else if(*p == '@') 236178825Sdfr break; 237178825Sdfr } 23855682Smarkm } 23955682Smarkm comp = calloc(ncomp, sizeof(*comp)); 24078527Sassar if (comp == NULL) { 241233294Sstas krb5_set_error_message(context, ENOMEM, 242233294Sstas N_("malloc: out of memory", "")); 24355682Smarkm return ENOMEM; 24478527Sassar } 245233294Sstas 24655682Smarkm n = 0; 247102644Snectar p = start = q = s = strdup(name); 24855682Smarkm if (start == NULL) { 24955682Smarkm free (comp); 250233294Sstas krb5_set_error_message(context, ENOMEM, 251233294Sstas N_("malloc: out of memory", "")); 25255682Smarkm return ENOMEM; 25355682Smarkm } 25455682Smarkm while(*p){ 25555682Smarkm c = *p++; 25655682Smarkm if(c == '\\'){ 25755682Smarkm c = *p++; 25855682Smarkm if(c == 'n') 25955682Smarkm c = '\n'; 26055682Smarkm else if(c == 't') 26155682Smarkm c = '\t'; 26255682Smarkm else if(c == 'b') 26355682Smarkm c = '\b'; 26455682Smarkm else if(c == '0') 26555682Smarkm c = '\0'; 266107207Snectar else if(c == '\0') { 267107207Snectar ret = KRB5_PARSE_MALFORMED; 268233294Sstas krb5_set_error_message(context, ret, 269233294Sstas N_("trailing \\ in principal name", "")); 270107207Snectar goto exit; 271107207Snectar } 272178825Sdfr }else if(enterprise && first_at) { 273178825Sdfr if (c == '@') 274178825Sdfr first_at = 0; 275178825Sdfr }else if((c == '/' && !enterprise) || c == '@'){ 27655682Smarkm if(got_realm){ 27755682Smarkm ret = KRB5_PARSE_MALFORMED; 278233294Sstas krb5_set_error_message(context, ret, 279233294Sstas N_("part after realm in principal name", "")); 28055682Smarkm goto exit; 28155682Smarkm }else{ 28255682Smarkm comp[n] = malloc(q - start + 1); 28355682Smarkm if (comp[n] == NULL) { 28455682Smarkm ret = ENOMEM; 285233294Sstas krb5_set_error_message(context, ret, 286233294Sstas N_("malloc: out of memory", "")); 28755682Smarkm goto exit; 28855682Smarkm } 28957416Smarkm memcpy(comp[n], start, q - start); 29055682Smarkm comp[n][q - start] = 0; 29155682Smarkm n++; 29255682Smarkm } 29355682Smarkm if(c == '@') 29455682Smarkm got_realm = 1; 29555682Smarkm start = q; 29655682Smarkm continue; 29755682Smarkm } 298233294Sstas if(got_realm && (c == '/' || c == '\0')) { 29955682Smarkm ret = KRB5_PARSE_MALFORMED; 300233294Sstas krb5_set_error_message(context, ret, 301233294Sstas N_("part after realm in principal name", "")); 30255682Smarkm goto exit; 30355682Smarkm } 30455682Smarkm *q++ = c; 30555682Smarkm } 30655682Smarkm if(got_realm){ 307178825Sdfr if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) { 308178825Sdfr ret = KRB5_PARSE_MALFORMED; 309233294Sstas krb5_set_error_message(context, ret, 310233294Sstas N_("realm found in 'short' principal " 311233294Sstas "expected to be without one", "")); 312178825Sdfr goto exit; 313178825Sdfr } 31455682Smarkm realm = malloc(q - start + 1); 31555682Smarkm if (realm == NULL) { 31655682Smarkm ret = ENOMEM; 317233294Sstas krb5_set_error_message(context, ret, 318233294Sstas N_("malloc: out of memory", "")); 31955682Smarkm goto exit; 32055682Smarkm } 32157416Smarkm memcpy(realm, start, q - start); 32255682Smarkm realm[q - start] = 0; 32355682Smarkm }else{ 324233294Sstas if (flags & KRB5_PRINCIPAL_PARSE_REQUIRE_REALM) { 325178825Sdfr ret = KRB5_PARSE_MALFORMED; 326233294Sstas krb5_set_error_message(context, ret, 327233294Sstas N_("realm NOT found in principal " 328233294Sstas "expected to be with one", "")); 32955682Smarkm goto exit; 330178825Sdfr } else if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) { 331178825Sdfr realm = NULL; 332178825Sdfr } else { 333178825Sdfr ret = krb5_get_default_realm (context, &realm); 334178825Sdfr if (ret) 335178825Sdfr goto exit; 336178825Sdfr } 33755682Smarkm 33855682Smarkm comp[n] = malloc(q - start + 1); 33955682Smarkm if (comp[n] == NULL) { 34055682Smarkm ret = ENOMEM; 341233294Sstas krb5_set_error_message(context, ret, 342233294Sstas N_("malloc: out of memory", "")); 34355682Smarkm goto exit; 34455682Smarkm } 34557416Smarkm memcpy(comp[n], start, q - start); 34655682Smarkm comp[n][q - start] = 0; 34755682Smarkm n++; 34855682Smarkm } 34955682Smarkm *principal = malloc(sizeof(**principal)); 35055682Smarkm if (*principal == NULL) { 35155682Smarkm ret = ENOMEM; 352233294Sstas krb5_set_error_message(context, ret, 353233294Sstas N_("malloc: out of memory", "")); 35455682Smarkm goto exit; 35555682Smarkm } 356178825Sdfr if (enterprise) 357178825Sdfr (*principal)->name.name_type = KRB5_NT_ENTERPRISE_PRINCIPAL; 358178825Sdfr else 359178825Sdfr (*principal)->name.name_type = KRB5_NT_PRINCIPAL; 36055682Smarkm (*principal)->name.name_string.val = comp; 36155682Smarkm princ_num_comp(*principal) = n; 36255682Smarkm (*principal)->realm = realm; 36355682Smarkm free(s); 36455682Smarkm return 0; 36555682Smarkmexit: 36655682Smarkm while(n>0){ 36755682Smarkm free(comp[--n]); 36855682Smarkm } 36955682Smarkm free(comp); 370178825Sdfr free(realm); 37155682Smarkm free(s); 37255682Smarkm return ret; 37355682Smarkm} 37455682Smarkm 375233294Sstas/** 376233294Sstas * Parse a name into a krb5_principal structure 377233294Sstas * 378233294Sstas * @param context Kerberos 5 context 379233294Sstas * @param name name to parse into a Kerberos principal 380233294Sstas * @param principal returned principal, free with krb5_free_principal(). 381233294Sstas * 382233294Sstas * @return An krb5 error code, see krb5_get_error_message(). 383233294Sstas * 384233294Sstas * @ingroup krb5_principal 385233294Sstas */ 386233294Sstas 387233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 388178825Sdfrkrb5_parse_name(krb5_context context, 389178825Sdfr const char *name, 390178825Sdfr krb5_principal *principal) 391178825Sdfr{ 392178825Sdfr return krb5_parse_name_flags(context, name, 0, principal); 393178825Sdfr} 394178825Sdfr 39557416Smarkmstatic const char quotable_chars[] = " \n\t\b\\/@"; 39657416Smarkmstatic const char replace_chars[] = " ntb\\/@"; 397178825Sdfrstatic const char nq_chars[] = " \\/@"; 39855682Smarkm 39955682Smarkm#define add_char(BASE, INDEX, LEN, C) do { if((INDEX) < (LEN)) (BASE)[(INDEX)++] = (C); }while(0); 40055682Smarkm 40155682Smarkmstatic size_t 402178825Sdfrquote_string(const char *s, char *out, size_t idx, size_t len, int display) 40355682Smarkm{ 40455682Smarkm const char *p, *q; 405178825Sdfr for(p = s; *p && idx < len; p++){ 406178825Sdfr q = strchr(quotable_chars, *p); 407178825Sdfr if (q && display) { 408178825Sdfr add_char(out, idx, len, replace_chars[q - quotable_chars]); 409178825Sdfr } else if (q) { 410178825Sdfr add_char(out, idx, len, '\\'); 411178825Sdfr add_char(out, idx, len, replace_chars[q - quotable_chars]); 41255682Smarkm }else 413178825Sdfr add_char(out, idx, len, *p); 41455682Smarkm } 415178825Sdfr if(idx < len) 416178825Sdfr out[idx] = '\0'; 417178825Sdfr return idx; 41855682Smarkm} 41955682Smarkm 42055682Smarkm 42155682Smarkmstatic krb5_error_code 42255682Smarkmunparse_name_fixed(krb5_context context, 42355682Smarkm krb5_const_principal principal, 42455682Smarkm char *name, 42555682Smarkm size_t len, 426178825Sdfr int flags) 42755682Smarkm{ 428178825Sdfr size_t idx = 0; 429233294Sstas size_t i; 430178825Sdfr int short_form = (flags & KRB5_PRINCIPAL_UNPARSE_SHORT) != 0; 431178825Sdfr int no_realm = (flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) != 0; 432178825Sdfr int display = (flags & KRB5_PRINCIPAL_UNPARSE_DISPLAY) != 0; 433178825Sdfr 434178825Sdfr if (!no_realm && princ_realm(principal) == NULL) { 435233294Sstas krb5_set_error_message(context, ERANGE, 436233294Sstas N_("Realm missing from principal, " 437233294Sstas "can't unparse", "")); 438178825Sdfr return ERANGE; 439178825Sdfr } 440178825Sdfr 44155682Smarkm for(i = 0; i < princ_num_comp(principal); i++){ 44255682Smarkm if(i) 443178825Sdfr add_char(name, idx, len, '/'); 444178825Sdfr idx = quote_string(princ_ncomp(principal, i), name, idx, len, display); 445178825Sdfr if(idx == len) { 446233294Sstas krb5_set_error_message(context, ERANGE, 447233294Sstas N_("Out of space printing principal", "")); 44855682Smarkm return ERANGE; 449178825Sdfr } 450233294Sstas } 45155682Smarkm /* add realm if different from default realm */ 452178825Sdfr if(short_form && !no_realm) { 45355682Smarkm krb5_realm r; 45455682Smarkm krb5_error_code ret; 45555682Smarkm ret = krb5_get_default_realm(context, &r); 45655682Smarkm if(ret) 45755682Smarkm return ret; 45855682Smarkm if(strcmp(princ_realm(principal), r) != 0) 45955682Smarkm short_form = 0; 46055682Smarkm free(r); 46155682Smarkm } 462178825Sdfr if(!short_form && !no_realm) { 463178825Sdfr add_char(name, idx, len, '@'); 464178825Sdfr idx = quote_string(princ_realm(principal), name, idx, len, display); 465178825Sdfr if(idx == len) { 466233294Sstas krb5_set_error_message(context, ERANGE, 467233294Sstas N_("Out of space printing " 468233294Sstas "realm of principal", "")); 46955682Smarkm return ERANGE; 470178825Sdfr } 47155682Smarkm } 47255682Smarkm return 0; 47355682Smarkm} 47455682Smarkm 475233294Sstas/** 476233294Sstas * Unparse the principal name to a fixed buffer 477233294Sstas * 478233294Sstas * @param context A Kerberos context. 479233294Sstas * @param principal principal to unparse 480233294Sstas * @param name buffer to write name to 481233294Sstas * @param len length of buffer 482233294Sstas * 483233294Sstas * @return An krb5 error code, see krb5_get_error_message(). 484233294Sstas * 485233294Sstas * @ingroup krb5_principal 486233294Sstas */ 487233294Sstas 488233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 48955682Smarkmkrb5_unparse_name_fixed(krb5_context context, 49055682Smarkm krb5_const_principal principal, 49155682Smarkm char *name, 49255682Smarkm size_t len) 49355682Smarkm{ 494178825Sdfr return unparse_name_fixed(context, principal, name, len, 0); 49555682Smarkm} 49655682Smarkm 497233294Sstas/** 498233294Sstas * Unparse the principal name to a fixed buffer. The realm is skipped 499233294Sstas * if its a default realm. 500233294Sstas * 501233294Sstas * @param context A Kerberos context. 502233294Sstas * @param principal principal to unparse 503233294Sstas * @param name buffer to write name to 504233294Sstas * @param len length of buffer 505233294Sstas * 506233294Sstas * @return An krb5 error code, see krb5_get_error_message(). 507233294Sstas * 508233294Sstas * @ingroup krb5_principal 509233294Sstas */ 510233294Sstas 511233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 51255682Smarkmkrb5_unparse_name_fixed_short(krb5_context context, 51355682Smarkm krb5_const_principal principal, 51455682Smarkm char *name, 51555682Smarkm size_t len) 51655682Smarkm{ 517233294Sstas return unparse_name_fixed(context, principal, name, len, 518178825Sdfr KRB5_PRINCIPAL_UNPARSE_SHORT); 51955682Smarkm} 52055682Smarkm 521233294Sstas/** 522233294Sstas * Unparse the principal name with unparse flags to a fixed buffer. 523233294Sstas * 524233294Sstas * @param context A Kerberos context. 525233294Sstas * @param principal principal to unparse 526233294Sstas * @param flags unparse flags 527233294Sstas * @param name buffer to write name to 528233294Sstas * @param len length of buffer 529233294Sstas * 530233294Sstas * @return An krb5 error code, see krb5_get_error_message(). 531233294Sstas * 532233294Sstas * @ingroup krb5_principal 533233294Sstas */ 534233294Sstas 535233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 536178825Sdfrkrb5_unparse_name_fixed_flags(krb5_context context, 537178825Sdfr krb5_const_principal principal, 538178825Sdfr int flags, 539178825Sdfr char *name, 540178825Sdfr size_t len) 541178825Sdfr{ 542178825Sdfr return unparse_name_fixed(context, principal, name, len, flags); 543178825Sdfr} 544178825Sdfr 54555682Smarkmstatic krb5_error_code 54655682Smarkmunparse_name(krb5_context context, 54755682Smarkm krb5_const_principal principal, 54855682Smarkm char **name, 549178825Sdfr int flags) 55055682Smarkm{ 55155682Smarkm size_t len = 0, plen; 552233294Sstas size_t i; 55355682Smarkm krb5_error_code ret; 55455682Smarkm /* count length */ 555178825Sdfr if (princ_realm(principal)) { 556178825Sdfr plen = strlen(princ_realm(principal)); 557178825Sdfr 558178825Sdfr if(strcspn(princ_realm(principal), quotable_chars) == plen) 559178825Sdfr len += plen; 560178825Sdfr else 561178825Sdfr len += 2*plen; 562178825Sdfr len++; /* '@' */ 563178825Sdfr } 56455682Smarkm for(i = 0; i < princ_num_comp(principal); i++){ 56555682Smarkm plen = strlen(princ_ncomp(principal, i)); 56655682Smarkm if(strcspn(princ_ncomp(principal, i), quotable_chars) == plen) 56755682Smarkm len += plen; 56855682Smarkm else 56955682Smarkm len += 2*plen; 57055682Smarkm len++; 57155682Smarkm } 572178825Sdfr len++; /* '\0' */ 57355682Smarkm *name = malloc(len); 574127808Snectar if(*name == NULL) { 575233294Sstas krb5_set_error_message(context, ENOMEM, 576233294Sstas N_("malloc: out of memory", "")); 57755682Smarkm return ENOMEM; 57878527Sassar } 579178825Sdfr ret = unparse_name_fixed(context, principal, *name, len, flags); 580127808Snectar if(ret) { 58155682Smarkm free(*name); 582127808Snectar *name = NULL; 583127808Snectar } 58455682Smarkm return ret; 58555682Smarkm} 58655682Smarkm 587233294Sstas/** 588233294Sstas * Unparse the Kerberos name into a string 589233294Sstas * 590233294Sstas * @param context Kerberos 5 context 591233294Sstas * @param principal principal to query 592233294Sstas * @param name resulting string, free with krb5_xfree() 593233294Sstas * 594233294Sstas * @return An krb5 error code, see krb5_get_error_message(). 595233294Sstas * 596233294Sstas * @ingroup krb5_principal 597233294Sstas */ 598233294Sstas 599233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 60055682Smarkmkrb5_unparse_name(krb5_context context, 60155682Smarkm krb5_const_principal principal, 60255682Smarkm char **name) 60355682Smarkm{ 604178825Sdfr return unparse_name(context, principal, name, 0); 60555682Smarkm} 60655682Smarkm 607233294Sstas/** 608233294Sstas * Unparse the Kerberos name into a string 609233294Sstas * 610233294Sstas * @param context Kerberos 5 context 611233294Sstas * @param principal principal to query 612233294Sstas * @param flags flag to determine the behavior 613233294Sstas * @param name resulting string, free with krb5_xfree() 614233294Sstas * 615233294Sstas * @return An krb5 error code, see krb5_get_error_message(). 616233294Sstas * 617233294Sstas * @ingroup krb5_principal 618233294Sstas */ 619233294Sstas 620233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 621178825Sdfrkrb5_unparse_name_flags(krb5_context context, 622178825Sdfr krb5_const_principal principal, 623178825Sdfr int flags, 624178825Sdfr char **name) 625178825Sdfr{ 626178825Sdfr return unparse_name(context, principal, name, flags); 627178825Sdfr} 628178825Sdfr 629233294Sstas/** 630233294Sstas * Unparse the principal name to a allocated buffer. The realm is 631233294Sstas * skipped if its a default realm. 632233294Sstas * 633233294Sstas * @param context A Kerberos context. 634233294Sstas * @param principal principal to unparse 635233294Sstas * @param name returned buffer, free with krb5_xfree() 636233294Sstas * 637233294Sstas * @return An krb5 error code, see krb5_get_error_message(). 638233294Sstas * 639233294Sstas * @ingroup krb5_principal 640233294Sstas */ 641233294Sstas 642233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 64355682Smarkmkrb5_unparse_name_short(krb5_context context, 64455682Smarkm krb5_const_principal principal, 64555682Smarkm char **name) 64655682Smarkm{ 647178825Sdfr return unparse_name(context, principal, name, KRB5_PRINCIPAL_UNPARSE_SHORT); 64855682Smarkm} 64955682Smarkm 650233294Sstas/** 651233294Sstas * Set a new realm for a principal, and as a side-effect free the 652233294Sstas * previous realm. 653233294Sstas * 654233294Sstas * @param context A Kerberos context. 655233294Sstas * @param principal principal set the realm for 656233294Sstas * @param realm the new realm to set 657233294Sstas * 658233294Sstas * @return An krb5 error code, see krb5_get_error_message(). 659233294Sstas * 660233294Sstas * @ingroup krb5_principal 661233294Sstas */ 66255682Smarkm 663233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 664233294Sstaskrb5_principal_set_realm(krb5_context context, 665233294Sstas krb5_principal principal, 666233294Sstas krb5_const_realm realm) 66755682Smarkm{ 668233294Sstas if (princ_realm(principal)) 669233294Sstas free(princ_realm(principal)); 67055682Smarkm 671233294Sstas princ_realm(principal) = strdup(realm); 672233294Sstas if (princ_realm(principal) == NULL) { 673233294Sstas krb5_set_error_message(context, ENOMEM, 674233294Sstas N_("malloc: out of memory", "")); 675233294Sstas return ENOMEM; 676233294Sstas } 677233294Sstas return 0; 67855682Smarkm} 67955682Smarkm 680233294Sstas#ifndef HEIMDAL_SMALLER 681233294Sstas/** 682233294Sstas * Build a principal using vararg style building 683233294Sstas * 684233294Sstas * @param context A Kerberos context. 685233294Sstas * @param principal returned principal 686233294Sstas * @param rlen length of realm 687233294Sstas * @param realm realm name 688233294Sstas * @param ... a list of components ended with NULL. 689233294Sstas * 690233294Sstas * @return An krb5 error code, see krb5_get_error_message(). 691233294Sstas * 692233294Sstas * @ingroup krb5_principal 693233294Sstas */ 69455682Smarkm 695233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 69655682Smarkmkrb5_build_principal(krb5_context context, 69755682Smarkm krb5_principal *principal, 69855682Smarkm int rlen, 69955682Smarkm krb5_const_realm realm, 70055682Smarkm ...) 70155682Smarkm{ 70255682Smarkm krb5_error_code ret; 70355682Smarkm va_list ap; 70455682Smarkm va_start(ap, realm); 70555682Smarkm ret = krb5_build_principal_va(context, principal, rlen, realm, ap); 70655682Smarkm va_end(ap); 70755682Smarkm return ret; 70855682Smarkm} 709233294Sstas#endif 71055682Smarkm 711233294Sstas/** 712233294Sstas * Build a principal using vararg style building 713233294Sstas * 714233294Sstas * @param context A Kerberos context. 715233294Sstas * @param principal returned principal 716233294Sstas * @param realm realm name 717233294Sstas * @param ... a list of components ended with NULL. 718233294Sstas * 719233294Sstas * @return An krb5 error code, see krb5_get_error_message(). 720233294Sstas * 721233294Sstas * @ingroup krb5_principal 722233294Sstas */ 723233294Sstas 724233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 725233294Sstaskrb5_make_principal(krb5_context context, 726233294Sstas krb5_principal *principal, 727233294Sstas krb5_const_realm realm, 728233294Sstas ...) 729233294Sstas{ 730233294Sstas krb5_error_code ret; 731233294Sstas krb5_realm r = NULL; 732233294Sstas va_list ap; 733233294Sstas if(realm == NULL) { 734233294Sstas ret = krb5_get_default_realm(context, &r); 735233294Sstas if(ret) 736233294Sstas return ret; 737233294Sstas realm = r; 738233294Sstas } 739233294Sstas va_start(ap, realm); 740233294Sstas ret = krb5_build_principal_va(context, principal, strlen(realm), realm, ap); 741233294Sstas va_end(ap); 742233294Sstas if(r) 743233294Sstas free(r); 744233294Sstas return ret; 745233294Sstas} 746233294Sstas 74755682Smarkmstatic krb5_error_code 748233294Sstasappend_component(krb5_context context, krb5_principal p, 74957416Smarkm const char *comp, 75055682Smarkm size_t comp_len) 75155682Smarkm{ 752178825Sdfr heim_general_string *tmp; 75355682Smarkm size_t len = princ_num_comp(p); 75457416Smarkm 75555682Smarkm tmp = realloc(princ_comp(p), (len + 1) * sizeof(*tmp)); 75678527Sassar if(tmp == NULL) { 757233294Sstas krb5_set_error_message(context, ENOMEM, 758233294Sstas N_("malloc: out of memory", "")); 75955682Smarkm return ENOMEM; 76078527Sassar } 76155682Smarkm princ_comp(p) = tmp; 76255682Smarkm princ_ncomp(p, len) = malloc(comp_len + 1); 76378527Sassar if (princ_ncomp(p, len) == NULL) { 764233294Sstas krb5_set_error_message(context, ENOMEM, 765233294Sstas N_("malloc: out of memory", "")); 76657416Smarkm return ENOMEM; 76778527Sassar } 76855682Smarkm memcpy (princ_ncomp(p, len), comp, comp_len); 76955682Smarkm princ_ncomp(p, len)[comp_len] = '\0'; 77055682Smarkm princ_num_comp(p)++; 77155682Smarkm return 0; 77255682Smarkm} 77355682Smarkm 77455682Smarkmstatic void 77555682Smarkmva_ext_princ(krb5_context context, krb5_principal p, va_list ap) 77655682Smarkm{ 77755682Smarkm while(1){ 77857416Smarkm const char *s; 77955682Smarkm int len; 78055682Smarkm len = va_arg(ap, int); 78155682Smarkm if(len == 0) 78255682Smarkm break; 78357416Smarkm s = va_arg(ap, const char*); 78455682Smarkm append_component(context, p, s, len); 78555682Smarkm } 78655682Smarkm} 78755682Smarkm 78855682Smarkmstatic void 78955682Smarkmva_princ(krb5_context context, krb5_principal p, va_list ap) 79055682Smarkm{ 79155682Smarkm while(1){ 79257416Smarkm const char *s; 79357416Smarkm s = va_arg(ap, const char*); 79455682Smarkm if(s == NULL) 79555682Smarkm break; 79655682Smarkm append_component(context, p, s, strlen(s)); 79755682Smarkm } 79855682Smarkm} 79955682Smarkm 80055682Smarkmstatic krb5_error_code 80155682Smarkmbuild_principal(krb5_context context, 80255682Smarkm krb5_principal *principal, 80355682Smarkm int rlen, 80455682Smarkm krb5_const_realm realm, 80555682Smarkm void (*func)(krb5_context, krb5_principal, va_list), 80655682Smarkm va_list ap) 80755682Smarkm{ 80855682Smarkm krb5_principal p; 809233294Sstas 81055682Smarkm p = calloc(1, sizeof(*p)); 81178527Sassar if (p == NULL) { 812233294Sstas krb5_set_error_message(context, ENOMEM, 813233294Sstas N_("malloc: out of memory", "")); 81455682Smarkm return ENOMEM; 81578527Sassar } 81655682Smarkm princ_type(p) = KRB5_NT_PRINCIPAL; 81755682Smarkm 81855682Smarkm princ_realm(p) = strdup(realm); 81955682Smarkm if(p->realm == NULL){ 82055682Smarkm free(p); 821233294Sstas krb5_set_error_message(context, ENOMEM, 822233294Sstas N_("malloc: out of memory", "")); 82355682Smarkm return ENOMEM; 82455682Smarkm } 825233294Sstas 82655682Smarkm (*func)(context, p, ap); 82755682Smarkm *principal = p; 82855682Smarkm return 0; 82955682Smarkm} 83055682Smarkm 831233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 832233294Sstaskrb5_build_principal_va(krb5_context context, 833233294Sstas krb5_principal *principal, 83455682Smarkm int rlen, 83555682Smarkm krb5_const_realm realm, 83655682Smarkm va_list ap) 83755682Smarkm{ 83855682Smarkm return build_principal(context, principal, rlen, realm, va_princ, ap); 83955682Smarkm} 84055682Smarkm 841233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 842233294Sstaskrb5_build_principal_va_ext(krb5_context context, 843233294Sstas krb5_principal *principal, 84455682Smarkm int rlen, 84555682Smarkm krb5_const_realm realm, 84655682Smarkm va_list ap) 84755682Smarkm{ 84855682Smarkm return build_principal(context, principal, rlen, realm, va_ext_princ, ap); 84955682Smarkm} 85055682Smarkm 85155682Smarkm 852233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 85355682Smarkmkrb5_build_principal_ext(krb5_context context, 85455682Smarkm krb5_principal *principal, 85555682Smarkm int rlen, 85655682Smarkm krb5_const_realm realm, 85755682Smarkm ...) 85855682Smarkm{ 85955682Smarkm krb5_error_code ret; 86055682Smarkm va_list ap; 86155682Smarkm va_start(ap, realm); 86255682Smarkm ret = krb5_build_principal_va_ext(context, principal, rlen, realm, ap); 86355682Smarkm va_end(ap); 86455682Smarkm return ret; 86555682Smarkm} 86655682Smarkm 867233294Sstas/** 868233294Sstas * Copy a principal 869233294Sstas * 870233294Sstas * @param context A Kerberos context. 871233294Sstas * @param inprinc principal to copy 872233294Sstas * @param outprinc copied principal, free with krb5_free_principal() 873233294Sstas * 874233294Sstas * @return An krb5 error code, see krb5_get_error_message(). 875233294Sstas * 876233294Sstas * @ingroup krb5_principal 877233294Sstas */ 87855682Smarkm 879233294Sstas 880233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 88155682Smarkmkrb5_copy_principal(krb5_context context, 88255682Smarkm krb5_const_principal inprinc, 88355682Smarkm krb5_principal *outprinc) 88455682Smarkm{ 88555682Smarkm krb5_principal p = malloc(sizeof(*p)); 88678527Sassar if (p == NULL) { 887233294Sstas krb5_set_error_message(context, ENOMEM, 888233294Sstas N_("malloc: out of memory", "")); 88955682Smarkm return ENOMEM; 89078527Sassar } 89178527Sassar if(copy_Principal(inprinc, p)) { 89278527Sassar free(p); 893233294Sstas krb5_set_error_message(context, ENOMEM, 894233294Sstas N_("malloc: out of memory", "")); 89555682Smarkm return ENOMEM; 89678527Sassar } 89755682Smarkm *outprinc = p; 89855682Smarkm return 0; 89955682Smarkm} 90055682Smarkm 901233294Sstas/** 902233294Sstas * Return TRUE iff princ1 == princ2 (without considering the realm) 903233294Sstas * 904233294Sstas * @param context Kerberos 5 context 905233294Sstas * @param princ1 first principal to compare 906233294Sstas * @param princ2 second principal to compare 907233294Sstas * 908233294Sstas * @return non zero if equal, 0 if not 909233294Sstas * 910233294Sstas * @ingroup krb5_principal 911233294Sstas * @see krb5_principal_compare() 912233294Sstas * @see krb5_realm_compare() 91372445Sassar */ 91455682Smarkm 915233294SstasKRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL 91655682Smarkmkrb5_principal_compare_any_realm(krb5_context context, 91755682Smarkm krb5_const_principal princ1, 91855682Smarkm krb5_const_principal princ2) 91955682Smarkm{ 920233294Sstas size_t i; 92155682Smarkm if(princ_num_comp(princ1) != princ_num_comp(princ2)) 92255682Smarkm return FALSE; 92355682Smarkm for(i = 0; i < princ_num_comp(princ1); i++){ 92455682Smarkm if(strcmp(princ_ncomp(princ1, i), princ_ncomp(princ2, i)) != 0) 92555682Smarkm return FALSE; 92655682Smarkm } 92755682Smarkm return TRUE; 92855682Smarkm} 92955682Smarkm 930233294SstasKRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL 931233294Sstas_krb5_principal_compare_PrincipalName(krb5_context context, 932233294Sstas krb5_const_principal princ1, 933233294Sstas PrincipalName *princ2) 934233294Sstas{ 935233294Sstas size_t i; 936233294Sstas if (princ_num_comp(princ1) != princ2->name_string.len) 937233294Sstas return FALSE; 938233294Sstas for(i = 0; i < princ_num_comp(princ1); i++){ 939233294Sstas if(strcmp(princ_ncomp(princ1, i), princ2->name_string.val[i]) != 0) 940233294Sstas return FALSE; 941233294Sstas } 942233294Sstas return TRUE; 943233294Sstas} 944233294Sstas 945233294Sstas 946233294Sstas/** 947233294Sstas * Compares the two principals, including realm of the principals and returns 948233294Sstas * TRUE if they are the same and FALSE if not. 949233294Sstas * 950233294Sstas * @param context Kerberos 5 context 951233294Sstas * @param princ1 first principal to compare 952233294Sstas * @param princ2 second principal to compare 953233294Sstas * 954233294Sstas * @ingroup krb5_principal 955233294Sstas * @see krb5_principal_compare_any_realm() 956233294Sstas * @see krb5_realm_compare() 957233294Sstas */ 958233294Sstas 95972445Sassar/* 96072445Sassar * return TRUE iff princ1 == princ2 96172445Sassar */ 96272445Sassar 963233294SstasKRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL 96455682Smarkmkrb5_principal_compare(krb5_context context, 96555682Smarkm krb5_const_principal princ1, 96655682Smarkm krb5_const_principal princ2) 96755682Smarkm{ 96855682Smarkm if(!krb5_realm_compare(context, princ1, princ2)) 96955682Smarkm return FALSE; 97055682Smarkm return krb5_principal_compare_any_realm(context, princ1, princ2); 97155682Smarkm} 97255682Smarkm 973233294Sstas/** 97472445Sassar * return TRUE iff realm(princ1) == realm(princ2) 975233294Sstas * 976233294Sstas * @param context Kerberos 5 context 977233294Sstas * @param princ1 first principal to compare 978233294Sstas * @param princ2 second principal to compare 979233294Sstas * 980233294Sstas * @ingroup krb5_principal 981233294Sstas * @see krb5_principal_compare_any_realm() 982233294Sstas * @see krb5_principal_compare() 98372445Sassar */ 98455682Smarkm 985233294SstasKRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL 98655682Smarkmkrb5_realm_compare(krb5_context context, 98755682Smarkm krb5_const_principal princ1, 98855682Smarkm krb5_const_principal princ2) 98955682Smarkm{ 99055682Smarkm return strcmp(princ_realm(princ1), princ_realm(princ2)) == 0; 99155682Smarkm} 99255682Smarkm 993233294Sstas/** 99472445Sassar * return TRUE iff princ matches pattern 995233294Sstas * 996233294Sstas * @ingroup krb5_principal 99772445Sassar */ 99872445Sassar 999233294SstasKRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL 100072445Sassarkrb5_principal_match(krb5_context context, 100172445Sassar krb5_const_principal princ, 100272445Sassar krb5_const_principal pattern) 100372445Sassar{ 1004233294Sstas size_t i; 100572445Sassar if(princ_num_comp(princ) != princ_num_comp(pattern)) 100672445Sassar return FALSE; 100772445Sassar if(fnmatch(princ_realm(pattern), princ_realm(princ), 0) != 0) 100872445Sassar return FALSE; 100972445Sassar for(i = 0; i < princ_num_comp(princ); i++){ 101072445Sassar if(fnmatch(princ_ncomp(pattern, i), princ_ncomp(princ, i), 0) != 0) 101172445Sassar return FALSE; 101272445Sassar } 101372445Sassar return TRUE; 101472445Sassar} 101572445Sassar 1016233294Sstas/** 1017233294Sstas * Create a principal for the service running on hostname. If 1018233294Sstas * KRB5_NT_SRV_HST is used, the hostname is canonization using DNS (or 1019233294Sstas * some other service), this is potentially insecure. 1020233294Sstas * 1021233294Sstas * @param context A Kerberos context. 1022233294Sstas * @param hostname hostname to use 1023233294Sstas * @param sname Service name to use 1024233294Sstas * @param type name type of pricipal, use KRB5_NT_SRV_HST or KRB5_NT_UNKNOWN. 1025233294Sstas * @param ret_princ return principal, free with krb5_free_principal(). 1026233294Sstas * 1027233294Sstas * @return An krb5 error code, see krb5_get_error_message(). 1028233294Sstas * 1029233294Sstas * @ingroup krb5_principal 103072445Sassar */ 103172445Sassar 1032233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 103355682Smarkmkrb5_sname_to_principal (krb5_context context, 103455682Smarkm const char *hostname, 103555682Smarkm const char *sname, 103655682Smarkm int32_t type, 103755682Smarkm krb5_principal *ret_princ) 103855682Smarkm{ 103955682Smarkm krb5_error_code ret; 104072445Sassar char localhost[MAXHOSTNAMELEN]; 104155682Smarkm char **realms, *host = NULL; 1042233294Sstas 104378527Sassar if(type != KRB5_NT_SRV_HST && type != KRB5_NT_UNKNOWN) { 1044233294Sstas krb5_set_error_message(context, KRB5_SNAME_UNSUPP_NAMETYPE, 1045233294Sstas N_("unsupported name type %d", ""), 1046233294Sstas (int)type); 104755682Smarkm return KRB5_SNAME_UNSUPP_NAMETYPE; 104878527Sassar } 104955682Smarkm if(hostname == NULL) { 1050233294Sstas ret = gethostname(localhost, sizeof(localhost) - 1); 1051233294Sstas if (ret != 0) { 1052233294Sstas ret = errno; 1053233294Sstas krb5_set_error_message(context, ret, 1054233294Sstas N_("Failed to get local hostname", "")); 1055233294Sstas return ret; 1056233294Sstas } 1057233294Sstas localhost[sizeof(localhost) - 1] = '\0'; 105855682Smarkm hostname = localhost; 105955682Smarkm } 106055682Smarkm if(sname == NULL) 106155682Smarkm sname = "host"; 106255682Smarkm if(type == KRB5_NT_SRV_HST) { 106357416Smarkm ret = krb5_expand_hostname_realms (context, hostname, 106457416Smarkm &host, &realms); 106555682Smarkm if (ret) 106655682Smarkm return ret; 106755682Smarkm strlwr(host); 106855682Smarkm hostname = host; 106957416Smarkm } else { 107057416Smarkm ret = krb5_get_host_realm(context, hostname, &realms); 107157416Smarkm if(ret) 107257416Smarkm return ret; 107355682Smarkm } 107455682Smarkm 107555682Smarkm ret = krb5_make_principal(context, ret_princ, realms[0], sname, 107655682Smarkm hostname, NULL); 107755682Smarkm if(host) 107855682Smarkm free(host); 107955682Smarkm krb5_free_host_realm(context, realms); 108055682Smarkm return ret; 108155682Smarkm} 1082178825Sdfr 1083178825Sdfrstatic const struct { 1084178825Sdfr const char *type; 1085178825Sdfr int32_t value; 1086178825Sdfr} nametypes[] = { 1087178825Sdfr { "UNKNOWN", KRB5_NT_UNKNOWN }, 1088178825Sdfr { "PRINCIPAL", KRB5_NT_PRINCIPAL }, 1089178825Sdfr { "SRV_INST", KRB5_NT_SRV_INST }, 1090178825Sdfr { "SRV_HST", KRB5_NT_SRV_HST }, 1091178825Sdfr { "SRV_XHST", KRB5_NT_SRV_XHST }, 1092178825Sdfr { "UID", KRB5_NT_UID }, 1093178825Sdfr { "X500_PRINCIPAL", KRB5_NT_X500_PRINCIPAL }, 1094178825Sdfr { "SMTP_NAME", KRB5_NT_SMTP_NAME }, 1095178825Sdfr { "ENTERPRISE_PRINCIPAL", KRB5_NT_ENTERPRISE_PRINCIPAL }, 1096178825Sdfr { "ENT_PRINCIPAL_AND_ID", KRB5_NT_ENT_PRINCIPAL_AND_ID }, 1097178825Sdfr { "MS_PRINCIPAL", KRB5_NT_MS_PRINCIPAL }, 1098178825Sdfr { "MS_PRINCIPAL_AND_ID", KRB5_NT_MS_PRINCIPAL_AND_ID }, 1099233294Sstas { NULL, 0 } 1100178825Sdfr}; 1101178825Sdfr 1102233294Sstas/** 1103233294Sstas * Parse nametype string and return a nametype integer 1104233294Sstas * 1105233294Sstas * @ingroup krb5_principal 1106233294Sstas */ 1107233294Sstas 1108233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1109178825Sdfrkrb5_parse_nametype(krb5_context context, const char *str, int32_t *nametype) 1110178825Sdfr{ 1111178825Sdfr size_t i; 1112233294Sstas 1113178825Sdfr for(i = 0; nametypes[i].type; i++) { 1114178825Sdfr if (strcasecmp(nametypes[i].type, str) == 0) { 1115178825Sdfr *nametype = nametypes[i].value; 1116178825Sdfr return 0; 1117178825Sdfr } 1118178825Sdfr } 1119233294Sstas krb5_set_error_message(context, KRB5_PARSE_MALFORMED, 1120233294Sstas N_("Failed to find name type %s", ""), str); 1121178825Sdfr return KRB5_PARSE_MALFORMED; 1122178825Sdfr} 1123233294Sstas 1124233294Sstas/** 1125233294Sstas * Check if the cname part of the principal is a krbtgt principal 1126233294Sstas * 1127233294Sstas * @ingroup krb5_principal 1128233294Sstas */ 1129233294Sstas 1130233294SstasKRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL 1131233294Sstaskrb5_principal_is_krbtgt(krb5_context context, krb5_const_principal p) 1132233294Sstas{ 1133233294Sstas return p->name.name_string.len == 2 && 1134233294Sstas strcmp(p->name.name_string.val[0], KRB5_TGS_NAME) == 0; 1135233294Sstas 1136233294Sstas} 1137