Changeset 745 for trunk/server/source3/libsmb/libsmb_file.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/libsmb/libsmb_file.c
r414 r745 8 8 Copyright (C) Derrell Lipman 2003-2008 9 9 Copyright (C) Jeremy Allison 2007, 2008 10 10 11 11 This program is free software; you can redistribute it and/or modify 12 12 it under the terms of the GNU General Public License as published by 13 13 the Free Software Foundation; either version 3 of the License, or 14 14 (at your option) any later version. 15 15 16 16 This program is distributed in the hope that it will be useful, 17 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 19 GNU General Public License for more details. 20 20 21 21 You should have received a copy of the GNU General Public License 22 22 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 24 24 25 25 #include "includes.h" 26 #include "libsmb/libsmb.h" 26 27 #include "libsmbclient.h" 27 28 #include "libsmb_internal.h" … … 51 52 NTSTATUS status = NT_STATUS_OBJECT_PATH_INVALID; 52 53 TALLOC_CTX *frame = talloc_stackframe(); 53 54 54 55 if (!context || !context->internal->initialized) { 55 56 56 errno = EINVAL; /* Best I can think of ... */ 57 57 TALLOC_FREE(frame); 58 58 return NULL; 59 60 } 61 59 } 60 62 61 if (!fname) { 63 64 62 errno = EINVAL; 65 63 TALLOC_FREE(frame); 66 64 return NULL; 67 68 } 69 65 } 66 70 67 if (SMBC_parse_path(frame, 71 68 context, … … 82 79 return NULL; 83 80 } 84 81 85 82 if (!user || user[0] == (char)0) { 86 83 user = talloc_strdup(frame, smbc_getUser(context)); … … 91 88 } 92 89 } 93 90 94 91 srv = SMBC_server(frame, context, True, 95 92 server, share, &workgroup, &user, &password); 96 97 93 if (!srv) { 98 94 if (errno == EPERM) errno = EACCES; … … 100 96 return NULL; /* SMBC_server sets errno */ 101 97 } 102 98 103 99 /* Hmmm, the test for a directory is suspect here ... FIXME */ 104 100 105 101 if (strlen(path) > 0 && path[strlen(path) - 1] == '\\') { 106 102 status = NT_STATUS_OBJECT_PATH_INVALID; 107 103 } else { 108 104 file = SMB_MALLOC_P(SMBCFILE); 109 110 105 if (!file) { 111 106 errno = ENOMEM; … … 113 108 return NULL; 114 109 } 115 110 116 111 ZERO_STRUCTP(file); 117 112 118 113 /*d_printf(">>>open: resolving %s\n", path);*/ 119 114 if (!cli_resolve_path(frame, "", context->internal->auth_info, … … 127 122 } 128 123 /*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/ 129 124 130 125 status = cli_open(targetcli, targetpath, flags, 131 126 context->internal->share_mode, &fd); 132 127 if (!NT_STATUS_IS_OK(status)) { 133 128 134 129 /* Handle the error ... */ 135 130 136 131 SAFE_FREE(file); 137 132 errno = SMBC_errno(context, targetcli); 138 133 TALLOC_FREE(frame); 139 134 return NULL; 140 141 135 } 142 136 143 137 /* Fill in file struct */ 144 138 145 139 file->cli_fd = fd; 146 140 file->fname = SMB_STRDUP(fname); … … 148 142 file->offset = 0; 149 143 file->file = True; 150 144 151 145 DLIST_ADD(context->internal->files, file); 152 146 153 147 /* 154 148 * If the file was opened in O_APPEND mode, all write … … 181 175 } 182 176 } 183 177 184 178 TALLOC_FREE(frame); 185 179 return file; 186 187 } 188 180 } 181 189 182 /* Check if opendir needed ... */ 190 183 191 184 if (!NT_STATUS_IS_OK(status)) { 192 185 int eno = 0; 193 186 194 187 eno = SMBC_errno(context, srv->cli); 195 188 file = smbc_getFunctionOpendir(context)(context, fname); … … 197 190 TALLOC_FREE(frame); 198 191 return file; 199 200 } 201 192 } 193 202 194 errno = EINVAL; /* FIXME, correct errno ? */ 203 195 TALLOC_FREE(frame); 204 196 return NULL; 205 206 197 } 207 198 … … 215 206 mode_t mode) 216 207 { 217 218 208 if (!context || !context->internal->initialized) { 219 220 209 errno = EINVAL; 221 210 return NULL; 222 223 } 224 211 } 212 225 213 return SMBC_open_ctx(context, path, 226 214 O_WRONLY | O_CREAT | O_TRUNC, mode); … … 243 231 struct cli_state *targetcli = NULL; 244 232 TALLOC_CTX *frame = talloc_stackframe(); 245 233 246 234 /* 247 235 * offset: … … 254 242 */ 255 243 off_t offset; 256 244 257 245 if (!context || !context->internal->initialized) { 258 259 errno = EINVAL; 260 TALLOC_FREE(frame); 261 return -1; 262 263 } 264 246 errno = EINVAL; 247 TALLOC_FREE(frame); 248 return -1; 249 } 250 265 251 DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); 266 252 267 253 if (!file || !SMBC_dlist_contains(context->internal->files, file)) { 268 254 errno = EBADF; 269 255 TALLOC_FREE(frame); 270 256 return -1; 271 272 } 273 257 } 258 274 259 offset = file->offset; 275 260 276 261 /* Check that the buffer exists ... */ 277 262 278 263 if (buf == NULL) { 279 264 errno = EINVAL; 280 265 TALLOC_FREE(frame); 281 266 return -1; 282 283 } 284 267 } 268 285 269 /*d_printf(">>>read: parsing %s\n", file->fname);*/ 286 270 if (SMBC_parse_path(frame, … … 298 282 return -1; 299 283 } 300 284 301 285 /*d_printf(">>>read: resolving %s\n", path);*/ 302 286 if (!cli_resolve_path(frame, "", context->internal->auth_info, … … 309 293 } 310 294 /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ 311 295 312 296 ret = cli_read(targetcli, file->cli_fd, (char *)buf, offset, count); 313 297 314 298 if (ret < 0) { 315 316 299 errno = SMBC_errno(context, targetcli); 317 300 TALLOC_FREE(frame); 318 301 return -1; 319 320 } 321 302 } 303 322 304 file->offset += ret; 323 305 324 306 DEBUG(4, (" --> %d\n", ret)); 325 307 326 308 TALLOC_FREE(frame); 327 309 return ret; /* Success, ret bytes of data ... */ 328 329 310 } 330 311 … … 339 320 size_t count) 340 321 { 341 int ret;342 322 off_t offset; 343 323 char *server = NULL, *share = NULL, *user = NULL, *password = NULL; … … 346 326 struct cli_state *targetcli = NULL; 347 327 TALLOC_CTX *frame = talloc_stackframe(); 348 328 NTSTATUS status; 329 349 330 /* First check all pointers before dereferencing them */ 350 331 351 332 if (!context || !context->internal->initialized) { 352 353 errno = EINVAL; 354 TALLOC_FREE(frame); 355 return -1; 356 357 } 358 333 errno = EINVAL; 334 TALLOC_FREE(frame); 335 return -1; 336 } 337 359 338 if (!file || !SMBC_dlist_contains(context->internal->files, file)) { 360 339 errno = EBADF; … … 362 341 return -1; 363 342 } 364 343 365 344 /* Check that the buffer exists ... */ 366 345 367 346 if (buf == NULL) { 368 347 errno = EINVAL; 369 348 TALLOC_FREE(frame); 370 349 return -1; 371 372 } 373 350 } 351 374 352 offset = file->offset; /* See "offset" comment in SMBC_read_ctx() */ 375 353 376 354 /*d_printf(">>>write: parsing %s\n", file->fname);*/ 377 355 if (SMBC_parse_path(frame, … … 400 378 } 401 379 /*d_printf(">>>write: resolved path as %s\n", targetpath);*/ 402 403 ret = cli_write(targetcli, file->cli_fd, 404 0, (char *)buf, offset, count); 405 406 if (ret <= 0) { 407 errno = SMBC_errno(context, targetcli); 408 TALLOC_FREE(frame); 409 return -1; 410 411 } 412 413 file->offset += ret; 414 380 381 status = cli_writeall(targetcli, file->cli_fd, 382 0, (uint8_t *)buf, offset, count, NULL); 383 if (!NT_STATUS_IS_OK(status)) { 384 errno = map_errno_from_nt_status(status); 385 TALLOC_FREE(frame); 386 return -1; 387 } 388 389 file->offset += count; 390 415 391 TALLOC_FREE(frame); 416 return ret; /* Success, 0 bytes of data ... */392 return count; /* Success, 0 bytes of data ... */ 417 393 } 418 394 … … 431 407 struct cli_state *targetcli = NULL; 432 408 TALLOC_CTX *frame = talloc_stackframe(); 433 409 434 410 if (!context || !context->internal->initialized) { 435 436 errno = EINVAL; 437 TALLOC_FREE(frame); 438 return -1; 439 } 440 411 errno = EINVAL; 412 TALLOC_FREE(frame); 413 return -1; 414 } 415 441 416 if (!file || !SMBC_dlist_contains(context->internal->files, file)) { 442 417 errno = EBADF; … … 444 419 return -1; 445 420 } 446 421 447 422 /* IS a dir ... */ 448 423 if (!file->file) { … … 450 425 return smbc_getFunctionClosedir(context)(context, file); 451 426 } 452 427 453 428 /*d_printf(">>>close: parsing %s\n", file->fname);*/ 454 429 if (SMBC_parse_path(frame, … … 466 441 return -1; 467 442 } 468 443 469 444 /*d_printf(">>>close: resolving %s\n", path);*/ 470 445 if (!cli_resolve_path(frame, "", context->internal->auth_info, … … 477 452 } 478 453 /*d_printf(">>>close: resolved path as %s\n", targetpath);*/ 479 454 480 455 if (!NT_STATUS_IS_OK(cli_close(targetcli, file->cli_fd))) { 481 482 456 DEBUG(3, ("cli_close failed on %s. purging server.\n", 483 457 file->fname)); … … 492 466 TALLOC_FREE(frame); 493 467 return -1; 494 495 } 496 468 } 469 497 470 DLIST_REMOVE(context->internal->files, file); 498 471 SAFE_FREE(file->fname); 499 472 SAFE_FREE(file); 500 473 TALLOC_FREE(frame); 501 502 474 return 0; 503 475 } … … 524 496 time_t write_time; 525 497 TALLOC_CTX *frame = talloc_stackframe(); 526 498 527 499 if (!context || !context->internal->initialized) { 528 529 500 errno = EINVAL; 530 501 TALLOC_FREE(frame); 531 502 return False; 532 503 } 533 504 534 505 /* path fixup for . and .. */ 535 506 if (strequal(path, ".") || strequal(path, "..")) { … … 551 522 } 552 523 DEBUG(4,("SMBC_getatr: sending qpathinfo\n")); 553 524 554 525 if (!cli_resolve_path(frame, "", context->internal->auth_info, 555 526 srv->cli, fixedpath, … … 560 531 return False; 561 532 } 562 533 563 534 if (!srv->no_pathinfo2 && 564 cli_qpathinfo2(targetcli, targetpath,535 NT_STATUS_IS_OK(cli_qpathinfo2(targetcli, targetpath, 565 536 create_time_ts, 566 537 access_time_ts, 567 538 write_time_ts, 568 539 change_time_ts, 569 size, mode, ino)) {540 size, mode, ino))) { 570 541 TALLOC_FREE(frame); 571 542 return True; 572 543 } 573 544 574 545 /* if this is NT then don't bother with the getatr */ 575 546 if (targetcli->capabilities & CAP_NT_SMBS) { … … 578 549 return False; 579 550 } 580 551 581 552 if (NT_STATUS_IS_OK(cli_getatr(targetcli, targetpath, mode, size, &write_time))) { 582 583 553 struct timespec w_time_ts; 584 554 585 555 w_time_ts = convert_time_t_to_timespec(write_time); 586 587 556 if (write_time_ts != NULL) { 588 557 *write_time_ts = w_time_ts; 589 558 } 590 591 559 if (create_time_ts != NULL) { 592 560 *create_time_ts = w_time_ts; 593 561 } 594 595 562 if (access_time_ts != NULL) { 596 563 *access_time_ts = w_time_ts; 597 564 } 598 599 565 if (change_time_ts != NULL) { 600 566 *change_time_ts = w_time_ts; 601 567 } 602 603 568 srv->no_pathinfo2 = True; 604 569 TALLOC_FREE(frame); 605 570 return True; 606 571 } 607 572 608 573 errno = EPERM; 609 574 TALLOC_FREE(frame); 610 575 return False; 611 612 576 } 613 577 … … 633 597 int ret; 634 598 TALLOC_CTX *frame = talloc_stackframe(); 635 599 636 600 /* 637 601 * First, try setpathinfo (if qpathinfo succeeded), for it is the … … 641 605 */ 642 606 if (srv->no_pathinfo || 643 ! cli_setpathinfo(srv->cli, path,644 645 646 647 648 mode)) {649 607 !NT_STATUS_IS_OK(cli_setpathinfo_basic(srv->cli, path, 608 create_time, 609 access_time, 610 write_time, 611 change_time, 612 mode))) { 613 650 614 /* 651 615 * setpathinfo is not supported; go to plan B. … … 657 621 * supports both times. 658 622 */ 659 623 660 624 /* Don't try {q,set}pathinfo() again, with this server */ 661 625 srv->no_pathinfo = True; 662 626 663 627 /* Open the file */ 664 628 if (!NT_STATUS_IS_OK(cli_open(srv->cli, path, O_RDWR, DENY_NONE, &fd))) { 665 666 629 errno = SMBC_errno(context, srv->cli); 667 630 TALLOC_FREE(frame); 668 631 return -1; 669 632 } 670 633 671 634 /* Set the new attributes */ 672 635 ret = NT_STATUS_IS_OK(cli_setattrE(srv->cli, fd, … … 674 637 access_time, 675 638 write_time)); 676 639 677 640 /* Close the file */ 678 641 cli_close(srv->cli, fd); 679 642 680 643 /* 681 644 * Unfortunately, setattrE() doesn't have a provision for … … 687 650 ret = NT_STATUS_IS_OK(cli_setatr(srv->cli, path, mode, 0)); 688 651 } 689 652 690 653 if (! ret) { 691 654 errno = SMBC_errno(context, srv->cli); … … 694 657 } 695 658 } 696 659 697 660 TALLOC_FREE(frame); 698 661 return True; … … 715 678 struct cli_state *targetcli = NULL; 716 679 TALLOC_CTX *frame = talloc_stackframe(); 717 680 718 681 if (!context || !context->internal->initialized) { 719 720 errno = EINVAL; 721 TALLOC_FREE(frame); 722 return -1; 723 } 724 682 errno = EINVAL; 683 TALLOC_FREE(frame); 684 return -1; 685 } 686 725 687 if (!file || !SMBC_dlist_contains(context->internal->files, file)) { 726 727 688 errno = EBADF; 728 689 TALLOC_FREE(frame); 729 690 return -1; 730 731 } 732 691 } 692 733 693 if (!file->file) { 734 735 694 errno = EINVAL; 736 695 TALLOC_FREE(frame); 737 696 return -1; /* Can't lseek a dir ... */ 738 739 } 740 697 } 698 741 699 switch (whence) { 742 700 case SEEK_SET: 743 701 file->offset = offset; 744 702 break; 745 746 703 case SEEK_CUR: 747 704 file->offset += offset; 748 705 break; 749 750 706 case SEEK_END: 751 707 /*d_printf(">>>lseek: parsing %s\n", file->fname);*/ … … 764 720 return -1; 765 721 } 766 722 767 723 /*d_printf(">>>lseek: resolving %s\n", path);*/ 768 724 if (!cli_resolve_path(frame, "", context->internal->auth_info, … … 774 730 return -1; 775 731 } 732 776 733 /*d_printf(">>>lseek: resolved path as %s\n", targetpath);*/ 777 778 if (!cli_qfileinfo(targetcli, file->cli_fd, NULL,779 &size, NULL, NULL, NULL, NULL, NULL)) 780 {734 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic( 735 targetcli, file->cli_fd, NULL, 736 &size, NULL, NULL, NULL, NULL, 737 NULL))) { 781 738 SMB_OFF_T b_size = size; 782 739 if (!NT_STATUS_IS_OK(cli_getattrE(targetcli, file->cli_fd, … … 790 747 file->offset = size + offset; 791 748 break; 792 793 749 default: 794 750 errno = EINVAL; 795 751 break; 796 797 } 798 752 } 753 799 754 TALLOC_FREE(frame); 800 755 return file->offset; 801 802 756 } 803 757 … … 821 775 struct cli_state *targetcli = NULL; 822 776 TALLOC_CTX *frame = talloc_stackframe(); 823 777 824 778 if (!context || !context->internal->initialized) { 825 826 errno = EINVAL; 827 TALLOC_FREE(frame); 828 return -1; 829 } 830 779 errno = EINVAL; 780 TALLOC_FREE(frame); 781 return -1; 782 } 783 831 784 if (!file || !SMBC_dlist_contains(context->internal->files, file)) { 832 785 errno = EBADF; … … 834 787 return -1; 835 788 } 836 789 837 790 if (!file->file) { 838 791 errno = EINVAL; … … 840 793 return -1; 841 794 } 842 795 843 796 /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ 844 797 if (SMBC_parse_path(frame, … … 856 809 return -1; 857 810 } 858 811 859 812 /*d_printf(">>>fstat: resolving %s\n", path);*/ 860 813 if (!cli_resolve_path(frame, "", context->internal->auth_info, … … 867 820 } 868 821 /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ 869 822 870 823 if (!NT_STATUS_IS_OK(cli_ftruncate(targetcli, file->cli_fd, (uint64_t)size))) { 871 824 errno = EINVAL; … … 873 826 return -1; 874 827 } 875 828 876 829 TALLOC_FREE(frame); 877 830 return 0; 878 879 831 }
Note:
See TracChangeset
for help on using the changeset viewer.