2 Unix SMB/CIFS implementation.
4 endpoint server for the epmapper pipe
6 Copyright (C) Andrew Tridgell 2003
7 Copyright (C) Jelmer Vernooij 2004
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 2 of the License, or
12 (at your option) any later version.
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.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "librpc/gen_ndr/ndr_epmapper.h"
26 #include "rpc_server/dcerpc_server.h"
27 #include "rpc_server/common/common.h"
29 typedef uint32_t error_status_t
;
31 /* handle types for this module */
32 enum handle_types
{HTYPE_LOOKUP
};
34 /* a endpoint combined with an interface description */
35 struct dcesrv_ep_iface
{
41 simple routine to compare a GUID string to a GUID structure
43 static int guid_cmp(TALLOC_CTX
*mem_ctx
, const struct GUID
*guid
, const char *uuid_str
)
45 const char *s
= GUID_string(mem_ctx
, guid
);
46 if (!s
|| strcasecmp(s
, uuid_str
)) {
53 build a list of all interfaces handled by all endpoint servers
55 static uint32_t build_ep_list(TALLOC_CTX
*mem_ctx
,
56 struct dcesrv_endpoint
*endpoint_list
,
57 struct dcesrv_ep_iface
**eps
)
59 struct dcesrv_endpoint
*d
;
65 for (d
=endpoint_list
; d
; d
=d
->next
) {
66 struct dcesrv_if_list
*iface
;
67 struct dcerpc_binding description
;
69 for (iface
=d
->interface_list
;iface
;iface
=iface
->next
) {
70 (*eps
) = talloc_realloc_p(mem_ctx
,
72 struct dcesrv_ep_iface
,
77 (*eps
)[total
].name
= iface
->iface
.name
;
79 description
= d
->ep_description
;
80 GUID_from_string(iface
->iface
.uuid
, &description
.object
);
81 description
.object_version
= iface
->iface
.if_version
;
83 status
= dcerpc_binding_build_tower(mem_ctx
, &description
, &(*eps
)[total
].ep
);
84 if (NT_STATUS_IS_ERR(status
)) {
85 DEBUG(1, ("Unable to build tower for %s\n", iface
->iface
.name
));
96 static error_status_t
epm_Insert(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
99 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
102 static error_status_t
epm_Delete(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
103 struct epm_Delete
*r
)
105 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
110 implement epm_Lookup. This call is used to enumerate the interfaces
111 available on a rpc server
113 static error_status_t
epm_Lookup(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
114 struct epm_Lookup
*r
)
116 struct dcesrv_handle
*h
;
119 struct dcesrv_ep_iface
*e
;
124 DCESRV_PULL_HANDLE_FAULT(h
, r
->in
.entry_handle
, HTYPE_LOOKUP
);
129 /* this is the first call - fill the list. Subsequent calls
130 will feed from this list, stored in the handle */
131 eps
= talloc_p(h
, struct rpc_eps
);
133 return EPMAPPER_STATUS_NO_MEMORY
;
137 eps
->count
= build_ep_list(h
, dce_call
->conn
->dce_ctx
->endpoint_list
, &eps
->e
);
140 /* return the next N elements */
141 num_ents
= r
->in
.max_ents
;
142 if (num_ents
> eps
->count
) {
143 num_ents
= eps
->count
;
146 *r
->out
.entry_handle
= h
->wire_handle
;
147 r
->out
.num_ents
= num_ents
;
150 r
->out
.entries
= NULL
;
151 ZERO_STRUCTP(r
->out
.entry_handle
);
153 return EPMAPPER_STATUS_NO_MORE_ENTRIES
;
156 r
->out
.entries
= talloc_array_p(mem_ctx
, struct epm_entry_t
, num_ents
);
157 if (!r
->out
.entries
) {
158 return EPMAPPER_STATUS_NO_MEMORY
;
161 for (i
=0;i
<num_ents
;i
++) {
162 ZERO_STRUCT(r
->out
.entries
[i
].object
);
163 r
->out
.entries
[i
].annotation
= eps
->e
[i
].name
;
164 r
->out
.entries
[i
].tower
= talloc_p(mem_ctx
, struct epm_twr_t
);
165 if (!r
->out
.entries
[i
].tower
) {
166 return EPMAPPER_STATUS_NO_MEMORY
;
168 r
->out
.entries
[i
].tower
->tower
= eps
->e
[i
].ep
;
171 eps
->count
-= num_ents
;
174 return EPMAPPER_STATUS_OK
;
179 implement epm_Map. This is used to find the specific endpoint to talk to given
180 a generic protocol tower
182 static error_status_t
epm_Map(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
187 struct dcesrv_ep_iface
*eps
;
188 struct epm_floor
*floors
;
189 enum dcerpc_transport_t transport
;
191 count
= build_ep_list(mem_ctx
, dce_call
->conn
->dce_ctx
->endpoint_list
, &eps
);
193 ZERO_STRUCT(*r
->out
.entry_handle
);
194 r
->out
.num_towers
= 1;
195 r
->out
.towers
= talloc_p(mem_ctx
, struct epm_twr_p_t
);
196 if (!r
->out
.towers
) {
197 return EPMAPPER_STATUS_NO_MEMORY
;
199 r
->out
.towers
->twr
= talloc_p(mem_ctx
, struct epm_twr_t
);
200 if (!r
->out
.towers
->twr
) {
201 return EPMAPPER_STATUS_NO_MEMORY
;
204 if (!r
->in
.map_tower
|| r
->in
.max_towers
== 0 ||
205 r
->in
.map_tower
->tower
.num_floors
< 3) {
209 floors
= r
->in
.map_tower
->tower
.floors
;
211 if (floors
[1].lhs
.protocol
!= EPM_PROTOCOL_UUID
||
212 guid_cmp(mem_ctx
, &floors
[1].lhs
.info
.uuid
.uuid
, NDR_GUID
) != 0 ||
213 floors
[1].lhs
.info
.uuid
.version
!= NDR_GUID_VERSION
) {
217 transport
= dcerpc_transport_by_tower(&r
->in
.map_tower
->tower
);
219 if (transport
== -1) {
220 DEBUG(1, ("Client requested unknown transport with levels: "));
221 for (i
= 2; i
< r
->in
.map_tower
->tower
.num_floors
; i
++) {
222 DEBUG(1, ("%d, ", r
->in
.map_tower
->tower
.floors
[i
].lhs
.protocol
));
227 for (i
=0;i
<count
;i
++) {
228 if (!GUID_equal(&r
->in
.map_tower
->tower
.floors
[0].lhs
.info
.uuid
.uuid
,
229 &eps
[i
].ep
.floors
[0].lhs
.info
.uuid
.uuid
) ||
230 r
->in
.map_tower
->tower
.floors
[0].lhs
.info
.uuid
.version
!=
231 eps
[i
].ep
.floors
[0].lhs
.info
.uuid
.version
||
232 transport
!= dcerpc_transport_by_tower(&eps
[i
].ep
)) {
236 r
->out
.towers
->twr
->tower
= eps
[i
].ep
;
237 r
->out
.towers
->twr
->tower_length
= 0;
238 return EPMAPPER_STATUS_OK
;
243 r
->out
.num_towers
= 0;
244 r
->out
.towers
->twr
= NULL
;
246 return EPMAPPER_STATUS_NO_MORE_ENTRIES
;
249 static error_status_t
epm_LookupHandleFree(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
250 struct epm_LookupHandleFree
*r
)
252 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
255 static error_status_t
epm_InqObject(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
256 struct epm_InqObject
*r
)
258 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
261 static error_status_t
epm_MgmtDelete(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
262 struct epm_MgmtDelete
*r
)
264 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
267 static error_status_t
epm_MapAuth(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
268 struct epm_MapAuth
*r
)
270 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR
);
273 /* include the generated boilerplate */
274 #include "librpc/gen_ndr/ndr_epmapper_s.c"