1/*
2   Unix SMB/CIFS implementation.
3   RPC pipe client
4
5   Copyright (C) Tim Potter 2000
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 2 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, write to the Free Software
19   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#include "includes.h"
23#include "rpcclient.h"
24
25/* Check DFS is supported by the remote server */
26
27static NTSTATUS cmd_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx,
28                              int argc, const char **argv)
29{
30	BOOL dfs_exists;
31	NTSTATUS result;
32
33	if (argc != 1) {
34		printf("Usage: %s\n", argv[0]);
35		return NT_STATUS_OK;
36	}
37
38	result = cli_dfs_exist(cli, mem_ctx, &dfs_exists);
39
40	if (NT_STATUS_IS_OK(result))
41		printf("dfs is %spresent\n", dfs_exists ? "" : "not ");
42
43	return result;
44}
45
46static NTSTATUS cmd_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
47                            int argc, const char **argv)
48{
49	NTSTATUS result;
50	const char *entrypath, *servername, *sharename, *comment;
51	uint32 flags = 0;
52
53	if (argc != 5) {
54		printf("Usage: %s entrypath servername sharename comment\n",
55		       argv[0]);
56		return NT_STATUS_OK;
57	}
58
59	entrypath = argv[1];
60	servername = argv[2];
61	sharename = argv[3];
62	comment = argv[4];
63
64	result = cli_dfs_add(cli, mem_ctx, entrypath, servername,
65			     sharename, comment, flags);
66
67	return result;
68}
69
70static NTSTATUS cmd_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx,
71                               int argc, const char **argv)
72{
73	NTSTATUS result;
74	const char *entrypath, *servername, *sharename;
75
76	if (argc != 4) {
77		printf("Usage: %s entrypath servername sharename\n", argv[0]);
78		return NT_STATUS_OK;
79	}
80
81	entrypath = argv[1];
82	servername = argv[2];
83	sharename = argv[3];
84
85	result = cli_dfs_remove(cli, mem_ctx, entrypath, servername,
86				sharename);
87
88	return result;
89}
90
91/* Display a DFS_INFO_1 structure */
92
93static void display_dfs_info_1(DFS_INFO_1 *info1)
94{
95	fstring temp;
96
97	unistr2_to_ascii(temp, &info1->entrypath, sizeof(temp) - 1);
98	printf("entrypath: %s\n", temp);
99}
100
101/* Display a DFS_INFO_2 structure */
102
103static void display_dfs_info_2(DFS_INFO_2 *info2)
104{
105	fstring temp;
106
107	unistr2_to_ascii(temp, &info2->entrypath, sizeof(temp) - 1);
108	printf("entrypath: %s\n", temp);
109
110	unistr2_to_ascii(temp, &info2->comment, sizeof(temp) - 1);
111	printf("\tcomment: %s\n", temp);
112
113	printf("\tstate: %d\n", info2->state);
114	printf("\tnum_storages: %d\n", info2->num_storages);
115}
116
117/* Display a DFS_INFO_3 structure */
118
119static void display_dfs_info_3(DFS_INFO_3 *info3)
120{
121	fstring temp;
122	int i;
123
124	unistr2_to_ascii(temp, &info3->entrypath, sizeof(temp) - 1);
125	printf("entrypath: %s\n", temp);
126
127	unistr2_to_ascii(temp, &info3->comment, sizeof(temp) - 1);
128	printf("\tcomment: %s\n", temp);
129
130	printf("\tstate: %d\n", info3->state);
131	printf("\tnum_storages: %d\n", info3->num_storages);
132
133	for (i = 0; i < info3->num_storages; i++) {
134		DFS_STORAGE_INFO *dsi = &info3->storages[i];
135
136		unistr2_to_ascii(temp, &dsi->servername, sizeof(temp) - 1);
137		printf("\t\tstorage[%d] servername: %s\n", i, temp);
138
139		unistr2_to_ascii(temp, &dsi->sharename, sizeof(temp) - 1);
140		printf("\t\tstorage[%d] sharename: %s\n", i, temp);
141	}
142}
143
144/* Display a DFS_INFO_CTR structure */
145
146static void display_dfs_info_ctr(DFS_INFO_CTR *ctr)
147{
148	int i;
149
150	for (i = 0; i < ctr->num_entries; i++) {
151		switch (ctr->switch_value) {
152		case 0x01:
153			display_dfs_info_1(&ctr->dfs.info1[i]);
154			break;
155		case 0x02:
156			display_dfs_info_2(&ctr->dfs.info2[i]);
157			break;
158		case 0x03:
159			display_dfs_info_3(&ctr->dfs.info3[i]);
160			break;
161		default:
162			printf("unsupported info level %d\n",
163			       ctr->switch_value);
164			break;
165		}
166	}
167}
168
169/* Enumerate dfs shares */
170
171static NTSTATUS cmd_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
172                             int argc, const char **argv)
173{
174	DFS_INFO_CTR ctr;
175	NTSTATUS result;
176	uint32 info_level = 1;
177
178	if (argc > 2) {
179		printf("Usage: %s [info_level]\n", argv[0]);
180		return NT_STATUS_OK;
181	}
182
183	if (argc == 2)
184		info_level = atoi(argv[1]);
185
186	result = cli_dfs_enum(cli, mem_ctx, info_level, &ctr);
187
188	if (NT_STATUS_IS_OK(result))
189		display_dfs_info_ctr(&ctr);
190
191	return result;
192}
193
194static NTSTATUS cmd_dfs_getinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
195                                int argc, const char **argv)
196{
197	NTSTATUS result;
198	const char *entrypath, *servername, *sharename;
199	uint32 info_level = 1;
200	DFS_INFO_CTR ctr;
201
202	if (argc < 4 || argc > 5) {
203		printf("Usage: %s entrypath servername sharename "
204                       "[info_level]\n", argv[0]);
205		return NT_STATUS_OK;
206	}
207
208	entrypath = argv[1];
209	servername = argv[2];
210	sharename = argv[3];
211
212	if (argc == 5)
213		info_level = atoi(argv[4]);
214
215	result = cli_dfs_get_info(cli, mem_ctx, entrypath, servername,
216				  sharename, info_level, &ctr);
217
218	if (NT_STATUS_IS_OK(result))
219		display_dfs_info_ctr(&ctr);
220
221	return result;
222}
223
224/* List of commands exported by this module */
225
226struct cmd_set dfs_commands[] = {
227
228	{ "DFS" },
229
230	{ "dfsexist",  RPC_RTYPE_NTSTATUS, cmd_dfs_exist,   NULL, PI_NETDFS, "Query DFS support",    "" },
231	{ "dfsadd",    RPC_RTYPE_NTSTATUS, cmd_dfs_add,     NULL, PI_NETDFS, "Add a DFS share",      "" },
232	{ "dfsremove", RPC_RTYPE_NTSTATUS, cmd_dfs_remove,  NULL, PI_NETDFS, "Remove a DFS share",   "" },
233	{ "dfsgetinfo",RPC_RTYPE_NTSTATUS, cmd_dfs_getinfo, NULL, PI_NETDFS, "Query DFS share info", "" },
234	{ "dfsenum",   RPC_RTYPE_NTSTATUS, cmd_dfs_enum,    NULL, PI_NETDFS, "Enumerate dfs shares", "" },
235
236	{ NULL }
237};
238