r13316: Let the carnage begin....
[kai/samba.git] / source3 / rpcclient / cmd_dfs.c
1 /* 
2    Unix SMB/CIFS implementation.
3    RPC pipe client
4
5    Copyright (C) Tim Potter 2000
6    Copyright (C) Jelmer Vernooij       2005.
7
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 2 of the License, or
11    (at your option) any later version.
12    
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.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "rpcclient.h"
25
26 /* Check DFS is supported by the remote server */
27
28 static NTSTATUS cmd_dfs_exist(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
29                               int argc, const char **argv)
30 {
31         uint32 dfs_exists;
32         NTSTATUS result;
33
34         if (argc != 1) {
35                 printf("Usage: %s\n", argv[0]);
36                 return NT_STATUS_OK;
37         }
38
39         result = rpccli_dfs_GetManagerVersion(cli, mem_ctx, &dfs_exists);
40
41         if (NT_STATUS_IS_OK(result))
42                 printf("dfs is %spresent\n", dfs_exists ? "" : "not ");
43
44         return result;
45 }
46
47 static NTSTATUS cmd_dfs_add(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
48                             int argc, const char **argv)
49 {
50         NTSTATUS result;
51         const char *path, *servername, *sharename, *comment;
52         uint32 flags = 0;
53
54         if (argc != 5) {
55                 printf("Usage: %s path servername sharename comment\n", 
56                        argv[0]);
57                 return NT_STATUS_OK;
58         }
59
60         path = argv[1];
61         servername = argv[2];
62         sharename = argv[3];
63         comment = argv[4];
64
65         result = rpccli_dfs_Add(cli, mem_ctx, path, servername, 
66                              sharename, comment, flags);
67
68         return result;
69 }
70
71 static NTSTATUS cmd_dfs_remove(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
72                                int argc, const char **argv)
73 {
74         NTSTATUS result;
75         const char *path, *servername, *sharename;
76
77         if (argc != 4) {
78                 printf("Usage: %s path servername sharename\n", argv[0]);
79                 return NT_STATUS_OK;
80         }
81
82         path = argv[1];
83         servername = argv[2];
84         sharename = argv[3];
85
86         result = rpccli_dfs_Remove(cli, mem_ctx, path, servername, 
87                                 sharename);
88
89         return result;
90 }
91
92 /* Display a DFS_INFO_1 structure */
93
94 static void display_dfs_info_1(NETDFS_DFS_INFO1 *info1)
95 {
96         fstring temp;
97
98         unistr2_to_ascii(temp, &info1->path, sizeof(temp) - 1);
99         printf("path: %s\n", temp);
100 }
101
102 /* Display a DFS_INFO_2 structure */
103
104 static void display_dfs_info_2(NETDFS_DFS_INFO2 *info2)
105 {
106         fstring temp;
107
108         unistr2_to_ascii(temp, &info2->path, sizeof(temp) - 1);
109         printf("path: %s\n", temp);
110
111         unistr2_to_ascii(temp, &info2->comment, sizeof(temp) - 1);
112         printf("\tcomment: %s\n", temp);
113
114         printf("\tstate: %d\n", info2->state);
115         printf("\tnum_stores: %d\n", info2->num_stores);
116 }
117
118 /* Display a DFS_INFO_3 structure */
119
120 static void display_dfs_info_3(NETDFS_DFS_INFO3 *info3)
121 {
122         fstring temp;
123         int i;
124
125         unistr2_to_ascii(temp, &info3->path, sizeof(temp) - 1);
126         printf("path: %s\n", temp);
127
128         unistr2_to_ascii(temp, &info3->comment, sizeof(temp) - 1);
129         printf("\tcomment: %s\n", temp);
130
131         printf("\tstate: %d\n", info3->state);
132         printf("\tnum_stores: %d\n", info3->num_stores);
133
134         for (i = 0; i < info3->num_stores; i++) {
135                 NETDFS_DFS_STORAGEINFO *dsi = &info3->stores[i];
136
137                 unistr2_to_ascii(temp, &dsi->server, sizeof(temp) - 1);
138                 printf("\t\tstorage[%d] server: %s\n", i, temp);
139
140                 unistr2_to_ascii(temp, &dsi->share, sizeof(temp) - 1);
141                 printf("\t\tstorage[%d] share: %s\n", i, temp);
142         }
143 }
144
145
146 /* Display a DFS_INFO_CTR structure */
147 static void display_dfs_info(NETDFS_DFS_INFO_CTR *ctr)
148 {
149         switch (ctr->switch_value) {
150                 case 0x01:
151                         display_dfs_info_1(&ctr->u.info1);
152                         break;
153                 case 0x02:
154                         display_dfs_info_2(&ctr->u.info2);
155                         break;
156                 case 0x03:
157                         display_dfs_info_3(&ctr->u.info3);
158                         break;
159                 default:
160                         printf("unsupported info level %d\n", 
161                                ctr->switch_value);
162                         break;
163         }
164 }
165
166 static void display_dfs_enumstruct(NETDFS_DFS_ENUMSTRUCT *ctr)
167 {
168         int i;
169         
170         /* count is always the first element, so we can just use info1 here */
171         for (i = 0; i < ctr->e.u.info1.count; i++) {
172                 switch (ctr->level) {
173                 case 1: display_dfs_info_1(&ctr->e.u.info1.s[i]); break;
174                 case 2: display_dfs_info_2(&ctr->e.u.info2.s[i]); break;
175                 case 3: display_dfs_info_3(&ctr->e.u.info3.s[i]); break;
176                 default:
177                                 printf("unsupported info level %d\n", 
178                                ctr->level);
179                                 return;
180                 }
181         }
182 }
183
184 /* Enumerate dfs shares */
185
186 static NTSTATUS cmd_dfs_enum(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
187                              int argc, const char **argv)
188 {
189         NETDFS_DFS_ENUMSTRUCT str;
190         NETDFS_DFS_ENUMINFO_CTR ctr;
191         NTSTATUS result;
192         uint32 info_level = 1;
193         uint32 unknown = 0, total = 0;
194
195         if (argc > 2) {
196                 printf("Usage: %s [info_level]\n", argv[0]);
197                 return NT_STATUS_OK;
198         }
199
200         if (argc == 2)
201                 info_level = atoi(argv[1]);
202
203         ZERO_STRUCT(ctr);
204         init_netdfs_dfs_EnumStruct(&str, info_level, ctr);
205         str.e.ptr0 = 1;
206
207         result = rpccli_dfs_Enum(cli, mem_ctx, info_level, 0xFFFFFFFF, &str, &unknown, &total);
208
209         if (NT_STATUS_IS_OK(result))
210                 display_dfs_enumstruct(&str);
211
212         return result;
213 }
214
215 static NTSTATUS cmd_dfs_getinfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
216                                 int argc, const char **argv)
217 {
218         NTSTATUS result;
219         const char *path, *servername, *sharename;
220         uint32 info_level = 1;
221         NETDFS_DFS_INFO_CTR ctr;
222
223         if (argc < 4 || argc > 5) {
224                 printf("Usage: %s path servername sharename "
225                        "[info_level]\n", argv[0]);
226                 return NT_STATUS_OK;
227         }
228
229         path = argv[1];
230         servername = argv[2];
231         sharename = argv[3];
232
233         if (argc == 5)
234                 info_level = atoi(argv[4]);
235
236         result = rpccli_dfs_GetInfo(cli, mem_ctx, path, servername, 
237                                   sharename, info_level, &ctr);
238
239         if (NT_STATUS_IS_OK(result))
240                 display_dfs_info(&ctr);
241
242         return result;
243 }
244
245 /* List of commands exported by this module */
246
247 struct cmd_set dfs_commands[] = {
248
249         { "DFS" },
250
251         { "dfsexist",  RPC_RTYPE_NTSTATUS, cmd_dfs_exist,   NULL, PI_NETDFS, NULL, "Query DFS support",    "" },
252         { "dfsadd",    RPC_RTYPE_NTSTATUS, cmd_dfs_add,     NULL, PI_NETDFS, NULL, "Add a DFS share",      "" },
253         { "dfsremove", RPC_RTYPE_NTSTATUS, cmd_dfs_remove,  NULL, PI_NETDFS, NULL, "Remove a DFS share",   "" },
254         { "dfsgetinfo",RPC_RTYPE_NTSTATUS, cmd_dfs_getinfo, NULL, PI_NETDFS, NULL, "Query DFS share info", "" },
255         { "dfsenum",   RPC_RTYPE_NTSTATUS, cmd_dfs_enum,    NULL, PI_NETDFS, NULL, "Enumerate dfs shares", "" },
256
257         { NULL }
258 };