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