a152e3528e38b683d5bf4db5b6d07ecf8acd18a1
[kai/samba.git] / source3 / rpc_parse / parse_dfs.c
1 /* 
2  *  Unix SMB/Netbios implementation.
3  *  Version 1.9.
4  *  MSDfs RPC Pipe client / server routines
5  *  Copyright (C) Andrew Tridgell              1992-2000,
6  *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
7  *  Copyright (C) Shirish Kalele               2000.
8  *  Copyright (C) Jeremy Allison                                2001.
9  *  
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *  
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *  
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25 #include "includes.h"
26 #include "nterr.h"
27 #include "rpc_parse.h"   
28
29 /******************************************************************* 
30 Make a DFS_Q_DFS_QUERY structure
31 *******************************************************************/
32
33 void init_dfs_q_dfs_exist(DFS_Q_DFS_EXIST *q_d)
34 {
35         q_d->dummy = 0;
36 }
37
38 /*************************************************************
39  Read/write a DFS_Q_DFS_EXIST structure - dummy...
40  ************************************************************/
41
42 BOOL dfs_io_q_dfs_exist(char *desc, DFS_Q_DFS_EXIST *q_d, prs_struct *ps, int depth)
43 {
44         if(q_d == NULL)
45                 return False;
46   
47         prs_debug(ps, depth, desc, "dfs_io_q_dfs_exist");
48
49         return True;
50 }
51   
52 /*************************************************************
53  Read/write a DFS_R_DFS_EXIST structure
54  ************************************************************/
55
56 BOOL dfs_io_r_dfs_exist(char *desc, DFS_R_DFS_EXIST *q_d, prs_struct *ps, int depth)
57 {
58         if(q_d == NULL)
59                 return False;
60   
61         prs_debug(ps, depth, desc, "dfs_io_r_dfs_exist");
62         depth++;
63
64         if(!prs_align(ps))
65                 return False;
66
67         if(!prs_uint32("exist flag", ps, 0, &q_d->status))
68                 return False;
69
70         return True;
71 }
72   
73 /******************************************************************* 
74 Make a DFS_Q_DFS_REMOVE structure
75 *******************************************************************/
76
77 BOOL init_dfs_q_dfs_remove(DFS_Q_DFS_REMOVE *q_d, char *entrypath, 
78                            char *servername, char *sharename)
79 {
80         DEBUG(5,("init_dfs_q_dfs_remove\n"));
81         init_unistr2(&q_d->DfsEntryPath, entrypath,  strlen(entrypath)+1);
82         init_unistr2(&q_d->ServerName,   servername, strlen(servername)+1);
83         init_unistr2(&q_d->ShareName,    sharename,  strlen(sharename)+1);
84         q_d->ptr_ServerName = q_d->ptr_ShareName = 1;
85         return True;
86 }
87
88 /******************************************************************* 
89 Read/write a DFS_Q_DFS_REMOVE structure
90 *******************************************************************/
91
92 BOOL dfs_io_q_dfs_remove(char *desc, DFS_Q_DFS_REMOVE *q_d, prs_struct *ps, int depth)
93 {
94         if(q_d == NULL)
95                 return False;
96
97         prs_debug(ps, depth, desc, "dfs_io_q_dfs_remove");
98         depth++;
99   
100         if(!prs_align(ps))
101                 return False;
102   
103         if(!smb_io_unistr2("DfsEntryPath",&q_d->DfsEntryPath, 1, ps, depth))
104                 return False;
105
106         if(!prs_align(ps))
107                 return False;
108
109         if(!prs_uint32("ptr_ServerName", ps, depth, &q_d->ptr_ServerName))
110                 return False;
111         if(q_d->ptr_ServerName)
112                 if (!smb_io_unistr2("ServerName",&q_d->ServerName, q_d->ptr_ServerName, ps, depth))
113                         return False;
114         if(!prs_align(ps))
115                 return False;
116
117         if(!prs_uint32("ptr_ShareName", ps, depth, &q_d->ptr_ShareName))
118                 return False;
119         if(q_d->ptr_ShareName)
120                 if (!smb_io_unistr2("ShareName",&q_d->ShareName,  q_d->ptr_ShareName, ps, depth))
121                         return False;
122         if(!prs_align(ps))
123                 return False;
124
125         return True;
126 }
127
128 /******************************************************************* 
129 Read/write a DFS_R_DFS_REMOVE structure
130 *******************************************************************/
131
132 BOOL dfs_io_r_dfs_remove(char *desc, DFS_R_DFS_REMOVE *r_d, prs_struct *ps, int depth)
133 {
134         if(r_d == NULL) 
135                 return False;
136
137         prs_debug(ps, depth, desc, "dfs_io_r_dfs_remove");
138         depth++;
139
140         if(!prs_werror("status", ps, depth, &r_d->status))
141                 return False;
142
143         return True;
144 }
145
146 /******************************************************************* 
147 Make a DFS_Q_DFS_ADD structure
148 *******************************************************************/
149
150 BOOL init_dfs_q_dfs_add(DFS_Q_DFS_ADD *q_d, char *entrypath, char *servername,
151                         char *sharename, char *comment, uint32 flags)
152 {
153         DEBUG(5,("init_dfs_q_dfs_add\n"));
154         q_d->ptr_DfsEntryPath = q_d->ptr_ServerName = q_d->ptr_ShareName = 1;
155         init_unistr2(&q_d->DfsEntryPath, entrypath,  strlen(entrypath)+1);
156         init_unistr2(&q_d->ServerName,   servername, strlen(servername)+1);
157         init_unistr2(&q_d->ShareName,    sharename,  strlen(sharename)+1);
158         if(comment != NULL) {
159                 init_unistr2(&q_d->Comment,      comment,    strlen(comment)+1);
160                 q_d->ptr_Comment = 1;
161         } else {
162                 q_d->ptr_Comment = 0;
163         }
164
165         q_d->Flags = flags;
166         return True;
167 }
168
169 /************************************************************
170  Read/write a DFS_Q_DFS_ADD structure
171  ************************************************************/
172
173 BOOL dfs_io_q_dfs_add(char *desc, DFS_Q_DFS_ADD *q_d, prs_struct *ps, int depth)
174 {
175         if(q_d == NULL)
176                 return False;
177
178         prs_debug(ps, depth, desc, "dfs_io_q_dfs_add");
179         depth++;
180   
181         if(!prs_align(ps))
182                 return False;
183   
184         if(!smb_io_unistr2("DfsEntryPath",&q_d->DfsEntryPath, 1, ps, depth))
185                 return False;
186         if(!prs_align(ps))
187                 return False;
188
189         if(!smb_io_unistr2("ServerName",&q_d->ServerName, 1, ps, depth))
190                 return False;
191         if(!prs_align(ps))
192                 return False;
193
194         if(!prs_uint32("ptr_ShareName", ps, depth, &q_d->ptr_ShareName))
195                 return False;
196         if(!smb_io_unistr2("ShareName",&q_d->ShareName,  1, ps, depth))
197                 return False;
198         if(!prs_align(ps))
199                 return False;
200
201         if(!prs_uint32("ptr_Comment", ps, depth, &q_d->ptr_Comment))
202                 return False;
203         if(!smb_io_unistr2("",&q_d->Comment, q_d->ptr_Comment , ps, depth))
204                 return False;
205         if(!prs_align(ps))
206                 return False;
207
208         if(!prs_uint32("Flags", ps, depth, &q_d->Flags))
209                 return True;
210
211         return True;
212 }
213
214 /************************************************************
215  Read/write a DFS_R_DFS_ADD structure 
216  ************************************************************/
217
218 BOOL dfs_io_r_dfs_add(char *desc, DFS_R_DFS_ADD *r_d, prs_struct *ps, int depth)
219 {
220         if(r_d == NULL)
221                 return False;
222
223         prs_debug(ps, depth, desc, "dfs_io_r_dfs_add");
224         depth++;
225
226         if(!prs_werror("status", ps, depth, &r_d->status))
227                 return False;
228
229         return True;
230 }
231
232 BOOL init_dfs_q_dfs_get_info(DFS_Q_DFS_GET_INFO *q_d, char *entrypath,
233                              char *servername, char *sharename, 
234                              uint32 info_level)
235 {
236         DEBUG(5,("init_dfs_q2_get_info\n"));
237         init_unistr2(&q_d->uni_path, entrypath,  strlen(entrypath)+1);
238         init_unistr2(&q_d->uni_server,   servername, strlen(servername)+1);
239         init_unistr2(&q_d->uni_share,    sharename,  strlen(sharename)+1);
240         q_d->level = info_level;
241         q_d->ptr_server = q_d->ptr_share = 1;
242         return True;
243 }
244
245 /************************************************************
246  Read/write a DFS_Q_GET_INFO structure
247  ************************************************************/
248
249 BOOL dfs_io_q_dfs_get_info(char* desc, DFS_Q_DFS_GET_INFO* q_i, prs_struct* ps, int depth)
250 {
251         if(q_i == NULL)
252                 return False;
253
254         prs_debug(ps, depth, desc, "dfs_io_q_dfs_get_info");
255         depth++;
256
257         if(!smb_io_unistr2("",&q_i->uni_path, 1, ps, depth))
258                 return False;
259
260         if(!prs_align(ps))
261                 return False;
262
263         if(!prs_uint32("ptr_server", ps, depth, &q_i->ptr_server))
264                 return False;
265
266         if(q_i->ptr_server)
267                 if (!smb_io_unistr2("",&q_i->uni_server, q_i->ptr_server, ps, depth))
268                         return False;
269         if(!prs_align(ps))
270                 return False;
271
272         if(!prs_uint32("ptr_share", ps, depth, &q_i->ptr_share))
273                 return False;
274         if(q_i->ptr_share)
275                 if(!smb_io_unistr2("", &q_i->uni_share, q_i->ptr_share, ps, depth))
276                         return False;
277         if(!prs_align(ps))
278                 return False;
279
280         if(!prs_uint32("level", ps, depth, &q_i->level))
281                 return False;
282         return True;
283 }
284
285 /************************************************************
286  Read/write a DFS_R_GET_INFO structure
287  ************************************************************/
288
289 BOOL dfs_io_r_dfs_get_info(char* desc, DFS_R_DFS_GET_INFO* r_i, prs_struct* ps, int depth)
290 {
291         if(r_i == NULL)
292                 return False;
293   
294         if(!prs_uint32("level", ps, depth, &r_i->level))
295                 return False;
296         if(!prs_uint32("ptr_ctr", ps, depth, &r_i->ptr_ctr))
297                 return False;
298
299         if(!dfs_io_dfs_info_ctr("", &r_i->ctr, 1, r_i->level, ps, depth))
300                 return False;
301         if(!prs_werror("status", ps, depth, &r_i->status))
302                 return False;
303         return True;
304 }
305                            
306 /************************************************************
307  Make a DFS_Q_DFS_ENUM structure
308  ************************************************************/
309 BOOL init_dfs_q_dfs_enum(DFS_Q_DFS_ENUM *q_d, uint32 level, DFS_INFO_CTR *ctr)
310 {
311         q_d->level = level;
312         q_d->maxpreflen = -1;
313         q_d->ptr_buffer = 1;
314         q_d->level2 = level;
315   
316         q_d->ptr_num_entries = 1;
317         q_d->num_entries = 0;
318         q_d->num_entries2 = 0;
319         q_d->reshnd.ptr_hnd = 1;
320         q_d->reshnd.handle = 0;
321         return True;
322 }
323   
324 /************************************************************
325  Read or write the DFS_Q_DFS_ENUM structure 
326  ************************************************************/
327
328 BOOL dfs_io_q_dfs_enum(char *desc, DFS_Q_DFS_ENUM *q_d, prs_struct *ps, int depth)
329 {
330         if(q_d == NULL)
331                 return False;
332
333         prs_debug(ps, depth, desc, "dfs_io_q_dfs_enum");
334         depth++;
335   
336         if(!prs_align(ps))
337                 return False;
338   
339         if(!prs_uint32("level", ps, depth, &q_d->level))
340                 return False;
341         if(!prs_uint32("maxpreflen", ps, depth, &q_d->maxpreflen))
342                 return False;
343         if(!prs_uint32("ptr_buffer", ps, depth, &q_d->ptr_buffer))
344                 return False;
345         if(!prs_uint32("level2", ps, depth, &q_d->level2))
346                 return False;
347         if(!prs_uint32("level3", ps, depth, &q_d->level2))
348                 return False;
349   
350         if(!prs_uint32("ptr_num_entries", ps, depth, &q_d->ptr_num_entries))
351                 return False;
352         if(!prs_uint32("num_entries", ps, depth, &q_d->num_entries))
353                 return False;
354         if(!prs_uint32("num_entries2", ps, depth, &q_d->num_entries2))
355                 return False;
356         if(!smb_io_enum_hnd("resume_hnd",&q_d->reshnd, ps, depth))
357                 return False;
358         return True;
359 }
360
361 /************************************************************
362  Read/write a DFS_INFO_CTR structure
363  ************************************************************/
364
365 BOOL dfs_io_dfs_info_ctr(char* desc, DFS_INFO_CTR* ctr, uint32 num_entries, uint32 level, prs_struct* ps, int depth)
366 {
367         int i=0;
368
369         switch(level) {
370         case 1:
371                 depth++;
372                 /* should depend on whether marshalling or unmarshalling! */
373                 if(UNMARSHALLING(ps)) {
374                         ctr->dfs.info1 = (DFS_INFO_1 *)prs_alloc_mem(ps, sizeof(DFS_INFO_1)*num_entries);
375                         if (!ctr->dfs.info1)
376                                 return False;
377                 }
378
379                 for(i=0;i<num_entries;i++) {
380                         if(!prs_uint32("ptr_entrypath",ps, depth, &ctr->dfs.info1[i].ptr_entrypath))
381                                 return False;
382                 }
383                 for(i=0;i<num_entries;i++) {
384                         if(!smb_io_unistr2("", &ctr->dfs.info1[i].entrypath, ctr->dfs.info1[i].ptr_entrypath, ps, depth))
385                                 return False;
386                         if(!prs_align(ps))
387                                 return False;
388                 }
389                 depth--;
390                 break;
391         case 2:
392                 depth++;
393                 if(UNMARSHALLING(ps)) {
394                         ctr->dfs.info2 = (DFS_INFO_2 *)prs_alloc_mem(ps, num_entries*sizeof(DFS_INFO_2));
395                         if (!ctr->dfs.info2)
396                                 return False;
397                 }
398
399                 for(i=0;i<num_entries;i++) {
400                         if(!prs_uint32("ptr_entrypath", ps, depth, &ctr->dfs.info2[i].ptr_entrypath))
401                                 return False;
402                         if(!prs_uint32("ptr_comment", ps, depth, &ctr->dfs.info2[i].ptr_comment))
403                                 return False;
404                         if(!prs_uint32("state", ps, depth, &ctr->dfs.info2[i].state))
405                                 return False;
406                         if(!prs_uint32("num_storages", ps, depth, &ctr->dfs.info2[i].num_storages))
407                                 return False;
408                 }
409                 for(i=0;i<num_entries;i++) {
410                         if(!smb_io_unistr2("", &ctr->dfs.info2[i].entrypath, ctr->dfs.info2[i].ptr_entrypath, ps, depth))
411                                 return False;
412                         if(!prs_align(ps))
413                                 return False;
414                         if(!smb_io_unistr2("",&ctr->dfs.info2[i].comment, ctr->dfs.info2[i].ptr_comment, ps, depth))
415                                 return False;
416                         if(!prs_align(ps))
417                                 return False;
418                 }
419                 depth--;
420                 break;
421         case 3:
422                 depth++;
423                 if(UNMARSHALLING(ps)) {
424                         ctr->dfs.info3 = (DFS_INFO_3 *)prs_alloc_mem(ps, num_entries*sizeof(DFS_INFO_3));
425                         if (!ctr->dfs.info3)
426                                 return False;
427                 }
428
429                 for(i=0;i<num_entries;i++) {
430                         if(!prs_uint32("ptr_entrypath", ps, depth, &ctr->dfs.info3[i].ptr_entrypath))
431                                 return False;
432                         if(!prs_uint32("ptr_comment", ps, depth, &ctr->dfs.info3[i].ptr_comment))
433                                 return False;
434                         if(!prs_uint32("state", ps, depth, &ctr->dfs.info3[i].state))
435                                 return False;
436                         if(!prs_uint32("num_storages", ps, depth, &ctr->dfs.info3[i].num_storages))
437                                 return False;
438                         if(!prs_uint32("ptr_storages", ps, depth, &ctr->dfs.info3[i].ptr_storages))
439                                 return False;
440                 }
441                 for(i=0;i<num_entries;i++) {
442                         if(!smb_io_unistr2("", &ctr->dfs.info3[i].entrypath, ctr->dfs.info3[i].ptr_entrypath, ps, depth))
443                                 return False;
444                         if(!prs_align(ps))
445                                 return False;
446                         if(!smb_io_unistr2("", &ctr->dfs.info3[i].comment, ctr->dfs.info3[i].ptr_comment, ps, depth))
447                                 return False;
448                         if(!prs_align(ps))
449                                 return False;
450                         if(!prs_uint32("num_storage_infos", ps, depth, &ctr->dfs.info3[i].num_storage_infos))
451                                 return False;
452
453                         if(!dfs_io_dfs_storage_info("storage_info", &ctr->dfs.info3[i], ps, depth))
454                                 return False;
455                 }
456         }
457
458         return True;
459 }
460
461 /************************************************************
462  Read/write a DFS_R_DFS_ENUM structure
463  ************************************************************/
464
465 BOOL dfs_io_r_dfs_enum(char *desc, DFS_R_DFS_ENUM *q_d, prs_struct *ps, int depth)
466 {
467         DFS_INFO_CTR *ctr;
468         if(q_d == NULL)
469                 return False;
470         ctr = q_d->ctr;
471         if(ctr == NULL)
472                 return False;
473
474         prs_debug(ps, depth, desc, "dfs_io_r_dfs_enum");
475         depth++;
476
477         if(!prs_align(ps))
478                 return False;
479
480         if(!prs_uint32("ptr_buffer", ps, depth, &q_d->ptr_buffer))
481                 return False;
482         if(!prs_uint32("level", ps, depth, &q_d->level))
483                 return False;
484         if(!prs_uint32("level2", ps, depth, &ctr->switch_value))
485                 return False;
486         if(!prs_uint32("ptr_num_entries", ps, depth, &q_d->ptr_num_entries))
487                 return False;
488         if(q_d->ptr_num_entries)
489                 if(!prs_uint32("num_entries", ps, depth, &q_d->num_entries))
490                         return False;
491         if(!prs_uint32("ptr_num_entries2", ps, depth, &q_d->ptr_num_entries2))
492                 return False;
493         if(q_d->ptr_num_entries2)
494                 if(!prs_uint32("num_entries2", ps, depth, &ctr->num_entries))
495                         return False;
496
497         if(!dfs_io_dfs_info_ctr("", ctr, q_d->num_entries, q_d->level, ps, depth))
498                 return False;
499
500         if(!smb_io_enum_hnd("resume_hnd", &q_d->reshnd, ps, depth))
501                 return False;
502         if(!prs_werror("status", ps, depth, &q_d->status))
503                 return False;
504         return True;
505 }
506
507 BOOL dfs_io_dfs_storage_info(char *desc, DFS_INFO_3* info3, prs_struct *ps, int depth)
508 {
509         int i=0;
510         if(info3 == NULL)
511                 return False;
512   
513         prs_debug(ps, depth, desc, "smb_io_dfs_storage_info");
514         depth++;
515
516         if(UNMARSHALLING(ps)) {
517                 info3->storages = (DFS_STORAGE_INFO *)prs_alloc_mem(ps, info3->num_storage_infos*sizeof(DFS_STORAGE_INFO));
518                 if (!info3->storages)
519                         return False;
520         }
521
522         for(i=0;i<info3->num_storage_infos;i++) {
523                 if(!prs_uint32("storage_state", ps, depth, &info3->storages[i].state))
524                         return False;
525                 if(!prs_uint32("ptr_servername", ps, depth, &info3->storages[i].ptr_servername))
526                         return False;
527                 if(!prs_uint32("ptr_sharename", ps, depth, &info3->storages[i].ptr_sharename))
528                         return False;
529         }
530
531         for(i=0;i<info3->num_storage_infos;i++) {
532                 if(!smb_io_unistr2("servername", &info3->storages[i].servername, info3->storages[i].ptr_servername, ps, depth))
533                         return False;
534                 if(!prs_align(ps))
535                         return False;
536                 if(!smb_io_unistr2("sharename", &info3->storages[i].sharename, info3->storages[i].ptr_sharename, ps, depth))
537                         return False;
538                 if(!prs_align(ps))
539                         return False;
540         }
541
542         return True;
543 }