1 /* 2 * Copyright 2002 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 8 /* 9 * lib/krb5/keytab/ktbase.c 10 * 11 * Copyright 1990 by the Massachusetts Institute of Technology. 12 * All Rights Reserved. 13 * 14 * Export of this software from the United States of America may 15 * require a specific license from the United States Government. 16 * It is the responsibility of any person or organization contemplating 17 * export to obtain such a license before exporting. 18 * 19 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 20 * distribute this software and its documentation for any purpose and 21 * without fee is hereby granted, provided that the above copyright 22 * notice appear in all copies and that both that copyright notice and 23 * this permission notice appear in supporting documentation, and that 24 * the name of M.I.T. not be used in advertising or publicity pertaining 25 * to distribution of the software without specific, written prior 26 * permission. Furthermore if you modify this software you must label 27 * your software as modified software and not distribute it in such a 28 * fashion that it might be confused with the original M.I.T. software. 29 * M.I.T. makes no representations about the suitability of 30 * this software for any purpose. It is provided "as is" without express 31 * or implied warranty. 32 * 33 * 34 * Registration functions for keytab. 35 */ 36 37 #include <k5-int.h> 38 39 extern krb5_kt_ops krb5_ktf_ops; 40 extern krb5_kt_ops krb5_kts_ops; 41 42 struct krb5_kt_typelist { 43 krb5_kt_ops *ops; 44 struct krb5_kt_typelist *next; 45 }; 46 static struct krb5_kt_typelist krb5_kt_typelist_dfl = { &krb5_kt_dfl_ops, 0 }; 47 static struct krb5_kt_typelist *kt_typehead = &krb5_kt_typelist_dfl; 48 49 /* 50 * Register a new key table type 51 * don't replace if it already exists; return an error instead. 52 */ 53 /*ARGSUSED*/ 54 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV 55 krb5_kt_register(context, ops) 56 krb5_context context; 57 krb5_kt_ops FAR *ops; 58 { 59 struct krb5_kt_typelist *t; 60 for (t = kt_typehead;t && strcmp(t->ops->prefix,ops->prefix);t = t->next) 61 ; 62 if (t) { 63 return KRB5_KT_TYPE_EXISTS; 64 } 65 if (!(t = (struct krb5_kt_typelist *) malloc(sizeof(*t)))) 66 return ENOMEM; 67 t->next = kt_typehead; 68 t->ops = ops; 69 kt_typehead = t; 70 return 0; 71 } 72 73 /* 74 * Resolve a key table name into a keytab object. 75 * 76 * The name is currently constrained to be of the form "type:residual"; 77 * 78 * The "type" portion corresponds to one of the registered key table 79 * types, while the "residual" portion is specific to the 80 * particular keytab type. 81 */ 82 83 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV 84 krb5_kt_resolve (context, name, ktid) 85 krb5_context context; 86 krb5_const char FAR *name; 87 krb5_keytab FAR *ktid; 88 { 89 struct krb5_kt_typelist *tlist; 90 char *pfx, *resid, *cp; 91 int pfxlen; 92 93 cp = strchr (name, ':'); 94 if (!cp) { 95 return (*krb5_kt_dfl_ops.resolve)(context, name, ktid); 96 } 97 98 pfxlen = cp - (char *)name; 99 resid = (char *)name + pfxlen + 1; 100 101 pfx = malloc (pfxlen+1); 102 if (!pfx) 103 return ENOMEM; 104 105 memcpy (pfx, name, pfxlen); 106 pfx[pfxlen] = '\0'; 107 108 *ktid = (krb5_keytab) 0; 109 110 for (tlist = kt_typehead; tlist; tlist = tlist->next) { 111 if (strcmp (tlist->ops->prefix, pfx) == 0) { 112 free(pfx); 113 return (*tlist->ops->resolve)(context, resid, ktid); 114 } 115 } 116 free(pfx); 117 return KRB5_KT_UNKNOWN_TYPE; 118 } 119 120 /* 121 * Routines to deal with externalizingt krb5_keytab. 122 * krb5_keytab_size(); 123 * krb5_keytab_externalize(); 124 * krb5_keytab_internalize(); 125 */ 126 static krb5_error_code krb5_keytab_size 127 KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *)); 128 static krb5_error_code krb5_keytab_externalize 129 KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *)); 130 static krb5_error_code krb5_keytab_internalize 131 KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *)); 132 133 /* 134 * Serialization entry for this type. 135 */ 136 static const krb5_ser_entry krb5_keytab_ser_entry = { 137 KV5M_KEYTAB, /* Type */ 138 krb5_keytab_size, /* Sizer routine */ 139 krb5_keytab_externalize, /* Externalize routine */ 140 krb5_keytab_internalize /* Internalize routine */ 141 }; 142 143 static krb5_error_code 144 krb5_keytab_size(kcontext, arg, sizep) 145 krb5_context kcontext; 146 krb5_pointer arg; 147 size_t *sizep; 148 { 149 krb5_error_code kret; 150 krb5_keytab keytab; 151 krb5_ser_handle shandle; 152 153 kret = EINVAL; 154 keytab = (krb5_keytab) arg; 155 shandle = (krb5_ser_handle) keytab->ops->serializer; 156 if ((keytab != NULL) && (keytab->ops) && 157 (shandle != NULL) && (shandle->sizer)) 158 kret = (*shandle->sizer)(kcontext, arg, sizep); 159 return(kret); 160 } 161 162 static krb5_error_code 163 krb5_keytab_externalize(kcontext, arg, buffer, lenremain) 164 krb5_context kcontext; 165 krb5_pointer arg; 166 krb5_octet **buffer; 167 size_t *lenremain; 168 { 169 krb5_error_code kret; 170 krb5_keytab keytab; 171 krb5_ser_handle shandle; 172 173 kret = EINVAL; 174 keytab = (krb5_keytab) arg; 175 shandle = (krb5_ser_handle) keytab->ops->serializer; 176 if ((keytab != NULL) && (keytab->ops) && 177 (shandle != NULL) && (shandle->externalizer)) 178 kret = (*shandle->externalizer)(kcontext, arg, buffer, lenremain); 179 return(kret); 180 } 181 182 static krb5_error_code 183 krb5_keytab_internalize(kcontext, argp, buffer, lenremain) 184 krb5_context kcontext; 185 krb5_pointer *argp; 186 krb5_octet **buffer; 187 size_t *lenremain; 188 { 189 krb5_error_code kret; 190 krb5_ser_handle shandle; 191 192 kret = EINVAL; 193 shandle = (krb5_ser_handle) krb5_kt_dfl_ops.serializer; 194 if ((shandle != NULL) && (shandle->internalizer)) 195 kret = (*shandle->internalizer)(kcontext, argp, buffer, lenremain); 196 return(kret); 197 } 198 199 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV 200 krb5_ser_keytab_init(kcontext) 201 krb5_context kcontext; 202 { 203 return(krb5_register_serializer(kcontext, &krb5_keytab_ser_entry)); 204 } 205