Changeset 77 for trunk/samba/source/smbd/nttrans.c
- Timestamp:
- Sep 30, 2007, 3:42:50 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/samba/source/smbd/nttrans.c
r62 r77 2 2 Unix SMB/CIFS implementation. 3 3 SMB NT transaction handling 4 Copyright (C) Jeremy Allison 1994- 19984 Copyright (C) Jeremy Allison 1994-2007 5 5 Copyright (C) Stefan (metze) Metzmacher 2003 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 the Free Software Foundation; either version 2of the License, or9 the Free Software Foundation; either version 3 of the License, or 10 10 (at your option) any later version. 11 11 … … 16 16 17 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 along with this program. If not, see <http://www.gnu.org/licenses/>. 20 19 */ 21 20 … … 51 50 { 52 51 if (ptr==NULL) { 53 smb_panic("nttrans_realloc() called with NULL ptr \n");54 } 55 52 smb_panic("nttrans_realloc() called with NULL ptr"); 53 } 54 56 55 *ptr = (char *)SMB_REALLOC(*ptr, size); 57 56 if(*ptr == NULL) { … … 69 68 ****************************************************************************/ 70 69 71 int send_nt_replies(char *outbuf, int bufsize, NTSTATUS nt_error, 72 char *params, int paramsize, char *pdata, int datasize) 70 void send_nt_replies(struct smb_request *req, NTSTATUS nt_error, 71 char *params, int paramsize, 72 char *pdata, int datasize) 73 73 { 74 74 int data_to_send = datasize; … … 82 82 83 83 /* 84 * Initially set the wcnt area to be 18 - this is true for all85 * transNT replies.86 */87 88 set_message(outbuf,18,0,True);89 90 if (NT_STATUS_V(nt_error)) {91 ERROR_NT(nt_error);92 }93 94 /*95 84 * If there genuinely are no parameters or data to send just send 96 85 * the empty packet. … … 98 87 99 88 if(params_to_send == 0 && data_to_send == 0) { 100 show_msg(outbuf); 101 if (!send_smb(smbd_server_fd(),outbuf)) { 102 exit_server_cleanly("send_nt_replies: send_smb failed."); 103 } 104 return 0; 89 reply_outbuf(req, 18, 0); 90 show_msg((char *)req->outbuf); 91 return; 105 92 } 106 93 … … 115 102 } 116 103 117 /* 104 /* 118 105 * Space is bufsize minus Netbios over TCP header minus SMB header. 119 106 * The alignment_offset is to align the param bytes on a four byte 120 * boundary (2 bytes for data len, one byte pad). 107 * boundary (2 bytes for data len, one byte pad). 121 108 * NT needs this to work correctly. 122 109 */ 123 110 124 useable_space = bufsize - ((smb_buf(outbuf)+ 125 alignment_offset+data_alignment_offset) - 126 outbuf); 111 useable_space = max_send - (smb_size 112 + 2 * 18 /* wct */ 113 + alignment_offset 114 + data_alignment_offset); 127 115 128 116 /* … … 144 132 alignment_offset + data_alignment_offset; 145 133 146 /* 134 /* 147 135 * We can never send more than useable_space. 148 136 */ … … 150 138 total_sent_thistime = MIN(total_sent_thistime, useable_space); 151 139 152 set_message(outbuf, 18, total_sent_thistime, True);140 reply_outbuf(req, 18, total_sent_thistime); 153 141 154 142 /* … … 156 144 */ 157 145 158 SIVAL( outbuf,smb_ntr_TotalParameterCount,paramsize);159 SIVAL( outbuf,smb_ntr_TotalDataCount,datasize);160 161 /* 146 SIVAL(req->outbuf,smb_ntr_TotalParameterCount,paramsize); 147 SIVAL(req->outbuf,smb_ntr_TotalDataCount,datasize); 148 149 /* 162 150 * Calculate how many parameters and data we can fit into 163 151 * this packet. Parameters get precedence. … … 168 156 data_sent_thistime = MIN(data_sent_thistime,data_to_send); 169 157 170 SIVAL(outbuf,smb_ntr_ParameterCount,params_sent_thistime); 158 SIVAL(req->outbuf, smb_ntr_ParameterCount, 159 params_sent_thistime); 171 160 172 161 if(params_sent_thistime == 0) { 173 SIVAL( outbuf,smb_ntr_ParameterOffset,0);174 SIVAL( outbuf,smb_ntr_ParameterDisplacement,0);162 SIVAL(req->outbuf,smb_ntr_ParameterOffset,0); 163 SIVAL(req->outbuf,smb_ntr_ParameterDisplacement,0); 175 164 } else { 176 165 /* … … 181 170 */ 182 171 183 SIVAL(outbuf,smb_ntr_ParameterOffset, 184 ((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf))); 185 /* 172 SIVAL(req->outbuf,smb_ntr_ParameterOffset, 173 ((smb_buf(req->outbuf)+alignment_offset) 174 - smb_base(req->outbuf))); 175 /* 186 176 * Absolute displacement of param bytes sent in this packet. 187 177 */ 188 178 189 SIVAL(outbuf,smb_ntr_ParameterDisplacement,pp - params); 179 SIVAL(req->outbuf, smb_ntr_ParameterDisplacement, 180 pp - params); 190 181 } 191 182 … … 194 185 */ 195 186 196 SIVAL( outbuf,smb_ntr_DataCount, data_sent_thistime);187 SIVAL(req->outbuf, smb_ntr_DataCount, data_sent_thistime); 197 188 198 189 if(data_sent_thistime == 0) { 199 SIVAL( outbuf,smb_ntr_DataOffset,0);200 SIVAL( outbuf,smb_ntr_DataDisplacement, 0);190 SIVAL(req->outbuf,smb_ntr_DataOffset,0); 191 SIVAL(req->outbuf,smb_ntr_DataDisplacement, 0); 201 192 } else { 202 193 /* … … 205 196 */ 206 197 207 SIVAL(outbuf,smb_ntr_DataOffset,((smb_buf(outbuf)+alignment_offset) - 208 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset); 209 SIVAL(outbuf,smb_ntr_DataDisplacement, pd - pdata); 210 } 211 212 /* 198 SIVAL(req->outbuf, smb_ntr_DataOffset, 199 ((smb_buf(req->outbuf)+alignment_offset) - 200 smb_base(req->outbuf)) 201 + params_sent_thistime + data_alignment_offset); 202 SIVAL(req->outbuf,smb_ntr_DataDisplacement, pd - pdata); 203 } 204 205 /* 213 206 * Copy the param bytes into the packet. 214 207 */ 215 208 216 209 if(params_sent_thistime) { 217 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime); 210 if (alignment_offset != 0) { 211 memset(smb_buf(req->outbuf), 0, 212 alignment_offset); 213 } 214 memcpy((smb_buf(req->outbuf)+alignment_offset), pp, 215 params_sent_thistime); 218 216 } 219 217 … … 223 221 224 222 if(data_sent_thistime) { 225 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+ 226 data_alignment_offset,pd,data_sent_thistime); 227 } 228 223 if (data_alignment_offset != 0) { 224 memset((smb_buf(req->outbuf)+alignment_offset+ 225 params_sent_thistime), 0, 226 data_alignment_offset); 227 } 228 memcpy(smb_buf(req->outbuf)+alignment_offset 229 +params_sent_thistime+data_alignment_offset, 230 pd,data_sent_thistime); 231 } 232 229 233 DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n", 230 234 params_sent_thistime, data_sent_thistime, useable_space)); 231 235 DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n", 232 236 params_to_send, data_to_send, paramsize, datasize)); 233 237 238 if (NT_STATUS_V(nt_error)) { 239 error_packet_set((char *)req->outbuf, 240 0, 0, nt_error, 241 __LINE__,__FILE__); 242 } 243 234 244 /* Send the packet */ 235 show_msg( outbuf);236 if (!send_smb(smbd_server_fd(), outbuf)) {245 show_msg((char *)req->outbuf); 246 if (!send_smb(smbd_server_fd(),(char *)req->outbuf)) { 237 247 exit_server_cleanly("send_nt_replies: send_smb failed."); 238 248 } 239 249 250 TALLOC_FREE(req->outbuf); 251 240 252 pp += params_sent_thistime; 241 253 pd += data_sent_thistime; 242 254 243 255 params_to_send -= params_sent_thistime; 244 256 data_to_send -= data_sent_thistime; … … 251 263 DEBUG(0,("send_nt_replies failed sanity check pts = %d, dts = %d\n!!!", 252 264 params_to_send, data_to_send)); 253 return -1; 254 } 255 } 256 257 return 0; 265 return; 266 } 267 } 258 268 } 259 269 … … 270 280 } 271 281 282 struct case_semantics_state { 283 connection_struct *conn; 284 BOOL case_sensitive; 285 BOOL case_preserve; 286 BOOL short_case_preserve; 287 }; 288 272 289 /**************************************************************************** 273 Save case statics.290 Restore case semantics. 274 291 ****************************************************************************/ 275 276 static BOOL saved_case_sensitive; 277 static BOOL saved_case_preserve; 278 static BOOL saved_short_case_preserve; 292 static int restore_case_semantics(struct case_semantics_state *state) 293 { 294 state->conn->case_sensitive = state->case_sensitive; 295 state->conn->case_preserve = state->case_preserve; 296 state->conn->short_case_preserve = state->short_case_preserve; 297 return 0; 298 } 279 299 280 300 /**************************************************************************** 281 301 Save case semantics. 282 302 ****************************************************************************/ 283 284 static uint32 set_posix_case_semantics(connection_struct *conn, uint32 file_attributes)303 static struct case_semantics_state *set_posix_case_semantics(TALLOC_CTX *mem_ctx, 304 connection_struct *conn) 285 305 { 286 if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) { 287 return file_attributes; 288 } 289 290 saved_case_sensitive = conn->case_sensitive; 291 saved_case_preserve = conn->case_preserve; 292 saved_short_case_preserve = conn->short_case_preserve; 306 struct case_semantics_state *result; 307 308 if (!(result = talloc(mem_ctx, struct case_semantics_state))) { 309 DEBUG(0, ("talloc failed\n")); 310 return NULL; 311 } 312 313 result->conn = conn; 314 result->case_sensitive = conn->case_sensitive; 315 result->case_preserve = conn->case_preserve; 316 result->short_case_preserve = conn->short_case_preserve; 293 317 294 318 /* Set to POSIX. */ … … 297 321 conn->short_case_preserve = True; 298 322 299 return (file_attributes & ~FILE_FLAG_POSIX_SEMANTICS); 323 talloc_set_destructor(result, restore_case_semantics); 324 325 return result; 300 326 } 301 327 302 328 /**************************************************************************** 303 Re store case semantics.329 Reply to an NT create and X call on a pipe 304 330 ****************************************************************************/ 305 331 306 static void restore_case_semantics(connection_struct *conn, uint32 file_attributes) 307 { 308 if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) { 309 return; 310 } 311 312 conn->case_sensitive = saved_case_sensitive; 313 conn->case_preserve = saved_case_preserve; 314 conn->short_case_preserve = saved_short_case_preserve; 315 } 316 317 /**************************************************************************** 318 Reply to an NT create and X call on a pipe. 319 ****************************************************************************/ 320 321 static int nt_open_pipe(char *fname, connection_struct *conn, 322 char *inbuf, char *outbuf, int *ppnum) 332 static void nt_open_pipe(char *fname, connection_struct *conn, 333 struct smb_request *req, int *ppnum) 323 334 { 324 335 smb_np_struct *p = NULL; 325 uint16 vuid = SVAL(inbuf, smb_uid);326 336 int i; 327 337 328 338 DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname)); 329 339 330 340 /* See if it is one we want to handle. */ 331 341 332 342 if (lp_disable_spoolss() && strequal(fname, "\\spoolss")) { 333 return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe)); 343 reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND, 344 ERRDOS, ERRbadpipe); 345 return; 334 346 } 335 347 … … 339 351 } 340 352 } 341 353 342 354 if ( known_nt_pipes[i] == NULL ) { 343 return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe)); 344 } 345 355 reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND, 356 ERRDOS, ERRbadpipe); 357 return; 358 } 359 346 360 /* Strip \\ off the name. */ 347 361 fname++; 348 362 349 363 DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname)); 350 364 351 p = open_rpc_pipe_p(fname, conn, vuid);365 p = open_rpc_pipe_p(fname, conn, req->vuid); 352 366 if (!p) { 353 return(ERROR_DOS(ERRSRV,ERRnofids)); 354 } 355 356 /* Add pipe to db */ 357 367 reply_doserror(req, ERRSRV, ERRnofids); 368 return; 369 } 370 371 /* TODO: Add pipe to db */ 372 358 373 if ( !store_pipe_opendb( p ) ) { 359 374 DEBUG(3,("nt_open_pipe: failed to store %s pipe open.\n", fname)); 360 375 } 361 376 362 377 *ppnum = p->pnum; 363 return 0;378 return; 364 379 } 365 380 … … 368 383 ****************************************************************************/ 369 384 370 static intdo_ntcreate_pipe_open(connection_struct *conn,371 char *inbuf,char *outbuf,int length,int bufsize)385 static void do_ntcreate_pipe_open(connection_struct *conn, 386 struct smb_request *req) 372 387 { 373 pstring fname; 374 int ret; 388 char *fname = NULL; 375 389 int pnum = -1; 376 390 char *p = NULL; 377 uint32 flags = IVAL(inbuf,smb_ntcreate_Flags); 378 379 srvstr_pull_buf(inbuf, fname, smb_buf(inbuf), sizeof(fname), STR_TERMINATE); 380 381 if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0) { 382 return ret; 391 uint32 flags = IVAL(req->inbuf,smb_ntcreate_Flags); 392 TALLOC_CTX *ctx = talloc_tos(); 393 394 srvstr_pull_buf_talloc(ctx, (char *)req->inbuf, req->flags2, &fname, 395 smb_buf(req->inbuf), STR_TERMINATE); 396 397 if (!fname) { 398 reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND, 399 ERRDOS, ERRbadpipe); 400 return; 401 } 402 nt_open_pipe(fname, conn, req, &pnum); 403 404 if (req->outbuf) { 405 /* error reply */ 406 return; 383 407 } 384 408 385 409 /* 386 410 * Deal with pipe return. 387 */ 411 */ 388 412 389 413 if (flags & EXTENDED_RESPONSE_REQUIRED) { … … 393 417 * what happens on the wire.... 394 418 */ 395 set_message(outbuf,50,0,True);396 SCVAL( outbuf,smb_wct,42);419 reply_outbuf(req, 50, 0); 420 SCVAL(req->outbuf,smb_wct,42); 397 421 } else { 398 set_message(outbuf,34,0,True);399 } 400 401 p = outbuf + smb_vwv2;422 reply_outbuf(req, 34, 0); 423 } 424 425 p = (char *)req->outbuf + smb_vwv2; 402 426 p++; 403 427 SSVAL(p,0,pnum); … … 417 441 p += 25; 418 442 SIVAL(p,0,FILE_GENERIC_ALL); 419 /* 443 /* 420 444 * For pipes W2K3 seems to return 421 445 * 0x12019B next. … … 427 451 DEBUG(5,("do_ntcreate_pipe_open: open pipe = %s\n", fname)); 428 452 429 return chain_reply(inbuf,outbuf,length,bufsize);453 chain_reply(req); 430 454 } 431 455 … … 434 458 ****************************************************************************/ 435 459 436 int reply_ntcreate_and_X_quota(connection_struct *conn, 437 char *inbuf, 438 char *outbuf, 439 int length, 440 int bufsize, 441 enum FAKE_FILE_TYPE fake_file_type, 442 const char *fname) 460 static void reply_ntcreate_and_X_quota(connection_struct *conn, 461 struct smb_request *req, 462 enum FAKE_FILE_TYPE fake_file_type, 463 const char *fname) 443 464 { 444 int result;445 465 char *p; 446 uint32 desired_access = IVAL( inbuf,smb_ntcreate_DesiredAccess);466 uint32 desired_access = IVAL(req->inbuf,smb_ntcreate_DesiredAccess); 447 467 files_struct *fsp; 448 468 NTSTATUS status; … … 452 472 453 473 if (!NT_STATUS_IS_OK(status)) { 454 return ERROR_NT(status); 455 } 456 457 set_message(outbuf,34,0,True); 458 459 p = outbuf + smb_vwv2; 460 474 reply_nterror(req, status); 475 return; 476 } 477 478 reply_outbuf(req, 34, 0); 479 480 p = (char *)req->outbuf + smb_vwv2; 481 461 482 /* SCVAL(p,0,NO_OPLOCK_RETURN); */ 462 483 p++; … … 465 486 DEBUG(5,("reply_ntcreate_and_X_quota: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name)); 466 487 467 result = chain_reply(inbuf,outbuf,length,bufsize); 468 return result; 488 chain_reply(req); 469 489 } 470 490 … … 473 493 ****************************************************************************/ 474 494 475 int reply_ntcreate_and_X(connection_struct *conn, 476 char *inbuf,char *outbuf,int length,int bufsize) 477 { 478 int result; 479 pstring fname; 480 uint32 flags = IVAL(inbuf,smb_ntcreate_Flags); 481 uint32 access_mask = IVAL(inbuf,smb_ntcreate_DesiredAccess); 482 uint32 file_attributes = IVAL(inbuf,smb_ntcreate_FileAttributes); 483 uint32 new_file_attributes; 484 uint32 share_access = IVAL(inbuf,smb_ntcreate_ShareAccess); 485 uint32 create_disposition = IVAL(inbuf,smb_ntcreate_CreateDisposition); 486 uint32 create_options = IVAL(inbuf,smb_ntcreate_CreateOptions); 487 uint16 root_dir_fid = (uint16)IVAL(inbuf,smb_ntcreate_RootDirectoryFid); 495 void reply_ntcreate_and_X(connection_struct *conn, 496 struct smb_request *req) 497 { 498 char *fname = NULL; 499 uint32 flags; 500 uint32 access_mask; 501 uint32 file_attributes; 502 uint32 share_access; 503 uint32 create_disposition; 504 uint32 create_options; 505 uint16 root_dir_fid; 506 SMB_BIG_UINT allocation_size; 488 507 /* Breakout the oplock request bits so we can set the 489 508 reply bits separately. */ … … 500 519 BOOL extended_oplock_granted = False; 501 520 NTSTATUS status; 521 struct case_semantics_state *case_state = NULL; 522 TALLOC_CTX *ctx = talloc_tos(); 502 523 503 524 START_PROFILE(SMBntcreateX); 525 526 if (req->wct < 24) { 527 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 528 return; 529 } 530 531 flags = IVAL(req->inbuf,smb_ntcreate_Flags); 532 access_mask = IVAL(req->inbuf,smb_ntcreate_DesiredAccess); 533 file_attributes = IVAL(req->inbuf,smb_ntcreate_FileAttributes); 534 share_access = IVAL(req->inbuf,smb_ntcreate_ShareAccess); 535 create_disposition = IVAL(req->inbuf,smb_ntcreate_CreateDisposition); 536 create_options = IVAL(req->inbuf,smb_ntcreate_CreateOptions); 537 root_dir_fid = (uint16)IVAL(req->inbuf,smb_ntcreate_RootDirectoryFid); 538 539 allocation_size = (SMB_BIG_UINT)IVAL(req->inbuf,smb_ntcreate_AllocationSize); 540 #ifdef LARGE_SMB_OFF_T 541 allocation_size |= (((SMB_BIG_UINT)IVAL(req->inbuf,smb_ntcreate_AllocationSize + 4)) << 32); 542 #endif 504 543 505 544 DEBUG(10,("reply_ntcreate_and_X: flags = 0x%x, access_mask = 0x%x " … … 521 560 if (IS_IPC(conn)) { 522 561 if (lp_nt_pipe_support()) { 562 do_ntcreate_pipe_open(conn, req); 523 563 END_PROFILE(SMBntcreateX); 524 return do_ntcreate_pipe_open(conn,inbuf,outbuf,length,bufsize);564 return; 525 565 } else { 566 reply_doserror(req, ERRDOS, ERRnoaccess); 526 567 END_PROFILE(SMBntcreateX); 527 return (ERROR_DOS(ERRDOS,ERRnoaccess));568 return; 528 569 } 529 570 } 530 571 531 572 if (create_options & FILE_OPEN_BY_FILE_ID) { 573 reply_nterror(req, NT_STATUS_NOT_SUPPORTED); 532 574 END_PROFILE(SMBntcreateX); 533 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);575 return; 534 576 } 535 577 … … 542 584 * This filename is relative to a directory fid. 543 585 */ 544 pstring rel_fname;545 files_struct *dir_fsp = file_fsp( inbuf,smb_ntcreate_RootDirectoryFid);546 size_t dir_name_len;586 char *rel_fname = NULL; 587 files_struct *dir_fsp = file_fsp( 588 SVAL(req->inbuf, smb_ntcreate_RootDirectoryFid)); 547 589 548 590 if(!dir_fsp) { 591 reply_doserror(req, ERRDOS, ERRbadfid); 549 592 END_PROFILE(SMBntcreateX); 550 return ERROR_DOS(ERRDOS,ERRbadfid);593 return; 551 594 } 552 595 553 596 if(!dir_fsp->is_directory) { 554 597 555 srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status); 598 srvstr_get_path(ctx, (char *)req->inbuf, 599 req->flags2, &fname, 600 smb_buf(req->inbuf), 0, 601 STR_TERMINATE, &status); 556 602 if (!NT_STATUS_IS_OK(status)) { 603 reply_nterror(req, status); 557 604 END_PROFILE(SMBntcreateX); 558 return ERROR_NT(status);605 return; 559 606 } 560 607 … … 564 611 565 612 if( is_ntfs_stream_name(fname)) { 613 reply_nterror( 614 req, NT_STATUS_OBJECT_PATH_NOT_FOUND); 566 615 END_PROFILE(SMBntcreateX); 567 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);616 return; 568 617 } 569 618 … … 575 624 */ 576 625 626 reply_doserror(req, ERRDOS, ERRbadfid); 577 627 END_PROFILE(SMBntcreateX); 578 return(ERROR_DOS(ERRDOS,ERRbadfid)); 579 } 580 581 /* 582 * Copy in the base directory name. 583 */ 584 585 pstrcpy( fname, dir_fsp->fsp_name ); 586 dir_name_len = strlen(fname); 587 588 /* 589 * Ensure it ends in a '\'. 590 */ 591 592 if((fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) { 593 pstrcat(fname, "/"); 594 dir_name_len++; 595 } 596 597 srvstr_get_path(inbuf, rel_fname, smb_buf(inbuf), sizeof(rel_fname), 0, STR_TERMINATE, &status); 628 return; 629 } 630 631 if (ISDOT(dir_fsp->fsp_name)) { 632 /* 633 * We're at the toplevel dir, the final file name 634 * must not contain ./, as this is filtered out 635 * normally by srvstr_get_path and unix_convert 636 * explicitly rejects paths containing ./. 637 */ 638 fname = talloc_strdup(ctx,""); 639 if (!fname) { 640 reply_nterror(req, NT_STATUS_NO_MEMORY); 641 END_PROFILE(SMBntcreateX); 642 return; 643 } 644 } else { 645 size_t dir_name_len = strlen(dir_fsp->fsp_name); 646 647 /* 648 * Copy in the base directory name. 649 */ 650 651 fname = TALLOC_ARRAY(ctx, char, dir_name_len+2); 652 if (!fname) { 653 reply_nterror( 654 req, NT_STATUS_NO_MEMORY); 655 END_PROFILE(SMBntcreateX); 656 return; 657 } 658 memcpy(fname, dir_fsp->fsp_name, dir_name_len+1); 659 660 /* 661 * Ensure it ends in a '/'. 662 * We used TALLOC_SIZE +2 to add space for the '/'. 663 */ 664 665 if(dir_name_len && 666 (fname[dir_name_len-1] != '\\') && 667 (fname[dir_name_len-1] != '/')) { 668 fname[dir_name_len] = '/'; 669 fname[dir_name_len+1] = '\0'; 670 } 671 } 672 673 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &rel_fname, 674 smb_buf(req->inbuf), 0, 675 STR_TERMINATE, &status); 598 676 if (!NT_STATUS_IS_OK(status)) { 677 reply_nterror(req, status); 599 678 END_PROFILE(SMBntcreateX); 600 return ERROR_NT(status); 601 } 602 pstrcat(fname, rel_fname); 679 return; 680 } 681 fname = talloc_asprintf(ctx, "%s%s", 682 fname, 683 rel_fname); 684 if (!fname) { 685 reply_nterror( 686 req, NT_STATUS_NO_MEMORY); 687 END_PROFILE(SMBntcreateX); 688 return; 689 } 603 690 } else { 604 srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status); 691 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, 692 smb_buf(req->inbuf), 0, 693 STR_TERMINATE, &status); 605 694 if (!NT_STATUS_IS_OK(status)) { 695 reply_nterror(req, status); 606 696 END_PROFILE(SMBntcreateX); 607 return ERROR_NT(status);697 return; 608 698 } 609 699 … … 624 714 * xp also tries a QUERY_FILE_INFO on the file and then close it 625 715 */ 626 result = reply_ntcreate_and_X_quota(conn, inbuf, outbuf, length, bufsize, 627 fake_file_type, fname); 628 END_PROFILE(SMBntcreateX); 629 return result; 716 reply_ntcreate_and_X_quota(conn, req, 717 fake_file_type, fname); 630 718 } else { 631 END_PROFILE(SMBntcreateX); 632 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); 719 reply_nterror(req, NT_STATUS_OBJECT_PATH_NOT_FOUND); 633 720 } 634 } 635 } 636 637 /* 638 * Now contruct the smb_open_mode value from the filename, 721 END_PROFILE(SMBntcreateX); 722 return; 723 } 724 } 725 726 /* 727 * Now contruct the smb_open_mode value from the filename, 639 728 * desired access and the share access. 640 729 */ 641 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname); 730 status = resolve_dfspath(ctx, conn, 731 req->flags2 & FLAGS2_DFS_PATHNAMES, 732 fname, 733 &fname); 642 734 if (!NT_STATUS_IS_OK(status)) { 735 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 736 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, 737 ERRSRV, ERRbadpath); 738 } 739 else { 740 reply_nterror(req, status); 741 } 643 742 END_PROFILE(SMBntcreateX); 644 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 645 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 646 } 647 return ERROR_NT(status); 743 return; 648 744 } 649 745 … … 656 752 * Ordinary file or directory. 657 753 */ 658 754 659 755 /* 660 756 * Check if POSIX semantics are wanted. 661 757 */ 662 663 new_file_attributes = set_posix_case_semantics(conn, file_attributes); 664 665 status = unix_convert(conn, fname, False, NULL, &sbuf); 758 759 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) { 760 case_state = set_posix_case_semantics(NULL, conn); 761 file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS; 762 } 763 764 status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf); 666 765 if (!NT_STATUS_IS_OK(status)) { 667 restore_case_semantics(conn, file_attributes); 766 TALLOC_FREE(case_state); 767 reply_nterror(req, status); 668 768 END_PROFILE(SMBntcreateX); 669 return ERROR_NT(status);769 return; 670 770 } 671 771 /* All file access must go through check_name() */ 672 772 status = check_name(conn, fname); 673 773 if (!NT_STATUS_IS_OK(status)) { 674 restore_case_semantics(conn, file_attributes); 774 TALLOC_FREE(case_state); 775 reply_nterror(req, status); 675 776 END_PROFILE(SMBntcreateX); 676 return ERROR_NT(status);777 return; 677 778 } 678 779 … … 691 792 if ((dos_mode(conn, fname, &sbuf) & FILE_ATTRIBUTE_READONLY) || 692 793 !can_delete_file_in_directory(conn, fname)) { 693 restore_case_semantics(conn, file_attributes); 794 TALLOC_FREE(case_state); 795 reply_nterror(req, NT_STATUS_ACCESS_DENIED); 694 796 END_PROFILE(SMBntcreateX); 695 return ERROR_NT(NT_STATUS_ACCESS_DENIED); 696 } 697 } 797 return; 798 } 799 } 800 801 #if 0 802 /* We need to support SeSecurityPrivilege for this. */ 803 if ((access_mask & SEC_RIGHT_SYSTEM_SECURITY) && 804 !user_has_privileges(current_user.nt_user_token, 805 &se_security)) { 806 TALLOC_FREE(case_state); 807 END_PROFILE(SMBntcreateX); 808 return ERROR_NT(NT_STATUS_PRIVILEGE_NOT_HELD); 809 } 810 #endif 698 811 699 812 /* … … 705 818 /* Can't open a temp directory. IFS kit test. */ 706 819 if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) { 820 TALLOC_FREE(case_state); 821 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 707 822 END_PROFILE(SMBntcreateX); 708 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);823 return; 709 824 } 710 825 711 826 oplock_request = 0; 712 status = open_directory(conn, fname, &sbuf,827 status = open_directory(conn, req, fname, &sbuf, 713 828 access_mask, 714 829 share_access, 715 830 create_disposition, 716 831 create_options, 717 new_file_attributes,832 file_attributes, 718 833 &info, &fsp); 834 719 835 } else { 720 836 … … 736 852 * our client. JRA. */ 737 853 738 status = open_file_ntcreate(conn, fname,&sbuf,854 status = open_file_ntcreate(conn, req, fname, &sbuf, 739 855 access_mask, 740 856 share_access, 741 857 create_disposition, 742 858 create_options, 743 new_file_attributes,859 file_attributes, 744 860 oplock_request, 745 861 &info, &fsp); 746 862 747 if (!NT_STATUS_IS_OK(status)) { 748 /* We cheat here. There are two cases we 749 * care about. One is a directory rename, 750 * where the NT client will attempt to 751 * open the source directory for 752 * DELETE access. Note that when the 753 * NT client does this it does *not* 754 * set the directory bit in the 755 * request packet. This is translated 756 * into a read/write open 757 * request. POSIX states that any open 758 * for write request on a directory 759 * will generate an EISDIR error, so 760 * we can catch this here and open a 761 * pseudo handle that is flagged as a 762 * directory. The second is an open 763 * for a permissions read only, which 764 * we handle in the open_file_stat case. JRA. 863 /* We cheat here. There are two cases we 864 * care about. One is a directory rename, 865 * where the NT client will attempt to 866 * open the source directory for 867 * DELETE access. Note that when the 868 * NT client does this it does *not* 869 * set the directory bit in the 870 * request packet. This is translated 871 * into a read/write open 872 * request. POSIX states that any open 873 * for write request on a directory 874 * will generate an EISDIR error, so 875 * we can catch this here and open a 876 * pseudo handle that is flagged as a 877 * directory. The second is an open 878 * for a permissions read only, which 879 * we handle in the open_file_stat case. JRA. 880 */ 881 882 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) { 883 884 /* 885 * Fail the open if it was explicitly a non-directory 886 * file. 765 887 */ 766 888 767 if (NT_STATUS_EQUAL(status, 768 NT_STATUS_FILE_IS_A_DIRECTORY)) { 769 770 /* 771 * Fail the open if it was explicitly a non-directory file. 772 */ 773 774 if (create_options & FILE_NON_DIRECTORY_FILE) { 775 restore_case_semantics(conn, file_attributes); 776 END_PROFILE(SMBntcreateX); 777 return ERROR_FORCE_NT(NT_STATUS_FILE_IS_A_DIRECTORY); 778 } 779 780 oplock_request = 0; 781 status = open_directory(conn, fname, &sbuf, 782 access_mask, 783 share_access, 784 create_disposition, 785 create_options, 786 new_file_attributes, 787 &info, &fsp); 788 889 if (create_options & FILE_NON_DIRECTORY_FILE) { 890 TALLOC_FREE(case_state); 891 reply_force_nterror(req, 892 NT_STATUS_FILE_IS_A_DIRECTORY); 893 END_PROFILE(SMBntcreateX); 894 return; 789 895 } 790 } 791 } 792 793 restore_case_semantics(conn, file_attributes); 794 795 if(!NT_STATUS_IS_OK(status)) { 896 897 oplock_request = 0; 898 status = open_directory(conn, req, fname, 899 &sbuf, 900 access_mask, 901 share_access, 902 create_disposition, 903 create_options, 904 file_attributes, 905 &info, &fsp); 906 } 907 } 908 909 TALLOC_FREE(case_state); 910 911 if (!NT_STATUS_IS_OK(status)) { 912 if (open_was_deferred(req->mid)) { 913 /* We have re-scheduled this call. */ 914 END_PROFILE(SMBntcreateX); 915 return; 916 } 917 reply_openerror(req, status); 796 918 END_PROFILE(SMBntcreateX); 797 798 if (open_was_deferred(SVAL(inbuf,smb_mid))) { 799 /* We have re-scheduled this call. */ 800 return -1; 801 } 802 803 return ERROR_OPEN(status); 919 return; 804 920 } 805 921 … … 811 927 if (!fsp->is_directory && (fattr & aDIR)) { 812 928 close_file(fsp,ERROR_CLOSE); 929 reply_doserror(req, ERRDOS, ERRnoaccess); 813 930 END_PROFILE(SMBntcreateX); 814 return ERROR_DOS(ERRDOS,ERRnoaccess);815 } 816 931 return; 932 } 933 817 934 /* Save the requested allocation size. */ 818 935 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) { 819 SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize);820 #ifdef LARGE_SMB_OFF_T821 allocation_size |= (((SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize + 4)) << 32);822 #endif823 936 if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) { 824 937 fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size); 825 938 if (fsp->is_directory) { 826 939 close_file(fsp,ERROR_CLOSE); 940 /* Can't set allocation size on a directory. */ 941 reply_nterror(req, NT_STATUS_ACCESS_DENIED); 827 942 END_PROFILE(SMBntcreateX); 828 /* Can't set allocation size on a directory. */ 829 return ERROR_NT(NT_STATUS_ACCESS_DENIED); 943 return; 830 944 } 831 945 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) { 832 946 close_file(fsp,ERROR_CLOSE); 947 reply_nterror(req, NT_STATUS_DISK_FULL); 833 948 END_PROFILE(SMBntcreateX); 834 return ERROR_NT(NT_STATUS_DISK_FULL);949 return; 835 950 } 836 951 } else { … … 839 954 } 840 955 841 /* 956 /* 842 957 * If the caller set the extended oplock request bit 843 958 * and we granted one (by whatever means) - set the … … 859 974 * what happens on the wire.... 860 975 */ 861 set_message(outbuf,50,0,True);862 SCVAL( outbuf,smb_wct,42);976 reply_outbuf(req, 50, 0); 977 SCVAL(req->outbuf,smb_wct,42); 863 978 } else { 864 set_message(outbuf,34,0,True);865 } 866 867 p = outbuf + smb_vwv2;868 979 reply_outbuf(req, 34, 0); 980 } 981 982 p = (char *)req->outbuf + smb_vwv2; 983 869 984 /* 870 985 * Currently as we don't support level II oplocks we just report … … 883 998 SCVAL(p,0,NO_OPLOCK_RETURN); 884 999 } 885 1000 886 1001 p++; 887 1002 SSVAL(p,0,fsp->fnum); … … 938 1053 DEBUG(5,("reply_ntcreate_and_X: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name)); 939 1054 940 result = chain_reply(inbuf,outbuf,length,bufsize);1055 chain_reply(req); 941 1056 END_PROFILE(SMBntcreateX); 942 return result;1057 return; 943 1058 } 944 1059 … … 947 1062 ****************************************************************************/ 948 1063 949 static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 950 uint16 **ppsetup, uint32 setup_count, 951 char **ppparams, uint32 parameter_count, 952 char **ppdata, uint32 data_count) 1064 static void do_nt_transact_create_pipe(connection_struct *conn, 1065 struct smb_request *req, 1066 uint16 **ppsetup, uint32 setup_count, 1067 char **ppparams, uint32 parameter_count, 1068 char **ppdata, uint32 data_count) 953 1069 { 954 pstring fname;1070 char *fname = NULL; 955 1071 char *params = *ppparams; 956 int ret;957 1072 int pnum = -1; 958 1073 char *p = NULL; … … 960 1075 size_t param_len; 961 1076 uint32 flags; 1077 TALLOC_CTX *ctx = talloc_tos(); 962 1078 963 1079 /* … … 967 1083 if(parameter_count < 54) { 968 1084 DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)parameter_count)); 969 return ERROR_DOS(ERRDOS,ERRnoaccess); 1085 reply_doserror(req, ERRDOS, ERRnoaccess); 1086 return; 970 1087 } 971 1088 972 1089 flags = IVAL(params,0); 973 1090 974 srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status); 1091 srvstr_get_path(ctx, params, req->flags2, &fname, params+53, 1092 parameter_count-53, STR_TERMINATE, 1093 &status); 975 1094 if (!NT_STATUS_IS_OK(status)) { 976 return ERROR_NT(status); 977 } 978 979 if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0) { 980 return ret; 981 } 982 1095 reply_nterror(req, status); 1096 return; 1097 } 1098 1099 nt_open_pipe(fname, conn, req, &pnum); 1100 1101 if (req->outbuf) { 1102 /* Error return */ 1103 return; 1104 } 1105 983 1106 /* Realloc the size of parameters and data we will return */ 984 1107 if (flags & EXTENDED_RESPONSE_REQUIRED) { … … 990 1113 params = nttrans_realloc(ppparams, param_len); 991 1114 if(params == NULL) { 992 return ERROR_DOS(ERRDOS,ERRnomem); 993 } 994 1115 reply_doserror(req, ERRDOS, ERRnomem); 1116 return; 1117 } 1118 995 1119 p = params; 996 1120 SCVAL(p,0,NO_OPLOCK_RETURN); 997 1121 998 1122 p += 2; 999 1123 SSVAL(p,0,pnum); … … 1001 1125 SIVAL(p,0,FILE_WAS_OPENED); 1002 1126 p += 8; 1003 1127 1004 1128 p += 32; 1005 1129 SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */ … … 1010 1134 SSVAL(p,2, 0x5FF); /* ? */ 1011 1135 p += 4; 1012 1136 1013 1137 if (flags & EXTENDED_RESPONSE_REQUIRED) { 1014 1138 p += 25; 1015 1139 SIVAL(p,0,FILE_GENERIC_ALL); 1016 /* 1140 /* 1017 1141 * For pipes W2K3 seems to return 1018 1142 * 0x12019B next. … … 1023 1147 1024 1148 DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname)); 1025 1149 1026 1150 /* Send the required number of replies */ 1027 send_nt_replies( outbuf, bufsize, NT_STATUS_OK, params, param_len, *ppdata, 0);1028 1029 return -1;1151 send_nt_replies(req, NT_STATUS_OK, params, param_len, *ppdata, 0); 1152 1153 return; 1030 1154 } 1031 1155 … … 1039 1163 SEC_DESC *psd = NULL; 1040 1164 TALLOC_CTX *mem_ctx; 1041 BOOL ret;1042 1165 NTSTATUS status; 1166 1043 1167 if (sd_len == 0 || !lp_nt_acl_support(SNUM(fsp->conn))) { 1044 1168 return NT_STATUS_OK; … … 1060 1184 * allocated. 1061 1185 */ 1062 1186 1063 1187 prs_give_memory( &pd, data, sd_len, False); 1064 1188 … … 1071 1195 /* 1072 1196 * Return access denied for want of a better error message.. 1073 */ 1197 */ 1074 1198 talloc_destroy(mem_ctx); 1075 1199 return NT_STATUS_NO_MEMORY; 1076 1200 } 1077 1201 1078 1202 if (psd->owner_sid==0) { 1079 1203 security_info_sent &= ~OWNER_SECURITY_INFORMATION; … … 1088 1212 security_info_sent &= ~DACL_SECURITY_INFORMATION; 1089 1213 } 1090 1091 ret = SMB_VFS_FSET_NT_ACL( fsp, fsp->fh->fd, security_info_sent, psd); 1092 1093 if (!ret) { 1094 talloc_destroy(mem_ctx); 1095 return NT_STATUS_ACCESS_DENIED; 1096 } 1097 1214 1215 status = SMB_VFS_FSET_NT_ACL( fsp, fsp->fh->fd, security_info_sent, psd); 1216 1098 1217 talloc_destroy(mem_ctx); 1099 1100 return NT_STATUS_OK; 1218 return status; 1101 1219 } 1102 1220 … … 1104 1222 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them. 1105 1223 ****************************************************************************/ 1106 1224 1107 1225 static struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size) 1108 1226 { … … 1128 1246 offset += next_offset; 1129 1247 } 1130 1248 1131 1249 return ea_list_head; 1132 1250 } … … 1136 1254 ****************************************************************************/ 1137 1255 1138 static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 1139 uint16 **ppsetup, uint32 setup_count, 1140 char **ppparams, uint32 parameter_count, 1141 char **ppdata, uint32 data_count, uint32 max_data_count) 1256 static void call_nt_transact_create(connection_struct *conn, 1257 struct smb_request *req, 1258 uint16 **ppsetup, uint32 setup_count, 1259 char **ppparams, uint32 parameter_count, 1260 char **ppdata, uint32 data_count, 1261 uint32 max_data_count) 1142 1262 { 1143 pstring fname;1263 char *fname = NULL; 1144 1264 char *params = *ppparams; 1145 1265 char *data = *ppdata; … … 1156 1276 uint32 access_mask; 1157 1277 uint32 file_attributes; 1158 uint32 new_file_attributes;1159 1278 uint32 share_access; 1160 1279 uint32 create_disposition; … … 1167 1286 struct timespec m_timespec; 1168 1287 struct ea_list *ea_list = NULL; 1169 TALLOC_CTX *ctx = NULL;1170 1288 char *pdata = NULL; 1171 1289 NTSTATUS status; 1172 1290 size_t param_len; 1291 struct case_semantics_state *case_state = NULL; 1292 TALLOC_CTX *ctx = talloc_tos(); 1173 1293 1174 1294 DEBUG(5,("call_nt_transact_create\n")); … … 1180 1300 if (IS_IPC(conn)) { 1181 1301 if (lp_nt_pipe_support()) { 1182 return do_nt_transact_create_pipe(conn, inbuf, outbuf, length, 1183 bufsize, 1184 ppsetup, setup_count, 1185 ppparams, parameter_count, 1186 ppdata, data_count); 1302 do_nt_transact_create_pipe( 1303 conn, req, 1304 ppsetup, setup_count, 1305 ppparams, parameter_count, 1306 ppdata, data_count); 1307 return; 1187 1308 } else { 1188 return ERROR_DOS(ERRDOS,ERRnoaccess); 1309 reply_doserror(req, ERRDOS, ERRnoaccess); 1310 return; 1189 1311 } 1190 1312 } … … 1196 1318 if(parameter_count < 54) { 1197 1319 DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)parameter_count)); 1198 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 1320 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 1321 return; 1199 1322 } 1200 1323 … … 1215 1338 DEBUG(10,("call_nt_transact_create - ea_len = %u, sd_len = %u, data_count = %u\n", 1216 1339 (unsigned int)ea_len, (unsigned int)sd_len, (unsigned int)data_count )); 1217 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 1340 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 1341 return; 1218 1342 } 1219 1343 … … 1222 1346 DEBUG(10,("call_nt_transact_create - ea_len = %u but EA's not supported.\n", 1223 1347 (unsigned int)ea_len )); 1224 return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED); 1348 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED); 1349 return; 1225 1350 } 1226 1351 … … 1228 1353 DEBUG(10,("call_nt_transact_create - ea_len = %u - too small (should be more than 10)\n", 1229 1354 (unsigned int)ea_len )); 1230 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 1355 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 1356 return; 1231 1357 } 1232 1358 } 1233 1359 1234 1360 if (create_options & FILE_OPEN_BY_FILE_ID) { 1235 return ERROR_NT(NT_STATUS_NOT_SUPPORTED); 1361 reply_nterror(req, NT_STATUS_NOT_SUPPORTED); 1362 return; 1236 1363 } 1237 1364 … … 1244 1371 * This filename is relative to a directory fid. 1245 1372 */ 1246 files_struct *dir_fsp = file_fsp(params,4);1247 size_t dir_name_len;1373 char *tmpname = NULL; 1374 files_struct *dir_fsp = file_fsp(SVAL(params,4)); 1248 1375 1249 1376 if(!dir_fsp) { 1250 return ERROR_DOS(ERRDOS,ERRbadfid); 1377 reply_doserror(req, ERRDOS, ERRbadfid); 1378 return; 1251 1379 } 1252 1380 1253 1381 if(!dir_fsp->is_directory) { 1254 srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status); 1382 srvstr_get_path(ctx, params, req->flags2, &fname, 1383 params+53, 1384 parameter_count-53, STR_TERMINATE, 1385 &status); 1255 1386 if (!NT_STATUS_IS_OK(status)) { 1256 return ERROR_NT(status); 1387 reply_nterror(req, status); 1388 return; 1257 1389 } 1258 1390 … … 1262 1394 1263 1395 if( is_ntfs_stream_name(fname)) { 1264 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); 1396 reply_nterror(req, 1397 NT_STATUS_OBJECT_PATH_NOT_FOUND); 1398 return; 1265 1399 } 1266 1400 1267 return ERROR_DOS(ERRDOS,ERRbadfid); 1268 } 1269 1270 /* 1271 * Copy in the base directory name. 1272 */ 1273 1274 pstrcpy( fname, dir_fsp->fsp_name ); 1275 dir_name_len = strlen(fname); 1276 1277 /* 1278 * Ensure it ends in a '\'. 1279 */ 1280 1281 if((fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) { 1282 pstrcat(fname, "/"); 1283 dir_name_len++; 1284 } 1285 1286 { 1287 pstring tmpname; 1288 srvstr_get_path(inbuf, tmpname, params+53, sizeof(tmpname), parameter_count-53, STR_TERMINATE, &status); 1289 if (!NT_STATUS_IS_OK(status)) { 1290 return ERROR_NT(status); 1401 reply_doserror(req, ERRDOS, ERRbadfid); 1402 return; 1403 } 1404 1405 if (ISDOT(dir_fsp->fsp_name)) { 1406 /* 1407 * We're at the toplevel dir, the final file name 1408 * must not contain ./, as this is filtered out 1409 * normally by srvstr_get_path and unix_convert 1410 * explicitly rejects paths containing ./. 1411 */ 1412 fname = talloc_strdup(ctx,""); 1413 if (!fname) { 1414 reply_nterror(req, NT_STATUS_NO_MEMORY); 1415 return; 1291 1416 } 1292 pstrcat(fname, tmpname); 1417 } else { 1418 size_t dir_name_len = strlen(dir_fsp->fsp_name); 1419 1420 /* 1421 * Copy in the base directory name. 1422 */ 1423 1424 fname = TALLOC_ARRAY(ctx, char, dir_name_len+2); 1425 if (!fname) { 1426 reply_nterror(req, NT_STATUS_NO_MEMORY); 1427 return; 1428 } 1429 memcpy(fname, dir_fsp->fsp_name, dir_name_len+1); 1430 1431 /* 1432 * Ensure it ends in a '/'. 1433 * We used TALLOC_SIZE +2 to add space for the '/'. 1434 */ 1435 1436 if(dir_name_len && 1437 (fname[dir_name_len-1] != '\\') && 1438 (fname[dir_name_len-1] != '/')) { 1439 fname[dir_name_len] = '/'; 1440 fname[dir_name_len+1] = '\0'; 1441 } 1442 } 1443 1444 srvstr_get_path(ctx, params, req->flags2, &tmpname, 1445 params+53, 1446 parameter_count-53, STR_TERMINATE, 1447 &status); 1448 if (!NT_STATUS_IS_OK(status)) { 1449 reply_nterror(req, status); 1450 return; 1451 } 1452 fname = talloc_asprintf(ctx, "%s%s", 1453 fname, 1454 tmpname); 1455 if (!fname) { 1456 reply_nterror( 1457 req, NT_STATUS_NO_MEMORY); 1458 return; 1293 1459 } 1294 1460 } else { 1295 srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status); 1461 srvstr_get_path(ctx, params, req->flags2, &fname, params+53, 1462 parameter_count-53, 1463 STR_TERMINATE, &status); 1296 1464 if (!NT_STATUS_IS_OK(status)) { 1297 return ERROR_NT(status); 1465 reply_nterror(req, status); 1466 return; 1298 1467 } 1299 1468 … … 1303 1472 1304 1473 if( is_ntfs_stream_name(fname)) { 1305 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); 1474 reply_nterror(req, NT_STATUS_OBJECT_PATH_NOT_FOUND); 1475 return; 1306 1476 } 1307 1477 } … … 1315 1485 * Ordinary file or directory. 1316 1486 */ 1317 1487 1318 1488 /* 1319 1489 * Check if POSIX semantics are wanted. 1320 1490 */ 1321 1322 new_file_attributes = set_posix_case_semantics(conn, file_attributes); 1323 1324 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname); 1491 1492 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) { 1493 case_state = set_posix_case_semantics(NULL, conn); 1494 file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS; 1495 } 1496 1497 status = resolve_dfspath(ctx, conn, 1498 req->flags2 & FLAGS2_DFS_PATHNAMES, 1499 fname, 1500 &fname); 1325 1501 if (!NT_STATUS_IS_OK(status)) { 1502 TALLOC_FREE(case_state); 1326 1503 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 1327 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 1328 } 1329 return ERROR_NT(status); 1330 } 1331 1332 status = unix_convert(conn, fname, False, NULL, &sbuf); 1504 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, 1505 ERRSRV, ERRbadpath); 1506 return; 1507 } 1508 reply_nterror(req, status); 1509 return; 1510 } 1511 1512 status = unix_convert(ctx, conn, fname, False, &fname, NULL, &sbuf); 1333 1513 if (!NT_STATUS_IS_OK(status)) { 1334 restore_case_semantics(conn, file_attributes); 1335 return ERROR_NT(status); 1514 TALLOC_FREE(case_state); 1515 reply_nterror(req, status); 1516 return; 1336 1517 } 1337 1518 /* All file access must go through check_name() */ 1338 1519 status = check_name(conn, fname); 1339 1520 if (!NT_STATUS_IS_OK(status)) { 1340 restore_case_semantics(conn, file_attributes); 1341 return ERROR_NT(status); 1521 TALLOC_FREE(case_state); 1522 reply_nterror(req, status); 1523 return; 1342 1524 } 1343 1525 … … 1356 1538 if ((dos_mode(conn, fname, &sbuf) & FILE_ATTRIBUTE_READONLY) || 1357 1539 !can_delete_file_in_directory(conn, fname)) { 1358 restore_case_semantics(conn, file_attributes); 1359 return ERROR_NT(NT_STATUS_ACCESS_DENIED); 1360 } 1361 } 1540 TALLOC_FREE(case_state); 1541 reply_nterror(req, NT_STATUS_ACCESS_DENIED); 1542 return; 1543 } 1544 } 1545 1546 #if 0 1547 /* We need to support SeSecurityPrivilege for this. */ 1548 if ((access_mask & SEC_RIGHT_SYSTEM_SECURITY) && 1549 !user_has_privileges(current_user.nt_user_token, 1550 &se_security)) { 1551 TALLOC_FREE(case_state); 1552 reply_nterror(req, NT_STATUS_PRIVILEGE_NOT_HELD); 1553 return; 1554 } 1555 #endif 1362 1556 1363 1557 if (ea_len) { … … 1365 1559 1366 1560 /* We have already checked that ea_len <= data_count here. */ 1367 ea_list = read_nttrans_ea_list(t mp_talloc_ctx(), pdata,1561 ea_list = read_nttrans_ea_list(talloc_tos(), pdata, 1368 1562 ea_len); 1369 1563 if (!ea_list ) { 1370 restore_case_semantics(conn, file_attributes); 1371 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 1564 TALLOC_FREE(case_state); 1565 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 1566 return; 1372 1567 } 1373 1568 } … … 1381 1576 /* Can't open a temp directory. IFS kit test. */ 1382 1577 if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) { 1383 restore_case_semantics(conn, file_attributes); 1384 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 1578 TALLOC_FREE(case_state); 1579 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 1580 return; 1385 1581 } 1386 1582 … … 1392 1588 1393 1589 oplock_request = 0; 1394 status = open_directory(conn, fname, &sbuf,1590 status = open_directory(conn, req, fname, &sbuf, 1395 1591 access_mask, 1396 1592 share_access, 1397 1593 create_disposition, 1398 1594 create_options, 1399 new_file_attributes,1595 file_attributes, 1400 1596 &info, &fsp); 1401 1597 } else { … … 1405 1601 */ 1406 1602 1407 status = open_file_ntcreate(conn, fname,&sbuf,1603 status = open_file_ntcreate(conn,req,fname,&sbuf, 1408 1604 access_mask, 1409 1605 share_access, 1410 1606 create_disposition, 1411 1607 create_options, 1412 new_file_attributes,1608 file_attributes, 1413 1609 oplock_request, 1414 1610 &info, &fsp); 1415 1611 1416 if (!NT_STATUS_IS_OK(status)) { 1417 if (NT_STATUS_EQUAL(status, 1418 NT_STATUS_FILE_IS_A_DIRECTORY)) { 1419 1420 /* 1421 * Fail the open if it was explicitly a non-directory file. 1422 */ 1423 1424 if (create_options & FILE_NON_DIRECTORY_FILE) { 1425 restore_case_semantics(conn, file_attributes); 1426 return ERROR_FORCE_NT(NT_STATUS_FILE_IS_A_DIRECTORY); 1427 } 1428 1429 oplock_request = 0; 1430 status = open_directory(conn, fname, &sbuf, 1431 access_mask, 1432 share_access, 1433 create_disposition, 1434 create_options, 1435 new_file_attributes, 1436 &info, &fsp); 1612 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) { 1613 1614 /* 1615 * Fail the open if it was explicitly a non-directory file. 1616 */ 1617 1618 if (create_options & FILE_NON_DIRECTORY_FILE) { 1619 TALLOC_FREE(case_state); 1620 reply_force_nterror( 1621 req, 1622 NT_STATUS_FILE_IS_A_DIRECTORY); 1623 return; 1437 1624 } 1438 } 1439 } 1440 1441 restore_case_semantics(conn, file_attributes); 1625 1626 oplock_request = 0; 1627 status = open_directory(conn, req, fname, 1628 &sbuf, 1629 access_mask, 1630 share_access, 1631 create_disposition, 1632 create_options, 1633 file_attributes, 1634 &info, &fsp); 1635 } 1636 } 1637 1638 TALLOC_FREE(case_state); 1639 1442 1640 if(!NT_STATUS_IS_OK(status)) { 1443 1444 if (open_was_deferred(SVAL(inbuf,smb_mid))) { 1641 if (open_was_deferred(req->mid)) { 1445 1642 /* We have re-scheduled this call. */ 1446 return -1;1447 } 1448 1449 return ERROR_OPEN(status);1643 return; 1644 } 1645 reply_openerror(req, status); 1646 return; 1450 1647 } 1451 1648 … … 1470 1667 status = set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION); 1471 1668 if (!NT_STATUS_IS_OK(status)) { 1472 talloc_destroy(ctx);1473 1669 close_file(fsp,ERROR_CLOSE); 1474 restore_case_semantics(conn, file_attributes); 1475 return ERROR_NT(status); 1670 TALLOC_FREE(case_state); 1671 reply_nterror(req, status); 1672 return; 1476 1673 } 1477 1674 fsp->access_mask = saved_access_mask; 1478 1675 } 1479 1676 1480 1677 if (ea_len && (info == FILE_WAS_CREATED)) { 1481 1678 status = set_ea(conn, fsp, fname, ea_list); 1482 1679 if (!NT_STATUS_IS_OK(status)) { 1483 1680 close_file(fsp,ERROR_CLOSE); 1484 restore_case_semantics(conn, file_attributes); 1485 return ERROR_NT(status); 1486 } 1487 } 1488 1489 restore_case_semantics(conn, file_attributes); 1681 TALLOC_FREE(case_state); 1682 reply_nterror(req, status); 1683 return; 1684 } 1685 } 1686 1687 TALLOC_FREE(case_state); 1490 1688 1491 1689 file_len = sbuf.st_size; … … 1496 1694 if (!fsp->is_directory && (fattr & aDIR)) { 1497 1695 close_file(fsp,ERROR_CLOSE); 1498 return ERROR_DOS(ERRDOS,ERRnoaccess); 1499 } 1500 1696 reply_doserror(req, ERRDOS, ERRnoaccess); 1697 return; 1698 } 1699 1501 1700 /* Save the requested allocation size. */ 1502 1701 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) { … … 1510 1709 close_file(fsp,ERROR_CLOSE); 1511 1710 /* Can't set allocation size on a directory. */ 1512 return ERROR_NT(NT_STATUS_ACCESS_DENIED); 1711 reply_nterror(req, NT_STATUS_ACCESS_DENIED); 1712 return; 1513 1713 } 1514 1714 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) { 1515 1715 close_file(fsp,ERROR_CLOSE); 1516 return ERROR_NT(NT_STATUS_DISK_FULL); 1716 reply_nterror(req, NT_STATUS_DISK_FULL); 1717 return; 1517 1718 } 1518 1719 } else { … … 1521 1722 } 1522 1723 1523 /* 1724 /* 1524 1725 * If the caller set the extended oplock request bit 1525 1726 * and we granted one (by whatever means) - set the … … 1544 1745 params = nttrans_realloc(ppparams, param_len); 1545 1746 if(params == NULL) { 1546 return ERROR_DOS(ERRDOS,ERRnomem); 1747 reply_doserror(req, ERRDOS, ERRnomem); 1748 return; 1547 1749 } 1548 1750 … … 1559 1761 SCVAL(p,0,NO_OPLOCK_RETURN); 1560 1762 } 1561 1763 1562 1764 p += 2; 1563 1765 SSVAL(p,0,fsp->fnum); … … 1615 1817 1616 1818 /* Send the required number of replies */ 1617 send_nt_replies( outbuf, bufsize, NT_STATUS_OK, params, param_len, *ppdata, 0);1618 1619 return -1;1819 send_nt_replies(req, NT_STATUS_OK, params, param_len, *ppdata, 0); 1820 1821 return; 1620 1822 } 1621 1823 … … 1625 1827 ****************************************************************************/ 1626 1828 1627 int reply_ntcancel(connection_struct *conn, 1628 char *inbuf,char *outbuf,int length,int bufsize) 1829 void reply_ntcancel(connection_struct *conn, struct smb_request *req) 1629 1830 { 1630 1831 /* 1631 1832 * Go through and cancel any pending change notifies. 1632 1833 */ 1633 1634 int mid = SVAL(inbuf,smb_mid); 1834 1635 1835 START_PROFILE(SMBntcancel); 1636 remove_pending_change_notify_requests_by_mid( mid);1637 remove_pending_lock_requests_by_mid( mid);1638 srv_cancel_sign_response( mid);1639 1640 DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", mid));1836 remove_pending_change_notify_requests_by_mid(req->mid); 1837 remove_pending_lock_requests_by_mid(req->mid); 1838 srv_cancel_sign_response(req->mid); 1839 1840 DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", req->mid)); 1641 1841 1642 1842 END_PROFILE(SMBntcancel); 1643 return (-1);1843 return; 1644 1844 } 1645 1845 … … 1648 1848 ****************************************************************************/ 1649 1849 1650 static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *newname, uint32 attrs) 1850 static NTSTATUS copy_internals(TALLOC_CTX *ctx, 1851 connection_struct *conn, 1852 struct smb_request *req, 1853 const char *oldname_in, 1854 const char *newname_in, 1855 uint32 attrs) 1651 1856 { 1652 1857 SMB_STRUCT_STAT sbuf1, sbuf2; 1653 pstring last_component_oldname; 1654 pstring last_component_newname; 1858 char *oldname = NULL; 1859 char *newname = NULL; 1860 char *last_component_oldname = NULL; 1861 char *last_component_newname = NULL; 1655 1862 files_struct *fsp1,*fsp2; 1656 1863 uint32 fattr; … … 1666 1873 } 1667 1874 1668 status = unix_convert(conn, oldname, False, last_component_oldname, &sbuf1); 1875 status = unix_convert(ctx, conn, oldname_in, False, &oldname, 1876 &last_component_oldname, &sbuf1); 1669 1877 if (!NT_STATUS_IS_OK(status)) { 1670 1878 return status; … … 1686 1894 } 1687 1895 1688 status = unix_convert(conn, newname, False, last_component_newname, &sbuf2); 1896 status = unix_convert(ctx, conn, newname_in, False, &newname, 1897 &last_component_newname, &sbuf2); 1689 1898 if (!NT_STATUS_IS_OK(status)) { 1690 1899 return status; … … 1707 1916 1708 1917 /* Ensure this is within the share. */ 1709 status = reduce_name(conn, oldname);1918 status = check_reduced_name(conn, oldname); 1710 1919 if (!NT_STATUS_IS_OK(status)) { 1711 1920 return status; 1712 1921 } 1713 1922 1714 DEBUG(10,("copy_internals: doing file copy %s to %s\n", oldname, newname)); 1715 1716 status = open_file_ntcreate(conn,oldname,&sbuf1, 1923 DEBUG(10,("copy_internals: doing file copy %s to %s\n", 1924 oldname, newname)); 1925 1926 status = open_file_ntcreate(conn, req, oldname, &sbuf1, 1717 1927 FILE_READ_DATA, /* Read-only. */ 1718 1928 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, … … 1727 1937 } 1728 1938 1729 status = open_file_ntcreate(conn, newname,&sbuf2,1939 status = open_file_ntcreate(conn, req, newname, &sbuf2, 1730 1940 FILE_WRITE_DATA, /* Read-only. */ 1731 1941 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, … … 1779 1989 ****************************************************************************/ 1780 1990 1781 int reply_ntrename(connection_struct *conn, 1782 char *inbuf,char *outbuf,int length,int bufsize) 1991 void reply_ntrename(connection_struct *conn, struct smb_request *req) 1783 1992 { 1784 int outsize = 0; 1785 pstring oldname; 1786 pstring newname; 1993 char *oldname = NULL; 1994 char *newname = NULL; 1787 1995 char *p; 1788 1996 NTSTATUS status; 1789 1997 BOOL src_has_wcard = False; 1790 1998 BOOL dest_has_wcard = False; 1791 uint32 attrs = SVAL(inbuf,smb_vwv0); 1792 uint16 rename_type = SVAL(inbuf,smb_vwv1); 1999 uint32 attrs; 2000 uint16 rename_type; 2001 TALLOC_CTX *ctx = talloc_tos(); 1793 2002 1794 2003 START_PROFILE(SMBntrename); 1795 2004 1796 p = smb_buf(inbuf) + 1; 1797 p += srvstr_get_path_wcard(inbuf, oldname, p, sizeof(oldname), 0, STR_TERMINATE, &status, &src_has_wcard); 2005 if (req->wct < 4) { 2006 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 2007 END_PROFILE(SMBntrename); 2008 return; 2009 } 2010 2011 attrs = SVAL(req->inbuf,smb_vwv0); 2012 rename_type = SVAL(req->inbuf,smb_vwv1); 2013 2014 p = smb_buf(req->inbuf) + 1; 2015 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &oldname, p, 2016 0, STR_TERMINATE, &status, 2017 &src_has_wcard); 1798 2018 if (!NT_STATUS_IS_OK(status)) { 2019 reply_nterror(req, status); 1799 2020 END_PROFILE(SMBntrename); 1800 return ERROR_NT(status);2021 return; 1801 2022 } 1802 2023 1803 2024 if( is_ntfs_stream_name(oldname)) { 1804 2025 /* Can't rename a stream. */ 2026 reply_nterror(req, NT_STATUS_ACCESS_DENIED); 1805 2027 END_PROFILE(SMBntrename); 1806 return ERROR_NT(NT_STATUS_ACCESS_DENIED);2028 return; 1807 2029 } 1808 2030 1809 2031 if (ms_has_wild(oldname)) { 2032 reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD); 1810 2033 END_PROFILE(SMBntrename); 1811 return ERROR_NT(NT_STATUS_OBJECT_PATH_SYNTAX_BAD);2034 return; 1812 2035 } 1813 2036 1814 2037 p++; 1815 p += srvstr_get_path_wcard(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, &dest_has_wcard); 2038 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p, 2039 0, STR_TERMINATE, &status, 2040 &dest_has_wcard); 1816 2041 if (!NT_STATUS_IS_OK(status)) { 2042 reply_nterror(req, status); 1817 2043 END_PROFILE(SMBntrename); 1818 return ERROR_NT(status); 1819 } 1820 1821 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, oldname); 2044 return; 2045 } 2046 2047 status = resolve_dfspath(ctx, conn, 2048 req->flags2 & FLAGS2_DFS_PATHNAMES, 2049 oldname, 2050 &oldname); 1822 2051 if (!NT_STATUS_IS_OK(status)) { 2052 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 2053 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, 2054 ERRSRV, ERRbadpath); 2055 END_PROFILE(SMBntrename); 2056 return; 2057 } 2058 reply_nterror(req, status); 1823 2059 END_PROFILE(SMBntrename); 2060 return; 2061 } 2062 2063 status = resolve_dfspath(ctx, conn, 2064 req->flags2 & FLAGS2_DFS_PATHNAMES, 2065 newname, 2066 &newname); 2067 if (!NT_STATUS_IS_OK(status)) { 1824 2068 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 1825 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 1826 } 1827 return ERROR_NT(status); 1828 } 1829 1830 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newname); 1831 if (!NT_STATUS_IS_OK(status)) { 2069 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, 2070 ERRSRV, ERRbadpath); 2071 END_PROFILE(SMBntrename); 2072 return; 2073 } 2074 reply_nterror(req, status); 1832 2075 END_PROFILE(SMBntrename); 1833 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 1834 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 1835 } 1836 return ERROR_NT(status); 2076 return; 1837 2077 } 1838 2078 1839 2079 DEBUG(3,("reply_ntrename : %s -> %s\n",oldname,newname)); 1840 2080 1841 2081 switch(rename_type) { 1842 2082 case RENAME_FLAG_RENAME: 1843 status = rename_internals(conn, oldname, newname, attrs, False, src_has_wcard, dest_has_wcard); 2083 status = rename_internals(ctx, conn, req, oldname, 2084 newname, attrs, False, src_has_wcard, 2085 dest_has_wcard); 1844 2086 break; 1845 2087 case RENAME_FLAG_HARD_LINK: … … 1848 2090 status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD; 1849 2091 } else { 1850 status = hardlink_internals(conn, oldname, newname); 2092 status = hardlink_internals(ctx, 2093 conn, 2094 oldname, 2095 newname); 1851 2096 } 1852 2097 break; … … 1856 2101 status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD; 1857 2102 } else { 1858 status = copy_internals(conn, oldname, newname, attrs); 2103 status = copy_internals(ctx, conn, req, oldname, 2104 newname, attrs); 1859 2105 } 1860 2106 break; … … 1868 2114 1869 2115 if (!NT_STATUS_IS_OK(status)) { 2116 if (open_was_deferred(req->mid)) { 2117 /* We have re-scheduled this call. */ 2118 END_PROFILE(SMBntrename); 2119 return; 2120 } 2121 2122 reply_nterror(req, status); 1870 2123 END_PROFILE(SMBntrename); 1871 if (open_was_deferred(SVAL(inbuf,smb_mid))) { 1872 /* We have re-scheduled this call. */ 1873 return -1; 1874 } 1875 return ERROR_NT(status); 1876 } 1877 1878 outsize = set_message(outbuf,0,0,False); 1879 2124 return; 2125 } 2126 2127 reply_outbuf(req, 0, 0); 2128 1880 2129 END_PROFILE(SMBntrename); 1881 return (outsize);2130 return; 1882 2131 } 1883 2132 1884 2133 /**************************************************************************** 1885 Reply to a notify change - queue the request and 2134 Reply to a notify change - queue the request and 1886 2135 don't allow a directory to be opened. 1887 2136 ****************************************************************************/ 1888 2137 1889 static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf,1890 char *outbuf, int length,1891 int bufsize,1892 uint16 **ppsetup,uint32 setup_count,1893 char **ppparams,1894 uint32 parameter_count,1895 char **ppdata, uint32 data_count,1896 uint32 max_data_count,1897 uint32 max_param_count)2138 static void call_nt_transact_notify_change(connection_struct *conn, 2139 struct smb_request *req, 2140 uint16 **ppsetup, 2141 uint32 setup_count, 2142 char **ppparams, 2143 uint32 parameter_count, 2144 char **ppdata, uint32 data_count, 2145 uint32 max_data_count, 2146 uint32 max_param_count) 1898 2147 { 1899 2148 uint16 *setup = *ppsetup; … … 1904 2153 1905 2154 if(setup_count < 6) { 1906 return ERROR_DOS(ERRDOS,ERRbadfunc); 1907 } 1908 1909 fsp = file_fsp((char *)setup,4); 2155 reply_doserror(req, ERRDOS, ERRbadfunc); 2156 return; 2157 } 2158 2159 fsp = file_fsp(SVAL(setup,4)); 1910 2160 filter = IVAL(setup, 0); 1911 2161 recursive = (SVAL(setup, 6) != 0) ? True : False; … … 1914 2164 1915 2165 if(!fsp) { 1916 return ERROR_DOS(ERRDOS,ERRbadfid); 2166 reply_doserror(req, ERRDOS, ERRbadfid); 2167 return; 1917 2168 } 1918 2169 … … 1921 2172 1922 2173 if (!(filter_string = notify_filter_string(NULL, filter))) { 1923 return ERROR_NT(NT_STATUS_NO_MEMORY); 2174 reply_nterror(req,NT_STATUS_NO_MEMORY); 2175 return; 1924 2176 } 1925 2177 … … 1932 2184 1933 2185 if((!fsp->is_directory) || (conn != fsp->conn)) { 1934 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 2186 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 2187 return; 1935 2188 } 1936 2189 … … 1942 2195 DEBUG(10, ("change_notify_create returned %s\n", 1943 2196 nt_errstr(status))); 1944 return ERROR_NT(status); 2197 reply_nterror(req, status); 2198 return; 1945 2199 } 1946 2200 } … … 1957 2211 */ 1958 2212 1959 change_notify_reply( inbuf, max_param_count, fsp->notify);2213 change_notify_reply(req->inbuf, max_param_count, fsp->notify); 1960 2214 1961 2215 /* … … 1963 2217 * results 1964 2218 */ 1965 return -1;2219 return; 1966 2220 } 1967 2221 … … 1970 2224 */ 1971 2225 1972 status = change_notify_add_request( inbuf, max_param_count, filter,2226 status = change_notify_add_request(req->inbuf, max_param_count, filter, 1973 2227 recursive, fsp); 1974 2228 if (!NT_STATUS_IS_OK(status)) { 1975 return ERROR_NT(status); 1976 } 1977 1978 return -1; 2229 reply_nterror(req, status); 2230 } 2231 return; 1979 2232 } 1980 2233 … … 1983 2236 ****************************************************************************/ 1984 2237 1985 static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 1986 uint16 **ppsetup, uint32 setup_count, 1987 char **ppparams, uint32 parameter_count, 1988 char **ppdata, uint32 data_count, uint32 max_data_count) 2238 static void call_nt_transact_rename(connection_struct *conn, 2239 struct smb_request *req, 2240 uint16 **ppsetup, uint32 setup_count, 2241 char **ppparams, uint32 parameter_count, 2242 char **ppdata, uint32 data_count, 2243 uint32 max_data_count) 1989 2244 { 1990 2245 char *params = *ppparams; 1991 pstring new_name;2246 char *new_name = NULL; 1992 2247 files_struct *fsp = NULL; 1993 2248 BOOL replace_if_exists = False; 1994 2249 BOOL dest_has_wcard = False; 1995 2250 NTSTATUS status; 2251 TALLOC_CTX *ctx = talloc_tos(); 1996 2252 1997 2253 if(parameter_count < 5) { 1998 return ERROR_DOS(ERRDOS,ERRbadfunc); 1999 } 2000 2001 fsp = file_fsp(params, 0); 2254 reply_doserror(req, ERRDOS, ERRbadfunc); 2255 return; 2256 } 2257 2258 fsp = file_fsp(SVAL(params, 0)); 2002 2259 replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False; 2003 CHECK_FSP(fsp, conn); 2004 srvstr_get_path_wcard(inbuf, new_name, params+4, sizeof(new_name), parameter_count - 4, 2005 STR_TERMINATE, &status, &dest_has_wcard); 2260 if (!check_fsp(conn, req, fsp, ¤t_user)) { 2261 return; 2262 } 2263 srvstr_get_path_wcard(ctx, params, req->flags2, &new_name, params+4, 2264 parameter_count - 4, 2265 STR_TERMINATE, &status, &dest_has_wcard); 2006 2266 if (!NT_STATUS_IS_OK(status)) { 2007 return ERROR_NT(status); 2008 } 2009 2010 status = rename_internals(conn, fsp->fsp_name, 2011 new_name, 0, replace_if_exists, False, dest_has_wcard); 2267 reply_nterror(req, status); 2268 return; 2269 } 2270 2271 status = rename_internals(ctx, 2272 conn, 2273 req, 2274 fsp->fsp_name, 2275 new_name, 2276 0, 2277 replace_if_exists, 2278 False, 2279 dest_has_wcard); 2012 2280 2013 2281 if (!NT_STATUS_IS_OK(status)) { 2014 if (open_was_deferred( SVAL(inbuf,smb_mid))) {2282 if (open_was_deferred(req->mid)) { 2015 2283 /* We have re-scheduled this call. */ 2016 return -1; 2017 } 2018 return ERROR_NT(status); 2284 return; 2285 } 2286 reply_nterror(req, status); 2287 return; 2019 2288 } 2020 2289 … … 2022 2291 * Rename was successful. 2023 2292 */ 2024 send_nt_replies( outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);2025 2026 DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n", 2293 send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0); 2294 2295 DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n", 2027 2296 fsp->fsp_name, new_name)); 2028 2029 return -1;2297 2298 return; 2030 2299 } 2031 2300 … … 2051 2320 ****************************************************************************/ 2052 2321 2053 static int call_nt_transact_query_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 2054 uint16 **ppsetup, uint32 setup_count, 2055 char **ppparams, uint32 parameter_count, 2056 char **ppdata, uint32 data_count, uint32 max_data_count) 2322 static void call_nt_transact_query_security_desc(connection_struct *conn, 2323 struct smb_request *req, 2324 uint16 **ppsetup, 2325 uint32 setup_count, 2326 char **ppparams, 2327 uint32 parameter_count, 2328 char **ppdata, 2329 uint32 data_count, 2330 uint32 max_data_count) 2057 2331 { 2058 2332 char *params = *ppparams; … … 2066 2340 2067 2341 if(parameter_count < 8) { 2068 return ERROR_DOS(ERRDOS,ERRbadfunc); 2069 } 2070 2071 fsp = file_fsp(params,0); 2342 reply_doserror(req, ERRDOS, ERRbadfunc); 2343 return; 2344 } 2345 2346 fsp = file_fsp(SVAL(params,0)); 2072 2347 if(!fsp) { 2073 return ERROR_DOS(ERRDOS,ERRbadfid); 2348 reply_doserror(req, ERRDOS, ERRbadfid); 2349 return; 2074 2350 } 2075 2351 … … 2081 2357 params = nttrans_realloc(ppparams, 4); 2082 2358 if(params == NULL) { 2083 return ERROR_DOS(ERRDOS,ERRnomem); 2359 reply_doserror(req, ERRDOS, ERRnomem); 2360 return; 2084 2361 } 2085 2362 2086 2363 if ((mem_ctx = talloc_init("call_nt_transact_query_security_desc")) == NULL) { 2087 2364 DEBUG(0,("call_nt_transact_query_security_desc: talloc_init failed.\n")); 2088 return ERROR_DOS(ERRDOS,ERRnomem); 2365 reply_doserror(req, ERRDOS, ERRnomem); 2366 return; 2089 2367 } 2090 2368 … … 2101 2379 if (sd_size == 0) { 2102 2380 talloc_destroy(mem_ctx); 2103 return(UNIXERROR(ERRDOS,ERRnoaccess)); 2381 reply_unixerror(req, ERRDOS, ERRnoaccess); 2382 return; 2104 2383 } 2105 2384 … … 2110 2389 if(max_data_count < sd_size) { 2111 2390 2112 send_nt_replies( outbuf, bufsize, NT_STATUS_BUFFER_TOO_SMALL,2391 send_nt_replies(req, NT_STATUS_BUFFER_TOO_SMALL, 2113 2392 params, 4, *ppdata, 0); 2114 2393 talloc_destroy(mem_ctx); 2115 return -1;2394 return; 2116 2395 } 2117 2396 … … 2123 2402 if(data == NULL) { 2124 2403 talloc_destroy(mem_ctx); 2125 return ERROR_DOS(ERRDOS,ERRnomem); 2404 reply_doserror(req, ERRDOS, ERRnomem); 2405 return; 2126 2406 } 2127 2407 … … 2148 2428 /* 2149 2429 * Return access denied for want of a better error message.. 2150 */ 2430 */ 2151 2431 talloc_destroy(mem_ctx); 2152 return(UNIXERROR(ERRDOS,ERRnoaccess)); 2432 reply_unixerror(req, ERRDOS, ERRnoaccess); 2433 return; 2153 2434 } 2154 2435 … … 2159 2440 talloc_destroy(mem_ctx); 2160 2441 2161 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, params, 4, data, 2162 (int)sd_size); 2163 return -1; 2442 send_nt_replies(req, NT_STATUS_OK, params, 4, data, (int)sd_size); 2443 return; 2164 2444 } 2165 2445 … … 2168 2448 ****************************************************************************/ 2169 2449 2170 static int call_nt_transact_set_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 2171 uint16 **ppsetup, uint32 setup_count, 2172 char **ppparams, uint32 parameter_count, 2173 char **ppdata, uint32 data_count, uint32 max_data_count) 2450 static void call_nt_transact_set_security_desc(connection_struct *conn, 2451 struct smb_request *req, 2452 uint16 **ppsetup, 2453 uint32 setup_count, 2454 char **ppparams, 2455 uint32 parameter_count, 2456 char **ppdata, 2457 uint32 data_count, 2458 uint32 max_data_count) 2174 2459 { 2175 2460 char *params= *ppparams; … … 2180 2465 2181 2466 if(parameter_count < 8) { 2182 return ERROR_DOS(ERRDOS,ERRbadfunc); 2183 } 2184 2185 if((fsp = file_fsp(params,0)) == NULL) { 2186 return ERROR_DOS(ERRDOS,ERRbadfid); 2467 reply_doserror(req, ERRDOS, ERRbadfunc); 2468 return; 2469 } 2470 2471 if((fsp = file_fsp(SVAL(params,0))) == NULL) { 2472 reply_doserror(req, ERRDOS, ERRbadfid); 2473 return; 2187 2474 } 2188 2475 … … 2197 2484 2198 2485 if (data_count == 0) { 2199 return ERROR_DOS(ERRDOS, ERRnoaccess); 2486 reply_doserror(req, ERRDOS, ERRnoaccess); 2487 return; 2200 2488 } 2201 2489 2202 2490 if (!NT_STATUS_IS_OK(nt_status = set_sd( fsp, data, data_count, security_info_sent))) { 2203 return ERROR_NT(nt_status); 2491 reply_nterror(req, nt_status); 2492 return; 2204 2493 } 2205 2494 2206 2495 done: 2207 2496 2208 send_nt_replies( outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);2209 return -1;2497 send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0); 2498 return; 2210 2499 } 2211 2500 2212 2501 /**************************************************************************** 2213 2502 Reply to NT IOCTL 2214 2503 ****************************************************************************/ 2215 2504 2216 static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 2217 uint16 **ppsetup, uint32 setup_count, 2218 char **ppparams, uint32 parameter_count, 2219 char **ppdata, uint32 data_count, uint32 max_data_count) 2505 static void call_nt_transact_ioctl(connection_struct *conn, 2506 struct smb_request *req, 2507 uint16 **ppsetup, uint32 setup_count, 2508 char **ppparams, uint32 parameter_count, 2509 char **ppdata, uint32 data_count, 2510 uint32 max_data_count) 2220 2511 { 2221 2512 uint32 function; … … 2229 2520 if (setup_count != 8) { 2230 2521 DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count)); 2231 return ERROR_NT(NT_STATUS_NOT_SUPPORTED); 2522 reply_nterror(req, NT_STATUS_NOT_SUPPORTED); 2523 return; 2232 2524 } 2233 2525 … … 2240 2532 function, fidnum, isFSctl, compfilter)); 2241 2533 2242 fsp=file_fsp( (char *)*ppsetup, 4);2534 fsp=file_fsp(fidnum); 2243 2535 /* this check is done in each implemented function case for now 2244 2536 because I don't want to break anything... --metze … … 2252 2544 2253 2545 DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X](but not implemented)\n", fidnum)); 2254 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 2255 0); 2256 return -1; 2257 2258 case FSCTL_0x000900C0: 2259 /* pretend this succeeded - don't know what this really is 2260 but works ok like this --metze 2546 send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0); 2547 return; 2548 2549 case FSCTL_CREATE_OR_GET_OBJECT_ID: 2550 { 2551 unsigned char objid[16]; 2552 2553 /* This should return the object-id on this file. 2554 * I think I'll make this be the inode+dev. JRA. 2261 2555 */ 2262 2556 2263 DEBUG(10,("FSCTL_0x000900C0: called on FID[0x%04X](but not implemented)\n",fidnum)); 2264 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 2265 0); 2266 return -1; 2557 DEBUG(10,("FSCTL_CREATE_OR_GET_OBJECT_ID: called on FID[0x%04X]\n",fidnum)); 2558 2559 if (!fsp_belongs_conn(conn, req, fsp, ¤t_user)) { 2560 return; 2561 } 2562 2563 data_count = 64; 2564 pdata = nttrans_realloc(ppdata, data_count); 2565 if (pdata == NULL) { 2566 reply_nterror(req, NT_STATUS_NO_MEMORY); 2567 return; 2568 } 2569 push_file_id_16(pdata, &fsp->file_id); 2570 memcpy(pdata+16,create_volume_objectid(conn,objid),16); 2571 push_file_id_16(pdata+32, &fsp->file_id); 2572 send_nt_replies(req, NT_STATUS_OK, NULL, 0, 2573 pdata, data_count); 2574 return; 2575 } 2267 2576 2268 2577 case FSCTL_GET_REPARSE_POINT: … … 2272 2581 2273 2582 DEBUG(10,("FSCTL_GET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum)); 2274 send_nt_replies(outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, 2275 NULL, 0, NULL, 0); 2276 return -1; 2583 reply_nterror(req, NT_STATUS_NOT_A_REPARSE_POINT); 2584 return; 2277 2585 2278 2586 case FSCTL_SET_REPARSE_POINT: … … 2282 2590 2283 2591 DEBUG(10,("FSCTL_SET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum)); 2284 send_nt_replies(outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, 2285 NULL, 0, NULL, 0); 2286 return -1; 2287 2592 reply_nterror(req, NT_STATUS_NOT_A_REPARSE_POINT); 2593 return; 2594 2288 2595 case FSCTL_GET_SHADOW_COPY_DATA: /* don't know if this name is right...*/ 2289 2596 { … … 2305 2612 char *cur_pdata; 2306 2613 2307 FSP_BELONGS_CONN(fsp,conn); 2614 if (!fsp_belongs_conn(conn, req, fsp, ¤t_user)) { 2615 return; 2616 } 2308 2617 2309 2618 if (max_data_count < 16) { 2310 2619 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n", 2311 2620 max_data_count)); 2312 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 2621 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 2622 return; 2313 2623 } 2314 2624 … … 2320 2630 if (shadow_mem_ctx == NULL) { 2321 2631 DEBUG(0,("talloc_init(SHADOW_COPY_DATA) failed!\n")); 2322 return ERROR_NT(NT_STATUS_NO_MEMORY); 2632 reply_nterror(req, NT_STATUS_NO_MEMORY); 2633 return; 2323 2634 } 2324 2635 … … 2327 2638 DEBUG(0,("TALLOC_ZERO() failed!\n")); 2328 2639 talloc_destroy(shadow_mem_ctx); 2329 return ERROR_NT(NT_STATUS_NO_MEMORY); 2330 } 2331 2640 reply_nterror(req, NT_STATUS_NO_MEMORY); 2641 return; 2642 } 2643 2332 2644 shadow_data->mem_ctx = shadow_mem_ctx; 2333 2645 2334 2646 /* 2335 2647 * Call the VFS routine to actually do the work. … … 2340 2652 DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n", 2341 2653 conn->connectpath)); 2342 return ERROR_NT(NT_STATUS_NOT_SUPPORTED); 2654 reply_nterror(req, NT_STATUS_NOT_SUPPORTED); 2655 return; 2343 2656 } else { 2344 2657 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n", 2345 2658 conn->connectpath)); 2346 return ERROR_NT(NT_STATUS_UNSUCCESSFUL); 2659 reply_nterror(req, NT_STATUS_UNSUCCESSFUL); 2660 return; 2347 2661 } 2348 2662 } … … 2360 2674 max_data_count,data_count)); 2361 2675 talloc_destroy(shadow_data->mem_ctx); 2362 return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL); 2676 reply_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); 2677 return; 2363 2678 } 2364 2679 … … 2366 2681 if (pdata == NULL) { 2367 2682 talloc_destroy(shadow_data->mem_ctx); 2368 return ERROR_NT(NT_STATUS_NO_MEMORY); 2369 } 2683 reply_nterror(req, NT_STATUS_NO_MEMORY); 2684 return; 2685 } 2370 2686 2371 2687 cur_pdata = pdata; … … 2388 2704 if (labels && shadow_data->labels) { 2389 2705 for (i=0;i<shadow_data->num_volumes;i++) { 2390 srvstr_push(outbuf, cur_pdata, shadow_data->labels[i], 2*sizeof(SHADOW_COPY_LABEL), STR_UNICODE|STR_TERMINATE); 2706 srvstr_push(pdata, req->flags2, 2707 cur_pdata, shadow_data->labels[i], 2708 2*sizeof(SHADOW_COPY_LABEL), 2709 STR_UNICODE|STR_TERMINATE); 2391 2710 cur_pdata+=2*sizeof(SHADOW_COPY_LABEL); 2392 2711 DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i])); … … 2396 2715 talloc_destroy(shadow_data->mem_ctx); 2397 2716 2398 send_nt_replies( outbuf, bufsize, NT_STATUS_OK, NULL, 0,2717 send_nt_replies(req, NT_STATUS_OK, NULL, 0, 2399 2718 pdata, data_count); 2400 2719 2401 return -1;2720 return; 2402 2721 } 2403 2722 2404 2723 case FSCTL_FIND_FILES_BY_SID: /* I hope this name is right */ 2405 2724 { 2406 /* pretend this succeeded - 2407 * 2725 /* pretend this succeeded - 2726 * 2408 2727 * we have to send back a list with all files owned by this SID 2409 2728 * … … 2413 2732 uid_t uid; 2414 2733 size_t sid_len = MIN(data_count-4,SID_MAX_SIZE); 2415 2734 2416 2735 DEBUG(10,("FSCTL_FIND_FILES_BY_SID: called on FID[0x%04X]\n",fidnum)); 2417 2736 2418 FSP_BELONGS_CONN(fsp,conn); 2737 if (!fsp_belongs_conn(conn, req, fsp, ¤t_user)) { 2738 return; 2739 } 2419 2740 2420 2741 /* unknown 4 bytes: this is not the length of the sid :-( */ 2421 2742 /*unknown = IVAL(pdata,0);*/ 2422 2743 2423 2744 sid_parse(pdata+4,sid_len,&sid); 2424 2745 DEBUGADD(10,("for SID: %s\n",sid_string_static(&sid))); … … 2429 2750 uid = (-1); 2430 2751 } 2431 2752 2432 2753 /* we can take a look at the find source :-) 2433 2754 * … … 2442 2763 * 2443 2764 * we don't send all files at once 2444 * and at the next we should *not* start from the beginning, 2445 * so we have to cache the result 2765 * and at the next we should *not* start from the beginning, 2766 * so we have to cache the result 2446 2767 * 2447 2768 * --metze 2448 2769 */ 2449 2770 2450 2771 /* this works for now... */ 2451 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, NULL, 0, 2452 NULL, 0); 2453 return -1; 2454 } 2772 send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0); 2773 return; 2774 } 2455 2775 default: 2456 2776 if (!logged_message) { … … 2461 2781 } 2462 2782 2463 re turn ERROR_NT(NT_STATUS_NOT_SUPPORTED);2783 reply_nterror(req, NT_STATUS_NOT_SUPPORTED); 2464 2784 } 2465 2785 … … 2467 2787 #ifdef HAVE_SYS_QUOTAS 2468 2788 /**************************************************************************** 2469 Reply to get user quota 2789 Reply to get user quota 2470 2790 ****************************************************************************/ 2471 2791 2472 static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 2473 uint16 **ppsetup, uint32 setup_count, 2474 char **ppparams, uint32 parameter_count, 2475 char **ppdata, uint32 data_count, uint32 max_data_count) 2792 static void call_nt_transact_get_user_quota(connection_struct *conn, 2793 struct smb_request *req, 2794 uint16 **ppsetup, 2795 uint32 setup_count, 2796 char **ppparams, 2797 uint32 parameter_count, 2798 char **ppdata, 2799 uint32 data_count, 2800 uint32 max_data_count) 2476 2801 { 2477 2802 NTSTATUS nt_status = NT_STATUS_OK; … … 2497 2822 DEBUG(1,("get_user_quota: access_denied service [%s] user [%s]\n", 2498 2823 lp_servicename(SNUM(conn)),conn->user)); 2499 return ERROR_DOS(ERRDOS,ERRnoaccess); 2824 reply_doserror(req, ERRDOS, ERRnoaccess); 2825 return; 2500 2826 } 2501 2827 … … 2506 2832 if (parameter_count < 4) { 2507 2833 DEBUG(0,("TRANSACT_GET_USER_QUOTA: requires %d >= 4 bytes parameters\n",parameter_count)); 2508 return ERROR_DOS(ERRDOS,ERRinvalidparam); 2509 } 2510 2834 reply_doserror(req, ERRDOS, ERRinvalidparam); 2835 return; 2836 } 2837 2511 2838 /* maybe we can check the quota_fnum */ 2512 fsp = file_fsp( params,0);2839 fsp = file_fsp(SVAL(params,0)); 2513 2840 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) { 2514 2841 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n")); 2515 return ERROR_NT(NT_STATUS_INVALID_HANDLE); 2842 reply_nterror(req, NT_STATUS_INVALID_HANDLE); 2843 return; 2516 2844 } 2517 2845 … … 2522 2850 2523 2851 level = SVAL(params,2); 2524 2525 /* unknown 12 bytes leading in params */ 2526 2852 2853 /* unknown 12 bytes leading in params */ 2854 2527 2855 switch (level) { 2528 2856 case TRANSACT_GET_USER_QUOTA_LIST_CONTINUE: 2529 2857 /* seems that we should continue with the enum here --metze */ 2530 2858 2531 if (qt_handle->quota_list!=NULL && 2859 if (qt_handle->quota_list!=NULL && 2532 2860 qt_handle->tmp_list==NULL) { 2533 2861 2534 2862 /* free the list */ 2535 2863 free_ntquota_list(&(qt_handle->quota_list)); … … 2539 2867 params = nttrans_realloc(ppparams, param_len); 2540 2868 if(params == NULL) { 2541 return ERROR_DOS(ERRDOS,ERRnomem); 2869 reply_doserror(req, ERRDOS, ERRnomem); 2870 return; 2542 2871 } 2543 2872 … … 2557 2886 } 2558 2887 2559 if (start_enum && vfs_get_user_ntquota_list(fsp,&(qt_handle->quota_list))!=0) 2560 return ERROR_DOS(ERRSRV,ERRerror); 2888 if (start_enum && vfs_get_user_ntquota_list(fsp,&(qt_handle->quota_list))!=0) { 2889 reply_doserror(req, ERRSRV, ERRerror); 2890 return; 2891 } 2561 2892 2562 2893 /* Realloc the size of parameters and data we will return */ … … 2564 2895 params = nttrans_realloc(ppparams, param_len); 2565 2896 if(params == NULL) { 2566 return ERROR_DOS(ERRDOS,ERRnomem); 2897 reply_doserror(req, ERRDOS, ERRnomem); 2898 return; 2567 2899 } 2568 2900 2569 2901 /* we should not trust the value in max_data_count*/ 2570 2902 max_data_count = MIN(max_data_count,2048); 2571 2903 2572 2904 pdata = nttrans_realloc(ppdata, max_data_count);/* should be max data count from client*/ 2573 2905 if(pdata == NULL) { 2574 return ERROR_DOS(ERRDOS,ERRnomem); 2906 reply_doserror(req, ERRDOS, ERRnomem); 2907 return; 2575 2908 } 2576 2909 … … 2579 2912 /* set params Size of returned Quota Data 4 bytes*/ 2580 2913 /* but set it later when we know it */ 2581 2914 2582 2915 /* for each entry push the data */ 2583 2916 … … 2596 2929 /* nextoffset entry 4 bytes */ 2597 2930 SIVAL(entry,0,entry_len); 2598 2931 2599 2932 /* then the len of the SID 4 bytes */ 2600 2933 SIVAL(entry,4,sid_len); 2601 2934 2602 2935 /* unknown data 8 bytes SMB_BIG_UINT */ 2603 2936 SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-metze*/ 2604 2937 2605 2938 /* the used disk space 8 bytes SMB_BIG_UINT */ 2606 2939 SBIG_UINT(entry,16,tmp_list->quotas->usedspace); 2607 2940 2608 2941 /* the soft quotas 8 bytes SMB_BIG_UINT */ 2609 2942 SBIG_UINT(entry,24,tmp_list->quotas->softlim); 2610 2943 2611 2944 /* the hard quotas 8 bytes SMB_BIG_UINT */ 2612 2945 SBIG_UINT(entry,32,tmp_list->quotas->hardlim); 2613 2946 2614 2947 /* and now the SID */ 2615 2948 sid_linearize(entry+40, sid_len, &tmp_list->quotas->sid); 2616 2949 } 2617 2950 2618 2951 qt_handle->tmp_list = tmp_list; 2619 2952 2620 2953 /* overwrite the offset of the last entry */ 2621 2954 SIVAL(entry-entry_len,0,0); … … 2628 2961 2629 2962 case TRANSACT_GET_USER_QUOTA_FOR_SID: 2630 2631 /* unknown 4 bytes IVAL(pdata,0) */ 2632 2963 2964 /* unknown 4 bytes IVAL(pdata,0) */ 2965 2633 2966 if (data_count < 8) { 2634 2967 DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %d bytes data\n",data_count,8)); 2635 return ERROR_DOS(ERRDOS,ERRunknownlevel); 2968 reply_doserror(req, ERRDOS, ERRunknownlevel); 2969 return; 2636 2970 } 2637 2971 … … 2639 2973 /* Ensure this is less than 1mb. */ 2640 2974 if (sid_len > (1024*1024)) { 2641 return ERROR_DOS(ERRDOS,ERRnomem); 2975 reply_doserror(req, ERRDOS, ERRnomem); 2976 return; 2642 2977 } 2643 2978 2644 2979 if (data_count < 8+sid_len) { 2645 2980 DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %lu bytes data\n",data_count,(unsigned long)(8+sid_len))); 2646 return ERROR_DOS(ERRDOS,ERRunknownlevel); 2981 reply_doserror(req, ERRDOS, ERRunknownlevel); 2982 return; 2647 2983 } 2648 2984 … … 2660 2996 2661 2997 sid_parse(pdata+8,sid_len,&sid); 2662 2998 2663 2999 if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) { 2664 3000 ZERO_STRUCT(qt); 2665 /* 2666 * we have to return zero's in all fields 3001 /* 3002 * we have to return zero's in all fields 2667 3003 * instead of returning an error here 2668 3004 * --metze … … 2674 3010 params = nttrans_realloc(ppparams, param_len); 2675 3011 if(params == NULL) { 2676 return ERROR_DOS(ERRDOS,ERRnomem); 3012 reply_doserror(req, ERRDOS, ERRnomem); 3013 return; 2677 3014 } 2678 3015 2679 3016 pdata = nttrans_realloc(ppdata, data_len); 2680 3017 if(pdata == NULL) { 2681 return ERROR_DOS(ERRDOS,ERRnomem); 3018 reply_doserror(req, ERRDOS, ERRnomem); 3019 return; 2682 3020 } 2683 3021 … … 2686 3024 /* set params Size of returned Quota Data 4 bytes*/ 2687 3025 SIVAL(params,0,data_len); 2688 3026 2689 3027 /* nextoffset entry 4 bytes */ 2690 3028 SIVAL(entry,0,0); 2691 3029 2692 3030 /* then the len of the SID 4 bytes */ 2693 3031 SIVAL(entry,4,sid_len); 2694 3032 2695 3033 /* unknown data 8 bytes SMB_BIG_UINT */ 2696 3034 SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-mezte*/ 2697 3035 2698 3036 /* the used disk space 8 bytes SMB_BIG_UINT */ 2699 3037 SBIG_UINT(entry,16,qt.usedspace); 2700 3038 2701 3039 /* the soft quotas 8 bytes SMB_BIG_UINT */ 2702 3040 SBIG_UINT(entry,24,qt.softlim); 2703 3041 2704 3042 /* the hard quotas 8 bytes SMB_BIG_UINT */ 2705 3043 SBIG_UINT(entry,32,qt.hardlim); 2706 3044 2707 3045 /* and now the SID */ 2708 3046 sid_linearize(entry+40, sid_len, &sid); … … 2712 3050 default: 2713 3051 DEBUG(0,("do_nt_transact_get_user_quota: fnum %d unknown level 0x%04hX\n",fsp->fnum,level)); 2714 return ERROR_DOS(ERRSRV,ERRerror); 3052 reply_doserror(req, ERRSRV, ERRerror); 3053 return; 2715 3054 break; 2716 3055 } 2717 3056 2718 send_nt_replies( outbuf, bufsize, nt_status, params, param_len,3057 send_nt_replies(req, nt_status, params, param_len, 2719 3058 pdata, data_len); 2720 2721 return -1;2722 3059 } 2723 3060 … … 2726 3063 ****************************************************************************/ 2727 3064 2728 static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 2729 uint16 **ppsetup, uint32 setup_count, 2730 char **ppparams, uint32 parameter_count, 2731 char **ppdata, uint32 data_count, uint32 max_data_count) 3065 static void call_nt_transact_set_user_quota(connection_struct *conn, 3066 struct smb_request *req, 3067 uint16 **ppsetup, 3068 uint32 setup_count, 3069 char **ppparams, 3070 uint32 parameter_count, 3071 char **ppdata, 3072 uint32 data_count, 3073 uint32 max_data_count) 2732 3074 { 2733 3075 char *params = *ppparams; … … 2745 3087 DEBUG(1,("set_user_quota: access_denied service [%s] user [%s]\n", 2746 3088 lp_servicename(SNUM(conn)),conn->user)); 2747 return ERROR_DOS(ERRDOS,ERRnoaccess); 3089 reply_doserror(req, ERRDOS, ERRnoaccess); 3090 return; 2748 3091 } 2749 3092 … … 2754 3097 if (parameter_count < 2) { 2755 3098 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= 2 bytes parameters\n",parameter_count)); 2756 return ERROR_DOS(ERRDOS,ERRinvalidparam); 2757 } 2758 3099 reply_doserror(req, ERRDOS, ERRinvalidparam); 3100 return; 3101 } 3102 2759 3103 /* maybe we can check the quota_fnum */ 2760 fsp = file_fsp( params,0);3104 fsp = file_fsp(SVAL(params,0)); 2761 3105 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) { 2762 3106 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n")); 2763 return ERROR_NT(NT_STATUS_INVALID_HANDLE); 3107 reply_nterror(req, NT_STATUS_INVALID_HANDLE); 3108 return; 2764 3109 } 2765 3110 2766 3111 if (data_count < 40) { 2767 3112 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %d bytes data\n",data_count,40)); 2768 return ERROR_DOS(ERRDOS,ERRunknownlevel); 3113 reply_doserror(req, ERRDOS, ERRunknownlevel); 3114 return; 2769 3115 } 2770 3116 … … 2779 3125 if (data_count < 40+sid_len) { 2780 3126 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %lu bytes data\n",data_count,(unsigned long)40+sid_len)); 2781 return ERROR_DOS(ERRDOS,ERRunknownlevel); 2782 } 2783 2784 /* unknown 8 bytes in pdata 3127 reply_doserror(req, ERRDOS, ERRunknownlevel); 3128 return; 3129 } 3130 3131 /* unknown 8 bytes in pdata 2785 3132 * maybe its the change time in NTTIME 2786 3133 */ … … 2795 3142 (IVAL(pdata,20)!=0xFFFFFFFF))) { 2796 3143 /* more than 32 bits? */ 2797 return ERROR_DOS(ERRDOS,ERRunknownlevel); 3144 reply_doserror(req, ERRDOS, ERRunknownlevel); 3145 return; 2798 3146 } 2799 3147 #endif /* LARGE_SMB_OFF_T */ … … 2808 3156 (IVAL(pdata,28)!=0xFFFFFFFF))) { 2809 3157 /* more than 32 bits? */ 2810 return ERROR_DOS(ERRDOS,ERRunknownlevel); 3158 reply_doserror(req, ERRDOS, ERRunknownlevel); 3159 return; 2811 3160 } 2812 3161 #endif /* LARGE_SMB_OFF_T */ … … 2821 3170 (IVAL(pdata,36)!=0xFFFFFFFF))) { 2822 3171 /* more than 32 bits? */ 2823 return ERROR_DOS(ERRDOS,ERRunknownlevel); 3172 reply_doserror(req, ERRDOS, ERRunknownlevel); 3173 return; 2824 3174 } 2825 3175 #endif /* LARGE_SMB_OFF_T */ 2826 3176 2827 3177 sid_parse(pdata+40,sid_len,&sid); 2828 3178 DEBUGADD(8,("SID: %s\n",sid_string_static(&sid))); … … 2831 3181 2832 3182 if (vfs_set_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) { 2833 return ERROR_DOS(ERRSRV,ERRerror); 2834 } 2835 2836 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, params, param_len, 3183 reply_doserror(req, ERRSRV, ERRerror); 3184 return; 3185 } 3186 3187 send_nt_replies(req, NT_STATUS_OK, params, param_len, 2837 3188 pdata, data_len); 2838 2839 return -1;2840 3189 } 2841 3190 #endif /* HAVE_SYS_QUOTAS */ 2842 3191 2843 static inthandle_nttrans(connection_struct *conn,2844 struct trans_state *state,2845 char *inbuf, char *outbuf, int size, int bufsize)3192 static void handle_nttrans(connection_struct *conn, 3193 struct trans_state *state, 3194 struct smb_request *req) 2846 3195 { 2847 int outsize;2848 2849 3196 if (Protocol >= PROTOCOL_NT1) { 2850 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */ 3197 req->flags2 |= 0x40; /* IS_LONG_NAME */ 3198 SSVAL(req->inbuf,smb_flg2,req->flags2); 2851 3199 } 2852 3200 … … 2856 3204 { 2857 3205 START_PROFILE(NT_transact_create); 2858 outsize = call_nt_transact_create(conn, inbuf, outbuf,2859 size, bufsize,2860 2861 &state->param, state->total_param,2862 2863 3206 call_nt_transact_create( 3207 conn, req, 3208 &state->setup, state->setup_count, 3209 &state->param, state->total_param, 3210 &state->data, state->total_data, 3211 state->max_data_return); 2864 3212 END_PROFILE(NT_transact_create); 2865 3213 break; … … 2869 3217 { 2870 3218 START_PROFILE(NT_transact_ioctl); 2871 outsize = call_nt_transact_ioctl(conn, inbuf, outbuf, 2872 size, bufsize, 2873 &state->setup, state->setup_count, 2874 &state->param, state->total_param, 2875 &state->data, state->total_data, state->max_data_return); 3219 call_nt_transact_ioctl( 3220 conn, req, 3221 &state->setup, state->setup_count, 3222 &state->param, state->total_param, 3223 &state->data, state->total_data, 3224 state->max_data_return); 2876 3225 END_PROFILE(NT_transact_ioctl); 2877 3226 break; … … 2881 3230 { 2882 3231 START_PROFILE(NT_transact_set_security_desc); 2883 outsize = call_nt_transact_set_security_desc(conn, inbuf, outbuf, 2884 size, bufsize, 2885 &state->setup, state->setup_count, 2886 &state->param, state->total_param, 2887 &state->data, state->total_data, state->max_data_return); 3232 call_nt_transact_set_security_desc( 3233 conn, req, 3234 &state->setup, state->setup_count, 3235 &state->param, state->total_param, 3236 &state->data, state->total_data, 3237 state->max_data_return); 2888 3238 END_PROFILE(NT_transact_set_security_desc); 2889 3239 break; … … 2893 3243 { 2894 3244 START_PROFILE(NT_transact_notify_change); 2895 outsize =call_nt_transact_notify_change(2896 conn, inbuf, outbuf, size, bufsize,3245 call_nt_transact_notify_change( 3246 conn, req, 2897 3247 &state->setup, state->setup_count, 2898 &state->param, state->total_param, 3248 &state->param, state->total_param, 2899 3249 &state->data, state->total_data, 2900 3250 state->max_data_return, … … 2907 3257 { 2908 3258 START_PROFILE(NT_transact_rename); 2909 outsize = call_nt_transact_rename(conn, inbuf, outbuf, 2910 size, bufsize, 2911 &state->setup, state->setup_count, 2912 &state->param, state->total_param, 2913 &state->data, state->total_data, state->max_data_return); 3259 call_nt_transact_rename( 3260 conn, req, 3261 &state->setup, state->setup_count, 3262 &state->param, state->total_param, 3263 &state->data, state->total_data, 3264 state->max_data_return); 2914 3265 END_PROFILE(NT_transact_rename); 2915 3266 break; … … 2919 3270 { 2920 3271 START_PROFILE(NT_transact_query_security_desc); 2921 outsize = call_nt_transact_query_security_desc(conn, inbuf, outbuf, 2922 size, bufsize, 2923 &state->setup, state->setup_count, 2924 &state->param, state->total_param, 2925 &state->data, state->total_data, state->max_data_return); 3272 call_nt_transact_query_security_desc( 3273 conn, req, 3274 &state->setup, state->setup_count, 3275 &state->param, state->total_param, 3276 &state->data, state->total_data, 3277 state->max_data_return); 2926 3278 END_PROFILE(NT_transact_query_security_desc); 2927 3279 break; … … 2932 3284 { 2933 3285 START_PROFILE(NT_transact_get_user_quota); 2934 outsize = call_nt_transact_get_user_quota(conn, inbuf, outbuf, 2935 size, bufsize, 2936 &state->setup, state->setup_count, 2937 &state->param, state->total_param, 2938 &state->data, state->total_data, state->max_data_return); 3286 call_nt_transact_get_user_quota( 3287 conn, req, 3288 &state->setup, state->setup_count, 3289 &state->param, state->total_param, 3290 &state->data, state->total_data, 3291 state->max_data_return); 2939 3292 END_PROFILE(NT_transact_get_user_quota); 2940 3293 break; … … 2944 3297 { 2945 3298 START_PROFILE(NT_transact_set_user_quota); 2946 outsize = call_nt_transact_set_user_quota(conn, inbuf, outbuf, 2947 size, bufsize, 2948 &state->setup, state->setup_count, 2949 &state->param, state->total_param, 2950 &state->data, state->total_data, state->max_data_return); 3299 call_nt_transact_set_user_quota( 3300 conn, req, 3301 &state->setup, state->setup_count, 3302 &state->param, state->total_param, 3303 &state->data, state->total_data, 3304 state->max_data_return); 2951 3305 END_PROFILE(NT_transact_set_user_quota); 2952 break; 3306 break; 2953 3307 } 2954 3308 #endif /* HAVE_SYS_QUOTAS */ … … 2956 3310 default: 2957 3311 /* Error in request */ 2958 DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", 2959 state->call)); 2960 return ERROR_DOS(ERRSRV,ERRerror); 2961 } 2962 return outsize; 3312 DEBUG(0,("handle_nttrans: Unknown request %d in " 3313 "nttrans call\n", state->call)); 3314 reply_doserror(req, ERRSRV, ERRerror); 3315 return; 3316 } 3317 return; 2963 3318 } 2964 3319 … … 2967 3322 ****************************************************************************/ 2968 3323 2969 int reply_nttrans(connection_struct *conn, 2970 char *inbuf,char *outbuf,int size,int bufsize) 3324 void reply_nttrans(connection_struct *conn, struct smb_request *req) 2971 3325 { 2972 int outsize = 0; 2973 uint32 pscnt = IVAL(inbuf,smb_nt_ParameterCount); 2974 uint32 psoff = IVAL(inbuf,smb_nt_ParameterOffset); 2975 uint32 dscnt = IVAL(inbuf,smb_nt_DataCount); 2976 uint32 dsoff = IVAL(inbuf,smb_nt_DataOffset); 2977 2978 uint16 function_code = SVAL( inbuf, smb_nt_Function); 3326 uint32 pscnt; 3327 uint32 psoff; 3328 uint32 dscnt; 3329 uint32 dsoff; 3330 uint16 function_code; 2979 3331 NTSTATUS result; 2980 3332 struct trans_state *state; 3333 int size; 2981 3334 2982 3335 START_PROFILE(SMBnttrans); 2983 3336 3337 if (req->wct < 19) { 3338 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 3339 END_PROFILE(SMBnttrans); 3340 return; 3341 } 3342 3343 size = smb_len(req->inbuf) + 4; 3344 pscnt = IVAL(req->inbuf,smb_nt_ParameterCount); 3345 psoff = IVAL(req->inbuf,smb_nt_ParameterOffset); 3346 dscnt = IVAL(req->inbuf,smb_nt_DataCount); 3347 dsoff = IVAL(req->inbuf,smb_nt_DataOffset); 3348 function_code = SVAL(req->inbuf, smb_nt_Function); 3349 2984 3350 if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) { 3351 reply_doserror(req, ERRSRV, ERRaccess); 2985 3352 END_PROFILE(SMBnttrans); 2986 return ERROR_DOS(ERRSRV,ERRaccess);2987 } 2988 2989 result = allow_new_trans(conn->pending_trans, SVAL(inbuf, smb_mid));3353 return; 3354 } 3355 3356 result = allow_new_trans(conn->pending_trans, req->mid); 2990 3357 if (!NT_STATUS_IS_OK(result)) { 2991 3358 DEBUG(2, ("Got invalid nttrans request: %s\n", nt_errstr(result))); 3359 reply_nterror(req, result); 2992 3360 END_PROFILE(SMBnttrans); 2993 return ERROR_NT(result);3361 return; 2994 3362 } 2995 3363 2996 3364 if ((state = TALLOC_P(conn->mem_ctx, struct trans_state)) == NULL) { 3365 reply_doserror(req, ERRSRV, ERRaccess); 2997 3366 END_PROFILE(SMBnttrans); 2998 return ERROR_DOS(ERRSRV,ERRaccess);3367 return; 2999 3368 } 3000 3369 3001 3370 state->cmd = SMBnttrans; 3002 3371 3003 state->mid = SVAL(inbuf,smb_mid);3004 state->vuid = SVAL(inbuf,smb_uid);3005 state->total_data = IVAL( inbuf, smb_nt_TotalDataCount);3372 state->mid = req->mid; 3373 state->vuid = req->vuid; 3374 state->total_data = IVAL(req->inbuf, smb_nt_TotalDataCount); 3006 3375 state->data = NULL; 3007 state->total_param = IVAL( inbuf, smb_nt_TotalParameterCount);3376 state->total_param = IVAL(req->inbuf, smb_nt_TotalParameterCount); 3008 3377 state->param = NULL; 3009 state->max_data_return = IVAL( inbuf,smb_nt_MaxDataCount);3010 state->max_param_return = IVAL( inbuf,smb_nt_MaxParameterCount);3378 state->max_data_return = IVAL(req->inbuf,smb_nt_MaxDataCount); 3379 state->max_param_return = IVAL(req->inbuf,smb_nt_MaxParameterCount); 3011 3380 3012 3381 /* setup count is in *words* */ 3013 state->setup_count = 2*CVAL( inbuf,smb_nt_SetupCount);3382 state->setup_count = 2*CVAL(req->inbuf,smb_nt_SetupCount); 3014 3383 state->setup = NULL; 3015 3384 state->call = function_code; 3016 3385 3017 /* 3386 /* 3018 3387 * All nttrans messages we handle have smb_wct == 19 + 3019 3388 * state->setup_count. Ensure this is so as a sanity check. 3020 3389 */ 3021 3390 3022 if( CVAL(inbuf, smb_wct)!= 19 + (state->setup_count/2)) {3391 if(req->wct != 19 + (state->setup_count/2)) { 3023 3392 DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n", 3024 CVAL(inbuf, smb_wct), 19 + (state->setup_count/2)));3393 req->wct, 19 + (state->setup_count/2))); 3025 3394 goto bad_param; 3026 3395 } … … 3029 3398 if ((state->total_data > (1024*1024*128)) || 3030 3399 (state->total_param > (1024*1024*128))) { 3400 reply_doserror(req, ERRDOS, ERRnomem); 3031 3401 END_PROFILE(SMBnttrans); 3032 return ERROR_DOS(ERRDOS,ERRnomem);3402 return; 3033 3403 } 3034 3404 … … 3043 3413 "bytes !\n", (unsigned int)state->total_data)); 3044 3414 TALLOC_FREE(state); 3415 reply_doserror(req, ERRDOS, ERRnomem); 3045 3416 END_PROFILE(SMBnttrans); 3046 return (ERROR_DOS(ERRDOS,ERRnomem));3047 } 3417 return; 3418 } 3048 3419 if ((dsoff+dscnt < dsoff) || (dsoff+dscnt < dscnt)) 3049 3420 goto bad_param; 3050 if ((smb_base(inbuf)+dsoff+dscnt > inbuf + size) || 3051 (smb_base(inbuf)+dsoff+dscnt < smb_base(inbuf))) 3421 if ((smb_base(req->inbuf)+dsoff+dscnt 3422 > (char *)req->inbuf + size) || 3423 (smb_base(req->inbuf)+dsoff+dscnt < smb_base(req->inbuf))) 3052 3424 goto bad_param; 3053 3425 3054 memcpy(state->data,smb_base( inbuf)+dsoff,dscnt);3426 memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt); 3055 3427 } 3056 3428 … … 3063 3435 SAFE_FREE(state->data); 3064 3436 TALLOC_FREE(state); 3437 reply_doserror(req, ERRDOS, ERRnomem); 3065 3438 END_PROFILE(SMBnttrans); 3066 return (ERROR_DOS(ERRDOS,ERRnomem));3067 } 3439 return; 3440 } 3068 3441 if ((psoff+pscnt < psoff) || (psoff+pscnt < pscnt)) 3069 3442 goto bad_param; 3070 if ((smb_base(inbuf)+psoff+pscnt > inbuf + size) || 3071 (smb_base(inbuf)+psoff+pscnt < smb_base(inbuf))) 3443 if ((smb_base(req->inbuf)+psoff+pscnt 3444 > (char *)req->inbuf + size) || 3445 (smb_base(req->inbuf)+psoff+pscnt < smb_base(req->inbuf))) 3072 3446 goto bad_param; 3073 3447 3074 memcpy(state->param,smb_base( inbuf)+psoff,pscnt);3448 memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt); 3075 3449 } 3076 3450 … … 3087 3461 SAFE_FREE(state->param); 3088 3462 TALLOC_FREE(state); 3463 reply_doserror(req, ERRDOS, ERRnomem); 3089 3464 END_PROFILE(SMBnttrans); 3090 return ERROR_DOS(ERRDOS,ERRnomem);3465 return; 3091 3466 } 3092 3467 … … 3099 3474 } 3100 3475 3101 memcpy( state->setup, &inbuf[smb_nt_SetupStart], state->setup_count); 3102 dump_data(10, (char *)state->setup, state->setup_count); 3476 memcpy( state->setup, &req->inbuf[smb_nt_SetupStart], 3477 state->setup_count); 3478 dump_data(10, (uint8 *)state->setup, state->setup_count); 3103 3479 } 3104 3480 3105 3481 if ((state->received_data == state->total_data) && 3106 3482 (state->received_param == state->total_param)) { 3107 outsize = handle_nttrans(conn, state, inbuf, outbuf, 3108 size, bufsize); 3483 handle_nttrans(conn, state, req); 3109 3484 SAFE_FREE(state->param); 3110 3485 SAFE_FREE(state->data); 3111 3486 TALLOC_FREE(state); 3112 3487 END_PROFILE(SMBnttrans); 3113 return outsize;3488 return; 3114 3489 } 3115 3490 … … 3118 3493 /* We need to send an interim response then receive the rest 3119 3494 of the parameter/data bytes */ 3120 outsize = set_message(outbuf,0,0,False);3121 show_msg( outbuf);3495 reply_outbuf(req, 0, 0); 3496 show_msg((char *)req->outbuf); 3122 3497 END_PROFILE(SMBnttrans); 3123 return outsize;3498 return; 3124 3499 3125 3500 bad_param: … … 3129 3504 SAFE_FREE(state->param); 3130 3505 TALLOC_FREE(state); 3506 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 3131 3507 END_PROFILE(SMBnttrans); 3132 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);3508 return; 3133 3509 } 3134 3510 3135 3511 /**************************************************************************** 3136 3512 Reply to a SMBnttranss 3137 3513 ****************************************************************************/ 3138 3514 3139 int reply_nttranss(connection_struct *conn, char *inbuf,char *outbuf, 3140 int size,int bufsize) 3515 void reply_nttranss(connection_struct *conn, struct smb_request *req) 3141 3516 { 3142 int outsize = 0;3143 3517 unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp; 3144 3518 struct trans_state *state; 3145 3519 3520 int size; 3521 3146 3522 START_PROFILE(SMBnttranss); 3147 3523 3148 show_msg(inbuf); 3524 show_msg((char *)req->inbuf); 3525 3526 if (req->wct < 18) { 3527 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 3528 END_PROFILE(SMBnttranss); 3529 return; 3530 } 3149 3531 3150 3532 for (state = conn->pending_trans; state != NULL; 3151 3533 state = state->next) { 3152 if (state->mid == SVAL(inbuf,smb_mid)) {3534 if (state->mid == req->mid) { 3153 3535 break; 3154 3536 } … … 3156 3538 3157 3539 if ((state == NULL) || (state->cmd != SMBnttrans)) { 3540 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 3158 3541 END_PROFILE(SMBnttranss); 3159 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);3542 return; 3160 3543 } 3161 3544 3162 3545 /* Revise state->total_param and state->total_data in case they have 3163 3546 changed downwards */ 3164 if (IVAL(inbuf, smb_nts_TotalParameterCount) < state->total_param) { 3165 state->total_param = IVAL(inbuf, smb_nts_TotalParameterCount); 3166 } 3167 if (IVAL(inbuf, smb_nts_TotalDataCount) < state->total_data) { 3168 state->total_data = IVAL(inbuf, smb_nts_TotalDataCount); 3169 } 3170 3171 pcnt = IVAL(inbuf,smb_nts_ParameterCount); 3172 poff = IVAL(inbuf, smb_nts_ParameterOffset); 3173 pdisp = IVAL(inbuf, smb_nts_ParameterDisplacement); 3174 3175 dcnt = IVAL(inbuf, smb_nts_DataCount); 3176 ddisp = IVAL(inbuf, smb_nts_DataDisplacement); 3177 doff = IVAL(inbuf, smb_nts_DataOffset); 3547 if (IVAL(req->inbuf, smb_nts_TotalParameterCount) 3548 < state->total_param) { 3549 state->total_param = IVAL(req->inbuf, 3550 smb_nts_TotalParameterCount); 3551 } 3552 if (IVAL(req->inbuf, smb_nts_TotalDataCount) < state->total_data) { 3553 state->total_data = IVAL(req->inbuf, smb_nts_TotalDataCount); 3554 } 3555 3556 size = smb_len(req->inbuf) + 4; 3557 3558 pcnt = IVAL(req->inbuf,smb_nts_ParameterCount); 3559 poff = IVAL(req->inbuf, smb_nts_ParameterOffset); 3560 pdisp = IVAL(req->inbuf, smb_nts_ParameterDisplacement); 3561 3562 dcnt = IVAL(req->inbuf, smb_nts_DataCount); 3563 ddisp = IVAL(req->inbuf, smb_nts_DataDisplacement); 3564 doff = IVAL(req->inbuf, smb_nts_DataOffset); 3178 3565 3179 3566 state->received_param += pcnt; 3180 3567 state->received_data += dcnt; 3181 3568 3182 3569 if ((state->received_data > state->total_data) || 3183 3570 (state->received_param > state->total_param)) … … 3191 3578 if (pdisp > state->total_param) 3192 3579 goto bad_param; 3193 if ((smb_base(inbuf) + poff + pcnt > inbuf + size) || 3194 (smb_base(inbuf) + poff + pcnt < smb_base(inbuf))) 3580 if ((smb_base(req->inbuf) + poff + pcnt 3581 > (char *)req->inbuf + size) || 3582 (smb_base(req->inbuf) + poff + pcnt 3583 < smb_base(req->inbuf))) 3195 3584 goto bad_param; 3196 3585 if (state->param + pdisp < state->param) 3197 3586 goto bad_param; 3198 3587 3199 memcpy(state->param+pdisp, smb_base(inbuf)+poff,3588 memcpy(state->param+pdisp, smb_base(req->inbuf)+poff, 3200 3589 pcnt); 3201 3590 } … … 3208 3597 if (ddisp > state->total_data) 3209 3598 goto bad_param; 3210 if ((smb_base(inbuf) + doff + dcnt > inbuf + size) || 3211 (smb_base(inbuf) + doff + dcnt < smb_base(inbuf))) 3599 if ((smb_base(req->inbuf) + doff + dcnt 3600 > (char *)req->inbuf + size) || 3601 (smb_base(req->inbuf) + doff + dcnt 3602 < smb_base(req->inbuf))) 3212 3603 goto bad_param; 3213 3604 if (state->data + ddisp < state->data) 3214 3605 goto bad_param; 3215 3606 3216 memcpy(state->data+ddisp, smb_base( inbuf)+doff,3217 dcnt); 3607 memcpy(state->data+ddisp, smb_base(req->inbuf)+doff, 3608 dcnt); 3218 3609 } 3219 3610 … … 3221 3612 (state->received_data < state->total_data)) { 3222 3613 END_PROFILE(SMBnttranss); 3223 return -1;3224 } 3225 3226 /* construct_reply_common has done us the favor to pre-fill the3227 * co mmand field with SMBnttranss which is wrong :-)3228 * /3229 SCVAL(outbuf,smb_com,SMBnttrans);3230 3231 outsize = handle_nttrans(conn, state, inbuf, outbuf, 3232 size, bufsize);3614 return; 3615 } 3616 3617 /* 3618 * construct_reply_common will copy smb_com from inbuf to 3619 * outbuf. SMBnttranss is wrong here. 3620 */ 3621 SCVAL(req->inbuf,smb_com,SMBnttrans); 3622 3623 handle_nttrans(conn, state, req); 3233 3624 3234 3625 DLIST_REMOVE(conn->pending_trans, state); … … 3236 3627 SAFE_FREE(state->param); 3237 3628 TALLOC_FREE(state); 3238 3239 if (outsize == 0) {3240 END_PROFILE(SMBnttranss);3241 return(ERROR_DOS(ERRSRV,ERRnosupport));3242 }3243 3244 3629 END_PROFILE(SMBnttranss); 3245 return (outsize);3630 return; 3246 3631 3247 3632 bad_param: … … 3252 3637 SAFE_FREE(state->param); 3253 3638 TALLOC_FREE(state); 3639 reply_nterror(req, NT_STATUS_INVALID_PARAMETER); 3254 3640 END_PROFILE(SMBnttranss); 3255 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);3641 return; 3256 3642 }
Note:
See TracChangeset
for help on using the changeset viewer.