2 * Endpoint Mapper Functions
3 * DCERPC local endpoint mapper client routines
4 * Copyright (c) 2010 Andreas Schneider.
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/>.
21 #include "librpc/rpc/dcerpc.h"
22 #include "librpc/rpc/dcerpc_ep.h"
23 #include "../librpc/gen_ndr/ndr_epmapper_c.h"
24 #include "rpc_client/cli_pipe.h"
26 #define EPM_MAX_ANNOTATION_SIZE 64
28 NTSTATUS
dcerpc_binding_vector_create(TALLOC_CTX
*mem_ctx
,
29 const struct ndr_interface_table
*iface
,
32 struct dcerpc_binding_vector
**pbvec
)
34 struct dcerpc_binding_vector
*bvec
;
41 tmp_ctx
= talloc_stackframe();
42 if (tmp_ctx
== NULL
) {
43 return NT_STATUS_NO_MEMORY
;
46 ep_count
= iface
->endpoints
->count
;
48 bvec
= talloc_zero(tmp_ctx
, struct dcerpc_binding_vector
);
50 status
= NT_STATUS_NO_MEMORY
;
54 bvec
->bindings
= talloc_zero_array(bvec
, struct dcerpc_binding
, ep_count
);
55 if (bvec
->bindings
== NULL
) {
56 status
= NT_STATUS_NO_MEMORY
;
60 for (i
= 0; i
< ep_count
; i
++) {
61 struct dcerpc_binding
*b
;
63 b
= talloc_zero(bvec
->bindings
, struct dcerpc_binding
);
65 status
= NT_STATUS_NO_MEMORY
;
69 status
= dcerpc_parse_binding(b
, iface
->endpoints
->names
[i
], &b
);
70 if (!NT_STATUS_IS_OK(status
)) {
71 status
= NT_STATUS_UNSUCCESSFUL
;
75 b
->object
= iface
->syntax_id
;
77 switch (b
->transport
) {
79 b
->host
= talloc_asprintf(b
, "\\\\%s", global_myname());
80 if (b
->host
== NULL
) {
81 status
= NT_STATUS_NO_MEMORY
;
91 b
->endpoint
= talloc_asprintf(b
, "%u", port
);
92 if (b
->endpoint
== NULL
) {
93 status
= NT_STATUS_NO_MEMORY
;
99 if (ncalrpc
== NULL
) {
104 b
->endpoint
= talloc_asprintf(b
,
108 if (b
->endpoint
== NULL
) {
109 status
= NT_STATUS_NO_MEMORY
;
118 bvec
->bindings
[count
] = *b
;
124 *pbvec
= talloc_move(mem_ctx
, &bvec
);
126 status
= NT_STATUS_OK
;
128 talloc_free(tmp_ctx
);
133 static NTSTATUS
ep_register(TALLOC_CTX
*mem_ctx
,
134 const struct ndr_interface_table
*iface
,
135 const struct dcerpc_binding_vector
*bind_vec
,
136 const struct GUID
*object_guid
,
137 const char *annotation
,
140 struct dcerpc_binding_handle
**pbh
)
142 struct rpc_pipe_client
*cli
= NULL
;
143 struct dcerpc_binding_handle
*h
;
144 struct pipe_auth_data
*auth
;
145 const char *ncalrpc_sock
;
146 const char *rpcsrv_type
;
147 struct epm_entry_t
*entries
;
148 uint32_t num_ents
, i
;
150 uint32_t result
= EPMAPPER_STATUS_OK
;
154 return NT_STATUS_INVALID_PARAMETER
;
157 if (bind_vec
== NULL
|| bind_vec
->count
== 0) {
158 return NT_STATUS_INVALID_PARAMETER
;
161 tmp_ctx
= talloc_stackframe();
162 if (tmp_ctx
== NULL
) {
163 return NT_STATUS_NO_MEMORY
;
166 rpcsrv_type
= lp_parm_const_string(GLOBAL_SECTION_SNUM
,
167 "rpc_server", "epmapper",
170 if (StrCaseCmp(rpcsrv_type
, "embedded") == 0) {
171 static struct client_address client_id
;
173 strlcpy(client_id
.addr
, "localhost", sizeof(client_id
.addr
));
174 client_id
.name
= "localhost";
176 status
= rpcint_binding_handle(tmp_ctx
,
179 get_session_info_system(),
180 server_messaging_context(),
182 if (!NT_STATUS_IS_OK(status
)) {
183 DEBUG(1, ("dcerpc_ep_register: Could not connect to "
184 "epmapper (%s)", nt_errstr(status
)));
187 } else if (StrCaseCmp(rpcsrv_type
, "daemon") == 0) {
188 /* Connect to the endpoint mapper locally */
189 ncalrpc_sock
= talloc_asprintf(tmp_ctx
,
193 if (ncalrpc_sock
== NULL
) {
194 status
= NT_STATUS_NO_MEMORY
;
198 status
= rpc_pipe_open_ncalrpc(tmp_ctx
,
200 &ndr_table_epmapper
.syntax_id
,
202 if (!NT_STATUS_IS_OK(status
)) {
206 status
= rpccli_ncalrpc_bind_data(cli
, &auth
);
207 if (!NT_STATUS_IS_OK(status
)) {
208 DEBUG(0, ("Failed to initialize anonymous bind.\n"));
212 status
= rpc_pipe_bind(cli
, auth
);
213 if (!NT_STATUS_IS_OK(status
)) {
214 DEBUG(2, ("Failed to bind ncalrpc socket.\n"));
218 h
= cli
->binding_handle
;
220 status
= NT_STATUS_INVALID_PARAMETER
;
224 num_ents
= bind_vec
->count
;
225 entries
= talloc_array(tmp_ctx
, struct epm_entry_t
, num_ents
);
227 for (i
= 0; i
< num_ents
; i
++) {
228 struct dcerpc_binding
*map_binding
= &bind_vec
->bindings
[i
];
229 struct epm_twr_t
*map_tower
;
231 map_tower
= talloc_zero(entries
, struct epm_twr_t
);
232 if (map_tower
== NULL
) {
233 status
= NT_STATUS_NO_MEMORY
;
237 status
= dcerpc_binding_build_tower(entries
,
240 if (!NT_STATUS_IS_OK(status
)) {
244 entries
[i
].tower
= map_tower
;
245 if (annotation
== NULL
) {
246 entries
[i
].annotation
= talloc_strdup(entries
, "");
248 entries
[i
].annotation
= talloc_strndup(entries
,
250 EPM_MAX_ANNOTATION_SIZE
);
252 if (entries
[i
].annotation
== NULL
) {
253 status
= NT_STATUS_NO_MEMORY
;
257 if (object_guid
!= NULL
) {
258 entries
[i
].object
= *object_guid
;
260 entries
[i
].object
= map_binding
->object
.uuid
;
265 status
= dcerpc_epm_Delete(h
,
271 status
= dcerpc_epm_Insert(h
,
278 if (!NT_STATUS_IS_OK(status
)) {
279 DEBUG(0, ("dcerpc_ep_register: Could not insert tower (%s)\n",
283 if (result
!= EPMAPPER_STATUS_OK
) {
284 DEBUG(0, ("dcerpc_ep_register: Could not insert tower (0x%.8x)\n",
286 status
= NT_STATUS_UNSUCCESSFUL
;
291 *pbh
= talloc_move(mem_ctx
, &h
);
292 talloc_steal(*pbh
, cli
);
296 talloc_free(tmp_ctx
);
301 NTSTATUS
dcerpc_ep_register(TALLOC_CTX
*mem_ctx
,
302 const struct ndr_interface_table
*iface
,
303 const struct dcerpc_binding_vector
*bind_vec
,
304 const struct GUID
*object_guid
,
305 const char *annotation
,
306 struct dcerpc_binding_handle
**ph
)
308 return ep_register(mem_ctx
,
318 NTSTATUS
dcerpc_ep_register_noreplace(TALLOC_CTX
*mem_ctx
,
319 const struct ndr_interface_table
*iface
,
320 const struct dcerpc_binding_vector
*bind_vec
,
321 const struct GUID
*object_guid
,
322 const char *annotation
,
323 struct dcerpc_binding_handle
**ph
)
325 return ep_register(mem_ctx
,
335 NTSTATUS
dcerpc_ep_unregister(const struct ndr_interface_table
*iface
,
336 const struct dcerpc_binding_vector
*bind_vec
,
337 const struct GUID
*object_guid
)
339 return ep_register(NULL
,
349 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */