s3: Make name_resolve_bcast return sockaddr_storage
[Samba.git] / source3 / rpc_server / srv_pipe_register.c
bloba6d654277ed53e94f8f4d2f95638bdf14d3ccb05
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Almost completely rewritten by (C) Jeremy Allison 2005 - 2010
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.
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.
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/>.
20 #include "includes.h"
21 #include "librpc/rpc/dcerpc.h"
22 #include "srv_pipe_internal.h"
24 #undef DBGC_CLASS
25 #define DBGC_CLASS DBGC_RPC_SRV
27 struct rpc_table {
28 struct {
29 const char *clnt;
30 const char *srv;
31 } pipe;
32 struct ndr_syntax_id rpc_interface;
33 const struct api_struct *cmds;
34 uint32_t n_cmds;
35 bool (*shutdown_fn)(void *private_data);
36 void *shutdown_data;
39 static struct rpc_table *rpc_lookup;
40 static uint32_t rpc_lookup_size;
42 static struct rpc_table *rpc_srv_get_pipe_by_id(const struct ndr_syntax_id *id)
44 uint32_t i;
46 for (i = 0; i < rpc_lookup_size; i++) {
47 if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface, id)) {
48 return &rpc_lookup[i];
52 return NULL;
55 bool rpc_srv_pipe_exists_by_id(const struct ndr_syntax_id *id)
57 uint32_t i;
59 for (i = 0; i < rpc_lookup_size; i++) {
60 if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface, id)) {
61 return true;
65 return false;
68 bool rpc_srv_pipe_exists_by_cli_name(const char *cli_name)
70 uint32_t i;
72 for (i = 0; i < rpc_lookup_size; i++) {
73 if (strequal(rpc_lookup[i].pipe.clnt, cli_name)) {
74 return true;
78 return false;
81 bool rpc_srv_pipe_exists_by_srv_name(const char *srv_name)
83 uint32_t i;
85 for (i = 0; i < rpc_lookup_size; i++) {
86 if (strequal(rpc_lookup[i].pipe.srv, srv_name)) {
87 return true;
91 return false;
94 const char *rpc_srv_get_pipe_cli_name(const struct ndr_syntax_id *id)
96 uint32_t i;
98 for (i = 0; i < rpc_lookup_size; i++) {
99 if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface, id)) {
100 return rpc_lookup[i].pipe.clnt;
104 return NULL;
107 const char *rpc_srv_get_pipe_srv_name(const struct ndr_syntax_id *id)
109 uint32_t i;
111 for (i = 0; i < rpc_lookup_size; i++) {
112 if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface, id)) {
113 return rpc_lookup[i].pipe.srv;
117 return NULL;
120 uint32_t rpc_srv_get_pipe_num_cmds(const struct ndr_syntax_id *id)
122 uint32_t i;
124 for (i = 0; i < rpc_lookup_size; i++) {
125 if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface, id)) {
126 return rpc_lookup[i].n_cmds;
130 return 0;
133 const struct api_struct *rpc_srv_get_pipe_cmds(const struct ndr_syntax_id *id)
135 uint32_t i;
137 for (i = 0; i < rpc_lookup_size; i++) {
138 if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface, id)) {
139 return rpc_lookup[i].cmds;
143 return NULL;
146 bool rpc_srv_get_pipe_interface_by_cli_name(const char *cli_name,
147 struct ndr_syntax_id *id)
149 uint32_t i;
151 for (i = 0; i < rpc_lookup_size; i++) {
152 if (strequal(rpc_lookup[i].pipe.clnt, cli_name)) {
153 if (id) {
154 *id = rpc_lookup[i].rpc_interface;
156 return true;
160 return false;
163 /*******************************************************************
164 Register commands to an RPC pipe
165 *******************************************************************/
167 NTSTATUS rpc_srv_register(int version, const char *clnt, const char *srv,
168 const struct ndr_interface_table *iface,
169 const struct api_struct *cmds, int size,
170 const struct rpc_srv_callbacks *rpc_srv_cb)
172 struct rpc_table *rpc_entry;
174 if (!clnt || !srv || !cmds) {
175 return NT_STATUS_INVALID_PARAMETER;
178 if (version != SMB_RPC_INTERFACE_VERSION) {
179 DEBUG(0,("Can't register rpc commands!\n"
180 "You tried to register a rpc module with SMB_RPC_INTERFACE_VERSION %d"
181 ", while this version of samba uses version %d!\n",
182 version,SMB_RPC_INTERFACE_VERSION));
183 return NT_STATUS_OBJECT_TYPE_MISMATCH;
186 /* Don't register the same command twice */
187 if (rpc_srv_pipe_exists_by_id(&iface->syntax_id)) {
188 return NT_STATUS_OK;
192 * We use a temporary variable because this call can fail and
193 * rpc_lookup will still be valid afterwards. It could then succeed if
194 * called again later
196 rpc_lookup_size++;
197 rpc_entry = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(rpc_lookup, struct rpc_table, rpc_lookup_size);
198 if (NULL == rpc_entry) {
199 rpc_lookup_size--;
200 DEBUG(0, ("rpc_pipe_register_commands: memory allocation failed\n"));
201 return NT_STATUS_NO_MEMORY;
202 } else {
203 rpc_lookup = rpc_entry;
206 rpc_entry = rpc_lookup + (rpc_lookup_size - 1);
207 ZERO_STRUCTP(rpc_entry);
208 rpc_entry->pipe.clnt = SMB_STRDUP(clnt);
209 rpc_entry->pipe.srv = SMB_STRDUP(srv);
210 rpc_entry->rpc_interface = iface->syntax_id;
211 rpc_entry->cmds = cmds;
212 rpc_entry->n_cmds = size;
214 if (rpc_srv_cb != NULL) {
215 rpc_entry->shutdown_fn = rpc_srv_cb->shutdown;
216 rpc_entry->shutdown_data = rpc_srv_cb->private_data;
218 if (rpc_srv_cb->init != NULL &&
219 !rpc_srv_cb->init(rpc_srv_cb->private_data)) {
220 DEBUG(0, ("rpc_srv_register: Failed to call the %s "
221 "init function!\n", srv));
222 return NT_STATUS_UNSUCCESSFUL;
226 return NT_STATUS_OK;
229 NTSTATUS rpc_srv_unregister(const struct ndr_interface_table *iface)
231 struct rpc_table *rpc_entry = rpc_srv_get_pipe_by_id(&iface->syntax_id);
233 if (rpc_entry != NULL && rpc_entry->shutdown_fn != NULL) {
234 if (!rpc_entry->shutdown_fn(rpc_entry->shutdown_data)) {
235 DEBUG(0, ("rpc_srv_unregister: Failed to call the %s "
236 "init function!\n", rpc_entry->pipe.srv));
237 return NT_STATUS_UNSUCCESSFUL;
241 return NT_STATUS_OK;