1/* 2 Unix SMB/CIFS implementation. 3 4 endpoint server for the srvsvc pipe 5 6 Copyright (C) Stefan (metze) Metzmacher 2004-2006 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 3 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, see <http://www.gnu.org/licenses/>. 20*/ 21 22#include "includes.h" 23#include "ntvfs/ntvfs.h" 24#include "rpc_server/dcerpc_server.h" 25#include "librpc/gen_ndr/ndr_srvsvc.h" 26#include "rpc_server/common/common.h" 27#include "auth/auth.h" 28#include "libcli/security/security.h" 29#include "system/time.h" 30#include "rpc_server/srvsvc/proto.h" 31#include "param/param.h" 32 33#define SRVSVC_CHECK_ADMIN_ACCESS do { \ 34 struct security_token *t = dce_call->conn->auth_state.session_info->security_token; \ 35 if (!security_token_has_builtin_administrators(t) && \ 36 !security_token_has_sid_string(t, SID_BUILTIN_SERVER_OPERATORS)) { \ 37 return WERR_ACCESS_DENIED; \ 38 } \ 39} while (0) 40 41/* 42 srvsvc_NetCharDevEnum 43*/ 44static WERROR dcesrv_srvsvc_NetCharDevEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 45 struct srvsvc_NetCharDevEnum *r) 46{ 47 *r->out.totalentries = 0; 48 49 switch (r->in.info_ctr->level) { 50 case 0: 51 r->out.info_ctr->ctr.ctr0 = talloc(mem_ctx, struct srvsvc_NetCharDevCtr0); 52 W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr0); 53 54 r->out.info_ctr->ctr.ctr0->count = 0; 55 r->out.info_ctr->ctr.ctr0->array = NULL; 56 57 return WERR_NOT_SUPPORTED; 58 59 case 1: 60 r->out.info_ctr->ctr.ctr1 = talloc(mem_ctx, struct srvsvc_NetCharDevCtr1); 61 W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr1); 62 63 r->out.info_ctr->ctr.ctr1->count = 0; 64 r->out.info_ctr->ctr.ctr1->array = NULL; 65 66 return WERR_NOT_SUPPORTED; 67 68 default: 69 return WERR_UNKNOWN_LEVEL; 70 } 71 72 return WERR_OK; 73} 74 75 76/* 77 srvsvc_NetCharDevGetInfo 78*/ 79static WERROR dcesrv_srvsvc_NetCharDevGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 80 struct srvsvc_NetCharDevGetInfo *r) 81{ 82 ZERO_STRUCTP(r->out.info); 83 84 switch (r->in.level) { 85 case 0: 86 { 87 return WERR_NOT_SUPPORTED; 88 } 89 case 1: 90 { 91 return WERR_NOT_SUPPORTED; 92 } 93 default: 94 return WERR_UNKNOWN_LEVEL; 95 } 96 97 return WERR_UNKNOWN_LEVEL; 98} 99 100 101/* 102 srvsvc_NetCharDevControl 103*/ 104static WERROR dcesrv_srvsvc_NetCharDevControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 105 struct srvsvc_NetCharDevControl *r) 106{ 107 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 108} 109 110 111/* 112 srvsvc_NetCharDevQEnum 113*/ 114static WERROR dcesrv_srvsvc_NetCharDevQEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 115 struct srvsvc_NetCharDevQEnum *r) 116{ 117 *r->out.totalentries = 0; 118 119 switch (r->in.info_ctr->level) { 120 case 0: 121 { 122 r->out.info_ctr->ctr.ctr0 = talloc(mem_ctx, struct srvsvc_NetCharDevQCtr0); 123 W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr0); 124 125 r->out.info_ctr->ctr.ctr0->count = 0; 126 r->out.info_ctr->ctr.ctr0->array = NULL; 127 128 return WERR_NOT_SUPPORTED; 129 } 130 case 1: 131 { 132 r->out.info_ctr->ctr.ctr1 = talloc(mem_ctx, struct srvsvc_NetCharDevQCtr1); 133 W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr1); 134 135 r->out.info_ctr->ctr.ctr1->count = 0; 136 r->out.info_ctr->ctr.ctr1->array = NULL; 137 138 return WERR_NOT_SUPPORTED; 139 } 140 default: 141 return WERR_UNKNOWN_LEVEL; 142 } 143 144 return WERR_UNKNOWN_LEVEL; 145} 146 147 148/* 149 srvsvc_NetCharDevQGetInfo 150*/ 151static WERROR dcesrv_srvsvc_NetCharDevQGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 152 struct srvsvc_NetCharDevQGetInfo *r) 153{ 154 ZERO_STRUCTP(r->out.info); 155 156 switch (r->in.level) { 157 case 0: 158 { 159 return WERR_NOT_SUPPORTED; 160 } 161 case 1: 162 { 163 return WERR_NOT_SUPPORTED; 164 } 165 default: 166 return WERR_UNKNOWN_LEVEL; 167 } 168 169 return WERR_UNKNOWN_LEVEL; 170} 171 172 173/* 174 srvsvc_NetCharDevQSetInfo 175*/ 176static WERROR dcesrv_srvsvc_NetCharDevQSetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 177 struct srvsvc_NetCharDevQSetInfo *r) 178{ 179 switch (r->in.level) { 180 case 0: 181 { 182 if (r->in.parm_error) { 183 r->out.parm_error = r->in.parm_error; 184 } 185 return WERR_NOT_SUPPORTED; 186 } 187 case 1: 188 { 189 if (r->in.parm_error) { 190 r->out.parm_error = r->in.parm_error; 191 } 192 return WERR_NOT_SUPPORTED; 193 } 194 default: 195 return WERR_UNKNOWN_LEVEL; 196 } 197 198 return WERR_UNKNOWN_LEVEL; 199} 200 201 202/* 203 srvsvc_NetCharDevQPurge 204*/ 205static WERROR dcesrv_srvsvc_NetCharDevQPurge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 206 struct srvsvc_NetCharDevQPurge *r) 207{ 208 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 209} 210 211 212/* 213 srvsvc_NetCharDevQPurgeSelf 214*/ 215static WERROR dcesrv_srvsvc_NetCharDevQPurgeSelf(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 216 struct srvsvc_NetCharDevQPurgeSelf *r) 217{ 218 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 219} 220 221 222/* 223 srvsvc_NetConnEnum 224*/ 225static WERROR dcesrv_srvsvc_NetConnEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 226 struct srvsvc_NetConnEnum *r) 227{ 228 *r->out.totalentries = 0; 229 230 switch (r->in.info_ctr->level) { 231 case 0: 232 { 233 r->out.info_ctr->ctr.ctr0 = talloc(mem_ctx, struct srvsvc_NetConnCtr0); 234 W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr0); 235 236 r->out.info_ctr->ctr.ctr0->count = 0; 237 r->out.info_ctr->ctr.ctr0->array = NULL; 238 239 return WERR_NOT_SUPPORTED; 240 } 241 case 1: 242 { 243 r->out.info_ctr->ctr.ctr1 = talloc(mem_ctx, struct srvsvc_NetConnCtr1); 244 W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr1); 245 246 r->out.info_ctr->ctr.ctr1->count = 0; 247 r->out.info_ctr->ctr.ctr1->array = NULL; 248 249 return WERR_NOT_SUPPORTED; 250 } 251 default: 252 return WERR_UNKNOWN_LEVEL; 253 } 254 255 return WERR_UNKNOWN_LEVEL; 256} 257 258 259/* 260 srvsvc_NetFileEnum 261*/ 262static WERROR dcesrv_srvsvc_NetFileEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 263 struct srvsvc_NetFileEnum *r) 264{ 265 *r->out.totalentries = 0; 266 267 switch (r->in.info_ctr->level) { 268 case 2: 269 { 270 r->out.info_ctr->ctr.ctr2 = talloc(mem_ctx, struct srvsvc_NetFileCtr2); 271 W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr2); 272 273 r->out.info_ctr->ctr.ctr2->count = 0; 274 r->out.info_ctr->ctr.ctr2->array = NULL; 275 276 return WERR_NOT_SUPPORTED; 277 } 278 case 3: 279 { 280 r->out.info_ctr->ctr.ctr3 = talloc(mem_ctx, struct srvsvc_NetFileCtr3); 281 W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr3); 282 283 r->out.info_ctr->ctr.ctr3->count = 0; 284 r->out.info_ctr->ctr.ctr3->array = NULL; 285 286 return WERR_NOT_SUPPORTED; 287 } 288 default: 289 return WERR_UNKNOWN_LEVEL; 290 } 291 292 return WERR_UNKNOWN_LEVEL; 293} 294 295 296/* 297 srvsvc_NetFileGetInfo 298*/ 299static WERROR dcesrv_srvsvc_NetFileGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 300 struct srvsvc_NetFileGetInfo *r) 301{ 302 ZERO_STRUCTP(r->out.info); 303 304 switch (r->in.level) { 305 case 2: 306 { 307 return WERR_NOT_SUPPORTED; 308 } 309 case 3: 310 { 311 return WERR_NOT_SUPPORTED; 312 } 313 default: 314 return WERR_UNKNOWN_LEVEL; 315 } 316 317 return WERR_UNKNOWN_LEVEL; 318} 319 320 321/* 322 srvsvc_NetFileClose 323*/ 324static WERROR dcesrv_srvsvc_NetFileClose(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 325 struct srvsvc_NetFileClose *r) 326{ 327 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 328} 329 330 331/* 332 srvsvc_NetSessEnum 333*/ 334static WERROR dcesrv_srvsvc_NetSessEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 335 struct srvsvc_NetSessEnum *r) 336{ 337 *r->out.totalentries = 0; 338 339 switch (r->in.info_ctr->level) { 340 case 0: 341 { 342 r->out.info_ctr->ctr.ctr0 = talloc(mem_ctx, struct srvsvc_NetSessCtr0); 343 W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr0); 344 345 r->out.info_ctr->ctr.ctr0->count = 0; 346 r->out.info_ctr->ctr.ctr0->array = NULL; 347 348 return WERR_NOT_SUPPORTED; 349 } 350 case 1: 351 { 352 r->out.info_ctr->ctr.ctr1 = talloc(mem_ctx, struct srvsvc_NetSessCtr1); 353 W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr1); 354 355 r->out.info_ctr->ctr.ctr1->count = 0; 356 r->out.info_ctr->ctr.ctr1->array = NULL; 357 358 return WERR_NOT_SUPPORTED; 359 } 360 case 2: 361 { 362 r->out.info_ctr->ctr.ctr2 = talloc(mem_ctx, struct srvsvc_NetSessCtr2); 363 W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr2); 364 365 r->out.info_ctr->ctr.ctr2->count = 0; 366 r->out.info_ctr->ctr.ctr2->array = NULL; 367 368 return WERR_NOT_SUPPORTED; 369 } 370 case 10: 371 { 372 r->out.info_ctr->ctr.ctr10 = talloc(mem_ctx, struct srvsvc_NetSessCtr10); 373 W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr10); 374 375 r->out.info_ctr->ctr.ctr10->count = 0; 376 r->out.info_ctr->ctr.ctr10->array = NULL; 377 378 return WERR_NOT_SUPPORTED; 379 } 380 case 502: 381 { 382 r->out.info_ctr->ctr.ctr502 = talloc(mem_ctx, struct srvsvc_NetSessCtr502); 383 W_ERROR_HAVE_NO_MEMORY(r->out.info_ctr->ctr.ctr502); 384 385 r->out.info_ctr->ctr.ctr502->count = 0; 386 r->out.info_ctr->ctr.ctr502->array = NULL; 387 388 return WERR_NOT_SUPPORTED; 389 } 390 default: 391 return WERR_UNKNOWN_LEVEL; 392 } 393 394 return WERR_UNKNOWN_LEVEL; 395} 396 397 398/* 399 srvsvc_NetSessDel 400*/ 401static WERROR dcesrv_srvsvc_NetSessDel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 402 struct srvsvc_NetSessDel *r) 403{ 404 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 405} 406 407 408/* 409 srvsvc_NetShareAdd 410*/ 411static WERROR dcesrv_srvsvc_NetShareAdd(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 412 struct srvsvc_NetShareAdd *r) 413{ 414 switch (r->in.level) { 415 case 0: 416 { 417 if (r->in.parm_error) { 418 r->out.parm_error = r->in.parm_error; 419 } 420 return WERR_NOT_SUPPORTED; 421 } 422 case 1: 423 { 424 if (r->in.parm_error) { 425 r->out.parm_error = r->in.parm_error; 426 } 427 return WERR_NOT_SUPPORTED; 428 } 429 case 2: 430 { 431 NTSTATUS nterr; 432 struct share_info *info; 433 struct share_context *sctx; 434 int count = 8; 435 int i; 436 437 nterr = share_get_context_by_name(mem_ctx, lp_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx); 438 if (!NT_STATUS_IS_OK(nterr)) { 439 return ntstatus_to_werror(nterr); 440 } 441 442 /* there are no more than 8 options in struct srvsvc_NetShareInfo2 */ 443 info = talloc_array(mem_ctx, struct share_info, count); 444 W_ERROR_HAVE_NO_MEMORY(info); 445 446 i = 0; 447 448 info[i].name = SHARE_TYPE; 449 info[i].type = SHARE_INFO_STRING; 450 switch (r->in.info->info2->type) { 451 case 0x00: 452 info[i].value = talloc_strdup(info, "DISK"); 453 break; 454 case 0x01: 455 info[i].value = talloc_strdup(info, "PRINTER"); 456 break; 457 case 0x03: 458 info[i].value = talloc_strdup(info, "IPC"); 459 break; 460 default: 461 return WERR_INVALID_PARAM; 462 } 463 W_ERROR_HAVE_NO_MEMORY(info[i].value); 464 i++; 465 466 if (r->in.info->info2->path && r->in.info->info2->path[0]) { 467 info[i].name = SHARE_PATH; 468 info[i].type = SHARE_INFO_STRING; 469 470 /* Windows will send a path in a form of C:\example\path */ 471 if (r->in.info->info2->path[1] == ':') { 472 info[i].value = talloc_strdup(info, &r->in.info->info2->path[2]); 473 } else { 474 /* very strange let's try to set as is */ 475 info[i].value = talloc_strdup(info, r->in.info->info2->path); 476 } 477 W_ERROR_HAVE_NO_MEMORY(info[i].value); 478 all_string_sub((char *)info[i].value, "\\", "/", 0); 479 480 i++; 481 } 482 483 if (r->in.info->info2->comment && r->in.info->info2->comment[0]) { 484 info[i].name = SHARE_COMMENT; 485 info[i].type = SHARE_INFO_STRING; 486 info[i].value = talloc_strdup(info, r->in.info->info2->comment); 487 W_ERROR_HAVE_NO_MEMORY(info[i].value); 488 489 i++; 490 } 491 492 if (r->in.info->info2->password && r->in.info->info2->password[0]) { 493 info[i].name = SHARE_PASSWORD; 494 info[i].type = SHARE_INFO_STRING; 495 info[i].value = talloc_strdup(info, r->in.info->info2->password); 496 W_ERROR_HAVE_NO_MEMORY(info[i].value); 497 498 i++; 499 } 500 501 info[i].name = SHARE_MAX_CONNECTIONS; 502 info[i].type = SHARE_INFO_INT; 503 info[i].value = talloc(info, int); 504 *((int *)info[i].value) = r->in.info->info2->max_users; 505 i++; 506 507 /* TODO: security descriptor */ 508 509 nterr = share_create(sctx, r->in.info->info2->name, info, i); 510 if (!NT_STATUS_IS_OK(nterr)) { 511 return ntstatus_to_werror(nterr); 512 } 513 514 if (r->in.parm_error) { 515 r->out.parm_error = r->in.parm_error; 516 } 517 518 return WERR_OK; 519 } 520 case 501: 521 { 522 if (r->in.parm_error) { 523 r->out.parm_error = r->in.parm_error; 524 } 525 return WERR_NOT_SUPPORTED; 526 } 527 case 502: 528 { 529 NTSTATUS nterr; 530 struct share_info *info; 531 struct share_context *sctx; 532 int count = 10; 533 int i; 534 535 nterr = share_get_context_by_name(mem_ctx, lp_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx); 536 if (!NT_STATUS_IS_OK(nterr)) { 537 return ntstatus_to_werror(nterr); 538 } 539 540 /* there are no more than 10 options in struct srvsvc_NetShareInfo502 */ 541 info = talloc_array(mem_ctx, struct share_info, count); 542 W_ERROR_HAVE_NO_MEMORY(info); 543 544 i = 0; 545 546 info[i].name = SHARE_TYPE; 547 info[i].type = SHARE_INFO_STRING; 548 switch (r->in.info->info502->type) { 549 case 0x00: 550 info[i].value = talloc_strdup(info, "DISK"); 551 break; 552 case 0x01: 553 info[i].value = talloc_strdup(info, "PRINTER"); 554 break; 555 case 0x03: 556 info[i].value = talloc_strdup(info, "IPC"); 557 break; 558 default: 559 return WERR_INVALID_PARAM; 560 } 561 W_ERROR_HAVE_NO_MEMORY(info[i].value); 562 i++; 563 564 if (r->in.info->info502->path && r->in.info->info502->path[0]) { 565 info[i].name = SHARE_PATH; 566 info[i].type = SHARE_INFO_STRING; 567 568 /* Windows will send a path in a form of C:\example\path */ 569 if (r->in.info->info502->path[1] == ':') { 570 info[i].value = talloc_strdup(info, &r->in.info->info502->path[2]); 571 } else { 572 /* very strange let's try to set as is */ 573 info[i].value = talloc_strdup(info, r->in.info->info502->path); 574 } 575 W_ERROR_HAVE_NO_MEMORY(info[i].value); 576 all_string_sub((char *)info[i].value, "\\", "/", 0); 577 578 i++; 579 } 580 581 if (r->in.info->info502->comment && r->in.info->info502->comment[0]) { 582 info[i].name = SHARE_COMMENT; 583 info[i].type = SHARE_INFO_STRING; 584 info[i].value = talloc_strdup(info, r->in.info->info502->comment); 585 W_ERROR_HAVE_NO_MEMORY(info[i].value); 586 587 i++; 588 } 589 590 if (r->in.info->info502->password && r->in.info->info502->password[0]) { 591 info[i].name = SHARE_PASSWORD; 592 info[i].type = SHARE_INFO_STRING; 593 info[i].value = talloc_strdup(info, r->in.info->info502->password); 594 W_ERROR_HAVE_NO_MEMORY(info[i].value); 595 596 i++; 597 } 598 599 info[i].name = SHARE_MAX_CONNECTIONS; 600 info[i].type = SHARE_INFO_INT; 601 info[i].value = talloc(info, int); 602 *((int *)info[i].value) = r->in.info->info502->max_users; 603 i++; 604 605 /* TODO: security descriptor */ 606 607 nterr = share_create(sctx, r->in.info->info502->name, info, i); 608 if (!NT_STATUS_IS_OK(nterr)) { 609 return ntstatus_to_werror(nterr); 610 } 611 612 if (r->in.parm_error) { 613 r->out.parm_error = r->in.parm_error; 614 } 615 616 return WERR_OK; 617 } 618 default: 619 return WERR_UNKNOWN_LEVEL; 620 } 621 622 return WERR_UNKNOWN_LEVEL; 623} 624 625static WERROR dcesrv_srvsvc_fiel_ShareInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 626 struct share_config *scfg, uint32_t level, 627 union srvsvc_NetShareInfo *info) 628{ 629 struct dcesrv_context *dce_ctx = dce_call->conn->dce_ctx; 630 631 switch (level) { 632 case 0: 633 { 634 info->info0->name = talloc_strdup(mem_ctx, scfg->name); 635 W_ERROR_HAVE_NO_MEMORY(info->info0->name); 636 637 return WERR_OK; 638 } 639 case 1: 640 { 641 info->info1->name = talloc_strdup(mem_ctx, scfg->name); 642 W_ERROR_HAVE_NO_MEMORY(info->info1->name); 643 info->info1->type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg); 644 info->info1->comment = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_COMMENT, "")); 645 W_ERROR_HAVE_NO_MEMORY(info->info1->comment); 646 647 return WERR_OK; 648 } 649 case 2: 650 { 651 info->info2->name = talloc_strdup(mem_ctx, scfg->name); 652 W_ERROR_HAVE_NO_MEMORY(info->info2->name); 653 info->info2->type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg); 654 info->info2->comment = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_COMMENT, "")); 655 W_ERROR_HAVE_NO_MEMORY(info->info2->comment); 656 info->info2->permissions = dcesrv_common_get_share_permissions(mem_ctx, dce_ctx, scfg); 657 info->info2->max_users = share_int_option(scfg, SHARE_MAX_CONNECTIONS, SHARE_MAX_CONNECTIONS_DEFAULT); 658 info->info2->current_users = dcesrv_common_get_share_current_users(mem_ctx, dce_ctx, scfg); 659 info->info2->path = dcesrv_common_get_share_path(mem_ctx, dce_ctx, scfg); 660 W_ERROR_HAVE_NO_MEMORY(info->info2->path); 661 info->info2->password = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_PASSWORD, NULL)); 662 663 return WERR_OK; 664 } 665 case 501: 666 { 667 info->info501->name = talloc_strdup(mem_ctx, scfg->name); 668 W_ERROR_HAVE_NO_MEMORY(info->info501->name); 669 info->info501->type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg); 670 info->info501->comment = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_COMMENT, "")); 671 W_ERROR_HAVE_NO_MEMORY(info->info501->comment); 672 info->info501->csc_policy = share_int_option(scfg, SHARE_CSC_POLICY, SHARE_CSC_POLICY_DEFAULT); 673 674 return WERR_OK; 675 } 676 case 502: 677 { 678 info->info502->name = talloc_strdup(mem_ctx, scfg->name); 679 W_ERROR_HAVE_NO_MEMORY(info->info502->name); 680 info->info502->type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg); 681 info->info502->comment = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_COMMENT, "")); 682 W_ERROR_HAVE_NO_MEMORY(info->info502->comment); 683 info->info502->permissions = dcesrv_common_get_share_permissions(mem_ctx, dce_ctx, scfg); 684 info->info502->max_users = share_int_option(scfg, SHARE_MAX_CONNECTIONS, SHARE_MAX_CONNECTIONS_DEFAULT); 685 info->info502->current_users = dcesrv_common_get_share_current_users(mem_ctx, dce_ctx, scfg); 686 info->info502->path = dcesrv_common_get_share_path(mem_ctx, dce_ctx, scfg); 687 W_ERROR_HAVE_NO_MEMORY(info->info502->path); 688 info->info502->password = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_PASSWORD, NULL)); 689 info->info502->sd_buf.sd = dcesrv_common_get_security_descriptor(mem_ctx, dce_ctx, scfg); 690 691 return WERR_OK; 692 } 693 case 1005: 694 { 695 info->info1005->dfs_flags = dcesrv_common_get_share_dfs_flags(mem_ctx, dce_ctx, scfg); 696 697 return WERR_OK; 698 } 699 default: 700 return WERR_UNKNOWN_LEVEL; 701 } 702 703 return WERR_UNKNOWN_LEVEL; 704} 705 706/* 707 srvsvc_NetShareEnumAll 708*/ 709static WERROR dcesrv_srvsvc_NetShareEnumAll(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 710 struct srvsvc_NetShareEnumAll *r) 711{ 712 NTSTATUS nterr; 713 int numshares = 0; 714 const char **snames; 715 struct share_context *sctx; 716 struct share_config *scfg; 717 718 *r->out.totalentries = 0; 719 720 /* TODO: - paging of results 721 */ 722 723 nterr = share_get_context_by_name(mem_ctx, lp_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx); 724 if (!NT_STATUS_IS_OK(nterr)) { 725 return ntstatus_to_werror(nterr); 726 } 727 728 nterr = share_list_all(mem_ctx, sctx, &numshares, &snames); 729 if (!NT_STATUS_IS_OK(nterr)) { 730 return ntstatus_to_werror(nterr); 731 } 732 733 switch (r->in.info_ctr->level) { 734 case 0: 735 { 736 int i; 737 struct srvsvc_NetShareCtr0 *ctr0; 738 739 ctr0 = talloc(mem_ctx, struct srvsvc_NetShareCtr0); 740 W_ERROR_HAVE_NO_MEMORY(ctr0); 741 742 ctr0->count = numshares; 743 ctr0->array = NULL; 744 745 if (ctr0->count == 0) { 746 r->out.info_ctr->ctr.ctr0 = ctr0; 747 return WERR_OK; 748 } 749 750 ctr0->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo0, ctr0->count); 751 W_ERROR_HAVE_NO_MEMORY(ctr0->array); 752 753 for (i = 0; i < ctr0->count; i++) { 754 WERROR status; 755 union srvsvc_NetShareInfo info; 756 757 nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg); 758 if (!NT_STATUS_IS_OK(nterr)) { 759 DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i])); 760 return WERR_GENERAL_FAILURE; 761 } 762 info.info0 = &ctr0->array[i]; 763 status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.info_ctr->level, &info); 764 if (!W_ERROR_IS_OK(status)) { 765 return status; 766 } 767 talloc_free(scfg); 768 } 769 talloc_free(snames); 770 771 r->out.info_ctr->ctr.ctr0 = ctr0; 772 *r->out.totalentries = r->out.info_ctr->ctr.ctr0->count; 773 return WERR_OK; 774 } 775 case 1: 776 { 777 int i; 778 struct srvsvc_NetShareCtr1 *ctr1; 779 780 ctr1 = talloc(mem_ctx, struct srvsvc_NetShareCtr1); 781 W_ERROR_HAVE_NO_MEMORY(ctr1); 782 783 ctr1->count = numshares; 784 ctr1->array = NULL; 785 786 if (ctr1->count == 0) { 787 r->out.info_ctr->ctr.ctr1 = ctr1; 788 return WERR_OK; 789 } 790 791 ctr1->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo1, ctr1->count); 792 W_ERROR_HAVE_NO_MEMORY(ctr1->array); 793 794 for (i=0; i < ctr1->count; i++) { 795 WERROR status; 796 union srvsvc_NetShareInfo info; 797 798 nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg); 799 if (!NT_STATUS_IS_OK(nterr)) { 800 DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i])); 801 return WERR_GENERAL_FAILURE; 802 } 803 info.info1 = &ctr1->array[i]; 804 status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.info_ctr->level, &info); 805 if (!W_ERROR_IS_OK(status)) { 806 return status; 807 } 808 talloc_free(scfg); 809 } 810 talloc_free(snames); 811 812 r->out.info_ctr->ctr.ctr1 = ctr1; 813 *r->out.totalentries = r->out.info_ctr->ctr.ctr1->count; 814 815 return WERR_OK; 816 } 817 case 2: 818 { 819 int i; 820 struct srvsvc_NetShareCtr2 *ctr2; 821 822 SRVSVC_CHECK_ADMIN_ACCESS; 823 824 ctr2 = talloc(mem_ctx, struct srvsvc_NetShareCtr2); 825 W_ERROR_HAVE_NO_MEMORY(ctr2); 826 827 ctr2->count = numshares; 828 ctr2->array = NULL; 829 830 if (ctr2->count == 0) { 831 r->out.info_ctr->ctr.ctr2 = ctr2; 832 return WERR_OK; 833 } 834 835 ctr2->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo2, ctr2->count); 836 W_ERROR_HAVE_NO_MEMORY(ctr2->array); 837 838 for (i=0; i < ctr2->count; i++) { 839 WERROR status; 840 union srvsvc_NetShareInfo info; 841 842 nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg); 843 if (!NT_STATUS_IS_OK(nterr)) { 844 DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i])); 845 return WERR_GENERAL_FAILURE; 846 } 847 info.info2 = &ctr2->array[i]; 848 status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.info_ctr->level, &info); 849 if (!W_ERROR_IS_OK(status)) { 850 return status; 851 } 852 talloc_free(scfg); 853 } 854 talloc_free(snames); 855 856 r->out.info_ctr->ctr.ctr2 = ctr2; 857 *r->out.totalentries = r->out.info_ctr->ctr.ctr2->count; 858 859 return WERR_OK; 860 } 861 case 501: 862 { 863 int i; 864 struct srvsvc_NetShareCtr501 *ctr501; 865 866 SRVSVC_CHECK_ADMIN_ACCESS; 867 868 ctr501 = talloc(mem_ctx, struct srvsvc_NetShareCtr501); 869 W_ERROR_HAVE_NO_MEMORY(ctr501); 870 871 ctr501->count = numshares; 872 ctr501->array = NULL; 873 874 if (ctr501->count == 0) { 875 r->out.info_ctr->ctr.ctr501 = ctr501; 876 return WERR_OK; 877 } 878 879 ctr501->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo501, ctr501->count); 880 W_ERROR_HAVE_NO_MEMORY(ctr501->array); 881 882 for (i=0; i < ctr501->count; i++) { 883 WERROR status; 884 union srvsvc_NetShareInfo info; 885 886 nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg); 887 if (!NT_STATUS_IS_OK(nterr)) { 888 DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i])); 889 return WERR_GENERAL_FAILURE; 890 } 891 info.info501 = &ctr501->array[i]; 892 status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.info_ctr->level, &info); 893 if (!W_ERROR_IS_OK(status)) { 894 return status; 895 } 896 talloc_free(scfg); 897 } 898 talloc_free(snames); 899 900 r->out.info_ctr->ctr.ctr501 = ctr501; 901 *r->out.totalentries = r->out.info_ctr->ctr.ctr501->count; 902 903 return WERR_OK; 904 } 905 case 502: 906 { 907 int i; 908 struct srvsvc_NetShareCtr502 *ctr502; 909 910 SRVSVC_CHECK_ADMIN_ACCESS; 911 912 ctr502 = talloc(mem_ctx, struct srvsvc_NetShareCtr502); 913 W_ERROR_HAVE_NO_MEMORY(ctr502); 914 915 ctr502->count = numshares; 916 ctr502->array = NULL; 917 918 if (ctr502->count == 0) { 919 r->out.info_ctr->ctr.ctr502 = ctr502; 920 return WERR_OK; 921 } 922 923 ctr502->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo502, ctr502->count); 924 W_ERROR_HAVE_NO_MEMORY(ctr502->array); 925 926 for (i=0; i < ctr502->count; i++) { 927 WERROR status; 928 union srvsvc_NetShareInfo info; 929 930 nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg); 931 if (!NT_STATUS_IS_OK(nterr)) { 932 DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i])); 933 return WERR_GENERAL_FAILURE; 934 } 935 info.info502 = &ctr502->array[i]; 936 status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.info_ctr->level, &info); 937 if (!W_ERROR_IS_OK(status)) { 938 return status; 939 } 940 talloc_free(scfg); 941 } 942 talloc_free(snames); 943 944 r->out.info_ctr->ctr.ctr502 = ctr502; 945 *r->out.totalentries = r->out.info_ctr->ctr.ctr502->count; 946 947 return WERR_OK; 948 } 949 default: 950 return WERR_UNKNOWN_LEVEL; 951 } 952 953 return WERR_UNKNOWN_LEVEL; 954} 955 956 957/* 958 srvsvc_NetShareGetInfo 959*/ 960static WERROR dcesrv_srvsvc_NetShareGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 961 struct srvsvc_NetShareGetInfo *r) 962{ 963 NTSTATUS nterr; 964 struct share_context *sctx = NULL; 965 struct share_config *scfg = NULL; 966 967 ZERO_STRUCTP(r->out.info); 968 969 /* TODO: - access check 970 */ 971 972 if (strcmp("", r->in.share_name) == 0) { 973 return WERR_INVALID_PARAM; 974 } 975 976 nterr = share_get_context_by_name(mem_ctx, lp_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx); 977 if (!NT_STATUS_IS_OK(nterr)) { 978 return ntstatus_to_werror(nterr); 979 } 980 981 nterr = share_get_config(mem_ctx, sctx, r->in.share_name, &scfg); 982 if (!NT_STATUS_IS_OK(nterr)) { 983 return ntstatus_to_werror(nterr); 984 } 985 986 switch (r->in.level) { 987 case 0: 988 { 989 WERROR status; 990 union srvsvc_NetShareInfo info; 991 992 info.info0 = talloc(mem_ctx, struct srvsvc_NetShareInfo0); 993 W_ERROR_HAVE_NO_MEMORY(info.info0); 994 995 status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); 996 if (!W_ERROR_IS_OK(status)) { 997 return status; 998 } 999 1000 r->out.info->info0 = info.info0; 1001 return WERR_OK; 1002 } 1003 case 1: 1004 { 1005 WERROR status; 1006 union srvsvc_NetShareInfo info; 1007 1008 info.info1 = talloc(mem_ctx, struct srvsvc_NetShareInfo1); 1009 W_ERROR_HAVE_NO_MEMORY(info.info1); 1010 1011 status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); 1012 if (!W_ERROR_IS_OK(status)) { 1013 return status; 1014 } 1015 1016 r->out.info->info1 = info.info1; 1017 return WERR_OK; 1018 } 1019 case 2: 1020 { 1021 WERROR status; 1022 union srvsvc_NetShareInfo info; 1023 1024 SRVSVC_CHECK_ADMIN_ACCESS; 1025 1026 info.info2 = talloc(mem_ctx, struct srvsvc_NetShareInfo2); 1027 W_ERROR_HAVE_NO_MEMORY(info.info2); 1028 1029 status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); 1030 if (!W_ERROR_IS_OK(status)) { 1031 return status; 1032 } 1033 1034 r->out.info->info2 = info.info2; 1035 return WERR_OK; 1036 } 1037 case 501: 1038 { 1039 WERROR status; 1040 union srvsvc_NetShareInfo info; 1041 1042 info.info501 = talloc(mem_ctx, struct srvsvc_NetShareInfo501); 1043 W_ERROR_HAVE_NO_MEMORY(info.info501); 1044 1045 status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); 1046 if (!W_ERROR_IS_OK(status)) { 1047 return status; 1048 } 1049 1050 r->out.info->info501 = info.info501; 1051 return WERR_OK; 1052 } 1053 case 502: 1054 { 1055 WERROR status; 1056 union srvsvc_NetShareInfo info; 1057 1058 SRVSVC_CHECK_ADMIN_ACCESS; 1059 1060 info.info502 = talloc(mem_ctx, struct srvsvc_NetShareInfo502); 1061 W_ERROR_HAVE_NO_MEMORY(info.info502); 1062 1063 status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); 1064 if (!W_ERROR_IS_OK(status)) { 1065 return status; 1066 } 1067 1068 r->out.info->info502 = info.info502; 1069 return WERR_OK; 1070 } 1071 case 1005: 1072 { 1073 WERROR status; 1074 union srvsvc_NetShareInfo info; 1075 1076 info.info1005 = talloc(mem_ctx, struct srvsvc_NetShareInfo1005); 1077 W_ERROR_HAVE_NO_MEMORY(info.info1005); 1078 1079 status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.level, &info); 1080 if (!W_ERROR_IS_OK(status)) { 1081 return status; 1082 } 1083 1084 r->out.info->info1005 = info.info1005; 1085 return WERR_OK; 1086 } 1087 default: 1088 return WERR_UNKNOWN_LEVEL; 1089 } 1090 1091 return WERR_UNKNOWN_LEVEL; 1092} 1093 1094static WERROR dcesrv_srvsvc_fill_share_info(struct share_info *info, int *count, 1095 const char *share_name, int level, 1096 const char *name, 1097 const char *path, 1098 const char *comment, 1099 const char *password, 1100 enum srvsvc_ShareType type, 1101 int32_t max_users, 1102 uint32_t csc_policy, 1103 struct security_descriptor *sd) 1104{ 1105 int i = 0; 1106 1107 if (level == 501) { 1108 info[i].name = SHARE_CSC_POLICY; 1109 info[i].type = SHARE_INFO_INT; 1110 info[i].value = talloc(info, int); 1111 *((int *)info[i].value) = csc_policy; 1112 i++; 1113 } 1114 1115 switch(level) { 1116 1117 case 502: 1118 /* TODO: check if unknown is csc_policy */ 1119 1120 /* TODO: security descriptor */ 1121 1122 case 2: 1123 if (path && path[0]) { 1124 info[i].name = SHARE_PATH; 1125 info[i].type = SHARE_INFO_STRING; 1126 1127 /* Windows will send a path in a form of C:\example\path */ 1128 if (path[1] == ':') { 1129 info[i].value = talloc_strdup(info, &path[2]); 1130 } else { 1131 /* very strange let's try to set as is */ 1132 info[i].value = talloc_strdup(info, path); 1133 } 1134 W_ERROR_HAVE_NO_MEMORY(info[i].value); 1135 all_string_sub((char *)info[i].value, "\\", "/", 0); 1136 1137 i++; 1138 } 1139 1140 if (password && password[0]) { 1141 info[i].name = SHARE_PASSWORD; 1142 info[i].type = SHARE_INFO_STRING; 1143 info[i].value = talloc_strdup(info, password); 1144 W_ERROR_HAVE_NO_MEMORY(info[i].value); 1145 1146 i++; 1147 } 1148 1149 info[i].name = SHARE_MAX_CONNECTIONS; 1150 info[i].type = SHARE_INFO_INT; 1151 info[i].value = talloc(info, int); 1152 *((int *)info[i].value) = max_users; 1153 i++; 1154 1155 case 501: 1156 case 1: 1157 info[i].name = SHARE_TYPE; 1158 info[i].type = SHARE_INFO_STRING; 1159 switch (type) { 1160 case 0x00: 1161 info[i].value = talloc_strdup(info, "DISK"); 1162 break; 1163 case 0x01: 1164 info[i].value = talloc_strdup(info, "PRINTER"); 1165 break; 1166 case 0x03: 1167 info[i].value = talloc_strdup(info, "IPC"); 1168 break; 1169 default: 1170 return WERR_INVALID_PARAM; 1171 } 1172 W_ERROR_HAVE_NO_MEMORY(info[i].value); 1173 i++; 1174 1175 case 1004: 1176 if (comment) { 1177 info[i].name = SHARE_COMMENT; 1178 info[i].type = SHARE_INFO_STRING; 1179 info[i].value = talloc_strdup(info, comment); 1180 W_ERROR_HAVE_NO_MEMORY(info[i].value); 1181 1182 i++; 1183 } 1184 case 0: 1185 if (name && 1186 strcasecmp(share_name, name) != 0) { 1187 info[i].name = SHARE_NAME; 1188 info[i].type = SHARE_INFO_STRING; 1189 info[i].value = talloc_strdup(info, name); 1190 W_ERROR_HAVE_NO_MEMORY(info[i].value); 1191 i++; 1192 } 1193 1194 break; 1195 1196 default: 1197 return WERR_UNKNOWN_LEVEL; 1198 } 1199 1200 *count = i; 1201 1202 return WERR_OK; 1203} 1204 1205/* 1206 srvsvc_NetShareSetInfo 1207*/ 1208static WERROR dcesrv_srvsvc_NetShareSetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1209 struct srvsvc_NetShareSetInfo *r) 1210{ 1211 NTSTATUS nterr; 1212 WERROR status; 1213 struct share_context *sctx = NULL; 1214 struct share_info *info; 1215 int count; 1216 1217 /* TODO: - access check 1218 */ 1219 1220 /* there are no more than 10 options in all struct srvsvc_NetShareInfoXXX */ 1221 info = talloc_array(mem_ctx, struct share_info, 10); 1222 W_ERROR_HAVE_NO_MEMORY(info); 1223 1224 ZERO_STRUCT(r->out); 1225 1226 if (strcmp("", r->in.share_name) == 0) { 1227 return WERR_INVALID_PARAM; 1228 } 1229 1230 nterr = share_get_context_by_name(mem_ctx, lp_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx); 1231 if (!NT_STATUS_IS_OK(nterr)) { 1232 return ntstatus_to_werror(nterr); 1233 } 1234 1235 switch (r->in.level) { 1236 case 0: 1237 { 1238 status = dcesrv_srvsvc_fill_share_info(info, &count, 1239 r->in.share_name, r->in.level, 1240 r->in.info->info0->name, 1241 NULL, 1242 NULL, 1243 NULL, 1244 0, 1245 0, 1246 0, 1247 NULL); 1248 if (!W_ERROR_EQUAL(status, WERR_OK)) { 1249 return status; 1250 } 1251 break; 1252 } 1253 case 1: 1254 { 1255 status = dcesrv_srvsvc_fill_share_info(info, &count, 1256 r->in.share_name, r->in.level, 1257 r->in.info->info1->name, 1258 NULL, 1259 r->in.info->info1->comment, 1260 NULL, 1261 r->in.info->info1->type, 1262 0, 1263 0, 1264 NULL); 1265 if (!W_ERROR_EQUAL(status, WERR_OK)) { 1266 return status; 1267 } 1268 break; 1269 } 1270 case 2: 1271 { 1272 status = dcesrv_srvsvc_fill_share_info(info, &count, 1273 r->in.share_name, r->in.level, 1274 r->in.info->info2->name, 1275 r->in.info->info2->path, 1276 r->in.info->info2->comment, 1277 r->in.info->info2->password, 1278 r->in.info->info2->type, 1279 r->in.info->info2->max_users, 1280 0, 1281 NULL); 1282 if (!W_ERROR_EQUAL(status, WERR_OK)) { 1283 return status; 1284 } 1285 break; 1286 } 1287 case 501: 1288 { 1289 status = dcesrv_srvsvc_fill_share_info(info, &count, 1290 r->in.share_name, r->in.level, 1291 r->in.info->info501->name, 1292 NULL, 1293 r->in.info->info501->comment, 1294 NULL, 1295 r->in.info->info501->type, 1296 0, 1297 r->in.info->info501->csc_policy, 1298 NULL); 1299 if (!W_ERROR_EQUAL(status, WERR_OK)) { 1300 return status; 1301 } 1302 break; 1303 } 1304 case 502: 1305 { 1306 status = dcesrv_srvsvc_fill_share_info(info, &count, 1307 r->in.share_name, r->in.level, 1308 r->in.info->info502->name, 1309 r->in.info->info502->path, 1310 r->in.info->info502->comment, 1311 r->in.info->info502->password, 1312 r->in.info->info502->type, 1313 r->in.info->info502->max_users, 1314 0, 1315 r->in.info->info502->sd_buf.sd); 1316 if (!W_ERROR_EQUAL(status, WERR_OK)) { 1317 return status; 1318 } 1319 break; 1320 } 1321 case 1004: 1322 { 1323 status = dcesrv_srvsvc_fill_share_info(info, &count, 1324 r->in.share_name, r->in.level, 1325 NULL, 1326 NULL, 1327 r->in.info->info1004->comment, 1328 NULL, 1329 0, 1330 0, 1331 0, 1332 NULL); 1333 if (!W_ERROR_EQUAL(status, WERR_OK)) { 1334 return status; 1335 } 1336 break; 1337 } 1338 case 1005: 1339 { 1340 /* r->in.info.dfs_flags; */ 1341 1342 if (r->in.parm_error) { 1343 r->out.parm_error = r->in.parm_error; 1344 } 1345 1346 return WERR_OK; 1347 } 1348 default: 1349 return WERR_UNKNOWN_LEVEL; 1350 } 1351 1352 nterr = share_set(sctx, r->in.share_name, info, count); 1353 if (!NT_STATUS_IS_OK(nterr)) { 1354 return ntstatus_to_werror(nterr); 1355 } 1356 1357 if (r->in.parm_error) { 1358 r->out.parm_error = r->in.parm_error; 1359 } 1360 1361 return WERR_OK; 1362} 1363 1364 1365/* 1366 srvsvc_NetShareDelSticky 1367*/ 1368static WERROR dcesrv_srvsvc_NetShareDelSticky(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1369 struct srvsvc_NetShareDelSticky *r) 1370{ 1371 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1372} 1373 1374 1375/* 1376 srvsvc_NetShareCheck 1377*/ 1378static WERROR dcesrv_srvsvc_NetShareCheck(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1379 struct srvsvc_NetShareCheck *r) 1380{ 1381 NTSTATUS nterr; 1382 struct share_context *sctx = NULL; 1383 struct share_config *scfg = NULL; 1384 char *device; 1385 const char **names; 1386 int count, i; 1387 1388 *r->out.type = 0; 1389 1390 /* TODO: - access check 1391 */ 1392 1393 if (strcmp("", r->in.device_name) == 0) { 1394 *r->out.type = STYPE_IPC; 1395 return WERR_OK; 1396 } 1397 1398 /* copy the path skipping C:\ */ 1399 if (strncasecmp(r->in.device_name, "C:", 2) == 0) { 1400 device = talloc_strdup(mem_ctx, &r->in.device_name[2]); 1401 } else { 1402 /* no chance we have a share that doesn't start with C:\ */ 1403 return WERR_DEVICE_NOT_SHARED; 1404 } 1405 all_string_sub(device, "\\", "/", 0); 1406 1407 nterr = share_get_context_by_name(mem_ctx, lp_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx); 1408 if (!NT_STATUS_IS_OK(nterr)) { 1409 return ntstatus_to_werror(nterr); 1410 } 1411 1412 nterr = share_list_all(mem_ctx, sctx, &count, &names); 1413 if (!NT_STATUS_IS_OK(nterr)) { 1414 return ntstatus_to_werror(nterr); 1415 } 1416 1417 for (i = 0; i < count; i++) { 1418 const char *path; 1419 const char *type; 1420 1421 nterr = share_get_config(mem_ctx, sctx, names[i], &scfg); 1422 if (!NT_STATUS_IS_OK(nterr)) { 1423 return ntstatus_to_werror(nterr); 1424 } 1425 path = share_string_option(scfg, SHARE_PATH, NULL); 1426 if (!path) continue; 1427 1428 if (strcmp(device, path) == 0) { 1429 type = share_string_option(scfg, SHARE_TYPE, NULL); 1430 if (!type) continue; 1431 1432 if (strcmp(type, "DISK") == 0) { 1433 *r->out.type = STYPE_DISKTREE; 1434 return WERR_OK; 1435 } 1436 1437 if (strcmp(type, "IPC") == 0) { 1438 *r->out.type = STYPE_IPC; 1439 return WERR_OK; 1440 } 1441 1442 if (strcmp(type, "PRINTER") == 0) { 1443 *r->out.type = STYPE_PRINTQ; 1444 return WERR_OK; 1445 } 1446 } 1447 } 1448 1449 return WERR_DEVICE_NOT_SHARED; 1450} 1451 1452 1453/* 1454 srvsvc_NetSrvGetInfo 1455*/ 1456static WERROR dcesrv_srvsvc_NetSrvGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1457 struct srvsvc_NetSrvGetInfo *r) 1458{ 1459 struct dcesrv_context *dce_ctx = dce_call->conn->dce_ctx; 1460 struct dcerpc_server_info *server_info = lp_dcerpc_server_info(mem_ctx, dce_ctx->lp_ctx); 1461 1462 ZERO_STRUCTP(r->out.info); 1463 1464 switch (r->in.level) { 1465 case 100: 1466 { 1467 struct srvsvc_NetSrvInfo100 *info100; 1468 1469 info100 = talloc(mem_ctx, struct srvsvc_NetSrvInfo100); 1470 W_ERROR_HAVE_NO_MEMORY(info100); 1471 1472 info100->platform_id = dcesrv_common_get_platform_id(mem_ctx, dce_ctx); 1473 info100->server_name = dcesrv_common_get_server_name(mem_ctx, dce_ctx, r->in.server_unc); 1474 W_ERROR_HAVE_NO_MEMORY(info100->server_name); 1475 1476 r->out.info->info100 = info100; 1477 return WERR_OK; 1478 } 1479 case 101: 1480 { 1481 struct srvsvc_NetSrvInfo101 *info101; 1482 1483 info101 = talloc(mem_ctx, struct srvsvc_NetSrvInfo101); 1484 W_ERROR_HAVE_NO_MEMORY(info101); 1485 1486 info101->platform_id = dcesrv_common_get_platform_id(mem_ctx, dce_ctx); 1487 info101->server_name = dcesrv_common_get_server_name(mem_ctx, dce_ctx, r->in.server_unc); 1488 W_ERROR_HAVE_NO_MEMORY(info101->server_name); 1489 1490 info101->version_major = server_info->version_major; 1491 info101->version_minor = server_info->version_minor; 1492 info101->server_type = dcesrv_common_get_server_type(mem_ctx, dce_call->event_ctx, dce_ctx); 1493 info101->comment = talloc_strdup(mem_ctx, lp_serverstring(dce_ctx->lp_ctx)); 1494 W_ERROR_HAVE_NO_MEMORY(info101->comment); 1495 1496 r->out.info->info101 = info101; 1497 return WERR_OK; 1498 } 1499 case 102: 1500 { 1501 struct srvsvc_NetSrvInfo102 *info102; 1502 1503 info102 = talloc(mem_ctx, struct srvsvc_NetSrvInfo102); 1504 W_ERROR_HAVE_NO_MEMORY(info102); 1505 1506 info102->platform_id = dcesrv_common_get_platform_id(mem_ctx, dce_ctx); 1507 info102->server_name = dcesrv_common_get_server_name(mem_ctx, dce_ctx, r->in.server_unc); 1508 W_ERROR_HAVE_NO_MEMORY(info102->server_name); 1509 1510 info102->version_major = server_info->version_major; 1511 info102->version_minor = server_info->version_minor; 1512 info102->server_type = dcesrv_common_get_server_type(mem_ctx, dce_call->event_ctx, dce_ctx); 1513 info102->comment = talloc_strdup(mem_ctx, lp_serverstring(dce_ctx->lp_ctx)); 1514 W_ERROR_HAVE_NO_MEMORY(info102->comment); 1515 1516 info102->users = dcesrv_common_get_users(mem_ctx, dce_ctx); 1517 info102->disc = dcesrv_common_get_disc(mem_ctx, dce_ctx); 1518 info102->hidden = dcesrv_common_get_hidden(mem_ctx, dce_ctx); 1519 info102->announce = dcesrv_common_get_announce(mem_ctx, dce_ctx); 1520 info102->anndelta = dcesrv_common_get_anndelta(mem_ctx, dce_ctx); 1521 info102->licenses = dcesrv_common_get_licenses(mem_ctx, dce_ctx); 1522 info102->userpath = dcesrv_common_get_userpath(mem_ctx, dce_ctx); 1523 W_ERROR_HAVE_NO_MEMORY(info102->userpath); 1524 1525 r->out.info->info102 = info102; 1526 return WERR_OK; 1527 } 1528 default: 1529 return WERR_UNKNOWN_LEVEL; 1530 } 1531 1532 return WERR_UNKNOWN_LEVEL; 1533} 1534 1535 1536/* 1537 srvsvc_NetSrvSetInfo 1538*/ 1539static WERROR dcesrv_srvsvc_NetSrvSetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1540 struct srvsvc_NetSrvSetInfo *r) 1541{ 1542 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1543} 1544 1545 1546/* 1547 srvsvc_NetDiskEnum 1548*/ 1549static WERROR dcesrv_srvsvc_NetDiskEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1550 struct srvsvc_NetDiskEnum *r) 1551{ 1552 r->out.info->disks = NULL; 1553 r->out.info->count = 0; 1554 *r->out.totalentries = 0; 1555 1556 switch (r->in.level) { 1557 case 0: 1558 { 1559 /* we can safely hardcode the reply and report we have only one disk (C:) */ 1560 /* for some reason Windows wants 2 entries with the second being empty */ 1561 r->out.info->disks = talloc_array(mem_ctx, struct srvsvc_NetDiskInfo0, 2); 1562 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks); 1563 r->out.info->count = 2; 1564 1565 r->out.info->disks[0].disk = talloc_strdup(mem_ctx, "C:"); 1566 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[0].disk); 1567 1568 r->out.info->disks[1].disk = talloc_strdup(mem_ctx, ""); 1569 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[1].disk); 1570 1571 *r->out.totalentries = 1; 1572 r->out.resume_handle = r->in.resume_handle; 1573 1574 return WERR_OK; 1575 } 1576 default: 1577 return WERR_UNKNOWN_LEVEL; 1578 } 1579 1580 return WERR_UNKNOWN_LEVEL; 1581} 1582 1583 1584/* 1585 srvsvc_NetServerStatisticsGet 1586*/ 1587static WERROR dcesrv_srvsvc_NetServerStatisticsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1588 struct srvsvc_NetServerStatisticsGet *r) 1589{ 1590 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1591} 1592 1593 1594/* 1595 srvsvc_NetTransportAdd 1596*/ 1597static WERROR dcesrv_srvsvc_NetTransportAdd(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1598 struct srvsvc_NetTransportAdd *r) 1599{ 1600 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1601} 1602 1603 1604/* 1605 srvsvc_NetTransportEnum 1606*/ 1607static WERROR dcesrv_srvsvc_NetTransportEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1608 struct srvsvc_NetTransportEnum *r) 1609{ 1610 r->out.transports->level = r->in.transports->level; 1611 *r->out.totalentries = 0; 1612 if (r->out.resume_handle) { 1613 *r->out.resume_handle = 0; 1614 } 1615 1616 switch (r->in.transports->level) { 1617 case 0: 1618 { 1619 r->out.transports->ctr.ctr0 = talloc(mem_ctx, struct srvsvc_NetTransportCtr0); 1620 W_ERROR_HAVE_NO_MEMORY(r->out.transports->ctr.ctr0); 1621 1622 r->out.transports->ctr.ctr0->count = 0; 1623 r->out.transports->ctr.ctr0->array = NULL; 1624 1625 return WERR_NOT_SUPPORTED; 1626 } 1627 case 1: 1628 { 1629 r->out.transports->ctr.ctr1 = talloc(mem_ctx, struct srvsvc_NetTransportCtr1); 1630 W_ERROR_HAVE_NO_MEMORY(r->out.transports->ctr.ctr1); 1631 1632 r->out.transports->ctr.ctr1->count = 0; 1633 r->out.transports->ctr.ctr1->array = NULL; 1634 1635 return WERR_NOT_SUPPORTED; 1636 } 1637 case 2: 1638 { 1639 r->out.transports->ctr.ctr2 = talloc(mem_ctx, struct srvsvc_NetTransportCtr2); 1640 W_ERROR_HAVE_NO_MEMORY(r->out.transports->ctr.ctr2); 1641 1642 r->out.transports->ctr.ctr2->count = 0; 1643 r->out.transports->ctr.ctr2->array = NULL; 1644 1645 return WERR_NOT_SUPPORTED; 1646 } 1647 case 3: 1648 { 1649 r->out.transports->ctr.ctr3 = talloc(mem_ctx, struct srvsvc_NetTransportCtr3); 1650 W_ERROR_HAVE_NO_MEMORY(r->out.transports->ctr.ctr3); 1651 1652 r->out.transports->ctr.ctr3->count = 0; 1653 r->out.transports->ctr.ctr3->array = NULL; 1654 1655 return WERR_NOT_SUPPORTED; 1656 } 1657 default: 1658 return WERR_UNKNOWN_LEVEL; 1659 } 1660 1661 return WERR_UNKNOWN_LEVEL; 1662} 1663 1664/* 1665 srvsvc_NetTransportDel 1666*/ 1667static WERROR dcesrv_srvsvc_NetTransportDel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1668 struct srvsvc_NetTransportDel *r) 1669{ 1670 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1671} 1672 1673 1674/* 1675 srvsvc_NetRemoteTOD 1676*/ 1677static WERROR dcesrv_srvsvc_NetRemoteTOD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1678 struct srvsvc_NetRemoteTOD *r) 1679{ 1680 struct timeval tval; 1681 time_t t; 1682 struct tm tm; 1683 struct srvsvc_NetRemoteTODInfo *info; 1684 1685 info = talloc(mem_ctx, struct srvsvc_NetRemoteTODInfo); 1686 W_ERROR_HAVE_NO_MEMORY(info); 1687 1688 GetTimeOfDay(&tval); 1689 t = tval.tv_sec; 1690 1691 gmtime_r(&t, &tm); 1692 1693 info->elapsed = t; 1694 /* TODO: fake the uptime: just return the milliseconds till 0:00:00 today */ 1695 info->msecs = (tm.tm_hour*60*60*1000) 1696 + (tm.tm_min*60*1000) 1697 + (tm.tm_sec*1000) 1698 + (tval.tv_usec/1000); 1699 info->hours = tm.tm_hour; 1700 info->mins = tm.tm_min; 1701 info->secs = tm.tm_sec; 1702 info->hunds = tval.tv_usec/10000; 1703 info->timezone = get_time_zone(t)/60; 1704 info->tinterval = 310; /* just return the same as windows */ 1705 info->day = tm.tm_mday; 1706 info->month = tm.tm_mon + 1; 1707 info->year = tm.tm_year + 1900; 1708 info->weekday = tm.tm_wday; 1709 1710 *r->out.info = info; 1711 1712 return WERR_OK; 1713} 1714 1715/* 1716 srvsvc_NetPathType 1717*/ 1718static WERROR dcesrv_srvsvc_NetPathType(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1719 struct srvsvc_NetPathType *r) 1720{ 1721 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1722} 1723 1724 1725/* 1726 srvsvc_NetPathCanonicalize 1727*/ 1728static WERROR dcesrv_srvsvc_NetPathCanonicalize(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1729 struct srvsvc_NetPathCanonicalize *r) 1730{ 1731 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1732} 1733 1734 1735/* 1736 srvsvc_NetPathCompare 1737*/ 1738static WERROR dcesrv_srvsvc_NetPathCompare(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1739 struct srvsvc_NetPathCompare *r) 1740{ 1741 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1742} 1743 1744 1745/* 1746 srvsvc_NetNameValidate 1747*/ 1748static WERROR dcesrv_srvsvc_NetNameValidate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1749 struct srvsvc_NetNameValidate *r) 1750{ 1751 int len; 1752 1753 if ((r->in.flags != 0x0) && (r->in.flags != 0x80000000)) { 1754 return WERR_INVALID_NAME; 1755 } 1756 1757 switch (r->in.name_type) { 1758 case 1: 1759 case 2: 1760 case 3: 1761 case 4: 1762 case 5: 1763 case 6: 1764 case 7: 1765 case 8: 1766 return WERR_NOT_SUPPORTED; 1767 1768 case 9: /* validate share name */ 1769 1770 len = strlen_m(r->in.name); 1771 if ((r->in.flags == 0x0) && (len > 81)) { 1772 return WERR_INVALID_NAME; 1773 } 1774 if ((r->in.flags == 0x80000000) && (len > 13)) { 1775 return WERR_INVALID_NAME; 1776 } 1777 if (! dcesrv_common_validate_share_name(mem_ctx, r->in.name)) { 1778 return WERR_INVALID_NAME; 1779 } 1780 return WERR_OK; 1781 1782 case 10: 1783 case 11: 1784 case 12: 1785 case 13: 1786 return WERR_NOT_SUPPORTED; 1787 default: 1788 return WERR_INVALID_PARAM; 1789 } 1790 1791 return WERR_INVALID_PARAM; 1792} 1793 1794 1795/* 1796 srvsvc_NetPRNameCompare 1797*/ 1798static WERROR dcesrv_srvsvc_NetPRNameCompare(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1799 struct srvsvc_NetPRNameCompare *r) 1800{ 1801 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1802} 1803 1804 1805/* 1806 srvsvc_NetShareEnum 1807*/ 1808static WERROR dcesrv_srvsvc_NetShareEnum(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1809 struct srvsvc_NetShareEnum *r) 1810{ 1811 NTSTATUS nterr; 1812 int numshares = 0; 1813 const char **snames; 1814 struct share_context *sctx; 1815 struct share_config *scfg; 1816 struct dcesrv_context *dce_ctx = dce_call->conn->dce_ctx; 1817 1818 *r->out.totalentries = 0; 1819 1820 /* TODO: - paging of results 1821 */ 1822 1823 nterr = share_get_context_by_name(mem_ctx, lp_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx); 1824 if (!NT_STATUS_IS_OK(nterr)) { 1825 return ntstatus_to_werror(nterr); 1826 } 1827 1828 nterr = share_list_all(mem_ctx, sctx, &numshares, &snames); 1829 if (!NT_STATUS_IS_OK(nterr)) { 1830 return ntstatus_to_werror(nterr); 1831 } 1832 1833 switch (r->in.info_ctr->level) { 1834 case 0: 1835 { 1836 int i, y = 0; 1837 int count; 1838 struct srvsvc_NetShareCtr0 *ctr0; 1839 1840 ctr0 = talloc(mem_ctx, struct srvsvc_NetShareCtr0); 1841 W_ERROR_HAVE_NO_MEMORY(ctr0); 1842 1843 count = numshares; 1844 ctr0->count = count; 1845 ctr0->array = NULL; 1846 1847 if (ctr0->count == 0) { 1848 r->out.info_ctr->ctr.ctr0 = ctr0; 1849 return WERR_OK; 1850 } 1851 1852 ctr0->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo0, count); 1853 W_ERROR_HAVE_NO_MEMORY(ctr0->array); 1854 1855 for (i=0; i < count; i++) { 1856 WERROR status; 1857 union srvsvc_NetShareInfo info; 1858 enum srvsvc_ShareType type; 1859 1860 nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg); 1861 if (!NT_STATUS_IS_OK(nterr)) { 1862 DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i])); 1863 return WERR_GENERAL_FAILURE; 1864 } 1865 1866 type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg); 1867 if (type & STYPE_HIDDEN) { 1868 ctr0->count--; 1869 talloc_free(scfg); 1870 continue; 1871 } 1872 1873 info.info0 = &ctr0->array[y]; 1874 status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.info_ctr->level, &info); 1875 W_ERROR_NOT_OK_RETURN(status); 1876 talloc_free(scfg); 1877 y++; 1878 } 1879 talloc_free(snames); 1880 1881 r->out.info_ctr->ctr.ctr0 = ctr0; 1882 *r->out.totalentries = r->out.info_ctr->ctr.ctr0->count; 1883 1884 return WERR_OK; 1885 } 1886 case 1: 1887 { 1888 int i, y = 0; 1889 int count; 1890 struct srvsvc_NetShareCtr1 *ctr1; 1891 1892 ctr1 = talloc(mem_ctx, struct srvsvc_NetShareCtr1); 1893 W_ERROR_HAVE_NO_MEMORY(ctr1); 1894 1895 count = numshares; 1896 ctr1->count = count; 1897 ctr1->array = NULL; 1898 1899 if (ctr1->count == 0) { 1900 r->out.info_ctr->ctr.ctr1 = ctr1; 1901 return WERR_OK; 1902 } 1903 1904 ctr1->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo1, count); 1905 W_ERROR_HAVE_NO_MEMORY(ctr1->array); 1906 1907 for (i=0; i < count; i++) { 1908 WERROR status; 1909 union srvsvc_NetShareInfo info; 1910 enum srvsvc_ShareType type; 1911 1912 nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg); 1913 if (!NT_STATUS_IS_OK(nterr)) { 1914 DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i])); 1915 return WERR_GENERAL_FAILURE; 1916 } 1917 1918 type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg); 1919 if (type & STYPE_HIDDEN) { 1920 ctr1->count--; 1921 talloc_free(scfg); 1922 continue; 1923 } 1924 1925 info.info1 = &ctr1->array[y]; 1926 status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.info_ctr->level, &info); 1927 W_ERROR_NOT_OK_RETURN(status); 1928 talloc_free(scfg); 1929 y++; 1930 } 1931 talloc_free(snames); 1932 1933 r->out.info_ctr->ctr.ctr1 = ctr1; 1934 *r->out.totalentries = r->out.info_ctr->ctr.ctr1->count; 1935 1936 return WERR_OK; 1937 } 1938 case 2: 1939 { 1940 int i, y = 0; 1941 int count; 1942 struct srvsvc_NetShareCtr2 *ctr2; 1943 1944 SRVSVC_CHECK_ADMIN_ACCESS; 1945 1946 ctr2 = talloc(mem_ctx, struct srvsvc_NetShareCtr2); 1947 W_ERROR_HAVE_NO_MEMORY(ctr2); 1948 1949 count = numshares; 1950 ctr2->count = count; 1951 ctr2->array = NULL; 1952 1953 if (ctr2->count == 0) { 1954 r->out.info_ctr->ctr.ctr2 = ctr2; 1955 return WERR_OK; 1956 } 1957 1958 ctr2->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo2, count); 1959 W_ERROR_HAVE_NO_MEMORY(ctr2->array); 1960 1961 for (i=0; i < count; i++) { 1962 WERROR status; 1963 union srvsvc_NetShareInfo info; 1964 enum srvsvc_ShareType type; 1965 1966 nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg); 1967 if (!NT_STATUS_IS_OK(nterr)) { 1968 DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i])); 1969 return WERR_GENERAL_FAILURE; 1970 } 1971 1972 type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg); 1973 if (type & STYPE_HIDDEN) { 1974 ctr2->count--; 1975 talloc_free(scfg); 1976 continue; 1977 } 1978 1979 info.info2 = &ctr2->array[y]; 1980 status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.info_ctr->level, &info); 1981 W_ERROR_NOT_OK_RETURN(status); 1982 talloc_free(scfg); 1983 y++; 1984 } 1985 talloc_free(snames); 1986 1987 r->out.info_ctr->ctr.ctr2 = ctr2; 1988 *r->out.totalentries = r->out.info_ctr->ctr.ctr2->count; 1989 1990 return WERR_OK; 1991 } 1992 case 502: 1993 { 1994 int i, y = 0; 1995 int count; 1996 struct srvsvc_NetShareCtr502 *ctr502; 1997 1998 SRVSVC_CHECK_ADMIN_ACCESS; 1999 2000 ctr502 = talloc(mem_ctx, struct srvsvc_NetShareCtr502); 2001 W_ERROR_HAVE_NO_MEMORY(ctr502); 2002 2003 count = numshares; 2004 ctr502->count = count; 2005 ctr502->array = NULL; 2006 2007 if (ctr502->count == 0) { 2008 r->out.info_ctr->ctr.ctr502 = ctr502; 2009 return WERR_OK; 2010 } 2011 2012 ctr502->array = talloc_array(mem_ctx, struct srvsvc_NetShareInfo502, count); 2013 W_ERROR_HAVE_NO_MEMORY(ctr502->array); 2014 2015 for (i=0; i < count; i++) { 2016 WERROR status; 2017 union srvsvc_NetShareInfo info; 2018 enum srvsvc_ShareType type; 2019 2020 nterr = share_get_config(mem_ctx, sctx, snames[i], &scfg); 2021 if (!NT_STATUS_IS_OK(nterr)) { 2022 DEBUG(1, ("ERROR: Service [%s] disappeared after enumeration", snames[i])); 2023 return WERR_GENERAL_FAILURE; 2024 } 2025 2026 type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg); 2027 if (type & STYPE_HIDDEN) { 2028 ctr502->count--; 2029 talloc_free(scfg); 2030 continue; 2031 } 2032 2033 info.info502 = &ctr502->array[y]; 2034 status = dcesrv_srvsvc_fiel_ShareInfo(dce_call, mem_ctx, scfg, r->in.info_ctr->level, &info); 2035 W_ERROR_NOT_OK_RETURN(status); 2036 talloc_free(scfg); 2037 y++; 2038 } 2039 talloc_free(snames); 2040 2041 r->out.info_ctr->ctr.ctr502 = ctr502; 2042 *r->out.totalentries = r->out.info_ctr->ctr.ctr502->count; 2043 2044 return WERR_OK; 2045 } 2046 default: 2047 return WERR_UNKNOWN_LEVEL; 2048 } 2049 2050 return WERR_UNKNOWN_LEVEL; 2051} 2052 2053 2054/* 2055 srvsvc_NetShareDelStart 2056*/ 2057static WERROR dcesrv_srvsvc_NetShareDelStart(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2058 struct srvsvc_NetShareDelStart *r) 2059{ 2060 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2061} 2062 2063 2064/* 2065 srvsvc_NetShareDelCommit 2066*/ 2067static WERROR dcesrv_srvsvc_NetShareDelCommit(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2068 struct srvsvc_NetShareDelCommit *r) 2069{ 2070 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2071} 2072 2073 2074/* 2075 srvsvc_NetGetFileSecurity 2076*/ 2077static WERROR dcesrv_srvsvc_NetGetFileSecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2078 struct srvsvc_NetGetFileSecurity *r) 2079{ 2080 struct sec_desc_buf *sd_buf; 2081 struct ntvfs_context *ntvfs_ctx = NULL; 2082 struct ntvfs_request *ntvfs_req; 2083 union smb_fileinfo *io; 2084 NTSTATUS nt_status; 2085 2086 nt_status = srvsvc_create_ntvfs_context(dce_call, mem_ctx, r->in.share, &ntvfs_ctx); 2087 if (!NT_STATUS_IS_OK(nt_status)) return ntstatus_to_werror(nt_status); 2088 2089 ntvfs_req = ntvfs_request_create(ntvfs_ctx, mem_ctx, 2090 dce_call->conn->auth_state.session_info, 2091 0, 2092 dce_call->time, 2093 NULL, NULL, 0); 2094 W_ERROR_HAVE_NO_MEMORY(ntvfs_req); 2095 2096 sd_buf = talloc(mem_ctx, struct sec_desc_buf); 2097 W_ERROR_HAVE_NO_MEMORY(sd_buf); 2098 2099 io = talloc(mem_ctx, union smb_fileinfo); 2100 W_ERROR_HAVE_NO_MEMORY(io); 2101 2102 io->query_secdesc.level = RAW_FILEINFO_SEC_DESC; 2103 io->query_secdesc.in.file.path = r->in.file; 2104 io->query_secdesc.in.secinfo_flags = r->in.securityinformation; 2105 2106 nt_status = ntvfs_qpathinfo(ntvfs_req, io); 2107 if (!NT_STATUS_IS_OK(nt_status)) return ntstatus_to_werror(nt_status); 2108 2109 sd_buf->sd = io->query_secdesc.out.sd; 2110 2111 *r->out.sd_buf = sd_buf; 2112 return WERR_OK; 2113} 2114 2115 2116/* 2117 srvsvc_NetSetFileSecurity 2118*/ 2119static WERROR dcesrv_srvsvc_NetSetFileSecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2120 struct srvsvc_NetSetFileSecurity *r) 2121{ 2122 struct ntvfs_context *ntvfs_ctx; 2123 struct ntvfs_request *ntvfs_req; 2124 union smb_setfileinfo *io; 2125 NTSTATUS nt_status; 2126 2127 nt_status = srvsvc_create_ntvfs_context(dce_call, mem_ctx, r->in.share, &ntvfs_ctx); 2128 if (!NT_STATUS_IS_OK(nt_status)) return ntstatus_to_werror(nt_status); 2129 2130 ntvfs_req = ntvfs_request_create(ntvfs_ctx, mem_ctx, 2131 dce_call->conn->auth_state.session_info, 2132 0, 2133 dce_call->time, 2134 NULL, NULL, 0); 2135 W_ERROR_HAVE_NO_MEMORY(ntvfs_req); 2136 2137 io = talloc(mem_ctx, union smb_setfileinfo); 2138 W_ERROR_HAVE_NO_MEMORY(io); 2139 2140 io->set_secdesc.level = RAW_FILEINFO_SEC_DESC; 2141 io->set_secdesc.in.file.path = r->in.file; 2142 io->set_secdesc.in.secinfo_flags = r->in.securityinformation; 2143 io->set_secdesc.in.sd = r->in.sd_buf->sd; 2144 2145 nt_status = ntvfs_setpathinfo(ntvfs_req, io); 2146 if (!NT_STATUS_IS_OK(nt_status)) return ntstatus_to_werror(nt_status); 2147 2148 return WERR_OK; 2149} 2150 2151 2152/* 2153 srvsvc_NetServerTransportAddEx 2154*/ 2155static WERROR dcesrv_srvsvc_NetServerTransportAddEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2156 struct srvsvc_NetServerTransportAddEx *r) 2157{ 2158 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2159} 2160 2161 2162/* 2163 srvsvc_NetServerSetServiceBitsEx 2164*/ 2165static WERROR dcesrv_srvsvc_NetServerSetServiceBitsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2166 struct srvsvc_NetServerSetServiceBitsEx *r) 2167{ 2168 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2169} 2170 2171 2172/* 2173 srvsvc_NETRDFSGETVERSION 2174*/ 2175static WERROR dcesrv_srvsvc_NETRDFSGETVERSION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2176 struct srvsvc_NETRDFSGETVERSION *r) 2177{ 2178 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2179} 2180 2181 2182/* 2183 srvsvc_NETRDFSCREATELOCALPARTITION 2184*/ 2185static WERROR dcesrv_srvsvc_NETRDFSCREATELOCALPARTITION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2186 struct srvsvc_NETRDFSCREATELOCALPARTITION *r) 2187{ 2188 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2189} 2190 2191 2192/* 2193 srvsvc_NETRDFSDELETELOCALPARTITION 2194*/ 2195static WERROR dcesrv_srvsvc_NETRDFSDELETELOCALPARTITION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2196 struct srvsvc_NETRDFSDELETELOCALPARTITION *r) 2197{ 2198 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2199} 2200 2201 2202/* 2203 srvsvc_NETRDFSSETLOCALVOLUMESTATE 2204*/ 2205static WERROR dcesrv_srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2206 struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r) 2207{ 2208 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2209} 2210 2211 2212/* 2213 srvsvc_NETRDFSSETSERVERINFO 2214*/ 2215static WERROR dcesrv_srvsvc_NETRDFSSETSERVERINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2216 struct srvsvc_NETRDFSSETSERVERINFO *r) 2217{ 2218 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2219} 2220 2221 2222/* 2223 srvsvc_NETRDFSCREATEEXITPOINT 2224*/ 2225static WERROR dcesrv_srvsvc_NETRDFSCREATEEXITPOINT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2226 struct srvsvc_NETRDFSCREATEEXITPOINT *r) 2227{ 2228 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2229} 2230 2231 2232/* 2233 srvsvc_NETRDFSDELETEEXITPOINT 2234*/ 2235static WERROR dcesrv_srvsvc_NETRDFSDELETEEXITPOINT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2236 struct srvsvc_NETRDFSDELETEEXITPOINT *r) 2237{ 2238 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2239} 2240 2241 2242/* 2243 srvsvc_NETRDFSMODIFYPREFIX 2244*/ 2245static WERROR dcesrv_srvsvc_NETRDFSMODIFYPREFIX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2246 struct srvsvc_NETRDFSMODIFYPREFIX *r) 2247{ 2248 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2249} 2250 2251 2252/* 2253 srvsvc_NETRDFSFIXLOCALVOLUME 2254*/ 2255static WERROR dcesrv_srvsvc_NETRDFSFIXLOCALVOLUME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2256 struct srvsvc_NETRDFSFIXLOCALVOLUME *r) 2257{ 2258 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2259} 2260 2261 2262/* 2263 srvsvc_NETRDFSMANAGERREPORTSITEINFO 2264*/ 2265static WERROR dcesrv_srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2266 struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r) 2267{ 2268 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2269} 2270 2271 2272/* 2273 srvsvc_NETRSERVERTRANSPORTDELEX 2274*/ 2275static WERROR dcesrv_srvsvc_NETRSERVERTRANSPORTDELEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2276 struct srvsvc_NETRSERVERTRANSPORTDELEX *r) 2277{ 2278 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2279} 2280 2281/* 2282 srvsvc_NetShareDel 2283*/ 2284static WERROR dcesrv_srvsvc_NetShareDel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2285 struct srvsvc_NetShareDel *r) 2286{ 2287 NTSTATUS nterr; 2288 struct share_context *sctx; 2289 2290 nterr = share_get_context_by_name(mem_ctx, lp_share_backend(dce_call->conn->dce_ctx->lp_ctx), dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, &sctx); 2291 if (!NT_STATUS_IS_OK(nterr)) { 2292 return ntstatus_to_werror(nterr); 2293 } 2294 2295 nterr = share_remove(sctx, r->in.share_name); 2296 if (!NT_STATUS_IS_OK(nterr)) { 2297 return ntstatus_to_werror(nterr); 2298 } 2299 2300 return WERR_OK; 2301} 2302 2303/* 2304 srvsvc_NetSetServiceBits 2305*/ 2306static WERROR dcesrv_srvsvc_NetSetServiceBits(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2307 struct srvsvc_NetSetServiceBits *r) 2308{ 2309 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2310} 2311 2312/* 2313 srvsvc_NETRPRNAMECANONICALIZE 2314*/ 2315static WERROR dcesrv_srvsvc_NETRPRNAMECANONICALIZE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2316 struct srvsvc_NETRPRNAMECANONICALIZE *r) 2317{ 2318 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2319} 2320 2321/* include the generated boilerplate */ 2322#include "librpc/gen_ndr/ndr_srvsvc_s.c" 2323