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