関数 | |
NTSTATUS | check_path_syntax_internal (pstring destname, const pstring srcname, BOOL posix_path, BOOL *p_last_component_contains_wcard) |
NTSTATUS | check_path_syntax (pstring destname, const pstring srcname) |
NTSTATUS | check_path_syntax_wcard (pstring destname, const pstring srcname, BOOL *p_contains_wcard) |
NTSTATUS | check_path_syntax_posix (pstring destname, const pstring srcname) |
size_t | srvstr_get_path_wcard (char *inbuf, char *dest, const char *src, size_t dest_len, size_t src_len, int flags, NTSTATUS *err, BOOL *contains_wcard) |
size_t | srvstr_get_path (char *inbuf, char *dest, const char *src, size_t dest_len, size_t src_len, int flags, NTSTATUS *err) |
int | reply_special (char *inbuf, char *outbuf) |
int | reply_tcon (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
int | reply_tcon_and_X (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize) |
int | reply_unknown (char *inbuf, char *outbuf) |
int | reply_ioctl (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
static NTSTATUS | map_checkpath_error (const char *inbuf, NTSTATUS status) |
int | reply_checkpath (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
int | reply_getatr (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
int | reply_setatr (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
int | reply_dskattr (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
int | reply_search (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
int | reply_fclose (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
int | reply_open (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
int | reply_open_and_X (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize) |
int | reply_ulogoffX (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize) |
int | reply_mknew (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
int | reply_ctemp (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
static NTSTATUS | can_rename (connection_struct *conn, char *fname, uint16 dirtype, SMB_STRUCT_STAT *pst, BOOL self_open) |
static NTSTATUS | can_delete (connection_struct *conn, char *fname, uint32 dirtype, BOOL can_defer) |
NTSTATUS | unlink_internals (connection_struct *conn, uint32 dirtype, char *name, BOOL has_wild, BOOL can_defer) |
int | reply_unlink (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
static void | fail_readraw (void) |
static ssize_t | fake_sendfile (files_struct *fsp, SMB_OFF_T startpos, size_t nread, char *buf, int bufsize) |
void | send_file_readbraw (connection_struct *conn, files_struct *fsp, SMB_OFF_T startpos, size_t nread, ssize_t mincount, char *outbuf, int out_buffsize) |
int | reply_readbraw (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int out_buffsize) |
int | reply_lockread (connection_struct *conn, char *inbuf, char *outbuf, int length, int dum_buffsiz) |
int | reply_read (connection_struct *conn, char *inbuf, char *outbuf, int size, int dum_buffsize) |
int | send_file_readX (connection_struct *conn, char *inbuf, char *outbuf, int length, int len_outbuf, files_struct *fsp, SMB_OFF_T startpos, size_t smb_maxcnt) |
int | reply_read_and_X (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize) |
int | reply_writebraw (connection_struct *conn, char *inbuf, char *outbuf, int size, int dum_buffsize) |
int | reply_writeunlock (connection_struct *conn, char *inbuf, char *outbuf, int size, int dum_buffsize) |
int | reply_write (connection_struct *conn, char *inbuf, char *outbuf, int size, int dum_buffsize) |
int | reply_write_and_X (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize) |
int | reply_lseek (connection_struct *conn, char *inbuf, char *outbuf, int size, int dum_buffsize) |
int | reply_flush (connection_struct *conn, char *inbuf, char *outbuf, int size, int dum_buffsize) |
int | reply_exit (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
int | reply_close (connection_struct *conn, char *inbuf, char *outbuf, int size, int dum_buffsize) |
int | reply_writeclose (connection_struct *conn, char *inbuf, char *outbuf, int size, int dum_buffsize) |
int | reply_lock (connection_struct *conn, char *inbuf, char *outbuf, int length, int dum_buffsize) |
int | reply_unlock (connection_struct *conn, char *inbuf, char *outbuf, int size, int dum_buffsize) |
int | reply_tdis (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
int | reply_echo (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
int | reply_printopen (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
int | reply_printclose (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
int | reply_printqueue (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
int | reply_printwrite (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
int | reply_mkdir (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
static BOOL | recursive_rmdir (connection_struct *conn, char *directory) |
NTSTATUS | rmdir_internals (connection_struct *conn, const char *directory) |
int | reply_rmdir (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
static BOOL | resolve_wildcards (const char *name1, char *name2) |
static void | rename_open_files (connection_struct *conn, struct share_mode_lock *lck, SMB_DEV_T dev, SMB_INO_T inode, const char *newname) |
static BOOL | rename_path_prefix_equal (const char *src, const char *dest) |
NTSTATUS | rename_internals_fsp (connection_struct *conn, files_struct *fsp, pstring newname, uint32 attrs, BOOL replace_if_exists) |
static void | notify_rename (connection_struct *conn, BOOL is_dir, const char *oldpath, const char *newpath) |
NTSTATUS | rename_internals (connection_struct *conn, pstring name, pstring newname, uint32 attrs, BOOL replace_if_exists, BOOL src_has_wild, BOOL dest_has_wild) |
int | reply_mv (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
NTSTATUS | copy_file (connection_struct *conn, char *src, char *dest1, int ofun, int count, BOOL target_is_directory) |
int | reply_copy (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
int | reply_setdir (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
uint32 | get_lock_pid (char *data, int data_offset, BOOL large_file_format) |
SMB_BIG_UINT | get_lock_count (char *data, int data_offset, BOOL large_file_format) |
static uint32 | map_lock_offset (uint32 high, uint32 low) |
SMB_BIG_UINT | get_lock_offset (char *data, int data_offset, BOOL large_file_format, BOOL *err) |
int | reply_lockingX (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize) |
int | reply_readbmpx (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize) |
int | reply_setattrE (connection_struct *conn, char *inbuf, char *outbuf, int size, int dum_buffsize) |
int | reply_writebmpx (connection_struct *conn, char *inbuf, char *outbuf, int size, int dum_buffsize) |
int | reply_writebs (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
int | reply_getattrE (connection_struct *conn, char *inbuf, char *outbuf, int size, int dum_buffsize) |
変数 | |
enum protocol_types | Protocol |
int | max_send |
int | max_recv |
unsigned int | smb_echo_count = 0 |
uint32 | global_client_caps |
current_user | current_user |
BOOL | global_encrypted_passwords_negotiated |
NTSTATUS check_path_syntax_internal | ( | pstring | destname, | |
const pstring | srcname, | |||
BOOL | posix_path, | |||
BOOL * | p_last_component_contains_wcard | |||
) |
参照先 next_codepoint().
参照元 check_path_syntax()・check_path_syntax_posix()・check_path_syntax_wcard().
00054 { 00055 char *d = destname; 00056 const char *s = srcname; 00057 NTSTATUS ret = NT_STATUS_OK; 00058 BOOL start_of_name_component = True; 00059 00060 *p_last_component_contains_wcard = False; 00061 00062 while (*s) { 00063 if (IS_PATH_SEP(*s,posix_path)) { 00064 /* 00065 * Safe to assume is not the second part of a mb char as this is handled below. 00066 */ 00067 /* Eat multiple '/' or '\\' */ 00068 while (IS_PATH_SEP(*s,posix_path)) { 00069 s++; 00070 } 00071 if ((d != destname) && (*s != '\0')) { 00072 /* We only care about non-leading or trailing '/' or '\\' */ 00073 *d++ = '/'; 00074 } 00075 00076 start_of_name_component = True; 00077 /* New component. */ 00078 *p_last_component_contains_wcard = False; 00079 continue; 00080 } 00081 00082 if (start_of_name_component) { 00083 if ((s[0] == '.') && (s[1] == '.') && (IS_PATH_SEP(s[2],posix_path) || s[2] == '\0')) { 00084 /* Uh oh - "/../" or "\\..\\" or "/..\0" or "\\..\0" ! */ 00085 00086 /* 00087 * No mb char starts with '.' so we're safe checking the directory separator here. 00088 */ 00089 00090 /* If we just added a '/' - delete it */ 00091 if ((d > destname) && (*(d-1) == '/')) { 00092 *(d-1) = '\0'; 00093 d--; 00094 } 00095 00096 /* Are we at the start ? Can't go back further if so. */ 00097 if (d <= destname) { 00098 ret = NT_STATUS_OBJECT_PATH_SYNTAX_BAD; 00099 break; 00100 } 00101 /* Go back one level... */ 00102 /* We know this is safe as '/' cannot be part of a mb sequence. */ 00103 /* NOTE - if this assumption is invalid we are not in good shape... */ 00104 /* Decrement d first as d points to the *next* char to write into. */ 00105 for (d--; d > destname; d--) { 00106 if (*d == '/') 00107 break; 00108 } 00109 s += 2; /* Else go past the .. */ 00110 /* We're still at the start of a name component, just the previous one. */ 00111 continue; 00112 00113 } else if ((s[0] == '.') && ((s[1] == '\0') || IS_PATH_SEP(s[1],posix_path))) { 00114 if (posix_path) { 00115 /* Eat the '.' */ 00116 s++; 00117 continue; 00118 } 00119 } 00120 00121 } 00122 00123 if (!(*s & 0x80)) { 00124 if (!posix_path) { 00125 if (*s <= 0x1f) { 00126 return NT_STATUS_OBJECT_NAME_INVALID; 00127 } 00128 switch (*s) { 00129 case '*': 00130 case '?': 00131 case '<': 00132 case '>': 00133 case '"': 00134 *p_last_component_contains_wcard = True; 00135 break; 00136 default: 00137 break; 00138 } 00139 } 00140 *d++ = *s++; 00141 } else { 00142 size_t siz; 00143 /* Get the size of the next MB character. */ 00144 next_codepoint(s,&siz); 00145 switch(siz) { 00146 case 5: 00147 *d++ = *s++; 00148 /*fall through*/ 00149 case 4: 00150 *d++ = *s++; 00151 /*fall through*/ 00152 case 3: 00153 *d++ = *s++; 00154 /*fall through*/ 00155 case 2: 00156 *d++ = *s++; 00157 /*fall through*/ 00158 case 1: 00159 *d++ = *s++; 00160 break; 00161 default: 00162 DEBUG(0,("check_path_syntax_internal: character length assumptions invalid !\n")); 00163 *d = '\0'; 00164 return NT_STATUS_INVALID_PARAMETER; 00165 } 00166 } 00167 start_of_name_component = False; 00168 } 00169 00170 *d = '\0'; 00171 return ret; 00172 }
参照先 check_path_syntax_internal().
参照元 parse_dfs_path()・srvstr_get_path().
00180 { 00181 BOOL ignore; 00182 return check_path_syntax_internal(destname, srcname, False, &ignore); 00183 }
NTSTATUS check_path_syntax_wcard | ( | pstring | destname, | |
const pstring | srcname, | |||
BOOL * | p_contains_wcard | |||
) |
参照先 check_path_syntax_internal().
参照元 parse_dfs_path()・srvstr_get_path_wcard().
00192 { 00193 return check_path_syntax_internal(destname, srcname, False, p_contains_wcard); 00194 }
参照先 check_path_syntax_internal().
参照元 parse_dfs_path()・srvstr_get_path()・srvstr_get_path_wcard().
00203 { 00204 BOOL ignore; 00205 return check_path_syntax_internal(destname, srcname, True, &ignore); 00206 }
size_t srvstr_get_path_wcard | ( | char * | inbuf, | |
char * | dest, | |||
const char * | src, | |||
size_t | dest_len, | |||
size_t | src_len, | |||
int | flags, | |||
NTSTATUS * | err, | |||
BOOL * | contains_wcard | |||
) |
参照先 check_path_syntax_posix()・check_path_syntax_wcard()・err.
参照元 call_nt_transact_rename()・call_trans2findfirst()・call_trans2findnext()・reply_copy()・reply_fclose()・reply_mv()・reply_ntrename()・reply_search()・reply_unlink()・smb_file_rename_information().
00214 { 00215 pstring tmppath; 00216 char *tmppath_ptr = tmppath; 00217 size_t ret; 00218 #ifdef DEVELOPER 00219 SMB_ASSERT(dest_len == sizeof(pstring)); 00220 #endif 00221 00222 if (src_len == 0) { 00223 ret = srvstr_pull_buf( inbuf, tmppath_ptr, src, dest_len, flags); 00224 } else { 00225 ret = srvstr_pull( inbuf, tmppath_ptr, src, dest_len, src_len, flags); 00226 } 00227 00228 *contains_wcard = False; 00229 00230 if (SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) { 00231 /* 00232 * For a DFS path the function parse_dfs_path() 00233 * will do the path processing, just make a copy. 00234 */ 00235 pstrcpy(dest, tmppath); 00236 *err = NT_STATUS_OK; 00237 return ret; 00238 } 00239 00240 if (lp_posix_pathnames()) { 00241 *err = check_path_syntax_posix(dest, tmppath); 00242 } else { 00243 *err = check_path_syntax_wcard(dest, tmppath, contains_wcard); 00244 } 00245 00246 return ret; 00247 }
size_t srvstr_get_path | ( | char * | inbuf, | |
char * | dest, | |||
const char * | src, | |||
size_t | dest_len, | |||
size_t | src_len, | |||
int | flags, | |||
NTSTATUS * | err | |||
) |
参照先 check_path_syntax()・check_path_syntax_posix()・err.
参照元 call_nt_transact_create()・call_trans2mkdir()・call_trans2open()・call_trans2qfilepathinfo()・call_trans2setfilepathinfo()・do_nt_transact_create_pipe()・reply_checkpath()・reply_ctemp()・reply_getatr()・reply_mkdir()・reply_mknew()・reply_ntcreate_and_X()・reply_open()・reply_open_and_X()・reply_rmdir()・reply_setatr()・reply_setdir()・smb_set_file_unix_hlink().
00254 { 00255 pstring tmppath; 00256 char *tmppath_ptr = tmppath; 00257 size_t ret; 00258 #ifdef DEVELOPER 00259 SMB_ASSERT(dest_len == sizeof(pstring)); 00260 #endif 00261 00262 if (src_len == 0) { 00263 ret = srvstr_pull_buf( inbuf, tmppath_ptr, src, dest_len, flags); 00264 } else { 00265 ret = srvstr_pull( inbuf, tmppath_ptr, src, dest_len, src_len, flags); 00266 } 00267 00268 if (SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) { 00269 /* 00270 * For a DFS path the function parse_dfs_path() 00271 * will do the path processing, just make a copy. 00272 */ 00273 pstrcpy(dest, tmppath); 00274 *err = NT_STATUS_OK; 00275 return ret; 00276 } 00277 00278 if (lp_posix_pathnames()) { 00279 *err = check_path_syntax_posix(dest, tmppath); 00280 } else { 00281 *err = check_path_syntax(dest, tmppath); 00282 } 00283 00284 return ret; 00285 }
int reply_special | ( | char * | inbuf, | |
char * | outbuf | |||
) |
参照先 add_session_user()・exit_server_cleanly()・get_local_machine_name()・get_remote_machine_name()・name_extract()・name_len()・name_type・reload_services()・reopen_logs()・SEC_SHARE・set_local_machine_name()・set_remote_machine_name()・smb_setlen().
参照元 construct_reply().
00292 { 00293 int outsize = 4; 00294 int msg_type = CVAL(inbuf,0); 00295 int msg_flags = CVAL(inbuf,1); 00296 fstring name1,name2; 00297 char name_type = 0; 00298 00299 static BOOL already_got_session = False; 00300 00301 *name1 = *name2 = 0; 00302 00303 memset(outbuf,'\0',smb_size); 00304 00305 smb_setlen(outbuf,0); 00306 00307 switch (msg_type) { 00308 case 0x81: /* session request */ 00309 00310 if (already_got_session) { 00311 exit_server_cleanly("multiple session request not permitted"); 00312 } 00313 00314 SCVAL(outbuf,0,0x82); 00315 SCVAL(outbuf,3,0); 00316 if (name_len(inbuf+4) > 50 || 00317 name_len(inbuf+4 + name_len(inbuf + 4)) > 50) { 00318 DEBUG(0,("Invalid name length in session request\n")); 00319 return(0); 00320 } 00321 name_extract(inbuf,4,name1); 00322 name_type = name_extract(inbuf,4 + name_len(inbuf + 4),name2); 00323 DEBUG(2,("netbios connect: name1=%s name2=%s\n", 00324 name1,name2)); 00325 00326 set_local_machine_name(name1, True); 00327 set_remote_machine_name(name2, True); 00328 00329 DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n", 00330 get_local_machine_name(), get_remote_machine_name(), 00331 name_type)); 00332 00333 if (name_type == 'R') { 00334 /* We are being asked for a pathworks session --- 00335 no thanks! */ 00336 SCVAL(outbuf, 0,0x83); 00337 break; 00338 } 00339 00340 /* only add the client's machine name to the list 00341 of possibly valid usernames if we are operating 00342 in share mode security */ 00343 if (lp_security() == SEC_SHARE) { 00344 add_session_user(get_remote_machine_name()); 00345 } 00346 00347 reload_services(True); 00348 reopen_logs(); 00349 00350 already_got_session = True; 00351 break; 00352 00353 case 0x89: /* session keepalive request 00354 (some old clients produce this?) */ 00355 SCVAL(outbuf,0,SMBkeepalive); 00356 SCVAL(outbuf,3,0); 00357 break; 00358 00359 case 0x82: /* positive session response */ 00360 case 0x83: /* negative session response */ 00361 case 0x84: /* retarget session response */ 00362 DEBUG(0,("Unexpected session response\n")); 00363 break; 00364 00365 case SMBkeepalive: /* session keepalive */ 00366 default: 00367 return(0); 00368 } 00369 00370 DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n", 00371 msg_type, msg_flags)); 00372 00373 return(outsize); 00374 }
int reply_tcon | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 connection_struct::cnum・current_user::conn・data_blob()・data_blob_clear_free()・dev・make_connection()・max_recv・password・set_message()・strrchr_m()・current_user::vuid.
00383 { 00384 const char *service; 00385 pstring service_buf; 00386 pstring password; 00387 pstring dev; 00388 int outsize = 0; 00389 uint16 vuid = SVAL(inbuf,smb_uid); 00390 int pwlen=0; 00391 NTSTATUS nt_status; 00392 char *p; 00393 DATA_BLOB password_blob; 00394 00395 START_PROFILE(SMBtcon); 00396 00397 *service_buf = *password = *dev = 0; 00398 00399 p = smb_buf(inbuf)+1; 00400 p += srvstr_pull_buf(inbuf, service_buf, p, sizeof(service_buf), STR_TERMINATE) + 1; 00401 pwlen = srvstr_pull_buf(inbuf, password, p, sizeof(password), STR_TERMINATE) + 1; 00402 p += pwlen; 00403 p += srvstr_pull_buf(inbuf, dev, p, sizeof(dev), STR_TERMINATE) + 1; 00404 00405 p = strrchr_m(service_buf,'\\'); 00406 if (p) { 00407 service = p+1; 00408 } else { 00409 service = service_buf; 00410 } 00411 00412 password_blob = data_blob(password, pwlen+1); 00413 00414 conn = make_connection(service,password_blob,dev,vuid,&nt_status); 00415 00416 data_blob_clear_free(&password_blob); 00417 00418 if (!conn) { 00419 END_PROFILE(SMBtcon); 00420 return ERROR_NT(nt_status); 00421 } 00422 00423 outsize = set_message(outbuf,2,0,True); 00424 SSVAL(outbuf,smb_vwv0,max_recv); 00425 SSVAL(outbuf,smb_vwv1,conn->cnum); 00426 SSVAL(outbuf,smb_tid,conn->cnum); 00427 00428 DEBUG(3,("tcon service=%s cnum=%d\n", 00429 service, conn->cnum)); 00430 00431 END_PROFILE(SMBtcon); 00432 return(outsize); 00433 }
int reply_tcon_and_X | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize | |||
) |
参照先 chain_reply()・close_cnum()・connection_struct::cnum・current_user::conn・data_blob()・data_blob_clear_free()・global_encrypted_passwords_negotiated・make_connection()・password・perm1・perm2・Protocol・PROTOCOL_NT1・SEC_SHARE・set_message()・set_message_end()・strchr_m()・current_user::vuid.
00441 { 00442 fstring service; 00443 DATA_BLOB password; 00444 00445 /* what the cleint thinks the device is */ 00446 fstring client_devicetype; 00447 /* what the server tells the client the share represents */ 00448 const char *server_devicetype; 00449 NTSTATUS nt_status; 00450 uint16 vuid = SVAL(inbuf,smb_uid); 00451 int passlen = SVAL(inbuf,smb_vwv3); 00452 pstring path; 00453 char *p, *q; 00454 uint16 tcon_flags = SVAL(inbuf,smb_vwv2); 00455 00456 START_PROFILE(SMBtconX); 00457 00458 *service = *client_devicetype = 0; 00459 00460 /* we might have to close an old one */ 00461 if ((SVAL(inbuf,smb_vwv2) & 0x1) && conn) { 00462 close_cnum(conn,vuid); 00463 } 00464 00465 if (passlen > MAX_PASS_LEN) { 00466 return ERROR_DOS(ERRDOS,ERRbuftoosmall); 00467 } 00468 00469 if (global_encrypted_passwords_negotiated) { 00470 password = data_blob(smb_buf(inbuf),passlen); 00471 if (lp_security() == SEC_SHARE) { 00472 /* 00473 * Security = share always has a pad byte 00474 * after the password. 00475 */ 00476 p = smb_buf(inbuf) + passlen + 1; 00477 } else { 00478 p = smb_buf(inbuf) + passlen; 00479 } 00480 } else { 00481 password = data_blob(smb_buf(inbuf),passlen+1); 00482 /* Ensure correct termination */ 00483 password.data[passlen]=0; 00484 p = smb_buf(inbuf) + passlen + 1; 00485 } 00486 00487 p += srvstr_pull_buf(inbuf, path, p, sizeof(path), STR_TERMINATE); 00488 00489 /* 00490 * the service name can be either: \\server\share 00491 * or share directly like on the DELL PowerVault 705 00492 */ 00493 if (*path=='\\') { 00494 q = strchr_m(path+2,'\\'); 00495 if (!q) { 00496 END_PROFILE(SMBtconX); 00497 return(ERROR_DOS(ERRDOS,ERRnosuchshare)); 00498 } 00499 fstrcpy(service,q+1); 00500 } 00501 else 00502 fstrcpy(service,path); 00503 00504 p += srvstr_pull(inbuf, client_devicetype, p, sizeof(client_devicetype), 6, STR_ASCII); 00505 00506 DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service)); 00507 00508 conn = make_connection(service,password,client_devicetype,vuid,&nt_status); 00509 00510 data_blob_clear_free(&password); 00511 00512 if (!conn) { 00513 END_PROFILE(SMBtconX); 00514 return ERROR_NT(nt_status); 00515 } 00516 00517 if ( IS_IPC(conn) ) 00518 server_devicetype = "IPC"; 00519 else if ( IS_PRINT(conn) ) 00520 server_devicetype = "LPT1:"; 00521 else 00522 server_devicetype = "A:"; 00523 00524 if (Protocol < PROTOCOL_NT1) { 00525 set_message(outbuf,2,0,True); 00526 p = smb_buf(outbuf); 00527 p += srvstr_push(outbuf, p, server_devicetype, BUFFER_SIZE - (p - outbuf), 00528 STR_TERMINATE|STR_ASCII); 00529 set_message_end(outbuf,p); 00530 } else { 00531 /* NT sets the fstype of IPC$ to the null string */ 00532 const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn)); 00533 00534 if (tcon_flags & TCONX_FLAG_EXTENDED_RESPONSE) { 00535 /* Return permissions. */ 00536 uint32 perm1 = 0; 00537 uint32 perm2 = 0; 00538 00539 set_message(outbuf,7,0,True); 00540 00541 if (IS_IPC(conn)) { 00542 perm1 = FILE_ALL_ACCESS; 00543 perm2 = FILE_ALL_ACCESS; 00544 } else { 00545 perm1 = CAN_WRITE(conn) ? 00546 SHARE_ALL_ACCESS : 00547 SHARE_READ_ONLY; 00548 } 00549 00550 SIVAL(outbuf, smb_vwv3, perm1); 00551 SIVAL(outbuf, smb_vwv5, perm2); 00552 } else { 00553 set_message(outbuf,3,0,True); 00554 } 00555 00556 p = smb_buf(outbuf); 00557 p += srvstr_push(outbuf, p, server_devicetype, BUFFER_SIZE - (p - outbuf), 00558 STR_TERMINATE|STR_ASCII); 00559 p += srvstr_push(outbuf, p, fstype, BUFFER_SIZE - (p - outbuf), 00560 STR_TERMINATE); 00561 00562 set_message_end(outbuf,p); 00563 00564 /* what does setting this bit do? It is set by NT4 and 00565 may affect the ability to autorun mounted cdroms */ 00566 SSVAL(outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS| 00567 (lp_csc_policy(SNUM(conn)) << 2)); 00568 00569 init_dfsroot(conn, inbuf, outbuf); 00570 } 00571 00572 00573 DEBUG(3,("tconX service=%s \n", 00574 service)); 00575 00576 /* set the incoming and outgoing tid to the just created one */ 00577 SSVAL(inbuf,smb_tid,conn->cnum); 00578 SSVAL(outbuf,smb_tid,conn->cnum); 00579 00580 END_PROFILE(SMBtconX); 00581 return chain_reply(inbuf,outbuf,length,bufsize); 00582 }
int reply_unknown | ( | char * | inbuf, | |
char * | outbuf | |||
) |
参照先 smb_fn_name()・type.
参照元 reply_fclose()・reply_search()・switch_message().
00589 { 00590 int type; 00591 type = CVAL(inbuf,smb_com); 00592 00593 DEBUG(0,("unknown command type (%s): type=%d (0x%X)\n", 00594 smb_fn_name(type), type, type)); 00595 00596 return(ERROR_DOS(ERRSRV,ERRunknownsmb)); 00597 }
int reply_ioctl | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 current_user::conn・file_fsp()・global_myname・files_struct::rap_print_jobid・set_message().
00606 { 00607 uint16 device = SVAL(inbuf,smb_vwv1); 00608 uint16 function = SVAL(inbuf,smb_vwv2); 00609 uint32 ioctl_code = (device << 16) + function; 00610 int replysize, outsize; 00611 char *p; 00612 START_PROFILE(SMBioctl); 00613 00614 DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code)); 00615 00616 switch (ioctl_code) { 00617 case IOCTL_QUERY_JOB_INFO: 00618 replysize = 32; 00619 break; 00620 default: 00621 END_PROFILE(SMBioctl); 00622 return(ERROR_DOS(ERRSRV,ERRnosupport)); 00623 } 00624 00625 outsize = set_message(outbuf,8,replysize+1,True); 00626 SSVAL(outbuf,smb_vwv1,replysize); /* Total data bytes returned */ 00627 SSVAL(outbuf,smb_vwv5,replysize); /* Data bytes this buffer */ 00628 SSVAL(outbuf,smb_vwv6,52); /* Offset to data */ 00629 p = smb_buf(outbuf) + 1; /* Allow for alignment */ 00630 00631 switch (ioctl_code) { 00632 case IOCTL_QUERY_JOB_INFO: 00633 { 00634 files_struct *fsp = file_fsp(inbuf,smb_vwv0); 00635 if (!fsp) { 00636 END_PROFILE(SMBioctl); 00637 return(UNIXERROR(ERRDOS,ERRbadfid)); 00638 } 00639 SSVAL(p,0,fsp->rap_print_jobid); /* Job number */ 00640 srvstr_push(outbuf, p+2, global_myname(), 15, STR_TERMINATE|STR_ASCII); 00641 if (conn) { 00642 srvstr_push(outbuf, p+18, lp_servicename(SNUM(conn)), 13, STR_TERMINATE|STR_ASCII); 00643 } 00644 break; 00645 } 00646 } 00647 00648 END_PROFILE(SMBioctl); 00649 return outsize; 00650 }
参照先 status.
参照元 reply_checkpath().
00657 { 00658 /* Strange DOS error code semantics only for checkpath... */ 00659 if (!(SVAL(inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)) { 00660 if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_INVALID,status)) { 00661 /* We need to map to ERRbadpath */ 00662 return NT_STATUS_OBJECT_PATH_NOT_FOUND; 00663 } 00664 } 00665 return status; 00666 }
int reply_checkpath | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 check_name()・current_user::conn・errno・map_checkpath_error()・map_nt_error_from_unix()・name・nt_errstr()・resolve_dfspath()・set_message()・srvstr_get_path()・status・strerror()・unix_convert().
00673 { 00674 int outsize = 0; 00675 pstring name; 00676 SMB_STRUCT_STAT sbuf; 00677 NTSTATUS status; 00678 00679 START_PROFILE(SMBcheckpath); 00680 00681 srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status); 00682 if (!NT_STATUS_IS_OK(status)) { 00683 END_PROFILE(SMBcheckpath); 00684 status = map_checkpath_error(inbuf, status); 00685 return ERROR_NT(status); 00686 } 00687 00688 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, name); 00689 if (!NT_STATUS_IS_OK(status)) { 00690 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 00691 END_PROFILE(SMBcheckpath); 00692 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 00693 } 00694 goto path_err; 00695 } 00696 00697 DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(inbuf,smb_vwv0))); 00698 00699 status = unix_convert(conn, name, False, NULL, &sbuf); 00700 if (!NT_STATUS_IS_OK(status)) { 00701 goto path_err; 00702 } 00703 00704 status = check_name(conn, name); 00705 if (!NT_STATUS_IS_OK(status)) { 00706 DEBUG(3,("reply_checkpath: check_name of %s failed (%s)\n",name,nt_errstr(status))); 00707 goto path_err; 00708 } 00709 00710 if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,name,&sbuf) != 0)) { 00711 DEBUG(3,("reply_checkpath: stat of %s failed (%s)\n",name,strerror(errno))); 00712 status = map_nt_error_from_unix(errno); 00713 goto path_err; 00714 } 00715 00716 if (!S_ISDIR(sbuf.st_mode)) { 00717 END_PROFILE(SMBcheckpath); 00718 return ERROR_BOTH(NT_STATUS_NOT_A_DIRECTORY,ERRDOS,ERRbadpath); 00719 } 00720 00721 outsize = set_message(outbuf,0,0,False); 00722 00723 END_PROFILE(SMBcheckpath); 00724 return outsize; 00725 00726 path_err: 00727 00728 END_PROFILE(SMBcheckpath); 00729 00730 /* We special case this - as when a Windows machine 00731 is parsing a path is steps through the components 00732 one at a time - if a component fails it expects 00733 ERRbadpath, not ERRbadfile. 00734 */ 00735 status = map_checkpath_error(inbuf, status); 00736 if(NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { 00737 /* 00738 * Windows returns different error codes if 00739 * the parent directory is valid but not the 00740 * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND 00741 * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND 00742 * if the path is invalid. 00743 */ 00744 return ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpath); 00745 } 00746 00747 return ERROR_NT(status); 00748 }
int reply_getatr | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 check_name()・current_user::conn・errno・mode・nt_errstr()・Protocol・PROTOCOL_NT1・resolve_dfspath()・set_message()・size・srv_put_dos_date3()・srvstr_get_path()・status・strerror()・unix_convert().
00755 { 00756 pstring fname; 00757 int outsize = 0; 00758 SMB_STRUCT_STAT sbuf; 00759 int mode=0; 00760 SMB_OFF_T size=0; 00761 time_t mtime=0; 00762 char *p; 00763 NTSTATUS status; 00764 00765 START_PROFILE(SMBgetatr); 00766 00767 p = smb_buf(inbuf) + 1; 00768 p += srvstr_get_path(inbuf, fname, p, sizeof(fname), 0, STR_TERMINATE, &status); 00769 if (!NT_STATUS_IS_OK(status)) { 00770 END_PROFILE(SMBgetatr); 00771 return ERROR_NT(status); 00772 } 00773 00774 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname); 00775 if (!NT_STATUS_IS_OK(status)) { 00776 END_PROFILE(SMBgetatr); 00777 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 00778 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 00779 } 00780 return ERROR_NT(status); 00781 } 00782 00783 /* dos smetimes asks for a stat of "" - it returns a "hidden directory" 00784 under WfWg - weird! */ 00785 if (*fname == '\0') { 00786 mode = aHIDDEN | aDIR; 00787 if (!CAN_WRITE(conn)) { 00788 mode |= aRONLY; 00789 } 00790 size = 0; 00791 mtime = 0; 00792 } else { 00793 status = unix_convert(conn, fname, False, NULL,&sbuf); 00794 if (!NT_STATUS_IS_OK(status)) { 00795 END_PROFILE(SMBgetatr); 00796 return ERROR_NT(status); 00797 } 00798 status = check_name(conn, fname); 00799 if (!NT_STATUS_IS_OK(status)) { 00800 DEBUG(3,("reply_getatr: check_name of %s failed (%s)\n",fname,nt_errstr(status))); 00801 END_PROFILE(SMBgetatr); 00802 return ERROR_NT(status); 00803 } 00804 if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,fname,&sbuf) != 0)) { 00805 DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",fname,strerror(errno))); 00806 return UNIXERROR(ERRDOS,ERRbadfile); 00807 } 00808 00809 mode = dos_mode(conn,fname,&sbuf); 00810 size = sbuf.st_size; 00811 mtime = sbuf.st_mtime; 00812 if (mode & aDIR) { 00813 size = 0; 00814 } 00815 } 00816 00817 outsize = set_message(outbuf,10,0,True); 00818 00819 SSVAL(outbuf,smb_vwv0,mode); 00820 if(lp_dos_filetime_resolution(SNUM(conn)) ) { 00821 srv_put_dos_date3(outbuf,smb_vwv1,mtime & ~1); 00822 } else { 00823 srv_put_dos_date3(outbuf,smb_vwv1,mtime); 00824 } 00825 SIVAL(outbuf,smb_vwv3,(uint32)size); 00826 00827 if (Protocol >= PROTOCOL_NT1) { 00828 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME); 00829 } 00830 00831 DEBUG(3,("reply_getatr: name=%s mode=%d size=%u\n", fname, mode, (unsigned int)size ) ); 00832 00833 END_PROFILE(SMBgetatr); 00834 return(outsize); 00835 }
int reply_setatr | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 check_name()・current_user::conn・convert_time_t_to_timespec()・mode・resolve_dfspath()・set_message()・srv_make_unix_date3()・srvstr_get_path()・status・unix_convert().
00842 { 00843 pstring fname; 00844 int outsize = 0; 00845 int mode; 00846 time_t mtime; 00847 SMB_STRUCT_STAT sbuf; 00848 char *p; 00849 NTSTATUS status; 00850 00851 START_PROFILE(SMBsetatr); 00852 00853 p = smb_buf(inbuf) + 1; 00854 p += srvstr_get_path(inbuf, fname, p, sizeof(fname), 0, STR_TERMINATE, &status); 00855 if (!NT_STATUS_IS_OK(status)) { 00856 END_PROFILE(SMBsetatr); 00857 return ERROR_NT(status); 00858 } 00859 00860 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname); 00861 if (!NT_STATUS_IS_OK(status)) { 00862 END_PROFILE(SMBsetatr); 00863 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 00864 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 00865 } 00866 return ERROR_NT(status); 00867 } 00868 00869 status = unix_convert(conn, fname, False, NULL, &sbuf); 00870 if (!NT_STATUS_IS_OK(status)) { 00871 END_PROFILE(SMBsetatr); 00872 return ERROR_NT(status); 00873 } 00874 00875 status = check_name(conn, fname); 00876 if (!NT_STATUS_IS_OK(status)) { 00877 END_PROFILE(SMBsetatr); 00878 return ERROR_NT(status); 00879 } 00880 00881 if (fname[0] == '.' && fname[1] == '\0') { 00882 /* 00883 * Not sure here is the right place to catch this 00884 * condition. Might be moved to somewhere else later -- vl 00885 */ 00886 END_PROFILE(SMBsetatr); 00887 return ERROR_NT(NT_STATUS_ACCESS_DENIED); 00888 } 00889 00890 mode = SVAL(inbuf,smb_vwv0); 00891 mtime = srv_make_unix_date3(inbuf+smb_vwv1); 00892 00893 if (mode != FILE_ATTRIBUTE_NORMAL) { 00894 if (VALID_STAT_OF_DIR(sbuf)) 00895 mode |= aDIR; 00896 else 00897 mode &= ~aDIR; 00898 00899 if (file_set_dosmode(conn,fname,mode,&sbuf,False) != 0) { 00900 END_PROFILE(SMBsetatr); 00901 return UNIXERROR(ERRDOS, ERRnoaccess); 00902 } 00903 } 00904 00905 if (!set_filetime(conn,fname,convert_time_t_to_timespec(mtime))) { 00906 END_PROFILE(SMBsetatr); 00907 return UNIXERROR(ERRDOS, ERRnoaccess); 00908 } 00909 00910 outsize = set_message(outbuf,0,0,False); 00911 00912 DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) ); 00913 00914 END_PROFILE(SMBsetatr); 00915 return(outsize); 00916 }
int reply_dskattr | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 current_user::conn・get_dfree_info()・Protocol・PROTOCOL_LANMAN2・set_message().
00923 { 00924 int outsize = 0; 00925 SMB_BIG_UINT dfree,dsize,bsize; 00926 START_PROFILE(SMBdskattr); 00927 00928 if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) { 00929 END_PROFILE(SMBdskattr); 00930 return(UNIXERROR(ERRHRD,ERRgeneral)); 00931 } 00932 00933 outsize = set_message(outbuf,5,0,True); 00934 00935 if (Protocol <= PROTOCOL_LANMAN2) { 00936 double total_space, free_space; 00937 /* we need to scale this to a number that DOS6 can handle. We 00938 use floating point so we can handle large drives on systems 00939 that don't have 64 bit integers 00940 00941 we end up displaying a maximum of 2G to DOS systems 00942 */ 00943 total_space = dsize * (double)bsize; 00944 free_space = dfree * (double)bsize; 00945 00946 dsize = (total_space+63*512) / (64*512); 00947 dfree = (free_space+63*512) / (64*512); 00948 00949 if (dsize > 0xFFFF) dsize = 0xFFFF; 00950 if (dfree > 0xFFFF) dfree = 0xFFFF; 00951 00952 SSVAL(outbuf,smb_vwv0,dsize); 00953 SSVAL(outbuf,smb_vwv1,64); /* this must be 64 for dos systems */ 00954 SSVAL(outbuf,smb_vwv2,512); /* and this must be 512 */ 00955 SSVAL(outbuf,smb_vwv3,dfree); 00956 } else { 00957 SSVAL(outbuf,smb_vwv0,dsize); 00958 SSVAL(outbuf,smb_vwv1,bsize/512); 00959 SSVAL(outbuf,smb_vwv2,512); 00960 SSVAL(outbuf,smb_vwv3,dfree); 00961 } 00962 00963 DEBUG(3,("dskattr dfree=%d\n", (unsigned int)dfree)); 00964 00965 END_PROFILE(SMBdskattr); 00966 return(outsize); 00967 }
int reply_search | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 check_name()・current_user::conn・connection_struct::dirpath・connection_struct::dirptr・dptr_attr()・dptr_close()・dptr_create()・dptr_dnum()・dptr_fetch()・dptr_fill()・dptr_path()・dptr_wcard()・get_dir_entry()・in_list()・make_dir_struct()・mode・ms_has_wild()・reply_unknown()・resolve_dfspath_wcard()・set_message()・size・smb_fn_name()・smb_setlen()・srvstr_get_path_wcard()・status・string_set()・strrchr_m()・unix_convert().
00975 { 00976 pstring mask; 00977 pstring directory; 00978 pstring fname; 00979 SMB_OFF_T size; 00980 uint32 mode; 00981 time_t date; 00982 uint32 dirtype; 00983 int outsize = 0; 00984 unsigned int numentries = 0; 00985 unsigned int maxentries = 0; 00986 BOOL finished = False; 00987 char *p; 00988 int status_len; 00989 pstring path; 00990 char status[21]; 00991 int dptr_num= -1; 00992 BOOL check_descend = False; 00993 BOOL expect_close = False; 00994 NTSTATUS nt_status; 00995 BOOL mask_contains_wcard = False; 00996 BOOL allow_long_path_components = (SVAL(inbuf,smb_flg2) & FLAGS2_LONG_PATH_COMPONENTS) ? True : False; 00997 00998 START_PROFILE(SMBsearch); 00999 01000 if (lp_posix_pathnames()) { 01001 END_PROFILE(SMBsearch); 01002 return reply_unknown(inbuf, outbuf); 01003 } 01004 01005 *mask = *directory = *fname = 0; 01006 01007 /* If we were called as SMBffirst then we must expect close. */ 01008 if(CVAL(inbuf,smb_com) == SMBffirst) { 01009 expect_close = True; 01010 } 01011 01012 outsize = set_message(outbuf,1,3,True); 01013 maxentries = SVAL(inbuf,smb_vwv0); 01014 dirtype = SVAL(inbuf,smb_vwv1); 01015 p = smb_buf(inbuf) + 1; 01016 p += srvstr_get_path_wcard(inbuf, path, p, sizeof(path), 0, STR_TERMINATE, &nt_status, &mask_contains_wcard); 01017 if (!NT_STATUS_IS_OK(nt_status)) { 01018 END_PROFILE(SMBsearch); 01019 return ERROR_NT(nt_status); 01020 } 01021 01022 nt_status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, path, &mask_contains_wcard); 01023 if (!NT_STATUS_IS_OK(nt_status)) { 01024 END_PROFILE(SMBsearch); 01025 if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) { 01026 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 01027 } 01028 return ERROR_NT(nt_status); 01029 } 01030 01031 p++; 01032 status_len = SVAL(p, 0); 01033 p += 2; 01034 01035 /* dirtype &= ~aDIR; */ 01036 01037 if (status_len == 0) { 01038 SMB_STRUCT_STAT sbuf; 01039 01040 pstrcpy(directory,path); 01041 nt_status = unix_convert(conn, directory, True, NULL, &sbuf); 01042 if (!NT_STATUS_IS_OK(nt_status)) { 01043 END_PROFILE(SMBsearch); 01044 return ERROR_NT(nt_status); 01045 } 01046 01047 nt_status = check_name(conn, directory); 01048 if (!NT_STATUS_IS_OK(nt_status)) { 01049 END_PROFILE(SMBsearch); 01050 return ERROR_NT(nt_status); 01051 } 01052 01053 p = strrchr_m(directory,'/'); 01054 if (!p) { 01055 pstrcpy(mask,directory); 01056 pstrcpy(directory,"."); 01057 } else { 01058 *p = 0; 01059 pstrcpy(mask,p+1); 01060 } 01061 01062 if (*directory == '\0') { 01063 pstrcpy(directory,"."); 01064 } 01065 memset((char *)status,'\0',21); 01066 SCVAL(status,0,(dirtype & 0x1F)); 01067 } else { 01068 int status_dirtype; 01069 01070 memcpy(status,p,21); 01071 status_dirtype = CVAL(status,0) & 0x1F; 01072 if (status_dirtype != (dirtype & 0x1F)) { 01073 dirtype = status_dirtype; 01074 } 01075 01076 conn->dirptr = dptr_fetch(status+12,&dptr_num); 01077 if (!conn->dirptr) { 01078 goto SearchEmpty; 01079 } 01080 string_set(&conn->dirpath,dptr_path(dptr_num)); 01081 pstrcpy(mask, dptr_wcard(dptr_num)); 01082 /* 01083 * For a 'continue' search we have no string. So 01084 * check from the initial saved string. 01085 */ 01086 mask_contains_wcard = ms_has_wild(mask); 01087 } 01088 01089 p = smb_buf(outbuf) + 3; 01090 01091 if (status_len == 0) { 01092 nt_status = dptr_create(conn, 01093 directory, 01094 True, 01095 expect_close, 01096 SVAL(inbuf,smb_pid), 01097 mask, 01098 mask_contains_wcard, 01099 dirtype, 01100 &conn->dirptr); 01101 if (!NT_STATUS_IS_OK(nt_status)) { 01102 return ERROR_NT(nt_status); 01103 } 01104 dptr_num = dptr_dnum(conn->dirptr); 01105 } else { 01106 dirtype = dptr_attr(dptr_num); 01107 } 01108 01109 DEBUG(4,("dptr_num is %d\n",dptr_num)); 01110 01111 if ((dirtype&0x1F) == aVOLID) { 01112 memcpy(p,status,21); 01113 make_dir_struct(p,"???????????",volume_label(SNUM(conn)), 01114 0,aVOLID,0,!allow_long_path_components); 01115 dptr_fill(p+12,dptr_num); 01116 if (dptr_zero(p+12) && (status_len==0)) { 01117 numentries = 1; 01118 } else { 01119 numentries = 0; 01120 } 01121 p += DIR_STRUCT_SIZE; 01122 } else { 01123 unsigned int i; 01124 maxentries = MIN(maxentries, ((BUFFER_SIZE - (p - outbuf))/DIR_STRUCT_SIZE)); 01125 01126 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", 01127 conn->dirpath,lp_dontdescend(SNUM(conn)))); 01128 if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True)) { 01129 check_descend = True; 01130 } 01131 01132 for (i=numentries;(i<maxentries) && !finished;i++) { 01133 finished = !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend); 01134 if (!finished) { 01135 memcpy(p,status,21); 01136 make_dir_struct(p,mask,fname,size, mode,date, 01137 !allow_long_path_components); 01138 if (!dptr_fill(p+12,dptr_num)) { 01139 break; 01140 } 01141 numentries++; 01142 p += DIR_STRUCT_SIZE; 01143 } 01144 } 01145 } 01146 01147 SearchEmpty: 01148 01149 /* If we were called as SMBffirst with smb_search_id == NULL 01150 and no entries were found then return error and close dirptr 01151 (X/Open spec) */ 01152 01153 if (numentries == 0) { 01154 dptr_close(&dptr_num); 01155 } else if(expect_close && status_len == 0) { 01156 /* Close the dptr - we know it's gone */ 01157 dptr_close(&dptr_num); 01158 } 01159 01160 /* If we were called as SMBfunique, then we can close the dirptr now ! */ 01161 if(dptr_num >= 0 && CVAL(inbuf,smb_com) == SMBfunique) { 01162 dptr_close(&dptr_num); 01163 } 01164 01165 if ((numentries == 0) && !mask_contains_wcard) { 01166 return ERROR_BOTH(STATUS_NO_MORE_FILES,ERRDOS,ERRnofiles); 01167 } 01168 01169 SSVAL(outbuf,smb_vwv0,numentries); 01170 SSVAL(outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE); 01171 SCVAL(smb_buf(outbuf),0,5); 01172 SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE); 01173 01174 /* The replies here are never long name. */ 01175 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) & (~FLAGS2_IS_LONG_NAME)); 01176 if (!allow_long_path_components) { 01177 SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) & (~FLAGS2_LONG_PATH_COMPONENTS)); 01178 } 01179 01180 /* This SMB *always* returns ASCII names. Remove the unicode bit in flags2. */ 01181 SSVAL(outbuf,smb_flg2, (SVAL(outbuf, smb_flg2) & (~FLAGS2_UNICODE_STRINGS))); 01182 01183 outsize += DIR_STRUCT_SIZE*numentries; 01184 smb_setlen(outbuf,outsize - 4); 01185 01186 if ((! *directory) && dptr_path(dptr_num)) 01187 slprintf(directory, sizeof(directory)-1, "(%s)",dptr_path(dptr_num)); 01188 01189 DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%u of %u\n", 01190 smb_fn_name(CVAL(inbuf,smb_com)), 01191 mask, directory, dirtype, numentries, maxentries ) ); 01192 01193 END_PROFILE(SMBsearch); 01194 return(outsize); 01195 }
int reply_fclose | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 dptr_close()・dptr_fetch()・err・reply_unknown()・set_message()・srvstr_get_path_wcard()・status.
01202 { 01203 int outsize = 0; 01204 int status_len; 01205 pstring path; 01206 char status[21]; 01207 int dptr_num= -2; 01208 char *p; 01209 NTSTATUS err; 01210 BOOL path_contains_wcard = False; 01211 01212 START_PROFILE(SMBfclose); 01213 01214 if (lp_posix_pathnames()) { 01215 END_PROFILE(SMBfclose); 01216 return reply_unknown(inbuf, outbuf); 01217 } 01218 01219 outsize = set_message(outbuf,1,0,True); 01220 p = smb_buf(inbuf) + 1; 01221 p += srvstr_get_path_wcard(inbuf, path, p, sizeof(path), 0, STR_TERMINATE, &err, &path_contains_wcard); 01222 if (!NT_STATUS_IS_OK(err)) { 01223 END_PROFILE(SMBfclose); 01224 return ERROR_NT(err); 01225 } 01226 p++; 01227 status_len = SVAL(p,0); 01228 p += 2; 01229 01230 if (status_len == 0) { 01231 END_PROFILE(SMBfclose); 01232 return ERROR_DOS(ERRSRV,ERRsrverror); 01233 } 01234 01235 memcpy(status,p,21); 01236 01237 if(dptr_fetch(status+12,&dptr_num)) { 01238 /* Close the dptr - we know it's gone */ 01239 dptr_close(&dptr_num); 01240 } 01241 01242 SSVAL(outbuf,smb_vwv0,0); 01243 01244 DEBUG(3,("search close\n")); 01245 01246 END_PROFILE(SMBfclose); 01247 return(outsize); 01248 }
int reply_open | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 check_name()・close_file()・current_user::conn・ERROR_CLOSE・files_struct::fnum・map_open_params_to_ntcreate()・open_file_ntcreate()・open_was_deferred()・files_struct::oplock_type・resolve_dfspath()・set_message()・size・srv_put_dos_date3()・srvstr_get_path()・status・unix_convert().
01255 { 01256 pstring fname; 01257 int outsize = 0; 01258 uint32 fattr=0; 01259 SMB_OFF_T size = 0; 01260 time_t mtime=0; 01261 int info; 01262 SMB_STRUCT_STAT sbuf; 01263 files_struct *fsp; 01264 int oplock_request = CORE_OPLOCK_REQUEST(inbuf); 01265 int deny_mode; 01266 uint32 dos_attr = SVAL(inbuf,smb_vwv1); 01267 uint32 access_mask; 01268 uint32 share_mode; 01269 uint32 create_disposition; 01270 uint32 create_options = 0; 01271 NTSTATUS status; 01272 START_PROFILE(SMBopen); 01273 01274 deny_mode = SVAL(inbuf,smb_vwv0); 01275 01276 srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status); 01277 if (!NT_STATUS_IS_OK(status)) { 01278 END_PROFILE(SMBopen); 01279 return ERROR_NT(status); 01280 } 01281 01282 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname); 01283 if (!NT_STATUS_IS_OK(status)) { 01284 END_PROFILE(SMBopen); 01285 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 01286 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 01287 } 01288 return ERROR_NT(status); 01289 } 01290 01291 status = unix_convert(conn, fname, False, NULL, &sbuf); 01292 if (!NT_STATUS_IS_OK(status)) { 01293 END_PROFILE(SMBopen); 01294 return ERROR_NT(status); 01295 } 01296 01297 status = check_name(conn, fname); 01298 if (!NT_STATUS_IS_OK(status)) { 01299 END_PROFILE(SMBopen); 01300 return ERROR_NT(status); 01301 } 01302 01303 if (!map_open_params_to_ntcreate(fname, deny_mode, OPENX_FILE_EXISTS_OPEN, 01304 &access_mask, &share_mode, &create_disposition, &create_options)) { 01305 END_PROFILE(SMBopen); 01306 return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRbadaccess)); 01307 } 01308 01309 status = open_file_ntcreate(conn,fname,&sbuf, 01310 access_mask, 01311 share_mode, 01312 create_disposition, 01313 create_options, 01314 dos_attr, 01315 oplock_request, 01316 &info, &fsp); 01317 01318 if (!NT_STATUS_IS_OK(status)) { 01319 END_PROFILE(SMBopen); 01320 if (open_was_deferred(SVAL(inbuf,smb_mid))) { 01321 /* We have re-scheduled this call. */ 01322 return -1; 01323 } 01324 return ERROR_OPEN(status); 01325 } 01326 01327 size = sbuf.st_size; 01328 fattr = dos_mode(conn,fname,&sbuf); 01329 mtime = sbuf.st_mtime; 01330 01331 if (fattr & aDIR) { 01332 DEBUG(3,("attempt to open a directory %s\n",fname)); 01333 close_file(fsp,ERROR_CLOSE); 01334 END_PROFILE(SMBopen); 01335 return ERROR_DOS(ERRDOS,ERRnoaccess); 01336 } 01337 01338 outsize = set_message(outbuf,7,0,True); 01339 SSVAL(outbuf,smb_vwv0,fsp->fnum); 01340 SSVAL(outbuf,smb_vwv1,fattr); 01341 if(lp_dos_filetime_resolution(SNUM(conn)) ) { 01342 srv_put_dos_date3(outbuf,smb_vwv2,mtime & ~1); 01343 } else { 01344 srv_put_dos_date3(outbuf,smb_vwv2,mtime); 01345 } 01346 SIVAL(outbuf,smb_vwv4,(uint32)size); 01347 SSVAL(outbuf,smb_vwv6,deny_mode); 01348 01349 if (oplock_request && lp_fake_oplocks(SNUM(conn))) { 01350 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED); 01351 } 01352 01353 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { 01354 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED); 01355 } 01356 END_PROFILE(SMBopen); 01357 return(outsize); 01358 }
int reply_open_and_X | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize | |||
) |
参照先 chain_reply()・check_name()・close_file()・files_struct::conn・current_user::conn・ERROR_CLOSE・files_struct::fnum・get_allocation_size()・files_struct::initial_allocation_size・make_unix_date3()・map_open_params_to_ntcreate()・open_file_ntcreate()・open_was_deferred()・files_struct::oplock_type・reply_open_pipe_and_X()・resolve_dfspath()・set_message()・smb_roundup()・srv_put_dos_date3()・srvstr_get_path()・status・unix_convert()・vfs_allocate_file_space()・vfs_set_filelen().
01365 { 01366 pstring fname; 01367 uint16 open_flags = SVAL(inbuf,smb_vwv2); 01368 int deny_mode = SVAL(inbuf,smb_vwv3); 01369 uint32 smb_attr = SVAL(inbuf,smb_vwv5); 01370 /* Breakout the oplock request bits so we can set the 01371 reply bits separately. */ 01372 int ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf); 01373 int core_oplock_request = CORE_OPLOCK_REQUEST(inbuf); 01374 int oplock_request = ex_oplock_request | core_oplock_request; 01375 #if 0 01376 int smb_sattr = SVAL(inbuf,smb_vwv4); 01377 uint32 smb_time = make_unix_date3(inbuf+smb_vwv6); 01378 #endif 01379 int smb_ofun = SVAL(inbuf,smb_vwv8); 01380 uint32 fattr=0; 01381 int mtime=0; 01382 SMB_STRUCT_STAT sbuf; 01383 int smb_action = 0; 01384 files_struct *fsp; 01385 NTSTATUS status; 01386 SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv9); 01387 ssize_t retval = -1; 01388 uint32 access_mask; 01389 uint32 share_mode; 01390 uint32 create_disposition; 01391 uint32 create_options = 0; 01392 01393 START_PROFILE(SMBopenX); 01394 01395 /* If it's an IPC, pass off the pipe handler. */ 01396 if (IS_IPC(conn)) { 01397 if (lp_nt_pipe_support()) { 01398 END_PROFILE(SMBopenX); 01399 return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize); 01400 } else { 01401 END_PROFILE(SMBopenX); 01402 return ERROR_DOS(ERRSRV,ERRaccess); 01403 } 01404 } 01405 01406 /* XXXX we need to handle passed times, sattr and flags */ 01407 srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status); 01408 if (!NT_STATUS_IS_OK(status)) { 01409 END_PROFILE(SMBopenX); 01410 return ERROR_NT(status); 01411 } 01412 01413 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname); 01414 if (!NT_STATUS_IS_OK(status)) { 01415 END_PROFILE(SMBopenX); 01416 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 01417 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 01418 } 01419 return ERROR_NT(status); 01420 } 01421 01422 status = unix_convert(conn, fname, False, NULL, &sbuf); 01423 if (!NT_STATUS_IS_OK(status)) { 01424 END_PROFILE(SMBopenX); 01425 return ERROR_NT(status); 01426 } 01427 01428 status = check_name(conn, fname); 01429 if (!NT_STATUS_IS_OK(status)) { 01430 END_PROFILE(SMBopenX); 01431 return ERROR_NT(status); 01432 } 01433 01434 if (!map_open_params_to_ntcreate(fname, deny_mode, smb_ofun, 01435 &access_mask, 01436 &share_mode, 01437 &create_disposition, 01438 &create_options)) { 01439 END_PROFILE(SMBopenX); 01440 return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRbadaccess)); 01441 } 01442 01443 status = open_file_ntcreate(conn,fname,&sbuf, 01444 access_mask, 01445 share_mode, 01446 create_disposition, 01447 create_options, 01448 smb_attr, 01449 oplock_request, 01450 &smb_action, &fsp); 01451 01452 if (!NT_STATUS_IS_OK(status)) { 01453 END_PROFILE(SMBopenX); 01454 if (open_was_deferred(SVAL(inbuf,smb_mid))) { 01455 /* We have re-scheduled this call. */ 01456 return -1; 01457 } 01458 return ERROR_OPEN(status); 01459 } 01460 01461 /* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size, 01462 if the file is truncated or created. */ 01463 if (((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) && allocation_size) { 01464 fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size); 01465 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) { 01466 close_file(fsp,ERROR_CLOSE); 01467 END_PROFILE(SMBopenX); 01468 return ERROR_NT(NT_STATUS_DISK_FULL); 01469 } 01470 retval = vfs_set_filelen(fsp, (SMB_OFF_T)allocation_size); 01471 if (retval < 0) { 01472 close_file(fsp,ERROR_CLOSE); 01473 END_PROFILE(SMBopenX); 01474 return ERROR_NT(NT_STATUS_DISK_FULL); 01475 } 01476 sbuf.st_size = get_allocation_size(conn,fsp,&sbuf); 01477 } 01478 01479 fattr = dos_mode(conn,fname,&sbuf); 01480 mtime = sbuf.st_mtime; 01481 if (fattr & aDIR) { 01482 close_file(fsp,ERROR_CLOSE); 01483 END_PROFILE(SMBopenX); 01484 return ERROR_DOS(ERRDOS,ERRnoaccess); 01485 } 01486 01487 /* If the caller set the extended oplock request bit 01488 and we granted one (by whatever means) - set the 01489 correct bit for extended oplock reply. 01490 */ 01491 01492 if (ex_oplock_request && lp_fake_oplocks(SNUM(conn))) { 01493 smb_action |= EXTENDED_OPLOCK_GRANTED; 01494 } 01495 01496 if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { 01497 smb_action |= EXTENDED_OPLOCK_GRANTED; 01498 } 01499 01500 /* If the caller set the core oplock request bit 01501 and we granted one (by whatever means) - set the 01502 correct bit for core oplock reply. 01503 */ 01504 01505 if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) { 01506 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED); 01507 } 01508 01509 if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { 01510 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED); 01511 } 01512 01513 if (open_flags & EXTENDED_RESPONSE_REQUIRED) { 01514 set_message(outbuf,19,0,True); 01515 } else { 01516 set_message(outbuf,15,0,True); 01517 } 01518 SSVAL(outbuf,smb_vwv2,fsp->fnum); 01519 SSVAL(outbuf,smb_vwv3,fattr); 01520 if(lp_dos_filetime_resolution(SNUM(conn)) ) { 01521 srv_put_dos_date3(outbuf,smb_vwv4,mtime & ~1); 01522 } else { 01523 srv_put_dos_date3(outbuf,smb_vwv4,mtime); 01524 } 01525 SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size); 01526 SSVAL(outbuf,smb_vwv8,GET_OPENX_MODE(deny_mode)); 01527 SSVAL(outbuf,smb_vwv11,smb_action); 01528 01529 if (open_flags & EXTENDED_RESPONSE_REQUIRED) { 01530 SIVAL(outbuf, smb_vwv15, STD_RIGHT_ALL_ACCESS); 01531 } 01532 01533 END_PROFILE(SMBopenX); 01534 return chain_reply(inbuf,outbuf,length,bufsize); 01535 }
int reply_ulogoffX | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize | |||
) |
参照先 chain_reply()・file_close_user()・get_valid_user_struct()・invalidate_vuid()・SEC_SHARE・set_message()・current_user::vuid.
01543 { 01544 uint16 vuid = SVAL(inbuf,smb_uid); 01545 user_struct *vuser = get_valid_user_struct(vuid); 01546 START_PROFILE(SMBulogoffX); 01547 01548 if(vuser == 0) 01549 DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid)); 01550 01551 /* in user level security we are supposed to close any files 01552 open by this user */ 01553 if ((vuser != 0) && (lp_security() != SEC_SHARE)) 01554 file_close_user(vuid); 01555 01556 invalidate_vuid(vuid); 01557 01558 set_message(outbuf,2,0,True); 01559 01560 DEBUG( 3, ( "ulogoffX vuid=%d\n", vuid ) ); 01561 01562 END_PROFILE(SMBulogoffX); 01563 return chain_reply(inbuf,outbuf,length,bufsize); 01564 }
int reply_mknew | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 check_name()・convert_time_t_to_timespec()・get_atimespec()・open_file_ntcreate()・open_was_deferred()・resolve_dfspath()・set_message()・srv_make_unix_date3()・srvstr_get_path()・status・unix_convert().
01571 { 01572 pstring fname; 01573 int com; 01574 int outsize = 0; 01575 uint32 fattr = SVAL(inbuf,smb_vwv0); 01576 struct timespec ts[2]; 01577 files_struct *fsp; 01578 int oplock_request = CORE_OPLOCK_REQUEST(inbuf); 01579 SMB_STRUCT_STAT sbuf; 01580 NTSTATUS status; 01581 uint32 access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE; 01582 uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE; 01583 uint32 create_disposition; 01584 uint32 create_options = 0; 01585 01586 START_PROFILE(SMBcreate); 01587 01588 com = SVAL(inbuf,smb_com); 01589 01590 ts[1] = convert_time_t_to_timespec(srv_make_unix_date3(inbuf + smb_vwv1)); /* mtime. */ 01591 01592 srvstr_get_path(inbuf, fname, smb_buf(inbuf) + 1, sizeof(fname), 0, STR_TERMINATE, &status); 01593 if (!NT_STATUS_IS_OK(status)) { 01594 END_PROFILE(SMBcreate); 01595 return ERROR_NT(status); 01596 } 01597 01598 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname); 01599 if (!NT_STATUS_IS_OK(status)) { 01600 END_PROFILE(SMBcreate); 01601 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 01602 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 01603 } 01604 return ERROR_NT(status); 01605 } 01606 01607 status = unix_convert(conn, fname, False, NULL, &sbuf); 01608 if (!NT_STATUS_IS_OK(status)) { 01609 END_PROFILE(SMBcreate); 01610 return ERROR_NT(status); 01611 } 01612 01613 status = check_name(conn, fname); 01614 if (!NT_STATUS_IS_OK(status)) { 01615 END_PROFILE(SMBcreate); 01616 return ERROR_NT(status); 01617 } 01618 01619 if (fattr & aVOLID) { 01620 DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname)); 01621 } 01622 01623 if(com == SMBmknew) { 01624 /* We should fail if file exists. */ 01625 create_disposition = FILE_CREATE; 01626 } else { 01627 /* Create if file doesn't exist, truncate if it does. */ 01628 create_disposition = FILE_OVERWRITE_IF; 01629 } 01630 01631 /* Open file using ntcreate. */ 01632 status = open_file_ntcreate(conn,fname,&sbuf, 01633 access_mask, 01634 share_mode, 01635 create_disposition, 01636 create_options, 01637 fattr, 01638 oplock_request, 01639 NULL, &fsp); 01640 01641 if (!NT_STATUS_IS_OK(status)) { 01642 END_PROFILE(SMBcreate); 01643 if (open_was_deferred(SVAL(inbuf,smb_mid))) { 01644 /* We have re-scheduled this call. */ 01645 return -1; 01646 } 01647 return ERROR_OPEN(status); 01648 } 01649 01650 ts[0] = get_atimespec(&sbuf); /* atime. */ 01651 file_ntimes(conn, fname, ts); 01652 01653 outsize = set_message(outbuf,1,0,True); 01654 SSVAL(outbuf,smb_vwv0,fsp->fnum); 01655 01656 if (oplock_request && lp_fake_oplocks(SNUM(conn))) { 01657 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED); 01658 } 01659 01660 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { 01661 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED); 01662 } 01663 01664 DEBUG( 2, ( "reply_mknew: file %s\n", fname ) ); 01665 DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n", fname, fsp->fh->fd, (unsigned int)fattr ) ); 01666 01667 END_PROFILE(SMBcreate); 01668 return(outsize); 01669 }
int reply_ctemp | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 check_name()・fd_handle::fd・files_struct::fh・files_struct::fnum・open_file_ntcreate()・open_was_deferred()・files_struct::oplock_type・resolve_dfspath()・set_message()・set_message_end()・smb_mkstemp()・srvstr_get_path()・status・strrchr_m()・unix_convert().
01676 { 01677 pstring fname; 01678 int outsize = 0; 01679 uint32 fattr = SVAL(inbuf,smb_vwv0); 01680 files_struct *fsp; 01681 int oplock_request = CORE_OPLOCK_REQUEST(inbuf); 01682 int tmpfd; 01683 SMB_STRUCT_STAT sbuf; 01684 char *p, *s; 01685 NTSTATUS status; 01686 unsigned int namelen; 01687 01688 START_PROFILE(SMBctemp); 01689 01690 srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status); 01691 if (!NT_STATUS_IS_OK(status)) { 01692 END_PROFILE(SMBctemp); 01693 return ERROR_NT(status); 01694 } 01695 if (*fname) { 01696 pstrcat(fname,"/TMXXXXXX"); 01697 } else { 01698 pstrcat(fname,"TMXXXXXX"); 01699 } 01700 01701 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname); 01702 if (!NT_STATUS_IS_OK(status)) { 01703 END_PROFILE(SMBctemp); 01704 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 01705 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 01706 } 01707 return ERROR_NT(status); 01708 } 01709 01710 status = unix_convert(conn, fname, False, NULL, &sbuf); 01711 if (!NT_STATUS_IS_OK(status)) { 01712 END_PROFILE(SMBctemp); 01713 return ERROR_NT(status); 01714 } 01715 01716 status = check_name(conn, fname); 01717 if (!NT_STATUS_IS_OK(status)) { 01718 END_PROFILE(SMBctemp); 01719 return ERROR_NT(status); 01720 } 01721 01722 tmpfd = smb_mkstemp(fname); 01723 if (tmpfd == -1) { 01724 END_PROFILE(SMBctemp); 01725 return(UNIXERROR(ERRDOS,ERRnoaccess)); 01726 } 01727 01728 SMB_VFS_STAT(conn,fname,&sbuf); 01729 01730 /* We should fail if file does not exist. */ 01731 status = open_file_ntcreate(conn,fname,&sbuf, 01732 FILE_GENERIC_READ | FILE_GENERIC_WRITE, 01733 FILE_SHARE_READ|FILE_SHARE_WRITE, 01734 FILE_OPEN, 01735 0, 01736 fattr, 01737 oplock_request, 01738 NULL, &fsp); 01739 01740 /* close fd from smb_mkstemp() */ 01741 close(tmpfd); 01742 01743 if (!NT_STATUS_IS_OK(status)) { 01744 END_PROFILE(SMBctemp); 01745 if (open_was_deferred(SVAL(inbuf,smb_mid))) { 01746 /* We have re-scheduled this call. */ 01747 return -1; 01748 } 01749 return ERROR_OPEN(status); 01750 } 01751 01752 outsize = set_message(outbuf,1,0,True); 01753 SSVAL(outbuf,smb_vwv0,fsp->fnum); 01754 01755 /* the returned filename is relative to the directory */ 01756 s = strrchr_m(fname, '/'); 01757 if (!s) { 01758 s = fname; 01759 } else { 01760 s++; 01761 } 01762 01763 p = smb_buf(outbuf); 01764 #if 0 01765 /* Tested vs W2K3 - this doesn't seem to be here - null terminated filename is the only 01766 thing in the byte section. JRA */ 01767 SSVALS(p, 0, -1); /* what is this? not in spec */ 01768 #endif 01769 namelen = srvstr_push(outbuf, p, s, BUFFER_SIZE - (p - outbuf), STR_ASCII|STR_TERMINATE); 01770 p += namelen; 01771 outsize = set_message_end(outbuf, p); 01772 01773 if (oplock_request && lp_fake_oplocks(SNUM(conn))) { 01774 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED); 01775 } 01776 01777 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { 01778 SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED); 01779 } 01780 01781 DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fname ) ); 01782 DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fname, fsp->fh->fd, 01783 (unsigned int)sbuf.st_mode ) ); 01784 01785 END_PROFILE(SMBctemp); 01786 return(outsize); 01787 }
static NTSTATUS can_rename | ( | connection_struct * | conn, | |
char * | fname, | |||
uint16 | dirtype, | |||
SMB_STRUCT_STAT * | pst, | |||
BOOL | self_open | |||
) | [static] |
参照先 close_file()・NORMAL_CLOSE・open_file_ntcreate()・status.
参照元 rename_internals()・rename_internals_fsp().
01794 { 01795 files_struct *fsp; 01796 uint32 fmode; 01797 NTSTATUS status; 01798 01799 if (!CAN_WRITE(conn)) { 01800 return NT_STATUS_MEDIA_WRITE_PROTECTED; 01801 } 01802 01803 fmode = dos_mode(conn,fname,pst); 01804 if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) { 01805 return NT_STATUS_NO_SUCH_FILE; 01806 } 01807 01808 if (S_ISDIR(pst->st_mode)) { 01809 return NT_STATUS_OK; 01810 } 01811 01812 status = open_file_ntcreate(conn, fname, pst, 01813 DELETE_ACCESS, 01814 /* If we're checking our fsp don't deny for delete. */ 01815 self_open ? 01816 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE : 01817 FILE_SHARE_READ|FILE_SHARE_WRITE, 01818 FILE_OPEN, 01819 0, 01820 FILE_ATTRIBUTE_NORMAL, 01821 0, 01822 NULL, &fsp); 01823 01824 if (!NT_STATUS_IS_OK(status)) { 01825 return status; 01826 } 01827 close_file(fsp,NORMAL_CLOSE); 01828 return NT_STATUS_OK; 01829 }
static NTSTATUS can_delete | ( | connection_struct * | conn, | |
char * | fname, | |||
uint32 | dirtype, | |||
BOOL | can_defer | |||
) | [static] |
参照先 close_file()・dir_check_ftype()・errno・map_nt_error_from_unix()・NORMAL_CLOSE・open_file_ntcreate()・status.
参照元 unlink_internals().
01837 { 01838 SMB_STRUCT_STAT sbuf; 01839 uint32 fattr; 01840 files_struct *fsp; 01841 uint32 dirtype_orig = dirtype; 01842 NTSTATUS status; 01843 01844 DEBUG(10,("can_delete: %s, dirtype = %d\n", fname, dirtype )); 01845 01846 if (!CAN_WRITE(conn)) { 01847 return NT_STATUS_MEDIA_WRITE_PROTECTED; 01848 } 01849 01850 if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0) { 01851 return map_nt_error_from_unix(errno); 01852 } 01853 01854 fattr = dos_mode(conn,fname,&sbuf); 01855 01856 if (dirtype & FILE_ATTRIBUTE_NORMAL) { 01857 dirtype = aDIR|aARCH|aRONLY; 01858 } 01859 01860 dirtype &= (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM); 01861 if (!dirtype) { 01862 return NT_STATUS_NO_SUCH_FILE; 01863 } 01864 01865 if (!dir_check_ftype(conn, fattr, dirtype)) { 01866 if (fattr & aDIR) { 01867 return NT_STATUS_FILE_IS_A_DIRECTORY; 01868 } 01869 return NT_STATUS_NO_SUCH_FILE; 01870 } 01871 01872 if (dirtype_orig & 0x8000) { 01873 /* These will never be set for POSIX. */ 01874 return NT_STATUS_NO_SUCH_FILE; 01875 } 01876 01877 #if 0 01878 if ((fattr & dirtype) & FILE_ATTRIBUTE_DIRECTORY) { 01879 return NT_STATUS_FILE_IS_A_DIRECTORY; 01880 } 01881 01882 if ((fattr & ~dirtype) & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) { 01883 return NT_STATUS_NO_SUCH_FILE; 01884 } 01885 01886 if (dirtype & 0xFF00) { 01887 /* These will never be set for POSIX. */ 01888 return NT_STATUS_NO_SUCH_FILE; 01889 } 01890 01891 dirtype &= 0xFF; 01892 if (!dirtype) { 01893 return NT_STATUS_NO_SUCH_FILE; 01894 } 01895 01896 /* Can't delete a directory. */ 01897 if (fattr & aDIR) { 01898 return NT_STATUS_FILE_IS_A_DIRECTORY; 01899 } 01900 #endif 01901 01902 #if 0 /* JRATEST */ 01903 else if (dirtype & aDIR) /* Asked for a directory and it isn't. */ 01904 return NT_STATUS_OBJECT_NAME_INVALID; 01905 #endif /* JRATEST */ 01906 01907 /* Fix for bug #3035 from SATOH Fumiyasu <fumiyas@miraclelinux.com> 01908 01909 On a Windows share, a file with read-only dosmode can be opened with 01910 DELETE_ACCESS. But on a Samba share (delete readonly = no), it 01911 fails with NT_STATUS_CANNOT_DELETE error. 01912 01913 This semantic causes a problem that a user can not 01914 rename a file with read-only dosmode on a Samba share 01915 from a Windows command prompt (i.e. cmd.exe, but can rename 01916 from Windows Explorer). 01917 */ 01918 01919 if (!lp_delete_readonly(SNUM(conn))) { 01920 if (fattr & aRONLY) { 01921 return NT_STATUS_CANNOT_DELETE; 01922 } 01923 } 01924 01925 /* On open checks the open itself will check the share mode, so 01926 don't do it here as we'll get it wrong. */ 01927 01928 status = open_file_ntcreate(conn, fname, &sbuf, 01929 DELETE_ACCESS, 01930 FILE_SHARE_NONE, 01931 FILE_OPEN, 01932 0, 01933 FILE_ATTRIBUTE_NORMAL, 01934 can_defer ? 0 : INTERNAL_OPEN_ONLY, 01935 NULL, &fsp); 01936 01937 if (NT_STATUS_IS_OK(status)) { 01938 close_file(fsp,NORMAL_CLOSE); 01939 } 01940 return status; 01941 }
NTSTATUS unlink_internals | ( | connection_struct * | conn, | |
uint32 | dirtype, | |||
char * | name, | |||
BOOL | has_wild, | |||
BOOL | can_defer | |||
) |
参照先 can_delete()・connection_struct::case_sensitive・check_name()・CloseDir()・smb_Dir::conn・errno・is_visible_file()・mangle_check_cache()・mangle_is_mangled()・map_nt_error_from_unix()・mask_match()・notify_fname()・smb_Dir::offset・OpenDir()・connection_struct::params・ReadDirName()・status・strequal()・strrchr_m()・unix_convert().
参照元 delete_driver_files()・reply_unlink().
01950 { 01951 pstring directory; 01952 pstring mask; 01953 char *p; 01954 int count=0; 01955 NTSTATUS status = NT_STATUS_OK; 01956 SMB_STRUCT_STAT sbuf; 01957 01958 *directory = *mask = 0; 01959 01960 status = unix_convert(conn, name, has_wild, NULL, &sbuf); 01961 if (!NT_STATUS_IS_OK(status)) { 01962 return status; 01963 } 01964 01965 p = strrchr_m(name,'/'); 01966 if (!p) { 01967 pstrcpy(directory,"."); 01968 pstrcpy(mask,name); 01969 } else { 01970 *p = 0; 01971 pstrcpy(directory,name); 01972 pstrcpy(mask,p+1); 01973 } 01974 01975 /* 01976 * We should only check the mangled cache 01977 * here if unix_convert failed. This means 01978 * that the path in 'mask' doesn't exist 01979 * on the file system and so we need to look 01980 * for a possible mangle. This patch from 01981 * Tine Smukavec <valentin.smukavec@hermes.si>. 01982 */ 01983 01984 if (!VALID_STAT(sbuf) && mangle_is_mangled(mask,conn->params)) 01985 mangle_check_cache( mask, sizeof(pstring)-1, conn->params ); 01986 01987 if (!has_wild) { 01988 pstrcat(directory,"/"); 01989 pstrcat(directory,mask); 01990 if (dirtype == 0) { 01991 dirtype = FILE_ATTRIBUTE_NORMAL; 01992 } 01993 01994 status = check_name(conn, directory); 01995 if (!NT_STATUS_IS_OK(status)) { 01996 return status; 01997 } 01998 01999 status = can_delete(conn,directory,dirtype,can_defer); 02000 if (!NT_STATUS_IS_OK(status)) { 02001 return status; 02002 } 02003 02004 if (SMB_VFS_UNLINK(conn,directory) == 0) { 02005 count++; 02006 notify_fname(conn, NOTIFY_ACTION_REMOVED, 02007 FILE_NOTIFY_CHANGE_FILE_NAME, 02008 directory); 02009 } 02010 } else { 02011 struct smb_Dir *dir_hnd = NULL; 02012 long offset = 0; 02013 const char *dname; 02014 02015 if ((dirtype & SAMBA_ATTRIBUTES_MASK) == aDIR) { 02016 return NT_STATUS_OBJECT_NAME_INVALID; 02017 } 02018 02019 if (strequal(mask,"????????.???")) { 02020 pstrcpy(mask,"*"); 02021 } 02022 02023 status = check_name(conn, directory); 02024 if (!NT_STATUS_IS_OK(status)) { 02025 return status; 02026 } 02027 02028 dir_hnd = OpenDir(conn, directory, mask, dirtype); 02029 if (dir_hnd == NULL) { 02030 return map_nt_error_from_unix(errno); 02031 } 02032 02033 /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then 02034 the pattern matches against the long name, otherwise the short name 02035 We don't implement this yet XXXX 02036 */ 02037 02038 status = NT_STATUS_NO_SUCH_FILE; 02039 02040 while ((dname = ReadDirName(dir_hnd, &offset))) { 02041 SMB_STRUCT_STAT st; 02042 pstring fname; 02043 pstrcpy(fname,dname); 02044 02045 if (!is_visible_file(conn, directory, dname, &st, True)) { 02046 continue; 02047 } 02048 02049 /* Quick check for "." and ".." */ 02050 if (fname[0] == '.') { 02051 if (!fname[1] || (fname[1] == '.' && !fname[2])) { 02052 continue; 02053 } 02054 } 02055 02056 if(!mask_match(fname, mask, conn->case_sensitive)) { 02057 continue; 02058 } 02059 02060 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname); 02061 02062 status = check_name(conn, fname); 02063 if (!NT_STATUS_IS_OK(status)) { 02064 CloseDir(dir_hnd); 02065 return status; 02066 } 02067 02068 status = can_delete(conn, fname, dirtype, can_defer); 02069 if (!NT_STATUS_IS_OK(status)) { 02070 continue; 02071 } 02072 if (SMB_VFS_UNLINK(conn,fname) == 0) { 02073 count++; 02074 DEBUG(3,("unlink_internals: successful unlink " 02075 "[%s]\n",fname)); 02076 notify_fname(conn, NOTIFY_ACTION_REMOVED, 02077 FILE_NOTIFY_CHANGE_FILE_NAME, 02078 fname); 02079 } 02080 02081 } 02082 CloseDir(dir_hnd); 02083 } 02084 02085 if (count == 0 && NT_STATUS_IS_OK(status)) { 02086 status = map_nt_error_from_unix(errno); 02087 } 02088 02089 return status; 02090 }
int reply_unlink | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 smb_Dir::conn・name・open_was_deferred()・resolve_dfspath_wcard()・set_message()・srvstr_get_path_wcard()・status・unlink_internals().
02098 { 02099 int outsize = 0; 02100 pstring name; 02101 uint32 dirtype; 02102 NTSTATUS status; 02103 BOOL path_contains_wcard = False; 02104 02105 START_PROFILE(SMBunlink); 02106 02107 dirtype = SVAL(inbuf,smb_vwv0); 02108 02109 srvstr_get_path_wcard(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status, &path_contains_wcard); 02110 if (!NT_STATUS_IS_OK(status)) { 02111 END_PROFILE(SMBunlink); 02112 return ERROR_NT(status); 02113 } 02114 02115 status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, name, &path_contains_wcard); 02116 if (!NT_STATUS_IS_OK(status)) { 02117 END_PROFILE(SMBunlink); 02118 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 02119 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 02120 } 02121 return ERROR_NT(status); 02122 } 02123 02124 DEBUG(3,("reply_unlink : %s\n",name)); 02125 02126 status = unlink_internals(conn, dirtype, name, path_contains_wcard, 02127 True); 02128 if (!NT_STATUS_IS_OK(status)) { 02129 END_PROFILE(SMBunlink); 02130 if (open_was_deferred(SVAL(inbuf,smb_mid))) { 02131 /* We have re-scheduled this call. */ 02132 return -1; 02133 } 02134 return ERROR_NT(status); 02135 } 02136 02137 outsize = set_message(outbuf,0,0,False); 02138 02139 END_PROFILE(SMBunlink); 02140 return outsize; 02141 }
static void fail_readraw | ( | void | ) | [static] |
参照先 errno・exit_server_cleanly()・strerror().
参照元 fake_sendfile()・reply_readbraw()・send_file_readbraw().
02148 { 02149 pstring errstr; 02150 slprintf(errstr, sizeof(errstr)-1, "FAIL ! reply_readbraw: socket write fail (%s)", 02151 strerror(errno) ); 02152 exit_server_cleanly(errstr); 02153 }
static ssize_t fake_sendfile | ( | files_struct * | fsp, | |
SMB_OFF_T | startpos, | |||
size_t | nread, | |||
char * | buf, | |||
int | bufsize | |||
) | [static] |
参照先 fail_readraw()・read_file()・smbd_server_fd()・write_data().
参照元 send_file_readbraw()・send_file_readX().
02161 { 02162 ssize_t ret=0; 02163 02164 /* Paranioa check... */ 02165 if (nread > bufsize) { 02166 fail_readraw(); 02167 } 02168 02169 if (nread > 0) { 02170 ret = read_file(fsp,buf,startpos,nread); 02171 if (ret == -1) { 02172 return -1; 02173 } 02174 } 02175 02176 /* If we had a short read, fill with zeros. */ 02177 if (ret < nread) { 02178 memset(buf, '\0', nread - ret); 02179 } 02180 02181 if (write_data(smbd_server_fd(),buf,nread) != nread) { 02182 return -1; 02183 } 02184 02185 return (ssize_t)nread; 02186 }
void send_file_readbraw | ( | connection_struct * | conn, | |
files_struct * | fsp, | |||
SMB_OFF_T | startpos, | |||
size_t | nread, | |||
ssize_t | mincount, | |||
char * | outbuf, | |||
int | out_buffsize | |||
) |
参照先 chain_size・smb_Dir::conn・data_blob_::data・errno・exit_server_cleanly()・fail_readraw()・fake_sendfile()・fd_handle::fd・files_struct::fh・data_blob_::free・files_struct::fsp_name・data_blob_::length・read_file()・smbd_server_fd()・strerror()・files_struct::wcp・write_data().
参照元 reply_readbraw().
02195 { 02196 ssize_t ret=0; 02197 02198 #if defined(WITH_SENDFILE) 02199 /* 02200 * We can only use sendfile on a non-chained packet 02201 * but we can use on a non-oplocked file. tridge proved this 02202 * on a train in Germany :-). JRA. 02203 * reply_readbraw has already checked the length. 02204 */ 02205 02206 if ( (chain_size == 0) && (nread > 0) && 02207 (fsp->wcp == NULL) && lp_use_sendfile(SNUM(conn)) ) { 02208 DATA_BLOB header; 02209 02210 _smb_setlen(outbuf,nread); 02211 header.data = (uint8 *)outbuf; 02212 header.length = 4; 02213 header.free = NULL; 02214 02215 if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fh->fd, &header, startpos, nread) == -1) { 02216 /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */ 02217 if (errno == ENOSYS) { 02218 goto normal_readbraw; 02219 } 02220 02221 /* 02222 * Special hack for broken Linux with no working sendfile. If we 02223 * return EINTR we sent the header but not the rest of the data. 02224 * Fake this up by doing read/write calls. 02225 */ 02226 if (errno == EINTR) { 02227 /* Ensure we don't do this again. */ 02228 set_use_sendfile(SNUM(conn), False); 02229 DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n")); 02230 02231 if (fake_sendfile(fsp, startpos, nread, outbuf + 4, out_buffsize - 4) == -1) { 02232 DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n", 02233 fsp->fsp_name, strerror(errno) )); 02234 exit_server_cleanly("send_file_readbraw fake_sendfile failed"); 02235 } 02236 return; 02237 } 02238 02239 DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n", 02240 fsp->fsp_name, strerror(errno) )); 02241 exit_server_cleanly("send_file_readbraw sendfile failed"); 02242 } 02243 02244 return; 02245 } 02246 02247 normal_readbraw: 02248 02249 #endif 02250 02251 if (nread > 0) { 02252 ret = read_file(fsp,outbuf+4,startpos,nread); 02253 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */ 02254 if (ret < mincount) 02255 ret = 0; 02256 #else 02257 if (ret < nread) 02258 ret = 0; 02259 #endif 02260 } 02261 02262 _smb_setlen(outbuf,ret); 02263 if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret) 02264 fail_readraw(); 02265 }
int reply_readbraw | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | out_buffsize | |||
) |
参照先 files_struct::can_read・smb_Dir::conn・exit_server_cleanly()・fail_readraw()・fd_handle::fd・files_struct::fh・file_fsp()・flush_write_cache()・files_struct::fnum・is_locked()・READ_LOCK・send_file_readbraw()・size・smbd_server_fd()・srv_is_signing_active()・write_data().
02272 { 02273 ssize_t maxcount,mincount; 02274 size_t nread = 0; 02275 SMB_OFF_T startpos; 02276 char *header = outbuf; 02277 files_struct *fsp; 02278 START_PROFILE(SMBreadbraw); 02279 02280 if (srv_is_signing_active()) { 02281 exit_server_cleanly("reply_readbraw: SMB signing is active - raw reads/writes are disallowed."); 02282 } 02283 02284 /* 02285 * Special check if an oplock break has been issued 02286 * and the readraw request croses on the wire, we must 02287 * return a zero length response here. 02288 */ 02289 02290 fsp = file_fsp(inbuf,smb_vwv0); 02291 02292 if (!FNUM_OK(fsp,conn) || !fsp->can_read) { 02293 /* 02294 * fsp could be NULL here so use the value from the packet. JRA. 02295 */ 02296 DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",(int)SVAL(inbuf,smb_vwv0))); 02297 _smb_setlen(header,0); 02298 if (write_data(smbd_server_fd(),header,4) != 4) 02299 fail_readraw(); 02300 END_PROFILE(SMBreadbraw); 02301 return(-1); 02302 } 02303 02304 CHECK_FSP(fsp,conn); 02305 02306 flush_write_cache(fsp, READRAW_FLUSH); 02307 02308 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1); 02309 if(CVAL(inbuf,smb_wct) == 10) { 02310 /* 02311 * This is a large offset (64 bit) read. 02312 */ 02313 #ifdef LARGE_SMB_OFF_T 02314 02315 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv8)) << 32); 02316 02317 #else /* !LARGE_SMB_OFF_T */ 02318 02319 /* 02320 * Ensure we haven't been sent a >32 bit offset. 02321 */ 02322 02323 if(IVAL(inbuf,smb_vwv8) != 0) { 02324 DEBUG(0,("readbraw - large offset (%x << 32) used and we don't support \ 02325 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv8) )); 02326 _smb_setlen(header,0); 02327 if (write_data(smbd_server_fd(),header,4) != 4) 02328 fail_readraw(); 02329 END_PROFILE(SMBreadbraw); 02330 return(-1); 02331 } 02332 02333 #endif /* LARGE_SMB_OFF_T */ 02334 02335 if(startpos < 0) { 02336 DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n", (double)startpos )); 02337 _smb_setlen(header,0); 02338 if (write_data(smbd_server_fd(),header,4) != 4) 02339 fail_readraw(); 02340 END_PROFILE(SMBreadbraw); 02341 return(-1); 02342 } 02343 } 02344 maxcount = (SVAL(inbuf,smb_vwv3) & 0xFFFF); 02345 mincount = (SVAL(inbuf,smb_vwv4) & 0xFFFF); 02346 02347 /* ensure we don't overrun the packet size */ 02348 maxcount = MIN(65535,maxcount); 02349 02350 if (!is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) { 02351 SMB_STRUCT_STAT st; 02352 SMB_OFF_T size = 0; 02353 02354 if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st) == 0) { 02355 size = st.st_size; 02356 } 02357 02358 if (startpos >= size) { 02359 nread = 0; 02360 } else { 02361 nread = MIN(maxcount,(size - startpos)); 02362 } 02363 } 02364 02365 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */ 02366 if (nread < mincount) 02367 nread = 0; 02368 #endif 02369 02370 DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%lu min=%lu nread=%lu\n", fsp->fnum, (double)startpos, 02371 (unsigned long)maxcount, (unsigned long)mincount, (unsigned long)nread ) ); 02372 02373 send_file_readbraw(conn, fsp, startpos, nread, mincount, outbuf, out_buffsize); 02374 02375 DEBUG(5,("readbraw finished\n")); 02376 END_PROFILE(SMBreadbraw); 02377 return -1; 02378 }
int reply_lockread | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | dum_buffsiz | |||
) |
参照先 do_lock()・file_fsp()・files_struct::fnum・byte_range_lock::fsp・max_recv・read_file()・release_level_2_oplocks_on_change()・set_message()・status・WINDOWS_LOCK・WRITE_LOCK.
02388 { 02389 ssize_t nread = -1; 02390 char *data; 02391 int outsize = 0; 02392 SMB_OFF_T startpos; 02393 size_t numtoread; 02394 NTSTATUS status; 02395 files_struct *fsp = file_fsp(inbuf,smb_vwv0); 02396 struct byte_range_lock *br_lck = NULL; 02397 START_PROFILE(SMBlockread); 02398 02399 CHECK_FSP(fsp,conn); 02400 if (!CHECK_READ(fsp,inbuf)) { 02401 return(ERROR_DOS(ERRDOS,ERRbadaccess)); 02402 } 02403 02404 release_level_2_oplocks_on_change(fsp); 02405 02406 numtoread = SVAL(inbuf,smb_vwv1); 02407 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2); 02408 02409 outsize = set_message(outbuf,5,3,True); 02410 numtoread = MIN(BUFFER_SIZE-outsize,numtoread); 02411 data = smb_buf(outbuf) + 3; 02412 02413 /* 02414 * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+ 02415 * protocol request that predates the read/write lock concept. 02416 * Thus instead of asking for a read lock here we need to ask 02417 * for a write lock. JRA. 02418 * Note that the requested lock size is unaffected by max_recv. 02419 */ 02420 02421 br_lck = do_lock(fsp, 02422 (uint32)SVAL(inbuf,smb_pid), 02423 (SMB_BIG_UINT)numtoread, 02424 (SMB_BIG_UINT)startpos, 02425 WRITE_LOCK, 02426 WINDOWS_LOCK, 02427 False, /* Non-blocking lock. */ 02428 &status, 02429 NULL); 02430 TALLOC_FREE(br_lck); 02431 02432 if (NT_STATUS_V(status)) { 02433 END_PROFILE(SMBlockread); 02434 return ERROR_NT(status); 02435 } 02436 02437 /* 02438 * However the requested READ size IS affected by max_recv. Insanity.... JRA. 02439 */ 02440 02441 if (numtoread > max_recv) { 02442 DEBUG(0,("reply_lockread: requested read size (%u) is greater than maximum allowed (%u). \ 02443 Returning short read of maximum allowed for compatibility with Windows 2000.\n", 02444 (unsigned int)numtoread, (unsigned int)max_recv )); 02445 numtoread = MIN(numtoread,max_recv); 02446 } 02447 nread = read_file(fsp,data,startpos,numtoread); 02448 02449 if (nread < 0) { 02450 END_PROFILE(SMBlockread); 02451 return(UNIXERROR(ERRDOS,ERRnoaccess)); 02452 } 02453 02454 outsize += nread; 02455 SSVAL(outbuf,smb_vwv0,nread); 02456 SSVAL(outbuf,smb_vwv5,nread+3); 02457 SSVAL(smb_buf(outbuf),1,nread); 02458 02459 DEBUG(3,("lockread fnum=%d num=%d nread=%d\n", 02460 fsp->fnum, (int)numtoread, (int)nread)); 02461 02462 END_PROFILE(SMBlockread); 02463 return(outsize); 02464 }
int reply_read | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | size, | |||
int | dum_buffsize | |||
) |
参照先 file_fsp()・files_struct::fnum・byte_range_lock::fsp・is_locked()・max_recv・read_file()・READ_LOCK・set_message().
02474 { 02475 size_t numtoread; 02476 ssize_t nread = 0; 02477 char *data; 02478 SMB_OFF_T startpos; 02479 int outsize = 0; 02480 files_struct *fsp = file_fsp(inbuf,smb_vwv0); 02481 START_PROFILE(SMBread); 02482 02483 CHECK_FSP(fsp,conn); 02484 if (!CHECK_READ(fsp,inbuf)) { 02485 return(ERROR_DOS(ERRDOS,ERRbadaccess)); 02486 } 02487 02488 numtoread = SVAL(inbuf,smb_vwv1); 02489 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2); 02490 02491 outsize = set_message(outbuf,5,3,True); 02492 numtoread = MIN(BUFFER_SIZE-outsize,numtoread); 02493 /* 02494 * The requested read size cannot be greater than max_recv. JRA. 02495 */ 02496 if (numtoread > max_recv) { 02497 DEBUG(0,("reply_read: requested read size (%u) is greater than maximum allowed (%u). \ 02498 Returning short read of maximum allowed for compatibility with Windows 2000.\n", 02499 (unsigned int)numtoread, (unsigned int)max_recv )); 02500 numtoread = MIN(numtoread,max_recv); 02501 } 02502 02503 data = smb_buf(outbuf) + 3; 02504 02505 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK)) { 02506 END_PROFILE(SMBread); 02507 return ERROR_DOS(ERRDOS,ERRlock); 02508 } 02509 02510 if (numtoread > 0) 02511 nread = read_file(fsp,data,startpos,numtoread); 02512 02513 if (nread < 0) { 02514 END_PROFILE(SMBread); 02515 return(UNIXERROR(ERRDOS,ERRnoaccess)); 02516 } 02517 02518 outsize += nread; 02519 SSVAL(outbuf,smb_vwv0,nread); 02520 SSVAL(outbuf,smb_vwv5,nread+3); 02521 SCVAL(smb_buf(outbuf),0,1); 02522 SSVAL(smb_buf(outbuf),1,nread); 02523 02524 DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n", 02525 fsp->fnum, (int)numtoread, (int)nread ) ); 02526 02527 END_PROFILE(SMBread); 02528 return(outsize); 02529 }
int send_file_readX | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | len_outbuf, | |||
files_struct * | fsp, | |||
SMB_OFF_T | startpos, | |||
size_t | smb_maxcnt | |||
) |
参照先 chain_size・data_blob_::data・errno・exit_server_cleanly()・fake_sendfile()・fd_handle::fd・files_struct::fh・files_struct::fnum・data_blob_::free・byte_range_lock::fsp・files_struct::fsp_name・data_blob_::length・read_file()・set_message()・smbd_server_fd()・strerror()・files_struct::wcp.
参照元 reply_read_and_X().
02537 { 02538 int outsize = 0; 02539 ssize_t nread = -1; 02540 char *data = smb_buf(outbuf); 02541 02542 #if defined(WITH_SENDFILE) 02543 /* 02544 * We can only use sendfile on a non-chained packet 02545 * but we can use on a non-oplocked file. tridge proved this 02546 * on a train in Germany :-). JRA. 02547 */ 02548 02549 if ((chain_size == 0) && (CVAL(inbuf,smb_vwv0) == 0xFF) && 02550 lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) { 02551 SMB_STRUCT_STAT sbuf; 02552 DATA_BLOB header; 02553 02554 if(SMB_VFS_FSTAT(fsp,fsp->fh->fd, &sbuf) == -1) 02555 return(UNIXERROR(ERRDOS,ERRnoaccess)); 02556 02557 if (startpos > sbuf.st_size) 02558 goto normal_read; 02559 02560 if (smb_maxcnt > (sbuf.st_size - startpos)) 02561 smb_maxcnt = (sbuf.st_size - startpos); 02562 02563 if (smb_maxcnt == 0) 02564 goto normal_read; 02565 02566 /* 02567 * Set up the packet header before send. We 02568 * assume here the sendfile will work (get the 02569 * correct amount of data). 02570 */ 02571 02572 SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */ 02573 SSVAL(outbuf,smb_vwv5,smb_maxcnt); 02574 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf)); 02575 SSVAL(outbuf,smb_vwv7,((smb_maxcnt >> 16) & 1)); 02576 SSVAL(smb_buf(outbuf),-2,smb_maxcnt); 02577 SCVAL(outbuf,smb_vwv0,0xFF); 02578 set_message(outbuf,12,smb_maxcnt,False); 02579 header.data = (uint8 *)outbuf; 02580 header.length = data - outbuf; 02581 header.free = NULL; 02582 02583 if ((nread = SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fh->fd, &header, startpos, smb_maxcnt)) == -1) { 02584 /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */ 02585 if (errno == ENOSYS) { 02586 goto normal_read; 02587 } 02588 02589 /* 02590 * Special hack for broken Linux with no working sendfile. If we 02591 * return EINTR we sent the header but not the rest of the data. 02592 * Fake this up by doing read/write calls. 02593 */ 02594 02595 if (errno == EINTR) { 02596 /* Ensure we don't do this again. */ 02597 set_use_sendfile(SNUM(conn), False); 02598 DEBUG(0,("send_file_readX: sendfile not available. Faking..\n")); 02599 02600 if ((nread = fake_sendfile(fsp, startpos, smb_maxcnt, data, 02601 len_outbuf - (data-outbuf))) == -1) { 02602 DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n", 02603 fsp->fsp_name, strerror(errno) )); 02604 exit_server_cleanly("send_file_readX: fake_sendfile failed"); 02605 } 02606 DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n", 02607 fsp->fnum, (int)smb_maxcnt, (int)nread ) ); 02608 /* Returning -1 here means successful sendfile. */ 02609 return -1; 02610 } 02611 02612 DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n", 02613 fsp->fsp_name, strerror(errno) )); 02614 exit_server_cleanly("send_file_readX sendfile failed"); 02615 } 02616 02617 DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n", 02618 fsp->fnum, (int)smb_maxcnt, (int)nread ) ); 02619 /* Returning -1 here means successful sendfile. */ 02620 return -1; 02621 } 02622 02623 normal_read: 02624 02625 #endif 02626 02627 nread = read_file(fsp,data,startpos,smb_maxcnt); 02628 02629 if (nread < 0) { 02630 return(UNIXERROR(ERRDOS,ERRnoaccess)); 02631 } 02632 02633 outsize = set_message(outbuf,12,nread,False); 02634 SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */ 02635 SSVAL(outbuf,smb_vwv5,nread); 02636 SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf)); 02637 SSVAL(outbuf,smb_vwv7,((nread >> 16) & 1)); 02638 SSVAL(smb_buf(outbuf),-2,nread); 02639 02640 DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n", 02641 fsp->fnum, (int)smb_maxcnt, (int)nread ) ); 02642 02643 /* Returning the number of bytes we want to send back - including header. */ 02644 return outsize; 02645 }
int reply_read_and_X | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize | |||
) |
参照先 chain_reply()・file_fsp()・byte_range_lock::fsp・global_client_caps・is_locked()・READ_LOCK・reply_pipe_read_and_X()・schedule_aio_read_and_X()・send_file_readX()・set_message().
02652 { 02653 files_struct *fsp = file_fsp(inbuf,smb_vwv2); 02654 SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3); 02655 ssize_t nread = -1; 02656 size_t smb_maxcnt = SVAL(inbuf,smb_vwv5); 02657 #if 0 02658 size_t smb_mincnt = SVAL(inbuf,smb_vwv6); 02659 #endif 02660 02661 START_PROFILE(SMBreadX); 02662 02663 /* If it's an IPC, pass off the pipe handler. */ 02664 if (IS_IPC(conn)) { 02665 END_PROFILE(SMBreadX); 02666 return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize); 02667 } 02668 02669 CHECK_FSP(fsp,conn); 02670 if (!CHECK_READ(fsp,inbuf)) { 02671 return(ERROR_DOS(ERRDOS,ERRbadaccess)); 02672 } 02673 02674 set_message(outbuf,12,0,True); 02675 02676 if (global_client_caps & CAP_LARGE_READX) { 02677 if (SVAL(inbuf,smb_vwv7) == 1) { 02678 smb_maxcnt |= (1<<16); 02679 } 02680 if (smb_maxcnt > BUFFER_SIZE) { 02681 DEBUG(0,("reply_read_and_X - read too large (%u) for reply buffer %u\n", 02682 (unsigned int)smb_maxcnt, (unsigned int)BUFFER_SIZE)); 02683 END_PROFILE(SMBreadX); 02684 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 02685 } 02686 } 02687 02688 if(CVAL(inbuf,smb_wct) == 12) { 02689 #ifdef LARGE_SMB_OFF_T 02690 /* 02691 * This is a large offset (64 bit) read. 02692 */ 02693 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32); 02694 02695 #else /* !LARGE_SMB_OFF_T */ 02696 02697 /* 02698 * Ensure we haven't been sent a >32 bit offset. 02699 */ 02700 02701 if(IVAL(inbuf,smb_vwv10) != 0) { 02702 DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \ 02703 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv10) )); 02704 END_PROFILE(SMBreadX); 02705 return ERROR_DOS(ERRDOS,ERRbadaccess); 02706 } 02707 02708 #endif /* LARGE_SMB_OFF_T */ 02709 02710 } 02711 02712 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK)) { 02713 END_PROFILE(SMBreadX); 02714 return ERROR_DOS(ERRDOS,ERRlock); 02715 } 02716 02717 if (schedule_aio_read_and_X(conn, inbuf, outbuf, length, bufsize, fsp, startpos, smb_maxcnt)) { 02718 END_PROFILE(SMBreadX); 02719 return -1; 02720 } 02721 02722 nread = send_file_readX(conn, inbuf, outbuf, length, bufsize, fsp, startpos, smb_maxcnt); 02723 /* Only call chain_reply if not an error. */ 02724 if (nread != -1 && SVAL(outbuf,smb_rcls) == 0) { 02725 nread = chain_reply(inbuf,outbuf,length,bufsize); 02726 } 02727 02728 END_PROFILE(SMBreadX); 02729 return nread; 02730 }
int reply_writebraw | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | size, | |||
int | dum_buffsize | |||
) |
参照先 errno・exit_server_cleanly()・file_fsp()・files_struct::fnum・byte_range_lock::fsp・files_struct::fsp_name・is_locked()・nt_errstr()・Protocol・PROTOCOL_COREPLUS・read_data()・read_smb_length()・send_keepalive()・send_smb()・set_message()・show_msg()・smbd_server_fd()・srv_is_signing_active()・status・strerror()・sync_file()・write_file()・WRITE_LOCK.
02737 { 02738 ssize_t nwritten=0; 02739 ssize_t total_written=0; 02740 size_t numtowrite=0; 02741 size_t tcount; 02742 SMB_OFF_T startpos; 02743 char *data=NULL; 02744 BOOL write_through; 02745 files_struct *fsp = file_fsp(inbuf,smb_vwv0); 02746 int outsize = 0; 02747 NTSTATUS status; 02748 START_PROFILE(SMBwritebraw); 02749 02750 if (srv_is_signing_active()) { 02751 exit_server_cleanly("reply_writebraw: SMB signing is active - raw reads/writes are disallowed."); 02752 } 02753 02754 CHECK_FSP(fsp,conn); 02755 if (!CHECK_WRITE(fsp)) { 02756 return(ERROR_DOS(ERRDOS,ERRbadaccess)); 02757 } 02758 02759 tcount = IVAL(inbuf,smb_vwv1); 02760 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3); 02761 write_through = BITSETW(inbuf+smb_vwv7,0); 02762 02763 /* We have to deal with slightly different formats depending 02764 on whether we are using the core+ or lanman1.0 protocol */ 02765 02766 if(Protocol <= PROTOCOL_COREPLUS) { 02767 numtowrite = SVAL(smb_buf(inbuf),-2); 02768 data = smb_buf(inbuf); 02769 } else { 02770 numtowrite = SVAL(inbuf,smb_vwv10); 02771 data = smb_base(inbuf) + SVAL(inbuf, smb_vwv11); 02772 } 02773 02774 /* force the error type */ 02775 SCVAL(inbuf,smb_com,SMBwritec); 02776 SCVAL(outbuf,smb_com,SMBwritec); 02777 02778 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { 02779 END_PROFILE(SMBwritebraw); 02780 return(ERROR_DOS(ERRDOS,ERRlock)); 02781 } 02782 02783 if (numtowrite>0) 02784 nwritten = write_file(fsp,data,startpos,numtowrite); 02785 02786 DEBUG(3,("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n", 02787 fsp->fnum, (double)startpos, (int)numtowrite, (int)nwritten, (int)write_through)); 02788 02789 if (nwritten < (ssize_t)numtowrite) { 02790 END_PROFILE(SMBwritebraw); 02791 return(UNIXERROR(ERRHRD,ERRdiskfull)); 02792 } 02793 02794 total_written = nwritten; 02795 02796 /* Return a message to the redirector to tell it to send more bytes */ 02797 SCVAL(outbuf,smb_com,SMBwritebraw); 02798 SSVALS(outbuf,smb_vwv0,-1); 02799 outsize = set_message(outbuf,Protocol>PROTOCOL_COREPLUS?1:0,0,True); 02800 show_msg(outbuf); 02801 if (!send_smb(smbd_server_fd(),outbuf)) 02802 exit_server_cleanly("reply_writebraw: send_smb failed."); 02803 02804 /* Now read the raw data into the buffer and write it */ 02805 if (read_smb_length(smbd_server_fd(),inbuf,SMB_SECONDARY_WAIT) == -1) { 02806 exit_server_cleanly("secondary writebraw failed"); 02807 } 02808 02809 /* Even though this is not an smb message, smb_len returns the generic length of an smb message */ 02810 numtowrite = smb_len(inbuf); 02811 02812 /* Set up outbuf to return the correct return */ 02813 outsize = set_message(outbuf,1,0,True); 02814 SCVAL(outbuf,smb_com,SMBwritec); 02815 02816 if (numtowrite != 0) { 02817 02818 if (numtowrite > BUFFER_SIZE) { 02819 DEBUG(0,("reply_writebraw: Oversize secondary write raw requested (%u). Terminating\n", 02820 (unsigned int)numtowrite )); 02821 exit_server_cleanly("secondary writebraw failed"); 02822 } 02823 02824 if (tcount > nwritten+numtowrite) { 02825 DEBUG(3,("Client overestimated the write %d %d %d\n", 02826 (int)tcount,(int)nwritten,(int)numtowrite)); 02827 } 02828 02829 if (read_data( smbd_server_fd(), inbuf+4, numtowrite) != numtowrite ) { 02830 DEBUG(0,("reply_writebraw: Oversize secondary write raw read failed (%s). Terminating\n", 02831 strerror(errno) )); 02832 exit_server_cleanly("secondary writebraw failed"); 02833 } 02834 02835 nwritten = write_file(fsp,inbuf+4,startpos+nwritten,numtowrite); 02836 if (nwritten == -1) { 02837 END_PROFILE(SMBwritebraw); 02838 return(UNIXERROR(ERRHRD,ERRdiskfull)); 02839 } 02840 02841 if (nwritten < (ssize_t)numtowrite) { 02842 SCVAL(outbuf,smb_rcls,ERRHRD); 02843 SSVAL(outbuf,smb_err,ERRdiskfull); 02844 } 02845 02846 if (nwritten > 0) 02847 total_written += nwritten; 02848 } 02849 02850 SSVAL(outbuf,smb_vwv0,total_written); 02851 02852 status = sync_file(conn, fsp, write_through); 02853 if (!NT_STATUS_IS_OK(status)) { 02854 DEBUG(5,("reply_writebraw: sync_file for %s returned %s\n", 02855 fsp->fsp_name, nt_errstr(status) )); 02856 END_PROFILE(SMBwritebraw); 02857 return ERROR_NT(status); 02858 } 02859 02860 DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n", 02861 fsp->fnum, (double)startpos, (int)numtowrite,(int)total_written)); 02862 02863 /* we won't return a status if write through is not selected - this follows what WfWg does */ 02864 END_PROFILE(SMBwritebraw); 02865 if (!write_through && total_written==tcount) { 02866 02867 #if RABBIT_PELLET_FIX 02868 /* 02869 * Fix for "rabbit pellet" mode, trigger an early TCP ack by 02870 * sending a SMBkeepalive. Thanks to DaveCB at Sun for this. JRA. 02871 */ 02872 if (!send_keepalive(smbd_server_fd())) 02873 exit_server_cleanly("reply_writebraw: send of keepalive failed"); 02874 #endif 02875 return(-1); 02876 } 02877 02878 return(outsize); 02879 }
int reply_writeunlock | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | size, | |||
int | dum_buffsize | |||
) |
参照先 do_unlock()・file_fsp()・files_struct::fnum・byte_range_lock::fsp・files_struct::fsp_name・is_locked()・nt_errstr()・set_message()・status・sync_file()・WINDOWS_LOCK・write_file()・WRITE_LOCK.
02890 { 02891 ssize_t nwritten = -1; 02892 size_t numtowrite; 02893 SMB_OFF_T startpos; 02894 char *data; 02895 NTSTATUS status = NT_STATUS_OK; 02896 files_struct *fsp = file_fsp(inbuf,smb_vwv0); 02897 int outsize = 0; 02898 START_PROFILE(SMBwriteunlock); 02899 02900 CHECK_FSP(fsp,conn); 02901 if (!CHECK_WRITE(fsp)) { 02902 return(ERROR_DOS(ERRDOS,ERRbadaccess)); 02903 } 02904 02905 numtowrite = SVAL(inbuf,smb_vwv1); 02906 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2); 02907 data = smb_buf(inbuf) + 3; 02908 02909 if (numtowrite && is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { 02910 END_PROFILE(SMBwriteunlock); 02911 return ERROR_DOS(ERRDOS,ERRlock); 02912 } 02913 02914 /* The special X/Open SMB protocol handling of 02915 zero length writes is *NOT* done for 02916 this call */ 02917 if(numtowrite == 0) { 02918 nwritten = 0; 02919 } else { 02920 nwritten = write_file(fsp,data,startpos,numtowrite); 02921 } 02922 02923 status = sync_file(conn, fsp, False /* write through */); 02924 if (!NT_STATUS_IS_OK(status)) { 02925 END_PROFILE(SMBwriteunlock); 02926 DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n", 02927 fsp->fsp_name, nt_errstr(status) )); 02928 return ERROR_NT(status); 02929 } 02930 02931 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { 02932 END_PROFILE(SMBwriteunlock); 02933 return(UNIXERROR(ERRHRD,ERRdiskfull)); 02934 } 02935 02936 if (numtowrite) { 02937 status = do_unlock(fsp, 02938 (uint32)SVAL(inbuf,smb_pid), 02939 (SMB_BIG_UINT)numtowrite, 02940 (SMB_BIG_UINT)startpos, 02941 WINDOWS_LOCK); 02942 02943 if (NT_STATUS_V(status)) { 02944 END_PROFILE(SMBwriteunlock); 02945 return ERROR_NT(status); 02946 } 02947 } 02948 02949 outsize = set_message(outbuf,1,0,True); 02950 02951 SSVAL(outbuf,smb_vwv0,nwritten); 02952 02953 DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n", 02954 fsp->fnum, (int)numtowrite, (int)nwritten)); 02955 02956 END_PROFILE(SMBwriteunlock); 02957 return outsize; 02958 }
int reply_write | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | size, | |||
int | dum_buffsize | |||
) |
参照先 file_fsp()・files_struct::fnum・byte_range_lock::fsp・files_struct::fsp_name・is_locked()・nt_errstr()・reply_pipe_write()・set_message()・status・sync_file()・vfs_allocate_file_space()・vfs_set_filelen()・write_file()・WRITE_LOCK.
02968 { 02969 size_t numtowrite; 02970 ssize_t nwritten = -1; 02971 SMB_OFF_T startpos; 02972 char *data; 02973 files_struct *fsp = file_fsp(inbuf,smb_vwv0); 02974 int outsize = 0; 02975 NTSTATUS status; 02976 START_PROFILE(SMBwrite); 02977 02978 /* If it's an IPC, pass off the pipe handler. */ 02979 if (IS_IPC(conn)) { 02980 END_PROFILE(SMBwrite); 02981 return reply_pipe_write(inbuf,outbuf,size,dum_buffsize); 02982 } 02983 02984 CHECK_FSP(fsp,conn); 02985 if (!CHECK_WRITE(fsp)) { 02986 END_PROFILE(SMBwrite); 02987 return(ERROR_DOS(ERRDOS,ERRbadaccess)); 02988 } 02989 02990 numtowrite = SVAL(inbuf,smb_vwv1); 02991 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2); 02992 data = smb_buf(inbuf) + 3; 02993 02994 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { 02995 END_PROFILE(SMBwrite); 02996 return ERROR_DOS(ERRDOS,ERRlock); 02997 } 02998 02999 /* 03000 * X/Open SMB protocol says that if smb_vwv1 is 03001 * zero then the file size should be extended or 03002 * truncated to the size given in smb_vwv[2-3]. 03003 */ 03004 03005 if(numtowrite == 0) { 03006 /* 03007 * This is actually an allocate call, and set EOF. JRA. 03008 */ 03009 nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos); 03010 if (nwritten < 0) { 03011 END_PROFILE(SMBwrite); 03012 return ERROR_NT(NT_STATUS_DISK_FULL); 03013 } 03014 nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos); 03015 if (nwritten < 0) { 03016 END_PROFILE(SMBwrite); 03017 return ERROR_NT(NT_STATUS_DISK_FULL); 03018 } 03019 } else 03020 nwritten = write_file(fsp,data,startpos,numtowrite); 03021 03022 status = sync_file(conn, fsp, False); 03023 if (!NT_STATUS_IS_OK(status)) { 03024 END_PROFILE(SMBwrite); 03025 DEBUG(5,("reply_write: sync_file for %s returned %s\n", 03026 fsp->fsp_name, nt_errstr(status) )); 03027 return ERROR_NT(status); 03028 } 03029 03030 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { 03031 END_PROFILE(SMBwrite); 03032 return(UNIXERROR(ERRHRD,ERRdiskfull)); 03033 } 03034 03035 outsize = set_message(outbuf,1,0,True); 03036 03037 SSVAL(outbuf,smb_vwv0,nwritten); 03038 03039 if (nwritten < (ssize_t)numtowrite) { 03040 SCVAL(outbuf,smb_rcls,ERRHRD); 03041 SSVAL(outbuf,smb_err,ERRdiskfull); 03042 } 03043 03044 DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten)); 03045 03046 END_PROFILE(SMBwrite); 03047 return(outsize); 03048 }
int reply_write_and_X | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize | |||
) |
参照先 chain_reply()・file_fsp()・files_struct::fnum・byte_range_lock::fsp・files_struct::fsp_name・is_locked()・nt_errstr()・reply_pipe_write_and_X()・schedule_aio_write_and_X()・set_message()・status・sync_file()・write_file()・WRITE_LOCK.
03055 { 03056 files_struct *fsp = file_fsp(inbuf,smb_vwv2); 03057 SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3); 03058 size_t numtowrite = SVAL(inbuf,smb_vwv10); 03059 BOOL write_through = BITSETW(inbuf+smb_vwv7,0); 03060 ssize_t nwritten = -1; 03061 unsigned int smb_doff = SVAL(inbuf,smb_vwv11); 03062 unsigned int smblen = smb_len(inbuf); 03063 char *data; 03064 BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF)); 03065 NTSTATUS status; 03066 START_PROFILE(SMBwriteX); 03067 03068 /* If it's an IPC, pass off the pipe handler. */ 03069 if (IS_IPC(conn)) { 03070 END_PROFILE(SMBwriteX); 03071 return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize); 03072 } 03073 03074 CHECK_FSP(fsp,conn); 03075 if (!CHECK_WRITE(fsp)) { 03076 return(ERROR_DOS(ERRDOS,ERRbadaccess)); 03077 } 03078 03079 set_message(outbuf,6,0,True); 03080 03081 /* Deal with possible LARGE_WRITEX */ 03082 if (large_writeX) { 03083 numtowrite |= ((((size_t)SVAL(inbuf,smb_vwv9)) & 1 )<<16); 03084 } 03085 03086 if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) { 03087 END_PROFILE(SMBwriteX); 03088 return ERROR_DOS(ERRDOS,ERRbadmem); 03089 } 03090 03091 data = smb_base(inbuf) + smb_doff; 03092 03093 if(CVAL(inbuf,smb_wct) == 14) { 03094 #ifdef LARGE_SMB_OFF_T 03095 /* 03096 * This is a large offset (64 bit) write. 03097 */ 03098 startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv12)) << 32); 03099 03100 #else /* !LARGE_SMB_OFF_T */ 03101 03102 /* 03103 * Ensure we haven't been sent a >32 bit offset. 03104 */ 03105 03106 if(IVAL(inbuf,smb_vwv12) != 0) { 03107 DEBUG(0,("reply_write_and_X - large offset (%x << 32) used and we don't support \ 03108 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv12) )); 03109 END_PROFILE(SMBwriteX); 03110 return ERROR_DOS(ERRDOS,ERRbadaccess); 03111 } 03112 03113 #endif /* LARGE_SMB_OFF_T */ 03114 } 03115 03116 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { 03117 END_PROFILE(SMBwriteX); 03118 return ERROR_DOS(ERRDOS,ERRlock); 03119 } 03120 03121 /* X/Open SMB protocol says that, unlike SMBwrite 03122 if the length is zero then NO truncation is 03123 done, just a write of zero. To truncate a file, 03124 use SMBwrite. */ 03125 03126 if(numtowrite == 0) { 03127 nwritten = 0; 03128 } else { 03129 03130 if (schedule_aio_write_and_X(conn, inbuf, outbuf, length, bufsize, 03131 fsp,data,startpos,numtowrite)) { 03132 END_PROFILE(SMBwriteX); 03133 return -1; 03134 } 03135 03136 nwritten = write_file(fsp,data,startpos,numtowrite); 03137 } 03138 03139 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { 03140 END_PROFILE(SMBwriteX); 03141 return(UNIXERROR(ERRHRD,ERRdiskfull)); 03142 } 03143 03144 SSVAL(outbuf,smb_vwv2,nwritten); 03145 if (large_writeX) 03146 SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1); 03147 03148 if (nwritten < (ssize_t)numtowrite) { 03149 SCVAL(outbuf,smb_rcls,ERRHRD); 03150 SSVAL(outbuf,smb_err,ERRdiskfull); 03151 } 03152 03153 DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n", 03154 fsp->fnum, (int)numtowrite, (int)nwritten)); 03155 03156 status = sync_file(conn, fsp, write_through); 03157 if (!NT_STATUS_IS_OK(status)) { 03158 END_PROFILE(SMBwriteX); 03159 DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n", 03160 fsp->fsp_name, nt_errstr(status) )); 03161 return ERROR_NT(status); 03162 } 03163 03164 END_PROFILE(SMBwriteX); 03165 return chain_reply(inbuf,outbuf,length,bufsize); 03166 }
int reply_lseek | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | size, | |||
int | dum_buffsize | |||
) |
参照先 errno・fd_handle::fd・files_struct::fh・file_fsp()・flush_write_cache()・files_struct::fnum・byte_range_lock::fsp・mode・fd_handle::pos・set_message().
03173 { 03174 SMB_OFF_T startpos; 03175 SMB_OFF_T res= -1; 03176 int mode,umode; 03177 int outsize = 0; 03178 files_struct *fsp = file_fsp(inbuf,smb_vwv0); 03179 START_PROFILE(SMBlseek); 03180 03181 CHECK_FSP(fsp,conn); 03182 03183 flush_write_cache(fsp, SEEK_FLUSH); 03184 03185 mode = SVAL(inbuf,smb_vwv1) & 3; 03186 /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */ 03187 startpos = (SMB_OFF_T)IVALS(inbuf,smb_vwv2); 03188 03189 switch (mode) { 03190 case 0: 03191 umode = SEEK_SET; 03192 res = startpos; 03193 break; 03194 case 1: 03195 umode = SEEK_CUR; 03196 res = fsp->fh->pos + startpos; 03197 break; 03198 case 2: 03199 umode = SEEK_END; 03200 break; 03201 default: 03202 umode = SEEK_SET; 03203 res = startpos; 03204 break; 03205 } 03206 03207 if (umode == SEEK_END) { 03208 if((res = SMB_VFS_LSEEK(fsp,fsp->fh->fd,startpos,umode)) == -1) { 03209 if(errno == EINVAL) { 03210 SMB_OFF_T current_pos = startpos; 03211 SMB_STRUCT_STAT sbuf; 03212 03213 if(SMB_VFS_FSTAT(fsp,fsp->fh->fd, &sbuf) == -1) { 03214 END_PROFILE(SMBlseek); 03215 return(UNIXERROR(ERRDOS,ERRnoaccess)); 03216 } 03217 03218 current_pos += sbuf.st_size; 03219 if(current_pos < 0) 03220 res = SMB_VFS_LSEEK(fsp,fsp->fh->fd,0,SEEK_SET); 03221 } 03222 } 03223 03224 if(res == -1) { 03225 END_PROFILE(SMBlseek); 03226 return(UNIXERROR(ERRDOS,ERRnoaccess)); 03227 } 03228 } 03229 03230 fsp->fh->pos = res; 03231 03232 outsize = set_message(outbuf,2,0,True); 03233 SIVAL(outbuf,smb_vwv0,res); 03234 03235 DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n", 03236 fsp->fnum, (double)startpos, (double)res, mode)); 03237 03238 END_PROFILE(SMBlseek); 03239 return(outsize); 03240 }
int reply_flush | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | size, | |||
int | dum_buffsize | |||
) |
参照先 file_fsp()・file_sync_all()・byte_range_lock::fsp・nt_errstr()・set_message()・status・sync_file().
03247 { 03248 int outsize = set_message(outbuf,0,0,False); 03249 uint16 fnum = SVAL(inbuf,smb_vwv0); 03250 files_struct *fsp = file_fsp(inbuf,smb_vwv0); 03251 START_PROFILE(SMBflush); 03252 03253 if (fnum != 0xFFFF) 03254 CHECK_FSP(fsp,conn); 03255 03256 if (!fsp) { 03257 file_sync_all(conn); 03258 } else { 03259 NTSTATUS status = sync_file(conn, fsp, True); 03260 if (!NT_STATUS_IS_OK(status)) { 03261 END_PROFILE(SMBflush); 03262 DEBUG(5,("reply_flush: sync_file for %s returned %s\n", 03263 fsp->fsp_name, nt_errstr(status) )); 03264 return ERROR_NT(status); 03265 } 03266 } 03267 03268 DEBUG(3,("flush\n")); 03269 END_PROFILE(SMBflush); 03270 return(outsize); 03271 }
int reply_exit | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 file_close_pid()・set_message().
03280 { 03281 int outsize; 03282 START_PROFILE(SMBexit); 03283 03284 file_close_pid(SVAL(inbuf,smb_pid),SVAL(inbuf,smb_uid)); 03285 03286 outsize = set_message(outbuf,0,0,False); 03287 03288 DEBUG(3,("exit\n")); 03289 03290 END_PROFILE(SMBexit); 03291 return(outsize); 03292 }
int reply_close | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | size, | |||
int | dum_buffsize | |||
) |
参照先 close_file()・files_struct::conn・convert_time_t_to_timespec()・current_user・fd_handle::fd・files_struct::fh・file_fsp()・files_struct::fnum・byte_range_lock::fsp・fsp_set_pending_modtime()・files_struct::is_directory・NORMAL_CLOSE・connection_struct::num_files_open・reply_pipe_close()・set_message()・srv_make_unix_date3()・status・current_user::vuid・files_struct::vuid.
03300 { 03301 NTSTATUS status = NT_STATUS_OK; 03302 int outsize = 0; 03303 files_struct *fsp = NULL; 03304 START_PROFILE(SMBclose); 03305 03306 outsize = set_message(outbuf,0,0,False); 03307 03308 /* If it's an IPC, pass off to the pipe handler. */ 03309 if (IS_IPC(conn)) { 03310 END_PROFILE(SMBclose); 03311 return reply_pipe_close(conn, inbuf,outbuf); 03312 } 03313 03314 fsp = file_fsp(inbuf,smb_vwv0); 03315 03316 /* 03317 * We can only use CHECK_FSP if we know it's not a directory. 03318 */ 03319 03320 if(!fsp || (fsp->conn != conn) || (fsp->vuid != current_user.vuid)) { 03321 END_PROFILE(SMBclose); 03322 return ERROR_DOS(ERRDOS,ERRbadfid); 03323 } 03324 03325 if(fsp->is_directory) { 03326 /* 03327 * Special case - close NT SMB directory handle. 03328 */ 03329 DEBUG(3,("close directory fnum=%d\n", fsp->fnum)); 03330 status = close_file(fsp,NORMAL_CLOSE); 03331 } else { 03332 /* 03333 * Close ordinary file. 03334 */ 03335 03336 DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n", 03337 fsp->fh->fd, fsp->fnum, 03338 conn->num_files_open)); 03339 03340 /* 03341 * Take care of any time sent in the close. 03342 */ 03343 03344 fsp_set_pending_modtime(fsp, 03345 convert_time_t_to_timespec(srv_make_unix_date3(inbuf+smb_vwv1))); 03346 03347 /* 03348 * close_file() returns the unix errno if an error 03349 * was detected on close - normally this is due to 03350 * a disk full error. If not then it was probably an I/O error. 03351 */ 03352 03353 status = close_file(fsp,NORMAL_CLOSE); 03354 } 03355 03356 if(!NT_STATUS_IS_OK(status)) { 03357 END_PROFILE(SMBclose); 03358 return ERROR_NT(status); 03359 } 03360 03361 END_PROFILE(SMBclose); 03362 return(outsize); 03363 }
int reply_writeclose | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | size, | |||
int | dum_buffsize | |||
) |
参照先 close_file()・convert_time_t_to_timespec()・file_fsp()・is_locked()・NORMAL_CLOSE・connection_struct::num_files_open・set_message()・srv_make_unix_date3()・write_file()・WRITE_LOCK.
03371 { 03372 size_t numtowrite; 03373 ssize_t nwritten = -1; 03374 int outsize = 0; 03375 NTSTATUS close_status = NT_STATUS_OK; 03376 SMB_OFF_T startpos; 03377 char *data; 03378 struct timespec mtime; 03379 files_struct *fsp = file_fsp(inbuf,smb_vwv0); 03380 START_PROFILE(SMBwriteclose); 03381 03382 CHECK_FSP(fsp,conn); 03383 if (!CHECK_WRITE(fsp)) { 03384 return(ERROR_DOS(ERRDOS,ERRbadaccess)); 03385 } 03386 03387 numtowrite = SVAL(inbuf,smb_vwv1); 03388 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2); 03389 mtime = convert_time_t_to_timespec(srv_make_unix_date3(inbuf+smb_vwv4)); 03390 data = smb_buf(inbuf) + 1; 03391 03392 if (numtowrite && is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { 03393 END_PROFILE(SMBwriteclose); 03394 return ERROR_DOS(ERRDOS,ERRlock); 03395 } 03396 03397 nwritten = write_file(fsp,data,startpos,numtowrite); 03398 03399 set_filetime(conn, fsp->fsp_name, mtime); 03400 03401 /* 03402 * More insanity. W2K only closes the file if writelen > 0. 03403 * JRA. 03404 */ 03405 03406 if (numtowrite) { 03407 DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n", 03408 fsp->fsp_name )); 03409 close_status = close_file(fsp,NORMAL_CLOSE); 03410 } 03411 03412 DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n", 03413 fsp->fnum, (int)numtowrite, (int)nwritten, 03414 conn->num_files_open)); 03415 03416 if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { 03417 END_PROFILE(SMBwriteclose); 03418 return(UNIXERROR(ERRHRD,ERRdiskfull)); 03419 } 03420 03421 if(!NT_STATUS_IS_OK(close_status)) { 03422 END_PROFILE(SMBwriteclose); 03423 return ERROR_NT(close_status); 03424 } 03425 03426 outsize = set_message(outbuf,1,0,True); 03427 03428 SSVAL(outbuf,smb_vwv0,nwritten); 03429 END_PROFILE(SMBwriteclose); 03430 return(outsize); 03431 }
int reply_lock | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | dum_buffsize | |||
) |
参照先 do_lock()・fd_handle::fd・files_struct::fh・file_fsp()・files_struct::fnum・byte_range_lock::fsp・release_level_2_oplocks_on_change()・set_message()・status・WINDOWS_LOCK・WRITE_LOCK.
03442 { 03443 int outsize = set_message(outbuf,0,0,False); 03444 SMB_BIG_UINT count,offset; 03445 NTSTATUS status; 03446 files_struct *fsp = file_fsp(inbuf,smb_vwv0); 03447 struct byte_range_lock *br_lck = NULL; 03448 03449 START_PROFILE(SMBlock); 03450 03451 CHECK_FSP(fsp,conn); 03452 03453 release_level_2_oplocks_on_change(fsp); 03454 03455 count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1); 03456 offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3); 03457 03458 DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n", 03459 fsp->fh->fd, fsp->fnum, (double)offset, (double)count)); 03460 03461 br_lck = do_lock(fsp, 03462 (uint32)SVAL(inbuf,smb_pid), 03463 count, 03464 offset, 03465 WRITE_LOCK, 03466 WINDOWS_LOCK, 03467 False, /* Non-blocking lock. */ 03468 &status, 03469 NULL); 03470 03471 TALLOC_FREE(br_lck); 03472 03473 if (NT_STATUS_V(status)) { 03474 END_PROFILE(SMBlock); 03475 return ERROR_NT(status); 03476 } 03477 03478 END_PROFILE(SMBlock); 03479 return(outsize); 03480 }
int reply_unlock | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | size, | |||
int | dum_buffsize | |||
) |
参照先 do_unlock()・fd_handle::fd・files_struct::fh・file_fsp()・files_struct::fnum・byte_range_lock::fsp・set_message()・status・WINDOWS_LOCK.
03488 { 03489 int outsize = set_message(outbuf,0,0,False); 03490 SMB_BIG_UINT count,offset; 03491 NTSTATUS status; 03492 files_struct *fsp = file_fsp(inbuf,smb_vwv0); 03493 START_PROFILE(SMBunlock); 03494 03495 CHECK_FSP(fsp,conn); 03496 03497 count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1); 03498 offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3); 03499 03500 status = do_unlock(fsp, 03501 (uint32)SVAL(inbuf,smb_pid), 03502 count, 03503 offset, 03504 WINDOWS_LOCK); 03505 03506 if (NT_STATUS_V(status)) { 03507 END_PROFILE(SMBunlock); 03508 return ERROR_NT(status); 03509 } 03510 03511 DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n", 03512 fsp->fh->fd, fsp->fnum, (double)offset, (double)count ) ); 03513 03514 END_PROFILE(SMBunlock); 03515 return(outsize); 03516 }
int reply_tdis | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 close_cnum()・set_message()・connection_struct::used.
03528 { 03529 int outsize = set_message(outbuf,0,0,False); 03530 uint16 vuid; 03531 START_PROFILE(SMBtdis); 03532 03533 vuid = SVAL(inbuf,smb_uid); 03534 03535 if (!conn) { 03536 DEBUG(4,("Invalid connection in tdis\n")); 03537 END_PROFILE(SMBtdis); 03538 return ERROR_DOS(ERRSRV,ERRinvnid); 03539 } 03540 03541 conn->used = False; 03542 03543 close_cnum(conn,vuid); 03544 03545 END_PROFILE(SMBtdis); 03546 return outsize; 03547 }
int reply_echo | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 exit_server_cleanly()・send_smb()・set_message()・show_msg()・smb_echo_count・smb_setlen()・smbd_server_fd().
03556 { 03557 int smb_reverb = SVAL(inbuf,smb_vwv0); 03558 int seq_num; 03559 unsigned int data_len = smb_buflen(inbuf); 03560 int outsize = set_message(outbuf,1,data_len,True); 03561 START_PROFILE(SMBecho); 03562 03563 if (data_len > BUFFER_SIZE) { 03564 DEBUG(0,("reply_echo: data_len too large.\n")); 03565 END_PROFILE(SMBecho); 03566 return -1; 03567 } 03568 03569 /* copy any incoming data back out */ 03570 if (data_len > 0) 03571 memcpy(smb_buf(outbuf),smb_buf(inbuf),data_len); 03572 03573 if (smb_reverb > 100) { 03574 DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb)); 03575 smb_reverb = 100; 03576 } 03577 03578 for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) { 03579 SSVAL(outbuf,smb_vwv0,seq_num); 03580 03581 smb_setlen(outbuf,outsize - 4); 03582 03583 show_msg(outbuf); 03584 if (!send_smb(smbd_server_fd(),outbuf)) 03585 exit_server_cleanly("reply_echo: send_smb failed."); 03586 } 03587 03588 DEBUG(3,("echo %d times\n", smb_reverb)); 03589 03590 smb_echo_count++; 03591 03592 END_PROFILE(SMBecho); 03593 return -1; 03594 }
int reply_printopen | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 fd_handle::fd・files_struct::fh・files_struct::fnum・byte_range_lock::fsp・print_fsp_open()・set_message()・status.
03602 { 03603 int outsize = 0; 03604 files_struct *fsp; 03605 NTSTATUS status; 03606 03607 START_PROFILE(SMBsplopen); 03608 03609 if (!CAN_PRINT(conn)) { 03610 END_PROFILE(SMBsplopen); 03611 return ERROR_DOS(ERRDOS,ERRnoaccess); 03612 } 03613 03614 /* Open for exclusive use, write only. */ 03615 status = print_fsp_open(conn, NULL, &fsp); 03616 03617 if (!NT_STATUS_IS_OK(status)) { 03618 END_PROFILE(SMBsplopen); 03619 return(ERROR_NT(status)); 03620 } 03621 03622 outsize = set_message(outbuf,1,0,True); 03623 SSVAL(outbuf,smb_vwv0,fsp->fnum); 03624 03625 DEBUG(3,("openprint fd=%d fnum=%d\n", 03626 fsp->fh->fd, fsp->fnum)); 03627 03628 END_PROFILE(SMBsplopen); 03629 return(outsize); 03630 }
int reply_printclose | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 close_file()・fd_handle::fd・files_struct::fh・file_fsp()・files_struct::fnum・byte_range_lock::fsp・NORMAL_CLOSE・set_message()・status.
03638 { 03639 int outsize = set_message(outbuf,0,0,False); 03640 files_struct *fsp = file_fsp(inbuf,smb_vwv0); 03641 NTSTATUS status; 03642 START_PROFILE(SMBsplclose); 03643 03644 CHECK_FSP(fsp,conn); 03645 03646 if (!CAN_PRINT(conn)) { 03647 END_PROFILE(SMBsplclose); 03648 return ERROR_NT(NT_STATUS_DOS(ERRSRV, ERRerror)); 03649 } 03650 03651 DEBUG(3,("printclose fd=%d fnum=%d\n", 03652 fsp->fh->fd,fsp->fnum)); 03653 03654 status = close_file(fsp,NORMAL_CLOSE); 03655 03656 if(!NT_STATUS_IS_OK(status)) { 03657 END_PROFILE(SMBsplclose); 03658 return ERROR_NT(status); 03659 } 03660 03661 END_PROFILE(SMBsplclose); 03662 return(outsize); 03663 }
int reply_printqueue | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 LPQ_PRINTING・print_queue_status()・set_message()・size・srv_put_dos_date2()・status.
03671 { 03672 int outsize = set_message(outbuf,2,3,True); 03673 int max_count = SVAL(inbuf,smb_vwv0); 03674 int start_index = SVAL(inbuf,smb_vwv1); 03675 START_PROFILE(SMBsplretq); 03676 03677 /* we used to allow the client to get the cnum wrong, but that 03678 is really quite gross and only worked when there was only 03679 one printer - I think we should now only accept it if they 03680 get it right (tridge) */ 03681 if (!CAN_PRINT(conn)) { 03682 END_PROFILE(SMBsplretq); 03683 return ERROR_DOS(ERRDOS,ERRnoaccess); 03684 } 03685 03686 SSVAL(outbuf,smb_vwv0,0); 03687 SSVAL(outbuf,smb_vwv1,0); 03688 SCVAL(smb_buf(outbuf),0,1); 03689 SSVAL(smb_buf(outbuf),1,0); 03690 03691 DEBUG(3,("printqueue start_index=%d max_count=%d\n", 03692 start_index, max_count)); 03693 03694 { 03695 print_queue_struct *queue = NULL; 03696 print_status_struct status; 03697 char *p = smb_buf(outbuf) + 3; 03698 int count = print_queue_status(SNUM(conn), &queue, &status); 03699 int num_to_get = ABS(max_count); 03700 int first = (max_count>0?start_index:start_index+max_count+1); 03701 int i; 03702 03703 if (first >= count) 03704 num_to_get = 0; 03705 else 03706 num_to_get = MIN(num_to_get,count-first); 03707 03708 03709 for (i=first;i<first+num_to_get;i++) { 03710 srv_put_dos_date2(p,0,queue[i].time); 03711 SCVAL(p,4,(queue[i].status==LPQ_PRINTING?2:3)); 03712 SSVAL(p,5, queue[i].job); 03713 SIVAL(p,7,queue[i].size); 03714 SCVAL(p,11,0); 03715 srvstr_push(outbuf, p+12, queue[i].fs_user, 16, STR_ASCII); 03716 p += 28; 03717 } 03718 03719 if (count > 0) { 03720 outsize = set_message(outbuf,2,28*count+3,False); 03721 SSVAL(outbuf,smb_vwv0,count); 03722 SSVAL(outbuf,smb_vwv1,(max_count>0?first+count:first-1)); 03723 SCVAL(smb_buf(outbuf),0,1); 03724 SSVAL(smb_buf(outbuf),1,28*count); 03725 } 03726 03727 SAFE_FREE(queue); 03728 03729 DEBUG(3,("%d entries returned in queue\n",count)); 03730 } 03731 03732 END_PROFILE(SMBsplretq); 03733 return(outsize); 03734 }
int reply_printwrite | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 file_fsp()・files_struct::fnum・byte_range_lock::fsp・set_message()・write_file().
03741 { 03742 int numtowrite; 03743 int outsize = set_message(outbuf,0,0,False); 03744 char *data; 03745 files_struct *fsp = file_fsp(inbuf,smb_vwv0); 03746 03747 START_PROFILE(SMBsplwr); 03748 03749 if (!CAN_PRINT(conn)) { 03750 END_PROFILE(SMBsplwr); 03751 return ERROR_DOS(ERRDOS,ERRnoaccess); 03752 } 03753 03754 CHECK_FSP(fsp,conn); 03755 if (!CHECK_WRITE(fsp)) { 03756 return(ERROR_DOS(ERRDOS,ERRbadaccess)); 03757 } 03758 03759 numtowrite = SVAL(smb_buf(inbuf),1); 03760 data = smb_buf(inbuf) + 3; 03761 03762 if (write_file(fsp,data,-1,numtowrite) != numtowrite) { 03763 END_PROFILE(SMBsplwr); 03764 return(UNIXERROR(ERRHRD,ERRdiskfull)); 03765 } 03766 03767 DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) ); 03768 03769 END_PROFILE(SMBsplwr); 03770 return(outsize); 03771 }
int reply_mkdir | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 check_name()・create_directory()・nt_errstr()・resolve_dfspath()・set_message()・srvstr_get_path()・status・unix_convert()・use_nt_status().
03778 { 03779 pstring directory; 03780 int outsize; 03781 NTSTATUS status; 03782 SMB_STRUCT_STAT sbuf; 03783 03784 START_PROFILE(SMBmkdir); 03785 03786 srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), 0, STR_TERMINATE, &status); 03787 if (!NT_STATUS_IS_OK(status)) { 03788 END_PROFILE(SMBmkdir); 03789 return ERROR_NT(status); 03790 } 03791 03792 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, directory); 03793 if (!NT_STATUS_IS_OK(status)) { 03794 END_PROFILE(SMBmkdir); 03795 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 03796 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 03797 } 03798 return ERROR_NT(status); 03799 } 03800 03801 status = unix_convert(conn, directory, False, NULL, &sbuf); 03802 if (!NT_STATUS_IS_OK(status)) { 03803 END_PROFILE(SMBmkdir); 03804 return ERROR_NT(status); 03805 } 03806 03807 status = check_name(conn, directory); 03808 if (!NT_STATUS_IS_OK(status)) { 03809 END_PROFILE(SMBmkdir); 03810 return ERROR_NT(status); 03811 } 03812 03813 status = create_directory(conn, directory); 03814 03815 DEBUG(5, ("create_directory returned %s\n", nt_errstr(status))); 03816 03817 if (!NT_STATUS_IS_OK(status)) { 03818 03819 if (!use_nt_status() 03820 && NT_STATUS_EQUAL(status, 03821 NT_STATUS_OBJECT_NAME_COLLISION)) { 03822 /* 03823 * Yes, in the DOS error code case we get a 03824 * ERRDOS:ERRnoaccess here. See BASE-SAMBA3ERROR 03825 * samba4 torture test. 03826 */ 03827 status = NT_STATUS_DOS(ERRDOS, ERRnoaccess); 03828 } 03829 03830 END_PROFILE(SMBmkdir); 03831 return ERROR_NT(status); 03832 } 03833 03834 outsize = set_message(outbuf,0,0,False); 03835 03836 DEBUG( 3, ( "mkdir %s ret=%d\n", directory, outsize ) ); 03837 03838 END_PROFILE(SMBmkdir); 03839 return(outsize); 03840 }
static BOOL recursive_rmdir | ( | connection_struct * | conn, | |
char * | directory | |||
) | [static] |
参照先 CloseDir()・smb_Dir::conn・errno・is_visible_file()・OpenDir()・ReadDirName().
参照元 rmdir_internals().
03848 { 03849 const char *dname = NULL; 03850 BOOL ret = True; 03851 long offset = 0; 03852 struct smb_Dir *dir_hnd = OpenDir(conn, directory, NULL, 0); 03853 03854 if(dir_hnd == NULL) 03855 return False; 03856 03857 while((dname = ReadDirName(dir_hnd, &offset))) { 03858 pstring fullname; 03859 SMB_STRUCT_STAT st; 03860 03861 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) 03862 continue; 03863 03864 if (!is_visible_file(conn, directory, dname, &st, False)) 03865 continue; 03866 03867 /* Construct the full name. */ 03868 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) { 03869 errno = ENOMEM; 03870 ret = False; 03871 break; 03872 } 03873 03874 pstrcpy(fullname, directory); 03875 pstrcat(fullname, "/"); 03876 pstrcat(fullname, dname); 03877 03878 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) { 03879 ret = False; 03880 break; 03881 } 03882 03883 if(st.st_mode & S_IFDIR) { 03884 if(!recursive_rmdir(conn, fullname)) { 03885 ret = False; 03886 break; 03887 } 03888 if(SMB_VFS_RMDIR(conn,fullname) != 0) { 03889 ret = False; 03890 break; 03891 } 03892 } else if(SMB_VFS_UNLINK(conn,fullname) != 0) { 03893 ret = False; 03894 break; 03895 } 03896 } 03897 CloseDir(dir_hnd); 03898 return ret; 03899 }
NTSTATUS rmdir_internals | ( | connection_struct * | conn, | |
const char * | directory | |||
) |
参照先 CloseDir()・smb_Dir::conn・err・errno・is_visible_file()・map_nt_error_from_unix()・notify_fname()・OpenDir()・ReadDirName()・recursive_rmdir()・RewindDir()・strerror().
参照元 reply_rmdir().
03906 { 03907 int ret; 03908 SMB_STRUCT_STAT st; 03909 03910 /* Might be a symlink. */ 03911 if(SMB_VFS_LSTAT(conn, directory, &st) != 0) { 03912 return map_nt_error_from_unix(errno); 03913 } 03914 03915 if (S_ISLNK(st.st_mode)) { 03916 /* Is what it points to a directory ? */ 03917 if(SMB_VFS_STAT(conn, directory, &st) != 0) { 03918 return map_nt_error_from_unix(errno); 03919 } 03920 if (!(S_ISDIR(st.st_mode))) { 03921 return NT_STATUS_NOT_A_DIRECTORY; 03922 } 03923 ret = SMB_VFS_UNLINK(conn,directory); 03924 } else { 03925 ret = SMB_VFS_RMDIR(conn,directory); 03926 } 03927 if (ret == 0) { 03928 notify_fname(conn, NOTIFY_ACTION_REMOVED, 03929 FILE_NOTIFY_CHANGE_DIR_NAME, 03930 directory); 03931 return NT_STATUS_OK; 03932 } 03933 03934 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) { 03935 /* 03936 * Check to see if the only thing in this directory are 03937 * vetoed files/directories. If so then delete them and 03938 * retry. If we fail to delete any of them (and we *don't* 03939 * do a recursive delete) then fail the rmdir. 03940 */ 03941 const char *dname; 03942 long dirpos = 0; 03943 struct smb_Dir *dir_hnd = OpenDir(conn, directory, NULL, 0); 03944 03945 if(dir_hnd == NULL) { 03946 errno = ENOTEMPTY; 03947 goto err; 03948 } 03949 03950 while ((dname = ReadDirName(dir_hnd,&dirpos))) { 03951 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) 03952 continue; 03953 if (!is_visible_file(conn, directory, dname, &st, False)) 03954 continue; 03955 if(!IS_VETO_PATH(conn, dname)) { 03956 CloseDir(dir_hnd); 03957 errno = ENOTEMPTY; 03958 goto err; 03959 } 03960 } 03961 03962 /* We only have veto files/directories. Recursive delete. */ 03963 03964 RewindDir(dir_hnd,&dirpos); 03965 while ((dname = ReadDirName(dir_hnd,&dirpos))) { 03966 pstring fullname; 03967 03968 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) 03969 continue; 03970 if (!is_visible_file(conn, directory, dname, &st, False)) 03971 continue; 03972 03973 /* Construct the full name. */ 03974 if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) { 03975 errno = ENOMEM; 03976 break; 03977 } 03978 03979 pstrcpy(fullname, directory); 03980 pstrcat(fullname, "/"); 03981 pstrcat(fullname, dname); 03982 03983 if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) 03984 break; 03985 if(st.st_mode & S_IFDIR) { 03986 if(lp_recursive_veto_delete(SNUM(conn))) { 03987 if(!recursive_rmdir(conn, fullname)) 03988 break; 03989 } 03990 if(SMB_VFS_RMDIR(conn,fullname) != 0) 03991 break; 03992 } else if(SMB_VFS_UNLINK(conn,fullname) != 0) 03993 break; 03994 } 03995 CloseDir(dir_hnd); 03996 /* Retry the rmdir */ 03997 ret = SMB_VFS_RMDIR(conn,directory); 03998 } 03999 04000 err: 04001 04002 if (ret != 0) { 04003 DEBUG(3,("rmdir_internals: couldn't remove directory %s : " 04004 "%s\n", directory,strerror(errno))); 04005 return map_nt_error_from_unix(errno); 04006 } 04007 04008 notify_fname(conn, NOTIFY_ACTION_REMOVED, 04009 FILE_NOTIFY_CHANGE_DIR_NAME, 04010 directory); 04011 04012 return NT_STATUS_OK; 04013 }
int reply_rmdir | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 check_name()・smb_Dir::conn・dptr_closepath()・resolve_dfspath()・rmdir_internals()・set_message()・srvstr_get_path()・status・unix_convert().
04020 { 04021 pstring directory; 04022 int outsize = 0; 04023 SMB_STRUCT_STAT sbuf; 04024 NTSTATUS status; 04025 START_PROFILE(SMBrmdir); 04026 04027 srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), 0, STR_TERMINATE, &status); 04028 if (!NT_STATUS_IS_OK(status)) { 04029 END_PROFILE(SMBrmdir); 04030 return ERROR_NT(status); 04031 } 04032 04033 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, directory); 04034 if (!NT_STATUS_IS_OK(status)) { 04035 END_PROFILE(SMBrmdir); 04036 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 04037 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 04038 } 04039 return ERROR_NT(status); 04040 } 04041 04042 status = unix_convert(conn, directory, False, NULL, &sbuf); 04043 if (!NT_STATUS_IS_OK(status)) { 04044 END_PROFILE(SMBrmdir); 04045 return ERROR_NT(status); 04046 } 04047 04048 status = check_name(conn, directory); 04049 if (!NT_STATUS_IS_OK(status)) { 04050 END_PROFILE(SMBrmdir); 04051 return ERROR_NT(status); 04052 } 04053 04054 dptr_closepath(directory,SVAL(inbuf,smb_pid)); 04055 status = rmdir_internals(conn, directory); 04056 if (!NT_STATUS_IS_OK(status)) { 04057 END_PROFILE(SMBrmdir); 04058 return ERROR_NT(status); 04059 } 04060 04061 outsize = set_message(outbuf,0,0,False); 04062 04063 DEBUG( 3, ( "rmdir %s\n", directory ) ); 04064 04065 END_PROFILE(SMBrmdir); 04066 return(outsize); 04067 }
static BOOL resolve_wildcards | ( | const char * | name1, | |
char * | name2 | |||
) | [static] |
参照先 snprintf()・strrchr_m().
参照元 rename_internals()・reply_copy().
04078 { 04079 pstring root1,root2; 04080 pstring ext1,ext2; 04081 char *p,*p2, *pname1, *pname2; 04082 int available_space, actual_space; 04083 04084 pname1 = strrchr_m(name1,'/'); 04085 pname2 = strrchr_m(name2,'/'); 04086 04087 if (!pname1 || !pname2) 04088 return(False); 04089 04090 pstrcpy(root1,pname1); 04091 pstrcpy(root2,pname2); 04092 p = strrchr_m(root1,'.'); 04093 if (p) { 04094 *p = 0; 04095 pstrcpy(ext1,p+1); 04096 } else { 04097 pstrcpy(ext1,""); 04098 } 04099 p = strrchr_m(root2,'.'); 04100 if (p) { 04101 *p = 0; 04102 pstrcpy(ext2,p+1); 04103 } else { 04104 pstrcpy(ext2,""); 04105 } 04106 04107 p = root1; 04108 p2 = root2; 04109 while (*p2) { 04110 if (*p2 == '?') { 04111 *p2 = *p; 04112 p2++; 04113 } else if (*p2 == '*') { 04114 pstrcpy(p2, p); 04115 break; 04116 } else { 04117 p2++; 04118 } 04119 if (*p) 04120 p++; 04121 } 04122 04123 p = ext1; 04124 p2 = ext2; 04125 while (*p2) { 04126 if (*p2 == '?') { 04127 *p2 = *p; 04128 p2++; 04129 } else if (*p2 == '*') { 04130 pstrcpy(p2, p); 04131 break; 04132 } else { 04133 p2++; 04134 } 04135 if (*p) 04136 p++; 04137 } 04138 04139 available_space = sizeof(pstring) - PTR_DIFF(pname2, name2); 04140 04141 if (ext2[0]) { 04142 actual_space = snprintf(pname2, available_space - 1, "%s.%s", root2, ext2); 04143 if (actual_space >= available_space - 1) { 04144 DEBUG(1,("resolve_wildcards: can't fit resolved name into specified buffer (overrun by %d bytes)\n", 04145 actual_space - available_space)); 04146 } 04147 } else { 04148 pstrcpy_base(pname2, root2, name2); 04149 } 04150 04151 return(True); 04152 }
static void rename_open_files | ( | connection_struct * | conn, | |
struct share_mode_lock * | lck, | |||
SMB_DEV_T | dev, | |||
SMB_INO_T | inode, | |||
const char * | newname | |||
) | [static] |
参照先 smb_Dir::conn・files_struct::conn・connection_struct::connectpath・files_struct::dev・file_find_di_first()・file_find_di_next()・files_struct::fnum・files_struct::fsp_name・files_struct::inode・rename_share_filename()・string_set().
参照元 rename_internals()・rename_internals_fsp().
04161 { 04162 files_struct *fsp; 04163 BOOL did_rename = False; 04164 04165 for(fsp = file_find_di_first(dev, inode); fsp; fsp = file_find_di_next(fsp)) { 04166 /* fsp_name is a relative path under the fsp. To change this for other 04167 sharepaths we need to manipulate relative paths. */ 04168 /* TODO - create the absolute path and manipulate the newname 04169 relative to the sharepath. */ 04170 if (fsp->conn != conn) { 04171 continue; 04172 } 04173 DEBUG(10,("rename_open_files: renaming file fnum %d (dev = %x, inode = %.0f) from %s -> %s\n", 04174 fsp->fnum, (unsigned int)fsp->dev, (double)fsp->inode, 04175 fsp->fsp_name, newname )); 04176 string_set(&fsp->fsp_name, newname); 04177 did_rename = True; 04178 } 04179 04180 if (!did_rename) { 04181 DEBUG(10,("rename_open_files: no open files on dev %x, inode %.0f for %s\n", 04182 (unsigned int)dev, (double)inode, newname )); 04183 } 04184 04185 /* Send messages to all smbd's (not ourself) that the name has changed. */ 04186 rename_share_filename(lck, conn->connectpath, newname); 04187 }
static BOOL rename_path_prefix_equal | ( | const char * | src, | |
const char * | dest | |||
) | [static] |
参照元 rename_internals()・rename_internals_fsp().
04201 { 04202 const char *psrc = src; 04203 const char *pdst = dest; 04204 size_t slen; 04205 04206 if (psrc[0] == '.' && psrc[1] == '/') { 04207 psrc += 2; 04208 } 04209 if (pdst[0] == '.' && pdst[1] == '/') { 04210 pdst += 2; 04211 } 04212 if ((slen = strlen(psrc)) > strlen(pdst)) { 04213 return False; 04214 } 04215 return ((memcmp(psrc, pdst, slen) == 0) && pdst[slen] == '/'); 04216 }
NTSTATUS rename_internals_fsp | ( | connection_struct * | conn, | |
files_struct * | fsp, | |||
pstring | newname, | |||
uint32 | attrs, | |||
BOOL | replace_if_exists | |||
) |
参照先 can_rename()・can_set_delete_on_close()・connection_struct::case_preserve・connection_struct::case_sensitive・check_name()・files_struct::dev・errno・fd_handle::fd・files_struct::fh・files_struct::fsp_name・get_share_mode_lock()・files_struct::initial_delete_on_close・files_struct::inode・map_nt_error_from_unix()・nt_errstr()・fd_handle::private_options・rename_open_files()・rename_path_prefix_equal()・set_allow_initial_delete_on_close()・status・strcsequal()・strequal()・strrchr_m()・unix_convert()・vfs_object_exist().
参照元 smb_file_rename_information().
04223 { 04224 SMB_STRUCT_STAT sbuf; 04225 pstring newname_last_component; 04226 NTSTATUS status = NT_STATUS_OK; 04227 BOOL dest_exists; 04228 struct share_mode_lock *lck = NULL; 04229 04230 ZERO_STRUCT(sbuf); 04231 04232 status = unix_convert(conn, newname, False, newname_last_component, &sbuf); 04233 04234 /* If an error we expect this to be NT_STATUS_OBJECT_PATH_NOT_FOUND */ 04235 04236 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND, status)) { 04237 return status; 04238 } 04239 04240 status = check_name(conn, newname); 04241 if (!NT_STATUS_IS_OK(status)) { 04242 return status; 04243 } 04244 04245 /* Ensure newname contains a '/' */ 04246 if(strrchr_m(newname,'/') == 0) { 04247 pstring tmpstr; 04248 04249 pstrcpy(tmpstr, "./"); 04250 pstrcat(tmpstr, newname); 04251 pstrcpy(newname, tmpstr); 04252 } 04253 04254 /* 04255 * Check for special case with case preserving and not 04256 * case sensitive. If the old last component differs from the original 04257 * last component only by case, then we should allow 04258 * the rename (user is trying to change the case of the 04259 * filename). 04260 */ 04261 04262 if((conn->case_sensitive == False) && (conn->case_preserve == True) && 04263 strequal(newname, fsp->fsp_name)) { 04264 char *p; 04265 pstring newname_modified_last_component; 04266 04267 /* 04268 * Get the last component of the modified name. 04269 * Note that we guarantee that newname contains a '/' 04270 * character above. 04271 */ 04272 p = strrchr_m(newname,'/'); 04273 pstrcpy(newname_modified_last_component,p+1); 04274 04275 if(strcsequal(newname_modified_last_component, 04276 newname_last_component) == False) { 04277 /* 04278 * Replace the modified last component with 04279 * the original. 04280 */ 04281 pstrcpy(p+1, newname_last_component); 04282 } 04283 } 04284 04285 /* 04286 * If the src and dest names are identical - including case, 04287 * don't do the rename, just return success. 04288 */ 04289 04290 if (strcsequal(fsp->fsp_name, newname)) { 04291 DEBUG(3,("rename_internals_fsp: identical names in rename %s - returning success\n", 04292 newname)); 04293 return NT_STATUS_OK; 04294 } 04295 04296 dest_exists = vfs_object_exist(conn,newname,NULL); 04297 04298 if(!replace_if_exists && dest_exists) { 04299 DEBUG(3,("rename_internals_fsp: dest exists doing rename %s -> %s\n", 04300 fsp->fsp_name,newname)); 04301 return NT_STATUS_OBJECT_NAME_COLLISION; 04302 } 04303 04304 /* Ensure we have a valid stat struct for the source. */ 04305 if (fsp->fh->fd != -1) { 04306 if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) == -1) { 04307 return map_nt_error_from_unix(errno); 04308 } 04309 } else { 04310 if (SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf) == -1) { 04311 return map_nt_error_from_unix(errno); 04312 } 04313 } 04314 04315 status = can_rename(conn,fsp->fsp_name,attrs,&sbuf,True); 04316 04317 if (!NT_STATUS_IS_OK(status)) { 04318 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n", 04319 nt_errstr(status), fsp->fsp_name,newname)); 04320 if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION)) 04321 status = NT_STATUS_ACCESS_DENIED; 04322 return status; 04323 } 04324 04325 if (rename_path_prefix_equal(fsp->fsp_name, newname)) { 04326 return NT_STATUS_ACCESS_DENIED; 04327 } 04328 04329 lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL); 04330 04331 if(SMB_VFS_RENAME(conn,fsp->fsp_name, newname) == 0) { 04332 uint32 create_options = fsp->fh->private_options; 04333 04334 DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n", 04335 fsp->fsp_name,newname)); 04336 04337 rename_open_files(conn, lck, fsp->dev, fsp->inode, newname); 04338 04339 /* 04340 * A rename acts as a new file create w.r.t. allowing an initial delete 04341 * on close, probably because in Windows there is a new handle to the 04342 * new file. If initial delete on close was requested but not 04343 * originally set, we need to set it here. This is probably not 100% correct, 04344 * but will work for the CIFSFS client which in non-posix mode 04345 * depends on these semantics. JRA. 04346 */ 04347 04348 set_allow_initial_delete_on_close(lck, fsp, True); 04349 04350 if (create_options & FILE_DELETE_ON_CLOSE) { 04351 status = can_set_delete_on_close(fsp, True, 0); 04352 04353 if (NT_STATUS_IS_OK(status)) { 04354 /* Note that here we set the *inital* delete on close flag, 04355 * not the regular one. The magic gets handled in close. */ 04356 fsp->initial_delete_on_close = True; 04357 } 04358 } 04359 TALLOC_FREE(lck); 04360 return NT_STATUS_OK; 04361 } 04362 04363 TALLOC_FREE(lck); 04364 04365 if (errno == ENOTDIR || errno == EISDIR) { 04366 status = NT_STATUS_OBJECT_NAME_COLLISION; 04367 } else { 04368 status = map_nt_error_from_unix(errno); 04369 } 04370 04371 DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n", 04372 nt_errstr(status), fsp->fsp_name,newname)); 04373 04374 return status; 04375 }
static void notify_rename | ( | connection_struct * | conn, | |
BOOL | is_dir, | |||
const char * | oldpath, | |||
const char * | newpath | |||
) | [static] |
参照先 notify_fname()・parent_dirname_talloc().
参照元 rename_internals().
04383 { 04384 char *olddir, *newdir; 04385 const char *oldname, *newname; 04386 uint32 mask; 04387 04388 mask = is_dir ? FILE_NOTIFY_CHANGE_DIR_NAME 04389 : FILE_NOTIFY_CHANGE_FILE_NAME; 04390 04391 if (!parent_dirname_talloc(NULL, oldpath, &olddir, &oldname) 04392 || !parent_dirname_talloc(NULL, newpath, &newdir, &newname)) { 04393 TALLOC_FREE(olddir); 04394 return; 04395 } 04396 04397 if (strcmp(olddir, newdir) == 0) { 04398 notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask, oldpath); 04399 notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask, newpath); 04400 } 04401 else { 04402 notify_fname(conn, NOTIFY_ACTION_REMOVED, mask, oldpath); 04403 notify_fname(conn, NOTIFY_ACTION_ADDED, mask, newpath); 04404 } 04405 TALLOC_FREE(olddir); 04406 TALLOC_FREE(newdir); 04407 04408 /* this is a strange one. w2k3 gives an additional event for 04409 CHANGE_ATTRIBUTES and CHANGE_CREATION on the new file when renaming 04410 files, but not directories */ 04411 if (!is_dir) { 04412 notify_fname(conn, NOTIFY_ACTION_MODIFIED, 04413 FILE_NOTIFY_CHANGE_ATTRIBUTES 04414 |FILE_NOTIFY_CHANGE_CREATION, 04415 newpath); 04416 } 04417 }
NTSTATUS rename_internals | ( | connection_struct * | conn, | |
pstring | name, | |||
pstring | newname, | |||
uint32 | attrs, | |||
BOOL | replace_if_exists, | |||
BOOL | src_has_wild, | |||
BOOL | dest_has_wild | |||
) |
参照先 can_rename()・connection_struct::case_preserve・connection_struct::case_sensitive・check_name()・CloseDir()・smb_Dir::conn・errno・get_share_mode_lock()・is_visible_file()・mangle_check_cache()・mangle_is_8_3()・mangle_is_mangled()・map_nt_error_from_unix()・mask_match()・notify_rename()・nt_errstr()・smb_Dir::offset・OpenDir()・connection_struct::params・ReadDirName()・rename_open_files()・rename_path_prefix_equal()・resolve_wildcards()・connection_struct::short_case_preserve・status・strcsequal()・strequal()・strrchr_m()・unix_convert()・vfs_file_exist()・vfs_object_exist().
参照元 call_nt_transact_rename()・reply_mv()・reply_ntrename()・smb_file_rename_information().
04431 { 04432 pstring directory; 04433 pstring mask; 04434 pstring last_component_src; 04435 pstring last_component_dest; 04436 char *p; 04437 int count=0; 04438 NTSTATUS status = NT_STATUS_OK; 04439 SMB_STRUCT_STAT sbuf1, sbuf2; 04440 struct share_mode_lock *lck = NULL; 04441 struct smb_Dir *dir_hnd = NULL; 04442 const char *dname; 04443 long offset = 0; 04444 pstring destname; 04445 04446 *directory = *mask = 0; 04447 04448 ZERO_STRUCT(sbuf1); 04449 ZERO_STRUCT(sbuf2); 04450 04451 status = unix_convert(conn, name, src_has_wild, last_component_src, &sbuf1); 04452 if (!NT_STATUS_IS_OK(status)) { 04453 return status; 04454 } 04455 04456 status = unix_convert(conn, newname, dest_has_wild, last_component_dest, &sbuf2); 04457 if (!NT_STATUS_IS_OK(status)) { 04458 return status; 04459 } 04460 04461 /* 04462 * Split the old name into directory and last component 04463 * strings. Note that unix_convert may have stripped off a 04464 * leading ./ from both name and newname if the rename is 04465 * at the root of the share. We need to make sure either both 04466 * name and newname contain a / character or neither of them do 04467 * as this is checked in resolve_wildcards(). 04468 */ 04469 04470 p = strrchr_m(name,'/'); 04471 if (!p) { 04472 pstrcpy(directory,"."); 04473 pstrcpy(mask,name); 04474 } else { 04475 *p = 0; 04476 pstrcpy(directory,name); 04477 pstrcpy(mask,p+1); 04478 *p = '/'; /* Replace needed for exceptional test below. */ 04479 } 04480 04481 /* 04482 * We should only check the mangled cache 04483 * here if unix_convert failed. This means 04484 * that the path in 'mask' doesn't exist 04485 * on the file system and so we need to look 04486 * for a possible mangle. This patch from 04487 * Tine Smukavec <valentin.smukavec@hermes.si>. 04488 */ 04489 04490 if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) { 04491 mangle_check_cache( mask, sizeof(pstring)-1, conn->params ); 04492 } 04493 04494 if (!src_has_wild) { 04495 /* 04496 * No wildcards - just process the one file. 04497 */ 04498 BOOL is_short_name = mangle_is_8_3(name, True, conn->params); 04499 04500 /* Add a terminating '/' to the directory name. */ 04501 pstrcat(directory,"/"); 04502 pstrcat(directory,mask); 04503 04504 /* Ensure newname contains a '/' also */ 04505 if(strrchr_m(newname,'/') == 0) { 04506 pstring tmpstr; 04507 04508 pstrcpy(tmpstr, "./"); 04509 pstrcat(tmpstr, newname); 04510 pstrcpy(newname, tmpstr); 04511 } 04512 04513 DEBUG(3, ("rename_internals: case_sensitive = %d, " 04514 "case_preserve = %d, short case preserve = %d, " 04515 "directory = %s, newname = %s, " 04516 "last_component_dest = %s, is_8_3 = %d\n", 04517 conn->case_sensitive, conn->case_preserve, 04518 conn->short_case_preserve, directory, 04519 newname, last_component_dest, is_short_name)); 04520 04521 /* Ensure the source name is valid for us to access. */ 04522 status = check_name(conn, directory); 04523 if (!NT_STATUS_IS_OK(status)) { 04524 return status; 04525 } 04526 04527 /* The dest name still may have wildcards. */ 04528 if (dest_has_wild) { 04529 if (!resolve_wildcards(directory,newname)) { 04530 DEBUG(6, ("rename_internals: resolve_wildcards %s %s failed\n", 04531 directory,newname)); 04532 return NT_STATUS_NO_MEMORY; 04533 } 04534 } 04535 04536 /* 04537 * Check for special case with case preserving and not 04538 * case sensitive, if directory and newname are identical, 04539 * and the old last component differs from the original 04540 * last component only by case, then we should allow 04541 * the rename (user is trying to change the case of the 04542 * filename). 04543 */ 04544 if((conn->case_sensitive == False) && 04545 (((conn->case_preserve == True) && 04546 (is_short_name == False)) || 04547 ((conn->short_case_preserve == True) && 04548 (is_short_name == True))) && 04549 strcsequal(directory, newname)) { 04550 pstring modified_last_component; 04551 04552 /* 04553 * Get the last component of the modified name. 04554 * Note that we guarantee that newname contains a '/' 04555 * character above. 04556 */ 04557 p = strrchr_m(newname,'/'); 04558 pstrcpy(modified_last_component,p+1); 04559 04560 if(strcsequal(modified_last_component, 04561 last_component_dest) == False) { 04562 /* 04563 * Replace the modified last component with 04564 * the original. 04565 */ 04566 pstrcpy(p+1, last_component_dest); 04567 } 04568 } 04569 04570 /* Ensure the dest name is valid for us to access. */ 04571 status = check_name(conn, newname); 04572 if (!NT_STATUS_IS_OK(status)) { 04573 return status; 04574 } 04575 04576 /* 04577 * The source object must exist. 04578 */ 04579 04580 if (!vfs_object_exist(conn, directory, &sbuf1)) { 04581 DEBUG(3, ("rename_internals: source doesn't exist " 04582 "doing rename %s -> %s\n", 04583 directory,newname)); 04584 04585 if (errno == ENOTDIR || errno == EISDIR 04586 || errno == ENOENT) { 04587 /* 04588 * Must return different errors depending on 04589 * whether the parent directory existed or 04590 * not. 04591 */ 04592 04593 p = strrchr_m(directory, '/'); 04594 if (!p) 04595 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 04596 *p = '\0'; 04597 if (vfs_object_exist(conn, directory, NULL)) 04598 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 04599 return NT_STATUS_OBJECT_PATH_NOT_FOUND; 04600 } 04601 status = map_nt_error_from_unix(errno); 04602 DEBUG(3, ("rename_internals: Error %s rename %s -> " 04603 "%s\n", nt_errstr(status), directory, 04604 newname)); 04605 04606 return status; 04607 } 04608 04609 status = can_rename(conn,directory,attrs,&sbuf1,False); 04610 04611 if (!NT_STATUS_IS_OK(status)) { 04612 DEBUG(3,("rename_internals: Error %s rename %s -> " 04613 "%s\n", nt_errstr(status), directory, 04614 newname)); 04615 return status; 04616 } 04617 04618 /* 04619 * If the src and dest names are identical - including case, 04620 * don't do the rename, just return success. 04621 */ 04622 04623 if (strcsequal(directory, newname)) { 04624 DEBUG(3, ("rename_internals: identical names in " 04625 "rename %s - returning success\n", 04626 directory)); 04627 return NT_STATUS_OK; 04628 } 04629 04630 if(!replace_if_exists && vfs_object_exist(conn,newname,NULL)) { 04631 DEBUG(3,("rename_internals: dest exists doing " 04632 "rename %s -> %s\n", directory, newname)); 04633 return NT_STATUS_OBJECT_NAME_COLLISION; 04634 } 04635 04636 if (rename_path_prefix_equal(directory, newname)) { 04637 return NT_STATUS_SHARING_VIOLATION; 04638 } 04639 04640 lck = get_share_mode_lock(NULL, sbuf1.st_dev, sbuf1.st_ino, 04641 NULL, NULL); 04642 04643 if(SMB_VFS_RENAME(conn,directory, newname) == 0) { 04644 DEBUG(3,("rename_internals: succeeded doing rename " 04645 "on %s -> %s\n", directory, newname)); 04646 rename_open_files(conn, lck, sbuf1.st_dev, 04647 sbuf1.st_ino, newname); 04648 TALLOC_FREE(lck); 04649 notify_rename(conn, S_ISDIR(sbuf1.st_mode), 04650 directory, newname); 04651 return NT_STATUS_OK; 04652 } 04653 04654 TALLOC_FREE(lck); 04655 if (errno == ENOTDIR || errno == EISDIR) { 04656 status = NT_STATUS_OBJECT_NAME_COLLISION; 04657 } else { 04658 status = map_nt_error_from_unix(errno); 04659 } 04660 04661 DEBUG(3,("rename_internals: Error %s rename %s -> %s\n", 04662 nt_errstr(status), directory,newname)); 04663 04664 return status; 04665 } 04666 04667 /* 04668 * Wildcards - process each file that matches. 04669 */ 04670 if (strequal(mask,"????????.???")) { 04671 pstrcpy(mask,"*"); 04672 } 04673 04674 status = check_name(conn, directory); 04675 if (!NT_STATUS_IS_OK(status)) { 04676 return status; 04677 } 04678 04679 dir_hnd = OpenDir(conn, directory, mask, attrs); 04680 if (dir_hnd == NULL) { 04681 return map_nt_error_from_unix(errno); 04682 } 04683 04684 status = NT_STATUS_NO_SUCH_FILE; 04685 /* 04686 * Was status = NT_STATUS_OBJECT_NAME_NOT_FOUND; 04687 * - gentest fix. JRA 04688 */ 04689 04690 while ((dname = ReadDirName(dir_hnd, &offset))) { 04691 pstring fname; 04692 BOOL sysdir_entry = False; 04693 04694 pstrcpy(fname,dname); 04695 04696 /* Quick check for "." and ".." */ 04697 if (fname[0] == '.') { 04698 if (!fname[1] || (fname[1] == '.' && !fname[2])) { 04699 if (attrs & aDIR) { 04700 sysdir_entry = True; 04701 } else { 04702 continue; 04703 } 04704 } 04705 } 04706 04707 if (!is_visible_file(conn, directory, dname, &sbuf1, False)) { 04708 continue; 04709 } 04710 04711 if(!mask_match(fname, mask, conn->case_sensitive)) { 04712 continue; 04713 } 04714 04715 if (sysdir_entry) { 04716 status = NT_STATUS_OBJECT_NAME_INVALID; 04717 break; 04718 } 04719 04720 status = NT_STATUS_ACCESS_DENIED; 04721 slprintf(fname, sizeof(fname)-1, "%s/%s", directory, dname); 04722 04723 /* Ensure the source name is valid for us to access. */ 04724 status = check_name(conn, fname); 04725 if (!NT_STATUS_IS_OK(status)) { 04726 return status; 04727 } 04728 04729 if (!vfs_object_exist(conn, fname, &sbuf1)) { 04730 status = NT_STATUS_OBJECT_NAME_NOT_FOUND; 04731 DEBUG(6, ("rename %s failed. Error %s\n", 04732 fname, nt_errstr(status))); 04733 continue; 04734 } 04735 status = can_rename(conn,fname,attrs,&sbuf1,False); 04736 if (!NT_STATUS_IS_OK(status)) { 04737 DEBUG(6, ("rename %s refused\n", fname)); 04738 continue; 04739 } 04740 pstrcpy(destname,newname); 04741 04742 if (!resolve_wildcards(fname,destname)) { 04743 DEBUG(6, ("resolve_wildcards %s %s failed\n", 04744 fname, destname)); 04745 continue; 04746 } 04747 04748 /* Ensure the dest name is valid for us to access. */ 04749 status = check_name(conn, destname); 04750 if (!NT_STATUS_IS_OK(status)) { 04751 return status; 04752 } 04753 04754 if (strcsequal(fname,destname)) { 04755 DEBUG(3,("rename_internals: identical names " 04756 "in wildcard rename %s - success\n", 04757 fname)); 04758 count++; 04759 status = NT_STATUS_OK; 04760 continue; 04761 } 04762 04763 if (!replace_if_exists && vfs_file_exist(conn,destname, NULL)) { 04764 DEBUG(6,("file_exist %s\n", destname)); 04765 status = NT_STATUS_OBJECT_NAME_COLLISION; 04766 continue; 04767 } 04768 04769 if (rename_path_prefix_equal(fname, destname)) { 04770 return NT_STATUS_SHARING_VIOLATION; 04771 } 04772 04773 lck = get_share_mode_lock(NULL, sbuf1.st_dev, 04774 sbuf1.st_ino, NULL, NULL); 04775 04776 if (!SMB_VFS_RENAME(conn,fname,destname)) { 04777 rename_open_files(conn, lck, sbuf1.st_dev, 04778 sbuf1.st_ino, newname); 04779 count++; 04780 status = NT_STATUS_OK; 04781 } 04782 TALLOC_FREE(lck); 04783 DEBUG(3,("rename_internals: doing rename on %s -> " 04784 "%s\n",fname,destname)); 04785 } 04786 CloseDir(dir_hnd); 04787 04788 if (count == 0 && NT_STATUS_IS_OK(status)) { 04789 status = map_nt_error_from_unix(errno); 04790 } 04791 04792 return status; 04793 }
int reply_mv | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 smb_Dir::conn・name・open_was_deferred()・rename_internals()・resolve_dfspath_wcard()・set_message()・srvstr_get_path_wcard()・status.
04801 { 04802 int outsize = 0; 04803 pstring name; 04804 pstring newname; 04805 char *p; 04806 uint32 attrs = SVAL(inbuf,smb_vwv0); 04807 NTSTATUS status; 04808 BOOL src_has_wcard = False; 04809 BOOL dest_has_wcard = False; 04810 04811 START_PROFILE(SMBmv); 04812 04813 p = smb_buf(inbuf) + 1; 04814 p += srvstr_get_path_wcard(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status, &src_has_wcard); 04815 if (!NT_STATUS_IS_OK(status)) { 04816 END_PROFILE(SMBmv); 04817 return ERROR_NT(status); 04818 } 04819 p++; 04820 p += srvstr_get_path_wcard(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, &dest_has_wcard); 04821 if (!NT_STATUS_IS_OK(status)) { 04822 END_PROFILE(SMBmv); 04823 return ERROR_NT(status); 04824 } 04825 04826 status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, name, &src_has_wcard); 04827 if (!NT_STATUS_IS_OK(status)) { 04828 END_PROFILE(SMBmv); 04829 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 04830 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 04831 } 04832 return ERROR_NT(status); 04833 } 04834 04835 status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newname, &dest_has_wcard); 04836 if (!NT_STATUS_IS_OK(status)) { 04837 END_PROFILE(SMBmv); 04838 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 04839 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 04840 } 04841 return ERROR_NT(status); 04842 } 04843 04844 DEBUG(3,("reply_mv : %s -> %s\n",name,newname)); 04845 04846 status = rename_internals(conn, name, newname, attrs, False, src_has_wcard, dest_has_wcard); 04847 if (!NT_STATUS_IS_OK(status)) { 04848 END_PROFILE(SMBmv); 04849 if (open_was_deferred(SVAL(inbuf,smb_mid))) { 04850 /* We have re-scheduled this call. */ 04851 return -1; 04852 } 04853 return ERROR_NT(status); 04854 } 04855 04856 outsize = set_message(outbuf,0,0,False); 04857 04858 END_PROFILE(SMBmv); 04859 return(outsize); 04860 }
NTSTATUS copy_file | ( | connection_struct * | conn, | |
char * | src, | |||
char * | dest1, | |||
int | ofun, | |||
int | count, | |||
BOOL | target_is_directory | |||
) |
参照先 close_file()・smb_Dir::conn・errno・ERROR_CLOSE・fd_handle::fd・files_struct::fh・fsp_set_pending_modtime()・get_mtimespec()・map_open_params_to_ntcreate()・NORMAL_CLOSE・open_file_ntcreate()・status・strerror()・strrchr_m()・vfs_file_exist()・vfs_transfer_file().
参照元 move_driver_to_download_area()・reply_copy().
04876 { 04877 SMB_STRUCT_STAT src_sbuf, sbuf2; 04878 SMB_OFF_T ret=-1; 04879 files_struct *fsp1,*fsp2; 04880 pstring dest; 04881 uint32 dosattrs; 04882 uint32 new_create_disposition; 04883 NTSTATUS status; 04884 04885 pstrcpy(dest,dest1); 04886 if (target_is_directory) { 04887 char *p = strrchr_m(src,'/'); 04888 if (p) { 04889 p++; 04890 } else { 04891 p = src; 04892 } 04893 pstrcat(dest,"/"); 04894 pstrcat(dest,p); 04895 } 04896 04897 if (!vfs_file_exist(conn,src,&src_sbuf)) { 04898 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 04899 } 04900 04901 if (!target_is_directory && count) { 04902 new_create_disposition = FILE_OPEN; 04903 } else { 04904 if (!map_open_params_to_ntcreate(dest1,0,ofun, 04905 NULL, NULL, &new_create_disposition, NULL)) { 04906 return NT_STATUS_INVALID_PARAMETER; 04907 } 04908 } 04909 04910 status = open_file_ntcreate(conn,src,&src_sbuf, 04911 FILE_GENERIC_READ, 04912 FILE_SHARE_READ|FILE_SHARE_WRITE, 04913 FILE_OPEN, 04914 0, 04915 FILE_ATTRIBUTE_NORMAL, 04916 INTERNAL_OPEN_ONLY, 04917 NULL, &fsp1); 04918 04919 if (!NT_STATUS_IS_OK(status)) { 04920 return status; 04921 } 04922 04923 dosattrs = dos_mode(conn, src, &src_sbuf); 04924 if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1) { 04925 ZERO_STRUCTP(&sbuf2); 04926 } 04927 04928 status = open_file_ntcreate(conn,dest,&sbuf2, 04929 FILE_GENERIC_WRITE, 04930 FILE_SHARE_READ|FILE_SHARE_WRITE, 04931 new_create_disposition, 04932 0, 04933 dosattrs, 04934 INTERNAL_OPEN_ONLY, 04935 NULL, &fsp2); 04936 04937 if (!NT_STATUS_IS_OK(status)) { 04938 close_file(fsp1,ERROR_CLOSE); 04939 return status; 04940 } 04941 04942 if ((ofun&3) == 1) { 04943 if(SMB_VFS_LSEEK(fsp2,fsp2->fh->fd,0,SEEK_END) == -1) { 04944 DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) )); 04945 /* 04946 * Stop the copy from occurring. 04947 */ 04948 ret = -1; 04949 src_sbuf.st_size = 0; 04950 } 04951 } 04952 04953 if (src_sbuf.st_size) { 04954 ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size); 04955 } 04956 04957 close_file(fsp1,NORMAL_CLOSE); 04958 04959 /* Ensure the modtime is set correctly on the destination file. */ 04960 fsp_set_pending_modtime( fsp2, get_mtimespec(&src_sbuf)); 04961 04962 /* 04963 * As we are opening fsp1 read-only we only expect 04964 * an error on close on fsp2 if we are out of space. 04965 * Thus we don't look at the error return from the 04966 * close of fsp1. 04967 */ 04968 status = close_file(fsp2,NORMAL_CLOSE); 04969 04970 if (!NT_STATUS_IS_OK(status)) { 04971 return status; 04972 } 04973 04974 if (ret != (SMB_OFF_T)src_sbuf.st_size) { 04975 return NT_STATUS_DISK_FULL; 04976 } 04977 04978 return NT_STATUS_OK; 04979 }
int reply_copy | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 connection_struct::case_sensitive・check_name()・CloseDir()・connection_struct::cnum・smb_Dir::conn・copy_file()・err・errno・error・flags・is_visible_file()・mangle_check_cache()・mangle_is_mangled()・map_nt_error_from_unix()・mask_match()・name・smb_Dir::offset・OpenDir()・connection_struct::params・ReadDirName()・resolve_dfspath_wcard()・resolve_wildcards()・set_message()・srvstr_get_path_wcard()・status・strequal()・strrchr_m()・unix_convert().
04986 { 04987 int outsize = 0; 04988 pstring name; 04989 pstring directory; 04990 pstring mask,newname; 04991 char *p; 04992 int count=0; 04993 int error = ERRnoaccess; 04994 int err = 0; 04995 int tid2 = SVAL(inbuf,smb_vwv0); 04996 int ofun = SVAL(inbuf,smb_vwv1); 04997 int flags = SVAL(inbuf,smb_vwv2); 04998 BOOL target_is_directory=False; 04999 BOOL source_has_wild = False; 05000 BOOL dest_has_wild = False; 05001 SMB_STRUCT_STAT sbuf1, sbuf2; 05002 NTSTATUS status; 05003 START_PROFILE(SMBcopy); 05004 05005 *directory = *mask = 0; 05006 05007 p = smb_buf(inbuf); 05008 p += srvstr_get_path_wcard(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status, &source_has_wild); 05009 if (!NT_STATUS_IS_OK(status)) { 05010 END_PROFILE(SMBcopy); 05011 return ERROR_NT(status); 05012 } 05013 p += srvstr_get_path_wcard(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, &dest_has_wild); 05014 if (!NT_STATUS_IS_OK(status)) { 05015 END_PROFILE(SMBcopy); 05016 return ERROR_NT(status); 05017 } 05018 05019 DEBUG(3,("reply_copy : %s -> %s\n",name,newname)); 05020 05021 if (tid2 != conn->cnum) { 05022 /* can't currently handle inter share copies XXXX */ 05023 DEBUG(3,("Rejecting inter-share copy\n")); 05024 END_PROFILE(SMBcopy); 05025 return ERROR_DOS(ERRSRV,ERRinvdevice); 05026 } 05027 05028 status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, name, &source_has_wild); 05029 if (!NT_STATUS_IS_OK(status)) { 05030 END_PROFILE(SMBcopy); 05031 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 05032 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 05033 } 05034 return ERROR_NT(status); 05035 } 05036 05037 status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newname, &dest_has_wild); 05038 if (!NT_STATUS_IS_OK(status)) { 05039 END_PROFILE(SMBcopy); 05040 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 05041 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 05042 } 05043 return ERROR_NT(status); 05044 } 05045 05046 status = unix_convert(conn, name, source_has_wild, NULL, &sbuf1); 05047 if (!NT_STATUS_IS_OK(status)) { 05048 END_PROFILE(SMBcopy); 05049 return ERROR_NT(status); 05050 } 05051 05052 status = unix_convert(conn, newname, dest_has_wild, NULL, &sbuf2); 05053 if (!NT_STATUS_IS_OK(status)) { 05054 END_PROFILE(SMBcopy); 05055 return ERROR_NT(status); 05056 } 05057 05058 target_is_directory = VALID_STAT_OF_DIR(sbuf2); 05059 05060 if ((flags&1) && target_is_directory) { 05061 END_PROFILE(SMBcopy); 05062 return ERROR_DOS(ERRDOS,ERRbadfile); 05063 } 05064 05065 if ((flags&2) && !target_is_directory) { 05066 END_PROFILE(SMBcopy); 05067 return ERROR_DOS(ERRDOS,ERRbadpath); 05068 } 05069 05070 if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) { 05071 /* wants a tree copy! XXXX */ 05072 DEBUG(3,("Rejecting tree copy\n")); 05073 END_PROFILE(SMBcopy); 05074 return ERROR_DOS(ERRSRV,ERRerror); 05075 } 05076 05077 p = strrchr_m(name,'/'); 05078 if (!p) { 05079 pstrcpy(directory,"./"); 05080 pstrcpy(mask,name); 05081 } else { 05082 *p = 0; 05083 pstrcpy(directory,name); 05084 pstrcpy(mask,p+1); 05085 } 05086 05087 /* 05088 * We should only check the mangled cache 05089 * here if unix_convert failed. This means 05090 * that the path in 'mask' doesn't exist 05091 * on the file system and so we need to look 05092 * for a possible mangle. This patch from 05093 * Tine Smukavec <valentin.smukavec@hermes.si>. 05094 */ 05095 05096 if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) { 05097 mangle_check_cache( mask, sizeof(pstring)-1, conn->params ); 05098 } 05099 05100 if (!source_has_wild) { 05101 pstrcat(directory,"/"); 05102 pstrcat(directory,mask); 05103 if (dest_has_wild) { 05104 if (!resolve_wildcards(directory,newname)) { 05105 END_PROFILE(SMBcopy); 05106 return ERROR_NT(NT_STATUS_NO_MEMORY); 05107 } 05108 } 05109 05110 status = check_name(conn, directory); 05111 if (!NT_STATUS_IS_OK(status)) { 05112 return ERROR_NT(status); 05113 } 05114 05115 status = check_name(conn, newname); 05116 if (!NT_STATUS_IS_OK(status)) { 05117 return ERROR_NT(status); 05118 } 05119 05120 status = copy_file(conn,directory,newname,ofun, 05121 count,target_is_directory); 05122 05123 if(!NT_STATUS_IS_OK(status)) { 05124 END_PROFILE(SMBcopy); 05125 return ERROR_NT(status); 05126 } else { 05127 count++; 05128 } 05129 } else { 05130 struct smb_Dir *dir_hnd = NULL; 05131 const char *dname; 05132 long offset = 0; 05133 pstring destname; 05134 05135 if (strequal(mask,"????????.???")) 05136 pstrcpy(mask,"*"); 05137 05138 status = check_name(conn, directory); 05139 if (!NT_STATUS_IS_OK(status)) { 05140 return ERROR_NT(status); 05141 } 05142 05143 dir_hnd = OpenDir(conn, directory, mask, 0); 05144 if (dir_hnd == NULL) { 05145 status = map_nt_error_from_unix(errno); 05146 return ERROR_NT(status); 05147 } 05148 05149 error = ERRbadfile; 05150 05151 while ((dname = ReadDirName(dir_hnd, &offset))) { 05152 pstring fname; 05153 pstrcpy(fname,dname); 05154 05155 if (!is_visible_file(conn, directory, dname, &sbuf1, False)) { 05156 continue; 05157 } 05158 05159 if(!mask_match(fname, mask, conn->case_sensitive)) { 05160 continue; 05161 } 05162 05163 error = ERRnoaccess; 05164 slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname); 05165 pstrcpy(destname,newname); 05166 if (!resolve_wildcards(fname,destname)) { 05167 continue; 05168 } 05169 05170 status = check_name(conn, fname); 05171 if (!NT_STATUS_IS_OK(status)) { 05172 CloseDir(dir_hnd); 05173 return ERROR_NT(status); 05174 } 05175 05176 status = check_name(conn, destname); 05177 if (!NT_STATUS_IS_OK(status)) { 05178 CloseDir(dir_hnd); 05179 return ERROR_NT(status); 05180 } 05181 05182 DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname, destname)); 05183 05184 status = copy_file(conn,fname,destname,ofun, 05185 count,target_is_directory); 05186 if (NT_STATUS_IS_OK(status)) { 05187 count++; 05188 } 05189 } 05190 CloseDir(dir_hnd); 05191 } 05192 05193 if (count == 0) { 05194 if(err) { 05195 /* Error on close... */ 05196 errno = err; 05197 END_PROFILE(SMBcopy); 05198 return(UNIXERROR(ERRHRD,ERRgeneral)); 05199 } 05200 05201 END_PROFILE(SMBcopy); 05202 return ERROR_DOS(ERRDOS,error); 05203 } 05204 05205 outsize = set_message(outbuf,1,0,True); 05206 SSVAL(outbuf,smb_vwv0,count); 05207 05208 END_PROFILE(SMBcopy); 05209 return(outsize); 05210 }
int reply_setdir | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 smb_Dir::conn・resolve_dfspath()・set_conn_connectpath()・set_message()・srvstr_get_path()・status・vfs_directory_exist().
05217 { 05218 int snum; 05219 int outsize = 0; 05220 pstring newdir; 05221 NTSTATUS status; 05222 05223 START_PROFILE(pathworks_setdir); 05224 05225 snum = SNUM(conn); 05226 if (!CAN_SETDIR(snum)) { 05227 END_PROFILE(pathworks_setdir); 05228 return ERROR_DOS(ERRDOS,ERRnoaccess); 05229 } 05230 05231 srvstr_get_path(inbuf, newdir, smb_buf(inbuf) + 1, sizeof(newdir), 0, STR_TERMINATE, &status); 05232 if (!NT_STATUS_IS_OK(status)) { 05233 END_PROFILE(pathworks_setdir); 05234 return ERROR_NT(status); 05235 } 05236 05237 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newdir); 05238 if (!NT_STATUS_IS_OK(status)) { 05239 END_PROFILE(pathworks_setdir); 05240 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 05241 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 05242 } 05243 return ERROR_NT(status); 05244 } 05245 05246 if (strlen(newdir) != 0) { 05247 if (!vfs_directory_exist(conn,newdir,NULL)) { 05248 END_PROFILE(pathworks_setdir); 05249 return ERROR_DOS(ERRDOS,ERRbadpath); 05250 } 05251 set_conn_connectpath(conn,newdir); 05252 } 05253 05254 outsize = set_message(outbuf,0,0,False); 05255 SCVAL(outbuf,smb_reh,CVAL(inbuf,smb_reh)); 05256 05257 DEBUG(3,("setdir %s\n", newdir)); 05258 05259 END_PROFILE(pathworks_setdir); 05260 return(outsize); 05261 }
uint32 get_lock_pid | ( | char * | data, | |
int | data_offset, | |||
BOOL | large_file_format | |||
) |
参照元 process_lockingX()・reply_lockingX()・reply_lockingX_error().
05271 { 05272 if(!large_file_format) 05273 return (uint32)SVAL(data,SMB_LPID_OFFSET(data_offset)); 05274 else 05275 return (uint32)SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset)); 05276 }
SMB_BIG_UINT get_lock_count | ( | char * | data, | |
int | data_offset, | |||
BOOL | large_file_format | |||
) |
参照元 process_lockingX()・reply_lockingX()・reply_lockingX_error().
05283 { 05284 SMB_BIG_UINT count = 0; 05285 05286 if(!large_file_format) { 05287 count = (SMB_BIG_UINT)IVAL(data,SMB_LKLEN_OFFSET(data_offset)); 05288 } else { 05289 05290 #if defined(HAVE_LONGLONG) 05291 count = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) | 05292 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset))); 05293 #else /* HAVE_LONGLONG */ 05294 05295 /* 05296 * NT4.x seems to be broken in that it sends large file (64 bit) 05297 * lockingX calls even if the CAP_LARGE_FILES was *not* 05298 * negotiated. For boxes without large unsigned ints truncate the 05299 * lock count by dropping the top 32 bits. 05300 */ 05301 05302 if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) { 05303 DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n", 05304 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)), 05305 (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) )); 05306 SIVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),0); 05307 } 05308 05309 count = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)); 05310 #endif /* HAVE_LONGLONG */ 05311 } 05312 05313 return count; 05314 }
static uint32 map_lock_offset | ( | uint32 | high, | |
uint32 | low | |||
) | [static] |
参照元 get_lock_offset().
05322 { 05323 unsigned int i; 05324 uint32 mask = 0; 05325 uint32 highcopy = high; 05326 05327 /* 05328 * Try and find out how many significant bits there are in high. 05329 */ 05330 05331 for(i = 0; highcopy; i++) 05332 highcopy >>= 1; 05333 05334 /* 05335 * We use 31 bits not 32 here as POSIX 05336 * lock offsets may not be negative. 05337 */ 05338 05339 mask = (~0) << (31 - i); 05340 05341 if(low & mask) 05342 return 0; /* Fail. */ 05343 05344 high <<= (31 - i); 05345 05346 return (high|low); 05347 }
参照先 map_lock_offset()・smb_Dir::offset.
参照元 process_lockingX()・reply_lockingX()・reply_lockingX_error().
05355 { 05356 SMB_BIG_UINT offset = 0; 05357 05358 *err = False; 05359 05360 if(!large_file_format) { 05361 offset = (SMB_BIG_UINT)IVAL(data,SMB_LKOFF_OFFSET(data_offset)); 05362 } else { 05363 05364 #if defined(HAVE_LONGLONG) 05365 offset = (((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) | 05366 ((SMB_BIG_UINT) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset))); 05367 #else /* HAVE_LONGLONG */ 05368 05369 /* 05370 * NT4.x seems to be broken in that it sends large file (64 bit) 05371 * lockingX calls even if the CAP_LARGE_FILES was *not* 05372 * negotiated. For boxes without large unsigned ints mangle the 05373 * lock offset by mapping the top 32 bits onto the lower 32. 05374 */ 05375 05376 if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) { 05377 uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)); 05378 uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)); 05379 uint32 new_low = 0; 05380 05381 if((new_low = map_lock_offset(high, low)) == 0) { 05382 *err = True; 05383 return (SMB_BIG_UINT)-1; 05384 } 05385 05386 DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n", 05387 (unsigned int)high, (unsigned int)low, (unsigned int)new_low )); 05388 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),0); 05389 SIVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),new_low); 05390 } 05391 05392 offset = (SMB_BIG_UINT)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)); 05393 #endif /* HAVE_LONGLONG */ 05394 } 05395 05396 return offset; 05397 }
int reply_lockingX | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize | |||
) |
参照先 blocking_lock_cancel()・chain_reply()・smb_Dir::conn・do_lock()・do_lock_cancel()・do_unlock()・downgrade_oplock()・err・file_fsp()・files_struct::fnum・byte_range_lock::fsp・files_struct::fsp_name・get_lock_count()・get_lock_offset()・get_lock_pid()・smb_Dir::offset・files_struct::oplock_type・push_blocking_lock_request()・READ_LOCK・release_level_2_oplocks_on_change()・remove_oplock()・reply_to_oplock_break_requests()・result・files_struct::sent_oplock_break・set_message()・smb_panic()・status・WINDOWS_LOCK・WRITE_LOCK.
05405 { 05406 files_struct *fsp = file_fsp(inbuf,smb_vwv2); 05407 unsigned char locktype = CVAL(inbuf,smb_vwv3); 05408 unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1); 05409 uint16 num_ulocks = SVAL(inbuf,smb_vwv6); 05410 uint16 num_locks = SVAL(inbuf,smb_vwv7); 05411 SMB_BIG_UINT count = 0, offset = 0; 05412 uint32 lock_pid; 05413 int32 lock_timeout = IVAL(inbuf,smb_vwv4); 05414 int i; 05415 char *data; 05416 BOOL large_file_format = 05417 (locktype & LOCKING_ANDX_LARGE_FILES)?True:False; 05418 BOOL err; 05419 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 05420 05421 START_PROFILE(SMBlockingX); 05422 05423 CHECK_FSP(fsp,conn); 05424 05425 data = smb_buf(inbuf); 05426 05427 if (locktype & LOCKING_ANDX_CHANGE_LOCKTYPE) { 05428 /* we don't support these - and CANCEL_LOCK makes w2k 05429 and XP reboot so I don't really want to be 05430 compatible! (tridge) */ 05431 return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks)); 05432 } 05433 05434 /* Check if this is an oplock break on a file 05435 we have granted an oplock on. 05436 */ 05437 if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) { 05438 /* Client can insist on breaking to none. */ 05439 BOOL break_to_none = (oplocklevel == 0); 05440 BOOL result; 05441 05442 DEBUG(5,("reply_lockingX: oplock break reply (%u) from client " 05443 "for fnum = %d\n", (unsigned int)oplocklevel, 05444 fsp->fnum )); 05445 05446 /* 05447 * Make sure we have granted an exclusive or batch oplock on 05448 * this file. 05449 */ 05450 05451 if (fsp->oplock_type == 0) { 05452 05453 /* The Samba4 nbench simulator doesn't understand 05454 the difference between break to level2 and break 05455 to none from level2 - it sends oplock break 05456 replies in both cases. Don't keep logging an error 05457 message here - just ignore it. JRA. */ 05458 05459 DEBUG(5,("reply_lockingX: Error : oplock break from " 05460 "client for fnum = %d (oplock=%d) and no " 05461 "oplock granted on this file (%s).\n", 05462 fsp->fnum, fsp->oplock_type, fsp->fsp_name)); 05463 05464 /* if this is a pure oplock break request then don't 05465 * send a reply */ 05466 if (num_locks == 0 && num_ulocks == 0) { 05467 END_PROFILE(SMBlockingX); 05468 return -1; 05469 } else { 05470 END_PROFILE(SMBlockingX); 05471 return ERROR_DOS(ERRDOS,ERRlock); 05472 } 05473 } 05474 05475 if ((fsp->sent_oplock_break == BREAK_TO_NONE_SENT) || 05476 (break_to_none)) { 05477 result = remove_oplock(fsp); 05478 } else { 05479 result = downgrade_oplock(fsp); 05480 } 05481 05482 if (!result) { 05483 DEBUG(0, ("reply_lockingX: error in removing " 05484 "oplock on file %s\n", fsp->fsp_name)); 05485 /* Hmmm. Is this panic justified? */ 05486 smb_panic("internal tdb error"); 05487 } 05488 05489 reply_to_oplock_break_requests(fsp); 05490 05491 /* if this is a pure oplock break request then don't send a 05492 * reply */ 05493 if (num_locks == 0 && num_ulocks == 0) { 05494 /* Sanity check - ensure a pure oplock break is not a 05495 chained request. */ 05496 if(CVAL(inbuf,smb_vwv0) != 0xff) 05497 DEBUG(0,("reply_lockingX: Error : pure oplock " 05498 "break is a chained %d request !\n", 05499 (unsigned int)CVAL(inbuf,smb_vwv0) )); 05500 END_PROFILE(SMBlockingX); 05501 return -1; 05502 } 05503 } 05504 05505 /* 05506 * We do this check *after* we have checked this is not a oplock break 05507 * response message. JRA. 05508 */ 05509 05510 release_level_2_oplocks_on_change(fsp); 05511 05512 /* Data now points at the beginning of the list 05513 of smb_unlkrng structs */ 05514 for(i = 0; i < (int)num_ulocks; i++) { 05515 lock_pid = get_lock_pid( data, i, large_file_format); 05516 count = get_lock_count( data, i, large_file_format); 05517 offset = get_lock_offset( data, i, large_file_format, &err); 05518 05519 /* 05520 * There is no error code marked "stupid client bug".... :-). 05521 */ 05522 if(err) { 05523 END_PROFILE(SMBlockingX); 05524 return ERROR_DOS(ERRDOS,ERRnoaccess); 05525 } 05526 05527 DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for " 05528 "pid %u, file %s\n", (double)offset, (double)count, 05529 (unsigned int)lock_pid, fsp->fsp_name )); 05530 05531 status = do_unlock(fsp, 05532 lock_pid, 05533 count, 05534 offset, 05535 WINDOWS_LOCK); 05536 05537 if (NT_STATUS_V(status)) { 05538 END_PROFILE(SMBlockingX); 05539 return ERROR_NT(status); 05540 } 05541 } 05542 05543 /* Setup the timeout in seconds. */ 05544 05545 if (!lp_blocking_locks(SNUM(conn))) { 05546 lock_timeout = 0; 05547 } 05548 05549 /* Now do any requested locks */ 05550 data += ((large_file_format ? 20 : 10)*num_ulocks); 05551 05552 /* Data now points at the beginning of the list 05553 of smb_lkrng structs */ 05554 05555 for(i = 0; i < (int)num_locks; i++) { 05556 enum brl_type lock_type = ((locktype & LOCKING_ANDX_SHARED_LOCK) ? 05557 READ_LOCK:WRITE_LOCK); 05558 lock_pid = get_lock_pid( data, i, large_file_format); 05559 count = get_lock_count( data, i, large_file_format); 05560 offset = get_lock_offset( data, i, large_file_format, &err); 05561 05562 /* 05563 * There is no error code marked "stupid client bug".... :-). 05564 */ 05565 if(err) { 05566 END_PROFILE(SMBlockingX); 05567 return ERROR_DOS(ERRDOS,ERRnoaccess); 05568 } 05569 05570 DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid " 05571 "%u, file %s timeout = %d\n", (double)offset, 05572 (double)count, (unsigned int)lock_pid, 05573 fsp->fsp_name, (int)lock_timeout )); 05574 05575 if (locktype & LOCKING_ANDX_CANCEL_LOCK) { 05576 if (lp_blocking_locks(SNUM(conn))) { 05577 05578 /* Schedule a message to ourselves to 05579 remove the blocking lock record and 05580 return the right error. */ 05581 05582 if (!blocking_lock_cancel(fsp, 05583 lock_pid, 05584 offset, 05585 count, 05586 WINDOWS_LOCK, 05587 locktype, 05588 NT_STATUS_FILE_LOCK_CONFLICT)) { 05589 END_PROFILE(SMBlockingX); 05590 return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRcancelviolation)); 05591 } 05592 } 05593 /* Remove a matching pending lock. */ 05594 status = do_lock_cancel(fsp, 05595 lock_pid, 05596 count, 05597 offset, 05598 WINDOWS_LOCK); 05599 } else { 05600 BOOL blocking_lock = lock_timeout ? True : False; 05601 BOOL defer_lock = False; 05602 struct byte_range_lock *br_lck; 05603 uint32 block_smbpid; 05604 05605 br_lck = do_lock(fsp, 05606 lock_pid, 05607 count, 05608 offset, 05609 lock_type, 05610 WINDOWS_LOCK, 05611 blocking_lock, 05612 &status, 05613 &block_smbpid); 05614 05615 if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) { 05616 /* Windows internal resolution for blocking locks seems 05617 to be about 200ms... Don't wait for less than that. JRA. */ 05618 if (lock_timeout != -1 && lock_timeout < lp_lock_spin_time()) { 05619 lock_timeout = lp_lock_spin_time(); 05620 } 05621 defer_lock = True; 05622 } 05623 05624 /* This heuristic seems to match W2K3 very well. If a 05625 lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT 05626 it pretends we asked for a timeout of between 150 - 300 milliseconds as 05627 far as I can tell. Replacement for do_lock_spin(). JRA. */ 05628 05629 if (br_lck && lp_blocking_locks(SNUM(conn)) && !blocking_lock && 05630 NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT)) { 05631 defer_lock = True; 05632 lock_timeout = lp_lock_spin_time(); 05633 } 05634 05635 if (br_lck && defer_lock) { 05636 /* 05637 * A blocking lock was requested. Package up 05638 * this smb into a queued request and push it 05639 * onto the blocking lock queue. 05640 */ 05641 if(push_blocking_lock_request(br_lck, 05642 inbuf, length, 05643 fsp, 05644 lock_timeout, 05645 i, 05646 lock_pid, 05647 lock_type, 05648 WINDOWS_LOCK, 05649 offset, 05650 count, 05651 block_smbpid)) { 05652 TALLOC_FREE(br_lck); 05653 END_PROFILE(SMBlockingX); 05654 return -1; 05655 } 05656 } 05657 05658 TALLOC_FREE(br_lck); 05659 } 05660 05661 if (NT_STATUS_V(status)) { 05662 END_PROFILE(SMBlockingX); 05663 return ERROR_NT(status); 05664 } 05665 } 05666 05667 /* If any of the above locks failed, then we must unlock 05668 all of the previous locks (X/Open spec). */ 05669 05670 if (!(locktype & LOCKING_ANDX_CANCEL_LOCK) && 05671 (i != num_locks) && 05672 (num_locks != 0)) { 05673 /* 05674 * Ensure we don't do a remove on the lock that just failed, 05675 * as under POSIX rules, if we have a lock already there, we 05676 * will delete it (and we shouldn't) ..... 05677 */ 05678 for(i--; i >= 0; i--) { 05679 lock_pid = get_lock_pid( data, i, large_file_format); 05680 count = get_lock_count( data, i, large_file_format); 05681 offset = get_lock_offset( data, i, large_file_format, 05682 &err); 05683 05684 /* 05685 * There is no error code marked "stupid client 05686 * bug".... :-). 05687 */ 05688 if(err) { 05689 END_PROFILE(SMBlockingX); 05690 return ERROR_DOS(ERRDOS,ERRnoaccess); 05691 } 05692 05693 do_unlock(fsp, 05694 lock_pid, 05695 count, 05696 offset, 05697 WINDOWS_LOCK); 05698 } 05699 END_PROFILE(SMBlockingX); 05700 return ERROR_NT(status); 05701 } 05702 05703 set_message(outbuf,2,0,True); 05704 05705 DEBUG(3, ("lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n", 05706 fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks)); 05707 05708 END_PROFILE(SMBlockingX); 05709 return chain_reply(inbuf,outbuf,length,bufsize); 05710 }
int reply_readbmpx | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize | |||
) |
参照先 exit_server_cleanly()・file_fsp()・byte_range_lock::fsp・is_locked()・read_file()・READ_LOCK・send_smb()・set_message()・show_msg()・smbd_server_fd().
05720 { 05721 ssize_t nread = -1; 05722 ssize_t total_read; 05723 char *data; 05724 SMB_OFF_T startpos; 05725 int outsize; 05726 size_t maxcount; 05727 int max_per_packet; 05728 size_t tcount; 05729 int pad; 05730 files_struct *fsp = file_fsp(inbuf,smb_vwv0); 05731 START_PROFILE(SMBreadBmpx); 05732 05733 /* this function doesn't seem to work - disable by default */ 05734 if (!lp_readbmpx()) { 05735 END_PROFILE(SMBreadBmpx); 05736 return ERROR_DOS(ERRSRV,ERRuseSTD); 05737 } 05738 05739 outsize = set_message(outbuf,8,0,True); 05740 05741 CHECK_FSP(fsp,conn); 05742 if (!CHECK_READ(fsp,inbuf)) { 05743 return(ERROR_DOS(ERRDOS,ERRbadaccess)); 05744 } 05745 05746 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1); 05747 maxcount = SVAL(inbuf,smb_vwv3); 05748 05749 data = smb_buf(outbuf); 05750 pad = ((long)data)%4; 05751 if (pad) 05752 pad = 4 - pad; 05753 data += pad; 05754 05755 max_per_packet = bufsize-(outsize+pad); 05756 tcount = maxcount; 05757 total_read = 0; 05758 05759 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) { 05760 END_PROFILE(SMBreadBmpx); 05761 return ERROR_DOS(ERRDOS,ERRlock); 05762 } 05763 05764 do { 05765 size_t N = MIN(max_per_packet,tcount-total_read); 05766 05767 nread = read_file(fsp,data,startpos,N); 05768 05769 if (nread <= 0) 05770 nread = 0; 05771 05772 if (nread < (ssize_t)N) 05773 tcount = total_read + nread; 05774 05775 set_message(outbuf,8,nread+pad,False); 05776 SIVAL(outbuf,smb_vwv0,startpos); 05777 SSVAL(outbuf,smb_vwv2,tcount); 05778 SSVAL(outbuf,smb_vwv6,nread); 05779 SSVAL(outbuf,smb_vwv7,smb_offset(data,outbuf)); 05780 05781 show_msg(outbuf); 05782 if (!send_smb(smbd_server_fd(),outbuf)) 05783 exit_server_cleanly("reply_readbmpx: send_smb failed."); 05784 05785 total_read += nread; 05786 startpos += nread; 05787 } while (total_read < (ssize_t)tcount); 05788 05789 END_PROFILE(SMBreadBmpx); 05790 return(-1); 05791 }
int reply_setattrE | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | size, | |||
int | dum_buffsize | |||
) |
参照先 files_struct::conn・convert_time_t_to_timespec()・dbgtext()・file_fsp()・files_struct::fnum・files_struct::fsp_name・null_timespec()・set_message()・srv_make_unix_date2().
05798 { 05799 struct timespec ts[2]; 05800 int outsize = 0; 05801 files_struct *fsp = file_fsp(inbuf,smb_vwv0); 05802 START_PROFILE(SMBsetattrE); 05803 05804 outsize = set_message(outbuf,0,0,False); 05805 05806 if(!fsp || (fsp->conn != conn)) { 05807 END_PROFILE(SMBsetattrE); 05808 return ERROR_DOS(ERRDOS,ERRbadfid); 05809 } 05810 05811 /* 05812 * Convert the DOS times into unix times. Ignore create 05813 * time as UNIX can't set this. 05814 */ 05815 05816 ts[0] = convert_time_t_to_timespec(srv_make_unix_date2(inbuf+smb_vwv3)); /* atime. */ 05817 ts[1] = convert_time_t_to_timespec(srv_make_unix_date2(inbuf+smb_vwv5)); /* mtime. */ 05818 05819 /* 05820 * Patch from Ray Frush <frush@engr.colostate.edu> 05821 * Sometimes times are sent as zero - ignore them. 05822 */ 05823 05824 if (null_timespec(ts[0]) && null_timespec(ts[1])) { 05825 /* Ignore request */ 05826 if( DEBUGLVL( 3 ) ) { 05827 dbgtext( "reply_setattrE fnum=%d ", fsp->fnum); 05828 dbgtext( "ignoring zero request - not setting timestamps of 0\n" ); 05829 } 05830 END_PROFILE(SMBsetattrE); 05831 return(outsize); 05832 } else if (!null_timespec(ts[0]) && null_timespec(ts[1])) { 05833 /* set modify time = to access time if modify time was unset */ 05834 ts[1] = ts[0]; 05835 } 05836 05837 /* Set the date on this file */ 05838 /* Should we set pending modtime here ? JRA */ 05839 if(file_ntimes(conn, fsp->fsp_name, ts)) { 05840 END_PROFILE(SMBsetattrE); 05841 return ERROR_DOS(ERRDOS,ERRnoaccess); 05842 } 05843 05844 DEBUG( 3, ( "reply_setattrE fnum=%d actime=%u modtime=%u\n", 05845 fsp->fnum, 05846 (unsigned int)ts[0].tv_sec, 05847 (unsigned int)ts[1].tv_sec)); 05848 05849 END_PROFILE(SMBsetattrE); 05850 return(outsize); 05851 }
int reply_writebmpx | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | size, | |||
int | dum_buffsize | |||
) |
参照先 exit_server_cleanly()・file_fsp()・files_struct::fnum・files_struct::fsp_name・is_locked()・nt_errstr()・send_smb()・set_message()・show_msg()・smb_setlen()・smbd_server_fd()・status・sync_file()・files_struct::wbmpx_ptr・write_bmpx_struct::wr_discard・write_bmpx_struct::wr_errclass・write_bmpx_struct::wr_error・write_bmpx_struct::wr_mode・write_bmpx_struct::wr_total_written・write_file()・WRITE_LOCK.
05861 { 05862 size_t numtowrite; 05863 ssize_t nwritten = -1; 05864 int outsize = 0; 05865 SMB_OFF_T startpos; 05866 size_t tcount; 05867 BOOL write_through; 05868 int smb_doff; 05869 char *data; 05870 files_struct *fsp = file_fsp(inbuf,smb_vwv0); 05871 NTSTATUS status; 05872 START_PROFILE(SMBwriteBmpx); 05873 05874 CHECK_FSP(fsp,conn); 05875 if (!CHECK_WRITE(fsp)) { 05876 return(ERROR_DOS(ERRDOS,ERRbadaccess)); 05877 } 05878 if (HAS_CACHED_ERROR(fsp)) { 05879 return(CACHED_ERROR(fsp)); 05880 } 05881 05882 tcount = SVAL(inbuf,smb_vwv1); 05883 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3); 05884 write_through = BITSETW(inbuf+smb_vwv7,0); 05885 numtowrite = SVAL(inbuf,smb_vwv10); 05886 smb_doff = SVAL(inbuf,smb_vwv11); 05887 05888 data = smb_base(inbuf) + smb_doff; 05889 05890 /* If this fails we need to send an SMBwriteC response, 05891 not an SMBwritebmpx - set this up now so we don't forget */ 05892 SCVAL(outbuf,smb_com,SMBwritec); 05893 05894 if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK)) { 05895 END_PROFILE(SMBwriteBmpx); 05896 return(ERROR_DOS(ERRDOS,ERRlock)); 05897 } 05898 05899 nwritten = write_file(fsp,data,startpos,numtowrite); 05900 05901 status = sync_file(conn, fsp, write_through); 05902 if (!NT_STATUS_IS_OK(status)) { 05903 END_PROFILE(SMBwriteBmpx); 05904 DEBUG(5,("reply_writebmpx: sync_file for %s returned %s\n", 05905 fsp->fsp_name, nt_errstr(status) )); 05906 return ERROR_NT(status); 05907 } 05908 05909 if(nwritten < (ssize_t)numtowrite) { 05910 END_PROFILE(SMBwriteBmpx); 05911 return(UNIXERROR(ERRHRD,ERRdiskfull)); 05912 } 05913 05914 /* If the maximum to be written to this file 05915 is greater than what we just wrote then set 05916 up a secondary struct to be attached to this 05917 fd, we will use this to cache error messages etc. */ 05918 05919 if((ssize_t)tcount > nwritten) { 05920 write_bmpx_struct *wbms; 05921 if(fsp->wbmpx_ptr != NULL) 05922 wbms = fsp->wbmpx_ptr; /* Use an existing struct */ 05923 else 05924 wbms = SMB_MALLOC_P(write_bmpx_struct); 05925 if(!wbms) { 05926 DEBUG(0,("Out of memory in reply_readmpx\n")); 05927 END_PROFILE(SMBwriteBmpx); 05928 return(ERROR_DOS(ERRSRV,ERRnoresource)); 05929 } 05930 wbms->wr_mode = write_through; 05931 wbms->wr_discard = False; /* No errors yet */ 05932 wbms->wr_total_written = nwritten; 05933 wbms->wr_errclass = 0; 05934 wbms->wr_error = 0; 05935 fsp->wbmpx_ptr = wbms; 05936 } 05937 05938 /* We are returning successfully, set the message type back to 05939 SMBwritebmpx */ 05940 SCVAL(outbuf,smb_com,SMBwriteBmpx); 05941 05942 outsize = set_message(outbuf,1,0,True); 05943 05944 SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */ 05945 05946 DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n", 05947 fsp->fnum, (int)numtowrite, (int)nwritten ) ); 05948 05949 if (write_through && tcount==nwritten) { 05950 /* We need to send both a primary and a secondary response */ 05951 smb_setlen(outbuf,outsize - 4); 05952 show_msg(outbuf); 05953 if (!send_smb(smbd_server_fd(),outbuf)) 05954 exit_server_cleanly("reply_writebmpx: send_smb failed."); 05955 05956 /* Now the secondary */ 05957 outsize = set_message(outbuf,1,0,True); 05958 SCVAL(outbuf,smb_com,SMBwritec); 05959 SSVAL(outbuf,smb_vwv0,nwritten); 05960 } 05961 05962 END_PROFILE(SMBwriteBmpx); 05963 return(outsize); 05964 }
int reply_writebs | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 file_fsp()・set_message()・status・sync_file()・files_struct::wbmpx_ptr・write_bmpx_struct::wr_discard・write_bmpx_struct::wr_errclass・write_bmpx_struct::wr_error・write_bmpx_struct::wr_mode・write_bmpx_struct::wr_status・write_bmpx_struct::wr_total_written・write_file().
05971 { 05972 size_t numtowrite; 05973 ssize_t nwritten = -1; 05974 int outsize = 0; 05975 SMB_OFF_T startpos; 05976 size_t tcount; 05977 BOOL write_through; 05978 int smb_doff; 05979 char *data; 05980 write_bmpx_struct *wbms; 05981 BOOL send_response = False; 05982 files_struct *fsp = file_fsp(inbuf,smb_vwv0); 05983 NTSTATUS status; 05984 START_PROFILE(SMBwriteBs); 05985 05986 CHECK_FSP(fsp,conn); 05987 if (!CHECK_WRITE(fsp)) { 05988 return(ERROR_DOS(ERRDOS,ERRbadaccess)); 05989 } 05990 05991 tcount = SVAL(inbuf,smb_vwv1); 05992 startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2); 05993 numtowrite = SVAL(inbuf,smb_vwv6); 05994 smb_doff = SVAL(inbuf,smb_vwv7); 05995 05996 data = smb_base(inbuf) + smb_doff; 05997 05998 /* We need to send an SMBwriteC response, not an SMBwritebs */ 05999 SCVAL(outbuf,smb_com,SMBwritec); 06000 06001 /* This fd should have an auxiliary struct attached, 06002 check that it does */ 06003 wbms = fsp->wbmpx_ptr; 06004 if(!wbms) { 06005 END_PROFILE(SMBwriteBs); 06006 return(-1); 06007 } 06008 06009 /* If write through is set we can return errors, else we must cache them */ 06010 write_through = wbms->wr_mode; 06011 06012 /* Check for an earlier error */ 06013 if(wbms->wr_discard) { 06014 END_PROFILE(SMBwriteBs); 06015 return -1; /* Just discard the packet */ 06016 } 06017 06018 nwritten = write_file(fsp,data,startpos,numtowrite); 06019 06020 status = sync_file(conn, fsp, write_through); 06021 06022 if (nwritten < (ssize_t)numtowrite || !NT_STATUS_IS_OK(status)) { 06023 if(write_through) { 06024 /* We are returning an error - we can delete the aux struct */ 06025 if (wbms) 06026 free((char *)wbms); 06027 fsp->wbmpx_ptr = NULL; 06028 END_PROFILE(SMBwriteBs); 06029 return(ERROR_DOS(ERRHRD,ERRdiskfull)); 06030 } 06031 wbms->wr_errclass = ERRHRD; 06032 wbms->wr_error = ERRdiskfull; 06033 wbms->wr_status = NT_STATUS_DISK_FULL; 06034 wbms->wr_discard = True; 06035 END_PROFILE(SMBwriteBs); 06036 return -1; 06037 } 06038 06039 /* Increment the total written, if this matches tcount 06040 we can discard the auxiliary struct (hurrah !) and return a writeC */ 06041 wbms->wr_total_written += nwritten; 06042 if(wbms->wr_total_written >= tcount) { 06043 if (write_through) { 06044 outsize = set_message(outbuf,1,0,True); 06045 SSVAL(outbuf,smb_vwv0,wbms->wr_total_written); 06046 send_response = True; 06047 } 06048 06049 free((char *)wbms); 06050 fsp->wbmpx_ptr = NULL; 06051 } 06052 06053 if(send_response) { 06054 END_PROFILE(SMBwriteBs); 06055 return(outsize); 06056 } 06057 06058 END_PROFILE(SMBwriteBs); 06059 return(-1); 06060 }
int reply_getattrE | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | size, | |||
int | dum_buffsize | |||
) |
参照先 files_struct::conn・file_fsp()・files_struct::fnum・files_struct::fsp_name・fsp_stat()・get_allocation_size()・get_create_time()・mode・set_message()・srv_put_dos_date2().
06067 { 06068 SMB_STRUCT_STAT sbuf; 06069 int outsize = 0; 06070 int mode; 06071 files_struct *fsp = file_fsp(inbuf,smb_vwv0); 06072 START_PROFILE(SMBgetattrE); 06073 06074 outsize = set_message(outbuf,11,0,True); 06075 06076 if(!fsp || (fsp->conn != conn)) { 06077 END_PROFILE(SMBgetattrE); 06078 return ERROR_DOS(ERRDOS,ERRbadfid); 06079 } 06080 06081 /* Do an fstat on this file */ 06082 if(fsp_stat(fsp, &sbuf)) { 06083 END_PROFILE(SMBgetattrE); 06084 return(UNIXERROR(ERRDOS,ERRnoaccess)); 06085 } 06086 06087 mode = dos_mode(conn,fsp->fsp_name,&sbuf); 06088 06089 /* 06090 * Convert the times into dos times. Set create 06091 * date to be last modify date as UNIX doesn't save 06092 * this. 06093 */ 06094 06095 srv_put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)))); 06096 srv_put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime); 06097 /* Should we check pending modtime here ? JRA */ 06098 srv_put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime); 06099 06100 if (mode & aDIR) { 06101 SIVAL(outbuf,smb_vwv6,0); 06102 SIVAL(outbuf,smb_vwv8,0); 06103 } else { 06104 uint32 allocation_size = get_allocation_size(conn,fsp, &sbuf); 06105 SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size); 06106 SIVAL(outbuf,smb_vwv8,allocation_size); 06107 } 06108 SSVAL(outbuf,smb_vwv10, mode); 06109 06110 DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum)); 06111 06112 END_PROFILE(SMBgetattrE); 06113 return(outsize); 06114 }
enum protocol_types Protocol |
unsigned int smb_echo_count = 0 |
uint32 global_client_caps |
sesssetup.c の 32 行で定義されています。
struct current_user current_user |