📄 principal.c
字号:
/* * Copyright (c) 1997-2007 Kungliga Tekniska H鰃skolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *//** * @page page_principal The principal handing functions. * * A Kerberos principal is a email address looking string that * contains to parts separeted by a @. The later part is the kerbero * realm the principal belongs to and the former is a list of 0 or * more components. For example * @verbatimlha@SU.SEhost/hummel.it.su.se@SU.SEhost/admin@H5L.ORG@endverbatim * * See the library functions here: @ref krb5_principal */#include "krb5_locl.h"#ifdef HAVE_RES_SEARCH#define USE_RESOLVER#endif#ifdef HAVE_ARPA_NAMESER_H#include <arpa/nameser.h>#endif#include <fnmatch.h>#include "resolve.h"RCSID("$Id: principal.c 22549 2008-01-29 09:37:25Z lha $");#define princ_num_comp(P) ((P)->name.name_string.len)#define princ_type(P) ((P)->name.name_type)#define princ_comp(P) ((P)->name.name_string.val)#define princ_ncomp(P, N) ((P)->name.name_string.val[(N)])#define princ_realm(P) ((P)->realm)/** * Frees a Kerberos principal allocated by the library with * krb5_parse_name(), krb5_make_principal() or any other related * principal functions. * * @param context A Kerberos context. * @param p a principal to free. * * @return An krb5 error code, see krb5_get_error_message(). * * @ingroup krb5_principal */void KRB5_LIB_FUNCTIONkrb5_free_principal(krb5_context context, krb5_principal p){ if(p){ free_Principal(p); free(p); }}void KRB5_LIB_FUNCTIONkrb5_principal_set_type(krb5_context context, krb5_principal principal, int type){ princ_type(principal) = type;}int KRB5_LIB_FUNCTIONkrb5_principal_get_type(krb5_context context, krb5_const_principal principal){ return princ_type(principal);}const char* KRB5_LIB_FUNCTIONkrb5_principal_get_realm(krb5_context context, krb5_const_principal principal){ return princ_realm(principal);} const char* KRB5_LIB_FUNCTIONkrb5_principal_get_comp_string(krb5_context context, krb5_const_principal principal, unsigned int component){ if(component >= princ_num_comp(principal)) return NULL; return princ_ncomp(principal, component);}krb5_error_code KRB5_LIB_FUNCTIONkrb5_parse_name_flags(krb5_context context, const char *name, int flags, krb5_principal *principal){ krb5_error_code ret; heim_general_string *comp; heim_general_string realm = NULL; int ncomp; const char *p; char *q; char *s; char *start; int n; char c; int got_realm = 0; int first_at = 1; int enterprise = (flags & KRB5_PRINCIPAL_PARSE_ENTERPRISE); *principal = NULL;#define RFLAGS (KRB5_PRINCIPAL_PARSE_NO_REALM|KRB5_PRINCIPAL_PARSE_MUST_REALM) if ((flags & RFLAGS) == RFLAGS) { krb5_set_error_string(context, "Can't require both realm and " "no realm at the same time"); return KRB5_ERR_NO_SERVICE; }#undef RFLAGS /* count number of component, * enterprise names only have one component */ ncomp = 1; if (!enterprise) { for(p = name; *p; p++){ if(*p=='\\'){ if(!p[1]) { krb5_set_error_string (context, "trailing \\ in principal name"); return KRB5_PARSE_MALFORMED; } p++; } else if(*p == '/') ncomp++; else if(*p == '@') break; } } comp = calloc(ncomp, sizeof(*comp)); if (comp == NULL) { krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } n = 0; p = start = q = s = strdup(name); if (start == NULL) { free (comp); krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } while(*p){ c = *p++; if(c == '\\'){ c = *p++; if(c == 'n') c = '\n'; else if(c == 't') c = '\t'; else if(c == 'b') c = '\b'; else if(c == '0') c = '\0'; else if(c == '\0') { krb5_set_error_string (context, "trailing \\ in principal name"); ret = KRB5_PARSE_MALFORMED; goto exit; } }else if(enterprise && first_at) { if (c == '@') first_at = 0; }else if((c == '/' && !enterprise) || c == '@'){ if(got_realm){ krb5_set_error_string (context, "part after realm in principal name"); ret = KRB5_PARSE_MALFORMED; goto exit; }else{ comp[n] = malloc(q - start + 1); if (comp[n] == NULL) { krb5_set_error_string (context, "malloc: out of memory"); ret = ENOMEM; goto exit; } memcpy(comp[n], start, q - start); comp[n][q - start] = 0; n++; } if(c == '@') got_realm = 1; start = q; continue; } if(got_realm && (c == ':' || c == '/' || c == '\0')) { krb5_set_error_string (context, "part after realm in principal name"); ret = KRB5_PARSE_MALFORMED; goto exit; } *q++ = c; } if(got_realm){ if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) { krb5_set_error_string (context, "realm found in 'short' principal " "expected to be without one"); ret = KRB5_PARSE_MALFORMED; goto exit; } realm = malloc(q - start + 1); if (realm == NULL) { krb5_set_error_string (context, "malloc: out of memory"); ret = ENOMEM; goto exit; } memcpy(realm, start, q - start); realm[q - start] = 0; }else{ if (flags & KRB5_PRINCIPAL_PARSE_MUST_REALM) { krb5_set_error_string (context, "realm NOT found in principal " "expected to be with one"); ret = KRB5_PARSE_MALFORMED; goto exit; } else if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) { realm = NULL; } else { ret = krb5_get_default_realm (context, &realm); if (ret) goto exit; } comp[n] = malloc(q - start + 1); if (comp[n] == NULL) { krb5_set_error_string (context, "malloc: out of memory"); ret = ENOMEM; goto exit; } memcpy(comp[n], start, q - start); comp[n][q - start] = 0; n++; } *principal = malloc(sizeof(**principal)); if (*principal == NULL) { krb5_set_error_string (context, "malloc: out of memory"); ret = ENOMEM; goto exit; } if (enterprise) (*principal)->name.name_type = KRB5_NT_ENTERPRISE_PRINCIPAL; else (*principal)->name.name_type = KRB5_NT_PRINCIPAL; (*principal)->name.name_string.val = comp; princ_num_comp(*principal) = n; (*principal)->realm = realm; free(s); return 0;exit: while(n>0){ free(comp[--n]); } free(comp); free(realm); free(s); return ret;}krb5_error_code KRB5_LIB_FUNCTIONkrb5_parse_name(krb5_context context, const char *name, krb5_principal *principal){ return krb5_parse_name_flags(context, name, 0, principal);}static const char quotable_chars[] = " \n\t\b\\/@";static const char replace_chars[] = " ntb\\/@";static const char nq_chars[] = " \\/@";#define add_char(BASE, INDEX, LEN, C) do { if((INDEX) < (LEN)) (BASE)[(INDEX)++] = (C); }while(0);static size_tquote_string(const char *s, char *out, size_t idx, size_t len, int display){ const char *p, *q; for(p = s; *p && idx < len; p++){ q = strchr(quotable_chars, *p); if (q && display) { add_char(out, idx, len, replace_chars[q - quotable_chars]); } else if (q) { add_char(out, idx, len, '\\'); add_char(out, idx, len, replace_chars[q - quotable_chars]); }else add_char(out, idx, len, *p); } if(idx < len) out[idx] = '\0'; return idx;}static krb5_error_codeunparse_name_fixed(krb5_context context, krb5_const_principal principal, char *name, size_t len, int flags){ size_t idx = 0; int i; int short_form = (flags & KRB5_PRINCIPAL_UNPARSE_SHORT) != 0; int no_realm = (flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) != 0; int display = (flags & KRB5_PRINCIPAL_UNPARSE_DISPLAY) != 0; if (!no_realm && princ_realm(principal) == NULL) { krb5_set_error_string(context, "Realm missing from principal, " "can't unparse"); return ERANGE; } for(i = 0; i < princ_num_comp(principal); i++){ if(i) add_char(name, idx, len, '/'); idx = quote_string(princ_ncomp(principal, i), name, idx, len, display); if(idx == len) { krb5_set_error_string(context, "Out of space printing principal"); return ERANGE; } } /* add realm if different from default realm */ if(short_form && !no_realm) { krb5_realm r; krb5_error_code ret; ret = krb5_get_default_realm(context, &r); if(ret) return ret; if(strcmp(princ_realm(principal), r) != 0) short_form = 0; free(r); } if(!short_form && !no_realm) { add_char(name, idx, len, '@'); idx = quote_string(princ_realm(principal), name, idx, len, display); if(idx == len) { krb5_set_error_string(context, "Out of space printing realm of principal"); return ERANGE; } } return 0;}krb5_error_code KRB5_LIB_FUNCTIONkrb5_unparse_name_fixed(krb5_context context, krb5_const_principal principal, char *name, size_t len){ return unparse_name_fixed(context, principal, name, len, 0);}krb5_error_code KRB5_LIB_FUNCTIONkrb5_unparse_name_fixed_short(krb5_context context, krb5_const_principal principal, char *name, size_t len){ return unparse_name_fixed(context, principal, name, len, KRB5_PRINCIPAL_UNPARSE_SHORT);}krb5_error_code KRB5_LIB_FUNCTIONkrb5_unparse_name_fixed_flags(krb5_context context, krb5_const_principal principal, int flags, char *name, size_t len){ return unparse_name_fixed(context, principal, name, len, flags);}static krb5_error_codeunparse_name(krb5_context context, krb5_const_principal principal, char **name, int flags){ size_t len = 0, plen; int i; krb5_error_code ret; /* count length */ if (princ_realm(principal)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -