関数 | |
static char * | nttrans_realloc (char **ptr, size_t size) |
int | send_nt_replies (char *outbuf, int bufsize, NTSTATUS nt_error, char *params, int paramsize, char *pdata, int datasize) |
BOOL | is_ntfs_stream_name (const char *fname) |
static uint32 | set_posix_case_semantics (connection_struct *conn, uint32 file_attributes) |
static void | restore_case_semantics (connection_struct *conn, uint32 file_attributes) |
static int | nt_open_pipe (char *fname, connection_struct *conn, char *inbuf, char *outbuf, int *ppnum) |
static int | do_ntcreate_pipe_open (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize) |
int | reply_ntcreate_and_X_quota (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, enum FAKE_FILE_TYPE fake_file_type, const char *fname) |
int | reply_ntcreate_and_X (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize) |
static int | do_nt_transact_create_pipe (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count) |
static NTSTATUS | set_sd (files_struct *fsp, char *data, uint32 sd_len, uint32 security_info_sent) |
static struct ea_list * | read_nttrans_ea_list (TALLOC_CTX *ctx, const char *pdata, size_t data_size) |
static int | call_nt_transact_create (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count) |
int | reply_ntcancel (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize) |
static NTSTATUS | copy_internals (connection_struct *conn, char *oldname, char *newname, uint32 attrs) |
int | reply_ntrename (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize) |
static int | call_nt_transact_notify_change (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count, uint32 max_param_count) |
static int | call_nt_transact_rename (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count) |
static size_t | get_null_nt_acl (TALLOC_CTX *mem_ctx, SEC_DESC **ppsd) |
static int | call_nt_transact_query_security_desc (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count) |
static int | call_nt_transact_set_security_desc (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count) |
static int | call_nt_transact_ioctl (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count) |
static int | call_nt_transact_get_user_quota (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count) |
static int | call_nt_transact_set_user_quota (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, uint16 **ppsetup, uint32 setup_count, char **ppparams, uint32 parameter_count, char **ppdata, uint32 data_count, uint32 max_data_count) |
static int | handle_nttrans (connection_struct *conn, struct trans_state *state, char *inbuf, char *outbuf, int size, int bufsize) |
int | reply_nttrans (connection_struct *conn, char *inbuf, char *outbuf, int size, int bufsize) |
int | reply_nttranss (connection_struct *conn, char *inbuf, char *outbuf, int size, int bufsize) |
変数 | |
int | max_send |
enum protocol_types | Protocol |
int | smb_read_error |
current_user | current_user |
static const char * | known_nt_pipes [] |
static BOOL | saved_case_sensitive |
static BOOL | saved_case_preserve |
static BOOL | saved_short_case_preserve |
static char* nttrans_realloc | ( | char ** | ptr, | |
size_t | size | |||
) | [static] |
参照先 smb_panic().
参照元 call_nt_transact_create()・call_nt_transact_get_user_quota()・call_nt_transact_ioctl()・call_nt_transact_query_security_desc()・do_nt_transact_create_pipe().
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 }
int send_nt_replies | ( | char * | outbuf, | |
int | bufsize, | |||
NTSTATUS | nt_error, | |||
char * | params, | |||
int | paramsize, | |||
char * | pdata, | |||
int | datasize | |||
) |
参照先 exit_server_cleanly()・max_send・send_smb()・set_message()・show_msg()・smbd_server_fd().
参照元 call_nt_transact_create()・call_nt_transact_get_user_quota()・call_nt_transact_ioctl()・call_nt_transact_query_security_desc()・call_nt_transact_rename()・call_nt_transact_set_security_desc()・call_nt_transact_set_user_quota()・change_notify_reply()・do_nt_transact_create_pipe().
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 * Initially set the wcnt area to be 18 - this is true for all 00085 * transNT replies. 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 * If there genuinely are no parameters or data to send just send 00096 * the empty packet. 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 * When sending params and data ensure that both are nicely aligned. 00109 * Only do this alignment when there is also data to send - else 00110 * can cause NT redirector problems. 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 * Space is bufsize minus Netbios over TCP header minus SMB header. 00119 * The alignment_offset is to align the param bytes on a four byte 00120 * boundary (2 bytes for data len, one byte pad). 00121 * NT needs this to work correctly. 00122 */ 00123 00124 useable_space = bufsize - ((smb_buf(outbuf)+ 00125 alignment_offset+data_alignment_offset) - 00126 outbuf); 00127 00128 /* 00129 * useable_space can never be more than max_send minus the 00130 * alignment offset. 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 * Calculate whether we will totally or partially fill this packet. 00141 */ 00142 00143 total_sent_thistime = params_to_send + data_to_send + 00144 alignment_offset + data_alignment_offset; 00145 00146 /* 00147 * We can never send more than useable_space. 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 * Set total params and data to be sent. 00156 */ 00157 00158 SIVAL(outbuf,smb_ntr_TotalParameterCount,paramsize); 00159 SIVAL(outbuf,smb_ntr_TotalDataCount,datasize); 00160 00161 /* 00162 * Calculate how many parameters and data we can fit into 00163 * this packet. Parameters get precedence. 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 * smb_ntr_ParameterOffset is the offset from the start of the SMB header to the 00178 * parameter bytes, however the first 4 bytes of outbuf are 00179 * the Netbios over TCP header. Thus use smb_base() to subtract 00180 * them from the calculation. 00181 */ 00182 00183 SIVAL(outbuf,smb_ntr_ParameterOffset, 00184 ((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf))); 00185 /* 00186 * Absolute displacement of param bytes sent in this packet. 00187 */ 00188 00189 SIVAL(outbuf,smb_ntr_ParameterDisplacement,pp - params); 00190 } 00191 00192 /* 00193 * Deal with the data portion. 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 * The offset of the data bytes is the offset of the 00204 * parameter bytes plus the number of parameters being sent this time. 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 * Copy the param bytes into the packet. 00214 */ 00215 00216 if(params_sent_thistime) { 00217 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime); 00218 } 00219 00220 /* 00221 * Copy in the data bytes 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 /* Send the packet */ 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 * Sanity check 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 }
BOOL is_ntfs_stream_name | ( | const char * | fname | ) |
参照先 strchr_m().
参照元 call_nt_transact_create()・open_directory()・reply_ntcreate_and_X()・reply_ntrename().
00265 { 00266 if (lp_posix_pathnames()) { 00267 return False; 00268 } 00269 return (strchr_m(fname, ':') != NULL) ? True : False; 00270 }
static uint32 set_posix_case_semantics | ( | connection_struct * | conn, | |
uint32 | file_attributes | |||
) | [static] |
参照先 connection_struct::case_preserve・connection_struct::case_sensitive・current_user::conn・saved_case_preserve・saved_case_sensitive・saved_short_case_preserve・connection_struct::short_case_preserve.
参照元 call_nt_transact_create()・reply_ntcreate_and_X().
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 /* Set to POSIX. */ 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 }
static void restore_case_semantics | ( | connection_struct * | conn, | |
uint32 | file_attributes | |||
) | [static] |
参照先 connection_struct::case_preserve・connection_struct::case_sensitive・current_user::conn・saved_case_preserve・saved_case_sensitive・saved_short_case_preserve・connection_struct::short_case_preserve.
参照元 call_nt_transact_create()・reply_ntcreate_and_X().
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 }
static int nt_open_pipe | ( | char * | fname, | |
connection_struct * | conn, | |||
char * | inbuf, | |||
char * | outbuf, | |||
int * | ppnum | |||
) | [static] |
参照先 current_user::conn・known_nt_pipes・open_rpc_pipe_p()・smb_np_struct::pnum・store_pipe_opendb()・strequal()・current_user::vuid.
参照元 do_nt_transact_create_pipe()・do_ntcreate_pipe_open().
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 /* See if it is one we want to handle. */ 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 /* Strip \\ off the name. */ 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 /* Add pipe to db */ 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 }
static int do_ntcreate_pipe_open | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize | |||
) | [static] |
参照先 chain_reply()・current_user::conn・flags・nt_open_pipe()・set_message().
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 * Deal with pipe return. 00387 */ 00388 00389 if (flags & EXTENDED_RESPONSE_REQUIRED) { 00390 /* This is very strange. We 00391 * return 50 words, but only set 00392 * the wcnt to 42 ? It's definately 00393 * what happens on the wire.... 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); /* File Attributes. */ 00409 p += 20; 00410 /* File type. */ 00411 SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE); 00412 /* Device state. */ 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 * For pipes W2K3 seems to return 00421 * 0x12019B next. 00422 * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA) 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 }
int reply_ntcreate_and_X_quota | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize, | |||
enum FAKE_FILE_TYPE | fake_file_type, | |||
const char * | fname | |||
) |
参照先 chain_reply()・current_user::conn・files_struct::fnum・files_struct::fsp_name・open_fake_file()・result・set_message()・status.
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 /* SCVAL(p,0,NO_OPLOCK_RETURN); */ 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 }
int reply_ntcreate_and_X | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize | |||
) |
参照先 can_delete_file_in_directory()・can_write_to_file()・chain_reply()・check_name()・close_file()・files_struct::conn・do_ntcreate_pipe_open()・dos_filetime_timespec()・ERROR_CLOSE・FAKE_FILE_TYPE_NONE・file_fsp()・flags・files_struct::fnum・files_struct::fsp_name・get_allocation_size()・get_atimespec()・get_create_timespec()・get_mtimespec()・files_struct::initial_allocation_size・files_struct::is_directory・is_fake_file()・is_ntfs_stream_name()・open_directory()・open_file_ntcreate()・open_was_deferred()・files_struct::oplock_type・perms・put_long_date_timespec()・reply_ntcreate_and_X_quota()・resolve_dfspath()・restore_case_semantics()・result・set_message()・set_posix_case_semantics()・smb_roundup()・srvstr_get_path()・status・unix_convert()・vfs_allocate_file_space().
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 /* Breakout the oplock request bits so we can set the 00489 reply bits separately. */ 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 * If it's an IPC, use the pipe handler. 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 * Get the file name. 00538 */ 00539 00540 if(root_dir_fid != 0) { 00541 /* 00542 * This filename is relative to a directory fid. 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 * Check to see if this is a mac fork of some kind. 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 we need to handle the case when we get a 00571 relative open relative to a file and the 00572 pathname is blank - this is a reopen! 00573 (hint from demyn plantenberg) 00574 */ 00575 00576 END_PROFILE(SMBntcreateX); 00577 return(ERROR_DOS(ERRDOS,ERRbadfid)); 00578 } 00579 00580 /* 00581 * Copy in the base directory name. 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 * Ensure it ends in a '\'. 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 * Check to see if this is a mac fork of some kind. 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 * Here we go! support for changing the disk quotas --metze 00621 * 00622 * We need to fake up to open this MAGIC QUOTA file 00623 * and return a valid FID. 00624 * 00625 * w2k close this file directly after openening 00626 * xp also tries a QUERY_FILE_INFO on the file and then close it 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 * Now contruct the smb_open_mode value from the filename, 00641 * desired access and the share access. 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 * Ordinary file or directory. 00659 */ 00660 00661 /* 00662 * Check if POSIX semantics are wanted. 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 /* All file access must go through check_name() */ 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 /* This is the correct thing to do (check every time) but can_delete is 00682 expensive (it may have to read the parent directory permissions). So 00683 for now we're not doing it unless we have a strong hint the client 00684 is really going to delete this file. If the client is forcing FILE_CREATE 00685 let the filesystem take care of the permissions. */ 00686 00687 /* Setting FILE_SHARE_DELETE is the hint. */ 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 * If it's a request for a directory open, deal with it separately. 00703 */ 00704 00705 if(create_options & FILE_DIRECTORY_FILE) { 00706 00707 /* Can't open a temp directory. IFS kit test. */ 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 * Ordinary file case. 00725 */ 00726 00727 /* NB. We have a potential bug here. If we 00728 * cause an oplock break to ourselves, then we 00729 * could end up processing filename related 00730 * SMB requests whilst we await the oplock 00731 * break response. As we may have changed the 00732 * filename case semantics to be POSIX-like, 00733 * this could mean a filename request could 00734 * fail when it should succeed. This is a rare 00735 * condition, but eventually we must arrange 00736 * to restore the correct case semantics 00737 * before issuing an oplock break request to 00738 * our client. JRA. */ 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 /* We cheat here. There are two cases we 00751 * care about. One is a directory rename, 00752 * where the NT client will attempt to 00753 * open the source directory for 00754 * DELETE access. Note that when the 00755 * NT client does this it does *not* 00756 * set the directory bit in the 00757 * request packet. This is translated 00758 * into a read/write open 00759 * request. POSIX states that any open 00760 * for write request on a directory 00761 * will generate an EISDIR error, so 00762 * we can catch this here and open a 00763 * pseudo handle that is flagged as a 00764 * directory. The second is an open 00765 * for a permissions read only, which 00766 * we handle in the open_file_stat case. JRA. 00767 */ 00768 00769 if (NT_STATUS_EQUAL(status, 00770 NT_STATUS_FILE_IS_A_DIRECTORY)) { 00771 00772 /* 00773 * Fail the open if it was explicitly a non-directory file. 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 /* We have re-scheduled this call. */ 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 /* Save the requested allocation size. */ 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 /* Can't set allocation size on a directory. */ 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 * If the caller set the extended oplock request bit 00845 * and we granted one (by whatever means) - set the 00846 * correct bit for extended oplock reply. 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 /* This is very strange. We 00859 * return 50 words, but only set 00860 * the wcnt to 42 ? It's definately 00861 * what happens on the wire.... 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 * Currently as we don't support level II oplocks we just report 00873 * exclusive & batch here. 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 /* Create time. */ 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); /* create time. */ 00910 p += 8; 00911 put_long_date_timespec(p, a_timespec); /* access time */ 00912 p += 8; 00913 put_long_date_timespec(p, m_timespec); /* write time */ 00914 p += 8; 00915 put_long_date_timespec(p, m_timespec); /* change time */ 00916 p += 8; 00917 SIVAL(p,0,fattr); /* File Attributes. */ 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 }
static int do_nt_transact_create_pipe | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize, | |||
uint16 ** | ppsetup, | |||
uint32 | setup_count, | |||
char ** | ppparams, | |||
uint32 | parameter_count, | |||
char ** | ppdata, | |||
uint32 | data_count | |||
) | [static] |
参照先 flags・nt_open_pipe()・nttrans_realloc()・send_nt_replies()・srvstr_get_path()・status.
参照元 call_nt_transact_create().
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 * Ensure minimum number of parameters sent. 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 /* Realloc the size of parameters and data we will return */ 00986 if (flags & EXTENDED_RESPONSE_REQUIRED) { 00987 /* Extended response is 32 more byyes. */ 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); /* File Attributes. */ 01008 p += 20; 01009 /* File type. */ 01010 SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE); 01011 /* Device state. */ 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 * For pipes W2K3 seems to return 01020 * 0x12019B next. 01021 * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA) 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 /* Send the required number of replies */ 01029 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, params, param_len, *ppdata, 0); 01030 01031 return -1; 01032 }
static NTSTATUS set_sd | ( | files_struct * | fsp, | |
char * | data, | |||
uint32 | sd_len, | |||
uint32 | security_info_sent | |||
) | [static] |
参照先 files_struct::conn・security_descriptor_info::dacl・fd_handle::fd・files_struct::fh・security_descriptor_info::group_sid・security_descriptor_info::owner_sid・prs_init()・security_descriptor_info::sacl・sec_io_desc()・talloc_init().
参照元 call_nt_transact_create()・call_nt_transact_set_security_desc().
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 * Init the parse struct we will unmarshall from. 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 * Setup the prs_struct to point at the memory we just 01062 * allocated. 01063 */ 01064 01065 prs_give_memory( &pd, data, sd_len, False); 01066 01067 /* 01068 * Finally, unmarshall from the data buffer. 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 * Return access denied for want of a better error message.. 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 }
static struct ea_list* read_nttrans_ea_list | ( | TALLOC_CTX * | ctx, | |
const char * | pdata, | |||
size_t | data_size | |||
) | [static] |
参照先 read_ea_list_entry().
参照元 call_nt_transact_create().
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 }
static int call_nt_transact_create | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize, | |||
uint16 ** | ppsetup, | |||
uint32 | setup_count, | |||
char ** | ppparams, | |||
uint32 | parameter_count, | |||
char ** | ppdata, | |||
uint32 | data_count, | |||
uint32 | max_data_count | |||
) | [static] |
参照先 files_struct::access_mask・can_delete_file_in_directory()・can_write_to_file()・check_name()・close_file()・files_struct::conn・ctx・do_nt_transact_create_pipe()・dos_filetime_timespec()・ERROR_CLOSE・file_fsp()・flags・files_struct::fnum・files_struct::fsp_name・get_allocation_size()・get_atimespec()・get_create_timespec()・get_mtimespec()・files_struct::initial_allocation_size・files_struct::is_directory・is_ntfs_stream_name()・nttrans_realloc()・open_directory()・open_file_ntcreate()・open_was_deferred()・files_struct::oplock_type・perms・put_long_date_timespec()・read_nttrans_ea_list()・resolve_dfspath()・restore_case_semantics()・send_nt_replies()・set_ea()・set_posix_case_semantics()・set_sd()・smb_roundup()・srvstr_get_path()・status・tmp_talloc_ctx()・unix_convert()・vfs_allocate_file_space().
参照元 handle_nttrans().
01144 { 01145 pstring fname; 01146 char *params = *ppparams; 01147 char *data = *ppdata; 01148 /* Breakout the oplock request bits so we can set the reply bits separately. */ 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 * If it's an IPC, use the pipe handler. 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 * Ensure minimum number of parameters sent. 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 /* Ensure the data_len is correct for the sd and ea values given. */ 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 * Get the file name. 01242 */ 01243 01244 if(root_dir_fid != 0) { 01245 /* 01246 * This filename is relative to a directory fid. 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 * Check to see if this is a mac fork of some kind. 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 * Copy in the base directory name. 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 * Ensure it ends in a '\'. 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 * Check to see if this is a mac fork of some kind. 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 * Ordinary file or directory. 01320 */ 01321 01322 /* 01323 * Check if POSIX semantics are wanted. 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 /* All file access must go through check_name() */ 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 /* This is the correct thing to do (check every time) but can_delete is 01349 expensive (it may have to read the parent directory permissions). So 01350 for now we're not doing it unless we have a strong hint the client 01351 is really going to delete this file. If the client is forcing FILE_CREATE 01352 let the filesystem take care of the permissions. */ 01353 01354 /* Setting FILE_SHARE_DELETE is the hint. */ 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 /* We have already checked that ea_len <= data_count here. */ 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 * If it's a request for a directory open, deal with it separately. 01381 */ 01382 01383 if(create_options & FILE_DIRECTORY_FILE) { 01384 01385 /* Can't open a temp directory. IFS kit test. */ 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 * We will get a create directory here if the Win32 01393 * app specified a security descriptor in the 01394 * CreateDirectory() call. 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 * Ordinary file case. 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 * Fail the open if it was explicitly a non-directory file. 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 /* We have re-scheduled this call. */ 01450 return -1; 01451 } 01452 01453 return ERROR_OPEN(status); 01454 } 01455 01456 /* 01457 * According to the MS documentation, the only time the security 01458 * descriptor is applied to the opened file is iff we *created* the 01459 * file; an existing file stays the same. 01460 * 01461 * Also, it seems (from observation) that you can open the file with 01462 * any access mask but you can still write the sd. We need to override 01463 * the granted access before we call set_sd 01464 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>. 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 /* We have already checked that sd_len <= data_count here. */ 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 /* Save the requested allocation size. */ 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 /* Can't set allocation size on a directory. */ 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 * If the caller set the extended oplock request bit 01529 * and we granted one (by whatever means) - set the 01530 * correct bit for extended oplock reply. 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 /* Realloc the size of parameters and data we will return */ 01542 if (flags & EXTENDED_RESPONSE_REQUIRED) { 01543 /* Extended response is 32 more byyes. */ 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 /* Create time. */ 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); /* create time. */ 01588 p += 8; 01589 put_long_date_timespec(p, a_timespec); /* access time */ 01590 p += 8; 01591 put_long_date_timespec(p, m_timespec); /* write time */ 01592 p += 8; 01593 put_long_date_timespec(p, m_timespec); /* change time */ 01594 p += 8; 01595 SIVAL(p,0,fattr); /* File Attributes. */ 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 /* Send the required number of replies */ 01621 send_nt_replies(outbuf, bufsize, NT_STATUS_OK, params, param_len, *ppdata, 0); 01622 01623 return -1; 01624 }
int reply_ntcancel | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize | |||
) |
参照先 remove_pending_change_notify_requests_by_mid()・remove_pending_lock_requests_by_mid()・srv_cancel_sign_response().
01633 { 01634 /* 01635 * Go through and cancel any pending change notifies. 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 }
static NTSTATUS copy_internals | ( | connection_struct * | conn, | |
char * | oldname, | |||
char * | newname, | |||
uint32 | attrs | |||
) | [static] |
参照先 check_name()・close_file()・ERROR_CLOSE・fsp_set_pending_modtime()・get_mtimespec()・NORMAL_CLOSE・nt_errstr()・open_file_ntcreate()・parent_dirname()・reduce_name()・status・unix_convert()・vfs_transfer_file().
参照元 reply_ntrename().
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 /* Source must already exist. */ 01683 if (!VALID_STAT(sbuf1)) { 01684 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 01685 } 01686 /* Ensure attributes match. */ 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 /* Disallow if newname already exists. */ 01703 if (VALID_STAT(sbuf2)) { 01704 return NT_STATUS_OBJECT_NAME_COLLISION; 01705 } 01706 01707 /* No links from a directory. */ 01708 if (S_ISDIR(sbuf1.st_mode)) { 01709 return NT_STATUS_FILE_IS_A_DIRECTORY; 01710 } 01711 01712 /* Ensure this is within the share. */ 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, /* Read-only. */ 01722 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 01723 FILE_OPEN, 01724 0, /* No create options. */ 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, /* Read-only. */ 01735 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 01736 FILE_CREATE, 01737 0, /* No create options. */ 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 * As we are opening fsp1 read-only we only expect 01753 * an error on close on fsp2 if we are out of space. 01754 * Thus we don't look at the error return from the 01755 * close of fsp1. 01756 */ 01757 close_file(fsp1,NORMAL_CLOSE); 01758 01759 /* Ensure the modtime is set correctly on the destination file. */ 01760 fsp_set_pending_modtime(fsp2, get_mtimespec(&sbuf1)); 01761 01762 status = close_file(fsp2,NORMAL_CLOSE); 01763 01764 /* Grrr. We have to do this as open_file_ntcreate adds aARCH when it 01765 creates the file. This isn't the correct thing to do in the copy 01766 case. JRA */ 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 }
int reply_ntrename | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize | |||
) |
参照先 copy_internals()・hardlink_internals()・is_ntfs_stream_name()・ms_has_wild()・open_was_deferred()・rename_internals()・resolve_dfspath()・set_message()・srvstr_get_path_wcard()・status.
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 /* Can't rename a stream. */ 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 /* No wildcards. */ 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 /* No wildcards. */ 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; /* Default error. */ 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 /* We have re-scheduled this call. */ 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 }
static int call_nt_transact_notify_change | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize, | |||
uint16 ** | ppsetup, | |||
uint32 | setup_count, | |||
char ** | ppparams, | |||
uint32 | parameter_count, | |||
char ** | ppdata, | |||
uint32 | data_count, | |||
uint32 | max_data_count, | |||
uint32 | max_param_count | |||
) | [static] |
参照先 change_notify_add_request()・change_notify_create()・change_notify_reply()・files_struct::conn・file_fsp()・files_struct::fsp_name・files_struct::is_directory・files_struct::notify・notify_filter_string()・nt_errstr()・notify_change_buf::num_changes・status.
参照元 handle_nttrans().
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 * We've got changes pending, respond immediately 01956 */ 01957 01958 /* 01959 * TODO: write a torture test to check the filtering behaviour 01960 * here. 01961 */ 01962 01963 change_notify_reply(inbuf, max_param_count, fsp->notify); 01964 01965 /* 01966 * change_notify_reply() above has independently sent its 01967 * results 01968 */ 01969 return -1; 01970 } 01971 01972 /* 01973 * No changes pending, queue the request 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 }
static int call_nt_transact_rename | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize, | |||
uint16 ** | ppsetup, | |||
uint32 | setup_count, | |||
char ** | ppparams, | |||
uint32 | parameter_count, | |||
char ** | ppdata, | |||
uint32 | data_count, | |||
uint32 | max_data_count | |||
) | [static] |
参照先 file_fsp()・open_was_deferred()・rename_internals()・send_nt_replies()・srvstr_get_path_wcard()・status.
参照元 handle_nttrans().
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 /* We have re-scheduled this call. */ 02020 return -1; 02021 } 02022 return ERROR_NT(status); 02023 } 02024 02025 /* 02026 * Rename was successful. 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 }
static size_t get_null_nt_acl | ( | TALLOC_CTX * | mem_ctx, | |
SEC_DESC ** | ppsd | |||
) | [static] |
参照先 global_sid_World・make_standard_sec_desc().
参照元 call_nt_transact_query_security_desc().
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 }
static int call_nt_transact_query_security_desc | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize, | |||
uint16 ** | ppsetup, | |||
uint32 | setup_count, | |||
char ** | ppparams, | |||
uint32 | parameter_count, | |||
char ** | ppdata, | |||
uint32 | data_count, | |||
uint32 | max_data_count | |||
) | [static] |
参照先 fd_handle::fd・files_struct::fh・file_fsp()・files_struct::fsp_name・get_null_nt_acl()・nttrans_realloc()・prs_init()・sec_io_desc()・send_nt_replies()・talloc_init().
参照元 handle_nttrans().
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 * Get the permissions to return. 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 * Allocate the data we will point this at. 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 * Init the parse struct we will marshall into. 02134 */ 02135 02136 prs_init(&pd, 0, mem_ctx, MARSHALL); 02137 02138 /* 02139 * Setup the prs_struct to point at the memory we just 02140 * allocated. 02141 */ 02142 02143 prs_give_memory( &pd, data, (uint32)sd_size, False); 02144 02145 /* 02146 * Finally, linearize into the outgoing buffer. 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 * Return access denied for want of a better error message.. 02154 */ 02155 talloc_destroy(mem_ctx); 02156 return(UNIXERROR(ERRDOS,ERRnoaccess)); 02157 } 02158 02159 /* 02160 * Now we can delete the security descriptor. 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 }
static int call_nt_transact_set_security_desc | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize, | |||
uint16 ** | ppsetup, | |||
uint32 | setup_count, | |||
char ** | ppparams, | |||
uint32 | parameter_count, | |||
char ** | ppdata, | |||
uint32 | data_count, | |||
uint32 | max_data_count | |||
) | [static] |
参照先 file_fsp()・files_struct::fsp_name・send_nt_replies()・set_sd().
参照元 handle_nttrans().
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 }
static int call_nt_transact_ioctl | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize, | |||
uint16 ** | ppsetup, | |||
uint32 | setup_count, | |||
char ** | ppparams, | |||
uint32 | parameter_count, | |||
char ** | ppdata, | |||
uint32 | data_count, | |||
uint32 | max_data_count | |||
) | [static] |
参照先 connection_struct::connectpath・errno・file_fsp()・files_struct::fsp_name・shadow_copy_data::labels・shadow_copy_data::mem_ctx・nttrans_realloc()・shadow_copy_data::num_volumes・send_nt_replies()・sid_parse()・sid_string_static()・sid_to_uid()・talloc_init().
参照元 handle_nttrans().
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 /* this check is done in each implemented function case for now 02248 because I don't want to break anything... --metze 02249 FSP_BELONGS_CONN(fsp,conn);*/ 02250 02251 switch (function) { 02252 case FSCTL_SET_SPARSE: 02253 /* pretend this succeeded - tho strictly we should 02254 mark the file sparse (if the local fs supports it) 02255 so we can know if we need to pre-allocate or not */ 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 /* pretend this succeeded - don't know what this really is 02264 but works ok like this --metze 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 /* pretend this fail - my winXP does it like this 02274 * --metze 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 /* pretend this fail - I'm assuming this because of the FSCTL_GET_REPARSE_POINT case. 02284 * --metze 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: /* don't know if this name is right...*/ 02293 { 02294 /* 02295 * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots) 02296 * and return their volume names. If max_data_count is 16, then it is just 02297 * asking for the number of volumes and length of the combined names. 02298 * 02299 * pdata is the data allocated by our caller, but that uses 02300 * total_data_count (which is 0 in our case) rather than max_data_count. 02301 * Allocate the correct amount and return the pointer to let 02302 * it be deallocated when we return. 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 * Call the VFS routine to actually do the work. 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 /* num_volumes 4 bytes */ 02378 SIVAL(pdata,0,shadow_data->num_volumes); 02379 02380 if (labels) { 02381 /* num_labels 4 bytes */ 02382 SIVAL(pdata,4,shadow_data->num_volumes); 02383 } 02384 02385 /* needed_data_count 4 bytes */ 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: /* I hope this name is right */ 02409 { 02410 /* pretend this succeeded - 02411 * 02412 * we have to send back a list with all files owned by this SID 02413 * 02414 * but I have to check that --metze 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 /* unknown 4 bytes: this is not the length of the sid :-( */ 02425 /*unknown = IVAL(pdata,0);*/ 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 /* we can take a look at the find source :-) 02437 * 02438 * find ./ -uid $uid -name '*' is what we need here 02439 * 02440 * 02441 * and send 4bytes len and then NULL terminated unicode strings 02442 * for each file 02443 * 02444 * but I don't know how to deal with the paged results 02445 * (maybe we can hang the result anywhere in the fsp struct) 02446 * 02447 * we don't send all files at once 02448 * and at the next we should *not* start from the beginning, 02449 * so we have to cache the result 02450 * 02451 * --metze 02452 */ 02453 02454 /* this works for now... */ 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; /* Only print this once... */ 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 }
static int call_nt_transact_get_user_quota | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize, | |||
uint16 ** | ppsetup, | |||
uint32 | setup_count, | |||
char ** | ppparams, | |||
uint32 | parameter_count, | |||
char ** | ppdata, | |||
uint32 | data_count, | |||
uint32 | max_data_count | |||
) | [static] |
参照先 current_user・files_struct::fake_file_handle・file_fsp()・files_struct::fnum・free_ntquota_list()・_SMB_NTQUOTA_STRUCT::hardlim・level・_SMB_NTQUOTA_LIST::next・nttrans_realloc()・_FAKE_FILE_HANDLE::pd・_SMB_NTQUOTA_HANDLE::quota_list・_SMB_NTQUOTA_LIST::quotas・send_nt_replies()・_SMB_NTQUOTA_STRUCT::sid・sid_linearize()・sid_parse()・sid_size()・SMB_USER_QUOTA_TYPE・_SMB_NTQUOTA_STRUCT::softlim・_SMB_NTQUOTA_HANDLE::tmp_list・_unix_token::uid・_SMB_NTQUOTA_STRUCT::usedspace・connection_struct::user・current_user::ut・vfs_get_ntquota()・vfs_get_user_ntquota_list().
参照元 handle_nttrans().
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 /* access check */ 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 * Ensure minimum number of parameters sent. 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 /* maybe we can check the quota_fnum */ 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 /* the NULL pointer checking for fsp->fake_file_handle->pd 02523 * is done by CHECK_NTQUOTA_HANDLE_OK() 02524 */ 02525 qt_handle = (SMB_NTQUOTA_HANDLE *)fsp->fake_file_handle->pd; 02526 02527 level = SVAL(params,2); 02528 02529 /* unknown 12 bytes leading in params */ 02530 02531 switch (level) { 02532 case TRANSACT_GET_USER_QUOTA_LIST_CONTINUE: 02533 /* seems that we should continue with the enum here --metze */ 02534 02535 if (qt_handle->quota_list!=NULL && 02536 qt_handle->tmp_list==NULL) { 02537 02538 /* free the list */ 02539 free_ntquota_list(&(qt_handle->quota_list)); 02540 02541 /* Realloc the size of parameters and data we will return */ 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 /* Realloc the size of parameters and data we will return */ 02567 param_len = 4; 02568 params = nttrans_realloc(ppparams, param_len); 02569 if(params == NULL) { 02570 return ERROR_DOS(ERRDOS,ERRnomem); 02571 } 02572 02573 /* we should not trust the value in max_data_count*/ 02574 max_data_count = MIN(max_data_count,2048); 02575 02576 pdata = nttrans_realloc(ppdata, max_data_count);/* should be max data count from client*/ 02577 if(pdata == NULL) { 02578 return ERROR_DOS(ERRDOS,ERRnomem); 02579 } 02580 02581 entry = pdata; 02582 02583 /* set params Size of returned Quota Data 4 bytes*/ 02584 /* but set it later when we know it */ 02585 02586 /* for each entry push the data */ 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 /* nextoffset entry 4 bytes */ 02601 SIVAL(entry,0,entry_len); 02602 02603 /* then the len of the SID 4 bytes */ 02604 SIVAL(entry,4,sid_len); 02605 02606 /* unknown data 8 bytes SMB_BIG_UINT */ 02607 SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-metze*/ 02608 02609 /* the used disk space 8 bytes SMB_BIG_UINT */ 02610 SBIG_UINT(entry,16,tmp_list->quotas->usedspace); 02611 02612 /* the soft quotas 8 bytes SMB_BIG_UINT */ 02613 SBIG_UINT(entry,24,tmp_list->quotas->softlim); 02614 02615 /* the hard quotas 8 bytes SMB_BIG_UINT */ 02616 SBIG_UINT(entry,32,tmp_list->quotas->hardlim); 02617 02618 /* and now the SID */ 02619 sid_linearize(entry+40, sid_len, &tmp_list->quotas->sid); 02620 } 02621 02622 qt_handle->tmp_list = tmp_list; 02623 02624 /* overwrite the offset of the last entry */ 02625 SIVAL(entry-entry_len,0,0); 02626 02627 data_len = 4+qt_len; 02628 /* overwrite the params quota_data_len */ 02629 SIVAL(params,0,data_len); 02630 02631 break; 02632 02633 case TRANSACT_GET_USER_QUOTA_FOR_SID: 02634 02635 /* unknown 4 bytes IVAL(pdata,0) */ 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 /* Ensure this is less than 1mb. */ 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 * we have to return zero's in all fields 02671 * instead of returning an error here 02672 * --metze 02673 */ 02674 } 02675 02676 /* Realloc the size of parameters and data we will return */ 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 /* set params Size of returned Quota Data 4 bytes*/ 02691 SIVAL(params,0,data_len); 02692 02693 /* nextoffset entry 4 bytes */ 02694 SIVAL(entry,0,0); 02695 02696 /* then the len of the SID 4 bytes */ 02697 SIVAL(entry,4,sid_len); 02698 02699 /* unknown data 8 bytes SMB_BIG_UINT */ 02700 SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-mezte*/ 02701 02702 /* the used disk space 8 bytes SMB_BIG_UINT */ 02703 SBIG_UINT(entry,16,qt.usedspace); 02704 02705 /* the soft quotas 8 bytes SMB_BIG_UINT */ 02706 SBIG_UINT(entry,24,qt.softlim); 02707 02708 /* the hard quotas 8 bytes SMB_BIG_UINT */ 02709 SBIG_UINT(entry,32,qt.hardlim); 02710 02711 /* and now the SID */ 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 }
static int call_nt_transact_set_user_quota | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize, | |||
uint16 ** | ppsetup, | |||
uint32 | setup_count, | |||
char ** | ppparams, | |||
uint32 | parameter_count, | |||
char ** | ppdata, | |||
uint32 | data_count, | |||
uint32 | max_data_count | |||
) | [static] |
参照先 current_user・file_fsp()・_SMB_NTQUOTA_STRUCT::hardlim・send_nt_replies()・sid_parse()・sid_string_static()・SMB_USER_QUOTA_TYPE・_SMB_NTQUOTA_STRUCT::softlim・_unix_token::uid・_SMB_NTQUOTA_STRUCT::usedspace・connection_struct::user・current_user::ut・vfs_set_ntquota().
参照元 handle_nttrans().
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 /* access check */ 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 * Ensure minimum number of parameters sent. 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 /* maybe we can check the quota_fnum */ 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 /* offset to next quota record. 02776 * 4 bytes IVAL(pdata,0) 02777 * unused here... 02778 */ 02779 02780 /* sid len */ 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 /* unknown 8 bytes in pdata 02789 * maybe its the change time in NTTIME 02790 */ 02791 02792 /* the used space 8 bytes (SMB_BIG_UINT)*/ 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 /* LARGE_SMB_OFF_T */ 02797 if ((IVAL(pdata,20) != 0)&& 02798 ((qt.usedspace != 0xFFFFFFFF)|| 02799 (IVAL(pdata,20)!=0xFFFFFFFF))) { 02800 /* more than 32 bits? */ 02801 return ERROR_DOS(ERRDOS,ERRunknownlevel); 02802 } 02803 #endif /* LARGE_SMB_OFF_T */ 02804 02805 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/ 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 /* LARGE_SMB_OFF_T */ 02810 if ((IVAL(pdata,28) != 0)&& 02811 ((qt.softlim != 0xFFFFFFFF)|| 02812 (IVAL(pdata,28)!=0xFFFFFFFF))) { 02813 /* more than 32 bits? */ 02814 return ERROR_DOS(ERRDOS,ERRunknownlevel); 02815 } 02816 #endif /* LARGE_SMB_OFF_T */ 02817 02818 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/ 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 /* LARGE_SMB_OFF_T */ 02823 if ((IVAL(pdata,36) != 0)&& 02824 ((qt.hardlim != 0xFFFFFFFF)|| 02825 (IVAL(pdata,36)!=0xFFFFFFFF))) { 02826 /* more than 32 bits? */ 02827 return ERROR_DOS(ERRDOS,ERRunknownlevel); 02828 } 02829 #endif /* LARGE_SMB_OFF_T */ 02830 02831 sid_parse(pdata+40,sid_len,&sid); 02832 DEBUGADD(8,("SID: %s\n",sid_string_static(&sid))); 02833 02834 /* 44 unknown bytes left... */ 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 }
static int handle_nttrans | ( | connection_struct * | conn, | |
struct trans_state * | state, | |||
char * | inbuf, | |||
char * | outbuf, | |||
int | size, | |||
int | bufsize | |||
) | [static] |
参照先 trans_state::call・call_nt_transact_create()・call_nt_transact_get_user_quota()・call_nt_transact_ioctl()・call_nt_transact_notify_change()・call_nt_transact_query_security_desc()・call_nt_transact_rename()・call_nt_transact_set_security_desc()・call_nt_transact_set_user_quota()・trans_state::data・trans_state::max_data_return・trans_state::max_param_return・trans_state::param・Protocol・PROTOCOL_NT1・trans_state::setup・trans_state::setup_count・trans_state::total_data・trans_state::total_param.
参照元 reply_nttrans()・reply_nttranss().
02850 { 02851 int outsize; 02852 02853 if (Protocol >= PROTOCOL_NT1) { 02854 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */ 02855 } 02856 02857 /* Now we must call the relevant NT_TRANS function */ 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 /* HAVE_SYS_QUOTAS */ 02959 02960 default: 02961 /* Error in request */ 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 }
int reply_nttrans | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | size, | |||
int | bufsize | |||
) |
参照先 allow_new_trans()・trans_state::call・trans_state::cmd・trans_state::data・dump_data()・handle_nttrans()・trans_state::max_data_return・trans_state::max_param_return・connection_struct::mem_ctx・trans_state::mid・nt_errstr()・trans_state::param・connection_struct::pending_trans・trans_state::received_data・trans_state::received_param・result・set_message()・trans_state::setup・trans_state::setup_count・show_msg()・trans_state::total_data・trans_state::total_param・trans_state::vuid.
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 /* setup count is in *words* */ 03018 state->setup_count = 2*CVAL(inbuf,smb_nt_SetupCount); 03019 state->setup = NULL; 03020 state->call = function_code; 03021 03022 /* 03023 * All nttrans messages we handle have smb_wct == 19 + 03024 * state->setup_count. Ensure this is so as a sanity check. 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 /* Don't allow more than 128mb for each value. */ 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 /* Can't use talloc here, the core routines do realloc on the 03045 * params and data. */ 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 /* Can't use talloc here, the core routines do realloc on the 03070 * params and data. */ 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 /* We need to send an interim response then receive the rest 03136 of the parameter/data bytes */ 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 }
int reply_nttranss | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | size, | |||
int | bufsize | |||
) |
参照先 trans_state::cmd・trans_state::data・handle_nttrans()・trans_state::mid・trans_state::next・trans_state::param・connection_struct::pending_trans・trans_state::received_data・trans_state::received_param・show_msg()・trans_state::total_data・trans_state::total_param.
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 /* Revise state->total_param and state->total_data in case they have 03181 changed downwards */ 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 /* construct_reply_common has done us the favor to pre-fill the 03249 * command field with SMBnttranss which is wrong :-) 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 }
enum protocol_types Protocol |
int smb_read_error |
util_sock.c の 117 行で定義されています。
struct current_user current_user |
const char* known_nt_pipes[] [static] |
初期値:
{ "\\LANMAN", "\\srvsvc", "\\samr", "\\wkssvc", "\\NETLOGON", "\\ntlsa", "\\ntsvcs", "\\lsass", "\\lsarpc", "\\winreg", "\\initshutdown", "\\spoolss", "\\netdfs", "\\rpcecho", "\\svcctl", "\\eventlog", "\\unixinfo", NULL }
参照元 nt_open_pipe().
BOOL saved_case_sensitive [static] |
BOOL saved_case_preserve [static] |
BOOL saved_short_case_preserve [static] |