2 Unix SMB/CIFS implementation.
4 Endpoint server for the epmapper pipe
6 Copyright (C) 2010-2011 Andreas Schneider <asn@samba.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "../libcli/security/security.h"
24 #include "librpc/gen_ndr/ndr_epmapper.h"
25 #include "librpc/gen_ndr/srv_epmapper.h"
27 typedef uint32_t error_status_t
;
29 /* An endpoint combined with an interface description */
30 struct dcesrv_ep_iface
{
32 struct ndr_syntax_id syntax_id
;
36 /* A rpc service interface like samr, lsarpc or netlogon */
39 struct ndr_syntax_id syntax_id
;
42 struct dcesrv_iface_list
{
43 struct dcesrv_iface_list
*next
, *prev
;
44 struct dcesrv_iface
*iface
;
48 * An endpoint can serve multiple rpc services interfaces.
49 * For example \\pipe\netlogon can be used by lsarpc and netlogon.
51 struct dcesrv_endpoint
{
52 struct dcesrv_endpoint
*next
, *prev
;
54 /* The type and the location of the endpoint */
55 struct dcerpc_binding
*ep_description
;
57 /* A list of rpc services able to connect to the endpoint */
58 struct dcesrv_iface_list
*iface_list
;
62 struct dcesrv_ep_iface
*e
;
66 static struct dcesrv_endpoint
*endpoint_table
;
69 * Check if the UUID and if_version match to an interface.
71 static bool interface_match(const struct dcesrv_iface
*if1
,
72 const struct dcesrv_iface
*if2
)
74 return GUID_equal(&if1
->syntax_id
.uuid
, &if2
->syntax_id
.uuid
);
78 * Find the interface operations on an endpoint.
80 static const struct dcesrv_iface
*find_interface(const struct dcesrv_endpoint
*endpoint
,
81 const struct dcesrv_iface
*iface
)
83 struct dcesrv_iface_list
*iflist
;
85 for (iflist
= endpoint
->iface_list
; iflist
; iflist
= iflist
->next
) {
86 if (interface_match(iflist
->iface
, iface
)) {
95 * See if a uuid and if_version match to an interface
97 static bool interface_match_by_uuid(const struct dcesrv_iface
*iface
,
98 const struct GUID
*uuid
)
100 return GUID_equal(&iface
->syntax_id
.uuid
, uuid
);
103 static struct dcesrv_iface_list
*find_interface_list(const struct dcesrv_endpoint
*endpoint
,
104 const struct dcesrv_iface
*iface
)
106 struct dcesrv_iface_list
*iflist
;
108 for (iflist
= endpoint
->iface_list
; iflist
; iflist
= iflist
->next
) {
109 if (interface_match(iflist
->iface
, iface
)) {
118 * Check if two endpoints match.
120 static bool endpoints_match(const struct dcerpc_binding
*ep1
,
121 const struct dcerpc_binding
*ep2
)
123 if (ep1
->transport
!= ep2
->transport
) {
127 if (!ep1
->endpoint
|| !ep2
->endpoint
) {
128 return ep1
->endpoint
== ep2
->endpoint
;
131 if (!strequal(ep1
->endpoint
, ep2
->endpoint
)) {
138 static struct dcesrv_endpoint
*find_endpoint(struct dcesrv_endpoint
*endpoint_list
,
139 struct dcerpc_binding
*ep_description
) {
140 struct dcesrv_endpoint
*ep
;
142 for (ep
= endpoint_list
; ep
!= NULL
; ep
= ep
->next
) {
143 if (endpoints_match(ep
->ep_description
, ep_description
)) {
152 * Build a list of all interfaces handled by all endpoint servers.
154 static uint32_t build_ep_list(TALLOC_CTX
*mem_ctx
,
155 struct dcesrv_endpoint
*endpoint_list
,
156 const struct GUID
*uuid
,
157 const char *srv_addr
,
158 struct dcesrv_ep_iface
**peps
)
160 struct dcesrv_ep_iface
*eps
= NULL
;
161 struct dcesrv_endpoint
*d
;
167 for (d
= endpoint_list
; d
!= NULL
; d
= d
->next
) {
168 struct dcesrv_iface_list
*iface
;
169 struct dcerpc_binding
*description
;
171 for (iface
= d
->iface_list
; iface
!= NULL
; iface
= iface
->next
) {
172 if (uuid
&& !interface_match_by_uuid(iface
->iface
, uuid
)) {
176 eps
= talloc_realloc(mem_ctx
,
178 struct dcesrv_ep_iface
,
183 eps
[total
].name
= talloc_strdup(eps
,
185 eps
[total
].syntax_id
= iface
->iface
->syntax_id
;
187 description
= d
->ep_description
;
188 description
->object
= iface
->iface
->syntax_id
;
189 if (description
->transport
== NCACN_IP_TCP
&&
191 strequal(description
->host
, "0.0.0.0")) {
192 description
->host
= srv_addr
;
195 status
= dcerpc_binding_build_tower(eps
,
198 if (NT_STATUS_IS_ERR(status
)) {
199 DEBUG(1, ("Unable to build tower for %s\n",
200 iface
->iface
->name
));
212 static bool is_priviledged_pipe(struct auth_serversupplied_info
*info
) {
213 /* If the user is not root, or has the system token, fail */
214 if ((info
->utok
.uid
!= sec_initial_uid()) &&
215 !security_token_is_system(info
->security_token
)) {
225 * Add the specified entries to an endpoint map.
227 error_status_t
_epm_Insert(struct pipes_struct
*p
,
228 struct epm_Insert
*r
)
235 /* If this is not a priviledged users, return */
236 if (p
->transport
!= NCALRPC
||
237 !is_priviledged_pipe(p
->session_info
)) {
238 return EPMAPPER_STATUS_CANT_PERFORM_OP
;
241 tmp_ctx
= talloc_stackframe();
242 if (tmp_ctx
== NULL
) {
243 return EPMAPPER_STATUS_NO_MEMORY
;
246 DEBUG(3, ("_epm_Insert: Trying to add %u new entries.\n",
249 for (i
= 0; i
< r
->in
.num_ents
; i
++) {
250 struct dcerpc_binding
*b
= NULL
;
251 struct dcesrv_endpoint
*ep
;
252 struct dcesrv_iface_list
*iflist
;
253 struct dcesrv_iface
*iface
;
256 status
= dcerpc_binding_from_tower(tmp_ctx
,
257 &r
->in
.entries
[i
].tower
->tower
,
259 if (!NT_STATUS_IS_OK(status
)) {
260 rc
= EPMAPPER_STATUS_NO_MEMORY
;
264 DEBUG(3, ("_epm_Insert: Adding transport %s for %s\n",
265 derpc_transport_string_by_transport(b
->transport
),
266 r
->in
.entries
[i
].annotation
));
268 /* Check if the entry already exits */
269 ep
= find_endpoint(endpoint_table
, b
);
271 /* No entry found, create it */
272 ep
= talloc_zero(NULL
, struct dcesrv_endpoint
);
274 rc
= EPMAPPER_STATUS_CANT_PERFORM_OP
;
279 ep
->ep_description
= talloc_steal(ep
, b
);
282 /* TODO Replace the entry if the replace flag is set */
284 /* Create an interface */
285 iface
= talloc(tmp_ctx
, struct dcesrv_iface
);
287 rc
= EPMAPPER_STATUS_NO_MEMORY
;
291 iface
->name
= talloc_strdup(iface
, r
->in
.entries
[i
].annotation
);
292 if (iface
->name
== NULL
) {
293 rc
= EPMAPPER_STATUS_NO_MEMORY
;
296 iface
->syntax_id
= b
->object
;
299 * Check if the rpc service is alrady registered on the
302 if (find_interface(ep
, iface
) != NULL
) {
303 DEBUG(0, ("dcesrv_interface_register: interface '%s' "
304 "already registered on endpoint\n",
306 /* FIXME wrong error code? */
307 rc
= EPMAPPER_STATUS_OK
;
311 /* Create an entry for the interface */
312 iflist
= talloc(ep
, struct dcesrv_iface_list
);
313 if (iflist
== NULL
) {
314 rc
= EPMAPPER_STATUS_NO_MEMORY
;
317 iflist
->iface
= talloc_move(iflist
, &iface
);
319 /* Finally add the interface on the endpoint */
320 DLIST_ADD(ep
->iface_list
, iflist
);
322 /* If it's a new endpoint add it to the endpoint_table */
324 DLIST_ADD(endpoint_table
, ep
);
328 rc
= EPMAPPER_STATUS_OK
;
330 talloc_free(tmp_ctx
);
339 * Delete the specified entries from an endpoint map.
341 error_status_t
_epm_Delete(struct pipes_struct
*p
,
342 struct epm_Delete
*r
)
349 DEBUG(3, ("_epm_Delete: Trying to delete %u entries.\n",
352 /* If this is not a priviledged users, return */
353 if (p
->transport
!= NCALRPC
||
354 !is_priviledged_pipe(p
->session_info
)) {
355 return EPMAPPER_STATUS_CANT_PERFORM_OP
;
358 tmp_ctx
= talloc_stackframe();
359 if (tmp_ctx
== NULL
) {
360 return EPMAPPER_STATUS_NO_MEMORY
;
363 for (i
= 0; i
< r
->in
.num_ents
; i
++) {
364 struct dcerpc_binding
*b
= NULL
;
365 struct dcesrv_endpoint
*ep
;
366 struct dcesrv_iface iface
;
367 struct dcesrv_iface_list
*iflist
;
369 status
= dcerpc_binding_from_tower(tmp_ctx
,
370 &r
->in
.entries
[i
].tower
->tower
,
372 if (!NT_STATUS_IS_OK(status
)) {
373 rc
= EPMAPPER_STATUS_NO_MEMORY
;
377 DEBUG(3, ("_epm_Delete: Deleting transport '%s' for '%s'\n",
378 derpc_transport_string_by_transport(b
->transport
),
379 r
->in
.entries
[i
].annotation
));
381 ep
= find_endpoint(endpoint_table
, b
);
383 rc
= EPMAPPER_STATUS_OK
;
387 iface
.name
= r
->in
.entries
[i
].annotation
;
388 iface
.syntax_id
= b
->object
;
390 iflist
= find_interface_list(ep
, &iface
);
391 if (iflist
== NULL
) {
392 DEBUG(0, ("_epm_Delete: No interfaces left, delete endpoint\n"));
393 DLIST_REMOVE(endpoint_table
, ep
);
396 rc
= EPMAPPER_STATUS_OK
;
400 DLIST_REMOVE(ep
->iface_list
, iflist
);
402 if (ep
->iface_list
== NULL
) {
403 DEBUG(0, ("_epm_Delete: No interfaces left, delete endpoint\n"));
404 DLIST_REMOVE(endpoint_table
, ep
);
407 rc
= EPMAPPER_STATUS_OK
;
413 rc
= EPMAPPER_STATUS_OK
;
415 talloc_free(tmp_ctx
);
424 * Lookup entries in an endpoint map.
426 error_status_t
_epm_Lookup(struct pipes_struct
*p
,
427 struct epm_Lookup
*r
)
429 struct policy_handle
*entry_handle
;
434 uint32_t num_ents
= 0;
439 *r
->out
.num_ents
= 0;
440 r
->out
.entries
= NULL
;
442 tmp_ctx
= talloc_stackframe();
443 if (tmp_ctx
== NULL
) {
444 return EPMAPPER_STATUS_NO_MEMORY
;
447 DEBUG(3, ("_epm_Lookup: Trying to lookup max. %u entries.\n",
450 if (r
->in
.entry_handle
== NULL
||
451 policy_handle_empty(r
->in
.entry_handle
)) {
454 DEBUG(5, ("_epm_Lookup: No entry_handle found, creating it.\n"));
456 eps
= talloc_zero(tmp_ctx
, struct rpc_eps
);
458 rc
= EPMAPPER_STATUS_NO_MEMORY
;
462 if (r
->in
.object
== NULL
|| GUID_all_zero(r
->in
.object
)) {
468 switch (r
->in
.inquiry_type
) {
469 case RPC_C_EP_ALL_ELTS
:
471 * Return all elements from the endpoint map. The
472 * interface_id, vers_option, and object parameters MUST
475 eps
->count
= build_ep_list(eps
,
478 p
->server_id
== NULL
? NULL
: p
->server_id
->addr
,
481 case RPC_C_EP_MATCH_BY_IF
:
483 * Return endpoint map elements that contain the
484 * interface identifier specified by the interface_id
485 * and vers_option values.
487 * RPC_C_EP_MATCH_BY_IF and RPC_C_EP_MATCH_BY_BOTH
488 * need both the same endpoint list. There is a second
489 * check for the inquiry_type below which differentiates
492 case RPC_C_EP_MATCH_BY_BOTH
:
494 * Return endpoint map elements that contain the
495 * interface identifier and object UUID specified by
496 * interface_id, vers_option, and object.
498 eps
->count
= build_ep_list(eps
,
500 &r
->in
.interface_id
->uuid
,
501 p
->server_id
== NULL
? NULL
: p
->server_id
->addr
,
504 case RPC_C_EP_MATCH_BY_OBJ
:
506 * Return endpoint map elements that contain the object
507 * UUID specified by object.
509 eps
->count
= build_ep_list(eps
,
512 p
->server_id
== NULL
? NULL
: p
->server_id
->addr
,
516 rc
= EPMAPPER_STATUS_CANT_PERFORM_OP
;
520 if (eps
->count
== 0) {
521 rc
= EPMAPPER_STATUS_NO_MORE_ENTRIES
;
525 ok
= create_policy_hnd(p
, r
->out
.entry_handle
, eps
);
527 rc
= EPMAPPER_STATUS_NO_MEMORY
;
531 ok
= find_policy_by_hnd(p
, r
->out
.entry_handle
, (void **)(void*) &eps
);
533 rc
= EPMAPPER_STATUS_NO_MEMORY
;
536 entry_handle
= r
->out
.entry_handle
;
538 DEBUG(5, ("_epm_Lookup: Trying to find entry_handle.\n"));
540 ok
= find_policy_by_hnd(p
, r
->in
.entry_handle
, (void **)(void*) &eps
);
542 rc
= EPMAPPER_STATUS_NO_MEMORY
;
545 entry_handle
= r
->in
.entry_handle
;
548 if (eps
== NULL
|| eps
->e
== NULL
) {
549 rc
= EPMAPPER_STATUS_NO_MORE_ENTRIES
;
553 /* return the next N elements */
554 count
= r
->in
.max_ents
;
555 if (count
> eps
->count
) {
559 DEBUG(3, ("_epm_Lookup: Find %u entries\n", count
));
562 close_policy_hnd(p
, entry_handle
);
563 ZERO_STRUCTP(r
->out
.entry_handle
);
565 rc
= EPMAPPER_STATUS_NO_MORE_ENTRIES
;
569 r
->out
.entries
= talloc_array(p
->mem_ctx
, struct epm_entry_t
, count
);
570 if (r
->out
.entries
== NULL
) {
571 rc
= EPMAPPER_STATUS_NO_MEMORY
;
575 for (i
= 0; i
< count
; i
++) {
578 switch (r
->in
.inquiry_type
) {
579 case RPC_C_EP_ALL_ELTS
:
581 * Return all elements from the endpoint map. The
582 * interface_id, vers_option, and object parameters MUST
587 case RPC_C_EP_MATCH_BY_IF
:
589 * Return endpoint map elements that contain the
590 * interface identifier specified by the interface_id
591 * and vers_option values.
593 if (GUID_equal(&r
->in
.interface_id
->uuid
,
594 &eps
->e
[i
].syntax_id
.uuid
)) {
598 case RPC_C_EP_MATCH_BY_OBJ
:
600 * Return endpoint map elements that contain the object
601 * UUID specified by object.
603 if (GUID_equal(r
->in
.object
,
604 &eps
->e
[i
].syntax_id
.uuid
)) {
608 case RPC_C_EP_MATCH_BY_BOTH
:
610 * Return endpoint map elements that contain the
611 * interface identifier and object UUID specified by
612 * interface_id, vers_option, and object.
614 if (GUID_equal(&r
->in
.interface_id
->uuid
,
615 &eps
->e
[i
].syntax_id
.uuid
) &&
616 GUID_equal(r
->in
.object
, &eps
->e
[i
].syntax_id
.uuid
)) {
621 return EPMAPPER_STATUS_CANT_PERFORM_OP
;
625 if (r
->in
.inquiry_type
== RPC_C_EP_MATCH_BY_IF
||
626 r
->in
.inquiry_type
== RPC_C_EP_MATCH_BY_OBJ
) {
627 /* Check inteface version */
630 switch (r
->in
.vers_option
) {
633 * Return endpoint map elements that
634 * contain the specified interface UUID,
635 * regardless of the version numbers.
639 case RPC_C_VERS_COMPATIBLE
:
641 * Return the endpoint map elements that
642 * contain the same major versions of
643 * the specified interface UUID and a
644 * minor version greater than or equal
645 * to the minor version of the specified
648 if (r
->in
.interface_id
->vers_major
==
649 (eps
->e
[i
].syntax_id
.if_version
>> 16) &&
650 r
->in
.interface_id
->vers_minor
<=
651 (eps
->e
[i
].syntax_id
.if_version
&& 0xFFFF)) {
655 case RPC_C_VERS_EXACT
:
657 * Return endpoint map elements that
658 * contain the specified version of the
659 * specified interface UUID.
661 if (r
->in
.interface_id
->vers_major
==
662 (eps
->e
[i
].syntax_id
.if_version
>> 16) &&
663 r
->in
.interface_id
->vers_minor
==
664 (eps
->e
[i
].syntax_id
.if_version
&& 0xFFFF)) {
669 case RPC_C_VERS_MAJOR_ONLY
:
671 * Return endpoint map elements that
672 * contain the same version of the
673 * specified interface UUID and ignore
676 if (r
->in
.interface_id
->vers_major
==
677 (eps
->e
[i
].syntax_id
.if_version
>> 16)) {
682 case RPC_C_VERS_UPTO
:
684 * Return endpoint map elements that
685 * contain a version of the specified
686 * interface UUID less than or equal to
687 * the specified major and minor
690 if (r
->in
.interface_id
->vers_major
>
691 eps
->e
[i
].syntax_id
.if_version
>> 16) {
694 if (r
->in
.interface_id
->vers_major
==
695 (eps
->e
[i
].syntax_id
.if_version
>> 16) &&
696 r
->in
.interface_id
->vers_minor
>=
697 (eps
->e
[i
].syntax_id
.if_version
&& 0xFFFF)) {
703 return EPMAPPER_STATUS_CANT_PERFORM_OP
;
709 ZERO_STRUCT(r
->out
.entries
[num_ents
].object
);
711 DEBUG(10, ("_epm_Lookup: Adding tower for '%s'\n",
713 r
->out
.entries
[num_ents
].annotation
= talloc_strdup(r
->out
.entries
,
715 r
->out
.entries
[num_ents
].tower
= talloc(r
->out
.entries
,
717 if (r
->out
.entries
[num_ents
].tower
== NULL
) {
718 rc
= EPMAPPER_STATUS_NO_MEMORY
;
721 r
->out
.entries
[num_ents
].tower
->tower
.floors
= talloc_move(r
->out
.entries
[num_ents
].tower
, &eps
->e
[i
].ep
.floors
);
722 r
->out
.entries
[num_ents
].tower
->tower
.num_floors
= eps
->e
[i
].ep
.num_floors
;
723 r
->out
.entries
[num_ents
].tower
->tower_length
= 0;
729 *r
->out
.num_ents
= num_ents
;
733 if (eps
->count
== 0) {
734 close_policy_hnd(p
, entry_handle
);
735 ZERO_STRUCTP(r
->out
.entry_handle
);
736 rc
= EPMAPPER_STATUS_NO_MORE_ENTRIES
;
740 rc
= EPMAPPER_STATUS_OK
;
742 talloc_free(tmp_ctx
);
750 * Apply some algorithm (using the fields in the map_tower) to an endpoint map
751 * to produce a list of protocol towers.
753 error_status_t
_epm_Map(struct pipes_struct
*p
,
756 struct policy_handle
*entry_handle
;
757 enum dcerpc_transport_t transport
;
758 struct ndr_syntax_id ifid
;
759 struct epm_floor
*floors
;
764 uint32_t num_towers
= 0;
765 uint32_t num_floors
= 0;
769 *r
->out
.num_towers
= 0;
770 r
->out
.towers
= NULL
;
772 if (r
->in
.map_tower
== NULL
|| r
->in
.max_towers
== 0 ||
773 r
->in
.map_tower
->tower
.num_floors
< 3) {
774 return EPMAPPER_STATUS_NO_MORE_ENTRIES
;
777 tmp_ctx
= talloc_stackframe();
778 if (tmp_ctx
== NULL
) {
779 return EPMAPPER_STATUS_NO_MEMORY
;
782 ZERO_STRUCTP(r
->out
.entry_handle
);
784 DEBUG(3, ("_epm_Map: Trying to map max. %u towers.\n",
788 * A tower has normally up to 6 floors
790 * +-----------------------------------------------------------------+
791 * | Floor 1 | Provides the RPC interface identifier. (e.g. UUID for |
793 * +---------+-------------------------------------------------------+
794 * | Floor 2 | Transfer syntax (NDR endcoded) |
795 * +---------+-------------------------------------------------------+
796 * | Floor 3 | RPC protocol identifier (ncacn_tcp_ip, ncacn_np, ...) |
797 * +---------+-------------------------------------------------------+
798 * | Floor 4 | Port address (e.g. TCP Port: 49156) |
799 * +---------+-------------------------------------------------------+
800 * | Floor 5 | Transport (e.g. IP:192.168.51.10) |
801 * +---------+-------------------------------------------------------+
802 * | Floor 6 | Routing |
803 * +---------+-------------------------------------------------------+
805 num_floors
= r
->in
.map_tower
->tower
.num_floors
;
806 floors
= r
->in
.map_tower
->tower
.floors
;
808 /* We accept NDR as the transfer syntax */
809 dcerpc_floor_get_lhs_data(&floors
[1], &ifid
);
811 if (floors
[1].lhs
.protocol
!= EPM_PROTOCOL_UUID
||
812 !GUID_equal(&ifid
.uuid
, &ndr_transfer_syntax
.uuid
) ||
813 ifid
.if_version
!= ndr_transfer_syntax
.if_version
) {
814 rc
= EPMAPPER_STATUS_NO_MORE_ENTRIES
;
818 /* We only talk to sane transports */
819 transport
= dcerpc_transport_by_tower(&r
->in
.map_tower
->tower
);
820 if (transport
== NCA_UNKNOWN
) {
821 DEBUG(2, ("epm_Map: Client requested unknown transport with"
823 for (i
= 2; i
< r
->in
.map_tower
->tower
.num_floors
; i
++) {
824 DEBUG(2, ("%d, ", r
->in
.map_tower
->tower
.floors
[i
].lhs
.protocol
));
827 rc
= EPMAPPER_STATUS_NO_MORE_ENTRIES
;
831 if (r
->in
.entry_handle
== NULL
||
832 policy_handle_empty(r
->in
.entry_handle
)) {
835 DEBUG(5, ("_epm_Map: No entry_handle found, creating it.\n"));
837 eps
= talloc_zero(tmp_ctx
, struct rpc_eps
);
839 rc
= EPMAPPER_STATUS_NO_MEMORY
;
848 * Apply some algorithm (using the fields in the map_tower)
849 * to an endpoint map to produce a list of protocol towers.
851 * The following code is the mysterious "some algorithm"!
854 /* Filter by object id if one was given. */
855 if (r
->in
.object
== NULL
|| GUID_all_zero(r
->in
.object
)) {
861 eps
->count
= build_ep_list(eps
,
864 p
->server_id
== NULL
? NULL
: p
->server_id
->addr
,
866 if (eps
->count
== 0) {
867 rc
= EPMAPPER_STATUS_NO_MORE_ENTRIES
;
871 /* Filter out endpoints which match the interface. */
873 struct rpc_eps
*teps
;
876 teps
= talloc_zero(tmp_ctx
, struct rpc_eps
);
878 rc
= EPMAPPER_STATUS_NO_MEMORY
;
882 for (i
= 0; i
< eps
->count
; i
++) {
883 if (data_blob_cmp(&r
->in
.map_tower
->tower
.floors
[0].lhs
.lhs_data
,
884 &eps
->e
[i
].ep
.floors
[0].lhs
.lhs_data
) != 0 ||
885 transport
!= dcerpc_transport_by_tower(&eps
->e
[i
].ep
)) {
889 teps
->e
= talloc_realloc(tmp_ctx
,
891 struct dcesrv_ep_iface
,
893 if (teps
->e
== NULL
) {
897 teps
->e
[total
].ep
.floors
= talloc_move(teps
, &eps
->e
[i
].ep
.floors
);
898 teps
->e
[total
].ep
.num_floors
= eps
->e
[i
].ep
.num_floors
;
899 teps
->e
[total
].name
= talloc_move(teps
, &eps
->e
[i
].name
);
900 teps
->e
[total
].syntax_id
= eps
->e
[i
].syntax_id
;
909 /* end of "some algorithm" */
911 ok
= create_policy_hnd(p
, r
->out
.entry_handle
, eps
);
913 rc
= EPMAPPER_STATUS_NO_MEMORY
;
917 ok
= find_policy_by_hnd(p
, r
->out
.entry_handle
, (void **)(void*) &eps
);
919 rc
= EPMAPPER_STATUS_NO_MEMORY
;
922 entry_handle
= r
->out
.entry_handle
;
924 DEBUG(5, ("_epm_Map: Trying to find entry_handle.\n"));
926 ok
= find_policy_by_hnd(p
, r
->in
.entry_handle
, (void **)(void*) &eps
);
928 rc
= EPMAPPER_STATUS_NO_MEMORY
;
931 entry_handle
= r
->in
.entry_handle
;
934 if (eps
== NULL
|| eps
->e
== NULL
) {
935 rc
= EPMAPPER_STATUS_NO_MORE_ENTRIES
;
939 /* return the next N elements */
940 count
= r
->in
.max_towers
;
941 if (count
> eps
->count
) {
946 close_policy_hnd(p
, entry_handle
);
947 ZERO_STRUCTP(r
->out
.entry_handle
);
949 rc
= EPMAPPER_STATUS_NO_MORE_ENTRIES
;
953 r
->out
.towers
= talloc_array(p
->mem_ctx
, struct epm_twr_p_t
, count
);
954 if (r
->out
.towers
== NULL
) {
955 rc
= EPMAPPER_STATUS_NO_MEMORY
;
959 for (i
= 0; i
< count
; i
++) {
960 DEBUG(5, ("_epm_Map: Map tower for '%s'\n",
963 r
->out
.towers
[num_towers
].twr
= talloc(r
->out
.towers
,
965 if (r
->out
.towers
[num_towers
].twr
== NULL
) {
966 rc
= EPMAPPER_STATUS_NO_MEMORY
;
969 r
->out
.towers
[num_towers
].twr
->tower
.floors
= talloc_move(r
->out
.towers
[num_towers
].twr
, &eps
->e
[i
].ep
.floors
);
970 r
->out
.towers
[num_towers
].twr
->tower
.num_floors
= eps
->e
[i
].ep
.num_floors
;
971 r
->out
.towers
[num_towers
].twr
->tower_length
= 0;
976 *r
->out
.num_towers
= num_towers
;
980 if (eps
->count
== 0) {
981 close_policy_hnd(p
, entry_handle
);
982 ZERO_STRUCTP(r
->out
.entry_handle
);
985 rc
= EPMAPPER_STATUS_OK
;
987 talloc_free(tmp_ctx
);
993 * epm_LookupHandleFree
995 error_status_t
_epm_LookupHandleFree(struct pipes_struct
*p
,
996 struct epm_LookupHandleFree
*r
)
998 if (r
->in
.entry_handle
== NULL
) {
999 return EPMAPPER_STATUS_OK
;
1002 if (is_valid_policy_hnd(r
->in
.entry_handle
)) {
1003 close_policy_hnd(p
, r
->in
.entry_handle
);
1006 r
->out
.entry_handle
= r
->in
.entry_handle
;
1008 return EPMAPPER_STATUS_OK
;
1015 * A client implementation SHOULD NOT call this method. These extensions do not
1016 * provide an alternative method.
1018 error_status_t
_epm_InqObject(struct pipes_struct
*p
,
1019 struct epm_InqObject
*r
)
1021 p
->rng_fault_state
= true;
1022 return EPMAPPER_STATUS_CANT_PERFORM_OP
;
1029 * A client implementation SHOULD NOT call this method. These extensions do not
1030 * provide an alternative method.
1032 error_status_t
_epm_MgmtDelete(struct pipes_struct
*p
,
1033 struct epm_MgmtDelete
*r
)
1035 p
->rng_fault_state
= true;
1036 return EPMAPPER_STATUS_CANT_PERFORM_OP
;
1043 error_status_t
_epm_MapAuth(struct pipes_struct
*p
,
1044 struct epm_MapAuth
*r
)
1046 p
->rng_fault_state
= true;
1047 return EPMAPPER_STATUS_CANT_PERFORM_OP
;
1050 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */