00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "includes.h"
00023
00024 extern int max_send;
00025 extern enum protocol_types Protocol;
00026 extern int smb_read_error;
00027 extern struct current_user current_user;
00028
00029 static const char *known_nt_pipes[] = {
00030 "\\LANMAN",
00031 "\\srvsvc",
00032 "\\samr",
00033 "\\wkssvc",
00034 "\\NETLOGON",
00035 "\\ntlsa",
00036 "\\ntsvcs",
00037 "\\lsass",
00038 "\\lsarpc",
00039 "\\winreg",
00040 "\\initshutdown",
00041 "\\spoolss",
00042 "\\netdfs",
00043 "\\rpcecho",
00044 "\\svcctl",
00045 "\\eventlog",
00046 "\\unixinfo",
00047 NULL
00048 };
00049
00050 static char *nttrans_realloc(char **ptr, size_t size)
00051 {
00052 if (ptr==NULL) {
00053 smb_panic("nttrans_realloc() called with NULL ptr\n");
00054 }
00055
00056 *ptr = (char *)SMB_REALLOC(*ptr, size);
00057 if(*ptr == NULL) {
00058 return NULL;
00059 }
00060 memset(*ptr,'\0',size);
00061 return *ptr;
00062 }
00063
00064
00065
00066
00067
00068
00069
00070
00071 int send_nt_replies(char *outbuf, int bufsize, NTSTATUS nt_error,
00072 char *params, int paramsize, char *pdata, int datasize)
00073 {
00074 int data_to_send = datasize;
00075 int params_to_send = paramsize;
00076 int useable_space;
00077 char *pp = params;
00078 char *pd = pdata;
00079 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
00080 int alignment_offset = 3;
00081 int data_alignment_offset = 0;
00082
00083
00084
00085
00086
00087
00088 set_message(outbuf,18,0,True);
00089
00090 if (NT_STATUS_V(nt_error)) {
00091 ERROR_NT(nt_error);
00092 }
00093
00094
00095
00096
00097
00098
00099 if(params_to_send == 0 && data_to_send == 0) {
00100 show_msg(outbuf);
00101 if (!send_smb(smbd_server_fd(),outbuf)) {
00102 exit_server_cleanly("send_nt_replies: send_smb failed.");
00103 }
00104 return 0;
00105 }
00106
00107
00108
00109
00110
00111
00112
00113 if (((params_to_send % 4) != 0) && (data_to_send != 0)) {
00114 data_alignment_offset = 4 - (params_to_send % 4);
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124 useable_space = bufsize - ((smb_buf(outbuf)+
00125 alignment_offset+data_alignment_offset) -
00126 outbuf);
00127
00128
00129
00130
00131
00132
00133 useable_space = MIN(useable_space,
00134 max_send - (alignment_offset+data_alignment_offset));
00135
00136
00137 while (params_to_send || data_to_send) {
00138
00139
00140
00141
00142
00143 total_sent_thistime = params_to_send + data_to_send +
00144 alignment_offset + data_alignment_offset;
00145
00146
00147
00148
00149
00150 total_sent_thistime = MIN(total_sent_thistime, useable_space);
00151
00152 set_message(outbuf, 18, total_sent_thistime, True);
00153
00154
00155
00156
00157
00158 SIVAL(outbuf,smb_ntr_TotalParameterCount,paramsize);
00159 SIVAL(outbuf,smb_ntr_TotalDataCount,datasize);
00160
00161
00162
00163
00164
00165
00166 params_sent_thistime = MIN(params_to_send,useable_space);
00167 data_sent_thistime = useable_space - params_sent_thistime;
00168 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
00169
00170 SIVAL(outbuf,smb_ntr_ParameterCount,params_sent_thistime);
00171
00172 if(params_sent_thistime == 0) {
00173 SIVAL(outbuf,smb_ntr_ParameterOffset,0);
00174 SIVAL(outbuf,smb_ntr_ParameterDisplacement,0);
00175 } else {
00176
00177
00178
00179
00180
00181
00182
00183 SIVAL(outbuf,smb_ntr_ParameterOffset,
00184 ((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
00185
00186
00187
00188
00189 SIVAL(outbuf,smb_ntr_ParameterDisplacement,pp - params);
00190 }
00191
00192
00193
00194
00195
00196 SIVAL(outbuf,smb_ntr_DataCount, data_sent_thistime);
00197
00198 if(data_sent_thistime == 0) {
00199 SIVAL(outbuf,smb_ntr_DataOffset,0);
00200 SIVAL(outbuf,smb_ntr_DataDisplacement, 0);
00201 } else {
00202
00203
00204
00205
00206
00207 SIVAL(outbuf,smb_ntr_DataOffset,((smb_buf(outbuf)+alignment_offset) -
00208 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
00209 SIVAL(outbuf,smb_ntr_DataDisplacement, pd - pdata);
00210 }
00211
00212
00213
00214
00215
00216 if(params_sent_thistime) {
00217 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
00218 }
00219
00220
00221
00222
00223
00224 if(data_sent_thistime) {
00225 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
00226 data_alignment_offset,pd,data_sent_thistime);
00227 }
00228
00229 DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
00230 params_sent_thistime, data_sent_thistime, useable_space));
00231 DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
00232 params_to_send, data_to_send, paramsize, datasize));
00233
00234
00235 show_msg(outbuf);
00236 if (!send_smb(smbd_server_fd(),outbuf)) {
00237 exit_server_cleanly("send_nt_replies: send_smb failed.");
00238 }
00239
00240 pp += params_sent_thistime;
00241 pd += data_sent_thistime;
00242
00243 params_to_send -= params_sent_thistime;
00244 data_to_send -= data_sent_thistime;
00245
00246
00247
00248
00249
00250 if(params_to_send < 0 || data_to_send < 0) {
00251 DEBUG(0,("send_nt_replies failed sanity check pts = %d, dts = %d\n!!!",
00252 params_to_send, data_to_send));
00253 return -1;
00254 }
00255 }
00256
00257 return 0;
00258 }
00259
00260
00261
00262
00263
00264 BOOL is_ntfs_stream_name(const char *fname)
00265 {
00266 if (lp_posix_pathnames()) {
00267 return False;
00268 }
00269 return (strchr_m(fname, ':') != NULL) ? True : False;
00270 }
00271
00272
00273
00274
00275
00276 static BOOL saved_case_sensitive;
00277 static BOOL saved_case_preserve;
00278 static BOOL saved_short_case_preserve;
00279
00280
00281
00282
00283
00284 static uint32 set_posix_case_semantics(connection_struct *conn, uint32 file_attributes)
00285 {
00286 if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
00287 return file_attributes;
00288 }
00289
00290 saved_case_sensitive = conn->case_sensitive;
00291 saved_case_preserve = conn->case_preserve;
00292 saved_short_case_preserve = conn->short_case_preserve;
00293
00294
00295 conn->case_sensitive = True;
00296 conn->case_preserve = True;
00297 conn->short_case_preserve = True;
00298
00299 return (file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
00300 }
00301
00302
00303
00304
00305
00306 static void restore_case_semantics(connection_struct *conn, uint32 file_attributes)
00307 {
00308 if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
00309 return;
00310 }
00311
00312 conn->case_sensitive = saved_case_sensitive;
00313 conn->case_preserve = saved_case_preserve;
00314 conn->short_case_preserve = saved_short_case_preserve;
00315 }
00316
00317
00318
00319
00320
00321 static int nt_open_pipe(char *fname, connection_struct *conn,
00322 char *inbuf, char *outbuf, int *ppnum)
00323 {
00324 smb_np_struct *p = NULL;
00325 uint16 vuid = SVAL(inbuf, smb_uid);
00326 int i;
00327
00328 DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname));
00329
00330
00331
00332 if (lp_disable_spoolss() && strequal(fname, "\\spoolss")) {
00333 return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe));
00334 }
00335
00336 for( i = 0; known_nt_pipes[i]; i++ ) {
00337 if( strequal(fname,known_nt_pipes[i])) {
00338 break;
00339 }
00340 }
00341
00342 if ( known_nt_pipes[i] == NULL ) {
00343 return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe));
00344 }
00345
00346
00347 fname++;
00348
00349 DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname));
00350
00351 p = open_rpc_pipe_p(fname, conn, vuid);
00352 if (!p) {
00353 return(ERROR_DOS(ERRSRV,ERRnofids));
00354 }
00355
00356
00357
00358 if ( !store_pipe_opendb( p ) ) {
00359 DEBUG(3,("nt_open_pipe: failed to store %s pipe open.\n", fname));
00360 }
00361
00362 *ppnum = p->pnum;
00363 return 0;
00364 }
00365
00366
00367
00368
00369
00370 static int do_ntcreate_pipe_open(connection_struct *conn,
00371 char *inbuf,char *outbuf,int length,int bufsize)
00372 {
00373 pstring fname;
00374 int ret;
00375 int pnum = -1;
00376 char *p = NULL;
00377 uint32 flags = IVAL(inbuf,smb_ntcreate_Flags);
00378
00379 srvstr_pull_buf(inbuf, fname, smb_buf(inbuf), sizeof(fname), STR_TERMINATE);
00380
00381 if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0) {
00382 return ret;
00383 }
00384
00385
00386
00387
00388
00389 if (flags & EXTENDED_RESPONSE_REQUIRED) {
00390
00391
00392
00393
00394
00395 set_message(outbuf,50,0,True);
00396 SCVAL(outbuf,smb_wct,42);
00397 } else {
00398 set_message(outbuf,34,0,True);
00399 }
00400
00401 p = outbuf + smb_vwv2;
00402 p++;
00403 SSVAL(p,0,pnum);
00404 p += 2;
00405 SIVAL(p,0,FILE_WAS_OPENED);
00406 p += 4;
00407 p += 32;
00408 SIVAL(p,0,FILE_ATTRIBUTE_NORMAL);
00409 p += 20;
00410
00411 SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
00412
00413 SSVAL(p,2, 0x5FF);
00414 p += 4;
00415
00416 if (flags & EXTENDED_RESPONSE_REQUIRED) {
00417 p += 25;
00418 SIVAL(p,0,FILE_GENERIC_ALL);
00419
00420
00421
00422
00423
00424 SIVAL(p,4,(FILE_GENERIC_READ|FILE_GENERIC_WRITE)&~FILE_APPEND_DATA);
00425 }
00426
00427 DEBUG(5,("do_ntcreate_pipe_open: open pipe = %s\n", fname));
00428
00429 return chain_reply(inbuf,outbuf,length,bufsize);
00430 }
00431
00432
00433
00434
00435
00436 int reply_ntcreate_and_X_quota(connection_struct *conn,
00437 char *inbuf,
00438 char *outbuf,
00439 int length,
00440 int bufsize,
00441 enum FAKE_FILE_TYPE fake_file_type,
00442 const char *fname)
00443 {
00444 int result;
00445 char *p;
00446 uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess);
00447 files_struct *fsp;
00448 NTSTATUS status;
00449
00450 status = open_fake_file(conn, fake_file_type, fname, desired_access,
00451 &fsp);
00452
00453 if (!NT_STATUS_IS_OK(status)) {
00454 return ERROR_NT(status);
00455 }
00456
00457 set_message(outbuf,34,0,True);
00458
00459 p = outbuf + smb_vwv2;
00460
00461
00462 p++;
00463 SSVAL(p,0,fsp->fnum);
00464
00465 DEBUG(5,("reply_ntcreate_and_X_quota: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name));
00466
00467 result = chain_reply(inbuf,outbuf,length,bufsize);
00468 return result;
00469 }
00470
00471
00472
00473
00474
00475 int reply_ntcreate_and_X(connection_struct *conn,
00476 char *inbuf,char *outbuf,int length,int bufsize)
00477 {
00478 int result;
00479 pstring fname;
00480 uint32 flags = IVAL(inbuf,smb_ntcreate_Flags);
00481 uint32 access_mask = IVAL(inbuf,smb_ntcreate_DesiredAccess);
00482 uint32 file_attributes = IVAL(inbuf,smb_ntcreate_FileAttributes);
00483 uint32 new_file_attributes;
00484 uint32 share_access = IVAL(inbuf,smb_ntcreate_ShareAccess);
00485 uint32 create_disposition = IVAL(inbuf,smb_ntcreate_CreateDisposition);
00486 uint32 create_options = IVAL(inbuf,smb_ntcreate_CreateOptions);
00487 uint16 root_dir_fid = (uint16)IVAL(inbuf,smb_ntcreate_RootDirectoryFid);
00488
00489
00490 int oplock_request = 0;
00491 uint32 fattr=0;
00492 SMB_OFF_T file_len = 0;
00493 SMB_STRUCT_STAT sbuf;
00494 int info = 0;
00495 files_struct *fsp = NULL;
00496 char *p = NULL;
00497 struct timespec c_timespec;
00498 struct timespec a_timespec;
00499 struct timespec m_timespec;
00500 BOOL extended_oplock_granted = False;
00501 NTSTATUS status;
00502
00503 START_PROFILE(SMBntcreateX);
00504
00505 DEBUG(10,("reply_ntcreate_and_X: flags = 0x%x, access_mask = 0x%x "
00506 "file_attributes = 0x%x, share_access = 0x%x, "
00507 "create_disposition = 0x%x create_options = 0x%x "
00508 "root_dir_fid = 0x%x\n",
00509 (unsigned int)flags,
00510 (unsigned int)access_mask,
00511 (unsigned int)file_attributes,
00512 (unsigned int)share_access,
00513 (unsigned int)create_disposition,
00514 (unsigned int)create_options,
00515 (unsigned int)root_dir_fid ));
00516
00517
00518
00519
00520
00521 if (IS_IPC(conn)) {
00522 if (lp_nt_pipe_support()) {
00523 END_PROFILE(SMBntcreateX);
00524 return do_ntcreate_pipe_open(conn,inbuf,outbuf,length,bufsize);
00525 } else {
00526 END_PROFILE(SMBntcreateX);
00527 return(ERROR_DOS(ERRDOS,ERRnoaccess));
00528 }
00529 }
00530
00531 if (create_options & FILE_OPEN_BY_FILE_ID) {
00532 END_PROFILE(SMBntcreateX);
00533 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
00534 }
00535
00536
00537
00538
00539
00540 if(root_dir_fid != 0) {
00541
00542
00543
00544 pstring rel_fname;
00545 files_struct *dir_fsp = file_fsp(inbuf,smb_ntcreate_RootDirectoryFid);
00546
00547 if(!dir_fsp) {
00548 END_PROFILE(SMBntcreateX);
00549 return ERROR_DOS(ERRDOS,ERRbadfid);
00550 }
00551
00552 if(!dir_fsp->is_directory) {
00553
00554 srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status);
00555 if (!NT_STATUS_IS_OK(status)) {
00556 END_PROFILE(SMBntcreateX);
00557 return ERROR_NT(status);
00558 }
00559
00560
00561
00562
00563
00564 if( is_ntfs_stream_name(fname)) {
00565 END_PROFILE(SMBntcreateX);
00566 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
00567 }
00568
00569
00570
00571
00572
00573
00574
00575
00576 END_PROFILE(SMBntcreateX);
00577 return(ERROR_DOS(ERRDOS,ERRbadfid));
00578 }
00579
00580
00581
00582
00583
00584 pstrcpy( fname, dir_fsp->fsp_name );
00585
00586 if (ISDOT(fname)) {
00587 fname[0] = '\0';
00588 } else {
00589 size_t dir_name_len = strlen(fname);
00590
00591
00592
00593
00594 if((fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
00595 pstrcat(fname, "/");
00596 }
00597 }
00598
00599 srvstr_get_path(inbuf, rel_fname, smb_buf(inbuf), sizeof(rel_fname), 0, STR_TERMINATE, &status);
00600 if (!NT_STATUS_IS_OK(status)) {
00601 END_PROFILE(SMBntcreateX);
00602 return ERROR_NT(status);
00603 }
00604 pstrcat(fname, rel_fname);
00605 } else {
00606 srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status);
00607 if (!NT_STATUS_IS_OK(status)) {
00608 END_PROFILE(SMBntcreateX);
00609 return ERROR_NT(status);
00610 }
00611
00612
00613
00614
00615
00616 if( is_ntfs_stream_name(fname)) {
00617 enum FAKE_FILE_TYPE fake_file_type = is_fake_file(fname);
00618 if (fake_file_type!=FAKE_FILE_TYPE_NONE) {
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628 result = reply_ntcreate_and_X_quota(conn, inbuf, outbuf, length, bufsize,
00629 fake_file_type, fname);
00630 END_PROFILE(SMBntcreateX);
00631 return result;
00632 } else {
00633 END_PROFILE(SMBntcreateX);
00634 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
00635 }
00636 }
00637 }
00638
00639
00640
00641
00642
00643 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
00644 if (!NT_STATUS_IS_OK(status)) {
00645 END_PROFILE(SMBntcreateX);
00646 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
00647 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
00648 }
00649 return ERROR_NT(status);
00650 }
00651
00652 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
00653 if (oplock_request) {
00654 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
00655 }
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665 new_file_attributes = set_posix_case_semantics(conn, file_attributes);
00666
00667 status = unix_convert(conn, fname, False, NULL, &sbuf);
00668 if (!NT_STATUS_IS_OK(status)) {
00669 restore_case_semantics(conn, file_attributes);
00670 END_PROFILE(SMBntcreateX);
00671 return ERROR_NT(status);
00672 }
00673
00674 status = check_name(conn, fname);
00675 if (!NT_STATUS_IS_OK(status)) {
00676 restore_case_semantics(conn, file_attributes);
00677 END_PROFILE(SMBntcreateX);
00678 return ERROR_NT(status);
00679 }
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689 if (lp_acl_check_permissions(SNUM(conn))
00690 && (create_disposition != FILE_CREATE)
00691 && (share_access & FILE_SHARE_DELETE)
00692 && (access_mask & DELETE_ACCESS)) {
00693 if ((dos_mode(conn, fname, &sbuf) & FILE_ATTRIBUTE_READONLY) ||
00694 !can_delete_file_in_directory(conn, fname)) {
00695 restore_case_semantics(conn, file_attributes);
00696 END_PROFILE(SMBntcreateX);
00697 return ERROR_NT(NT_STATUS_ACCESS_DENIED);
00698 }
00699 }
00700
00701
00702
00703
00704
00705 if(create_options & FILE_DIRECTORY_FILE) {
00706
00707
00708 if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) {
00709 END_PROFILE(SMBntcreateX);
00710 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
00711 }
00712
00713 oplock_request = 0;
00714 status = open_directory(conn, fname, &sbuf,
00715 access_mask,
00716 share_access,
00717 create_disposition,
00718 create_options,
00719 new_file_attributes,
00720 &info, &fsp);
00721 } else {
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740 status = open_file_ntcreate(conn,fname,&sbuf,
00741 access_mask,
00742 share_access,
00743 create_disposition,
00744 create_options,
00745 new_file_attributes,
00746 oplock_request,
00747 &info, &fsp);
00748
00749 if (!NT_STATUS_IS_OK(status)) {
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769 if (NT_STATUS_EQUAL(status,
00770 NT_STATUS_FILE_IS_A_DIRECTORY)) {
00771
00772
00773
00774
00775
00776 if (create_options & FILE_NON_DIRECTORY_FILE) {
00777 restore_case_semantics(conn, file_attributes);
00778 END_PROFILE(SMBntcreateX);
00779 return ERROR_FORCE_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
00780 }
00781
00782 oplock_request = 0;
00783 status = open_directory(conn, fname, &sbuf,
00784 access_mask,
00785 share_access,
00786 create_disposition,
00787 create_options,
00788 new_file_attributes,
00789 &info, &fsp);
00790
00791 }
00792 }
00793 }
00794
00795 restore_case_semantics(conn, file_attributes);
00796
00797 if(!NT_STATUS_IS_OK(status)) {
00798 END_PROFILE(SMBntcreateX);
00799
00800 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
00801
00802 return -1;
00803 }
00804
00805 return ERROR_OPEN(status);
00806 }
00807
00808 file_len = sbuf.st_size;
00809 fattr = dos_mode(conn,fname,&sbuf);
00810 if(fattr == 0) {
00811 fattr = FILE_ATTRIBUTE_NORMAL;
00812 }
00813 if (!fsp->is_directory && (fattr & aDIR)) {
00814 close_file(fsp,ERROR_CLOSE);
00815 END_PROFILE(SMBntcreateX);
00816 return ERROR_DOS(ERRDOS,ERRnoaccess);
00817 }
00818
00819
00820 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
00821 SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize);
00822 #ifdef LARGE_SMB_OFF_T
00823 allocation_size |= (((SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize + 4)) << 32);
00824 #endif
00825 if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) {
00826 fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
00827 if (fsp->is_directory) {
00828 close_file(fsp,ERROR_CLOSE);
00829 END_PROFILE(SMBntcreateX);
00830
00831 return ERROR_NT(NT_STATUS_ACCESS_DENIED);
00832 }
00833 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
00834 close_file(fsp,ERROR_CLOSE);
00835 END_PROFILE(SMBntcreateX);
00836 return ERROR_NT(NT_STATUS_DISK_FULL);
00837 }
00838 } else {
00839 fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)file_len);
00840 }
00841 }
00842
00843
00844
00845
00846
00847
00848
00849 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
00850 extended_oplock_granted = True;
00851 }
00852
00853 if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
00854 extended_oplock_granted = True;
00855 }
00856
00857 if (flags & EXTENDED_RESPONSE_REQUIRED) {
00858
00859
00860
00861
00862
00863 set_message(outbuf,50,0,True);
00864 SCVAL(outbuf,smb_wct,42);
00865 } else {
00866 set_message(outbuf,34,0,True);
00867 }
00868
00869 p = outbuf + smb_vwv2;
00870
00871
00872
00873
00874
00875
00876 if (extended_oplock_granted) {
00877 if (flags & REQUEST_BATCH_OPLOCK) {
00878 SCVAL(p,0, BATCH_OPLOCK_RETURN);
00879 } else {
00880 SCVAL(p,0, EXCLUSIVE_OPLOCK_RETURN);
00881 }
00882 } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
00883 SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
00884 } else {
00885 SCVAL(p,0,NO_OPLOCK_RETURN);
00886 }
00887
00888 p++;
00889 SSVAL(p,0,fsp->fnum);
00890 p += 2;
00891 if ((create_disposition == FILE_SUPERSEDE) && (info == FILE_WAS_OVERWRITTEN)) {
00892 SIVAL(p,0,FILE_WAS_SUPERSEDED);
00893 } else {
00894 SIVAL(p,0,info);
00895 }
00896 p += 4;
00897
00898
00899 c_timespec = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
00900 a_timespec = get_atimespec(&sbuf);
00901 m_timespec = get_mtimespec(&sbuf);
00902
00903 if (lp_dos_filetime_resolution(SNUM(conn))) {
00904 dos_filetime_timespec(&c_timespec);
00905 dos_filetime_timespec(&a_timespec);
00906 dos_filetime_timespec(&m_timespec);
00907 }
00908
00909 put_long_date_timespec(p, c_timespec);
00910 p += 8;
00911 put_long_date_timespec(p, a_timespec);
00912 p += 8;
00913 put_long_date_timespec(p, m_timespec);
00914 p += 8;
00915 put_long_date_timespec(p, m_timespec);
00916 p += 8;
00917 SIVAL(p,0,fattr);
00918 p += 4;
00919 SOFF_T(p, 0, get_allocation_size(conn,fsp,&sbuf));
00920 p += 8;
00921 SOFF_T(p,0,file_len);
00922 p += 8;
00923 if (flags & EXTENDED_RESPONSE_REQUIRED) {
00924 SSVAL(p,2,0x7);
00925 }
00926 p += 4;
00927 SCVAL(p,0,fsp->is_directory ? 1 : 0);
00928
00929 if (flags & EXTENDED_RESPONSE_REQUIRED) {
00930 uint32 perms = 0;
00931 p += 25;
00932 if (fsp->is_directory || can_write_to_file(conn, fname, &sbuf)) {
00933 perms = FILE_GENERIC_ALL;
00934 } else {
00935 perms = FILE_GENERIC_READ|FILE_EXECUTE;
00936 }
00937 SIVAL(p,0,perms);
00938 }
00939
00940 DEBUG(5,("reply_ntcreate_and_X: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name));
00941
00942 result = chain_reply(inbuf,outbuf,length,bufsize);
00943 END_PROFILE(SMBntcreateX);
00944 return result;
00945 }
00946
00947
00948
00949
00950
00951 static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
00952 uint16 **ppsetup, uint32 setup_count,
00953 char **ppparams, uint32 parameter_count,
00954 char **ppdata, uint32 data_count)
00955 {
00956 pstring fname;
00957 char *params = *ppparams;
00958 int ret;
00959 int pnum = -1;
00960 char *p = NULL;
00961 NTSTATUS status;
00962 size_t param_len;
00963 uint32 flags;
00964
00965
00966
00967
00968
00969 if(parameter_count < 54) {
00970 DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)parameter_count));
00971 return ERROR_DOS(ERRDOS,ERRnoaccess);
00972 }
00973
00974 flags = IVAL(params,0);
00975
00976 srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
00977 if (!NT_STATUS_IS_OK(status)) {
00978 return ERROR_NT(status);
00979 }
00980
00981 if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0) {
00982 return ret;
00983 }
00984
00985
00986 if (flags & EXTENDED_RESPONSE_REQUIRED) {
00987
00988 param_len = 101;
00989 } else {
00990 param_len = 69;
00991 }
00992 params = nttrans_realloc(ppparams, param_len);
00993 if(params == NULL) {
00994 return ERROR_DOS(ERRDOS,ERRnomem);
00995 }
00996
00997 p = params;
00998 SCVAL(p,0,NO_OPLOCK_RETURN);
00999
01000 p += 2;
01001 SSVAL(p,0,pnum);
01002 p += 2;
01003 SIVAL(p,0,FILE_WAS_OPENED);
01004 p += 8;
01005
01006 p += 32;
01007 SIVAL(p,0,FILE_ATTRIBUTE_NORMAL);
01008 p += 20;
01009
01010 SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
01011
01012 SSVAL(p,2, 0x5FF);
01013 p += 4;
01014
01015 if (flags & EXTENDED_RESPONSE_REQUIRED) {
01016 p += 25;
01017 SIVAL(p,0,FILE_GENERIC_ALL);
01018
01019
01020
01021
01022
01023 SIVAL(p,4,(FILE_GENERIC_READ|FILE_GENERIC_WRITE)&~FILE_APPEND_DATA);
01024 }
01025
01026 DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname));
01027
01028
01029 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, params, param_len, *ppdata, 0);
01030
01031 return -1;
01032 }
01033
01034
01035
01036
01037
01038 static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 security_info_sent)
01039 {
01040 prs_struct pd;
01041 SEC_DESC *psd = NULL;
01042 TALLOC_CTX *mem_ctx;
01043 BOOL ret;
01044
01045 if (sd_len == 0 || !lp_nt_acl_support(SNUM(fsp->conn))) {
01046 return NT_STATUS_OK;
01047 }
01048
01049
01050
01051
01052
01053 if ((mem_ctx = talloc_init("set_sd")) == NULL) {
01054 DEBUG(0,("set_sd: talloc_init failed.\n"));
01055 return NT_STATUS_NO_MEMORY;
01056 }
01057
01058 prs_init(&pd, 0, mem_ctx, UNMARSHALL);
01059
01060
01061
01062
01063
01064
01065 prs_give_memory( &pd, data, sd_len, False);
01066
01067
01068
01069
01070
01071 if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
01072 DEBUG(0,("set_sd: Error in unmarshalling security descriptor.\n"));
01073
01074
01075
01076 talloc_destroy(mem_ctx);
01077 return NT_STATUS_NO_MEMORY;
01078 }
01079
01080 if (psd->owner_sid==0) {
01081 security_info_sent &= ~OWNER_SECURITY_INFORMATION;
01082 }
01083 if (psd->group_sid==0) {
01084 security_info_sent &= ~GROUP_SECURITY_INFORMATION;
01085 }
01086 if (psd->sacl==0) {
01087 security_info_sent &= ~SACL_SECURITY_INFORMATION;
01088 }
01089 if (psd->dacl==0) {
01090 security_info_sent &= ~DACL_SECURITY_INFORMATION;
01091 }
01092
01093 ret = SMB_VFS_FSET_NT_ACL( fsp, fsp->fh->fd, security_info_sent, psd);
01094
01095 if (!ret) {
01096 talloc_destroy(mem_ctx);
01097 return NT_STATUS_ACCESS_DENIED;
01098 }
01099
01100 talloc_destroy(mem_ctx);
01101
01102 return NT_STATUS_OK;
01103 }
01104
01105
01106
01107
01108
01109 static struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
01110 {
01111 struct ea_list *ea_list_head = NULL;
01112 size_t offset = 0;
01113
01114 if (data_size < 4) {
01115 return NULL;
01116 }
01117
01118 while (offset + 4 <= data_size) {
01119 size_t next_offset = IVAL(pdata,offset);
01120 struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset + 4, data_size - offset - 4, NULL);
01121
01122 if (!eal) {
01123 return NULL;
01124 }
01125
01126 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
01127 if (next_offset == 0) {
01128 break;
01129 }
01130 offset += next_offset;
01131 }
01132
01133 return ea_list_head;
01134 }
01135
01136
01137
01138
01139
01140 static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
01141 uint16 **ppsetup, uint32 setup_count,
01142 char **ppparams, uint32 parameter_count,
01143 char **ppdata, uint32 data_count, uint32 max_data_count)
01144 {
01145 pstring fname;
01146 char *params = *ppparams;
01147 char *data = *ppdata;
01148
01149 int oplock_request = 0;
01150 uint32 fattr=0;
01151 SMB_OFF_T file_len = 0;
01152 SMB_STRUCT_STAT sbuf;
01153 int info = 0;
01154 files_struct *fsp = NULL;
01155 char *p = NULL;
01156 BOOL extended_oplock_granted = False;
01157 uint32 flags;
01158 uint32 access_mask;
01159 uint32 file_attributes;
01160 uint32 new_file_attributes;
01161 uint32 share_access;
01162 uint32 create_disposition;
01163 uint32 create_options;
01164 uint32 sd_len;
01165 uint32 ea_len;
01166 uint16 root_dir_fid;
01167 struct timespec c_timespec;
01168 struct timespec a_timespec;
01169 struct timespec m_timespec;
01170 struct ea_list *ea_list = NULL;
01171 TALLOC_CTX *ctx = NULL;
01172 char *pdata = NULL;
01173 NTSTATUS status;
01174 size_t param_len;
01175
01176 DEBUG(5,("call_nt_transact_create\n"));
01177
01178
01179
01180
01181
01182 if (IS_IPC(conn)) {
01183 if (lp_nt_pipe_support()) {
01184 return do_nt_transact_create_pipe(conn, inbuf, outbuf, length,
01185 bufsize,
01186 ppsetup, setup_count,
01187 ppparams, parameter_count,
01188 ppdata, data_count);
01189 } else {
01190 return ERROR_DOS(ERRDOS,ERRnoaccess);
01191 }
01192 }
01193
01194
01195
01196
01197
01198 if(parameter_count < 54) {
01199 DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)parameter_count));
01200 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
01201 }
01202
01203 flags = IVAL(params,0);
01204 access_mask = IVAL(params,8);
01205 file_attributes = IVAL(params,20);
01206 share_access = IVAL(params,24);
01207 create_disposition = IVAL(params,28);
01208 create_options = IVAL(params,32);
01209 sd_len = IVAL(params,36);
01210 ea_len = IVAL(params,40);
01211 root_dir_fid = (uint16)IVAL(params,4);
01212
01213
01214 if ((ea_len + sd_len > data_count) ||
01215 (ea_len > data_count) || (sd_len > data_count) ||
01216 (ea_len + sd_len < ea_len) || (ea_len + sd_len < sd_len)) {
01217 DEBUG(10,("call_nt_transact_create - ea_len = %u, sd_len = %u, data_count = %u\n",
01218 (unsigned int)ea_len, (unsigned int)sd_len, (unsigned int)data_count ));
01219 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
01220 }
01221
01222 if (ea_len) {
01223 if (!lp_ea_support(SNUM(conn))) {
01224 DEBUG(10,("call_nt_transact_create - ea_len = %u but EA's not supported.\n",
01225 (unsigned int)ea_len ));
01226 return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
01227 }
01228
01229 if (ea_len < 10) {
01230 DEBUG(10,("call_nt_transact_create - ea_len = %u - too small (should be more than 10)\n",
01231 (unsigned int)ea_len ));
01232 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
01233 }
01234 }
01235
01236 if (create_options & FILE_OPEN_BY_FILE_ID) {
01237 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
01238 }
01239
01240
01241
01242
01243
01244 if(root_dir_fid != 0) {
01245
01246
01247
01248 files_struct *dir_fsp = file_fsp(params,4);
01249
01250 if(!dir_fsp) {
01251 return ERROR_DOS(ERRDOS,ERRbadfid);
01252 }
01253
01254 if(!dir_fsp->is_directory) {
01255 srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
01256 if (!NT_STATUS_IS_OK(status)) {
01257 return ERROR_NT(status);
01258 }
01259
01260
01261
01262
01263
01264 if( is_ntfs_stream_name(fname)) {
01265 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
01266 }
01267
01268 return ERROR_DOS(ERRDOS,ERRbadfid);
01269 }
01270
01271
01272
01273
01274
01275 pstrcpy( fname, dir_fsp->fsp_name );
01276
01277 if (ISDOT(fname)) {
01278 fname[0] = '\0';
01279 } else {
01280 size_t dir_name_len = strlen(fname);
01281
01282
01283
01284
01285 if((fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
01286 pstrcat(fname, "/");
01287 }
01288 }
01289
01290 {
01291 pstring tmpname;
01292 srvstr_get_path(inbuf, tmpname, params+53, sizeof(tmpname), parameter_count-53, STR_TERMINATE, &status);
01293 if (!NT_STATUS_IS_OK(status)) {
01294 return ERROR_NT(status);
01295 }
01296 pstrcat(fname, tmpname);
01297 }
01298 } else {
01299 srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
01300 if (!NT_STATUS_IS_OK(status)) {
01301 return ERROR_NT(status);
01302 }
01303
01304
01305
01306
01307
01308 if( is_ntfs_stream_name(fname)) {
01309 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
01310 }
01311 }
01312
01313 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
01314 if (oplock_request) {
01315 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
01316 }
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326 new_file_attributes = set_posix_case_semantics(conn, file_attributes);
01327
01328 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
01329 if (!NT_STATUS_IS_OK(status)) {
01330 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
01331 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
01332 }
01333 return ERROR_NT(status);
01334 }
01335
01336 status = unix_convert(conn, fname, False, NULL, &sbuf);
01337 if (!NT_STATUS_IS_OK(status)) {
01338 restore_case_semantics(conn, file_attributes);
01339 return ERROR_NT(status);
01340 }
01341
01342 status = check_name(conn, fname);
01343 if (!NT_STATUS_IS_OK(status)) {
01344 restore_case_semantics(conn, file_attributes);
01345 return ERROR_NT(status);
01346 }
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356 if (lp_acl_check_permissions(SNUM(conn))
01357 && (create_disposition != FILE_CREATE)
01358 && (share_access & FILE_SHARE_DELETE)
01359 && (access_mask & DELETE_ACCESS)) {
01360 if ((dos_mode(conn, fname, &sbuf) & FILE_ATTRIBUTE_READONLY) ||
01361 !can_delete_file_in_directory(conn, fname)) {
01362 restore_case_semantics(conn, file_attributes);
01363 return ERROR_NT(NT_STATUS_ACCESS_DENIED);
01364 }
01365 }
01366
01367 if (ea_len) {
01368 pdata = data + sd_len;
01369
01370
01371 ea_list = read_nttrans_ea_list(tmp_talloc_ctx(), pdata,
01372 ea_len);
01373 if (!ea_list ) {
01374 restore_case_semantics(conn, file_attributes);
01375 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
01376 }
01377 }
01378
01379
01380
01381
01382
01383 if(create_options & FILE_DIRECTORY_FILE) {
01384
01385
01386 if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) {
01387 restore_case_semantics(conn, file_attributes);
01388 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
01389 }
01390
01391
01392
01393
01394
01395
01396
01397 oplock_request = 0;
01398 status = open_directory(conn, fname, &sbuf,
01399 access_mask,
01400 share_access,
01401 create_disposition,
01402 create_options,
01403 new_file_attributes,
01404 &info, &fsp);
01405 } else {
01406
01407
01408
01409
01410
01411 status = open_file_ntcreate(conn,fname,&sbuf,
01412 access_mask,
01413 share_access,
01414 create_disposition,
01415 create_options,
01416 new_file_attributes,
01417 oplock_request,
01418 &info, &fsp);
01419
01420 if (!NT_STATUS_IS_OK(status)) {
01421 if (NT_STATUS_EQUAL(status,
01422 NT_STATUS_FILE_IS_A_DIRECTORY)) {
01423
01424
01425
01426
01427
01428 if (create_options & FILE_NON_DIRECTORY_FILE) {
01429 restore_case_semantics(conn, file_attributes);
01430 return ERROR_FORCE_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
01431 }
01432
01433 oplock_request = 0;
01434 status = open_directory(conn, fname, &sbuf,
01435 access_mask,
01436 share_access,
01437 create_disposition,
01438 create_options,
01439 new_file_attributes,
01440 &info, &fsp);
01441 }
01442 }
01443 }
01444
01445 restore_case_semantics(conn, file_attributes);
01446 if(!NT_STATUS_IS_OK(status)) {
01447
01448 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
01449
01450 return -1;
01451 }
01452
01453 return ERROR_OPEN(status);
01454 }
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467 if (lp_nt_acl_support(SNUM(conn)) && sd_len && info == FILE_WAS_CREATED) {
01468 uint32 saved_access_mask = fsp->access_mask;
01469
01470
01471
01472 fsp->access_mask = FILE_GENERIC_ALL;
01473
01474 status = set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION);
01475 if (!NT_STATUS_IS_OK(status)) {
01476 talloc_destroy(ctx);
01477 close_file(fsp,ERROR_CLOSE);
01478 restore_case_semantics(conn, file_attributes);
01479 return ERROR_NT(status);
01480 }
01481 fsp->access_mask = saved_access_mask;
01482 }
01483
01484 if (ea_len && (info == FILE_WAS_CREATED)) {
01485 status = set_ea(conn, fsp, fname, ea_list);
01486 if (!NT_STATUS_IS_OK(status)) {
01487 close_file(fsp,ERROR_CLOSE);
01488 restore_case_semantics(conn, file_attributes);
01489 return ERROR_NT(status);
01490 }
01491 }
01492
01493 restore_case_semantics(conn, file_attributes);
01494
01495 file_len = sbuf.st_size;
01496 fattr = dos_mode(conn,fname,&sbuf);
01497 if(fattr == 0) {
01498 fattr = FILE_ATTRIBUTE_NORMAL;
01499 }
01500 if (!fsp->is_directory && (fattr & aDIR)) {
01501 close_file(fsp,ERROR_CLOSE);
01502 return ERROR_DOS(ERRDOS,ERRnoaccess);
01503 }
01504
01505
01506 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
01507 SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(params,12);
01508 #ifdef LARGE_SMB_OFF_T
01509 allocation_size |= (((SMB_BIG_UINT)IVAL(params,16)) << 32);
01510 #endif
01511 if (allocation_size && (allocation_size > file_len)) {
01512 fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
01513 if (fsp->is_directory) {
01514 close_file(fsp,ERROR_CLOSE);
01515
01516 return ERROR_NT(NT_STATUS_ACCESS_DENIED);
01517 }
01518 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
01519 close_file(fsp,ERROR_CLOSE);
01520 return ERROR_NT(NT_STATUS_DISK_FULL);
01521 }
01522 } else {
01523 fsp->initial_allocation_size = smb_roundup(fsp->conn, (SMB_BIG_UINT)file_len);
01524 }
01525 }
01526
01527
01528
01529
01530
01531
01532
01533 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
01534 extended_oplock_granted = True;
01535 }
01536
01537 if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
01538 extended_oplock_granted = True;
01539 }
01540
01541
01542 if (flags & EXTENDED_RESPONSE_REQUIRED) {
01543
01544 param_len = 101;
01545 } else {
01546 param_len = 69;
01547 }
01548 params = nttrans_realloc(ppparams, param_len);
01549 if(params == NULL) {
01550 return ERROR_DOS(ERRDOS,ERRnomem);
01551 }
01552
01553 p = params;
01554 if (extended_oplock_granted) {
01555 if (flags & REQUEST_BATCH_OPLOCK) {
01556 SCVAL(p,0, BATCH_OPLOCK_RETURN);
01557 } else {
01558 SCVAL(p,0, EXCLUSIVE_OPLOCK_RETURN);
01559 }
01560 } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
01561 SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
01562 } else {
01563 SCVAL(p,0,NO_OPLOCK_RETURN);
01564 }
01565
01566 p += 2;
01567 SSVAL(p,0,fsp->fnum);
01568 p += 2;
01569 if ((create_disposition == FILE_SUPERSEDE) && (info == FILE_WAS_OVERWRITTEN)) {
01570 SIVAL(p,0,FILE_WAS_SUPERSEDED);
01571 } else {
01572 SIVAL(p,0,info);
01573 }
01574 p += 8;
01575
01576
01577 c_timespec = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
01578 a_timespec = get_atimespec(&sbuf);
01579 m_timespec = get_mtimespec(&sbuf);
01580
01581 if (lp_dos_filetime_resolution(SNUM(conn))) {
01582 dos_filetime_timespec(&c_timespec);
01583 dos_filetime_timespec(&a_timespec);
01584 dos_filetime_timespec(&m_timespec);
01585 }
01586
01587 put_long_date_timespec(p, c_timespec);
01588 p += 8;
01589 put_long_date_timespec(p, a_timespec);
01590 p += 8;
01591 put_long_date_timespec(p, m_timespec);
01592 p += 8;
01593 put_long_date_timespec(p, m_timespec);
01594 p += 8;
01595 SIVAL(p,0,fattr);
01596 p += 4;
01597 SOFF_T(p, 0, get_allocation_size(conn,fsp,&sbuf));
01598 p += 8;
01599 SOFF_T(p,0,file_len);
01600 p += 8;
01601 if (flags & EXTENDED_RESPONSE_REQUIRED) {
01602 SSVAL(p,2,0x7);
01603 }
01604 p += 4;
01605 SCVAL(p,0,fsp->is_directory ? 1 : 0);
01606
01607 if (flags & EXTENDED_RESPONSE_REQUIRED) {
01608 uint32 perms = 0;
01609 p += 25;
01610 if (fsp->is_directory || can_write_to_file(conn, fname, &sbuf)) {
01611 perms = FILE_GENERIC_ALL;
01612 } else {
01613 perms = FILE_GENERIC_READ|FILE_EXECUTE;
01614 }
01615 SIVAL(p,0,perms);
01616 }
01617
01618 DEBUG(5,("call_nt_transact_create: open name = %s\n", fname));
01619
01620
01621 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, params, param_len, *ppdata, 0);
01622
01623 return -1;
01624 }
01625
01626
01627
01628
01629
01630
01631 int reply_ntcancel(connection_struct *conn,
01632 char *inbuf,char *outbuf,int length,int bufsize)
01633 {
01634
01635
01636
01637
01638 int mid = SVAL(inbuf,smb_mid);
01639 START_PROFILE(SMBntcancel);
01640 remove_pending_change_notify_requests_by_mid(mid);
01641 remove_pending_lock_requests_by_mid(mid);
01642 srv_cancel_sign_response(mid);
01643
01644 DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", mid));
01645
01646 END_PROFILE(SMBntcancel);
01647 return(-1);
01648 }
01649
01650
01651
01652
01653
01654 static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *newname, uint32 attrs)
01655 {
01656 SMB_STRUCT_STAT sbuf1, sbuf2;
01657 pstring last_component_oldname;
01658 pstring last_component_newname;
01659 files_struct *fsp1,*fsp2;
01660 uint32 fattr;
01661 int info;
01662 SMB_OFF_T ret=-1;
01663 NTSTATUS status = NT_STATUS_OK;
01664
01665 ZERO_STRUCT(sbuf1);
01666 ZERO_STRUCT(sbuf2);
01667
01668 if (!CAN_WRITE(conn)) {
01669 return NT_STATUS_MEDIA_WRITE_PROTECTED;
01670 }
01671
01672 status = unix_convert(conn, oldname, False, last_component_oldname, &sbuf1);
01673 if (!NT_STATUS_IS_OK(status)) {
01674 return status;
01675 }
01676
01677 status = check_name(conn, oldname);
01678 if (!NT_STATUS_IS_OK(status)) {
01679 return status;
01680 }
01681
01682
01683 if (!VALID_STAT(sbuf1)) {
01684 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
01685 }
01686
01687 fattr = dos_mode(conn,oldname,&sbuf1);
01688 if ((fattr & ~attrs) & (aHIDDEN | aSYSTEM)) {
01689 return NT_STATUS_NO_SUCH_FILE;
01690 }
01691
01692 status = unix_convert(conn, newname, False, last_component_newname, &sbuf2);
01693 if (!NT_STATUS_IS_OK(status)) {
01694 return status;
01695 }
01696
01697 status = check_name(conn, newname);
01698 if (!NT_STATUS_IS_OK(status)) {
01699 return status;
01700 }
01701
01702
01703 if (VALID_STAT(sbuf2)) {
01704 return NT_STATUS_OBJECT_NAME_COLLISION;
01705 }
01706
01707
01708 if (S_ISDIR(sbuf1.st_mode)) {
01709 return NT_STATUS_FILE_IS_A_DIRECTORY;
01710 }
01711
01712
01713 status = reduce_name(conn, oldname);
01714 if (!NT_STATUS_IS_OK(status)) {
01715 return status;
01716 }
01717
01718 DEBUG(10,("copy_internals: doing file copy %s to %s\n", oldname, newname));
01719
01720 status = open_file_ntcreate(conn,oldname,&sbuf1,
01721 FILE_READ_DATA,
01722 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
01723 FILE_OPEN,
01724 0,
01725 FILE_ATTRIBUTE_NORMAL,
01726 NO_OPLOCK,
01727 &info, &fsp1);
01728
01729 if (!NT_STATUS_IS_OK(status)) {
01730 return status;
01731 }
01732
01733 status = open_file_ntcreate(conn,newname,&sbuf2,
01734 FILE_WRITE_DATA,
01735 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
01736 FILE_CREATE,
01737 0,
01738 fattr,
01739 NO_OPLOCK,
01740 &info, &fsp2);
01741
01742 if (!NT_STATUS_IS_OK(status)) {
01743 close_file(fsp1,ERROR_CLOSE);
01744 return status;
01745 }
01746
01747 if (sbuf1.st_size) {
01748 ret = vfs_transfer_file(fsp1, fsp2, sbuf1.st_size);
01749 }
01750
01751
01752
01753
01754
01755
01756
01757 close_file(fsp1,NORMAL_CLOSE);
01758
01759
01760 fsp_set_pending_modtime(fsp2, get_mtimespec(&sbuf1));
01761
01762 status = close_file(fsp2,NORMAL_CLOSE);
01763
01764
01765
01766
01767 file_set_dosmode(conn, newname, fattr, &sbuf2,
01768 parent_dirname(newname));
01769
01770 if (ret < (SMB_OFF_T)sbuf1.st_size) {
01771 return NT_STATUS_DISK_FULL;
01772 }
01773
01774 if (!NT_STATUS_IS_OK(status)) {
01775 DEBUG(3,("copy_internals: Error %s copy file %s to %s\n",
01776 nt_errstr(status), oldname, newname));
01777 }
01778 return status;
01779 }
01780
01781
01782
01783
01784
01785 int reply_ntrename(connection_struct *conn,
01786 char *inbuf,char *outbuf,int length,int bufsize)
01787 {
01788 int outsize = 0;
01789 pstring oldname;
01790 pstring newname;
01791 char *p;
01792 NTSTATUS status;
01793 BOOL src_has_wcard = False;
01794 BOOL dest_has_wcard = False;
01795 uint32 attrs = SVAL(inbuf,smb_vwv0);
01796 uint16 rename_type = SVAL(inbuf,smb_vwv1);
01797
01798 START_PROFILE(SMBntrename);
01799
01800 p = smb_buf(inbuf) + 1;
01801 p += srvstr_get_path_wcard(inbuf, oldname, p, sizeof(oldname), 0, STR_TERMINATE, &status, &src_has_wcard);
01802 if (!NT_STATUS_IS_OK(status)) {
01803 END_PROFILE(SMBntrename);
01804 return ERROR_NT(status);
01805 }
01806
01807 if( is_ntfs_stream_name(oldname)) {
01808
01809 END_PROFILE(SMBntrename);
01810 return ERROR_NT(NT_STATUS_ACCESS_DENIED);
01811 }
01812
01813 if (ms_has_wild(oldname)) {
01814 END_PROFILE(SMBntrename);
01815 return ERROR_NT(NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
01816 }
01817
01818 p++;
01819 p += srvstr_get_path_wcard(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, &dest_has_wcard);
01820 if (!NT_STATUS_IS_OK(status)) {
01821 END_PROFILE(SMBntrename);
01822 return ERROR_NT(status);
01823 }
01824
01825 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, oldname);
01826 if (!NT_STATUS_IS_OK(status)) {
01827 END_PROFILE(SMBntrename);
01828 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
01829 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
01830 }
01831 return ERROR_NT(status);
01832 }
01833
01834 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newname);
01835 if (!NT_STATUS_IS_OK(status)) {
01836 END_PROFILE(SMBntrename);
01837 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
01838 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
01839 }
01840 return ERROR_NT(status);
01841 }
01842
01843 DEBUG(3,("reply_ntrename : %s -> %s\n",oldname,newname));
01844
01845 switch(rename_type) {
01846 case RENAME_FLAG_RENAME:
01847 status = rename_internals(conn, oldname, newname, attrs, False, src_has_wcard, dest_has_wcard);
01848 break;
01849 case RENAME_FLAG_HARD_LINK:
01850 if (src_has_wcard || dest_has_wcard) {
01851
01852 status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
01853 } else {
01854 status = hardlink_internals(conn, oldname, newname);
01855 }
01856 break;
01857 case RENAME_FLAG_COPY:
01858 if (src_has_wcard || dest_has_wcard) {
01859
01860 status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
01861 } else {
01862 status = copy_internals(conn, oldname, newname, attrs);
01863 }
01864 break;
01865 case RENAME_FLAG_MOVE_CLUSTER_INFORMATION:
01866 status = NT_STATUS_INVALID_PARAMETER;
01867 break;
01868 default:
01869 status = NT_STATUS_ACCESS_DENIED;
01870 break;
01871 }
01872
01873 if (!NT_STATUS_IS_OK(status)) {
01874 END_PROFILE(SMBntrename);
01875 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
01876
01877 return -1;
01878 }
01879 return ERROR_NT(status);
01880 }
01881
01882 outsize = set_message(outbuf,0,0,False);
01883
01884 END_PROFILE(SMBntrename);
01885 return(outsize);
01886 }
01887
01888
01889
01890
01891
01892
01893 static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf,
01894 char *outbuf, int length,
01895 int bufsize,
01896 uint16 **ppsetup, uint32 setup_count,
01897 char **ppparams,
01898 uint32 parameter_count,
01899 char **ppdata, uint32 data_count,
01900 uint32 max_data_count,
01901 uint32 max_param_count)
01902 {
01903 uint16 *setup = *ppsetup;
01904 files_struct *fsp;
01905 uint32 filter;
01906 NTSTATUS status;
01907 BOOL recursive;
01908
01909 if(setup_count < 6) {
01910 return ERROR_DOS(ERRDOS,ERRbadfunc);
01911 }
01912
01913 fsp = file_fsp((char *)setup,4);
01914 filter = IVAL(setup, 0);
01915 recursive = (SVAL(setup, 6) != 0) ? True : False;
01916
01917 DEBUG(3,("call_nt_transact_notify_change\n"));
01918
01919 if(!fsp) {
01920 return ERROR_DOS(ERRDOS,ERRbadfid);
01921 }
01922
01923 {
01924 char *filter_string;
01925
01926 if (!(filter_string = notify_filter_string(NULL, filter))) {
01927 return ERROR_NT(NT_STATUS_NO_MEMORY);
01928 }
01929
01930 DEBUG(3,("call_nt_transact_notify_change: notify change "
01931 "called on %s, filter = %s, recursive = %d\n",
01932 fsp->fsp_name, filter_string, recursive));
01933
01934 TALLOC_FREE(filter_string);
01935 }
01936
01937 if((!fsp->is_directory) || (conn != fsp->conn)) {
01938 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
01939 }
01940
01941 if (fsp->notify == NULL) {
01942
01943 status = change_notify_create(fsp, filter, recursive);
01944
01945 if (!NT_STATUS_IS_OK(status)) {
01946 DEBUG(10, ("change_notify_create returned %s\n",
01947 nt_errstr(status)));
01948 return ERROR_NT(status);
01949 }
01950 }
01951
01952 if (fsp->notify->num_changes != 0) {
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963 change_notify_reply(inbuf, max_param_count, fsp->notify);
01964
01965
01966
01967
01968
01969 return -1;
01970 }
01971
01972
01973
01974
01975
01976 status = change_notify_add_request(inbuf, max_param_count, filter,
01977 recursive, fsp);
01978 if (!NT_STATUS_IS_OK(status)) {
01979 return ERROR_NT(status);
01980 }
01981
01982 return -1;
01983 }
01984
01985
01986
01987
01988
01989 static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
01990 uint16 **ppsetup, uint32 setup_count,
01991 char **ppparams, uint32 parameter_count,
01992 char **ppdata, uint32 data_count, uint32 max_data_count)
01993 {
01994 char *params = *ppparams;
01995 pstring new_name;
01996 files_struct *fsp = NULL;
01997 BOOL replace_if_exists = False;
01998 BOOL dest_has_wcard = False;
01999 NTSTATUS status;
02000
02001 if(parameter_count < 5) {
02002 return ERROR_DOS(ERRDOS,ERRbadfunc);
02003 }
02004
02005 fsp = file_fsp(params, 0);
02006 replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;
02007 CHECK_FSP(fsp, conn);
02008 srvstr_get_path_wcard(inbuf, new_name, params+4, sizeof(new_name), parameter_count - 4,
02009 STR_TERMINATE, &status, &dest_has_wcard);
02010 if (!NT_STATUS_IS_OK(status)) {
02011 return ERROR_NT(status);
02012 }
02013
02014 status = rename_internals(conn, fsp->fsp_name,
02015 new_name, 0, replace_if_exists, False, dest_has_wcard);
02016
02017 if (!NT_STATUS_IS_OK(status)) {
02018 if (open_was_deferred(SVAL(inbuf,smb_mid))) {
02019
02020 return -1;
02021 }
02022 return ERROR_NT(status);
02023 }
02024
02025
02026
02027
02028 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
02029
02030 DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n",
02031 fsp->fsp_name, new_name));
02032
02033 return -1;
02034 }
02035
02036
02037
02038
02039
02040 static size_t get_null_nt_acl(TALLOC_CTX *mem_ctx, SEC_DESC **ppsd)
02041 {
02042 size_t sd_size;
02043
02044 *ppsd = make_standard_sec_desc( mem_ctx, &global_sid_World, &global_sid_World, NULL, &sd_size);
02045 if(!*ppsd) {
02046 DEBUG(0,("get_null_nt_acl: Unable to malloc space for security descriptor.\n"));
02047 sd_size = 0;
02048 }
02049
02050 return sd_size;
02051 }
02052
02053
02054
02055
02056
02057 static int call_nt_transact_query_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
02058 uint16 **ppsetup, uint32 setup_count,
02059 char **ppparams, uint32 parameter_count,
02060 char **ppdata, uint32 data_count, uint32 max_data_count)
02061 {
02062 char *params = *ppparams;
02063 char *data = *ppdata;
02064 prs_struct pd;
02065 SEC_DESC *psd = NULL;
02066 size_t sd_size;
02067 uint32 security_info_wanted;
02068 TALLOC_CTX *mem_ctx;
02069 files_struct *fsp = NULL;
02070
02071 if(parameter_count < 8) {
02072 return ERROR_DOS(ERRDOS,ERRbadfunc);
02073 }
02074
02075 fsp = file_fsp(params,0);
02076 if(!fsp) {
02077 return ERROR_DOS(ERRDOS,ERRbadfid);
02078 }
02079
02080 security_info_wanted = IVAL(params,4);
02081
02082 DEBUG(3,("call_nt_transact_query_security_desc: file = %s, info_wanted = 0x%x\n", fsp->fsp_name,
02083 (unsigned int)security_info_wanted ));
02084
02085 params = nttrans_realloc(ppparams, 4);
02086 if(params == NULL) {
02087 return ERROR_DOS(ERRDOS,ERRnomem);
02088 }
02089
02090 if ((mem_ctx = talloc_init("call_nt_transact_query_security_desc")) == NULL) {
02091 DEBUG(0,("call_nt_transact_query_security_desc: talloc_init failed.\n"));
02092 return ERROR_DOS(ERRDOS,ERRnomem);
02093 }
02094
02095
02096
02097
02098
02099 if (!lp_nt_acl_support(SNUM(conn))) {
02100 sd_size = get_null_nt_acl(mem_ctx, &psd);
02101 } else {
02102 sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, security_info_wanted, &psd);
02103 }
02104
02105 if (sd_size == 0) {
02106 talloc_destroy(mem_ctx);
02107 return(UNIXERROR(ERRDOS,ERRnoaccess));
02108 }
02109
02110 DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %lu.\n",(unsigned long)sd_size));
02111
02112 SIVAL(params,0,(uint32)sd_size);
02113
02114 if(max_data_count < sd_size) {
02115
02116 send_nt_replies(outbuf, bufsize, NT_STATUS_BUFFER_TOO_SMALL,
02117 params, 4, *ppdata, 0);
02118 talloc_destroy(mem_ctx);
02119 return -1;
02120 }
02121
02122
02123
02124
02125
02126 data = nttrans_realloc(ppdata, sd_size);
02127 if(data == NULL) {
02128 talloc_destroy(mem_ctx);
02129 return ERROR_DOS(ERRDOS,ERRnomem);
02130 }
02131
02132
02133
02134
02135
02136 prs_init(&pd, 0, mem_ctx, MARSHALL);
02137
02138
02139
02140
02141
02142
02143 prs_give_memory( &pd, data, (uint32)sd_size, False);
02144
02145
02146
02147
02148
02149 if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
02150 DEBUG(0,("call_nt_transact_query_security_desc: Error in marshalling \
02151 security descriptor.\n"));
02152
02153
02154
02155 talloc_destroy(mem_ctx);
02156 return(UNIXERROR(ERRDOS,ERRnoaccess));
02157 }
02158
02159
02160
02161
02162
02163 talloc_destroy(mem_ctx);
02164
02165 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, params, 4, data,
02166 (int)sd_size);
02167 return -1;
02168 }
02169
02170
02171
02172
02173
02174 static int call_nt_transact_set_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
02175 uint16 **ppsetup, uint32 setup_count,
02176 char **ppparams, uint32 parameter_count,
02177 char **ppdata, uint32 data_count, uint32 max_data_count)
02178 {
02179 char *params= *ppparams;
02180 char *data = *ppdata;
02181 files_struct *fsp = NULL;
02182 uint32 security_info_sent = 0;
02183 NTSTATUS nt_status;
02184
02185 if(parameter_count < 8) {
02186 return ERROR_DOS(ERRDOS,ERRbadfunc);
02187 }
02188
02189 if((fsp = file_fsp(params,0)) == NULL) {
02190 return ERROR_DOS(ERRDOS,ERRbadfid);
02191 }
02192
02193 if(!lp_nt_acl_support(SNUM(conn))) {
02194 goto done;
02195 }
02196
02197 security_info_sent = IVAL(params,4);
02198
02199 DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name,
02200 (unsigned int)security_info_sent ));
02201
02202 if (data_count == 0) {
02203 return ERROR_DOS(ERRDOS, ERRnoaccess);
02204 }
02205
02206 if (!NT_STATUS_IS_OK(nt_status = set_sd( fsp, data, data_count, security_info_sent))) {
02207 return ERROR_NT(nt_status);
02208 }
02209
02210 done:
02211
02212 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
02213 return -1;
02214 }
02215
02216
02217
02218
02219
02220 static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
02221 uint16 **ppsetup, uint32 setup_count,
02222 char **ppparams, uint32 parameter_count,
02223 char **ppdata, uint32 data_count, uint32 max_data_count)
02224 {
02225 uint32 function;
02226 uint16 fidnum;
02227 files_struct *fsp;
02228 uint8 isFSctl;
02229 uint8 compfilter;
02230 static BOOL logged_message;
02231 char *pdata = *ppdata;
02232
02233 if (setup_count != 8) {
02234 DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count));
02235 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
02236 }
02237
02238 function = IVAL(*ppsetup, 0);
02239 fidnum = SVAL(*ppsetup, 4);
02240 isFSctl = CVAL(*ppsetup, 6);
02241 compfilter = CVAL(*ppsetup, 7);
02242
02243 DEBUG(10,("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n",
02244 function, fidnum, isFSctl, compfilter));
02245
02246 fsp=file_fsp((char *)*ppsetup, 4);
02247
02248
02249
02250
02251 switch (function) {
02252 case FSCTL_SET_SPARSE:
02253
02254
02255
02256
02257 DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X](but not implemented)\n", fidnum));
02258 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL,
02259 0);
02260 return -1;
02261
02262 case FSCTL_0x000900C0:
02263
02264
02265
02266
02267 DEBUG(10,("FSCTL_0x000900C0: called on FID[0x%04X](but not implemented)\n",fidnum));
02268 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL,
02269 0);
02270 return -1;
02271
02272 case FSCTL_GET_REPARSE_POINT:
02273
02274
02275
02276
02277 DEBUG(10,("FSCTL_GET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
02278 send_nt_replies(outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT,
02279 NULL, 0, NULL, 0);
02280 return -1;
02281
02282 case FSCTL_SET_REPARSE_POINT:
02283
02284
02285
02286
02287 DEBUG(10,("FSCTL_SET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
02288 send_nt_replies(outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT,
02289 NULL, 0, NULL, 0);
02290 return -1;
02291
02292 case FSCTL_GET_SHADOW_COPY_DATA:
02293 {
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303
02304 SHADOW_COPY_DATA *shadow_data = NULL;
02305 TALLOC_CTX *shadow_mem_ctx = NULL;
02306 BOOL labels = False;
02307 uint32 labels_data_count = 0;
02308 uint32 i;
02309 char *cur_pdata;
02310
02311 FSP_BELONGS_CONN(fsp,conn);
02312
02313 if (max_data_count < 16) {
02314 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
02315 max_data_count));
02316 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
02317 }
02318
02319 if (max_data_count > 16) {
02320 labels = True;
02321 }
02322
02323 shadow_mem_ctx = talloc_init("SHADOW_COPY_DATA");
02324 if (shadow_mem_ctx == NULL) {
02325 DEBUG(0,("talloc_init(SHADOW_COPY_DATA) failed!\n"));
02326 return ERROR_NT(NT_STATUS_NO_MEMORY);
02327 }
02328
02329 shadow_data = TALLOC_ZERO_P(shadow_mem_ctx,SHADOW_COPY_DATA);
02330 if (shadow_data == NULL) {
02331 DEBUG(0,("TALLOC_ZERO() failed!\n"));
02332 talloc_destroy(shadow_mem_ctx);
02333 return ERROR_NT(NT_STATUS_NO_MEMORY);
02334 }
02335
02336 shadow_data->mem_ctx = shadow_mem_ctx;
02337
02338
02339
02340
02341 if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)!=0) {
02342 talloc_destroy(shadow_data->mem_ctx);
02343 if (errno == ENOSYS) {
02344 DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n",
02345 conn->connectpath));
02346 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
02347 } else {
02348 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n",
02349 conn->connectpath));
02350 return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
02351 }
02352 }
02353
02354 labels_data_count = (shadow_data->num_volumes*2*sizeof(SHADOW_COPY_LABEL))+2;
02355
02356 if (!labels) {
02357 data_count = 16;
02358 } else {
02359 data_count = 12+labels_data_count+4;
02360 }
02361
02362 if (max_data_count<data_count) {
02363 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
02364 max_data_count,data_count));
02365 talloc_destroy(shadow_data->mem_ctx);
02366 return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
02367 }
02368
02369 pdata = nttrans_realloc(ppdata, data_count);
02370 if (pdata == NULL) {
02371 talloc_destroy(shadow_data->mem_ctx);
02372 return ERROR_NT(NT_STATUS_NO_MEMORY);
02373 }
02374
02375 cur_pdata = pdata;
02376
02377
02378 SIVAL(pdata,0,shadow_data->num_volumes);
02379
02380 if (labels) {
02381
02382 SIVAL(pdata,4,shadow_data->num_volumes);
02383 }
02384
02385
02386 SIVAL(pdata,8,labels_data_count);
02387
02388 cur_pdata+=12;
02389
02390 DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
02391 shadow_data->num_volumes,fsp->fsp_name));
02392 if (labels && shadow_data->labels) {
02393 for (i=0;i<shadow_data->num_volumes;i++) {
02394 srvstr_push(outbuf, cur_pdata, shadow_data->labels[i], 2*sizeof(SHADOW_COPY_LABEL), STR_UNICODE|STR_TERMINATE);
02395 cur_pdata+=2*sizeof(SHADOW_COPY_LABEL);
02396 DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i]));
02397 }
02398 }
02399
02400 talloc_destroy(shadow_data->mem_ctx);
02401
02402 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, NULL, 0,
02403 pdata, data_count);
02404
02405 return -1;
02406 }
02407
02408 case FSCTL_FIND_FILES_BY_SID:
02409 {
02410
02411
02412
02413
02414
02415
02416 DOM_SID sid;
02417 uid_t uid;
02418 size_t sid_len = MIN(data_count-4,SID_MAX_SIZE);
02419
02420 DEBUG(10,("FSCTL_FIND_FILES_BY_SID: called on FID[0x%04X]\n",fidnum));
02421
02422 FSP_BELONGS_CONN(fsp,conn);
02423
02424
02425
02426
02427 sid_parse(pdata+4,sid_len,&sid);
02428 DEBUGADD(10,("for SID: %s\n",sid_string_static(&sid)));
02429
02430 if (!sid_to_uid(&sid, &uid)) {
02431 DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
02432 sid_string_static(&sid),(unsigned long)sid_len));
02433 uid = (-1);
02434 }
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, NULL, 0,
02456 NULL, 0);
02457 return -1;
02458 }
02459 default:
02460 if (!logged_message) {
02461 logged_message = True;
02462 DEBUG(0,("call_nt_transact_ioctl(0x%x): Currently not implemented.\n",
02463 function));
02464 }
02465 }
02466
02467 return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
02468 }
02469
02470
02471 #ifdef HAVE_SYS_QUOTAS
02472
02473
02474
02475
02476 static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
02477 uint16 **ppsetup, uint32 setup_count,
02478 char **ppparams, uint32 parameter_count,
02479 char **ppdata, uint32 data_count, uint32 max_data_count)
02480 {
02481 NTSTATUS nt_status = NT_STATUS_OK;
02482 char *params = *ppparams;
02483 char *pdata = *ppdata;
02484 char *entry;
02485 int data_len=0,param_len=0;
02486 int qt_len=0;
02487 int entry_len = 0;
02488 files_struct *fsp = NULL;
02489 uint16 level = 0;
02490 size_t sid_len;
02491 DOM_SID sid;
02492 BOOL start_enum = True;
02493 SMB_NTQUOTA_STRUCT qt;
02494 SMB_NTQUOTA_LIST *tmp_list;
02495 SMB_NTQUOTA_HANDLE *qt_handle = NULL;
02496
02497 ZERO_STRUCT(qt);
02498
02499
02500 if (current_user.ut.uid != 0) {
02501 DEBUG(1,("get_user_quota: access_denied service [%s] user [%s]\n",
02502 lp_servicename(SNUM(conn)),conn->user));
02503 return ERROR_DOS(ERRDOS,ERRnoaccess);
02504 }
02505
02506
02507
02508
02509
02510 if (parameter_count < 4) {
02511 DEBUG(0,("TRANSACT_GET_USER_QUOTA: requires %d >= 4 bytes parameters\n",parameter_count));
02512 return ERROR_DOS(ERRDOS,ERRinvalidparam);
02513 }
02514
02515
02516 fsp = file_fsp(params,0);
02517 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
02518 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
02519 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
02520 }
02521
02522
02523
02524
02525 qt_handle = (SMB_NTQUOTA_HANDLE *)fsp->fake_file_handle->pd;
02526
02527 level = SVAL(params,2);
02528
02529
02530
02531 switch (level) {
02532 case TRANSACT_GET_USER_QUOTA_LIST_CONTINUE:
02533
02534
02535 if (qt_handle->quota_list!=NULL &&
02536 qt_handle->tmp_list==NULL) {
02537
02538
02539 free_ntquota_list(&(qt_handle->quota_list));
02540
02541
02542 param_len = 4;
02543 params = nttrans_realloc(ppparams, param_len);
02544 if(params == NULL) {
02545 return ERROR_DOS(ERRDOS,ERRnomem);
02546 }
02547
02548 data_len = 0;
02549 SIVAL(params,0,data_len);
02550
02551 break;
02552 }
02553
02554 start_enum = False;
02555
02556 case TRANSACT_GET_USER_QUOTA_LIST_START:
02557
02558 if (qt_handle->quota_list==NULL &&
02559 qt_handle->tmp_list==NULL) {
02560 start_enum = True;
02561 }
02562
02563 if (start_enum && vfs_get_user_ntquota_list(fsp,&(qt_handle->quota_list))!=0)
02564 return ERROR_DOS(ERRSRV,ERRerror);
02565
02566
02567 param_len = 4;
02568 params = nttrans_realloc(ppparams, param_len);
02569 if(params == NULL) {
02570 return ERROR_DOS(ERRDOS,ERRnomem);
02571 }
02572
02573
02574 max_data_count = MIN(max_data_count,2048);
02575
02576 pdata = nttrans_realloc(ppdata, max_data_count);
02577 if(pdata == NULL) {
02578 return ERROR_DOS(ERRDOS,ERRnomem);
02579 }
02580
02581 entry = pdata;
02582
02583
02584
02585
02586
02587
02588 if (start_enum) {
02589 qt_handle->tmp_list = qt_handle->quota_list;
02590 }
02591
02592 tmp_list = qt_handle->tmp_list;
02593
02594 for (;((tmp_list!=NULL)&&((qt_len +40+SID_MAX_SIZE)<max_data_count));
02595 tmp_list=tmp_list->next,entry+=entry_len,qt_len+=entry_len) {
02596
02597 sid_len = sid_size(&tmp_list->quotas->sid);
02598 entry_len = 40 + sid_len;
02599
02600
02601 SIVAL(entry,0,entry_len);
02602
02603
02604 SIVAL(entry,4,sid_len);
02605
02606
02607 SBIG_UINT(entry,8,(SMB_BIG_UINT)0);
02608
02609
02610 SBIG_UINT(entry,16,tmp_list->quotas->usedspace);
02611
02612
02613 SBIG_UINT(entry,24,tmp_list->quotas->softlim);
02614
02615
02616 SBIG_UINT(entry,32,tmp_list->quotas->hardlim);
02617
02618
02619 sid_linearize(entry+40, sid_len, &tmp_list->quotas->sid);
02620 }
02621
02622 qt_handle->tmp_list = tmp_list;
02623
02624
02625 SIVAL(entry-entry_len,0,0);
02626
02627 data_len = 4+qt_len;
02628
02629 SIVAL(params,0,data_len);
02630
02631 break;
02632
02633 case TRANSACT_GET_USER_QUOTA_FOR_SID:
02634
02635
02636
02637 if (data_count < 8) {
02638 DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %d bytes data\n",data_count,8));
02639 return ERROR_DOS(ERRDOS,ERRunknownlevel);
02640 }
02641
02642 sid_len = IVAL(pdata,4);
02643
02644 if (sid_len > (1024*1024)) {
02645 return ERROR_DOS(ERRDOS,ERRnomem);
02646 }
02647
02648 if (data_count < 8+sid_len) {
02649 DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %lu bytes data\n",data_count,(unsigned long)(8+sid_len)));
02650 return ERROR_DOS(ERRDOS,ERRunknownlevel);
02651 }
02652
02653 data_len = 4+40+sid_len;
02654
02655 if (max_data_count < data_len) {
02656 DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: max_data_count(%d) < data_len(%d)\n",
02657 max_data_count, data_len));
02658 param_len = 4;
02659 SIVAL(params,0,data_len);
02660 data_len = 0;
02661 nt_status = NT_STATUS_BUFFER_TOO_SMALL;
02662 break;
02663 }
02664
02665 sid_parse(pdata+8,sid_len,&sid);
02666
02667 if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
02668 ZERO_STRUCT(qt);
02669
02670
02671
02672
02673
02674 }
02675
02676
02677 param_len = 4;
02678 params = nttrans_realloc(ppparams, param_len);
02679 if(params == NULL) {
02680 return ERROR_DOS(ERRDOS,ERRnomem);
02681 }
02682
02683 pdata = nttrans_realloc(ppdata, data_len);
02684 if(pdata == NULL) {
02685 return ERROR_DOS(ERRDOS,ERRnomem);
02686 }
02687
02688 entry = pdata;
02689
02690
02691 SIVAL(params,0,data_len);
02692
02693
02694 SIVAL(entry,0,0);
02695
02696
02697 SIVAL(entry,4,sid_len);
02698
02699
02700 SBIG_UINT(entry,8,(SMB_BIG_UINT)0);
02701
02702
02703 SBIG_UINT(entry,16,qt.usedspace);
02704
02705
02706 SBIG_UINT(entry,24,qt.softlim);
02707
02708
02709 SBIG_UINT(entry,32,qt.hardlim);
02710
02711
02712 sid_linearize(entry+40, sid_len, &sid);
02713
02714 break;
02715
02716 default:
02717 DEBUG(0,("do_nt_transact_get_user_quota: fnum %d unknown level 0x%04hX\n",fsp->fnum,level));
02718 return ERROR_DOS(ERRSRV,ERRerror);
02719 break;
02720 }
02721
02722 send_nt_replies(outbuf, bufsize, nt_status, params, param_len,
02723 pdata, data_len);
02724
02725 return -1;
02726 }
02727
02728
02729
02730
02731
02732 static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
02733 uint16 **ppsetup, uint32 setup_count,
02734 char **ppparams, uint32 parameter_count,
02735 char **ppdata, uint32 data_count, uint32 max_data_count)
02736 {
02737 char *params = *ppparams;
02738 char *pdata = *ppdata;
02739 int data_len=0,param_len=0;
02740 SMB_NTQUOTA_STRUCT qt;
02741 size_t sid_len;
02742 DOM_SID sid;
02743 files_struct *fsp = NULL;
02744
02745 ZERO_STRUCT(qt);
02746
02747
02748 if (current_user.ut.uid != 0) {
02749 DEBUG(1,("set_user_quota: access_denied service [%s] user [%s]\n",
02750 lp_servicename(SNUM(conn)),conn->user));
02751 return ERROR_DOS(ERRDOS,ERRnoaccess);
02752 }
02753
02754
02755
02756
02757
02758 if (parameter_count < 2) {
02759 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= 2 bytes parameters\n",parameter_count));
02760 return ERROR_DOS(ERRDOS,ERRinvalidparam);
02761 }
02762
02763
02764 fsp = file_fsp(params,0);
02765 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
02766 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
02767 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
02768 }
02769
02770 if (data_count < 40) {
02771 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %d bytes data\n",data_count,40));
02772 return ERROR_DOS(ERRDOS,ERRunknownlevel);
02773 }
02774
02775
02776
02777
02778
02779
02780
02781 sid_len = IVAL(pdata,4);
02782
02783 if (data_count < 40+sid_len) {
02784 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %lu bytes data\n",data_count,(unsigned long)40+sid_len));
02785 return ERROR_DOS(ERRDOS,ERRunknownlevel);
02786 }
02787
02788
02789
02790
02791
02792
02793 qt.usedspace = (SMB_BIG_UINT)IVAL(pdata,16);
02794 #ifdef LARGE_SMB_OFF_T
02795 qt.usedspace |= (((SMB_BIG_UINT)IVAL(pdata,20)) << 32);
02796 #else
02797 if ((IVAL(pdata,20) != 0)&&
02798 ((qt.usedspace != 0xFFFFFFFF)||
02799 (IVAL(pdata,20)!=0xFFFFFFFF))) {
02800
02801 return ERROR_DOS(ERRDOS,ERRunknownlevel);
02802 }
02803 #endif
02804
02805
02806 qt.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
02807 #ifdef LARGE_SMB_OFF_T
02808 qt.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
02809 #else
02810 if ((IVAL(pdata,28) != 0)&&
02811 ((qt.softlim != 0xFFFFFFFF)||
02812 (IVAL(pdata,28)!=0xFFFFFFFF))) {
02813
02814 return ERROR_DOS(ERRDOS,ERRunknownlevel);
02815 }
02816 #endif
02817
02818
02819 qt.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
02820 #ifdef LARGE_SMB_OFF_T
02821 qt.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
02822 #else
02823 if ((IVAL(pdata,36) != 0)&&
02824 ((qt.hardlim != 0xFFFFFFFF)||
02825 (IVAL(pdata,36)!=0xFFFFFFFF))) {
02826
02827 return ERROR_DOS(ERRDOS,ERRunknownlevel);
02828 }
02829 #endif
02830
02831 sid_parse(pdata+40,sid_len,&sid);
02832 DEBUGADD(8,("SID: %s\n",sid_string_static(&sid)));
02833
02834
02835
02836 if (vfs_set_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
02837 return ERROR_DOS(ERRSRV,ERRerror);
02838 }
02839
02840 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, params, param_len,
02841 pdata, data_len);
02842
02843 return -1;
02844 }
02845 #endif
02846
02847 static int handle_nttrans(connection_struct *conn,
02848 struct trans_state *state,
02849 char *inbuf, char *outbuf, int size, int bufsize)
02850 {
02851 int outsize;
02852
02853 if (Protocol >= PROTOCOL_NT1) {
02854 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40);
02855 }
02856
02857
02858 switch(state->call) {
02859 case NT_TRANSACT_CREATE:
02860 {
02861 START_PROFILE(NT_transact_create);
02862 outsize = call_nt_transact_create(conn, inbuf, outbuf,
02863 size, bufsize,
02864 &state->setup, state->setup_count,
02865 &state->param, state->total_param,
02866 &state->data, state->total_data,
02867 state->max_data_return);
02868 END_PROFILE(NT_transact_create);
02869 break;
02870 }
02871
02872 case NT_TRANSACT_IOCTL:
02873 {
02874 START_PROFILE(NT_transact_ioctl);
02875 outsize = call_nt_transact_ioctl(conn, inbuf, outbuf,
02876 size, bufsize,
02877 &state->setup, state->setup_count,
02878 &state->param, state->total_param,
02879 &state->data, state->total_data, state->max_data_return);
02880 END_PROFILE(NT_transact_ioctl);
02881 break;
02882 }
02883
02884 case NT_TRANSACT_SET_SECURITY_DESC:
02885 {
02886 START_PROFILE(NT_transact_set_security_desc);
02887 outsize = call_nt_transact_set_security_desc(conn, inbuf, outbuf,
02888 size, bufsize,
02889 &state->setup, state->setup_count,
02890 &state->param, state->total_param,
02891 &state->data, state->total_data, state->max_data_return);
02892 END_PROFILE(NT_transact_set_security_desc);
02893 break;
02894 }
02895
02896 case NT_TRANSACT_NOTIFY_CHANGE:
02897 {
02898 START_PROFILE(NT_transact_notify_change);
02899 outsize = call_nt_transact_notify_change(
02900 conn, inbuf, outbuf, size, bufsize,
02901 &state->setup, state->setup_count,
02902 &state->param, state->total_param,
02903 &state->data, state->total_data,
02904 state->max_data_return,
02905 state->max_param_return);
02906 END_PROFILE(NT_transact_notify_change);
02907 break;
02908 }
02909
02910 case NT_TRANSACT_RENAME:
02911 {
02912 START_PROFILE(NT_transact_rename);
02913 outsize = call_nt_transact_rename(conn, inbuf, outbuf,
02914 size, bufsize,
02915 &state->setup, state->setup_count,
02916 &state->param, state->total_param,
02917 &state->data, state->total_data, state->max_data_return);
02918 END_PROFILE(NT_transact_rename);
02919 break;
02920 }
02921
02922 case NT_TRANSACT_QUERY_SECURITY_DESC:
02923 {
02924 START_PROFILE(NT_transact_query_security_desc);
02925 outsize = call_nt_transact_query_security_desc(conn, inbuf, outbuf,
02926 size, bufsize,
02927 &state->setup, state->setup_count,
02928 &state->param, state->total_param,
02929 &state->data, state->total_data, state->max_data_return);
02930 END_PROFILE(NT_transact_query_security_desc);
02931 break;
02932 }
02933
02934 #ifdef HAVE_SYS_QUOTAS
02935 case NT_TRANSACT_GET_USER_QUOTA:
02936 {
02937 START_PROFILE(NT_transact_get_user_quota);
02938 outsize = call_nt_transact_get_user_quota(conn, inbuf, outbuf,
02939 size, bufsize,
02940 &state->setup, state->setup_count,
02941 &state->param, state->total_param,
02942 &state->data, state->total_data, state->max_data_return);
02943 END_PROFILE(NT_transact_get_user_quota);
02944 break;
02945 }
02946
02947 case NT_TRANSACT_SET_USER_QUOTA:
02948 {
02949 START_PROFILE(NT_transact_set_user_quota);
02950 outsize = call_nt_transact_set_user_quota(conn, inbuf, outbuf,
02951 size, bufsize,
02952 &state->setup, state->setup_count,
02953 &state->param, state->total_param,
02954 &state->data, state->total_data, state->max_data_return);
02955 END_PROFILE(NT_transact_set_user_quota);
02956 break;
02957 }
02958 #endif
02959
02960 default:
02961
02962 DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n",
02963 state->call));
02964 return ERROR_DOS(ERRSRV,ERRerror);
02965 }
02966 return outsize;
02967 }
02968
02969
02970
02971
02972
02973 int reply_nttrans(connection_struct *conn,
02974 char *inbuf,char *outbuf,int size,int bufsize)
02975 {
02976 int outsize = 0;
02977 uint32 pscnt = IVAL(inbuf,smb_nt_ParameterCount);
02978 uint32 psoff = IVAL(inbuf,smb_nt_ParameterOffset);
02979 uint32 dscnt = IVAL(inbuf,smb_nt_DataCount);
02980 uint32 dsoff = IVAL(inbuf,smb_nt_DataOffset);
02981 uint32 av_size = size-4;
02982
02983 uint16 function_code = SVAL( inbuf, smb_nt_Function);
02984 NTSTATUS result;
02985 struct trans_state *state;
02986
02987 START_PROFILE(SMBnttrans);
02988
02989 if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) {
02990 END_PROFILE(SMBnttrans);
02991 return ERROR_DOS(ERRSRV,ERRaccess);
02992 }
02993
02994 result = allow_new_trans(conn->pending_trans, SVAL(inbuf, smb_mid));
02995 if (!NT_STATUS_IS_OK(result)) {
02996 DEBUG(2, ("Got invalid nttrans request: %s\n", nt_errstr(result)));
02997 END_PROFILE(SMBnttrans);
02998 return ERROR_NT(result);
02999 }
03000
03001 if ((state = TALLOC_P(conn->mem_ctx, struct trans_state)) == NULL) {
03002 END_PROFILE(SMBnttrans);
03003 return ERROR_DOS(ERRSRV,ERRaccess);
03004 }
03005
03006 state->cmd = SMBnttrans;
03007
03008 state->mid = SVAL(inbuf,smb_mid);
03009 state->vuid = SVAL(inbuf,smb_uid);
03010 state->total_data = IVAL(inbuf, smb_nt_TotalDataCount);
03011 state->data = NULL;
03012 state->total_param = IVAL(inbuf, smb_nt_TotalParameterCount);
03013 state->param = NULL;
03014 state->max_data_return = IVAL(inbuf,smb_nt_MaxDataCount);
03015 state->max_param_return = IVAL(inbuf,smb_nt_MaxParameterCount);
03016
03017
03018 state->setup_count = 2*CVAL(inbuf,smb_nt_SetupCount);
03019 state->setup = NULL;
03020 state->call = function_code;
03021
03022
03023
03024
03025
03026
03027 if(CVAL(inbuf, smb_wct) != 19 + (state->setup_count/2)) {
03028 DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
03029 CVAL(inbuf, smb_wct), 19 + (state->setup_count/2)));
03030 goto bad_param;
03031 }
03032
03033
03034 if ((state->total_data > (1024*1024*128)) ||
03035 (state->total_param > (1024*1024*128))) {
03036 END_PROFILE(SMBnttrans);
03037 return ERROR_DOS(ERRDOS,ERRnomem);
03038 }
03039
03040 if ((dscnt > state->total_data) || (pscnt > state->total_param))
03041 goto bad_param;
03042
03043 if (state->total_data) {
03044
03045
03046 if ((state->data = (char *)SMB_MALLOC(state->total_data)) == NULL) {
03047 DEBUG(0,("reply_nttrans: data malloc fail for %u "
03048 "bytes !\n", (unsigned int)state->total_data));
03049 TALLOC_FREE(state);
03050 END_PROFILE(SMBnttrans);
03051 return(ERROR_DOS(ERRDOS,ERRnomem));
03052 }
03053
03054 if (dscnt > state->total_data ||
03055 dsoff+dscnt < dsoff) {
03056 goto bad_param;
03057 }
03058
03059 if (dsoff > av_size ||
03060 dscnt > av_size ||
03061 dsoff+dscnt > av_size) {
03062 goto bad_param;
03063 }
03064
03065 memcpy(state->data,smb_base(inbuf)+dsoff,dscnt);
03066 }
03067
03068 if (state->total_param) {
03069
03070
03071 if ((state->param = (char *)SMB_MALLOC(state->total_param)) == NULL) {
03072 DEBUG(0,("reply_nttrans: param malloc fail for %u "
03073 "bytes !\n", (unsigned int)state->total_param));
03074 SAFE_FREE(state->data);
03075 TALLOC_FREE(state);
03076 END_PROFILE(SMBnttrans);
03077 return(ERROR_DOS(ERRDOS,ERRnomem));
03078 }
03079
03080 if (pscnt > state->total_param ||
03081 psoff+pscnt < psoff) {
03082 goto bad_param;
03083 }
03084
03085 if (psoff > av_size ||
03086 pscnt > av_size ||
03087 psoff+pscnt > av_size) {
03088 goto bad_param;
03089 }
03090
03091 memcpy(state->param,smb_base(inbuf)+psoff,pscnt);
03092 }
03093
03094 state->received_data = dscnt;
03095 state->received_param = pscnt;
03096
03097 if(state->setup_count > 0) {
03098 DEBUG(10,("reply_nttrans: state->setup_count = %d\n",
03099 state->setup_count));
03100 state->setup = (uint16 *)TALLOC(state, state->setup_count);
03101 if (state->setup == NULL) {
03102 DEBUG(0,("reply_nttrans : Out of memory\n"));
03103 SAFE_FREE(state->data);
03104 SAFE_FREE(state->param);
03105 TALLOC_FREE(state);
03106 END_PROFILE(SMBnttrans);
03107 return ERROR_DOS(ERRDOS,ERRnomem);
03108 }
03109
03110 if ((smb_nt_SetupStart + state->setup_count < smb_nt_SetupStart) ||
03111 (smb_nt_SetupStart + state->setup_count < state->setup_count)) {
03112 goto bad_param;
03113 }
03114 if (smb_nt_SetupStart + state->setup_count > size) {
03115 goto bad_param;
03116 }
03117
03118 memcpy( state->setup, &inbuf[smb_nt_SetupStart], state->setup_count);
03119 dump_data(10, (char *)state->setup, state->setup_count);
03120 }
03121
03122 if ((state->received_data == state->total_data) &&
03123 (state->received_param == state->total_param)) {
03124 outsize = handle_nttrans(conn, state, inbuf, outbuf,
03125 size, bufsize);
03126 SAFE_FREE(state->param);
03127 SAFE_FREE(state->data);
03128 TALLOC_FREE(state);
03129 END_PROFILE(SMBnttrans);
03130 return outsize;
03131 }
03132
03133 DLIST_ADD(conn->pending_trans, state);
03134
03135
03136
03137 outsize = set_message(outbuf,0,0,False);
03138 show_msg(outbuf);
03139 END_PROFILE(SMBnttrans);
03140 return outsize;
03141
03142 bad_param:
03143
03144 DEBUG(0,("reply_nttrans: invalid trans parameters\n"));
03145 SAFE_FREE(state->data);
03146 SAFE_FREE(state->param);
03147 TALLOC_FREE(state);
03148 END_PROFILE(SMBnttrans);
03149 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
03150 }
03151
03152
03153
03154
03155
03156 int reply_nttranss(connection_struct *conn, char *inbuf,char *outbuf,
03157 int size,int bufsize)
03158 {
03159 int outsize = 0;
03160 uint32_t pcnt,poff,dcnt,doff,pdisp,ddisp;
03161 uint32_t av_size = size-4;
03162 struct trans_state *state;
03163
03164 START_PROFILE(SMBnttranss);
03165
03166 show_msg(inbuf);
03167
03168 for (state = conn->pending_trans; state != NULL;
03169 state = state->next) {
03170 if (state->mid == SVAL(inbuf,smb_mid)) {
03171 break;
03172 }
03173 }
03174
03175 if ((state == NULL) || (state->cmd != SMBnttrans)) {
03176 END_PROFILE(SMBnttranss);
03177 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
03178 }
03179
03180
03181
03182 if (IVAL(inbuf, smb_nts_TotalParameterCount) < state->total_param) {
03183 state->total_param = IVAL(inbuf, smb_nts_TotalParameterCount);
03184 }
03185 if (IVAL(inbuf, smb_nts_TotalDataCount) < state->total_data) {
03186 state->total_data = IVAL(inbuf, smb_nts_TotalDataCount);
03187 }
03188
03189 pcnt = IVAL(inbuf,smb_nts_ParameterCount);
03190 poff = IVAL(inbuf, smb_nts_ParameterOffset);
03191 pdisp = IVAL(inbuf, smb_nts_ParameterDisplacement);
03192
03193 dcnt = IVAL(inbuf, smb_nts_DataCount);
03194 ddisp = IVAL(inbuf, smb_nts_DataDisplacement);
03195 doff = IVAL(inbuf, smb_nts_DataOffset);
03196
03197 state->received_param += pcnt;
03198 state->received_data += dcnt;
03199
03200 if ((state->received_data > state->total_data) ||
03201 (state->received_param > state->total_param))
03202 goto bad_param;
03203
03204 if (pcnt) {
03205 if (pdisp > state->total_param ||
03206 pcnt > state->total_param ||
03207 pdisp+pcnt > state->total_param ||
03208 pdisp+pcnt < pdisp) {
03209 goto bad_param;
03210 }
03211
03212 if (poff > av_size ||
03213 pcnt > av_size ||
03214 poff+pcnt > av_size ||
03215 poff+pcnt < poff) {
03216 goto bad_param;
03217 }
03218
03219 memcpy(state->param+pdisp,smb_base(inbuf)+poff,
03220 pcnt);
03221 }
03222
03223 if (dcnt) {
03224 if (ddisp > state->total_data ||
03225 dcnt > state->total_data ||
03226 ddisp+dcnt > state->total_data ||
03227 ddisp+dcnt < ddisp) {
03228 goto bad_param;
03229 }
03230
03231 if (doff > av_size ||
03232 dcnt > av_size ||
03233 doff+dcnt > av_size ||
03234 doff+dcnt < doff) {
03235 goto bad_param;
03236 }
03237
03238 memcpy(state->data+ddisp, smb_base(inbuf)+doff,
03239 dcnt);
03240 }
03241
03242 if ((state->received_param < state->total_param) ||
03243 (state->received_data < state->total_data)) {
03244 END_PROFILE(SMBnttranss);
03245 return -1;
03246 }
03247
03248
03249
03250
03251 SCVAL(outbuf,smb_com,SMBnttrans);
03252
03253 outsize = handle_nttrans(conn, state, inbuf, outbuf,
03254 size, bufsize);
03255
03256 DLIST_REMOVE(conn->pending_trans, state);
03257 SAFE_FREE(state->data);
03258 SAFE_FREE(state->param);
03259 TALLOC_FREE(state);
03260
03261 if (outsize == 0) {
03262 END_PROFILE(SMBnttranss);
03263 return(ERROR_DOS(ERRSRV,ERRnosupport));
03264 }
03265
03266 END_PROFILE(SMBnttranss);
03267 return(outsize);
03268
03269 bad_param:
03270
03271 DEBUG(0,("reply_nttranss: invalid trans parameters\n"));
03272 DLIST_REMOVE(conn->pending_trans, state);
03273 SAFE_FREE(state->data);
03274 SAFE_FREE(state->param);
03275 TALLOC_FREE(state);
03276 END_PROFILE(SMBnttranss);
03277 return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
03278 }