xref: /freebsd/crypto/krb5/src/lib/gssapi/mechglue/g_mechname.c (revision d0ff5773cefaf3fa41b1be3e44ca35bd9d5f68ee)
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(name_type)
24     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(name_type)
40     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
57 gss_add_mech_name_type(minor_status, name_type, mech)
58     OM_uint32	*minor_status;
59     gss_OID	name_type;
60     gss_OID	mech;
61 {
62     OM_uint32	major_status, tmp;
63     gss_mech_spec_name p;
64 
65     p = search_mech_spec(name_type);
66     if (p) {
67 	/*
68 	 * We found an entry for this name type; mark it as not being
69 	 * a mechanism-specific name type.
70 	 */
71 	if (p->mech) {
72 	    if (!g_OID_equal(mech, p->mech)) {
73 		generic_gss_release_oid(minor_status, &p->mech);
74 		p->mech = 0;
75 	    }
76 	}
77 	return GSS_S_COMPLETE;
78     }
79     p = malloc(sizeof(gss_mech_spec_name_desc));
80     if (!p) {
81 	*minor_status = ENOMEM;
82 	map_errcode(minor_status);
83 	goto allocation_failure;
84     }
85     p->name_type = 0;
86     p->mech = 0;
87 
88     major_status = generic_gss_copy_oid(minor_status, name_type,
89 					&p->name_type);
90     if (major_status) {
91 	map_errcode(minor_status);
92 	goto allocation_failure;
93     }
94     major_status = generic_gss_copy_oid(minor_status, mech,
95 					&p->mech);
96     if (major_status) {
97 	map_errcode(minor_status);
98 	goto allocation_failure;
99     }
100 
101     p->next = name_list;
102     p->prev = 0;
103     name_list = p;
104 
105     return GSS_S_COMPLETE;
106 
107 allocation_failure:
108     if (p) {
109 	if (p->mech)
110 	    generic_gss_release_oid(&tmp, &p->mech);
111 	if (p->name_type)
112 	    generic_gss_release_oid(&tmp, &p->name_type);
113 	free(p);
114     }
115     return GSS_S_FAILURE;
116 }
117