1 /*- 2 * Copyright (c) 2005 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #include <gssapi/gssapi.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <errno.h> 33 34 #include "mech_switch.h" 35 #include "name.h" 36 37 /* 38 * The implementation must reserve static storage for a 39 * gss_OID_desc object containing the value 40 * {10, (void *)"\x2a\x86\x48\x86\xf7\x12" 41 * "\x01\x02\x01\x01"}, 42 * corresponding to an object-identifier value of 43 * {iso(1) member-body(2) United States(840) mit(113554) 44 * infosys(1) gssapi(2) generic(1) user_name(1)}. The constant 45 * GSS_C_NT_USER_NAME should be initialized to point 46 * to that gss_OID_desc. 47 */ 48 static gss_OID_desc GSS_C_NT_USER_NAME_storage = 49 {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01"}; 50 gss_OID GSS_C_NT_USER_NAME = &GSS_C_NT_USER_NAME_storage; 51 52 /* 53 * The implementation must reserve static storage for a 54 * gss_OID_desc object containing the value 55 * {10, (void *)"\x2a\x86\x48\x86\xf7\x12" 56 * "\x01\x02\x01\x02"}, 57 * corresponding to an object-identifier value of 58 * {iso(1) member-body(2) United States(840) mit(113554) 59 * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}. 60 * The constant GSS_C_NT_MACHINE_UID_NAME should be 61 * initialized to point to that gss_OID_desc. 62 */ 63 static gss_OID_desc GSS_C_NT_MACHINE_UID_NAME_storage = 64 {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02"}; 65 gss_OID GSS_C_NT_MACHINE_UID_NAME = &GSS_C_NT_MACHINE_UID_NAME_storage; 66 67 /* 68 * The implementation must reserve static storage for a 69 * gss_OID_desc object containing the value 70 * {10, (void *)"\x2a\x86\x48\x86\xf7\x12" 71 * "\x01\x02\x01\x03"}, 72 * corresponding to an object-identifier value of 73 * {iso(1) member-body(2) United States(840) mit(113554) 74 * infosys(1) gssapi(2) generic(1) string_uid_name(3)}. 75 * The constant GSS_C_NT_STRING_UID_NAME should be 76 * initialized to point to that gss_OID_desc. 77 */ 78 static gss_OID_desc GSS_C_NT_STRING_UID_NAME_storage = 79 {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03"}; 80 gss_OID GSS_C_NT_STRING_UID_NAME = &GSS_C_NT_STRING_UID_NAME_storage; 81 82 /* 83 * The implementation must reserve static storage for a 84 * gss_OID_desc object containing the value 85 * {6, (void *)"\x2b\x06\x01\x05\x06\x02"}, 86 * corresponding to an object-identifier value of 87 * {iso(1) org(3) dod(6) internet(1) security(5) 88 * nametypes(6) gss-host-based-services(2)). The constant 89 * GSS_C_NT_HOSTBASED_SERVICE_X should be initialized to point 90 * to that gss_OID_desc. This is a deprecated OID value, and 91 * implementations wishing to support hostbased-service names 92 * should instead use the GSS_C_NT_HOSTBASED_SERVICE OID, 93 * defined below, to identify such names; 94 * GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym 95 * for GSS_C_NT_HOSTBASED_SERVICE when presented as an input 96 * parameter, but should not be emitted by GSS-API 97 * implementations 98 */ 99 static gss_OID_desc GSS_C_NT_HOSTBASED_SERVICE_X_storage = 100 {6, (void *)"\x2b\x06\x01\x05\x06\x02"}; 101 gss_OID GSS_C_NT_HOSTBASED_SERVICE_X = &GSS_C_NT_HOSTBASED_SERVICE_X_storage; 102 103 /* 104 * The implementation must reserve static storage for a 105 * gss_OID_desc object containing the value 106 * {10, (void *)"\x2a\x86\x48\x86\xf7\x12" 107 * "\x01\x02\x01\x04"}, corresponding to an 108 * object-identifier value of {iso(1) member-body(2) 109 * Unites States(840) mit(113554) infosys(1) gssapi(2) 110 * generic(1) service_name(4)}. The constant 111 * GSS_C_NT_HOSTBASED_SERVICE should be initialized 112 * to point to that gss_OID_desc. 113 */ 114 static gss_OID_desc GSS_C_NT_HOSTBASED_SERVICE_storage = 115 {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04"}; 116 gss_OID GSS_C_NT_HOSTBASED_SERVICE = &GSS_C_NT_HOSTBASED_SERVICE_storage; 117 118 /* 119 * The implementation must reserve static storage for a 120 * gss_OID_desc object containing the value 121 * {6, (void *)"\x2b\x06\01\x05\x06\x03"}, 122 * corresponding to an object identifier value of 123 * {1(iso), 3(org), 6(dod), 1(internet), 5(security), 124 * 6(nametypes), 3(gss-anonymous-name)}. The constant 125 * and GSS_C_NT_ANONYMOUS should be initialized to point 126 * to that gss_OID_desc. 127 */ 128 static gss_OID_desc GSS_C_NT_ANONYMOUS_storage = 129 {6, (void *)"\x2b\x06\01\x05\x06\x03"}; 130 gss_OID GSS_C_NT_ANONYMOUS = &GSS_C_NT_ANONYMOUS_storage; 131 132 /* 133 * The implementation must reserve static storage for a 134 * gss_OID_desc object containing the value 135 * {6, (void *)"\x2b\x06\x01\x05\x06\x04"}, 136 * corresponding to an object-identifier value of 137 * {1(iso), 3(org), 6(dod), 1(internet), 5(security), 138 * 6(nametypes), 4(gss-api-exported-name)}. The constant 139 * GSS_C_NT_EXPORT_NAME should be initialized to point 140 * to that gss_OID_desc. 141 */ 142 static gss_OID_desc GSS_C_NT_EXPORT_NAME_storage = 143 {6, (void *)"\x2b\x06\x01\x05\x06\x04"}; 144 gss_OID GSS_C_NT_EXPORT_NAME = &GSS_C_NT_EXPORT_NAME_storage; 145 146 /* 147 * This name form shall be represented by the Object Identifier {iso(1) 148 * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2) 149 * krb5(2) krb5_name(1)}. The recommended symbolic name for this type 150 * is "GSS_KRB5_NT_PRINCIPAL_NAME". 151 */ 152 static gss_OID_desc GSS_KRB5_NT_PRINCIPAL_NAME_storage = 153 {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01"}; 154 gss_OID GSS_KRB5_NT_PRINCIPAL_NAME = &GSS_KRB5_NT_PRINCIPAL_NAME_storage; 155 156 /* 157 * This name form shall be represented by the Object Identifier {iso(1) 158 * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2) 159 * generic(1) user_name(1)}. The recommended symbolic name for this 160 * type is "GSS_KRB5_NT_USER_NAME". 161 */ 162 gss_OID GSS_KRB5_NT_USER_NAME = &GSS_C_NT_USER_NAME_storage; 163 164 /* 165 * This name form shall be represented by the Object Identifier {iso(1) 166 * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2) 167 * generic(1) machine_uid_name(2)}. The recommended symbolic name for 168 * this type is "GSS_KRB5_NT_MACHINE_UID_NAME". 169 */ 170 gss_OID GSS_KRB5_NT_MACHINE_UID_NAME = &GSS_C_NT_MACHINE_UID_NAME_storage; 171 172 /* 173 * This name form shall be represented by the Object Identifier {iso(1) 174 * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2) 175 * generic(1) string_uid_name(3)}. The recommended symbolic name for 176 * this type is "GSS_KRB5_NT_STRING_UID_NAME". 177 */ 178 gss_OID GSS_KRB5_NT_STRING_UID_NAME = &GSS_C_NT_STRING_UID_NAME_storage; 179 180 struct _gss_mechanism_name * 181 _gss_find_mn(struct _gss_name *name, gss_OID mech) 182 { 183 OM_uint32 major_status, minor_status; 184 struct _gss_mech_switch *m; 185 struct _gss_mechanism_name *mn; 186 187 SLIST_FOREACH(mn, &name->gn_mn, gmn_link) { 188 if (_gss_oid_equal(mech, mn->gmn_mech_oid)) 189 break; 190 } 191 192 if (!mn) { 193 /* 194 * If this name is canonical (i.e. there is only an 195 * MN but it is from a different mech), give up now. 196 */ 197 if (!name->gn_value.value) 198 return (0); 199 200 m = _gss_find_mech_switch(mech); 201 if (!m) 202 return (0); 203 204 mn = malloc(sizeof(struct _gss_mechanism_name)); 205 if (!mn) 206 return (0); 207 208 major_status = m->gm_import_name(&minor_status, 209 &name->gn_value, 210 (name->gn_type.elements 211 ? &name->gn_type : GSS_C_NO_OID), 212 &mn->gmn_name); 213 if (major_status) { 214 free(mn); 215 return (0); 216 } 217 218 mn->gmn_mech = m; 219 mn->gmn_mech_oid = &m->gm_mech_oid; 220 SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link); 221 } 222 return (mn); 223 } 224 225 /* 226 * Make a name from an MN. 227 */ 228 struct _gss_name * 229 _gss_make_name(struct _gss_mech_switch *m, gss_name_t new_mn) 230 { 231 OM_uint32 minor_status; 232 struct _gss_name *name; 233 struct _gss_mechanism_name *mn; 234 235 name = malloc(sizeof(struct _gss_name)); 236 if (!name) 237 return (0); 238 memset(name, 0, sizeof(struct _gss_name)); 239 240 mn = malloc(sizeof(struct _gss_mechanism_name)); 241 if (!mn) { 242 free(name); 243 return (0); 244 } 245 246 SLIST_INIT(&name->gn_mn); 247 mn->gmn_mech = m; 248 mn->gmn_mech_oid = &m->gm_mech_oid; 249 mn->gmn_name = new_mn; 250 SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link); 251 252 return (name); 253 } 254 255