Changeset 740 for vendor/current/source3/libsmb/clifile.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/libsmb/clifile.c
r414 r740 4 4 Copyright (C) Andrew Tridgell 1994-1998 5 5 Copyright (C) Jeremy Allison 2001-2009 6 6 7 7 This program is free software; you can redistribute it and/or modify 8 8 it under the terms of the GNU General Public License as published by 9 9 the Free Software Foundation; either version 3 of the License, or 10 10 (at your option) any later version. 11 11 12 12 This program is distributed in the hope that it will be useful, 13 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 15 GNU General Public License for more details. 16 16 17 17 You should have received a copy of the GNU General Public License 18 18 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 20 20 21 21 #include "includes.h" 22 #include "system/filesys.h" 23 #include "libsmb/libsmb.h" 24 #include "../lib/util/tevent_ntstatus.h" 25 #include "async_smb.h" 26 #include "libsmb/clirap.h" 27 #include "trans2.h" 28 #include "ntioctl.h" 22 29 23 30 /*********************************************************** … … 92 99 } 93 100 101 uint8_t *smb_bytes_push_bytes(uint8_t *buf, uint8_t prefix, 102 const uint8_t *bytes, size_t num_bytes) 103 { 104 size_t buflen; 105 106 if (buf == NULL) { 107 return NULL; 108 } 109 buflen = talloc_get_size(buf); 110 111 buf = TALLOC_REALLOC_ARRAY(NULL, buf, uint8_t, 112 buflen + 1 + num_bytes); 113 if (buf == NULL) { 114 return NULL; 115 } 116 buf[buflen] = prefix; 117 memcpy(&buf[buflen+1], bytes, num_bytes); 118 return buf; 119 } 120 94 121 /*********************************************************** 95 122 Same as smb_bytes_push_str(), but without the odd byte … … 107 134 } 108 135 136 struct cli_setpathinfo_state { 137 uint16_t setup; 138 uint8_t *param; 139 }; 140 141 static void cli_setpathinfo_done(struct tevent_req *subreq); 142 143 struct tevent_req *cli_setpathinfo_send(TALLOC_CTX *mem_ctx, 144 struct tevent_context *ev, 145 struct cli_state *cli, 146 uint16_t level, 147 const char *path, 148 uint8_t *data, 149 size_t data_len) 150 { 151 struct tevent_req *req, *subreq; 152 struct cli_setpathinfo_state *state; 153 154 req = tevent_req_create(mem_ctx, &state, 155 struct cli_setpathinfo_state); 156 if (req == NULL) { 157 return NULL; 158 } 159 160 /* Setup setup word. */ 161 SSVAL(&state->setup, 0, TRANSACT2_SETPATHINFO); 162 163 /* Setup param array. */ 164 state->param = TALLOC_ZERO_ARRAY(state, uint8_t, 6); 165 if (tevent_req_nomem(state->param, req)) { 166 return tevent_req_post(req, ev); 167 } 168 SSVAL(state->param, 0, level); 169 170 state->param = trans2_bytes_push_str( 171 state->param, cli_ucs2(cli), path, strlen(path)+1, NULL); 172 if (tevent_req_nomem(state->param, req)) { 173 return tevent_req_post(req, ev); 174 } 175 176 subreq = cli_trans_send( 177 state, /* mem ctx. */ 178 ev, /* event ctx. */ 179 cli, /* cli_state. */ 180 SMBtrans2, /* cmd. */ 181 NULL, /* pipe name. */ 182 -1, /* fid. */ 183 0, /* function. */ 184 0, /* flags. */ 185 &state->setup, /* setup. */ 186 1, /* num setup uint16_t words. */ 187 0, /* max returned setup. */ 188 state->param, /* param. */ 189 talloc_get_size(state->param), /* num param. */ 190 2, /* max returned param. */ 191 data, /* data. */ 192 data_len, /* num data. */ 193 0); /* max returned data. */ 194 195 if (tevent_req_nomem(subreq, req)) { 196 return tevent_req_post(req, ev); 197 } 198 tevent_req_set_callback(subreq, cli_setpathinfo_done, req); 199 return req; 200 } 201 202 static void cli_setpathinfo_done(struct tevent_req *subreq) 203 { 204 NTSTATUS status = cli_trans_recv(subreq, NULL, NULL, NULL, 0, NULL, 205 NULL, 0, NULL, NULL, 0, NULL); 206 tevent_req_simple_finish_ntstatus(subreq, status); 207 } 208 209 NTSTATUS cli_setpathinfo_recv(struct tevent_req *req) 210 { 211 return tevent_req_simple_recv_ntstatus(req); 212 } 213 214 NTSTATUS cli_setpathinfo(struct cli_state *cli, 215 uint16_t level, 216 const char *path, 217 uint8_t *data, 218 size_t data_len) 219 { 220 TALLOC_CTX *frame = talloc_stackframe(); 221 struct tevent_context *ev; 222 struct tevent_req *req; 223 NTSTATUS status = NT_STATUS_NO_MEMORY; 224 225 if (cli_has_async_calls(cli)) { 226 /* 227 * Can't use sync call while an async call is in flight 228 */ 229 status = NT_STATUS_INVALID_PARAMETER; 230 goto fail; 231 } 232 ev = tevent_context_init(frame); 233 if (ev == NULL) { 234 goto fail; 235 } 236 req = cli_setpathinfo_send(ev, ev, cli, level, path, data, data_len); 237 if (req == NULL) { 238 goto fail; 239 } 240 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 241 goto fail; 242 } 243 status = cli_setpathinfo_recv(req); 244 fail: 245 TALLOC_FREE(frame); 246 return status; 247 } 248 109 249 /**************************************************************************** 110 250 Hard/Symlink a file (UNIX extensions). … … 112 252 ****************************************************************************/ 113 253 114 struct link_state { 115 uint16_t setup; 116 uint8_t *param; 254 struct cli_posix_link_internal_state { 117 255 uint8_t *data; 118 256 }; 119 257 120 static void cli_posix_link_internal_done(struct tevent_req *subreq) 121 { 122 struct tevent_req *req = tevent_req_callback_data( 123 subreq, struct tevent_req); 124 struct link_state *state = tevent_req_data(req, struct link_state); 125 NTSTATUS status; 126 127 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL); 128 TALLOC_FREE(subreq); 129 if (!NT_STATUS_IS_OK(status)) { 130 tevent_req_nterror(req, status); 131 return; 132 } 133 tevent_req_done(req); 134 } 258 static void cli_posix_link_internal_done(struct tevent_req *subreq); 135 259 136 260 static struct tevent_req *cli_posix_link_internal_send(TALLOC_CTX *mem_ctx, 137 261 struct event_context *ev, 138 262 struct cli_state *cli, 263 uint16_t level, 139 264 const char *oldname, 140 const char *newname, 141 bool hardlink) 265 const char *newname) 142 266 { 143 267 struct tevent_req *req = NULL, *subreq = NULL; 144 struct link_state *state = NULL; 145 146 req = tevent_req_create(mem_ctx, &state, struct link_state); 268 struct cli_posix_link_internal_state *state = NULL; 269 270 req = tevent_req_create(mem_ctx, &state, 271 struct cli_posix_link_internal_state); 147 272 if (req == NULL) { 148 273 return NULL; 149 }150 151 /* Setup setup word. */152 SSVAL(&state->setup, 0, TRANSACT2_SETPATHINFO);153 154 /* Setup param array. */155 state->param = talloc_array(state, uint8_t, 6);156 if (tevent_req_nomem(state->param, req)) {157 return tevent_req_post(req, ev);158 }159 memset(state->param, '\0', 6);160 SSVAL(state->param,0,hardlink ? SMB_SET_FILE_UNIX_HLINK : SMB_SET_FILE_UNIX_LINK);161 162 state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), newname,163 strlen(newname)+1, NULL);164 165 if (tevent_req_nomem(state->param, req)) {166 return tevent_req_post(req, ev);167 274 } 168 275 … … 172 279 return tevent_req_post(req, ev); 173 280 } 174 state->data = trans2_bytes_push_str(state->data, cli_ucs2(cli), oldname, 175 strlen(oldname)+1, NULL); 176 177 subreq = cli_trans_send(state, /* mem ctx. */ 178 ev, /* event ctx. */ 179 cli, /* cli_state. */ 180 SMBtrans2, /* cmd. */ 181 NULL, /* pipe name. */ 182 -1, /* fid. */ 183 0, /* function. */ 184 0, /* flags. */ 185 &state->setup, /* setup. */ 186 1, /* num setup uint16_t words. */ 187 0, /* max returned setup. */ 188 state->param, /* param. */ 189 talloc_get_size(state->param), /* num param. */ 190 2, /* max returned param. */ 191 state->data, /* data. */ 192 talloc_get_size(state->data), /* num data. */ 193 0); /* max returned data. */ 194 281 state->data = trans2_bytes_push_str( 282 state->data, cli_ucs2(cli), oldname, strlen(oldname)+1, NULL); 283 284 subreq = cli_setpathinfo_send( 285 state, ev, cli, level, newname, 286 state->data, talloc_get_size(state->data)); 195 287 if (tevent_req_nomem(subreq, req)) { 196 288 return tevent_req_post(req, ev); … … 198 290 tevent_req_set_callback(subreq, cli_posix_link_internal_done, req); 199 291 return req; 292 } 293 294 static void cli_posix_link_internal_done(struct tevent_req *subreq) 295 { 296 NTSTATUS status = cli_setpathinfo_recv(subreq); 297 tevent_req_simple_finish_ntstatus(subreq, status); 200 298 } 201 299 … … 210 308 const char *newname) 211 309 { 212 return cli_posix_link_internal_send( mem_ctx, ev, cli,213 oldname, newname, false);310 return cli_posix_link_internal_send( 311 mem_ctx, ev, cli, SMB_SET_FILE_UNIX_LINK, oldname, newname); 214 312 } 215 313 216 314 NTSTATUS cli_posix_symlink_recv(struct tevent_req *req) 217 315 { 218 NTSTATUS status; 219 220 if (tevent_req_is_nterror(req, &status)) { 221 return status; 222 } 223 return NT_STATUS_OK; 316 return tevent_req_simple_recv_ntstatus(req); 224 317 } 225 318 … … 277 370 278 371 struct readlink_state { 279 uint16_t setup;280 uint8_t *param;281 372 uint8_t *data; 282 373 uint32_t num_data; 283 374 }; 284 375 285 static void cli_posix_readlink_done(struct tevent_req *subreq) 286 { 287 struct tevent_req *req = tevent_req_callback_data( 288 subreq, struct tevent_req); 289 struct readlink_state *state = tevent_req_data(req, struct readlink_state); 290 NTSTATUS status; 291 292 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, 293 &state->data, &state->num_data); 294 TALLOC_FREE(subreq); 295 if (!NT_STATUS_IS_OK(status)) { 296 tevent_req_nterror(req, status); 297 return; 298 } 299 if (state->num_data == 0) { 300 tevent_req_nterror(req, NT_STATUS_DATA_ERROR); 301 return; 302 } 303 if (state->data[state->num_data-1] != '\0') { 304 tevent_req_nterror(req, NT_STATUS_DATA_ERROR); 305 return; 306 } 307 tevent_req_done(req); 308 } 376 static void cli_posix_readlink_done(struct tevent_req *subreq); 309 377 310 378 struct tevent_req *cli_posix_readlink_send(TALLOC_CTX *mem_ctx, … … 318 386 uint32_t maxbytelen = (uint32_t)(cli_ucs2(cli) ? len*3 : len); 319 387 320 if (maxbytelen < len) { 388 req = tevent_req_create(mem_ctx, &state, struct readlink_state); 389 if (req == NULL) { 321 390 return NULL; 322 391 } 323 392 324 req = tevent_req_create(mem_ctx, &state, struct readlink_state); 325 if (req == NULL) { 326 return NULL; 327 } 328 329 /* Setup setup word. */ 330 SSVAL(&state->setup, 0, TRANSACT2_QPATHINFO); 331 332 /* Setup param array. */ 333 state->param = talloc_array(state, uint8_t, 6); 334 if (tevent_req_nomem(state->param, req)) { 335 return tevent_req_post(req, ev); 336 } 337 memset(state->param, '\0', 6); 338 SSVAL(state->param,0,SMB_QUERY_FILE_UNIX_LINK); 339 340 state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname, 341 strlen(fname)+1, NULL); 342 343 if (tevent_req_nomem(state->param, req)) { 344 return tevent_req_post(req, ev); 345 } 346 347 subreq = cli_trans_send(state, /* mem ctx. */ 348 ev, /* event ctx. */ 349 cli, /* cli_state. */ 350 SMBtrans2, /* cmd. */ 351 NULL, /* pipe name. */ 352 -1, /* fid. */ 353 0, /* function. */ 354 0, /* flags. */ 355 &state->setup, /* setup. */ 356 1, /* num setup uint16_t words. */ 357 0, /* max returned setup. */ 358 state->param, /* param. */ 359 talloc_get_size(state->param), /* num param. */ 360 2, /* max returned param. */ 361 NULL, /* data. */ 362 0, /* num data. */ 363 maxbytelen); /* max returned data. */ 364 393 /* 394 * Len is in bytes, we need it in UCS2 units. 395 */ 396 if ((2*len < len) || (maxbytelen < len)) { 397 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 398 return tevent_req_post(req, ev); 399 } 400 401 subreq = cli_qpathinfo_send(state, ev, cli, fname, 402 SMB_QUERY_FILE_UNIX_LINK, 1, maxbytelen); 365 403 if (tevent_req_nomem(subreq, req)) { 366 404 return tevent_req_post(req, ev); … … 368 406 tevent_req_set_callback(subreq, cli_posix_readlink_done, req); 369 407 return req; 408 } 409 410 static void cli_posix_readlink_done(struct tevent_req *subreq) 411 { 412 struct tevent_req *req = tevent_req_callback_data( 413 subreq, struct tevent_req); 414 struct readlink_state *state = tevent_req_data( 415 req, struct readlink_state); 416 NTSTATUS status; 417 418 status = cli_qpathinfo_recv(subreq, state, &state->data, 419 &state->num_data); 420 TALLOC_FREE(subreq); 421 if (tevent_req_nterror(req, status)) { 422 return; 423 } 424 /* 425 * num_data is > 1, we've given 1 as minimum to cli_qpathinfo_send 426 */ 427 if (state->data[state->num_data-1] != '\0') { 428 tevent_req_nterror(req, NT_STATUS_DATA_ERROR); 429 return; 430 } 431 tevent_req_done(req); 370 432 } 371 433 … … 423 485 } 424 486 425 /* Len is in bytes, we need it in UCS2 units. */426 if (2*len < len) {427 status = NT_STATUS_INVALID_PARAMETER;428 goto fail;429 }430 431 487 req = cli_posix_readlink_send(frame, 432 488 ev, … … 464 520 const char *newname) 465 521 { 466 return cli_posix_link_internal_send( mem_ctx, ev, cli,467 oldname, newname, true);522 return cli_posix_link_internal_send( 523 mem_ctx, ev, cli, SMB_SET_FILE_UNIX_HLINK, oldname, newname); 468 524 } 469 525 470 526 NTSTATUS cli_posix_hardlink_recv(struct tevent_req *req) 471 527 { 472 NTSTATUS status; 473 474 if (tevent_req_is_nterror(req, &status)) { 475 return status; 476 } 477 return NT_STATUS_OK; 528 return tevent_req_simple_recv_ntstatus(req); 478 529 } 479 530 … … 625 676 626 677 struct getfacl_state { 627 uint16_t setup;628 uint8_t *param;629 678 uint32_t num_data; 630 679 uint8_t *data; 631 680 }; 632 681 633 static void cli_posix_getfacl_done(struct tevent_req *subreq) 634 { 635 struct tevent_req *req = tevent_req_callback_data( 636 subreq, struct tevent_req); 637 struct getfacl_state *state = tevent_req_data(req, struct getfacl_state); 638 NTSTATUS status; 639 640 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, 641 &state->data, &state->num_data); 642 TALLOC_FREE(subreq); 643 if (!NT_STATUS_IS_OK(status)) { 644 tevent_req_nterror(req, status); 645 return; 646 } 647 tevent_req_done(req); 648 } 682 static void cli_posix_getfacl_done(struct tevent_req *subreq); 649 683 650 684 struct tevent_req *cli_posix_getfacl_send(TALLOC_CTX *mem_ctx, … … 654 688 { 655 689 struct tevent_req *req = NULL, *subreq = NULL; 656 struct link_state *state = NULL;690 struct getfacl_state *state = NULL; 657 691 658 692 req = tevent_req_create(mem_ctx, &state, struct getfacl_state); … … 660 694 return NULL; 661 695 } 662 663 /* Setup setup word. */ 664 SSVAL(&state->setup, 0, TRANSACT2_QPATHINFO); 665 666 /* Setup param array. */ 667 state->param = talloc_array(state, uint8_t, 6); 668 if (tevent_req_nomem(state->param, req)) { 669 return tevent_req_post(req, ev); 670 } 671 memset(state->param, '\0', 6); 672 SSVAL(state->param, 0, SMB_QUERY_POSIX_ACL); 673 674 state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname, 675 strlen(fname)+1, NULL); 676 677 if (tevent_req_nomem(state->param, req)) { 678 return tevent_req_post(req, ev); 679 } 680 681 subreq = cli_trans_send(state, /* mem ctx. */ 682 ev, /* event ctx. */ 683 cli, /* cli_state. */ 684 SMBtrans2, /* cmd. */ 685 NULL, /* pipe name. */ 686 -1, /* fid. */ 687 0, /* function. */ 688 0, /* flags. */ 689 &state->setup, /* setup. */ 690 1, /* num setup uint16_t words. */ 691 0, /* max returned setup. */ 692 state->param, /* param. */ 693 talloc_get_size(state->param), /* num param. */ 694 2, /* max returned param. */ 695 NULL, /* data. */ 696 0, /* num data. */ 697 cli->max_xmit); /* max returned data. */ 698 696 subreq = cli_qpathinfo_send(state, ev, cli, fname, SMB_QUERY_POSIX_ACL, 697 0, cli->max_xmit); 699 698 if (tevent_req_nomem(subreq, req)) { 700 699 return tevent_req_post(req, ev); … … 702 701 tevent_req_set_callback(subreq, cli_posix_getfacl_done, req); 703 702 return req; 703 } 704 705 static void cli_posix_getfacl_done(struct tevent_req *subreq) 706 { 707 struct tevent_req *req = tevent_req_callback_data( 708 subreq, struct tevent_req); 709 struct getfacl_state *state = tevent_req_data( 710 req, struct getfacl_state); 711 NTSTATUS status; 712 713 status = cli_qpathinfo_recv(subreq, state, &state->data, 714 &state->num_data); 715 TALLOC_FREE(subreq); 716 if (tevent_req_nterror(req, status)) { 717 return; 718 } 719 tevent_req_done(req); 704 720 } 705 721 … … 774 790 775 791 struct stat_state { 776 uint16_t setup;777 uint8_t *param;778 792 uint32_t num_data; 779 793 uint8_t *data; 780 794 }; 795 796 static void cli_posix_stat_done(struct tevent_req *subreq); 797 798 struct tevent_req *cli_posix_stat_send(TALLOC_CTX *mem_ctx, 799 struct event_context *ev, 800 struct cli_state *cli, 801 const char *fname) 802 { 803 struct tevent_req *req = NULL, *subreq = NULL; 804 struct stat_state *state = NULL; 805 806 req = tevent_req_create(mem_ctx, &state, struct stat_state); 807 if (req == NULL) { 808 return NULL; 809 } 810 subreq = cli_qpathinfo_send(state, ev, cli, fname, 811 SMB_QUERY_FILE_UNIX_BASIC, 100, 100); 812 if (tevent_req_nomem(subreq, req)) { 813 return tevent_req_post(req, ev); 814 } 815 tevent_req_set_callback(subreq, cli_posix_stat_done, req); 816 return req; 817 } 781 818 782 819 static void cli_posix_stat_done(struct tevent_req *subreq) … … 787 824 NTSTATUS status; 788 825 789 status = cli_ trans_recv(subreq, state, NULL, NULL, NULL, NULL,790 &state->data,&state->num_data);826 status = cli_qpathinfo_recv(subreq, state, &state->data, 827 &state->num_data); 791 828 TALLOC_FREE(subreq); 792 if (!NT_STATUS_IS_OK(status)) { 793 tevent_req_nterror(req, status); 829 if (tevent_req_nterror(req, status)) { 794 830 return; 795 831 } 796 832 tevent_req_done(req); 797 }798 799 struct tevent_req *cli_posix_stat_send(TALLOC_CTX *mem_ctx,800 struct event_context *ev,801 struct cli_state *cli,802 const char *fname)803 {804 struct tevent_req *req = NULL, *subreq = NULL;805 struct stat_state *state = NULL;806 807 req = tevent_req_create(mem_ctx, &state, struct stat_state);808 if (req == NULL) {809 return NULL;810 }811 812 /* Setup setup word. */813 SSVAL(&state->setup, 0, TRANSACT2_QPATHINFO);814 815 /* Setup param array. */816 state->param = talloc_array(state, uint8_t, 6);817 if (tevent_req_nomem(state->param, req)) {818 return tevent_req_post(req, ev);819 }820 memset(state->param, '\0', 6);821 SSVAL(state->param, 0, SMB_QUERY_FILE_UNIX_BASIC);822 823 state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname,824 strlen(fname)+1, NULL);825 826 if (tevent_req_nomem(state->param, req)) {827 return tevent_req_post(req, ev);828 }829 830 subreq = cli_trans_send(state, /* mem ctx. */831 ev, /* event ctx. */832 cli, /* cli_state. */833 SMBtrans2, /* cmd. */834 NULL, /* pipe name. */835 -1, /* fid. */836 0, /* function. */837 0, /* flags. */838 &state->setup, /* setup. */839 1, /* num setup uint16_t words. */840 0, /* max returned setup. */841 state->param, /* param. */842 talloc_get_size(state->param), /* num param. */843 2, /* max returned param. */844 NULL, /* data. */845 0, /* num data. */846 96); /* max returned data. */847 848 if (tevent_req_nomem(subreq, req)) {849 return tevent_req_post(req, ev);850 }851 tevent_req_set_callback(subreq, cli_posix_stat_done, req);852 return req;853 833 } 854 834 … … 861 841 if (tevent_req_is_nterror(req, &status)) { 862 842 return status; 863 }864 865 if (state->num_data != 96) {866 return NT_STATUS_DATA_ERROR;867 843 } 868 844 … … 891 867 sbuf->st_ex_ino = (SMB_INO_T)IVAL2_TO_SMB_BIG_UINT(state->data,76); /* inode */ 892 868 sbuf->st_ex_mode |= wire_perms_to_unix(IVAL(state->data,84)); /* protection */ 893 sbuf->st_ex_nlink = IVAL(state->data,92);/* number of hard links */869 sbuf->st_ex_nlink = BIG_UINT(state->data,92); /* number of hard links */ 894 870 895 871 return NT_STATUS_OK; … … 947 923 ****************************************************************************/ 948 924 949 struct ch_state { 950 uint16_t setup; 951 uint8_t *param; 952 uint8_t *data; 925 struct cli_posix_chown_chmod_internal_state { 926 uint8_t data[100]; 953 927 }; 954 928 955 static void cli_posix_chown_chmod_internal_done(struct tevent_req *subreq) 956 { 957 struct tevent_req *req = tevent_req_callback_data( 958 subreq, struct tevent_req); 959 struct ch_state *state = tevent_req_data(req, struct ch_state); 960 NTSTATUS status; 961 962 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL); 963 TALLOC_FREE(subreq); 964 if (!NT_STATUS_IS_OK(status)) { 965 tevent_req_nterror(req, status); 966 return; 967 } 968 tevent_req_done(req); 969 } 929 static void cli_posix_chown_chmod_internal_done(struct tevent_req *subreq); 970 930 971 931 static struct tevent_req *cli_posix_chown_chmod_internal_send(TALLOC_CTX *mem_ctx, … … 978 938 { 979 939 struct tevent_req *req = NULL, *subreq = NULL; 980 struct ch_state *state = NULL; 981 982 req = tevent_req_create(mem_ctx, &state, struct ch_state); 940 struct cli_posix_chown_chmod_internal_state *state = NULL; 941 942 req = tevent_req_create(mem_ctx, &state, 943 struct cli_posix_chown_chmod_internal_state); 983 944 if (req == NULL) { 984 945 return NULL; 985 946 } 986 947 987 /* Setup setup word. */988 SSVAL(&state->setup, 0, TRANSACT2_SETPATHINFO);989 990 /* Setup param array. */991 state->param = talloc_array(state, uint8_t, 6);992 if (tevent_req_nomem(state->param, req)) {993 return tevent_req_post(req, ev);994 }995 memset(state->param, '\0', 6);996 SSVAL(state->param,0,SMB_SET_FILE_UNIX_BASIC);997 998 state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname,999 strlen(fname)+1, NULL);1000 1001 if (tevent_req_nomem(state->param, req)) {1002 return tevent_req_post(req, ev);1003 }1004 1005 /* Setup data array. */1006 state->data = talloc_array(state, uint8_t, 100);1007 if (tevent_req_nomem(state->data, req)) {1008 return tevent_req_post(req, ev);1009 }1010 948 memset(state->data, 0xff, 40); /* Set all sizes/times to no change. */ 1011 949 memset(&state->data[40], '\0', 60); … … 1014 952 SIVAL(state->data,84,mode); 1015 953 1016 subreq = cli_trans_send(state, /* mem ctx. */ 1017 ev, /* event ctx. */ 1018 cli, /* cli_state. */ 1019 SMBtrans2, /* cmd. */ 1020 NULL, /* pipe name. */ 1021 -1, /* fid. */ 1022 0, /* function. */ 1023 0, /* flags. */ 1024 &state->setup, /* setup. */ 1025 1, /* num setup uint16_t words. */ 1026 0, /* max returned setup. */ 1027 state->param, /* param. */ 1028 talloc_get_size(state->param), /* num param. */ 1029 2, /* max returned param. */ 1030 state->data, /* data. */ 1031 talloc_get_size(state->data), /* num data. */ 1032 0); /* max returned data. */ 1033 954 subreq = cli_setpathinfo_send(state, ev, cli, SMB_SET_FILE_UNIX_BASIC, 955 fname, state->data, sizeof(state->data)); 1034 956 if (tevent_req_nomem(subreq, req)) { 1035 957 return tevent_req_post(req, ev); 1036 958 } 1037 tevent_req_set_callback(subreq, cli_posix_chown_chmod_internal_done, req); 959 tevent_req_set_callback(subreq, cli_posix_chown_chmod_internal_done, 960 req); 1038 961 return req; 962 } 963 964 static void cli_posix_chown_chmod_internal_done(struct tevent_req *subreq) 965 { 966 NTSTATUS status = cli_setpathinfo_recv(subreq); 967 tevent_req_simple_finish_ntstatus(subreq, status); 1039 968 } 1040 969 … … 1058 987 NTSTATUS cli_posix_chmod_recv(struct tevent_req *req) 1059 988 { 1060 NTSTATUS status; 1061 1062 if (tevent_req_is_nterror(req, &status)) { 1063 return status; 1064 } 1065 return NT_STATUS_OK; 989 return tevent_req_simple_recv_ntstatus(req); 1066 990 } 1067 991 … … 1132 1056 NTSTATUS cli_posix_chown_recv(struct tevent_req *req) 1133 1057 { 1134 NTSTATUS status; 1135 1136 if (tevent_req_is_nterror(req, &status)) { 1137 return status; 1138 } 1139 return NT_STATUS_OK; 1058 return tevent_req_simple_recv_ntstatus(req); 1140 1059 } 1141 1060 … … 1216 1135 } 1217 1136 1218 SSVAL(state->vwv+0, 0, aSYSTEM | aHIDDEN | aDIR);1137 SSVAL(state->vwv+0, 0, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY); 1219 1138 1220 1139 bytes = talloc_array(state, uint8_t, 1); … … 1257 1176 NTSTATUS status; 1258 1177 1259 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);1178 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 1260 1179 TALLOC_FREE(subreq); 1261 if (!NT_STATUS_IS_OK(status)) { 1262 tevent_req_nterror(req, status); 1180 if (tevent_req_nterror(req, status)) { 1263 1181 return; 1264 1182 } … … 1341 1259 } 1342 1260 1343 SSVAL(state->vwv+0, 0 , aSYSTEM | aHIDDEN | aDIR);1261 SSVAL(state->vwv+0, 0 ,FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY); 1344 1262 SSVAL(state->vwv+1, 0, rename_flag); 1345 1263 … … 1383 1301 NTSTATUS status; 1384 1302 1385 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);1303 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 1386 1304 TALLOC_FREE(subreq); 1387 if (!NT_STATUS_IS_OK(status)) { 1388 tevent_req_nterror(req, status); 1305 if (tevent_req_nterror(req, status)) { 1389 1306 return; 1390 1307 } … … 1578 1495 NTSTATUS status; 1579 1496 1580 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);1497 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 1581 1498 TALLOC_FREE(subreq); 1582 if (!NT_STATUS_IS_OK(status)) { 1583 tevent_req_nterror(req, status); 1499 if (tevent_req_nterror(req, status)) { 1584 1500 return; 1585 1501 } … … 1686 1602 NTSTATUS status; 1687 1603 1688 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);1604 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 1689 1605 TALLOC_FREE(subreq); 1690 if (!NT_STATUS_IS_OK(status)) { 1691 tevent_req_nterror(req, status); 1606 if (tevent_req_nterror(req, status)) { 1692 1607 return; 1693 1608 } … … 1794 1709 NTSTATUS status; 1795 1710 1796 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);1711 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 1797 1712 TALLOC_FREE(subreq); 1798 if (!NT_STATUS_IS_OK(status)) { 1799 tevent_req_nterror(req, status); 1713 if (tevent_req_nterror(req, status)) { 1800 1714 return; 1801 1715 } … … 1862 1776 static void cli_nt_delete_on_close_done(struct tevent_req *subreq) 1863 1777 { 1864 struct tevent_req *req = tevent_req_callback_data( 1865 subreq, struct tevent_req); 1866 struct doc_state *state = tevent_req_data(req, struct doc_state); 1867 NTSTATUS status; 1868 1869 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL); 1870 TALLOC_FREE(subreq); 1871 if (!NT_STATUS_IS_OK(status)) { 1872 tevent_req_nterror(req, status); 1873 return; 1874 } 1875 tevent_req_done(req); 1778 NTSTATUS status = cli_trans_recv(subreq, NULL, NULL, NULL, 0, NULL, 1779 NULL, 0, NULL, NULL, 0, NULL); 1780 tevent_req_simple_finish_ntstatus(subreq, status); 1876 1781 } 1877 1782 … … 1927 1832 NTSTATUS cli_nt_delete_on_close_recv(struct tevent_req *req) 1928 1833 { 1929 NTSTATUS status; 1930 1931 if (tevent_req_is_nterror(req, &status)) { 1932 return status; 1933 } 1934 return NT_STATUS_OK; 1834 return tevent_req_simple_recv_ntstatus(req); 1935 1835 } 1936 1836 … … 2066 1966 uint32_t num_bytes; 2067 1967 uint8_t *bytes; 1968 uint8_t *inbuf; 2068 1969 NTSTATUS status; 2069 1970 2070 status = cli_smb_recv(subreq, 3, &wct, &vwv, &num_bytes, &bytes);2071 if (!NT_STATUS_IS_OK(status)) {2072 2073 tevent_req_nterror(req, status);1971 status = cli_smb_recv(subreq, state, &inbuf, 3, &wct, &vwv, 1972 &num_bytes, &bytes); 1973 TALLOC_FREE(subreq); 1974 if (tevent_req_nterror(req, status)) { 2074 1975 return; 2075 1976 } … … 2209 2110 SSVAL(state->vwv + 2, 0, 0); /* no additional info */ 2210 2111 SSVAL(state->vwv + 3, 0, accessmode); 2211 SSVAL(state->vwv + 4, 0, aSYSTEM | aHIDDEN);2112 SSVAL(state->vwv + 4, 0, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); 2212 2113 SSVAL(state->vwv + 5, 0, 0); 2213 2114 SIVAL(state->vwv + 6, 0, 0); … … 2263 2164 2264 2165 status = cli_smb_req_send(subreq); 2265 if (!NT_STATUS_IS_OK(status)) { 2266 tevent_req_nterror(req, status); 2166 if (tevent_req_nterror(req, status)) { 2267 2167 return tevent_req_post(req, ev); 2268 2168 } … … 2278 2178 uint8_t wct; 2279 2179 uint16_t *vwv; 2180 uint8_t *inbuf; 2280 2181 NTSTATUS status; 2281 2182 2282 status = cli_smb_recv(subreq, 3, &wct, &vwv, NULL, NULL);2283 if (!NT_STATUS_IS_OK(status)) {2284 2285 tevent_req_nterror(req, status);2183 status = cli_smb_recv(subreq, state, &inbuf, 3, &wct, &vwv, NULL, 2184 NULL); 2185 TALLOC_FREE(subreq); 2186 if (tevent_req_nterror(req, status)) { 2286 2187 return; 2287 2188 } … … 2397 2298 2398 2299 status = cli_smb_req_send(subreq); 2399 if (!NT_STATUS_IS_OK(status)) { 2400 tevent_req_nterror(req, status); 2300 if (tevent_req_nterror(req, status)) { 2401 2301 return tevent_req_post(req, ev); 2402 2302 } … … 2410 2310 NTSTATUS status; 2411 2311 2412 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);2312 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 2413 2313 TALLOC_FREE(subreq); 2414 if (!NT_STATUS_IS_OK(status)) { 2415 tevent_req_nterror(req, status); 2314 if (tevent_req_nterror(req, status)) { 2416 2315 return; 2417 2316 } … … 2477 2376 static void cli_ftruncate_done(struct tevent_req *subreq) 2478 2377 { 2479 struct tevent_req *req = tevent_req_callback_data( 2480 subreq, struct tevent_req); 2481 struct ftrunc_state *state = tevent_req_data(req, struct ftrunc_state); 2482 NTSTATUS status; 2483 2484 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL); 2485 TALLOC_FREE(subreq); 2486 if (!NT_STATUS_IS_OK(status)) { 2487 tevent_req_nterror(req, status); 2488 return; 2489 } 2490 tevent_req_done(req); 2378 NTSTATUS status = cli_trans_recv(subreq, NULL, NULL, NULL, 0, NULL, 2379 NULL, 0, NULL, NULL, 0, NULL); 2380 tevent_req_simple_finish_ntstatus(subreq, status); 2491 2381 } 2492 2382 … … 2543 2433 NTSTATUS cli_ftruncate_recv(struct tevent_req *req) 2544 2434 { 2545 NTSTATUS status; 2546 2547 if (tevent_req_is_nterror(req, &status)) { 2548 return status; 2549 } 2550 return NT_STATUS_OK; 2435 return tevent_req_simple_recv_ntstatus(req); 2551 2436 } 2552 2437 … … 2606 2491 int timeout, unsigned char locktype) 2607 2492 { 2608 char *p; 2609 int saved_timeout = cli->timeout; 2610 2611 memset(cli->outbuf,'\0',smb_size); 2612 memset(cli->inbuf,'\0', smb_size); 2613 2614 cli_set_message(cli->outbuf,8,0,True); 2615 2616 SCVAL(cli->outbuf,smb_com,SMBlockingX); 2617 SSVAL(cli->outbuf,smb_tid,cli->cnum); 2618 cli_setup_packet(cli); 2619 2620 SCVAL(cli->outbuf,smb_vwv0,0xFF); 2621 SSVAL(cli->outbuf,smb_vwv2,fnum); 2622 SCVAL(cli->outbuf,smb_vwv3,locktype); 2623 SIVALS(cli->outbuf, smb_vwv4, timeout); 2624 SSVAL(cli->outbuf,smb_vwv6,0); 2625 SSVAL(cli->outbuf,smb_vwv7,1); 2626 2627 p = smb_buf(cli->outbuf); 2628 SSVAL(p, 0, cli->pid); 2629 SIVAL(p, 2, offset); 2630 SIVAL(p, 6, len); 2631 2632 p += 10; 2633 2634 cli_setup_bcc(cli, p); 2635 2636 cli_send_smb(cli); 2493 uint16_t vwv[8]; 2494 uint8_t bytes[10]; 2495 NTSTATUS status; 2496 int saved_timeout; 2497 2498 SCVAL(vwv + 0, 0, 0xff); 2499 SCVAL(vwv + 0, 1, 0); 2500 SSVAL(vwv + 1, 0, 0); 2501 SSVAL(vwv + 2, 0, fnum); 2502 SCVAL(vwv + 3, 0, locktype); 2503 SCVAL(vwv + 3, 1, 0); 2504 SIVALS(vwv + 4, 0, timeout); 2505 SSVAL(vwv + 6, 0, 0); 2506 SSVAL(vwv + 7, 0, 1); 2507 2508 SSVAL(bytes, 0, cli->pid); 2509 SIVAL(bytes, 2, offset); 2510 SIVAL(bytes, 6, len); 2511 2512 saved_timeout = cli->timeout; 2637 2513 2638 2514 if (timeout != 0) { 2639 cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); 2640 } 2641 2642 if (!cli_receive_smb(cli)) { 2643 cli->timeout = saved_timeout; 2644 return NT_STATUS_UNSUCCESSFUL; 2645 } 2515 cli->timeout = (timeout == -1) 2516 ? 0x7FFFFFFF : (timeout + 2*1000); 2517 } 2518 2519 status = cli_smb(talloc_tos(), cli, SMBlockingX, 0, 8, vwv, 2520 10, bytes, NULL, 0, NULL, NULL, NULL, NULL); 2646 2521 2647 2522 cli->timeout = saved_timeout; 2648 2523 2649 return cli_nt_error(cli);2524 return status; 2650 2525 } 2651 2526 … … 2656 2531 2657 2532 bool cli_lock(struct cli_state *cli, uint16_t fnum, 2658 uint32_t offset, uint32_t len, int timeout, enum brl_type lock_type) 2659 { 2660 char *p; 2661 int saved_timeout = cli->timeout; 2662 2663 memset(cli->outbuf,'\0',smb_size); 2664 memset(cli->inbuf,'\0', smb_size); 2665 2666 cli_set_message(cli->outbuf,8,0,True); 2667 2668 SCVAL(cli->outbuf,smb_com,SMBlockingX); 2669 SSVAL(cli->outbuf,smb_tid,cli->cnum); 2670 cli_setup_packet(cli); 2671 2672 SCVAL(cli->outbuf,smb_vwv0,0xFF); 2673 SSVAL(cli->outbuf,smb_vwv2,fnum); 2674 SCVAL(cli->outbuf,smb_vwv3,(lock_type == READ_LOCK? 1 : 0)); 2675 SIVALS(cli->outbuf, smb_vwv4, timeout); 2676 SSVAL(cli->outbuf,smb_vwv6,0); 2677 SSVAL(cli->outbuf,smb_vwv7,1); 2678 2679 p = smb_buf(cli->outbuf); 2680 SSVAL(p, 0, cli->pid); 2681 SIVAL(p, 2, offset); 2682 SIVAL(p, 6, len); 2683 2684 p += 10; 2685 2686 cli_setup_bcc(cli, p); 2687 2688 cli_send_smb(cli); 2689 2690 if (timeout != 0) { 2691 cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout*2 + 5*1000); 2692 } 2693 2694 if (!cli_receive_smb(cli)) { 2695 cli->timeout = saved_timeout; 2696 return False; 2697 } 2698 2699 cli->timeout = saved_timeout; 2700 2701 if (cli_is_error(cli)) { 2702 return False; 2703 } 2704 2705 return True; 2533 uint32_t offset, uint32_t len, int timeout, 2534 enum brl_type lock_type) 2535 { 2536 NTSTATUS status; 2537 2538 status = cli_locktype(cli, fnum, offset, len, timeout, 2539 (lock_type == READ_LOCK? 1 : 0)); 2540 cli_set_error(cli, status); 2541 return NT_STATUS_IS_OK(status); 2706 2542 } 2707 2543 … … 2760 2596 NTSTATUS status; 2761 2597 2762 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);2598 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 2763 2599 TALLOC_FREE(subreq); 2764 if (!NT_STATUS_IS_OK(status)) { 2765 tevent_req_nterror(req, status); 2600 if (tevent_req_nterror(req, status)) { 2766 2601 return; 2767 2602 } … … 2825 2660 2826 2661 bool cli_lock64(struct cli_state *cli, uint16_t fnum, 2827 uint64_t offset, uint64_t len, int timeout, enum brl_type lock_type) 2828 { 2829 char *p; 2662 uint64_t offset, uint64_t len, int timeout, 2663 enum brl_type lock_type) 2664 { 2665 uint16_t vwv[8]; 2666 uint8_t bytes[20]; 2830 2667 int saved_timeout = cli->timeout; 2831 2668 int ltype; 2669 NTSTATUS status; 2832 2670 2833 2671 if (! (cli->capabilities & CAP_LARGE_FILES)) { … … 2838 2676 ltype |= LOCKING_ANDX_LARGE_FILES; 2839 2677 2840 memset(cli->outbuf,'\0',smb_size); 2841 memset(cli->inbuf,'\0', smb_size); 2842 2843 cli_set_message(cli->outbuf,8,0,True); 2844 2845 SCVAL(cli->outbuf,smb_com,SMBlockingX); 2846 SSVAL(cli->outbuf,smb_tid,cli->cnum); 2847 cli_setup_packet(cli); 2848 2849 SCVAL(cli->outbuf,smb_vwv0,0xFF); 2850 SSVAL(cli->outbuf,smb_vwv2,fnum); 2851 SCVAL(cli->outbuf,smb_vwv3,ltype); 2852 SIVALS(cli->outbuf, smb_vwv4, timeout); 2853 SSVAL(cli->outbuf,smb_vwv6,0); 2854 SSVAL(cli->outbuf,smb_vwv7,1); 2855 2856 p = smb_buf(cli->outbuf); 2857 SIVAL(p, 0, cli->pid); 2858 SOFF_T_R(p, 4, offset); 2859 SOFF_T_R(p, 12, len); 2860 p += 20; 2861 2862 cli_setup_bcc(cli, p); 2863 cli_send_smb(cli); 2678 SCVAL(vwv + 0, 0, 0xff); 2679 SCVAL(vwv + 0, 1, 0); 2680 SSVAL(vwv + 1, 0, 0); 2681 SSVAL(vwv + 2, 0, fnum); 2682 SCVAL(vwv + 3, 0, ltype); 2683 SCVAL(vwv + 3, 1, 0); 2684 SIVALS(vwv + 4, 0, timeout); 2685 SSVAL(vwv + 6, 0, 0); 2686 SSVAL(vwv + 7, 0, 1); 2687 2688 SIVAL(bytes, 0, cli->pid); 2689 SOFF_T_R(bytes, 4, offset); 2690 SOFF_T_R(bytes, 12, len); 2691 2692 saved_timeout = cli->timeout; 2864 2693 2865 2694 if (timeout != 0) { 2866 cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 5*1000); 2867 } 2868 2869 if (!cli_receive_smb(cli)) { 2870 cli->timeout = saved_timeout; 2871 return False; 2872 } 2695 cli->timeout = (timeout == -1) 2696 ? 0x7FFFFFFF : (timeout + 2*1000); 2697 } 2698 2699 status = cli_smb(talloc_tos(), cli, SMBlockingX, 0, 8, vwv, 2700 20, bytes, NULL, 0, NULL, NULL, NULL, NULL); 2873 2701 2874 2702 cli->timeout = saved_timeout; 2875 2703 2876 if (cli_is_error(cli)) { 2877 return False; 2878 } 2879 2880 return True; 2704 cli_set_error(cli, status); 2705 return NT_STATUS_IS_OK(status); 2881 2706 } 2882 2707 … … 2935 2760 NTSTATUS status; 2936 2761 2937 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);2762 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 2938 2763 TALLOC_FREE(subreq); 2939 if (!NT_STATUS_IS_OK(status)) { 2940 tevent_req_nterror(req, status); 2764 if (tevent_req_nterror(req, status)) { 2941 2765 return; 2942 2766 } … … 3011 2835 static void cli_posix_unlock_internal_done(struct tevent_req *subreq) 3012 2836 { 3013 struct tevent_req *req = tevent_req_callback_data( 3014 subreq, struct tevent_req); 3015 struct posix_lock_state *state = tevent_req_data(req, struct posix_lock_state); 3016 NTSTATUS status; 3017 3018 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL); 3019 TALLOC_FREE(subreq); 3020 if (!NT_STATUS_IS_OK(status)) { 3021 tevent_req_nterror(req, status); 3022 return; 3023 } 3024 tevent_req_done(req); 2837 NTSTATUS status = cli_trans_recv(subreq, NULL, NULL, NULL, 0, NULL, 2838 NULL, 0, NULL, NULL, 0, NULL); 2839 tevent_req_simple_finish_ntstatus(subreq, status); 3025 2840 } 3026 2841 … … 3123 2938 NTSTATUS cli_posix_lock_recv(struct tevent_req *req) 3124 2939 { 3125 NTSTATUS status; 3126 3127 if (tevent_req_is_nterror(req, &status)) { 3128 return status; 3129 } 3130 return NT_STATUS_OK; 2940 return tevent_req_simple_recv_ntstatus(req); 3131 2941 } 3132 2942 … … 3204 3014 NTSTATUS cli_posix_unlock_recv(struct tevent_req *req) 3205 3015 { 3206 NTSTATUS status; 3207 3208 if (tevent_req_is_nterror(req, &status)) { 3209 return status; 3210 } 3211 return NT_STATUS_OK; 3016 return tevent_req_simple_recv_ntstatus(req); 3212 3017 } 3213 3018 … … 3309 3114 uint8_t wct; 3310 3115 uint16_t *vwv = NULL; 3116 uint8_t *inbuf; 3311 3117 NTSTATUS status; 3312 3118 3313 status = cli_smb_recv(subreq, 11, &wct, &vwv, NULL, NULL); 3314 if (!NT_STATUS_IS_OK(status)) { 3315 tevent_req_nterror(req, status); 3119 status = cli_smb_recv(subreq, state, &inbuf, 11, &wct, &vwv, 3120 NULL, NULL); 3121 TALLOC_FREE(subreq); 3122 if (tevent_req_nterror(req, status)) { 3316 3123 return; 3317 3124 } … … 3323 3130 state->write_time = make_unix_date2(vwv+4, state->zone_offset); 3324 3131 3325 TALLOC_FREE(subreq);3326 3132 tevent_req_done(req); 3327 3133 } … … 3471 3277 uint8_t wct; 3472 3278 uint16_t *vwv = NULL; 3279 uint8_t *inbuf; 3473 3280 NTSTATUS status; 3474 3281 3475 status = cli_smb_recv(subreq, 4, &wct, &vwv, NULL, NULL); 3476 if (!NT_STATUS_IS_OK(status)) { 3477 tevent_req_nterror(req, status); 3282 status = cli_smb_recv(subreq, state, &inbuf, 4, &wct, &vwv, NULL, 3283 NULL); 3284 TALLOC_FREE(subreq); 3285 if (tevent_req_nterror(req, status)) { 3478 3286 return; 3479 3287 } … … 3483 3291 state->write_time = make_unix_date3(vwv+1, state->zone_offset); 3484 3292 3485 TALLOC_FREE(subreq);3486 3293 tevent_req_done(req); 3487 3294 } … … 3588 3395 3589 3396 SSVAL(state->vwv+0, 0, fnum); 3590 cli_put_dos_date2(cli, (char *)&state->vwv[1], 0, change_time); 3591 cli_put_dos_date2(cli, (char *)&state->vwv[3], 0, access_time); 3592 cli_put_dos_date2(cli, (char *)&state->vwv[5], 0, write_time); 3397 push_dos_date2((uint8_t *)&state->vwv[1], 0, change_time, 3398 cli->serverzone); 3399 push_dos_date2((uint8_t *)&state->vwv[3], 0, access_time, 3400 cli->serverzone); 3401 push_dos_date2((uint8_t *)&state->vwv[5], 0, write_time, 3402 cli->serverzone); 3593 3403 3594 3404 subreq = cli_smb_send(state, ev, cli, SMBsetattrE, additional_flags, … … 3607 3417 NTSTATUS status; 3608 3418 3609 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);3419 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 3610 3420 TALLOC_FREE(subreq); 3611 if (!NT_STATUS_IS_OK(status)) { 3612 tevent_req_nterror(req, status); 3421 if (tevent_req_nterror(req, status)) { 3613 3422 return; 3614 3423 } … … 3701 3510 3702 3511 SSVAL(state->vwv+0, 0, attr); 3703 cli_put_dos_date3(cli, (char *)&state->vwv[1], 0, mtime);3512 push_dos_date3((uint8_t *)&state->vwv[1], 0, mtime, cli->serverzone); 3704 3513 3705 3514 bytes = talloc_array(state, uint8_t, 1); … … 3741 3550 NTSTATUS status; 3742 3551 3743 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);3552 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 3744 3553 TALLOC_FREE(subreq); 3745 if (!NT_STATUS_IS_OK(status)) { 3746 tevent_req_nterror(req, status); 3554 if (tevent_req_nterror(req, status)) { 3747 3555 return; 3748 3556 } … … 3852 3660 NTSTATUS status; 3853 3661 3854 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);3662 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 3855 3663 TALLOC_FREE(subreq); 3856 if (!NT_STATUS_IS_OK(status)) { 3857 tevent_req_nterror(req, status); 3664 if (tevent_req_nterror(req, status)) { 3858 3665 return; 3859 3666 } … … 3965 3772 uint8_t wct; 3966 3773 uint16_t *vwv = NULL; 3774 uint8_t *inbuf; 3967 3775 NTSTATUS status; 3968 3776 3969 status = cli_smb_recv(subreq, 4, &wct, &vwv, NULL, NULL); 3970 if (!NT_STATUS_IS_OK(status)) { 3971 tevent_req_nterror(req, status); 3777 status = cli_smb_recv(subreq, state, &inbuf, 4, &wct, &vwv, NULL, 3778 NULL); 3779 TALLOC_FREE(subreq); 3780 if (tevent_req_nterror(req, status)) { 3972 3781 return; 3973 3782 } … … 3975 3784 state->total = SVAL(vwv+0, 0); 3976 3785 state->avail = SVAL(vwv+3, 0); 3977 TALLOC_FREE(subreq);3978 3786 tevent_req_done(req); 3979 3787 } … … 4097 3905 uint32_t num_bytes = 0; 4098 3906 uint8_t *bytes = NULL; 4099 4100 status = cli_smb_recv(subreq, 1, &wcnt, &vwv, &num_bytes, &bytes); 4101 if (!NT_STATUS_IS_OK(status)) { 4102 TALLOC_FREE(subreq); 4103 tevent_req_nterror(req, status); 3907 uint8_t *inbuf; 3908 3909 status = cli_smb_recv(subreq, state, &inbuf, 1, &wcnt, &vwv, 3910 &num_bytes, &bytes); 3911 TALLOC_FREE(subreq); 3912 if (tevent_req_nterror(req, status)) { 4104 3913 return; 4105 3914 } 4106 3915 4107 3916 state->fnum = SVAL(vwv+0, 0); 4108 4109 TALLOC_FREE(subreq);4110 3917 4111 3918 /* From W2K3, the result is just the ASCII name */ … … 4199 4006 NTSTATUS cli_raw_ioctl(struct cli_state *cli, uint16_t fnum, uint32_t code, DATA_BLOB *blob) 4200 4007 { 4201 memset(cli->outbuf,'\0',smb_size); 4202 memset(cli->inbuf,'\0',smb_size); 4203 4204 cli_set_message(cli->outbuf, 3, 0, True); 4205 SCVAL(cli->outbuf,smb_com,SMBioctl); 4206 cli_setup_packet(cli); 4207 4208 SSVAL(cli->outbuf, smb_vwv0, fnum); 4209 SSVAL(cli->outbuf, smb_vwv1, code>>16); 4210 SSVAL(cli->outbuf, smb_vwv2, (code&0xFFFF)); 4211 4212 cli_send_smb(cli); 4213 if (!cli_receive_smb(cli)) { 4214 return NT_STATUS_UNEXPECTED_NETWORK_ERROR; 4215 } 4216 4217 if (cli_is_error(cli)) { 4218 return cli_nt_error(cli); 4219 } 4220 4008 uint16_t vwv[3]; 4009 NTSTATUS status; 4010 4011 SSVAL(vwv+0, 0, fnum); 4012 SSVAL(vwv+1, 0, code>>16); 4013 SSVAL(vwv+2, 0, (code&0xFFFF)); 4014 4015 status = cli_smb(talloc_tos(), cli, SMBioctl, 0, 3, vwv, 0, NULL, 4016 NULL, 0, NULL, NULL, NULL, NULL); 4017 if (!NT_STATUS_IS_OK(status)) { 4018 return status; 4019 } 4221 4020 *blob = data_blob_null; 4222 4223 4021 return NT_STATUS_OK; 4224 4022 } … … 4228 4026 *********************************************************/ 4229 4027 4230 static bool cli_set_ea(struct cli_state *cli, uint16_t setup, char *param, unsigned int param_len, 4231 const char *ea_name, const char *ea_val, size_t ea_len) 4232 { 4028 static NTSTATUS cli_set_ea(struct cli_state *cli, uint16_t setup_val, 4029 uint8_t *param, unsigned int param_len, 4030 const char *ea_name, 4031 const char *ea_val, size_t ea_len) 4032 { 4033 uint16_t setup[1]; 4233 4034 unsigned int data_len = 0; 4234 char *data = NULL; 4235 char *rparam=NULL, *rdata=NULL; 4035 uint8_t *data = NULL; 4236 4036 char *p; 4237 4037 size_t ea_namelen = strlen(ea_name); 4038 NTSTATUS status; 4039 4040 SSVAL(setup, 0, setup_val); 4238 4041 4239 4042 if (ea_namelen == 0 && ea_len == 0) { 4240 4043 data_len = 4; 4241 data = ( char*)SMB_MALLOC(data_len);4044 data = (uint8_t *)SMB_MALLOC(data_len); 4242 4045 if (!data) { 4243 return False;4046 return NT_STATUS_NO_MEMORY; 4244 4047 } 4245 p = data;4048 p = (char *)data; 4246 4049 SIVAL(p,0,data_len); 4247 4050 } else { 4248 4051 data_len = 4 + 4 + ea_namelen + 1 + ea_len; 4249 data = ( char*)SMB_MALLOC(data_len);4052 data = (uint8_t *)SMB_MALLOC(data_len); 4250 4053 if (!data) { 4251 return False;4054 return NT_STATUS_NO_MEMORY; 4252 4055 } 4253 p = data;4056 p = (char *)data; 4254 4057 SIVAL(p,0,data_len); 4255 4058 p += 4; … … 4261 4064 } 4262 4065 4263 if (!cli_send_trans(cli, SMBtrans2, 4264 NULL, /* name */ 4265 -1, 0, /* fid, flags */ 4266 &setup, 1, 0, /* setup, length, max */ 4267 param, param_len, 2, /* param, length, max */ 4268 data, data_len, cli->max_xmit /* data, length, max */ 4269 )) { 4270 SAFE_FREE(data); 4271 return False; 4272 } 4273 4274 if (!cli_receive_trans(cli, SMBtrans2, 4275 &rparam, ¶m_len, 4276 &rdata, &data_len)) { 4277 SAFE_FREE(data); 4278 return false; 4279 } 4280 4066 status = cli_trans(talloc_tos(), cli, SMBtrans2, NULL, -1, 0, 0, 4067 setup, 1, 0, 4068 param, param_len, 2, 4069 data, data_len, cli->max_xmit, 4070 NULL, 4071 NULL, 0, NULL, /* rsetup */ 4072 NULL, 0, NULL, /* rparam */ 4073 NULL, 0, NULL); /* rdata */ 4281 4074 SAFE_FREE(data); 4282 SAFE_FREE(rdata); 4283 SAFE_FREE(rparam); 4284 4285 return True; 4075 return status; 4286 4076 } 4287 4077 … … 4290 4080 *********************************************************/ 4291 4081 4292 bool cli_set_ea_path(struct cli_state *cli, const char *path, const char *ea_name, const char *ea_val, size_t ea_len) 4293 { 4294 uint16_t setup = TRANSACT2_SETPATHINFO; 4082 NTSTATUS cli_set_ea_path(struct cli_state *cli, const char *path, 4083 const char *ea_name, const char *ea_val, 4084 size_t ea_len) 4085 { 4295 4086 unsigned int param_len = 0; 4296 char*param;4087 uint8_t *param; 4297 4088 size_t srclen = 2*(strlen(path)+1); 4298 4089 char *p; 4299 bool ret;4300 4301 param = SMB_MALLOC_ARRAY( char, 6+srclen+2);4090 NTSTATUS status; 4091 4092 param = SMB_MALLOC_ARRAY(uint8_t, 6+srclen+2); 4302 4093 if (!param) { 4303 return false;4094 return NT_STATUS_NO_MEMORY; 4304 4095 } 4305 4096 memset(param, '\0', 6); 4306 4097 SSVAL(param,0,SMB_INFO_SET_EA); 4307 p = ¶m[6];4098 p = (char *)(¶m[6]); 4308 4099 4309 4100 p += clistr_push(cli, p, path, srclen, STR_TERMINATE); 4310 4101 param_len = PTR_DIFF(p, param); 4311 4102 4312 ret = cli_set_ea(cli, setup, param, param_len, ea_name, ea_val, ea_len); 4103 status = cli_set_ea(cli, TRANSACT2_SETPATHINFO, param, param_len, 4104 ea_name, ea_val, ea_len); 4313 4105 SAFE_FREE(param); 4314 return ret;4106 return status; 4315 4107 } 4316 4108 … … 4319 4111 *********************************************************/ 4320 4112 4321 bool cli_set_ea_fnum(struct cli_state *cli, uint16_t fnum, const char *ea_name, const char *ea_val, size_t ea_len) 4322 { 4323 char param[6]; 4324 uint16_t setup = TRANSACT2_SETFILEINFO; 4113 NTSTATUS cli_set_ea_fnum(struct cli_state *cli, uint16_t fnum, 4114 const char *ea_name, const char *ea_val, 4115 size_t ea_len) 4116 { 4117 uint8_t param[6]; 4325 4118 4326 4119 memset(param, 0, 6); … … 4328 4121 SSVAL(param,2,SMB_INFO_SET_EA); 4329 4122 4330 return cli_set_ea(cli, setup, param, 6, ea_name, ea_val, ea_len); 4123 return cli_set_ea(cli, TRANSACT2_SETFILEINFO, param, 6, 4124 ea_name, ea_val, ea_len); 4331 4125 } 4332 4126 … … 4335 4129 *********************************************************/ 4336 4130 4337 static bool cli_get_ea_list(struct cli_state *cli, 4338 uint16_t setup, char *param, unsigned int param_len, 4339 TALLOC_CTX *ctx, 4340 size_t *pnum_eas, 4341 struct ea_struct **pea_list) 4342 { 4343 unsigned int data_len = 0; 4344 unsigned int rparam_len, rdata_len; 4345 char *rparam=NULL, *rdata=NULL; 4346 char *p; 4131 static bool parse_ea_blob(TALLOC_CTX *ctx, const uint8_t *rdata, 4132 size_t rdata_len, 4133 size_t *pnum_eas, struct ea_struct **pea_list) 4134 { 4135 struct ea_struct *ea_list = NULL; 4136 size_t num_eas; 4347 4137 size_t ea_size; 4348 size_t num_eas; 4349 bool ret = False; 4350 struct ea_struct *ea_list; 4351 4352 *pnum_eas = 0; 4353 if (pea_list) { 4354 *pea_list = NULL; 4355 } 4356 4357 if (!cli_send_trans(cli, SMBtrans2, 4358 NULL, /* Name */ 4359 -1, 0, /* fid, flags */ 4360 &setup, 1, 0, /* setup, length, max */ 4361 param, param_len, 10, /* param, length, max */ 4362 NULL, data_len, cli->max_xmit /* data, length, max */ 4363 )) { 4364 return False; 4365 } 4366 4367 if (!cli_receive_trans(cli, SMBtrans2, 4368 &rparam, &rparam_len, 4369 &rdata, &rdata_len)) { 4370 return False; 4371 } 4372 4373 if (!rdata || rdata_len < 4) { 4374 goto out; 4138 const uint8_t *p; 4139 4140 if (rdata_len < 4) { 4141 return false; 4375 4142 } 4376 4143 4377 4144 ea_size = (size_t)IVAL(rdata,0); 4378 4145 if (ea_size > rdata_len) { 4379 goto out;4146 return false; 4380 4147 } 4381 4148 4382 4149 if (ea_size == 0) { 4383 4150 /* No EA's present. */ 4384 ret = True; 4385 goto out; 4151 *pnum_eas = 0; 4152 *pea_list = NULL; 4153 return true; 4386 4154 } 4387 4155 … … 4394 4162 unsigned int ea_valuelen = SVAL(p,2); 4395 4163 if (ea_namelen == 0) { 4396 goto out;4164 return false; 4397 4165 } 4398 4166 if (4 + ea_namelen + 1 + ea_valuelen > ea_size) { 4399 goto out;4167 return false; 4400 4168 } 4401 4169 ea_size -= 4 + ea_namelen + 1 + ea_valuelen; … … 4404 4172 4405 4173 if (num_eas == 0) { 4406 ret = True; 4407 goto out; 4174 *pnum_eas = 0; 4175 *pea_list = NULL; 4176 return true; 4408 4177 } 4409 4178 … … 4411 4180 if (!pea_list) { 4412 4181 /* Caller only wants number of EA's. */ 4413 ret = True; 4414 goto out; 4182 return true; 4415 4183 } 4416 4184 4417 4185 ea_list = TALLOC_ARRAY(ctx, struct ea_struct, num_eas); 4418 4186 if (!ea_list) { 4419 goto out;4187 return false; 4420 4188 } 4421 4189 … … 4432 4200 unix_ea_name[0] = '\0'; 4433 4201 pull_ascii_fstring(unix_ea_name, p + 4); 4434 ea->name = talloc_strdup(ctx, unix_ea_name); 4202 ea->name = talloc_strdup(ea_list, unix_ea_name); 4203 if (!ea->name) { 4204 goto fail; 4205 } 4435 4206 /* Ensure the value is null terminated (in case it's a string). */ 4436 ea->value = data_blob_talloc( ctx, NULL, ea_valuelen + 1);4207 ea->value = data_blob_talloc(ea_list, NULL, ea_valuelen + 1); 4437 4208 if (!ea->value.data) { 4438 goto out;4209 goto fail; 4439 4210 } 4440 4211 if (ea_valuelen) { … … 4447 4218 4448 4219 *pea_list = ea_list; 4449 ret = True; 4450 4451 out : 4452 4453 SAFE_FREE(rdata); 4454 SAFE_FREE(rparam); 4455 return ret; 4220 return true; 4221 4222 fail: 4223 TALLOC_FREE(ea_list); 4224 return false; 4456 4225 } 4457 4226 … … 4460 4229 *********************************************************/ 4461 4230 4462 bool cli_get_ea_list_path(struct cli_state *cli, const char *path, 4231 struct cli_get_ea_list_path_state { 4232 uint32_t num_data; 4233 uint8_t *data; 4234 }; 4235 4236 static void cli_get_ea_list_path_done(struct tevent_req *subreq); 4237 4238 struct tevent_req *cli_get_ea_list_path_send(TALLOC_CTX *mem_ctx, 4239 struct tevent_context *ev, 4240 struct cli_state *cli, 4241 const char *fname) 4242 { 4243 struct tevent_req *req, *subreq; 4244 struct cli_get_ea_list_path_state *state; 4245 4246 req = tevent_req_create(mem_ctx, &state, 4247 struct cli_get_ea_list_path_state); 4248 if (req == NULL) { 4249 return NULL; 4250 } 4251 subreq = cli_qpathinfo_send(state, ev, cli, fname, 4252 SMB_INFO_QUERY_ALL_EAS, 4, 4253 cli->max_xmit); 4254 if (tevent_req_nomem(subreq, req)) { 4255 return tevent_req_post(req, ev); 4256 } 4257 tevent_req_set_callback(subreq, cli_get_ea_list_path_done, req); 4258 return req; 4259 } 4260 4261 static void cli_get_ea_list_path_done(struct tevent_req *subreq) 4262 { 4263 struct tevent_req *req = tevent_req_callback_data( 4264 subreq, struct tevent_req); 4265 struct cli_get_ea_list_path_state *state = tevent_req_data( 4266 req, struct cli_get_ea_list_path_state); 4267 NTSTATUS status; 4268 4269 status = cli_qpathinfo_recv(subreq, state, &state->data, 4270 &state->num_data); 4271 TALLOC_FREE(subreq); 4272 if (tevent_req_nterror(req, status)) { 4273 return; 4274 } 4275 tevent_req_done(req); 4276 } 4277 4278 NTSTATUS cli_get_ea_list_path_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 4279 size_t *pnum_eas, struct ea_struct **peas) 4280 { 4281 struct cli_get_ea_list_path_state *state = tevent_req_data( 4282 req, struct cli_get_ea_list_path_state); 4283 NTSTATUS status; 4284 4285 if (tevent_req_is_nterror(req, &status)) { 4286 return status; 4287 } 4288 if (!parse_ea_blob(mem_ctx, state->data, state->num_data, 4289 pnum_eas, peas)) { 4290 return NT_STATUS_INVALID_NETWORK_RESPONSE; 4291 } 4292 return NT_STATUS_OK; 4293 } 4294 4295 NTSTATUS cli_get_ea_list_path(struct cli_state *cli, const char *path, 4463 4296 TALLOC_CTX *ctx, 4464 4297 size_t *pnum_eas, 4465 4298 struct ea_struct **pea_list) 4466 4299 { 4467 uint16_t setup = TRANSACT2_QPATHINFO; 4468 unsigned int param_len = 0; 4469 char *param; 4470 char *p; 4471 size_t srclen = 2*(strlen(path)+1); 4472 bool ret; 4473 4474 param = SMB_MALLOC_ARRAY(char, 6+srclen+2); 4475 if (!param) { 4476 return false; 4477 } 4478 p = param; 4479 memset(p, 0, 6); 4480 SSVAL(p, 0, SMB_INFO_QUERY_ALL_EAS); 4481 p += 6; 4482 p += clistr_push(cli, p, path, srclen, STR_TERMINATE); 4483 param_len = PTR_DIFF(p, param); 4484 4485 ret = cli_get_ea_list(cli, setup, param, param_len, ctx, pnum_eas, pea_list); 4486 SAFE_FREE(param); 4487 return ret; 4488 } 4489 4490 /********************************************************* 4491 Get an extended attribute list from an fnum. 4492 *********************************************************/ 4493 4494 bool cli_get_ea_list_fnum(struct cli_state *cli, uint16_t fnum, 4495 TALLOC_CTX *ctx, 4496 size_t *pnum_eas, 4497 struct ea_struct **pea_list) 4498 { 4499 uint16_t setup = TRANSACT2_QFILEINFO; 4500 char param[6]; 4501 4502 memset(param, 0, 6); 4503 SSVAL(param,0,fnum); 4504 SSVAL(param,2,SMB_INFO_SET_EA); 4505 4506 return cli_get_ea_list(cli, setup, param, 6, ctx, pnum_eas, pea_list); 4300 TALLOC_CTX *frame = talloc_stackframe(); 4301 struct event_context *ev = NULL; 4302 struct tevent_req *req = NULL; 4303 NTSTATUS status = NT_STATUS_NO_MEMORY; 4304 4305 if (cli_has_async_calls(cli)) { 4306 /* 4307 * Can't use sync call while an async call is in flight 4308 */ 4309 status = NT_STATUS_INVALID_PARAMETER; 4310 goto fail; 4311 } 4312 ev = event_context_init(frame); 4313 if (ev == NULL) { 4314 goto fail; 4315 } 4316 req = cli_get_ea_list_path_send(frame, ev, cli, path); 4317 if (req == NULL) { 4318 goto fail; 4319 } 4320 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 4321 goto fail; 4322 } 4323 status = cli_get_ea_list_path_recv(req, ctx, pnum_eas, pea_list); 4324 fail: 4325 TALLOC_FREE(frame); 4326 if (!NT_STATUS_IS_OK(status)) { 4327 cli_set_error(cli, status); 4328 } 4329 return status; 4507 4330 } 4508 4331 … … 4553 4376 #if defined(O_DIRECTORY) 4554 4377 if (flags & O_DIRECTORY) { 4555 ret &= ~(SMB_O_RDONLY|SMB_O_RDWR|SMB_O_WRONLY);4556 4378 ret |= SMB_O_DIRECTORY; 4557 4379 } … … 4580 4402 uint32_t num_data; 4581 4403 4582 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, &data, &num_data); 4404 status = cli_trans_recv(subreq, state, NULL, NULL, 0, NULL, 4405 NULL, 0, NULL, &data, 12, &num_data); 4583 4406 TALLOC_FREE(subreq); 4584 if (!NT_STATUS_IS_OK(status)) { 4585 tevent_req_nterror(req, status); 4586 return; 4587 } 4588 if (num_data < 12) { 4589 tevent_req_nterror(req, status); 4407 if (tevent_req_nterror(req, status)) { 4590 4408 return; 4591 4409 } … … 4631 4449 /* Setup data words. */ 4632 4450 if (is_dir) { 4633 wire_flags &= ~(SMB_O_RDONLY|SMB_O_RDWR|SMB_O_WRONLY);4634 4451 wire_flags |= SMB_O_DIRECTORY; 4635 4452 } … … 4754 4571 NTSTATUS cli_posix_mkdir_recv(struct tevent_req *req) 4755 4572 { 4756 NTSTATUS status; 4757 4758 if (tevent_req_is_nterror(req, &status)) { 4759 return status; 4760 } 4761 return NT_STATUS_OK; 4573 return tevent_req_simple_recv_ntstatus(req); 4762 4574 } 4763 4575 … … 4812 4624 ****************************************************************************/ 4813 4625 4814 struct unlink_state { 4815 uint16_t setup; 4626 struct cli_posix_unlink_internal_state { 4816 4627 uint8_t data[2]; 4817 4628 }; 4818 4629 4819 static void cli_posix_unlink_internal_done(struct tevent_req *subreq) 4820 { 4821 struct tevent_req *req = tevent_req_callback_data( 4822 subreq, struct tevent_req); 4823 struct unlink_state *state = tevent_req_data(req, struct unlink_state); 4824 NTSTATUS status; 4825 4826 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL); 4827 TALLOC_FREE(subreq); 4828 if (!NT_STATUS_IS_OK(status)) { 4829 tevent_req_nterror(req, status); 4830 return; 4831 } 4832 tevent_req_done(req); 4833 } 4630 static void cli_posix_unlink_internal_done(struct tevent_req *subreq); 4834 4631 4835 4632 static struct tevent_req *cli_posix_unlink_internal_send(TALLOC_CTX *mem_ctx, … … 4837 4634 struct cli_state *cli, 4838 4635 const char *fname, 4839 bool is_dir)4636 uint16_t level) 4840 4637 { 4841 4638 struct tevent_req *req = NULL, *subreq = NULL; 4842 struct unlink_state *state = NULL;4843 uint8_t *param = NULL; 4844 4845 req = tevent_req_create(mem_ctx, &state, struct unlink_state);4639 struct cli_posix_unlink_internal_state *state = NULL; 4640 4641 req = tevent_req_create(mem_ctx, &state, 4642 struct cli_posix_unlink_internal_state); 4846 4643 if (req == NULL) { 4847 4644 return NULL; 4848 4645 } 4849 4646 4850 /* Setup setup word. */4851 SSVAL(&state->setup, 0, TRANSACT2_SETPATHINFO);4852 4853 /* Setup param array. */4854 param = talloc_array(state, uint8_t, 6);4855 if (tevent_req_nomem(param, req)) {4856 return tevent_req_post(req, ev);4857 }4858 memset(param, '\0', 6);4859 SSVAL(param, 0, SMB_POSIX_PATH_UNLINK);4860 4861 param = trans2_bytes_push_str(param, cli_ucs2(cli), fname,4862 strlen(fname)+1, NULL);4863 4864 if (tevent_req_nomem(param, req)) {4865 return tevent_req_post(req, ev);4866 }4867 4868 4647 /* Setup data word. */ 4869 SSVAL(state->data, 0, is_dir ? SMB_POSIX_UNLINK_DIRECTORY_TARGET : 4870 SMB_POSIX_UNLINK_FILE_TARGET); 4871 4872 subreq = cli_trans_send(state, /* mem ctx. */ 4873 ev, /* event ctx. */ 4874 cli, /* cli_state. */ 4875 SMBtrans2, /* cmd. */ 4876 NULL, /* pipe name. */ 4877 -1, /* fid. */ 4878 0, /* function. */ 4879 0, /* flags. */ 4880 &state->setup, /* setup. */ 4881 1, /* num setup uint16_t words. */ 4882 0, /* max returned setup. */ 4883 param, /* param. */ 4884 talloc_get_size(param), /* num param. */ 4885 2, /* max returned param. */ 4886 state->data, /* data. */ 4887 2, /* num data. */ 4888 0); /* max returned data. */ 4889 4648 SSVAL(state->data, 0, level); 4649 4650 subreq = cli_setpathinfo_send(state, ev, cli, 4651 SMB_POSIX_PATH_UNLINK, 4652 fname, 4653 state->data, sizeof(state->data)); 4890 4654 if (tevent_req_nomem(subreq, req)) { 4891 4655 return tevent_req_post(req, ev); … … 4893 4657 tevent_req_set_callback(subreq, cli_posix_unlink_internal_done, req); 4894 4658 return req; 4659 } 4660 4661 static void cli_posix_unlink_internal_done(struct tevent_req *subreq) 4662 { 4663 NTSTATUS status = cli_setpathinfo_recv(subreq); 4664 tevent_req_simple_finish_ntstatus(subreq, status); 4895 4665 } 4896 4666 … … 4900 4670 const char *fname) 4901 4671 { 4902 return cli_posix_unlink_internal_send(mem_ctx, ev, cli, fname, false); 4672 return cli_posix_unlink_internal_send(mem_ctx, ev, cli, fname, 4673 SMB_POSIX_UNLINK_FILE_TARGET); 4903 4674 } 4904 4675 4905 4676 NTSTATUS cli_posix_unlink_recv(struct tevent_req *req) 4906 4677 { 4907 NTSTATUS status; 4908 4909 if (tevent_req_is_nterror(req, &status)) { 4910 return status; 4911 } 4912 return NT_STATUS_OK; 4678 return tevent_req_simple_recv_ntstatus(req); 4913 4679 } 4914 4680 … … 4971 4737 const char *fname) 4972 4738 { 4973 return cli_posix_unlink_internal_send(mem_ctx, ev, cli, fname, true); 4739 return cli_posix_unlink_internal_send( 4740 mem_ctx, ev, cli, fname, 4741 SMB_POSIX_UNLINK_DIRECTORY_TARGET); 4974 4742 } 4975 4743 4976 4744 NTSTATUS cli_posix_rmdir_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx) 4977 4745 { 4978 NTSTATUS status; 4979 4980 if (tevent_req_is_nterror(req, &status)) { 4981 return status; 4982 } 4983 return NT_STATUS_OK; 4746 return tevent_req_simple_recv_ntstatus(req); 4984 4747 } 4985 4748 … … 5094 4857 uint8_t *params; 5095 4858 uint32_t i, ofs, num_params; 5096 5097 status = cli_trans_recv(subreq, talloc_tos(), NULL, NULL, 5098 ¶ms, &num_params, NULL, NULL); 4859 uint16_t flags2; 4860 4861 status = cli_trans_recv(subreq, talloc_tos(), &flags2, NULL, 0, NULL, 4862 ¶ms, 0, &num_params, NULL, 0, NULL); 5099 4863 TALLOC_FREE(subreq); 5100 if ( !NT_STATUS_IS_OK(status)) {4864 if (tevent_req_nterror(req, status)) { 5101 4865 DEBUG(10, ("cli_trans_recv returned %s\n", nt_errstr(status))); 5102 tevent_req_nterror(req, status);5103 4866 return; 5104 4867 } … … 5140 4903 5141 4904 state->changes[i].action = IVAL(params, ofs+4); 5142 ret = clistr_pull_talloc(params, (char *)params, &name,5143 params+ofs+12, len,4905 ret = clistr_pull_talloc(params, (char *)params, flags2, 4906 &name, params+ofs+12, len, 5144 4907 STR_TERMINATE|STR_UNICODE); 5145 4908 if (ret == -1) { … … 5172 4935 return NT_STATUS_OK; 5173 4936 } 4937 4938 struct cli_qpathinfo_state { 4939 uint8_t *param; 4940 uint8_t *data; 4941 uint16_t setup[1]; 4942 uint32_t min_rdata; 4943 uint8_t *rdata; 4944 uint32_t num_rdata; 4945 }; 4946 4947 static void cli_qpathinfo_done(struct tevent_req *subreq); 4948 4949 struct tevent_req *cli_qpathinfo_send(TALLOC_CTX *mem_ctx, 4950 struct tevent_context *ev, 4951 struct cli_state *cli, const char *fname, 4952 uint16_t level, uint32_t min_rdata, 4953 uint32_t max_rdata) 4954 { 4955 struct tevent_req *req, *subreq; 4956 struct cli_qpathinfo_state *state; 4957 4958 req = tevent_req_create(mem_ctx, &state, struct cli_qpathinfo_state); 4959 if (req == NULL) { 4960 return NULL; 4961 } 4962 state->min_rdata = min_rdata; 4963 SSVAL(state->setup, 0, TRANSACT2_QPATHINFO); 4964 4965 state->param = talloc_zero_array(state, uint8_t, 6); 4966 if (tevent_req_nomem(state->param, req)) { 4967 return tevent_req_post(req, ev); 4968 } 4969 SSVAL(state->param, 0, level); 4970 state->param = trans2_bytes_push_str( 4971 state->param, cli_ucs2(cli), fname, strlen(fname)+1, NULL); 4972 if (tevent_req_nomem(state->param, req)) { 4973 return tevent_req_post(req, ev); 4974 } 4975 4976 subreq = cli_trans_send( 4977 state, /* mem ctx. */ 4978 ev, /* event ctx. */ 4979 cli, /* cli_state. */ 4980 SMBtrans2, /* cmd. */ 4981 NULL, /* pipe name. */ 4982 -1, /* fid. */ 4983 0, /* function. */ 4984 0, /* flags. */ 4985 state->setup, /* setup. */ 4986 1, /* num setup uint16_t words. */ 4987 0, /* max returned setup. */ 4988 state->param, /* param. */ 4989 talloc_get_size(state->param), /* num param. */ 4990 2, /* max returned param. */ 4991 NULL, /* data. */ 4992 0, /* num data. */ 4993 max_rdata); /* max returned data. */ 4994 4995 if (tevent_req_nomem(subreq, req)) { 4996 return tevent_req_post(req, ev); 4997 } 4998 tevent_req_set_callback(subreq, cli_qpathinfo_done, req); 4999 return req; 5000 } 5001 5002 static void cli_qpathinfo_done(struct tevent_req *subreq) 5003 { 5004 struct tevent_req *req = tevent_req_callback_data( 5005 subreq, struct tevent_req); 5006 struct cli_qpathinfo_state *state = tevent_req_data( 5007 req, struct cli_qpathinfo_state); 5008 NTSTATUS status; 5009 5010 status = cli_trans_recv(subreq, state, NULL, NULL, 0, NULL, 5011 NULL, 0, NULL, 5012 &state->rdata, state->min_rdata, 5013 &state->num_rdata); 5014 if (tevent_req_nterror(req, status)) { 5015 return; 5016 } 5017 tevent_req_done(req); 5018 } 5019 5020 NTSTATUS cli_qpathinfo_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 5021 uint8_t **rdata, uint32_t *num_rdata) 5022 { 5023 struct cli_qpathinfo_state *state = tevent_req_data( 5024 req, struct cli_qpathinfo_state); 5025 NTSTATUS status; 5026 5027 if (tevent_req_is_nterror(req, &status)) { 5028 return status; 5029 } 5030 if (rdata != NULL) { 5031 *rdata = talloc_move(mem_ctx, &state->rdata); 5032 } else { 5033 TALLOC_FREE(state->rdata); 5034 } 5035 if (num_rdata != NULL) { 5036 *num_rdata = state->num_rdata; 5037 } 5038 return NT_STATUS_OK; 5039 } 5040 5041 NTSTATUS cli_qpathinfo(TALLOC_CTX *mem_ctx, struct cli_state *cli, 5042 const char *fname, uint16_t level, uint32_t min_rdata, 5043 uint32_t max_rdata, 5044 uint8_t **rdata, uint32_t *num_rdata) 5045 { 5046 TALLOC_CTX *frame = talloc_stackframe(); 5047 struct event_context *ev; 5048 struct tevent_req *req; 5049 NTSTATUS status = NT_STATUS_NO_MEMORY; 5050 5051 if (cli_has_async_calls(cli)) { 5052 /* 5053 * Can't use sync call while an async call is in flight 5054 */ 5055 status = NT_STATUS_INVALID_PARAMETER; 5056 goto fail; 5057 } 5058 ev = event_context_init(frame); 5059 if (ev == NULL) { 5060 goto fail; 5061 } 5062 req = cli_qpathinfo_send(frame, ev, cli, fname, level, min_rdata, 5063 max_rdata); 5064 if (req == NULL) { 5065 goto fail; 5066 } 5067 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 5068 goto fail; 5069 } 5070 status = cli_qpathinfo_recv(req, mem_ctx, rdata, num_rdata); 5071 fail: 5072 TALLOC_FREE(frame); 5073 if (!NT_STATUS_IS_OK(status)) { 5074 cli_set_error(cli, status); 5075 } 5076 return status; 5077 } 5078 5079 struct cli_qfileinfo_state { 5080 uint16_t setup[1]; 5081 uint8_t param[4]; 5082 uint8_t *data; 5083 uint32_t min_rdata; 5084 uint8_t *rdata; 5085 uint32_t num_rdata; 5086 }; 5087 5088 static void cli_qfileinfo_done(struct tevent_req *subreq); 5089 5090 struct tevent_req *cli_qfileinfo_send(TALLOC_CTX *mem_ctx, 5091 struct tevent_context *ev, 5092 struct cli_state *cli, uint16_t fnum, 5093 uint16_t level, uint32_t min_rdata, 5094 uint32_t max_rdata) 5095 { 5096 struct tevent_req *req, *subreq; 5097 struct cli_qfileinfo_state *state; 5098 5099 req = tevent_req_create(mem_ctx, &state, struct cli_qfileinfo_state); 5100 if (req == NULL) { 5101 return NULL; 5102 } 5103 state->min_rdata = min_rdata; 5104 SSVAL(state->param, 0, fnum); 5105 SSVAL(state->param, 2, level); 5106 SSVAL(state->setup, 0, TRANSACT2_QFILEINFO); 5107 5108 subreq = cli_trans_send( 5109 state, /* mem ctx. */ 5110 ev, /* event ctx. */ 5111 cli, /* cli_state. */ 5112 SMBtrans2, /* cmd. */ 5113 NULL, /* pipe name. */ 5114 -1, /* fid. */ 5115 0, /* function. */ 5116 0, /* flags. */ 5117 state->setup, /* setup. */ 5118 1, /* num setup uint16_t words. */ 5119 0, /* max returned setup. */ 5120 state->param, /* param. */ 5121 sizeof(state->param), /* num param. */ 5122 2, /* max returned param. */ 5123 NULL, /* data. */ 5124 0, /* num data. */ 5125 max_rdata); /* max returned data. */ 5126 5127 if (tevent_req_nomem(subreq, req)) { 5128 return tevent_req_post(req, ev); 5129 } 5130 tevent_req_set_callback(subreq, cli_qfileinfo_done, req); 5131 return req; 5132 } 5133 5134 static void cli_qfileinfo_done(struct tevent_req *subreq) 5135 { 5136 struct tevent_req *req = tevent_req_callback_data( 5137 subreq, struct tevent_req); 5138 struct cli_qfileinfo_state *state = tevent_req_data( 5139 req, struct cli_qfileinfo_state); 5140 NTSTATUS status; 5141 5142 status = cli_trans_recv(subreq, state, NULL, NULL, 0, NULL, 5143 NULL, 0, NULL, 5144 &state->rdata, state->min_rdata, 5145 &state->num_rdata); 5146 if (tevent_req_nterror(req, status)) { 5147 return; 5148 } 5149 tevent_req_done(req); 5150 } 5151 5152 NTSTATUS cli_qfileinfo_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 5153 uint8_t **rdata, uint32_t *num_rdata) 5154 { 5155 struct cli_qfileinfo_state *state = tevent_req_data( 5156 req, struct cli_qfileinfo_state); 5157 NTSTATUS status; 5158 5159 if (tevent_req_is_nterror(req, &status)) { 5160 return status; 5161 } 5162 if (rdata != NULL) { 5163 *rdata = talloc_move(mem_ctx, &state->rdata); 5164 } else { 5165 TALLOC_FREE(state->rdata); 5166 } 5167 if (num_rdata != NULL) { 5168 *num_rdata = state->num_rdata; 5169 } 5170 return NT_STATUS_OK; 5171 } 5172 5173 NTSTATUS cli_qfileinfo(TALLOC_CTX *mem_ctx, struct cli_state *cli, 5174 uint16_t fnum, uint16_t level, uint32_t min_rdata, 5175 uint32_t max_rdata, 5176 uint8_t **rdata, uint32_t *num_rdata) 5177 { 5178 TALLOC_CTX *frame = talloc_stackframe(); 5179 struct event_context *ev; 5180 struct tevent_req *req; 5181 NTSTATUS status = NT_STATUS_NO_MEMORY; 5182 5183 if (cli_has_async_calls(cli)) { 5184 /* 5185 * Can't use sync call while an async call is in flight 5186 */ 5187 status = NT_STATUS_INVALID_PARAMETER; 5188 goto fail; 5189 } 5190 ev = event_context_init(frame); 5191 if (ev == NULL) { 5192 goto fail; 5193 } 5194 req = cli_qfileinfo_send(frame, ev, cli, fnum, level, min_rdata, 5195 max_rdata); 5196 if (req == NULL) { 5197 goto fail; 5198 } 5199 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 5200 goto fail; 5201 } 5202 status = cli_qfileinfo_recv(req, mem_ctx, rdata, num_rdata); 5203 fail: 5204 TALLOC_FREE(frame); 5205 if (!NT_STATUS_IS_OK(status)) { 5206 cli_set_error(cli, status); 5207 } 5208 return status; 5209 } 5210 5211 struct cli_flush_state { 5212 uint16_t vwv[1]; 5213 }; 5214 5215 static void cli_flush_done(struct tevent_req *subreq); 5216 5217 struct tevent_req *cli_flush_send(TALLOC_CTX *mem_ctx, 5218 struct event_context *ev, 5219 struct cli_state *cli, 5220 uint16_t fnum) 5221 { 5222 struct tevent_req *req, *subreq; 5223 struct cli_flush_state *state; 5224 5225 req = tevent_req_create(mem_ctx, &state, struct cli_flush_state); 5226 if (req == NULL) { 5227 return NULL; 5228 } 5229 SSVAL(state->vwv + 0, 0, fnum); 5230 5231 subreq = cli_smb_send(state, ev, cli, SMBflush, 0, 1, state->vwv, 5232 0, NULL); 5233 if (tevent_req_nomem(subreq, req)) { 5234 return tevent_req_post(req, ev); 5235 } 5236 tevent_req_set_callback(subreq, cli_flush_done, req); 5237 return req; 5238 } 5239 5240 static void cli_flush_done(struct tevent_req *subreq) 5241 { 5242 struct tevent_req *req = tevent_req_callback_data( 5243 subreq, struct tevent_req); 5244 NTSTATUS status; 5245 5246 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 5247 TALLOC_FREE(subreq); 5248 if (tevent_req_nterror(req, status)) { 5249 return; 5250 } 5251 tevent_req_done(req); 5252 } 5253 5254 NTSTATUS cli_flush_recv(struct tevent_req *req) 5255 { 5256 return tevent_req_simple_recv_ntstatus(req); 5257 } 5258 5259 NTSTATUS cli_flush(TALLOC_CTX *mem_ctx, struct cli_state *cli, uint16_t fnum) 5260 { 5261 TALLOC_CTX *frame = talloc_stackframe(); 5262 struct event_context *ev; 5263 struct tevent_req *req; 5264 NTSTATUS status = NT_STATUS_NO_MEMORY; 5265 5266 if (cli_has_async_calls(cli)) { 5267 /* 5268 * Can't use sync call while an async call is in flight 5269 */ 5270 status = NT_STATUS_INVALID_PARAMETER; 5271 goto fail; 5272 } 5273 ev = event_context_init(frame); 5274 if (ev == NULL) { 5275 goto fail; 5276 } 5277 req = cli_flush_send(frame, ev, cli, fnum); 5278 if (req == NULL) { 5279 goto fail; 5280 } 5281 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 5282 goto fail; 5283 } 5284 status = cli_flush_recv(req); 5285 fail: 5286 TALLOC_FREE(frame); 5287 if (!NT_STATUS_IS_OK(status)) { 5288 cli_set_error(cli, status); 5289 } 5290 return status; 5291 } 5292 5293 struct cli_shadow_copy_data_state { 5294 uint16_t setup[4]; 5295 uint8_t *data; 5296 uint32_t num_data; 5297 bool get_names; 5298 }; 5299 5300 static void cli_shadow_copy_data_done(struct tevent_req *subreq); 5301 5302 struct tevent_req *cli_shadow_copy_data_send(TALLOC_CTX *mem_ctx, 5303 struct tevent_context *ev, 5304 struct cli_state *cli, 5305 uint16_t fnum, 5306 bool get_names) 5307 { 5308 struct tevent_req *req, *subreq; 5309 struct cli_shadow_copy_data_state *state; 5310 uint32_t ret_size; 5311 5312 req = tevent_req_create(mem_ctx, &state, 5313 struct cli_shadow_copy_data_state); 5314 if (req == NULL) { 5315 return NULL; 5316 } 5317 state->get_names = get_names; 5318 ret_size = get_names ? cli->max_xmit : 16; 5319 5320 SIVAL(state->setup + 0, 0, FSCTL_GET_SHADOW_COPY_DATA); 5321 SSVAL(state->setup + 2, 0, fnum); 5322 SCVAL(state->setup + 3, 0, 0); /* isFsctl */ 5323 SCVAL(state->setup + 3, 1, 0); /* compfilter, isFlags (WSSP) */ 5324 5325 subreq = cli_trans_send( 5326 state, ev, cli, SMBnttrans, NULL, 0, NT_TRANSACT_IOCTL, 0, 5327 state->setup, ARRAY_SIZE(state->setup), 0, 5328 NULL, 0, 0, 5329 NULL, 0, ret_size); 5330 if (tevent_req_nomem(subreq, req)) { 5331 return tevent_req_post(req, ev); 5332 } 5333 tevent_req_set_callback(subreq, cli_shadow_copy_data_done, req); 5334 return req; 5335 } 5336 5337 static void cli_shadow_copy_data_done(struct tevent_req *subreq) 5338 { 5339 struct tevent_req *req = tevent_req_callback_data( 5340 subreq, struct tevent_req); 5341 struct cli_shadow_copy_data_state *state = tevent_req_data( 5342 req, struct cli_shadow_copy_data_state); 5343 NTSTATUS status; 5344 5345 status = cli_trans_recv(subreq, state, NULL, 5346 NULL, 0, NULL, /* setup */ 5347 NULL, 0, NULL, /* param */ 5348 &state->data, 12, &state->num_data); 5349 TALLOC_FREE(subreq); 5350 if (tevent_req_nterror(req, status)) { 5351 return; 5352 } 5353 tevent_req_done(req); 5354 } 5355 5356 NTSTATUS cli_shadow_copy_data_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 5357 char ***pnames, int *pnum_names) 5358 { 5359 struct cli_shadow_copy_data_state *state = tevent_req_data( 5360 req, struct cli_shadow_copy_data_state); 5361 char **names; 5362 int i, num_names; 5363 uint32_t dlength; 5364 NTSTATUS status; 5365 5366 if (tevent_req_is_nterror(req, &status)) { 5367 return status; 5368 } 5369 num_names = IVAL(state->data, 4); 5370 dlength = IVAL(state->data, 8); 5371 5372 if (!state->get_names) { 5373 *pnum_names = num_names; 5374 return NT_STATUS_OK; 5375 } 5376 5377 if (dlength+12 > state->num_data) { 5378 return NT_STATUS_INVALID_NETWORK_RESPONSE; 5379 } 5380 names = talloc_array(mem_ctx, char *, num_names); 5381 if (names == NULL) { 5382 return NT_STATUS_NO_MEMORY; 5383 } 5384 5385 for (i=0; i<num_names; i++) { 5386 bool ret; 5387 uint8_t *src; 5388 size_t converted_size; 5389 5390 src = state->data + 12 + i * 2 * sizeof(SHADOW_COPY_LABEL); 5391 ret = convert_string_talloc( 5392 names, CH_UTF16LE, CH_UNIX, 5393 src, 2 * sizeof(SHADOW_COPY_LABEL), 5394 &names[i], &converted_size, True); 5395 if (!ret) { 5396 TALLOC_FREE(names); 5397 return NT_STATUS_INVALID_NETWORK_RESPONSE; 5398 } 5399 } 5400 *pnum_names = num_names; 5401 *pnames = names; 5402 return NT_STATUS_OK; 5403 } 5404 5405 NTSTATUS cli_shadow_copy_data(TALLOC_CTX *mem_ctx, struct cli_state *cli, 5406 uint16_t fnum, bool get_names, 5407 char ***pnames, int *pnum_names) 5408 { 5409 TALLOC_CTX *frame = talloc_stackframe(); 5410 struct event_context *ev; 5411 struct tevent_req *req; 5412 NTSTATUS status = NT_STATUS_NO_MEMORY; 5413 5414 if (cli_has_async_calls(cli)) { 5415 /* 5416 * Can't use sync call while an async call is in flight 5417 */ 5418 status = NT_STATUS_INVALID_PARAMETER; 5419 goto fail; 5420 } 5421 ev = event_context_init(frame); 5422 if (ev == NULL) { 5423 goto fail; 5424 } 5425 req = cli_shadow_copy_data_send(frame, ev, cli, fnum, get_names); 5426 if (req == NULL) { 5427 goto fail; 5428 } 5429 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 5430 goto fail; 5431 } 5432 status = cli_shadow_copy_data_recv(req, mem_ctx, pnames, pnum_names); 5433 fail: 5434 TALLOC_FREE(frame); 5435 if (!NT_STATUS_IS_OK(status)) { 5436 cli_set_error(cli, status); 5437 } 5438 return status; 5439 }
Note:
See TracChangeset
for help on using the changeset viewer.