Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : dcerpc utility functions
5 :
6 : Copyright (C) Andrew Tridgell 2003
7 : Copyright (C) Jelmer Vernooij 2004
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "includes.h"
24 : #include "../lib/util/dlinklist.h"
25 : #include "librpc/ndr/libndr.h"
26 : #include "librpc/ndr/ndr_table.h"
27 : #undef strcasecmp
28 :
29 : static struct ndr_interface_list *ndr_interfaces;
30 :
31 : /*
32 : register a ndr interface table
33 : */
34 129276 : NTSTATUS ndr_table_register(const struct ndr_interface_table *table)
35 : {
36 : struct ndr_interface_list *l;
37 :
38 8209026 : for (l = ndr_interfaces; l; l = l->next) {
39 : /*
40 : * If no GUID is supplied, use the name to determine
41 : * uniquness.
42 : */
43 8079750 : if (GUID_all_zero(&table->syntax_id.uuid)) {
44 4070350 : if (strcmp(table->name,
45 3288330 : l->table->name) != 0) {
46 4427810 : continue;
47 : }
48 0 : DBG_ERR("Attempt to register interface %s which has the "
49 : "same name as already registered interface\n",
50 : table->name);
51 : } else {
52 4791420 : if (!GUID_equal(&table->syntax_id.uuid,
53 4791420 : &l->table->syntax_id.uuid)) {
54 4791420 : continue;
55 : }
56 0 : DBG_ERR("Attempt to register interface %s which has the "
57 : "same UUID as already registered interface %s\n",
58 : table->name, l->table->name);
59 : }
60 0 : return NT_STATUS_OBJECT_NAME_COLLISION;
61 : }
62 :
63 : /*
64 : * This is a singleton instance guarenteed
65 : * by the above check to be only added once
66 : * into the list so we can allocate off the NULL
67 : * context. We never want this to be freed
68 : * until process shutdown. If needed we could
69 : * add a deregister function that walks and
70 : * frees the list.
71 : */
72 :
73 129276 : l = talloc(NULL, struct ndr_interface_list);
74 129276 : l->table = table;
75 :
76 129276 : DLIST_ADD(ndr_interfaces, l);
77 :
78 129276 : return NT_STATUS_OK;
79 : }
80 :
81 : /*
82 : find the pipe name for a local IDL interface
83 : */
84 261 : const char *ndr_interface_name(const struct GUID *uuid, uint32_t if_version)
85 : {
86 : const struct ndr_interface_list *l;
87 30144 : for (l=ndr_table_list();l;l=l->next) {
88 30399 : if (GUID_equal(&l->table->syntax_id.uuid, uuid) &&
89 258 : l->table->syntax_id.if_version == if_version) {
90 258 : return l->table->name;
91 : }
92 : }
93 3 : return "UNKNOWN";
94 : }
95 :
96 : /*
97 : find the number of calls defined by local IDL
98 : */
99 0 : int ndr_interface_num_calls(const struct GUID *uuid, uint32_t if_version)
100 : {
101 : const struct ndr_interface_list *l;
102 0 : for (l=ndr_table_list();l;l=l->next){
103 0 : if (GUID_equal(&l->table->syntax_id.uuid, uuid) &&
104 0 : l->table->syntax_id.if_version == if_version) {
105 0 : return l->table->num_calls;
106 : }
107 : }
108 0 : return -1;
109 : }
110 :
111 :
112 : /*
113 : find a dcerpc interface by name
114 : */
115 2 : const struct ndr_interface_table *ndr_table_by_name(const char *name)
116 : {
117 : const struct ndr_interface_list *l;
118 212 : for (l=ndr_table_list();l;l=l->next) {
119 212 : if (strcasecmp(l->table->name, name) == 0) {
120 2 : return l->table;
121 : }
122 : }
123 0 : return NULL;
124 : }
125 :
126 : /*
127 : find a dcerpc interface by syntax
128 : */
129 0 : const struct ndr_interface_table *ndr_table_by_syntax(const struct ndr_syntax_id *syntax)
130 : {
131 : const struct ndr_interface_list *l;
132 0 : if (GUID_all_zero(&syntax->uuid)) {
133 : /* These are not unique */
134 0 : return NULL;
135 : }
136 0 : for (l=ndr_table_list();l;l=l->next) {
137 0 : if (ndr_syntax_id_equal(&l->table->syntax_id, syntax)) {
138 0 : return l->table;
139 : }
140 : }
141 0 : return NULL;
142 : }
143 :
144 : /*
145 : find a dcerpc interface by uuid
146 : */
147 0 : const struct ndr_interface_table *ndr_table_by_uuid(const struct GUID *uuid)
148 : {
149 : const struct ndr_interface_list *l;
150 0 : if (GUID_all_zero(uuid)) {
151 : /* These are not unique */
152 0 : return NULL;
153 : }
154 0 : for (l=ndr_table_list();l;l=l->next) {
155 0 : if (GUID_equal(&l->table->syntax_id.uuid, uuid)) {
156 0 : return l->table;
157 : }
158 : }
159 0 : return NULL;
160 : }
161 :
162 : /*
163 : return the list of registered dcerpc_pipes
164 : */
165 274 : const struct ndr_interface_list *ndr_table_list(void)
166 : {
167 274 : ndr_table_init();
168 274 : return ndr_interfaces;
169 : }
170 :
171 :
172 1292 : NTSTATUS ndr_table_init(void)
173 : {
174 : static bool initialized = false;
175 :
176 1292 : if (initialized) return NT_STATUS_OK;
177 1026 : initialized = true;
178 :
179 1026 : ndr_table_register_builtin_tables();
180 :
181 1026 : return NT_STATUS_OK;
182 : }
|