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/>.
24
#include "../libcli/security/security.h"
25
#include "librpc/gen_ndr/srv_epmapper.h"
26
#include "srv_epmapper.h"
29
typedef uint32_t error_status_t;
31
/* An endpoint combined with an interface description */
32
struct dcesrv_ep_iface {
34
struct ndr_syntax_id syntax_id;
38
/* A rpc service interface like samr, lsarpc or netlogon */
41
struct ndr_syntax_id syntax_id;
44
struct dcesrv_iface_list {
45
struct dcesrv_iface_list *next, *prev;
46
struct dcesrv_iface *iface;
50
* An endpoint can serve multiple rpc services interfaces.
51
* For example \\pipe\netlogon can be used by lsarpc and netlogon.
53
struct dcesrv_endpoint {
54
struct dcesrv_endpoint *next, *prev;
56
/* The type and the location of the endpoint */
57
struct dcerpc_binding *ep_description;
59
/* A list of rpc services able to connect to the endpoint */
60
struct dcesrv_iface_list *iface_list;
63
struct dcesrv_ep_entry_list {
64
struct dcesrv_ep_entry_list *next, *prev;
67
struct epm_entry_t *entries;
71
struct dcesrv_ep_iface *e;
75
static struct dcesrv_endpoint *endpoint_table;
78
* Check if the UUID and if_version match to an interface.
80
static bool interface_match(const struct dcesrv_iface *if1,
81
const struct dcesrv_iface *if2)
83
return GUID_equal(&if1->syntax_id.uuid, &if2->syntax_id.uuid);
87
* Find the interface operations on an endpoint.
89
static const struct dcesrv_iface *find_interface(const struct dcesrv_endpoint *endpoint,
90
const struct dcesrv_iface *iface)
92
struct dcesrv_iface_list *iflist;
94
for (iflist = endpoint->iface_list; iflist; iflist = iflist->next) {
95
if (interface_match(iflist->iface, iface)) {
104
* See if a uuid and if_version match to an interface
106
static bool interface_match_by_uuid(const struct dcesrv_iface *iface,
107
const struct GUID *uuid)
109
return GUID_equal(&iface->syntax_id.uuid, uuid);
112
static struct dcesrv_iface_list *find_interface_list(const struct dcesrv_endpoint *endpoint,
113
const struct dcesrv_iface *iface)
115
struct dcesrv_iface_list *iflist;
117
for (iflist = endpoint->iface_list; iflist; iflist = iflist->next) {
118
if (interface_match(iflist->iface, iface)) {
127
* Check if two endpoints match.
129
static bool endpoints_match(const struct dcerpc_binding *ep1,
130
const struct dcerpc_binding *ep2)
132
if (ep1->transport != ep2->transport) {
136
if (!ep1->endpoint || !ep2->endpoint) {
137
return ep1->endpoint == ep2->endpoint;
140
if (!strequal(ep1->endpoint, ep2->endpoint)) {
147
static struct dcesrv_endpoint *find_endpoint(struct dcesrv_endpoint *endpoint_list,
148
struct dcerpc_binding *ep_description) {
149
struct dcesrv_endpoint *ep;
151
for (ep = endpoint_list; ep != NULL; ep = ep->next) {
152
if (endpoints_match(ep->ep_description, ep_description)) {
161
* Build a list of all interfaces handled by all endpoint servers.
163
static uint32_t build_ep_list(TALLOC_CTX *mem_ctx,
164
struct dcesrv_endpoint *endpoint_list,
165
const struct GUID *uuid,
166
const char *srv_addr,
167
struct dcesrv_ep_iface **peps)
169
struct dcesrv_ep_iface *eps = NULL;
170
struct dcesrv_endpoint *d;
176
for (d = endpoint_list; d != NULL; d = d->next) {
177
struct dcesrv_iface_list *iface;
178
struct dcerpc_binding *description;
180
for (iface = d->iface_list; iface != NULL; iface = iface->next) {
181
if (uuid && !interface_match_by_uuid(iface->iface, uuid)) {
185
eps = talloc_realloc(mem_ctx,
187
struct dcesrv_ep_iface,
192
eps[total].name = talloc_strdup(eps,
194
eps[total].syntax_id = iface->iface->syntax_id;
196
description = dcerpc_binding_dup(mem_ctx, d->ep_description);
197
if (description == NULL) {
200
description->object = iface->iface->syntax_id;
201
if (description->transport == NCACN_IP_TCP &&
203
(strcmp(description->host, "0.0.0.0") == 0 ||
204
strcmp(description->host, "::") == 0)) {
205
description->host = srv_addr;
208
status = dcerpc_binding_build_tower(eps,
211
TALLOC_FREE(description);
212
if (NT_STATUS_IS_ERR(status)) {
213
DEBUG(1, ("Unable to build tower for %s\n",
214
iface->iface->name));
226
static bool is_priviledged_pipe(struct auth_serversupplied_info *info) {
227
/* If the user is not root, or has the system token, fail */
228
if ((info->utok.uid != sec_initial_uid()) &&
229
!security_token_is_system(info->security_token)) {
236
bool srv_epmapper_delete_endpoints(struct pipes_struct *p)
239
struct dcesrv_ep_entry_list *el = p->ep_entries;
240
error_status_t result;
243
struct dcesrv_ep_entry_list *next = el->next;
245
r.in.num_ents = el->num_ents;
246
r.in.entries = el->entries;
248
DEBUG(10, ("Delete_endpoints for: %s\n",
249
el->entries[0].annotation));
251
result = _epm_Delete(p, &r);
252
if (result != EPMAPPER_STATUS_OK) {
256
DLIST_REMOVE(p->ep_entries, el);
265
void srv_epmapper_cleanup(void)
267
struct dcesrv_endpoint *ep = endpoint_table;
270
struct dcesrv_endpoint *next = ep->next;
272
DLIST_REMOVE(endpoint_table, ep);
282
* Add the specified entries to an endpoint map.
284
error_status_t _epm_Insert(struct pipes_struct *p,
285
struct epm_Insert *r)
291
struct dcerpc_binding *b;
292
struct dcesrv_endpoint *ep;
293
struct dcesrv_iface_list *iflist;
294
struct dcesrv_iface *iface;
297
/* If this is not a priviledged users, return */
298
if (p->transport != NCALRPC ||
299
!is_priviledged_pipe(p->session_info)) {
300
return EPMAPPER_STATUS_CANT_PERFORM_OP;
303
tmp_ctx = talloc_stackframe();
304
if (tmp_ctx == NULL) {
305
return EPMAPPER_STATUS_NO_MEMORY;
308
DEBUG(3, ("_epm_Insert: Trying to add %u new entries.\n",
311
for (i = 0; i < r->in.num_ents; i++) {
315
status = dcerpc_binding_from_tower(tmp_ctx,
316
&r->in.entries[i].tower->tower,
318
if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MEMORY)) {
319
rc = EPMAPPER_STATUS_NO_MEMORY;
322
if (!NT_STATUS_IS_OK(status)) {
323
rc = EPMAPPER_STATUS_CANT_PERFORM_OP;
327
DEBUG(3, ("_epm_Insert: Adding transport %s for %s\n",
328
derpc_transport_string_by_transport(b->transport),
329
r->in.entries[i].annotation));
331
/* Check if the entry already exits */
332
ep = find_endpoint(endpoint_table, b);
334
/* No entry found, create it */
335
ep = talloc_zero(NULL, struct dcesrv_endpoint);
337
rc = EPMAPPER_STATUS_NO_MEMORY;
342
ep->ep_description = talloc_steal(ep, b);
345
/* TODO Replace the entry if the replace flag is set */
347
/* Create an interface */
348
iface = talloc(tmp_ctx, struct dcesrv_iface);
350
rc = EPMAPPER_STATUS_NO_MEMORY;
354
iface->name = talloc_strdup(iface, r->in.entries[i].annotation);
355
if (iface->name == NULL) {
356
rc = EPMAPPER_STATUS_NO_MEMORY;
359
iface->syntax_id = b->object;
362
* Check if the rpc service is alrady registered on the
365
if (find_interface(ep, iface) != NULL) {
366
DEBUG(0, ("dcesrv_interface_register: interface '%s' "
367
"already registered on endpoint\n",
369
/* FIXME wrong error code? */
370
rc = EPMAPPER_STATUS_OK;
374
/* Create an entry for the interface */
375
iflist = talloc(ep, struct dcesrv_iface_list);
376
if (iflist == NULL) {
377
rc = EPMAPPER_STATUS_NO_MEMORY;
380
iflist->iface = talloc_move(iflist, &iface);
382
/* Finally add the interface on the endpoint */
383
DLIST_ADD(ep->iface_list, iflist);
385
/* If it's a new endpoint add it to the endpoint_table */
387
DLIST_ADD(endpoint_table, ep);
391
if (r->in.num_ents > 0) {
392
struct dcesrv_ep_entry_list *el;
394
el = talloc_zero(p, struct dcesrv_ep_entry_list);
396
rc = EPMAPPER_STATUS_NO_MEMORY;
399
el->num_ents = r->in.num_ents;
400
el->entries = talloc_move(el, &r->in.entries);
402
DLIST_ADD(p->ep_entries, el);
405
rc = EPMAPPER_STATUS_OK;
407
talloc_free(tmp_ctx);
416
* Delete the specified entries from an endpoint map.
418
error_status_t _epm_Delete(struct pipes_struct *p,
419
struct epm_Delete *r)
425
struct dcerpc_binding *b;
426
struct dcesrv_endpoint *ep;
427
struct dcesrv_iface iface;
428
struct dcesrv_iface_list *iflist;
430
DEBUG(3, ("_epm_Delete: Trying to delete %u entries.\n",
433
/* If this is not a priviledged users, return */
434
if (p->transport != NCALRPC ||
435
!is_priviledged_pipe(p->session_info)) {
436
return EPMAPPER_STATUS_CANT_PERFORM_OP;
439
tmp_ctx = talloc_stackframe();
440
if (tmp_ctx == NULL) {
441
return EPMAPPER_STATUS_NO_MEMORY;
444
for (i = 0; i < r->in.num_ents; i++) {
447
status = dcerpc_binding_from_tower(tmp_ctx,
448
&r->in.entries[i].tower->tower,
450
if (!NT_STATUS_IS_OK(status)) {
451
rc = EPMAPPER_STATUS_NO_MEMORY;
455
DEBUG(3, ("_epm_Delete: Deleting transport '%s' for '%s'\n",
456
derpc_transport_string_by_transport(b->transport),
457
r->in.entries[i].annotation));
459
ep = find_endpoint(endpoint_table, b);
461
rc = EPMAPPER_STATUS_OK;
465
iface.name = r->in.entries[i].annotation;
466
iface.syntax_id = b->object;
468
iflist = find_interface_list(ep, &iface);
469
if (iflist == NULL) {
470
DEBUG(0, ("_epm_Delete: No interfaces left, delete endpoint\n"));
471
DLIST_REMOVE(endpoint_table, ep);
474
rc = EPMAPPER_STATUS_OK;
478
DLIST_REMOVE(ep->iface_list, iflist);
480
if (ep->iface_list == NULL) {
481
DEBUG(0, ("_epm_Delete: No interfaces left, delete endpoint\n"));
482
DLIST_REMOVE(endpoint_table, ep);
485
rc = EPMAPPER_STATUS_OK;
491
rc = EPMAPPER_STATUS_OK;
493
talloc_free(tmp_ctx);
502
* Lookup entries in an endpoint map.
504
error_status_t _epm_Lookup(struct pipes_struct *p,
505
struct epm_Lookup *r)
507
struct policy_handle *entry_handle;
512
uint32_t num_ents = 0;
517
*r->out.num_ents = 0;
518
r->out.entries = NULL;
520
tmp_ctx = talloc_stackframe();
521
if (tmp_ctx == NULL) {
522
return EPMAPPER_STATUS_NO_MEMORY;
525
DEBUG(3, ("_epm_Lookup: Trying to lookup max. %u entries.\n",
528
if (r->in.entry_handle == NULL ||
529
policy_handle_empty(r->in.entry_handle)) {
532
DEBUG(5, ("_epm_Lookup: No entry_handle found, creating it.\n"));
534
eps = talloc_zero(tmp_ctx, struct rpc_eps);
536
rc = EPMAPPER_STATUS_NO_MEMORY;
540
if (r->in.object == NULL || GUID_all_zero(r->in.object)) {
546
switch (r->in.inquiry_type) {
547
case RPC_C_EP_ALL_ELTS:
549
* Return all elements from the endpoint map. The
550
* interface_id, vers_option, and object parameters MUST
553
eps->count = build_ep_list(eps,
556
p->server_id == NULL ? NULL : p->server_id->addr,
559
case RPC_C_EP_MATCH_BY_IF:
561
* Return endpoint map elements that contain the
562
* interface identifier specified by the interface_id
563
* and vers_option values.
565
* RPC_C_EP_MATCH_BY_IF and RPC_C_EP_MATCH_BY_BOTH
566
* need both the same endpoint list. There is a second
567
* check for the inquiry_type below which differentiates
570
case RPC_C_EP_MATCH_BY_BOTH:
572
* Return endpoint map elements that contain the
573
* interface identifier and object UUID specified by
574
* interface_id, vers_option, and object.
576
eps->count = build_ep_list(eps,
578
&r->in.interface_id->uuid,
579
p->server_id == NULL ? NULL : p->server_id->addr,
582
case RPC_C_EP_MATCH_BY_OBJ:
584
* Return endpoint map elements that contain the object
585
* UUID specified by object.
587
eps->count = build_ep_list(eps,
590
p->server_id == NULL ? NULL : p->server_id->addr,
594
rc = EPMAPPER_STATUS_CANT_PERFORM_OP;
598
if (eps->count == 0) {
599
rc = EPMAPPER_STATUS_NO_MORE_ENTRIES;
603
ok = create_policy_hnd(p, r->out.entry_handle, eps);
605
rc = EPMAPPER_STATUS_NO_MEMORY;
609
ok = find_policy_by_hnd(p, r->out.entry_handle, (void **)(void*) &eps);
611
rc = EPMAPPER_STATUS_NO_MEMORY;
614
entry_handle = r->out.entry_handle;
616
DEBUG(5, ("_epm_Lookup: Trying to find entry_handle.\n"));
618
ok = find_policy_by_hnd(p, r->in.entry_handle, (void **)(void*) &eps);
620
rc = EPMAPPER_STATUS_NO_MEMORY;
623
entry_handle = r->in.entry_handle;
626
if (eps == NULL || eps->e == NULL) {
627
rc = EPMAPPER_STATUS_NO_MORE_ENTRIES;
631
/* return the next N elements */
632
count = r->in.max_ents;
633
if (count > eps->count) {
637
DEBUG(3, ("_epm_Lookup: Find %u entries\n", count));
640
close_policy_hnd(p, entry_handle);
641
ZERO_STRUCTP(r->out.entry_handle);
643
rc = EPMAPPER_STATUS_NO_MORE_ENTRIES;
647
r->out.entries = talloc_array(p->mem_ctx, struct epm_entry_t, count);
648
if (r->out.entries == NULL) {
649
rc = EPMAPPER_STATUS_NO_MEMORY;
653
for (i = 0; i < count; i++) {
656
switch (r->in.inquiry_type) {
657
case RPC_C_EP_ALL_ELTS:
659
* Return all elements from the endpoint map. The
660
* interface_id, vers_option, and object parameters MUST
665
case RPC_C_EP_MATCH_BY_IF:
667
* Return endpoint map elements that contain the
668
* interface identifier specified by the interface_id
669
* and vers_option values.
671
if (GUID_equal(&r->in.interface_id->uuid,
672
&eps->e[i].syntax_id.uuid)) {
676
case RPC_C_EP_MATCH_BY_OBJ:
678
* Return endpoint map elements that contain the object
679
* UUID specified by object.
681
if (GUID_equal(r->in.object,
682
&eps->e[i].syntax_id.uuid)) {
686
case RPC_C_EP_MATCH_BY_BOTH:
688
* Return endpoint map elements that contain the
689
* interface identifier and object UUID specified by
690
* interface_id, vers_option, and object.
692
if (GUID_equal(&r->in.interface_id->uuid,
693
&eps->e[i].syntax_id.uuid) &&
694
GUID_equal(r->in.object, &eps->e[i].syntax_id.uuid)) {
699
return EPMAPPER_STATUS_CANT_PERFORM_OP;
703
if (r->in.inquiry_type == RPC_C_EP_MATCH_BY_IF ||
704
r->in.inquiry_type == RPC_C_EP_MATCH_BY_OBJ) {
705
/* Check inteface version */
708
switch (r->in.vers_option) {
711
* Return endpoint map elements that
712
* contain the specified interface UUID,
713
* regardless of the version numbers.
717
case RPC_C_VERS_COMPATIBLE:
719
* Return the endpoint map elements that
720
* contain the same major versions of
721
* the specified interface UUID and a
722
* minor version greater than or equal
723
* to the minor version of the specified
726
if (r->in.interface_id->vers_major ==
727
(eps->e[i].syntax_id.if_version >> 16) &&
728
r->in.interface_id->vers_minor <=
729
(eps->e[i].syntax_id.if_version && 0xFFFF)) {
733
case RPC_C_VERS_EXACT:
735
* Return endpoint map elements that
736
* contain the specified version of the
737
* specified interface UUID.
739
if (r->in.interface_id->vers_major ==
740
(eps->e[i].syntax_id.if_version >> 16) &&
741
r->in.interface_id->vers_minor ==
742
(eps->e[i].syntax_id.if_version && 0xFFFF)) {
747
case RPC_C_VERS_MAJOR_ONLY:
749
* Return endpoint map elements that
750
* contain the same version of the
751
* specified interface UUID and ignore
754
if (r->in.interface_id->vers_major ==
755
(eps->e[i].syntax_id.if_version >> 16)) {
760
case RPC_C_VERS_UPTO:
762
* Return endpoint map elements that
763
* contain a version of the specified
764
* interface UUID less than or equal to
765
* the specified major and minor
768
if (r->in.interface_id->vers_major >
769
eps->e[i].syntax_id.if_version >> 16) {
772
if (r->in.interface_id->vers_major ==
773
(eps->e[i].syntax_id.if_version >> 16) &&
774
r->in.interface_id->vers_minor >=
775
(eps->e[i].syntax_id.if_version && 0xFFFF)) {
781
return EPMAPPER_STATUS_CANT_PERFORM_OP;
787
ZERO_STRUCT(r->out.entries[num_ents].object);
789
DEBUG(10, ("_epm_Lookup: Adding tower for '%s'\n",
791
r->out.entries[num_ents].annotation = talloc_strdup(r->out.entries,
793
r->out.entries[num_ents].tower = talloc(r->out.entries,
795
if (r->out.entries[num_ents].tower == NULL) {
796
rc = EPMAPPER_STATUS_NO_MEMORY;
799
r->out.entries[num_ents].tower->tower.floors = talloc_move(r->out.entries[num_ents].tower, &eps->e[i].ep.floors);
800
r->out.entries[num_ents].tower->tower.num_floors = eps->e[i].ep.num_floors;
801
r->out.entries[num_ents].tower->tower_length = 0;
807
*r->out.num_ents = num_ents;
811
if (eps->count == 0) {
812
close_policy_hnd(p, entry_handle);
813
ZERO_STRUCTP(r->out.entry_handle);
814
rc = EPMAPPER_STATUS_NO_MORE_ENTRIES;
818
rc = EPMAPPER_STATUS_OK;
820
talloc_free(tmp_ctx);
828
* Apply some algorithm (using the fields in the map_tower) to an endpoint map
829
* to produce a list of protocol towers.
831
error_status_t _epm_Map(struct pipes_struct *p,
834
struct policy_handle *entry_handle;
835
enum dcerpc_transport_t transport;
836
struct ndr_syntax_id ifid;
837
struct epm_floor *floors;
842
uint32_t num_towers = 0;
843
uint32_t num_floors = 0;
847
*r->out.num_towers = 0;
848
r->out.towers = NULL;
850
if (r->in.map_tower == NULL || r->in.max_towers == 0 ||
851
r->in.map_tower->tower.num_floors < 3) {
852
return EPMAPPER_STATUS_NO_MORE_ENTRIES;
855
tmp_ctx = talloc_stackframe();
856
if (tmp_ctx == NULL) {
857
return EPMAPPER_STATUS_NO_MEMORY;
860
ZERO_STRUCTP(r->out.entry_handle);
862
DEBUG(3, ("_epm_Map: Trying to map max. %u towers.\n",
866
* A tower has normally up to 6 floors
868
* +-----------------------------------------------------------------+
869
* | Floor 1 | Provides the RPC interface identifier. (e.g. UUID for |
871
* +---------+-------------------------------------------------------+
872
* | Floor 2 | Transfer syntax (NDR endcoded) |
873
* +---------+-------------------------------------------------------+
874
* | Floor 3 | RPC protocol identifier (ncacn_tcp_ip, ncacn_np, ...) |
875
* +---------+-------------------------------------------------------+
876
* | Floor 4 | Port address (e.g. TCP Port: 49156) |
877
* +---------+-------------------------------------------------------+
878
* | Floor 5 | Transport (e.g. IP:192.168.51.10) |
879
* +---------+-------------------------------------------------------+
880
* | Floor 6 | Routing |
881
* +---------+-------------------------------------------------------+
883
num_floors = r->in.map_tower->tower.num_floors;
884
floors = r->in.map_tower->tower.floors;
886
/* We accept NDR as the transfer syntax */
887
dcerpc_floor_get_lhs_data(&floors[1], &ifid);
889
if (floors[1].lhs.protocol != EPM_PROTOCOL_UUID ||
890
!GUID_equal(&ifid.uuid, &ndr_transfer_syntax.uuid) ||
891
ifid.if_version != ndr_transfer_syntax.if_version) {
892
rc = EPMAPPER_STATUS_NO_MORE_ENTRIES;
896
/* We only talk to sane transports */
897
transport = dcerpc_transport_by_tower(&r->in.map_tower->tower);
898
if (transport == NCA_UNKNOWN) {
899
DEBUG(2, ("epm_Map: Client requested unknown transport with"
901
for (i = 2; i < r->in.map_tower->tower.num_floors; i++) {
902
DEBUG(2, ("%d, ", r->in.map_tower->tower.floors[i].lhs.protocol));
905
rc = EPMAPPER_STATUS_NO_MORE_ENTRIES;
909
if (r->in.entry_handle == NULL ||
910
policy_handle_empty(r->in.entry_handle)) {
913
DEBUG(5, ("_epm_Map: No entry_handle found, creating it.\n"));
915
eps = talloc_zero(tmp_ctx, struct rpc_eps);
917
rc = EPMAPPER_STATUS_NO_MEMORY;
926
* Apply some algorithm (using the fields in the map_tower)
927
* to an endpoint map to produce a list of protocol towers.
929
* The following code is the mysterious "some algorithm"!
932
/* Filter by object id if one was given. */
933
if (r->in.object == NULL || GUID_all_zero(r->in.object)) {
939
eps->count = build_ep_list(eps,
942
p->server_id == NULL ? NULL : p->server_id->addr,
944
if (eps->count == 0) {
945
rc = EPMAPPER_STATUS_NO_MORE_ENTRIES;
949
/* Filter out endpoints which match the interface. */
951
struct rpc_eps *teps;
954
teps = talloc_zero(tmp_ctx, struct rpc_eps);
956
rc = EPMAPPER_STATUS_NO_MEMORY;
960
for (i = 0; i < eps->count; i++) {
961
if (data_blob_cmp(&r->in.map_tower->tower.floors[0].lhs.lhs_data,
962
&eps->e[i].ep.floors[0].lhs.lhs_data) != 0 ||
963
transport != dcerpc_transport_by_tower(&eps->e[i].ep)) {
967
teps->e = talloc_realloc(tmp_ctx,
969
struct dcesrv_ep_iface,
971
if (teps->e == NULL) {
975
teps->e[total].ep.floors = talloc_move(teps, &eps->e[i].ep.floors);
976
teps->e[total].ep.num_floors = eps->e[i].ep.num_floors;
977
teps->e[total].name = talloc_move(teps, &eps->e[i].name);
978
teps->e[total].syntax_id = eps->e[i].syntax_id;
987
/* end of "some algorithm" */
989
ok = create_policy_hnd(p, r->out.entry_handle, eps);
991
rc = EPMAPPER_STATUS_NO_MEMORY;
995
ok = find_policy_by_hnd(p, r->out.entry_handle, (void **)(void*) &eps);
997
rc = EPMAPPER_STATUS_NO_MEMORY;
1000
entry_handle = r->out.entry_handle;
1002
DEBUG(5, ("_epm_Map: Trying to find entry_handle.\n"));
1004
ok = find_policy_by_hnd(p, r->in.entry_handle, (void **)(void*) &eps);
1006
rc = EPMAPPER_STATUS_NO_MEMORY;
1009
entry_handle = r->in.entry_handle;
1012
if (eps == NULL || eps->e == NULL) {
1013
rc = EPMAPPER_STATUS_NO_MORE_ENTRIES;
1017
/* return the next N elements */
1018
count = r->in.max_towers;
1019
if (count > eps->count) {
1024
close_policy_hnd(p, entry_handle);
1025
ZERO_STRUCTP(r->out.entry_handle);
1027
rc = EPMAPPER_STATUS_NO_MORE_ENTRIES;
1031
r->out.towers = talloc_array(p->mem_ctx, struct epm_twr_p_t, count);
1032
if (r->out.towers == NULL) {
1033
rc = EPMAPPER_STATUS_NO_MEMORY;
1037
for (i = 0; i < count; i++) {
1038
DEBUG(5, ("_epm_Map: Map tower for '%s'\n",
1041
r->out.towers[num_towers].twr = talloc(r->out.towers,
1043
if (r->out.towers[num_towers].twr == NULL) {
1044
rc = EPMAPPER_STATUS_NO_MEMORY;
1047
r->out.towers[num_towers].twr->tower.floors = talloc_move(r->out.towers[num_towers].twr, &eps->e[i].ep.floors);
1048
r->out.towers[num_towers].twr->tower.num_floors = eps->e[i].ep.num_floors;
1049
r->out.towers[num_towers].twr->tower_length = 0;
1054
*r->out.num_towers = num_towers;
1056
eps->count -= count;
1058
if (eps->count == 0) {
1059
close_policy_hnd(p, entry_handle);
1060
ZERO_STRUCTP(r->out.entry_handle);
1063
rc = EPMAPPER_STATUS_OK;
1065
talloc_free(tmp_ctx);
1071
* epm_LookupHandleFree
1073
error_status_t _epm_LookupHandleFree(struct pipes_struct *p,
1074
struct epm_LookupHandleFree *r)
1076
if (r->in.entry_handle == NULL) {
1077
return EPMAPPER_STATUS_OK;
1080
if (is_valid_policy_hnd(r->in.entry_handle)) {
1081
close_policy_hnd(p, r->in.entry_handle);
1084
r->out.entry_handle = r->in.entry_handle;
1086
return EPMAPPER_STATUS_OK;
1093
* A client implementation SHOULD NOT call this method. These extensions do not
1094
* provide an alternative method.
1096
error_status_t _epm_InqObject(struct pipes_struct *p,
1097
struct epm_InqObject *r)
1099
p->rng_fault_state = true;
1100
return EPMAPPER_STATUS_CANT_PERFORM_OP;
1107
* A client implementation SHOULD NOT call this method. These extensions do not
1108
* provide an alternative method.
1110
error_status_t _epm_MgmtDelete(struct pipes_struct *p,
1111
struct epm_MgmtDelete *r)
1113
p->rng_fault_state = true;
1114
return EPMAPPER_STATUS_CANT_PERFORM_OP;
1121
error_status_t _epm_MapAuth(struct pipes_struct *p,
1122
struct epm_MapAuth *r)
1124
p->rng_fault_state = true;
1125
return EPMAPPER_STATUS_CANT_PERFORM_OP;
1128
/* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */