7753df24709f564bdc4943358193b33d90fd6960
[samba.git] / source3 / rpcclient / cmd_epmapper.c
1 /*
2    Unix SMB/CIFS implementation.
3    RPC pipe client
4
5    Copyright (C) Volker Lendecke 2009
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "rpcclient.h"
23 #include "../librpc/gen_ndr/ndr_epmapper_c.h"
24 #include "librpc/ndr/ndr_table.h"
25
26 static NTSTATUS cmd_epmapper_map(struct rpc_pipe_client *p,
27                                  TALLOC_CTX *mem_ctx,
28                                  int argc, const char **argv)
29 {
30         struct dcerpc_binding_handle *b = p->binding_handle;
31         struct dcerpc_binding *map_binding;
32         struct epm_twr_t map_tower;
33         struct epm_twr_p_t towers[500];
34         struct policy_handle entry_handle;
35         struct ndr_syntax_id abstract_syntax;
36         uint32_t num_towers;
37         TALLOC_CTX *tmp_ctx = talloc_stackframe();
38         NTSTATUS status;
39         uint32_t result;
40         uint32_t i;
41         const struct ndr_interface_list *l;
42         const char *interface_name = "lsarpc";
43         enum dcerpc_transport_t transport = NCACN_NP;
44         bool ok = false;
45
46         if (argc > 3) {
47                 d_fprintf(stderr, "Usage: %s [interface_name] [transport]\n",
48                         argv[0]);
49                 return NT_STATUS_OK;
50         }
51
52         if (argc >= 2) {
53                 interface_name = argv[1];
54         }
55
56         for (l = ndr_table_list(); l != NULL; l = l->next) {
57
58                 ok = strequal(interface_name, l->table->name);
59                 if (ok) {
60                         abstract_syntax = l->table->syntax_id;
61                         break;
62                 }
63         }
64
65         if (!ok) {
66                 d_fprintf(stderr, "unknown interface: %s\n",
67                         interface_name);
68                 status = NT_STATUS_UNSUCCESSFUL;
69                 goto done;
70         }
71
72         if (argc >= 3) {
73                 transport = dcerpc_transport_by_name(argv[2]);
74                 if (transport == NCA_UNKNOWN) {
75                         d_fprintf(stderr, "unknown transport: %s\n",
76                                 argv[2]);
77                         status = NT_STATUS_UNSUCCESSFUL;
78                         goto done;
79                 }
80         }
81
82         /* 127.0.0.1[0] => correct? needed? */
83         status = dcerpc_parse_binding(tmp_ctx, "ncacn_np:127.0.0.1[0]",
84                                       &map_binding);
85         if (!NT_STATUS_IS_OK(status)) {
86                 d_fprintf(stderr, "dcerpc_parse_binding returned %s\n",
87                           nt_errstr(status));
88                 goto done;
89         }
90
91         status = dcerpc_binding_set_transport(map_binding, transport);
92         if (!NT_STATUS_IS_OK(status)) {
93                 d_fprintf(stderr, "dcerpc_binding_set_transport returned %s\n",
94                           nt_errstr(status));
95                 goto done;
96         }
97
98         status = dcerpc_binding_set_abstract_syntax(map_binding,
99                                                     &abstract_syntax);
100         if (!NT_STATUS_IS_OK(status)) {
101                 d_fprintf(stderr, "dcerpc_binding_set_abstract_syntax returned %s\n",
102                           nt_errstr(status));
103                 goto done;
104         }
105
106         status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
107                                             &map_tower.tower);
108         if (!NT_STATUS_IS_OK(status)) {
109                 d_fprintf(stderr, "dcerpc_binding_build_tower returned %s\n",
110                           nt_errstr(status));
111                 goto done;
112         }
113
114         ZERO_STRUCT(towers);
115         ZERO_STRUCT(entry_handle);
116
117         status = dcerpc_epm_Map(
118                 b, tmp_ctx, &abstract_syntax.uuid,
119                 &map_tower, &entry_handle, ARRAY_SIZE(towers),
120                 &num_towers, towers, &result);
121         if (!NT_STATUS_IS_OK(status)) {
122                 d_fprintf(stderr, "dcerpc_epm_Map returned %s\n",
123                           nt_errstr(status));
124                 goto done;
125         }
126
127         if (result != EPMAPPER_STATUS_OK) {
128                 d_fprintf(stderr, "epm_Map returned %u (0x%08X)\n",
129                           result, result);
130                 status = NT_STATUS_UNSUCCESSFUL;
131                 goto done;
132         }
133
134         d_printf("num_tower[%u]\n", num_towers);
135
136         for (i=0; i < num_towers; i++) {
137                 struct dcerpc_binding *binding;
138
139                 if (towers[i].twr == NULL) {
140                         d_fprintf(stderr, "tower[%u] NULL\n", i);
141                         break;
142                 }
143
144                 status = dcerpc_binding_from_tower(tmp_ctx, &towers[i].twr->tower,
145                                                    &binding);
146                 if (!NT_STATUS_IS_OK(status)) {
147                         break;
148                 }
149
150                 d_printf("tower[%u] %s\n", i, dcerpc_binding_string(tmp_ctx, binding));
151         }
152 done:
153         TALLOC_FREE(tmp_ctx);
154         return status;
155 }
156
157 static NTSTATUS cmd_epmapper_lookup(struct rpc_pipe_client *p,
158                                     TALLOC_CTX *mem_ctx,
159                                     int argc, const char **argv)
160 {
161         struct dcerpc_binding_handle *b = p->binding_handle;
162         struct policy_handle entry_handle;
163
164         ZERO_STRUCT(entry_handle);
165
166         while (true) {
167                 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
168                 uint32_t num_entries;
169                 struct epm_entry_t entry;
170                 NTSTATUS status;
171                 char *guid_string;
172                 struct dcerpc_binding *binding;
173                 uint32_t result;
174
175                 status = dcerpc_epm_Lookup(b, tmp_ctx,
176                                    0, /* rpc_c_ep_all */
177                                    NULL,
178                                    NULL,
179                                    0, /* rpc_c_vers_all */
180                                    &entry_handle,
181                                    1, /* max_ents */
182                                    &num_entries, &entry,
183                                    &result);
184                 if (!NT_STATUS_IS_OK(status)) {
185                         d_fprintf(stderr, "dcerpc_epm_Lookup returned %s\n",
186                                   nt_errstr(status));
187                         break;
188                 }
189
190                 if (result == EPMAPPER_STATUS_NO_MORE_ENTRIES) {
191                         d_fprintf(stderr, "epm_Lookup no more entries\n");
192                         break;
193                 }
194
195                 if (result != EPMAPPER_STATUS_OK) {
196                         d_fprintf(stderr, "epm_Lookup returned %u (0x%08X)\n",
197                                   result, result);
198                         break;
199                 }
200
201                 if (num_entries != 1) {
202                         d_fprintf(stderr, "epm_Lookup returned %d "
203                                   "entries, expected one\n", (int)num_entries);
204                         break;
205                 }
206
207                 guid_string = GUID_string(tmp_ctx, &entry.object);
208                 if (guid_string == NULL) {
209                         break;
210                 }
211
212                 status = dcerpc_binding_from_tower(tmp_ctx, &entry.tower->tower,
213                                                    &binding);
214                 if (!NT_STATUS_IS_OK(status)) {
215                         break;
216                 }
217
218                 d_printf("%s %s: %s\n", guid_string,
219                          dcerpc_binding_string(tmp_ctx, binding),
220                          entry.annotation);
221
222                 TALLOC_FREE(tmp_ctx);
223         }
224
225         return NT_STATUS_OK;
226 }
227
228
229 /* List of commands exported by this module */
230
231 struct cmd_set epmapper_commands[] = {
232
233         { "EPMAPPER" },
234
235         { "epmmap", RPC_RTYPE_NTSTATUS, cmd_epmapper_map,     NULL,
236           &ndr_table_epmapper, NULL, "Map a binding", "" },
237         { "epmlookup", RPC_RTYPE_NTSTATUS, cmd_epmapper_lookup,     NULL,
238           &ndr_table_epmapper, NULL, "Lookup bindings", "" },
239         { NULL }
240 };