Changeset 745 for trunk/server/source3/libsmb/clifile.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/clifile.c
r454 r745 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 #ifdef __OS2__ 4363 NULL, data_len, CLI_BUFFER_SIZE /* data, length, max */ 4364 #else 4365 NULL, data_len, cli->max_xmit /* data, length, max */ 4366 #endif 4367 )) { 4368 return False; 4369 } 4370 4371 if (!cli_receive_trans(cli, SMBtrans2, 4372 &rparam, &rparam_len, 4373 &rdata, &rdata_len)) { 4374 return False; 4375 } 4376 4377 if (!rdata || rdata_len < 4) { 4378 goto out; 4138 const uint8_t *p; 4139 4140 if (rdata_len < 4) { 4141 return false; 4379 4142 } 4380 4143 4381 4144 ea_size = (size_t)IVAL(rdata,0); 4382 4145 if (ea_size > rdata_len) { 4383 goto out;4146 return false; 4384 4147 } 4385 4148 4386 4149 if (ea_size == 0) { 4387 4150 /* No EA's present. */ 4388 ret = True; 4389 goto out; 4151 *pnum_eas = 0; 4152 *pea_list = NULL; 4153 return true; 4390 4154 } 4391 4155 … … 4398 4162 unsigned int ea_valuelen = SVAL(p,2); 4399 4163 if (ea_namelen == 0) { 4400 goto out;4164 return false; 4401 4165 } 4402 4166 if (4 + ea_namelen + 1 + ea_valuelen > ea_size) { 4403 goto out;4167 return false; 4404 4168 } 4405 4169 ea_size -= 4 + ea_namelen + 1 + ea_valuelen; … … 4408 4172 4409 4173 if (num_eas == 0) { 4410 ret = True; 4411 goto out; 4174 *pnum_eas = 0; 4175 *pea_list = NULL; 4176 return true; 4412 4177 } 4413 4178 … … 4415 4180 if (!pea_list) { 4416 4181 /* Caller only wants number of EA's. */ 4417 ret = True; 4418 goto out; 4182 return true; 4419 4183 } 4420 4184 4421 4185 ea_list = TALLOC_ARRAY(ctx, struct ea_struct, num_eas); 4422 4186 if (!ea_list) { 4423 goto out;4187 return false; 4424 4188 } 4425 4189 … … 4436 4200 unix_ea_name[0] = '\0'; 4437 4201 pull_ascii_fstring(unix_ea_name, p + 4); 4438 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 } 4439 4206 /* Ensure the value is null terminated (in case it's a string). */ 4440 ea->value = data_blob_talloc( ctx, NULL, ea_valuelen + 1);4207 ea->value = data_blob_talloc(ea_list, NULL, ea_valuelen + 1); 4441 4208 if (!ea->value.data) { 4442 goto out;4209 goto fail; 4443 4210 } 4444 4211 if (ea_valuelen) { … … 4451 4218 4452 4219 *pea_list = ea_list; 4453 ret = True; 4454 4455 out : 4456 4457 SAFE_FREE(rdata); 4458 SAFE_FREE(rparam); 4459 return ret; 4220 return true; 4221 4222 fail: 4223 TALLOC_FREE(ea_list); 4224 return false; 4460 4225 } 4461 4226 … … 4464 4229 *********************************************************/ 4465 4230 4466 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 // @todo in earlier port the above cli->max_xmit was changed to CLI_BUFFER_SIZE 4255 // @todo is that still needed? if no regressions are found please remove it 4256 if (tevent_req_nomem(subreq, req)) { 4257 return tevent_req_post(req, ev); 4258 } 4259 tevent_req_set_callback(subreq, cli_get_ea_list_path_done, req); 4260 return req; 4261 } 4262 4263 static void cli_get_ea_list_path_done(struct tevent_req *subreq) 4264 { 4265 struct tevent_req *req = tevent_req_callback_data( 4266 subreq, struct tevent_req); 4267 struct cli_get_ea_list_path_state *state = tevent_req_data( 4268 req, struct cli_get_ea_list_path_state); 4269 NTSTATUS status; 4270 4271 status = cli_qpathinfo_recv(subreq, state, &state->data, 4272 &state->num_data); 4273 TALLOC_FREE(subreq); 4274 if (tevent_req_nterror(req, status)) { 4275 return; 4276 } 4277 tevent_req_done(req); 4278 } 4279 4280 NTSTATUS cli_get_ea_list_path_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 4281 size_t *pnum_eas, struct ea_struct **peas) 4282 { 4283 struct cli_get_ea_list_path_state *state = tevent_req_data( 4284 req, struct cli_get_ea_list_path_state); 4285 NTSTATUS status; 4286 4287 if (tevent_req_is_nterror(req, &status)) { 4288 return status; 4289 } 4290 if (!parse_ea_blob(mem_ctx, state->data, state->num_data, 4291 pnum_eas, peas)) { 4292 return NT_STATUS_INVALID_NETWORK_RESPONSE; 4293 } 4294 return NT_STATUS_OK; 4295 } 4296 4297 NTSTATUS cli_get_ea_list_path(struct cli_state *cli, const char *path, 4467 4298 TALLOC_CTX *ctx, 4468 4299 size_t *pnum_eas, 4469 4300 struct ea_struct **pea_list) 4470 4301 { 4471 uint16_t setup = TRANSACT2_QPATHINFO; 4472 unsigned int param_len = 0; 4473 char *param; 4474 char *p; 4475 size_t srclen = 2*(strlen(path)+1); 4476 bool ret; 4477 4478 param = SMB_MALLOC_ARRAY(char, 6+srclen+2); 4479 if (!param) { 4480 return false; 4481 } 4482 p = param; 4483 memset(p, 0, 6); 4484 SSVAL(p, 0, SMB_INFO_QUERY_ALL_EAS); 4485 p += 6; 4486 p += clistr_push(cli, p, path, srclen, STR_TERMINATE); 4487 param_len = PTR_DIFF(p, param); 4488 4489 ret = cli_get_ea_list(cli, setup, param, param_len, ctx, pnum_eas, pea_list); 4490 SAFE_FREE(param); 4491 return ret; 4492 } 4493 4494 /********************************************************* 4495 Get an extended attribute list from an fnum. 4496 *********************************************************/ 4497 4498 bool cli_get_ea_list_fnum(struct cli_state *cli, uint16_t fnum, 4499 TALLOC_CTX *ctx, 4500 size_t *pnum_eas, 4501 struct ea_struct **pea_list) 4502 { 4503 uint16_t setup = TRANSACT2_QFILEINFO; 4504 char param[6]; 4505 4506 memset(param, 0, 6); 4507 SSVAL(param,0,fnum); 4508 #ifndef __OS2__ 4509 SSVAL(param,2,SMB_INFO_SET_EA); 4510 #else 4511 SSVAL(param,2,SMB_INFO_QUERY_ALL_EAS); 4512 #endif 4513 4514 return cli_get_ea_list(cli, setup, param, 6, ctx, pnum_eas, pea_list); 4302 TALLOC_CTX *frame = talloc_stackframe(); 4303 struct event_context *ev = NULL; 4304 struct tevent_req *req = NULL; 4305 NTSTATUS status = NT_STATUS_NO_MEMORY; 4306 4307 if (cli_has_async_calls(cli)) { 4308 /* 4309 * Can't use sync call while an async call is in flight 4310 */ 4311 status = NT_STATUS_INVALID_PARAMETER; 4312 goto fail; 4313 } 4314 ev = event_context_init(frame); 4315 if (ev == NULL) { 4316 goto fail; 4317 } 4318 req = cli_get_ea_list_path_send(frame, ev, cli, path); 4319 if (req == NULL) { 4320 goto fail; 4321 } 4322 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 4323 goto fail; 4324 } 4325 status = cli_get_ea_list_path_recv(req, ctx, pnum_eas, pea_list); 4326 fail: 4327 TALLOC_FREE(frame); 4328 if (!NT_STATUS_IS_OK(status)) { 4329 cli_set_error(cli, status); 4330 } 4331 return status; 4515 4332 } 4516 4333 … … 4561 4378 #if defined(O_DIRECTORY) 4562 4379 if (flags & O_DIRECTORY) { 4563 ret &= ~(SMB_O_RDONLY|SMB_O_RDWR|SMB_O_WRONLY);4564 4380 ret |= SMB_O_DIRECTORY; 4565 4381 } … … 4588 4404 uint32_t num_data; 4589 4405 4590 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, &data, &num_data); 4406 status = cli_trans_recv(subreq, state, NULL, NULL, 0, NULL, 4407 NULL, 0, NULL, &data, 12, &num_data); 4591 4408 TALLOC_FREE(subreq); 4592 if (!NT_STATUS_IS_OK(status)) { 4593 tevent_req_nterror(req, status); 4594 return; 4595 } 4596 if (num_data < 12) { 4597 tevent_req_nterror(req, status); 4409 if (tevent_req_nterror(req, status)) { 4598 4410 return; 4599 4411 } … … 4639 4451 /* Setup data words. */ 4640 4452 if (is_dir) { 4641 wire_flags &= ~(SMB_O_RDONLY|SMB_O_RDWR|SMB_O_WRONLY);4642 4453 wire_flags |= SMB_O_DIRECTORY; 4643 4454 } … … 4762 4573 NTSTATUS cli_posix_mkdir_recv(struct tevent_req *req) 4763 4574 { 4764 NTSTATUS status; 4765 4766 if (tevent_req_is_nterror(req, &status)) { 4767 return status; 4768 } 4769 return NT_STATUS_OK; 4575 return tevent_req_simple_recv_ntstatus(req); 4770 4576 } 4771 4577 … … 4820 4626 ****************************************************************************/ 4821 4627 4822 struct unlink_state { 4823 uint16_t setup; 4628 struct cli_posix_unlink_internal_state { 4824 4629 uint8_t data[2]; 4825 4630 }; 4826 4631 4827 static void cli_posix_unlink_internal_done(struct tevent_req *subreq) 4828 { 4829 struct tevent_req *req = tevent_req_callback_data( 4830 subreq, struct tevent_req); 4831 struct unlink_state *state = tevent_req_data(req, struct unlink_state); 4832 NTSTATUS status; 4833 4834 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL); 4835 TALLOC_FREE(subreq); 4836 if (!NT_STATUS_IS_OK(status)) { 4837 tevent_req_nterror(req, status); 4838 return; 4839 } 4840 tevent_req_done(req); 4841 } 4632 static void cli_posix_unlink_internal_done(struct tevent_req *subreq); 4842 4633 4843 4634 static struct tevent_req *cli_posix_unlink_internal_send(TALLOC_CTX *mem_ctx, … … 4845 4636 struct cli_state *cli, 4846 4637 const char *fname, 4847 bool is_dir)4638 uint16_t level) 4848 4639 { 4849 4640 struct tevent_req *req = NULL, *subreq = NULL; 4850 struct unlink_state *state = NULL;4851 uint8_t *param = NULL; 4852 4853 req = tevent_req_create(mem_ctx, &state, struct unlink_state);4641 struct cli_posix_unlink_internal_state *state = NULL; 4642 4643 req = tevent_req_create(mem_ctx, &state, 4644 struct cli_posix_unlink_internal_state); 4854 4645 if (req == NULL) { 4855 4646 return NULL; 4856 4647 } 4857 4648 4858 /* Setup setup word. */4859 SSVAL(&state->setup, 0, TRANSACT2_SETPATHINFO);4860 4861 /* Setup param array. */4862 param = talloc_array(state, uint8_t, 6);4863 if (tevent_req_nomem(param, req)) {4864 return tevent_req_post(req, ev);4865 }4866 memset(param, '\0', 6);4867 SSVAL(param, 0, SMB_POSIX_PATH_UNLINK);4868 4869 param = trans2_bytes_push_str(param, cli_ucs2(cli), fname,4870 strlen(fname)+1, NULL);4871 4872 if (tevent_req_nomem(param, req)) {4873 return tevent_req_post(req, ev);4874 }4875 4876 4649 /* Setup data word. */ 4877 SSVAL(state->data, 0, is_dir ? SMB_POSIX_UNLINK_DIRECTORY_TARGET : 4878 SMB_POSIX_UNLINK_FILE_TARGET); 4879 4880 subreq = cli_trans_send(state, /* mem ctx. */ 4881 ev, /* event ctx. */ 4882 cli, /* cli_state. */ 4883 SMBtrans2, /* cmd. */ 4884 NULL, /* pipe name. */ 4885 -1, /* fid. */ 4886 0, /* function. */ 4887 0, /* flags. */ 4888 &state->setup, /* setup. */ 4889 1, /* num setup uint16_t words. */ 4890 0, /* max returned setup. */ 4891 param, /* param. */ 4892 talloc_get_size(param), /* num param. */ 4893 2, /* max returned param. */ 4894 state->data, /* data. */ 4895 2, /* num data. */ 4896 0); /* max returned data. */ 4897 4650 SSVAL(state->data, 0, level); 4651 4652 subreq = cli_setpathinfo_send(state, ev, cli, 4653 SMB_POSIX_PATH_UNLINK, 4654 fname, 4655 state->data, sizeof(state->data)); 4898 4656 if (tevent_req_nomem(subreq, req)) { 4899 4657 return tevent_req_post(req, ev); … … 4901 4659 tevent_req_set_callback(subreq, cli_posix_unlink_internal_done, req); 4902 4660 return req; 4661 } 4662 4663 static void cli_posix_unlink_internal_done(struct tevent_req *subreq) 4664 { 4665 NTSTATUS status = cli_setpathinfo_recv(subreq); 4666 tevent_req_simple_finish_ntstatus(subreq, status); 4903 4667 } 4904 4668 … … 4908 4672 const char *fname) 4909 4673 { 4910 return cli_posix_unlink_internal_send(mem_ctx, ev, cli, fname, false); 4674 return cli_posix_unlink_internal_send(mem_ctx, ev, cli, fname, 4675 SMB_POSIX_UNLINK_FILE_TARGET); 4911 4676 } 4912 4677 4913 4678 NTSTATUS cli_posix_unlink_recv(struct tevent_req *req) 4914 4679 { 4915 NTSTATUS status; 4916 4917 if (tevent_req_is_nterror(req, &status)) { 4918 return status; 4919 } 4920 return NT_STATUS_OK; 4680 return tevent_req_simple_recv_ntstatus(req); 4921 4681 } 4922 4682 … … 4979 4739 const char *fname) 4980 4740 { 4981 return cli_posix_unlink_internal_send(mem_ctx, ev, cli, fname, true); 4741 return cli_posix_unlink_internal_send( 4742 mem_ctx, ev, cli, fname, 4743 SMB_POSIX_UNLINK_DIRECTORY_TARGET); 4982 4744 } 4983 4745 4984 4746 NTSTATUS cli_posix_rmdir_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx) 4985 4747 { 4986 NTSTATUS status; 4987 4988 if (tevent_req_is_nterror(req, &status)) { 4989 return status; 4990 } 4991 return NT_STATUS_OK; 4748 return tevent_req_simple_recv_ntstatus(req); 4992 4749 } 4993 4750 … … 5102 4859 uint8_t *params; 5103 4860 uint32_t i, ofs, num_params; 5104 5105 status = cli_trans_recv(subreq, talloc_tos(), NULL, NULL, 5106 ¶ms, &num_params, NULL, NULL); 4861 uint16_t flags2; 4862 4863 status = cli_trans_recv(subreq, talloc_tos(), &flags2, NULL, 0, NULL, 4864 ¶ms, 0, &num_params, NULL, 0, NULL); 5107 4865 TALLOC_FREE(subreq); 5108 if ( !NT_STATUS_IS_OK(status)) {4866 if (tevent_req_nterror(req, status)) { 5109 4867 DEBUG(10, ("cli_trans_recv returned %s\n", nt_errstr(status))); 5110 tevent_req_nterror(req, status);5111 4868 return; 5112 4869 } … … 5148 4905 5149 4906 state->changes[i].action = IVAL(params, ofs+4); 5150 ret = clistr_pull_talloc(params, (char *)params, &name,5151 params+ofs+12, len,4907 ret = clistr_pull_talloc(params, (char *)params, flags2, 4908 &name, params+ofs+12, len, 5152 4909 STR_TERMINATE|STR_UNICODE); 5153 4910 if (ret == -1) { … … 5180 4937 return NT_STATUS_OK; 5181 4938 } 4939 4940 struct cli_qpathinfo_state { 4941 uint8_t *param; 4942 uint8_t *data; 4943 uint16_t setup[1]; 4944 uint32_t min_rdata; 4945 uint8_t *rdata; 4946 uint32_t num_rdata; 4947 }; 4948 4949 static void cli_qpathinfo_done(struct tevent_req *subreq); 4950 4951 struct tevent_req *cli_qpathinfo_send(TALLOC_CTX *mem_ctx, 4952 struct tevent_context *ev, 4953 struct cli_state *cli, const char *fname, 4954 uint16_t level, uint32_t min_rdata, 4955 uint32_t max_rdata) 4956 { 4957 struct tevent_req *req, *subreq; 4958 struct cli_qpathinfo_state *state; 4959 4960 req = tevent_req_create(mem_ctx, &state, struct cli_qpathinfo_state); 4961 if (req == NULL) { 4962 return NULL; 4963 } 4964 state->min_rdata = min_rdata; 4965 SSVAL(state->setup, 0, TRANSACT2_QPATHINFO); 4966 4967 state->param = talloc_zero_array(state, uint8_t, 6); 4968 if (tevent_req_nomem(state->param, req)) { 4969 return tevent_req_post(req, ev); 4970 } 4971 SSVAL(state->param, 0, level); 4972 state->param = trans2_bytes_push_str( 4973 state->param, cli_ucs2(cli), fname, strlen(fname)+1, NULL); 4974 if (tevent_req_nomem(state->param, req)) { 4975 return tevent_req_post(req, ev); 4976 } 4977 4978 subreq = cli_trans_send( 4979 state, /* mem ctx. */ 4980 ev, /* event ctx. */ 4981 cli, /* cli_state. */ 4982 SMBtrans2, /* cmd. */ 4983 NULL, /* pipe name. */ 4984 -1, /* fid. */ 4985 0, /* function. */ 4986 0, /* flags. */ 4987 state->setup, /* setup. */ 4988 1, /* num setup uint16_t words. */ 4989 0, /* max returned setup. */ 4990 state->param, /* param. */ 4991 talloc_get_size(state->param), /* num param. */ 4992 2, /* max returned param. */ 4993 NULL, /* data. */ 4994 0, /* num data. */ 4995 max_rdata); /* max returned data. */ 4996 4997 if (tevent_req_nomem(subreq, req)) { 4998 return tevent_req_post(req, ev); 4999 } 5000 tevent_req_set_callback(subreq, cli_qpathinfo_done, req); 5001 return req; 5002 } 5003 5004 static void cli_qpathinfo_done(struct tevent_req *subreq) 5005 { 5006 struct tevent_req *req = tevent_req_callback_data( 5007 subreq, struct tevent_req); 5008 struct cli_qpathinfo_state *state = tevent_req_data( 5009 req, struct cli_qpathinfo_state); 5010 NTSTATUS status; 5011 5012 status = cli_trans_recv(subreq, state, NULL, NULL, 0, NULL, 5013 NULL, 0, NULL, 5014 &state->rdata, state->min_rdata, 5015 &state->num_rdata); 5016 if (tevent_req_nterror(req, status)) { 5017 return; 5018 } 5019 tevent_req_done(req); 5020 } 5021 5022 NTSTATUS cli_qpathinfo_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 5023 uint8_t **rdata, uint32_t *num_rdata) 5024 { 5025 struct cli_qpathinfo_state *state = tevent_req_data( 5026 req, struct cli_qpathinfo_state); 5027 NTSTATUS status; 5028 5029 if (tevent_req_is_nterror(req, &status)) { 5030 return status; 5031 } 5032 if (rdata != NULL) { 5033 *rdata = talloc_move(mem_ctx, &state->rdata); 5034 } else { 5035 TALLOC_FREE(state->rdata); 5036 } 5037 if (num_rdata != NULL) { 5038 *num_rdata = state->num_rdata; 5039 } 5040 return NT_STATUS_OK; 5041 } 5042 5043 NTSTATUS cli_qpathinfo(TALLOC_CTX *mem_ctx, struct cli_state *cli, 5044 const char *fname, uint16_t level, uint32_t min_rdata, 5045 uint32_t max_rdata, 5046 uint8_t **rdata, uint32_t *num_rdata) 5047 { 5048 TALLOC_CTX *frame = talloc_stackframe(); 5049 struct event_context *ev; 5050 struct tevent_req *req; 5051 NTSTATUS status = NT_STATUS_NO_MEMORY; 5052 5053 if (cli_has_async_calls(cli)) { 5054 /* 5055 * Can't use sync call while an async call is in flight 5056 */ 5057 status = NT_STATUS_INVALID_PARAMETER; 5058 goto fail; 5059 } 5060 ev = event_context_init(frame); 5061 if (ev == NULL) { 5062 goto fail; 5063 } 5064 req = cli_qpathinfo_send(frame, ev, cli, fname, level, min_rdata, 5065 max_rdata); 5066 if (req == NULL) { 5067 goto fail; 5068 } 5069 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 5070 goto fail; 5071 } 5072 status = cli_qpathinfo_recv(req, mem_ctx, rdata, num_rdata); 5073 fail: 5074 TALLOC_FREE(frame); 5075 if (!NT_STATUS_IS_OK(status)) { 5076 cli_set_error(cli, status); 5077 } 5078 return status; 5079 } 5080 5081 struct cli_qfileinfo_state { 5082 uint16_t setup[1]; 5083 uint8_t param[4]; 5084 uint8_t *data; 5085 uint32_t min_rdata; 5086 uint8_t *rdata; 5087 uint32_t num_rdata; 5088 }; 5089 5090 static void cli_qfileinfo_done(struct tevent_req *subreq); 5091 5092 struct tevent_req *cli_qfileinfo_send(TALLOC_CTX *mem_ctx, 5093 struct tevent_context *ev, 5094 struct cli_state *cli, uint16_t fnum, 5095 uint16_t level, uint32_t min_rdata, 5096 uint32_t max_rdata) 5097 { 5098 struct tevent_req *req, *subreq; 5099 struct cli_qfileinfo_state *state; 5100 5101 req = tevent_req_create(mem_ctx, &state, struct cli_qfileinfo_state); 5102 if (req == NULL) { 5103 return NULL; 5104 } 5105 state->min_rdata = min_rdata; 5106 SSVAL(state->param, 0, fnum); 5107 SSVAL(state->param, 2, level); 5108 SSVAL(state->setup, 0, TRANSACT2_QFILEINFO); 5109 5110 subreq = cli_trans_send( 5111 state, /* mem ctx. */ 5112 ev, /* event ctx. */ 5113 cli, /* cli_state. */ 5114 SMBtrans2, /* cmd. */ 5115 NULL, /* pipe name. */ 5116 -1, /* fid. */ 5117 0, /* function. */ 5118 0, /* flags. */ 5119 state->setup, /* setup. */ 5120 1, /* num setup uint16_t words. */ 5121 0, /* max returned setup. */ 5122 state->param, /* param. */ 5123 sizeof(state->param), /* num param. */ 5124 2, /* max returned param. */ 5125 NULL, /* data. */ 5126 0, /* num data. */ 5127 max_rdata); /* max returned data. */ 5128 5129 if (tevent_req_nomem(subreq, req)) { 5130 return tevent_req_post(req, ev); 5131 } 5132 tevent_req_set_callback(subreq, cli_qfileinfo_done, req); 5133 return req; 5134 } 5135 5136 static void cli_qfileinfo_done(struct tevent_req *subreq) 5137 { 5138 struct tevent_req *req = tevent_req_callback_data( 5139 subreq, struct tevent_req); 5140 struct cli_qfileinfo_state *state = tevent_req_data( 5141 req, struct cli_qfileinfo_state); 5142 NTSTATUS status; 5143 5144 status = cli_trans_recv(subreq, state, NULL, NULL, 0, NULL, 5145 NULL, 0, NULL, 5146 &state->rdata, state->min_rdata, 5147 &state->num_rdata); 5148 if (tevent_req_nterror(req, status)) { 5149 return; 5150 } 5151 tevent_req_done(req); 5152 } 5153 5154 NTSTATUS cli_qfileinfo_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 5155 uint8_t **rdata, uint32_t *num_rdata) 5156 { 5157 struct cli_qfileinfo_state *state = tevent_req_data( 5158 req, struct cli_qfileinfo_state); 5159 NTSTATUS status; 5160 5161 if (tevent_req_is_nterror(req, &status)) { 5162 return status; 5163 } 5164 if (rdata != NULL) { 5165 *rdata = talloc_move(mem_ctx, &state->rdata); 5166 } else { 5167 TALLOC_FREE(state->rdata); 5168 } 5169 if (num_rdata != NULL) { 5170 *num_rdata = state->num_rdata; 5171 } 5172 return NT_STATUS_OK; 5173 } 5174 5175 NTSTATUS cli_qfileinfo(TALLOC_CTX *mem_ctx, struct cli_state *cli, 5176 uint16_t fnum, uint16_t level, uint32_t min_rdata, 5177 uint32_t max_rdata, 5178 uint8_t **rdata, uint32_t *num_rdata) 5179 { 5180 TALLOC_CTX *frame = talloc_stackframe(); 5181 struct event_context *ev; 5182 struct tevent_req *req; 5183 NTSTATUS status = NT_STATUS_NO_MEMORY; 5184 5185 if (cli_has_async_calls(cli)) { 5186 /* 5187 * Can't use sync call while an async call is in flight 5188 */ 5189 status = NT_STATUS_INVALID_PARAMETER; 5190 goto fail; 5191 } 5192 ev = event_context_init(frame); 5193 if (ev == NULL) { 5194 goto fail; 5195 } 5196 req = cli_qfileinfo_send(frame, ev, cli, fnum, level, min_rdata, 5197 max_rdata); 5198 if (req == NULL) { 5199 goto fail; 5200 } 5201 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 5202 goto fail; 5203 } 5204 status = cli_qfileinfo_recv(req, mem_ctx, rdata, num_rdata); 5205 fail: 5206 TALLOC_FREE(frame); 5207 if (!NT_STATUS_IS_OK(status)) { 5208 cli_set_error(cli, status); 5209 } 5210 return status; 5211 } 5212 5213 struct cli_flush_state { 5214 uint16_t vwv[1]; 5215 }; 5216 5217 static void cli_flush_done(struct tevent_req *subreq); 5218 5219 struct tevent_req *cli_flush_send(TALLOC_CTX *mem_ctx, 5220 struct event_context *ev, 5221 struct cli_state *cli, 5222 uint16_t fnum) 5223 { 5224 struct tevent_req *req, *subreq; 5225 struct cli_flush_state *state; 5226 5227 req = tevent_req_create(mem_ctx, &state, struct cli_flush_state); 5228 if (req == NULL) { 5229 return NULL; 5230 } 5231 SSVAL(state->vwv + 0, 0, fnum); 5232 5233 subreq = cli_smb_send(state, ev, cli, SMBflush, 0, 1, state->vwv, 5234 0, NULL); 5235 if (tevent_req_nomem(subreq, req)) { 5236 return tevent_req_post(req, ev); 5237 } 5238 tevent_req_set_callback(subreq, cli_flush_done, req); 5239 return req; 5240 } 5241 5242 static void cli_flush_done(struct tevent_req *subreq) 5243 { 5244 struct tevent_req *req = tevent_req_callback_data( 5245 subreq, struct tevent_req); 5246 NTSTATUS status; 5247 5248 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 5249 TALLOC_FREE(subreq); 5250 if (tevent_req_nterror(req, status)) { 5251 return; 5252 } 5253 tevent_req_done(req); 5254 } 5255 5256 NTSTATUS cli_flush_recv(struct tevent_req *req) 5257 { 5258 return tevent_req_simple_recv_ntstatus(req); 5259 } 5260 5261 NTSTATUS cli_flush(TALLOC_CTX *mem_ctx, struct cli_state *cli, uint16_t fnum) 5262 { 5263 TALLOC_CTX *frame = talloc_stackframe(); 5264 struct event_context *ev; 5265 struct tevent_req *req; 5266 NTSTATUS status = NT_STATUS_NO_MEMORY; 5267 5268 if (cli_has_async_calls(cli)) { 5269 /* 5270 * Can't use sync call while an async call is in flight 5271 */ 5272 status = NT_STATUS_INVALID_PARAMETER; 5273 goto fail; 5274 } 5275 ev = event_context_init(frame); 5276 if (ev == NULL) { 5277 goto fail; 5278 } 5279 req = cli_flush_send(frame, ev, cli, fnum); 5280 if (req == NULL) { 5281 goto fail; 5282 } 5283 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 5284 goto fail; 5285 } 5286 status = cli_flush_recv(req); 5287 fail: 5288 TALLOC_FREE(frame); 5289 if (!NT_STATUS_IS_OK(status)) { 5290 cli_set_error(cli, status); 5291 } 5292 return status; 5293 } 5294 5295 struct cli_shadow_copy_data_state { 5296 uint16_t setup[4]; 5297 uint8_t *data; 5298 uint32_t num_data; 5299 bool get_names; 5300 }; 5301 5302 static void cli_shadow_copy_data_done(struct tevent_req *subreq); 5303 5304 struct tevent_req *cli_shadow_copy_data_send(TALLOC_CTX *mem_ctx, 5305 struct tevent_context *ev, 5306 struct cli_state *cli, 5307 uint16_t fnum, 5308 bool get_names) 5309 { 5310 struct tevent_req *req, *subreq; 5311 struct cli_shadow_copy_data_state *state; 5312 uint32_t ret_size; 5313 5314 req = tevent_req_create(mem_ctx, &state, 5315 struct cli_shadow_copy_data_state); 5316 if (req == NULL) { 5317 return NULL; 5318 } 5319 state->get_names = get_names; 5320 ret_size = get_names ? cli->max_xmit : 16; 5321 5322 SIVAL(state->setup + 0, 0, FSCTL_GET_SHADOW_COPY_DATA); 5323 SSVAL(state->setup + 2, 0, fnum); 5324 SCVAL(state->setup + 3, 0, 0); /* isFsctl */ 5325 SCVAL(state->setup + 3, 1, 0); /* compfilter, isFlags (WSSP) */ 5326 5327 subreq = cli_trans_send( 5328 state, ev, cli, SMBnttrans, NULL, 0, NT_TRANSACT_IOCTL, 0, 5329 state->setup, ARRAY_SIZE(state->setup), 0, 5330 NULL, 0, 0, 5331 NULL, 0, ret_size); 5332 if (tevent_req_nomem(subreq, req)) { 5333 return tevent_req_post(req, ev); 5334 } 5335 tevent_req_set_callback(subreq, cli_shadow_copy_data_done, req); 5336 return req; 5337 } 5338 5339 static void cli_shadow_copy_data_done(struct tevent_req *subreq) 5340 { 5341 struct tevent_req *req = tevent_req_callback_data( 5342 subreq, struct tevent_req); 5343 struct cli_shadow_copy_data_state *state = tevent_req_data( 5344 req, struct cli_shadow_copy_data_state); 5345 NTSTATUS status; 5346 5347 status = cli_trans_recv(subreq, state, NULL, 5348 NULL, 0, NULL, /* setup */ 5349 NULL, 0, NULL, /* param */ 5350 &state->data, 12, &state->num_data); 5351 TALLOC_FREE(subreq); 5352 if (tevent_req_nterror(req, status)) { 5353 return; 5354 } 5355 tevent_req_done(req); 5356 } 5357 5358 NTSTATUS cli_shadow_copy_data_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 5359 char ***pnames, int *pnum_names) 5360 { 5361 struct cli_shadow_copy_data_state *state = tevent_req_data( 5362 req, struct cli_shadow_copy_data_state); 5363 char **names; 5364 int i, num_names; 5365 uint32_t dlength; 5366 NTSTATUS status; 5367 5368 if (tevent_req_is_nterror(req, &status)) { 5369 return status; 5370 } 5371 num_names = IVAL(state->data, 4); 5372 dlength = IVAL(state->data, 8); 5373 5374 if (!state->get_names) { 5375 *pnum_names = num_names; 5376 return NT_STATUS_OK; 5377 } 5378 5379 if (dlength+12 > state->num_data) { 5380 return NT_STATUS_INVALID_NETWORK_RESPONSE; 5381 } 5382 names = talloc_array(mem_ctx, char *, num_names); 5383 if (names == NULL) { 5384 return NT_STATUS_NO_MEMORY; 5385 } 5386 5387 for (i=0; i<num_names; i++) { 5388 bool ret; 5389 uint8_t *src; 5390 size_t converted_size; 5391 5392 src = state->data + 12 + i * 2 * sizeof(SHADOW_COPY_LABEL); 5393 ret = convert_string_talloc( 5394 names, CH_UTF16LE, CH_UNIX, 5395 src, 2 * sizeof(SHADOW_COPY_LABEL), 5396 &names[i], &converted_size, True); 5397 if (!ret) { 5398 TALLOC_FREE(names); 5399 return NT_STATUS_INVALID_NETWORK_RESPONSE; 5400 } 5401 } 5402 *pnum_names = num_names; 5403 *pnames = names; 5404 return NT_STATUS_OK; 5405 } 5406 5407 NTSTATUS cli_shadow_copy_data(TALLOC_CTX *mem_ctx, struct cli_state *cli, 5408 uint16_t fnum, bool get_names, 5409 char ***pnames, int *pnum_names) 5410 { 5411 TALLOC_CTX *frame = talloc_stackframe(); 5412 struct event_context *ev; 5413 struct tevent_req *req; 5414 NTSTATUS status = NT_STATUS_NO_MEMORY; 5415 5416 if (cli_has_async_calls(cli)) { 5417 /* 5418 * Can't use sync call while an async call is in flight 5419 */ 5420 status = NT_STATUS_INVALID_PARAMETER; 5421 goto fail; 5422 } 5423 ev = event_context_init(frame); 5424 if (ev == NULL) { 5425 goto fail; 5426 } 5427 req = cli_shadow_copy_data_send(frame, ev, cli, fnum, get_names); 5428 if (req == NULL) { 5429 goto fail; 5430 } 5431 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 5432 goto fail; 5433 } 5434 status = cli_shadow_copy_data_recv(req, mem_ctx, pnames, pnum_names); 5435 fail: 5436 TALLOC_FREE(frame); 5437 if (!NT_STATUS_IS_OK(status)) { 5438 cli_set_error(cli, status); 5439 } 5440 return status; 5441 }
Note:
See TracChangeset
for help on using the changeset viewer.