root/source4/heimdal/lib/gssapi/krb5/import_name.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. parse_krb5_name
  2. import_krb5_name
  3. _gsskrb5_canon_name
  4. import_hostbased_name
  5. import_export_name

   1 /*
   2  * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
   3  * (Royal Institute of Technology, Stockholm, Sweden).
   4  * All rights reserved.
   5  *
   6  * Redistribution and use in source and binary forms, with or without
   7  * modification, are permitted provided that the following conditions
   8  * are met:
   9  *
  10  * 1. Redistributions of source code must retain the above copyright
  11  *    notice, this list of conditions and the following disclaimer.
  12  *
  13  * 2. Redistributions in binary form must reproduce the above copyright
  14  *    notice, this list of conditions and the following disclaimer in the
  15  *    documentation and/or other materials provided with the distribution.
  16  *
  17  * 3. Neither the name of the Institute nor the names of its contributors
  18  *    may be used to endorse or promote products derived from this software
  19  *    without specific prior written permission.
  20  *
  21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
  22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
  25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31  * SUCH DAMAGE.
  32  */
  33 
  34 #include "krb5/gsskrb5_locl.h"
  35 
  36 RCSID("$Id$");
  37 
  38 static OM_uint32
  39 parse_krb5_name (OM_uint32 *minor_status,
     /* [<][>][^][v][top][bottom][index][help] */
  40                  krb5_context context,
  41                  const char *name,
  42                  gss_name_t *output_name)
  43 {
  44     krb5_principal princ;
  45     krb5_error_code kerr;
  46 
  47     kerr = krb5_parse_name (context, name, &princ);
  48 
  49     if (kerr == 0) {
  50         *output_name = (gss_name_t)princ;
  51         return GSS_S_COMPLETE;
  52     }
  53     *minor_status = kerr;
  54 
  55     if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED)
  56         return GSS_S_BAD_NAME;
  57 
  58     return GSS_S_FAILURE;
  59 }
  60 
  61 static OM_uint32
  62 import_krb5_name (OM_uint32 *minor_status,
     /* [<][>][^][v][top][bottom][index][help] */
  63                   krb5_context context,
  64                   const gss_buffer_t input_name_buffer,
  65                   gss_name_t *output_name)
  66 {
  67     OM_uint32 ret;
  68     char *tmp;
  69 
  70     tmp = malloc (input_name_buffer->length + 1);
  71     if (tmp == NULL) {
  72         *minor_status = ENOMEM;
  73         return GSS_S_FAILURE;
  74     }
  75     memcpy (tmp,
  76             input_name_buffer->value,
  77             input_name_buffer->length);
  78     tmp[input_name_buffer->length] = '\0';
  79 
  80     ret = parse_krb5_name(minor_status, context, tmp, output_name);
  81     free(tmp);
  82 
  83     return ret;
  84 }
  85 
  86 OM_uint32
  87 _gsskrb5_canon_name(OM_uint32 *minor_status, krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
  88                     int use_dns, gss_name_t name, krb5_principal *out)
  89 {
  90     krb5_principal p = (krb5_principal)name;
  91     krb5_error_code ret;
  92     char *hostname = NULL, *service;
  93 
  94     *minor_status = 0;
  95 
  96     /* If its not a hostname */
  97     if (krb5_principal_get_type(context, p) != MAGIC_HOSTBASED_NAME_TYPE) {
  98         ret = krb5_copy_principal(context, p, out);
  99     } else if (!use_dns) {
 100         ret = krb5_copy_principal(context, p, out);
 101         if (ret == 0)
 102             krb5_principal_set_type(context, *out, KRB5_NT_SRV_HST);
 103     } else {
 104         if (p->name.name_string.len == 0)
 105             return GSS_S_BAD_NAME;
 106         else if (p->name.name_string.len > 1)
 107             hostname = p->name.name_string.val[1];
 108         
 109         service = p->name.name_string.val[0];
 110         
 111         ret = krb5_sname_to_principal(context,
 112                                       hostname,
 113                                       service,
 114                                       KRB5_NT_SRV_HST,
 115                                       out);
 116     }
 117 
 118     if (ret) {
 119         *minor_status = ret;
 120         return GSS_S_FAILURE;
 121     }
 122 
 123     return 0;
 124 }
 125 
 126 
 127 static OM_uint32
 128 import_hostbased_name (OM_uint32 *minor_status,
     /* [<][>][^][v][top][bottom][index][help] */
 129                        krb5_context context,
 130                        const gss_buffer_t input_name_buffer,
 131                        gss_name_t *output_name)
 132 {
 133     krb5_principal princ = NULL;
 134     krb5_error_code kerr;
 135     char *tmp, *p, *host = NULL;
 136 
 137     tmp = malloc (input_name_buffer->length + 1);
 138     if (tmp == NULL) {
 139         *minor_status = ENOMEM;
 140         return GSS_S_FAILURE;
 141     }
 142     memcpy (tmp,
 143             input_name_buffer->value,
 144             input_name_buffer->length);
 145     tmp[input_name_buffer->length] = '\0';
 146 
 147     p = strchr (tmp, '@');
 148     if (p != NULL) {
 149         *p = '\0';
 150         host = p + 1;
 151     }
 152 
 153     kerr = krb5_make_principal(context, &princ, NULL, tmp, host, NULL);
 154     free (tmp);
 155     *minor_status = kerr;
 156     if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED)
 157         return GSS_S_BAD_NAME;
 158     else if (kerr)
 159         return GSS_S_FAILURE;
 160 
 161     krb5_principal_set_type(context, princ, MAGIC_HOSTBASED_NAME_TYPE);
 162     *output_name = (gss_name_t)princ;
 163 
 164     return 0;
 165 }
 166 
 167 static OM_uint32
 168 import_export_name (OM_uint32 *minor_status,
     /* [<][>][^][v][top][bottom][index][help] */
 169                     krb5_context context,
 170                     const gss_buffer_t input_name_buffer,
 171                     gss_name_t *output_name)
 172 {
 173     unsigned char *p;
 174     uint32_t length;
 175     OM_uint32 ret;
 176     char *name;
 177 
 178     if (input_name_buffer->length < 10 + GSS_KRB5_MECHANISM->length)
 179         return GSS_S_BAD_NAME;
 180 
 181     /* TOK, MECH_OID_LEN, DER(MECH_OID), NAME_LEN, NAME */
 182 
 183     p = input_name_buffer->value;
 184 
 185     if (memcmp(&p[0], "\x04\x01\x00", 3) != 0 ||
 186         p[3] != GSS_KRB5_MECHANISM->length + 2 ||
 187         p[4] != 0x06 ||
 188         p[5] != GSS_KRB5_MECHANISM->length ||
 189         memcmp(&p[6], GSS_KRB5_MECHANISM->elements,
 190                GSS_KRB5_MECHANISM->length) != 0)
 191         return GSS_S_BAD_NAME;
 192 
 193     p += 6 + GSS_KRB5_MECHANISM->length;
 194 
 195     length = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
 196     p += 4;
 197 
 198     if (length > input_name_buffer->length - 10 - GSS_KRB5_MECHANISM->length)
 199         return GSS_S_BAD_NAME;
 200 
 201     name = malloc(length + 1);
 202     if (name == NULL) {
 203         *minor_status = ENOMEM;
 204         return GSS_S_FAILURE;
 205     }
 206     memcpy(name, p, length);
 207     name[length] = '\0';
 208 
 209     ret = parse_krb5_name(minor_status, context, name, output_name);
 210     free(name);
 211 
 212     return ret;
 213 }
 214 
 215 OM_uint32 _gsskrb5_import_name
 216            (OM_uint32 * minor_status,
 217             const gss_buffer_t input_name_buffer,
 218             const gss_OID input_name_type,
 219             gss_name_t * output_name
 220            )
 221 {
 222     krb5_context context;
 223 
 224     *minor_status = 0;
 225     *output_name = GSS_C_NO_NAME;
 226 
 227     GSSAPI_KRB5_INIT (&context);
 228 
 229     if (gss_oid_equal(input_name_type, GSS_C_NT_HOSTBASED_SERVICE) ||
 230         gss_oid_equal(input_name_type, GSS_C_NT_HOSTBASED_SERVICE_X))
 231         return import_hostbased_name (minor_status,
 232                                       context,
 233                                       input_name_buffer,
 234                                       output_name);
 235     else if (gss_oid_equal(input_name_type, GSS_C_NO_OID)
 236              || gss_oid_equal(input_name_type, GSS_C_NT_USER_NAME)
 237              || gss_oid_equal(input_name_type, GSS_KRB5_NT_PRINCIPAL_NAME))
 238         /* default printable syntax */
 239         return import_krb5_name (minor_status,
 240                                  context,
 241                                  input_name_buffer,
 242                                  output_name);
 243     else if (gss_oid_equal(input_name_type, GSS_C_NT_EXPORT_NAME)) {
 244         return import_export_name(minor_status,
 245                                   context,
 246                                   input_name_buffer,
 247                                   output_name);
 248     } else {
 249         *minor_status = 0;
 250         return GSS_S_BAD_NAMETYPE;
 251     }
 252 }

/* [<][>][^][v][top][bottom][index][help] */