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