xref: /freebsd/crypto/krb5/src/lib/gssapi/mechglue/g_mechname.c (revision f1c4c3daccbaf3820f0e2224de53df12fc952fcc)
1 /*
2  * g_mechname.c --- registry of mechanism-specific name types
3  *
4  * This file contains a registry of mechanism-specific name types.  It
5  * is used to determine which name types not should be lazy evaluated,
6  * but rather evaluated on the spot.
7  */
8 
9 #include "mglueP.h"
10 #ifdef HAVE_STDLIB_H
11 #include <stdlib.h>
12 #endif
13 
14 #include <stdio.h>
15 #include <string.h>
16 #include <errno.h>
17 
18 static gss_mech_spec_name name_list = NULL;
19 
20 /*
21  * generic searching helper function.
22  */
23 static gss_mech_spec_name
search_mech_spec(gss_OID name_type)24 search_mech_spec(gss_OID name_type)
25 {
26     gss_mech_spec_name p;
27 
28     for (p = name_list; p; p = p->next) {
29 	if (g_OID_equal(name_type, p->name_type))
30 	    return p;
31     }
32     return NULL;
33 }
34 
35 /*
36  * Given a name_type, if it is specific to a mechanism, return the
37  * mechanism OID.  Otherwise, return NULL.
38  */
39 gss_OID
gss_find_mechanism_from_name_type(gss_OID name_type)40 gss_find_mechanism_from_name_type(gss_OID name_type)
41 {
42     gss_mech_spec_name p;
43 
44     p = search_mech_spec(name_type);
45     if (!p)
46 	return NULL;
47     return p->mech;
48 }
49 
50 /*
51  * This function adds a (name_type, mechanism) pair to the
52  * mechanism-specific name type registry.  If an entry for the
53  * name_type already exists, then zero out the mechanism entry.
54  * Otherwise, enter the pair into the registry.
55  */
56 OM_uint32
gss_add_mech_name_type(OM_uint32 * minor_status,gss_OID name_type,gss_OID mech)57 gss_add_mech_name_type(OM_uint32 *minor_status, gss_OID name_type,
58 		       gss_OID mech)
59 {
60     OM_uint32	major_status, tmp;
61     gss_mech_spec_name p;
62 
63     p = search_mech_spec(name_type);
64     if (p) {
65 	/*
66 	 * We found an entry for this name type; mark it as not being
67 	 * a mechanism-specific name type.
68 	 */
69 	if (p->mech) {
70 	    if (!g_OID_equal(mech, p->mech)) {
71 		generic_gss_release_oid(minor_status, &p->mech);
72 		p->mech = 0;
73 	    }
74 	}
75 	return GSS_S_COMPLETE;
76     }
77     p = malloc(sizeof(gss_mech_spec_name_desc));
78     if (!p) {
79 	*minor_status = ENOMEM;
80 	map_errcode(minor_status);
81 	goto allocation_failure;
82     }
83     p->name_type = 0;
84     p->mech = 0;
85 
86     major_status = generic_gss_copy_oid(minor_status, name_type,
87 					&p->name_type);
88     if (major_status) {
89 	map_errcode(minor_status);
90 	goto allocation_failure;
91     }
92     major_status = generic_gss_copy_oid(minor_status, mech,
93 					&p->mech);
94     if (major_status) {
95 	map_errcode(minor_status);
96 	goto allocation_failure;
97     }
98 
99     p->next = name_list;
100     p->prev = 0;
101     name_list = p;
102 
103     return GSS_S_COMPLETE;
104 
105 allocation_failure:
106     if (p) {
107 	if (p->mech)
108 	    generic_gss_release_oid(&tmp, &p->mech);
109 	if (p->name_type)
110 	    generic_gss_release_oid(&tmp, &p->name_type);
111 	free(p);
112     }
113     return GSS_S_FAILURE;
114 }
115