source: trunk/server/source3/rpc_server/srv_pipe_register.c@ 845

Last change on this file since 845 was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 6.0 KB
Line 
1/*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Almost completely rewritten by (C) Jeremy Allison 2005 - 2010
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "includes.h"
21#include "librpc/rpc/dcerpc.h"
22#include "srv_pipe_internal.h"
23#include "rpc_server/srv_pipe_register.h"
24
25#undef DBGC_CLASS
26#define DBGC_CLASS DBGC_RPC_SRV
27
28struct rpc_table {
29 struct {
30 const char *clnt;
31 const char *srv;
32 } pipe;
33 struct ndr_syntax_id rpc_interface;
34 const struct api_struct *cmds;
35 uint32_t n_cmds;
36 bool (*shutdown_fn)(void *private_data);
37 void *shutdown_data;
38};
39
40static struct rpc_table *rpc_lookup;
41static uint32_t rpc_lookup_size;
42
43static struct rpc_table *rpc_srv_get_pipe_by_id(const struct ndr_syntax_id *id)
44{
45 uint32_t i;
46
47 for (i = 0; i < rpc_lookup_size; i++) {
48 if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface, id)) {
49 return &rpc_lookup[i];
50 }
51 }
52
53 return NULL;
54}
55
56bool rpc_srv_pipe_exists_by_id(const struct ndr_syntax_id *id)
57{
58 uint32_t i;
59
60 for (i = 0; i < rpc_lookup_size; i++) {
61 if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface, id)) {
62 return true;
63 }
64 }
65
66 return false;
67}
68
69bool rpc_srv_pipe_exists_by_cli_name(const char *cli_name)
70{
71 uint32_t i;
72
73 for (i = 0; i < rpc_lookup_size; i++) {
74 if (strequal(rpc_lookup[i].pipe.clnt, cli_name)) {
75 return true;
76 }
77 }
78
79 return false;
80}
81
82bool rpc_srv_pipe_exists_by_srv_name(const char *srv_name)
83{
84 uint32_t i;
85
86 for (i = 0; i < rpc_lookup_size; i++) {
87 if (strequal(rpc_lookup[i].pipe.srv, srv_name)) {
88 return true;
89 }
90 }
91
92 return false;
93}
94
95const char *rpc_srv_get_pipe_cli_name(const struct ndr_syntax_id *id)
96{
97 uint32_t i;
98
99 for (i = 0; i < rpc_lookup_size; i++) {
100 if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface, id)) {
101 return rpc_lookup[i].pipe.clnt;
102 }
103 }
104
105 return NULL;
106}
107
108const char *rpc_srv_get_pipe_srv_name(const struct ndr_syntax_id *id)
109{
110 uint32_t i;
111
112 for (i = 0; i < rpc_lookup_size; i++) {
113 if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface, id)) {
114 return rpc_lookup[i].pipe.srv;
115 }
116 }
117
118 return NULL;
119}
120
121uint32_t rpc_srv_get_pipe_num_cmds(const struct ndr_syntax_id *id)
122{
123 uint32_t i;
124
125 for (i = 0; i < rpc_lookup_size; i++) {
126 if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface, id)) {
127 return rpc_lookup[i].n_cmds;
128 }
129 }
130
131 return 0;
132}
133
134const struct api_struct *rpc_srv_get_pipe_cmds(const struct ndr_syntax_id *id)
135{
136 uint32_t i;
137
138 for (i = 0; i < rpc_lookup_size; i++) {
139 if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface, id)) {
140 return rpc_lookup[i].cmds;
141 }
142 }
143
144 return NULL;
145}
146
147bool rpc_srv_get_pipe_interface_by_cli_name(const char *cli_name,
148 struct ndr_syntax_id *id)
149{
150 uint32_t i;
151
152 for (i = 0; i < rpc_lookup_size; i++) {
153 if (strequal(rpc_lookup[i].pipe.clnt, cli_name)) {
154 if (id) {
155 *id = rpc_lookup[i].rpc_interface;
156 }
157 return true;
158 }
159 }
160
161 return false;
162}
163
164/*******************************************************************
165 Register commands to an RPC pipe
166*******************************************************************/
167
168NTSTATUS rpc_srv_register(int version, const char *clnt, const char *srv,
169 const struct ndr_interface_table *iface,
170 const struct api_struct *cmds, int size,
171 const struct rpc_srv_callbacks *rpc_srv_cb)
172{
173 struct rpc_table *rpc_entry;
174
175 if (!clnt || !srv || !cmds) {
176 return NT_STATUS_INVALID_PARAMETER;
177 }
178
179 if (version != SMB_RPC_INTERFACE_VERSION) {
180 DEBUG(0,("Can't register rpc commands!\n"
181 "You tried to register a rpc module with SMB_RPC_INTERFACE_VERSION %d"
182 ", while this version of samba uses version %d!\n",
183 version,SMB_RPC_INTERFACE_VERSION));
184 return NT_STATUS_OBJECT_TYPE_MISMATCH;
185 }
186
187 /* Don't register the same command twice */
188 if (rpc_srv_pipe_exists_by_id(&iface->syntax_id)) {
189 return NT_STATUS_OK;
190 }
191
192 /*
193 * We use a temporary variable because this call can fail and
194 * rpc_lookup will still be valid afterwards. It could then succeed if
195 * called again later
196 */
197 rpc_lookup_size++;
198 rpc_entry = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(rpc_lookup, struct rpc_table, rpc_lookup_size);
199 if (NULL == rpc_entry) {
200 rpc_lookup_size--;
201 DEBUG(0, ("rpc_srv_register: memory allocation failed\n"));
202 return NT_STATUS_NO_MEMORY;
203 } else {
204 rpc_lookup = rpc_entry;
205 }
206
207 rpc_entry = rpc_lookup + (rpc_lookup_size - 1);
208 ZERO_STRUCTP(rpc_entry);
209 rpc_entry->pipe.clnt = SMB_STRDUP(clnt);
210 rpc_entry->pipe.srv = SMB_STRDUP(srv);
211 rpc_entry->rpc_interface = iface->syntax_id;
212 rpc_entry->cmds = cmds;
213 rpc_entry->n_cmds = size;
214
215 if (rpc_srv_cb != NULL) {
216 rpc_entry->shutdown_fn = rpc_srv_cb->shutdown;
217 rpc_entry->shutdown_data = rpc_srv_cb->private_data;
218
219 if (rpc_srv_cb->init != NULL &&
220 !rpc_srv_cb->init(rpc_srv_cb->private_data)) {
221 DEBUG(0, ("rpc_srv_register: Failed to call the %s "
222 "init function!\n", srv));
223 return NT_STATUS_UNSUCCESSFUL;
224 }
225 }
226
227 return NT_STATUS_OK;
228}
229
230NTSTATUS rpc_srv_unregister(const struct ndr_interface_table *iface)
231{
232 struct rpc_table *rpc_entry = rpc_srv_get_pipe_by_id(&iface->syntax_id);
233
234 if (rpc_entry != NULL && rpc_entry->shutdown_fn != NULL) {
235 if (!rpc_entry->shutdown_fn(rpc_entry->shutdown_data)) {
236 DEBUG(0, ("rpc_srv_unregister: Failed to call the %s "
237 "init function!\n", rpc_entry->pipe.srv));
238 return NT_STATUS_UNSUCCESSFUL;
239 }
240 }
241
242 return NT_STATUS_OK;
243}
Note: See TracBrowser for help on using the repository browser.