列挙型 | |
enum | perm_type { PERM_NEW_FILE, PERM_NEW_DIR, PERM_EXISTING_FILE, PERM_EXISTING_DIR } |
関数 | |
static char * | store_file_unix_basic (connection_struct *conn, char *pdata, files_struct *fsp, const SMB_STRUCT_STAT *psbuf) |
static char * | store_file_unix_basic_info2 (connection_struct *conn, char *pdata, files_struct *fsp, const SMB_STRUCT_STAT *psbuf) |
SMB_BIG_UINT | smb_roundup (connection_struct *conn, SMB_BIG_UINT val) |
SMB_BIG_UINT | get_allocation_size (connection_struct *conn, files_struct *fsp, const SMB_STRUCT_STAT *sbuf) |
static BOOL | samba_private_attr_name (const char *unix_ea_name) |
static BOOL | get_ea_value (TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp, const char *fname, char *ea_name, struct ea_struct *pea) |
static struct ea_list * | get_ea_list_from_file (TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp, const char *fname, size_t *pea_total_len) |
static unsigned int | fill_ea_buffer (TALLOC_CTX *mem_ctx, char *pdata, unsigned int total_data_size, connection_struct *conn, struct ea_list *ea_list) |
static unsigned int | estimate_ea_size (connection_struct *conn, files_struct *fsp, const char *fname) |
static void | canonicalize_ea_name (connection_struct *conn, files_struct *fsp, const char *fname, fstring unix_ea_name) |
NTSTATUS | set_ea (connection_struct *conn, files_struct *fsp, const char *fname, struct ea_list *ea_list) |
static struct ea_list * | read_ea_name_list (TALLOC_CTX *ctx, const char *pdata, size_t data_size) |
ea_list * | read_ea_list_entry (TALLOC_CTX *ctx, const char *pdata, size_t data_size, size_t *pbytes_used) |
static struct ea_list * | read_ea_list (TALLOC_CTX *ctx, const char *pdata, size_t data_size) |
static size_t | ea_list_size (struct ea_list *ealist) |
static struct ea_list * | ea_list_union (struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len) |
int | send_trans2_replies (char *outbuf, int bufsize, const char *params, int paramsize, const char *pdata, int datasize, int max_data_bytes) |
static int | call_trans2open (connection_struct *conn, char *inbuf, char *outbuf, int bufsize, char **pparams, int total_params, char **ppdata, int total_data, unsigned int max_data_bytes) |
static BOOL | exact_match (connection_struct *conn, char *str, char *mask) |
static uint32 | unix_filetype (mode_t mode) |
static NTSTATUS | unix_perms_from_wire (connection_struct *conn, SMB_STRUCT_STAT *psbuf, uint32 perms, enum perm_type ptype, mode_t *ret_perms) |
static BOOL | get_lanman2_dir_entry (connection_struct *conn, void *inbuf, char *outbuf, char *path_mask, uint32 dirtype, int info_level, int requires_resume_key, BOOL dont_descend, char **ppdata, char *base_data, char *end_data, int space_remaining, BOOL *out_of_space, BOOL *got_exact_match, int *last_entry_off, struct ea_list *name_list, TALLOC_CTX *ea_ctx) |
static int | call_trans2findfirst (connection_struct *conn, char *inbuf, char *outbuf, int bufsize, char **pparams, int total_params, char **ppdata, int total_data, unsigned int max_data_bytes) |
static int | call_trans2findnext (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, char **pparams, int total_params, char **ppdata, int total_data, unsigned int max_data_bytes) |
static void | samba_extended_info_version (struct smb_extended_info *extended_info) |
static int | call_trans2qfsinfo (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, char **pparams, int total_params, char **ppdata, int total_data, unsigned int max_data_bytes) |
static int | call_trans2setfsinfo (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, char **pparams, int total_params, char **ppdata, int total_data, unsigned int max_data_bytes) |
static unsigned int | count_acl_entries (connection_struct *conn, SMB_ACL_T posix_acl) |
static BOOL | marshall_posix_acl (connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl) |
static void | map_info2_flags_from_sbuf (const SMB_STRUCT_STAT *psbuf, uint32 *smb_fflags, uint32 *smb_fmask) |
static BOOL | map_info2_flags_to_sbuf (const SMB_STRUCT_STAT *psbuf, const uint32 smb_fflags, const uint32 smb_fmask, int *stat_fflags) |
static int | call_trans2qfilepathinfo (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, unsigned int tran_call, char **pparams, int total_params, char **ppdata, int total_data, unsigned int max_data_bytes) |
NTSTATUS | hardlink_internals (connection_struct *conn, pstring oldname, pstring newname) |
static NTSTATUS | smb_set_file_time (connection_struct *conn, files_struct *fsp, const char *fname, const SMB_STRUCT_STAT *psbuf, struct timespec ts[2]) |
static NTSTATUS | smb_set_file_dosmode (connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf, uint32 dosmode) |
static NTSTATUS | smb_set_file_size (connection_struct *conn, files_struct *fsp, const char *fname, SMB_STRUCT_STAT *psbuf, SMB_OFF_T size) |
static NTSTATUS | smb_info_set_ea (connection_struct *conn, const char *pdata, int total_data, files_struct *fsp, const char *fname) |
static NTSTATUS | smb_set_file_disposition_info (connection_struct *conn, const char *pdata, int total_data, files_struct *fsp, const char *fname, SMB_STRUCT_STAT *psbuf) |
static NTSTATUS | smb_file_position_information (connection_struct *conn, const char *pdata, int total_data, files_struct *fsp) |
static NTSTATUS | smb_file_mode_information (connection_struct *conn, const char *pdata, int total_data) |
static NTSTATUS | smb_set_file_unix_link (connection_struct *conn, char *inbuf, const char *pdata, int total_data, const char *fname) |
static NTSTATUS | smb_set_file_unix_hlink (connection_struct *conn, char *inbuf, char *outbuf, const char *pdata, int total_data, pstring fname) |
static NTSTATUS | smb_file_rename_information (connection_struct *conn, char *inbuf, char *outbuf, const char *pdata, int total_data, files_struct *fsp, pstring fname) |
static NTSTATUS | smb_set_posix_acl (connection_struct *conn, const char *pdata, int total_data, files_struct *fsp, const char *fname, SMB_STRUCT_STAT *psbuf) |
static NTSTATUS | smb_set_posix_lock (connection_struct *conn, char *inbuf, int length, const char *pdata, int total_data, files_struct *fsp) |
static NTSTATUS | smb_set_info_standard (connection_struct *conn, const char *pdata, int total_data, files_struct *fsp, const char *fname, const SMB_STRUCT_STAT *psbuf) |
static NTSTATUS | smb_set_file_basic_info (connection_struct *conn, const char *pdata, int total_data, files_struct *fsp, const char *fname, SMB_STRUCT_STAT *psbuf) |
static NTSTATUS | smb_set_file_allocation_info (connection_struct *conn, const char *pdata, int total_data, files_struct *fsp, const char *fname, SMB_STRUCT_STAT *psbuf) |
static NTSTATUS | smb_set_file_end_of_file_info (connection_struct *conn, const char *pdata, int total_data, files_struct *fsp, const char *fname, SMB_STRUCT_STAT *psbuf) |
static NTSTATUS | smb_unix_mknod (connection_struct *conn, const char *pdata, int total_data, const char *fname, SMB_STRUCT_STAT *psbuf) |
static NTSTATUS | smb_set_file_unix_basic (connection_struct *conn, const char *pdata, int total_data, files_struct *fsp, const char *fname, SMB_STRUCT_STAT *psbuf) |
static NTSTATUS | smb_set_file_unix_info2 (connection_struct *conn, const char *pdata, int total_data, files_struct *fsp, const char *fname, SMB_STRUCT_STAT *psbuf) |
static NTSTATUS | smb_posix_mkdir (connection_struct *conn, char **ppdata, int total_data, const char *fname, SMB_STRUCT_STAT *psbuf, int *pdata_return_size) |
static NTSTATUS | smb_posix_open (connection_struct *conn, char **ppdata, int total_data, const char *fname, SMB_STRUCT_STAT *psbuf, int *pdata_return_size) |
static NTSTATUS | smb_posix_unlink (connection_struct *conn, const char *pdata, int total_data, const char *fname, SMB_STRUCT_STAT *psbuf) |
static int | call_trans2setfilepathinfo (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, unsigned int tran_call, char **pparams, int total_params, char **ppdata, int total_data, unsigned int max_data_bytes) |
static int | call_trans2mkdir (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, char **pparams, int total_params, char **ppdata, int total_data, unsigned int max_data_bytes) |
static int | call_trans2findnotifyfirst (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, char **pparams, int total_params, char **ppdata, int total_data, unsigned int max_data_bytes) |
static int | call_trans2findnotifynext (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, char **pparams, int total_params, char **ppdata, int total_data, unsigned int max_data_bytes) |
static int | call_trans2getdfsreferral (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, char **pparams, int total_params, char **ppdata, int total_data, unsigned int max_data_bytes) |
static int | call_trans2ioctl (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, char **pparams, int total_params, char **ppdata, int total_data, unsigned int max_data_bytes) |
int | reply_findclose (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize) |
int | reply_findnclose (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize) |
int | handle_trans2 (connection_struct *conn, struct trans_state *state, char *inbuf, char *outbuf, int size, int bufsize) |
int | reply_trans2 (connection_struct *conn, char *inbuf, char *outbuf, int size, int bufsize) |
int | reply_transs2 (connection_struct *conn, char *inbuf, char *outbuf, int size, int bufsize) |
変数 | |
int | max_send |
enum protocol_types | Protocol |
int | smb_read_error |
uint32 | global_client_caps |
current_user | current_user |
static const char * | prohibited_ea_names [] |
struct { | |
unsigned stat_fflag | |
unsigned smb_fflag | |
} | info2_flags_map [] |
enum perm_type |
static char * store_file_unix_basic | ( | connection_struct * | conn, | |
char * | pdata, | |||
files_struct * | fsp, | |||
const SMB_STRUCT_STAT * | psbuf | |||
) | [static] |
参照先 get_allocation_size()・get_atimespec()・get_ctimespec()・get_file_size()・get_mtimespec()・put_long_date_timespec()・unix_dev_major()・unix_dev_minor()・unix_filetype()・unix_perms_to_wire().
参照元 call_trans2qfilepathinfo()・get_lanman2_dir_entry()・smb_posix_mkdir()・smb_posix_open()・store_file_unix_basic_info2().
03033 { 03034 DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n")); 03035 DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_mode)); 03036 03037 SOFF_T(pdata,0,get_file_size(*psbuf)); /* File size 64 Bit */ 03038 pdata += 8; 03039 03040 SOFF_T(pdata,0,get_allocation_size(conn,fsp,psbuf)); /* Number of bytes used on disk - 64 Bit */ 03041 pdata += 8; 03042 03043 put_long_date_timespec(pdata,get_ctimespec(psbuf)); /* Change Time 64 Bit */ 03044 put_long_date_timespec(pdata+8,get_atimespec(psbuf)); /* Last access time 64 Bit */ 03045 put_long_date_timespec(pdata+16,get_mtimespec(psbuf)); /* Last modification time 64 Bit */ 03046 pdata += 24; 03047 03048 SIVAL(pdata,0,psbuf->st_uid); /* user id for the owner */ 03049 SIVAL(pdata,4,0); 03050 pdata += 8; 03051 03052 SIVAL(pdata,0,psbuf->st_gid); /* group id of owner */ 03053 SIVAL(pdata,4,0); 03054 pdata += 8; 03055 03056 SIVAL(pdata,0,unix_filetype(psbuf->st_mode)); 03057 pdata += 4; 03058 03059 SIVAL(pdata,0,unix_dev_major(psbuf->st_rdev)); /* Major device number if type is device */ 03060 SIVAL(pdata,4,0); 03061 pdata += 8; 03062 03063 SIVAL(pdata,0,unix_dev_minor(psbuf->st_rdev)); /* Minor device number if type is device */ 03064 SIVAL(pdata,4,0); 03065 pdata += 8; 03066 03067 SINO_T_VAL(pdata,0,(SMB_INO_T)psbuf->st_ino); /* inode number */ 03068 pdata += 8; 03069 03070 SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_mode)); /* Standard UNIX file permissions */ 03071 SIVAL(pdata,4,0); 03072 pdata += 8; 03073 03074 SIVAL(pdata,0,psbuf->st_nlink); /* number of hard links */ 03075 SIVAL(pdata,4,0); 03076 pdata += 8; 03077 03078 return pdata; 03079 }
static char * store_file_unix_basic_info2 | ( | connection_struct * | conn, | |
char * | pdata, | |||
files_struct * | fsp, | |||
const SMB_STRUCT_STAT * | psbuf | |||
) | [static] |
参照先 get_create_timespec()・map_info2_flags_from_sbuf()・put_long_date_timespec()・store_file_unix_basic().
参照元 call_trans2qfilepathinfo()・get_lanman2_dir_entry()・smb_posix_mkdir()・smb_posix_open().
03178 { 03179 uint32 file_flags = 0; 03180 uint32 flags_mask = 0; 03181 03182 pdata = store_file_unix_basic(conn, pdata, fsp, psbuf); 03183 03184 /* Create (birth) time 64 bit */ 03185 put_long_date_timespec(pdata, get_create_timespec(psbuf, False)); 03186 pdata += 8; 03187 03188 map_info2_flags_from_sbuf(psbuf, &file_flags, &flags_mask); 03189 SIVAL(pdata, 0, file_flags); /* flags */ 03190 SIVAL(pdata, 4, flags_mask); /* mask */ 03191 pdata += 8; 03192 03193 return pdata; 03194 }
SMB_BIG_UINT smb_roundup | ( | connection_struct * | conn, | |
SMB_BIG_UINT | val | |||
) |
参照先 current_user::conn・get_remote_arch()・RA_CIFSFS・RA_SAMBA・ra_type.
参照元 call_nt_transact_create()・call_trans2open()・get_allocation_size()・reply_ntcreate_and_X()・reply_open_and_X()・smb_set_file_allocation_info().
00054 { 00055 SMB_BIG_UINT rval = lp_allocation_roundup_size(SNUM(conn)); 00056 00057 /* Only roundup for Windows clients. */ 00058 enum remote_arch_types ra_type = get_remote_arch(); 00059 if (rval && (ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) { 00060 val = SMB_ROUNDUP(val,rval); 00061 } 00062 return val; 00063 }
SMB_BIG_UINT get_allocation_size | ( | connection_struct * | conn, | |
files_struct * | fsp, | |||
const SMB_STRUCT_STAT * | sbuf | |||
) |
参照先 current_user::conn・get_file_size()・files_struct::initial_allocation_size・smb_roundup().
参照元 call_nt_transact_create()・call_trans2qfilepathinfo()・get_lanman2_dir_entry()・reply_getattrE()・reply_ntcreate_and_X()・reply_open_and_X()・store_file_unix_basic().
00071 { 00072 SMB_BIG_UINT ret; 00073 00074 if(S_ISDIR(sbuf->st_mode)) { 00075 return 0; 00076 } 00077 00078 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE) 00079 ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks; 00080 #else 00081 ret = (SMB_BIG_UINT)get_file_size(*sbuf); 00082 #endif 00083 00084 if (fsp && fsp->initial_allocation_size) 00085 ret = MAX(ret,fsp->initial_allocation_size); 00086 00087 return smb_roundup(conn, ret); 00088 }
static BOOL samba_private_attr_name | ( | const char * | unix_ea_name | ) | [static] |
参照先 prohibited_ea_names・strequal().
参照元 get_ea_list_from_file()・set_ea().
00105 { 00106 int i; 00107 00108 for (i = 0; prohibited_ea_names[i]; i++) { 00109 if (strequal( prohibited_ea_names[i], unix_ea_name)) 00110 return True; 00111 } 00112 return False; 00113 }
static BOOL get_ea_value | ( | TALLOC_CTX * | mem_ctx, | |
connection_struct * | conn, | |||
files_struct * | fsp, | |||
const char * | fname, | |||
char * | ea_name, | |||
struct ea_struct * | pea | |||
) | [static] |
参照先 current_user::conn・data_blob_::data・dump_data()・errno・fd_handle::fd・files_struct::fh・ea_struct::flags・data_blob_::length・ea_struct::name・strnequal()・ea_struct::value.
00121 { 00122 /* Get the value of this xattr. Max size is 64k. */ 00123 size_t attr_size = 256; 00124 char *val = NULL; 00125 ssize_t sizeret; 00126 00127 again: 00128 00129 val = TALLOC_REALLOC_ARRAY(mem_ctx, val, char, attr_size); 00130 if (!val) { 00131 return False; 00132 } 00133 00134 if (fsp && fsp->fh->fd != -1) { 00135 sizeret = SMB_VFS_FGETXATTR(fsp, fsp->fh->fd, ea_name, val, attr_size); 00136 } else { 00137 sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size); 00138 } 00139 00140 if (sizeret == -1 && errno == ERANGE && attr_size != 65536) { 00141 attr_size = 65536; 00142 goto again; 00143 } 00144 00145 if (sizeret == -1) { 00146 return False; 00147 } 00148 00149 DEBUG(10,("get_ea_value: EA %s is of length %u: ", ea_name, (unsigned int)sizeret)); 00150 dump_data(10, val, sizeret); 00151 00152 pea->flags = 0; 00153 if (strnequal(ea_name, "user.", 5)) { 00154 pea->name = &ea_name[5]; 00155 } else { 00156 pea->name = ea_name; 00157 } 00158 pea->value.data = (unsigned char *)val; 00159 pea->value.length = (size_t)sizeret; 00160 return True; 00161 }
static struct ea_list* get_ea_list_from_file | ( | TALLOC_CTX * | mem_ctx, | |
connection_struct * | conn, | |||
files_struct * | fsp, | |||
const char * | fname, | |||
size_t * | pea_total_len | |||
) | [static] |
参照先 errno・fd_handle::fd・files_struct::fh・get_ea_value()・push_ascii_fstring()・samba_private_attr_name()・strnequal().
参照元 call_trans2qfilepathinfo()・canonicalize_ea_name()・estimate_ea_size()・get_lanman2_dir_entry().
00169 { 00170 /* Get a list of all xattrs. Max namesize is 64k. */ 00171 size_t ea_namelist_size = 1024; 00172 char *ea_namelist; 00173 char *p; 00174 ssize_t sizeret; 00175 int i; 00176 struct ea_list *ea_list_head = NULL; 00177 00178 *pea_total_len = 0; 00179 00180 if (!lp_ea_support(SNUM(conn))) { 00181 return NULL; 00182 } 00183 00184 for (i = 0, ea_namelist = TALLOC_ARRAY(mem_ctx, char, ea_namelist_size); i < 6; 00185 ea_namelist = TALLOC_REALLOC_ARRAY(mem_ctx, ea_namelist, char, ea_namelist_size), i++) { 00186 00187 if (!ea_namelist) { 00188 return NULL; 00189 } 00190 00191 if (fsp && fsp->fh->fd != -1) { 00192 sizeret = SMB_VFS_FLISTXATTR(fsp, fsp->fh->fd, ea_namelist, ea_namelist_size); 00193 } else { 00194 sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist, ea_namelist_size); 00195 } 00196 00197 if (sizeret == -1 && errno == ERANGE) { 00198 ea_namelist_size *= 2; 00199 } else { 00200 break; 00201 } 00202 } 00203 00204 if (sizeret == -1) 00205 return NULL; 00206 00207 DEBUG(10,("get_ea_list_from_file: ea_namelist size = %u\n", (unsigned int)sizeret )); 00208 00209 if (sizeret) { 00210 for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p) + 1) { 00211 struct ea_list *listp; 00212 00213 if (strnequal(p, "system.", 7) || samba_private_attr_name(p)) 00214 continue; 00215 00216 listp = TALLOC_P(mem_ctx, struct ea_list); 00217 if (!listp) 00218 return NULL; 00219 00220 if (!get_ea_value(mem_ctx, conn, fsp, fname, p, &listp->ea)) { 00221 return NULL; 00222 } 00223 00224 { 00225 fstring dos_ea_name; 00226 push_ascii_fstring(dos_ea_name, listp->ea.name); 00227 *pea_total_len += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length; 00228 DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len = %u\n", 00229 (unsigned int)*pea_total_len, dos_ea_name, 00230 (unsigned int)listp->ea.value.length )); 00231 } 00232 DLIST_ADD_END(ea_list_head, listp, struct ea_list *); 00233 } 00234 /* Add on 4 for total length. */ 00235 if (*pea_total_len) { 00236 *pea_total_len += 4; 00237 } 00238 } 00239 00240 DEBUG(10,("get_ea_list_from_file: total_len = %u\n", (unsigned int)*pea_total_len)); 00241 return ea_list_head; 00242 }
static unsigned int fill_ea_buffer | ( | TALLOC_CTX * | mem_ctx, | |
char * | pdata, | |||
unsigned int | total_data_size, | |||
connection_struct * | conn, | |||
struct ea_list * | ea_list | |||
) | [static] |
参照先 data_blob_::data・ea_list::ea・ea_struct::flags・data_blob_::length・ea_struct::name・ea_list::next・push_ascii_fstring()・ea_struct::value.
参照元 call_trans2qfilepathinfo()・get_lanman2_dir_entry().
00251 { 00252 unsigned int ret_data_size = 4; 00253 char *p = pdata; 00254 00255 SMB_ASSERT(total_data_size >= 4); 00256 00257 if (!lp_ea_support(SNUM(conn))) { 00258 SIVAL(pdata,4,0); 00259 return 4; 00260 } 00261 00262 for (p = pdata + 4; ea_list; ea_list = ea_list->next) { 00263 size_t dos_namelen; 00264 fstring dos_ea_name; 00265 push_ascii_fstring(dos_ea_name, ea_list->ea.name); 00266 dos_namelen = strlen(dos_ea_name); 00267 if (dos_namelen > 255 || dos_namelen == 0) { 00268 break; 00269 } 00270 if (ea_list->ea.value.length > 65535) { 00271 break; 00272 } 00273 if (4 + dos_namelen + 1 + ea_list->ea.value.length > total_data_size) { 00274 break; 00275 } 00276 00277 /* We know we have room. */ 00278 SCVAL(p,0,ea_list->ea.flags); 00279 SCVAL(p,1,dos_namelen); 00280 SSVAL(p,2,ea_list->ea.value.length); 00281 fstrcpy(p+4, dos_ea_name); 00282 memcpy( p + 4 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length); 00283 00284 total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length; 00285 p += 4 + dos_namelen + 1 + ea_list->ea.value.length; 00286 } 00287 00288 ret_data_size = PTR_DIFF(p, pdata); 00289 DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size )); 00290 SIVAL(pdata,0,ret_data_size); 00291 return ret_data_size; 00292 }
static unsigned int estimate_ea_size | ( | connection_struct * | conn, | |
files_struct * | fsp, | |||
const char * | fname | |||
) | [static] |
参照先 get_ea_list_from_file()・talloc_init().
参照元 call_trans2open()・call_trans2qfilepathinfo()・get_lanman2_dir_entry().
00295 { 00296 size_t total_ea_len = 0; 00297 TALLOC_CTX *mem_ctx = NULL; 00298 00299 if (!lp_ea_support(SNUM(conn))) { 00300 return 0; 00301 } 00302 mem_ctx = talloc_init("estimate_ea_size"); 00303 (void)get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len); 00304 talloc_destroy(mem_ctx); 00305 return total_ea_len; 00306 }
static void canonicalize_ea_name | ( | connection_struct * | conn, | |
files_struct * | fsp, | |||
const char * | fname, | |||
fstring | unix_ea_name | |||
) | [static] |
参照先 ea_list::ea・get_ea_list_from_file()・ea_struct::name・ea_list::next・strequal()・talloc_init().
参照元 set_ea().
00313 { 00314 size_t total_ea_len; 00315 TALLOC_CTX *mem_ctx = talloc_init("canonicalize_ea_name"); 00316 struct ea_list *ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len); 00317 00318 for (; ea_list; ea_list = ea_list->next) { 00319 if (strequal(&unix_ea_name[5], ea_list->ea.name)) { 00320 DEBUG(10,("canonicalize_ea_name: %s -> %s\n", 00321 &unix_ea_name[5], ea_list->ea.name)); 00322 safe_strcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-6); 00323 break; 00324 } 00325 } 00326 talloc_destroy(mem_ctx); 00327 }
NTSTATUS set_ea | ( | connection_struct * | conn, | |
files_struct * | fsp, | |||
const char * | fname, | |||
struct ea_list * | ea_list | |||
) |
参照先 canonicalize_ea_name()・data_blob_::data・ea_list::ea・errno・fd_handle::fd・files_struct::fh・files_struct::fsp_name・data_blob_::length・map_nt_error_from_unix()・ea_struct::name・ea_list::next・samba_private_attr_name()・ea_struct::value.
参照元 call_nt_transact_create()・call_trans2mkdir()・call_trans2open()・smb_info_set_ea().
00334 { 00335 if (!lp_ea_support(SNUM(conn))) { 00336 return NT_STATUS_EAS_NOT_SUPPORTED; 00337 } 00338 00339 for (;ea_list; ea_list = ea_list->next) { 00340 int ret; 00341 fstring unix_ea_name; 00342 00343 fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */ 00344 fstrcat(unix_ea_name, ea_list->ea.name); 00345 00346 canonicalize_ea_name(conn, fsp, fname, unix_ea_name); 00347 00348 DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, (unsigned int)ea_list->ea.value.length)); 00349 00350 if (samba_private_attr_name(unix_ea_name)) { 00351 DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name)); 00352 return NT_STATUS_ACCESS_DENIED; 00353 } 00354 00355 if (ea_list->ea.value.length == 0) { 00356 /* Remove the attribute. */ 00357 if (fsp && (fsp->fh->fd != -1)) { 00358 DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n", 00359 unix_ea_name, fsp->fsp_name)); 00360 ret = SMB_VFS_FREMOVEXATTR(fsp, fsp->fh->fd, unix_ea_name); 00361 } else { 00362 DEBUG(10,("set_ea: deleting ea name %s on file %s.\n", 00363 unix_ea_name, fname)); 00364 ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name); 00365 } 00366 #ifdef ENOATTR 00367 /* Removing a non existent attribute always succeeds. */ 00368 if (ret == -1 && errno == ENOATTR) { 00369 DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n", 00370 unix_ea_name)); 00371 ret = 0; 00372 } 00373 #endif 00374 } else { 00375 if (fsp && (fsp->fh->fd != -1)) { 00376 DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n", 00377 unix_ea_name, fsp->fsp_name)); 00378 ret = SMB_VFS_FSETXATTR(fsp, fsp->fh->fd, unix_ea_name, 00379 ea_list->ea.value.data, ea_list->ea.value.length, 0); 00380 } else { 00381 DEBUG(10,("set_ea: setting ea name %s on file %s.\n", 00382 unix_ea_name, fname)); 00383 ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name, 00384 ea_list->ea.value.data, ea_list->ea.value.length, 0); 00385 } 00386 } 00387 00388 if (ret == -1) { 00389 #ifdef ENOTSUP 00390 if (errno == ENOTSUP) { 00391 return NT_STATUS_EAS_NOT_SUPPORTED; 00392 } 00393 #endif 00394 return map_nt_error_from_unix(errno); 00395 } 00396 00397 } 00398 return NT_STATUS_OK; 00399 }
static struct ea_list* read_ea_name_list | ( | TALLOC_CTX * | ctx, | |
const char * | pdata, | |||
size_t | data_size | |||
) | [static] |
参照先 ea_list::ea・ea_struct::name・pull_ascii_talloc().
参照元 call_trans2findfirst()・call_trans2findnext()・call_trans2qfilepathinfo().
00405 { 00406 struct ea_list *ea_list_head = NULL; 00407 size_t offset = 0; 00408 00409 while (offset + 2 < data_size) { 00410 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list); 00411 unsigned int namelen = CVAL(pdata,offset); 00412 00413 offset++; /* Go past the namelen byte. */ 00414 00415 /* integer wrap paranioa. */ 00416 if ((offset + namelen < offset) || (offset + namelen < namelen) || 00417 (offset > data_size) || (namelen > data_size) || 00418 (offset + namelen >= data_size)) { 00419 break; 00420 } 00421 /* Ensure the name is null terminated. */ 00422 if (pdata[offset + namelen] != '\0') { 00423 return NULL; 00424 } 00425 pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset]); 00426 if (!eal->ea.name) { 00427 return NULL; 00428 } 00429 00430 offset += (namelen + 1); /* Go past the name + terminating zero. */ 00431 DLIST_ADD_END(ea_list_head, eal, struct ea_list *); 00432 DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name)); 00433 } 00434 00435 return ea_list_head; 00436 }
struct ea_list* read_ea_list_entry | ( | TALLOC_CTX * | ctx, | |
const char * | pdata, | |||
size_t | data_size, | |||
size_t * | pbytes_used | |||
) |
参照先 data_blob_::data・data_blob_talloc()・dump_data()・ea_list::ea・ea_struct::flags・data_blob_::length・ea_struct::name・pull_ascii_talloc()・ea_struct::value.
参照元 read_ea_list()・read_nttrans_ea_list().
00443 { 00444 struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list); 00445 uint16 val_len; 00446 unsigned int namelen; 00447 00448 if (!eal) { 00449 return NULL; 00450 } 00451 00452 if (data_size < 6) { 00453 return NULL; 00454 } 00455 00456 eal->ea.flags = CVAL(pdata,0); 00457 namelen = CVAL(pdata,1); 00458 val_len = SVAL(pdata,2); 00459 00460 if (4 + namelen + 1 + val_len > data_size) { 00461 return NULL; 00462 } 00463 00464 /* Ensure the name is null terminated. */ 00465 if (pdata[namelen + 4] != '\0') { 00466 return NULL; 00467 } 00468 pull_ascii_talloc(ctx, &eal->ea.name, pdata + 4); 00469 if (!eal->ea.name) { 00470 return NULL; 00471 } 00472 00473 eal->ea.value = data_blob_talloc(eal, NULL, (size_t)val_len + 1); 00474 if (!eal->ea.value.data) { 00475 return NULL; 00476 } 00477 00478 memcpy(eal->ea.value.data, pdata + 4 + namelen + 1, val_len); 00479 00480 /* Ensure we're null terminated just in case we print the value. */ 00481 eal->ea.value.data[val_len] = '\0'; 00482 /* But don't count the null. */ 00483 eal->ea.value.length--; 00484 00485 if (pbytes_used) { 00486 *pbytes_used = 4 + namelen + 1 + val_len; 00487 } 00488 00489 DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal->ea.name)); 00490 dump_data(10, (const char *)eal->ea.value.data, eal->ea.value.length); 00491 00492 return eal; 00493 }
static struct ea_list* read_ea_list | ( | TALLOC_CTX * | ctx, | |
const char * | pdata, | |||
size_t | data_size | |||
) | [static] |
参照先 read_ea_list_entry().
参照元 call_trans2mkdir()・call_trans2open()・smb_info_set_ea().
00500 { 00501 struct ea_list *ea_list_head = NULL; 00502 size_t offset = 0; 00503 size_t bytes_used = 0; 00504 00505 while (offset < data_size) { 00506 struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset, data_size - offset, &bytes_used); 00507 00508 if (!eal) { 00509 return NULL; 00510 } 00511 00512 DLIST_ADD_END(ea_list_head, eal, struct ea_list *); 00513 offset += bytes_used; 00514 } 00515 00516 return ea_list_head; 00517 }
static size_t ea_list_size | ( | struct ea_list * | ealist | ) | [static] |
参照先 ea_list::ea・data_blob_::length・ea_struct::name・ea_list::next・push_ascii_fstring()・ea_struct::value.
00524 { 00525 fstring dos_ea_name; 00526 struct ea_list *listp; 00527 size_t ret = 0; 00528 00529 for (listp = ealist; listp; listp = listp->next) { 00530 push_ascii_fstring(dos_ea_name, listp->ea.name); 00531 ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length; 00532 } 00533 /* Add on 4 for total length. */ 00534 if (ret) { 00535 ret += 4; 00536 } 00537 00538 return ret; 00539 }
static struct ea_list* ea_list_union | ( | struct ea_list * | name_list, | |
struct ea_list * | file_list, | |||
size_t * | total_ea_len | |||
) | [static] |
参照先 ea_list::ea・ea_struct::flags・ea_struct::name・ea_list::next・strequal()・ea_struct::value.
参照元 call_trans2qfilepathinfo()・get_lanman2_dir_entry().
00548 { 00549 struct ea_list *nlistp, *flistp; 00550 00551 for (nlistp = name_list; nlistp; nlistp = nlistp->next) { 00552 for (flistp = file_list; flistp; flistp = flistp->next) { 00553 if (strequal(nlistp->ea.name, flistp->ea.name)) { 00554 break; 00555 } 00556 } 00557 00558 if (flistp) { 00559 /* Copy the data from this entry. */ 00560 nlistp->ea.flags = flistp->ea.flags; 00561 nlistp->ea.value = flistp->ea.value; 00562 } else { 00563 /* Null entry. */ 00564 nlistp->ea.flags = 0; 00565 ZERO_STRUCT(nlistp->ea.value); 00566 } 00567 } 00568 00569 *total_ea_len = ea_list_size(name_list); 00570 return name_list; 00571 }
int send_trans2_replies | ( | char * | outbuf, | |
int | bufsize, | |||
const char * | params, | |||
int | paramsize, | |||
const char * | pdata, | |||
int | datasize, | |||
int | max_data_bytes | |||
) |
参照先 error_packet_set()・exit_server_cleanly()・max_send・send_smb()・set_message()・show_msg()・smbd_server_fd().
参照元 call_trans2findfirst()・call_trans2findnext()・call_trans2findnotifyfirst()・call_trans2findnotifynext()・call_trans2getdfsreferral()・call_trans2ioctl()・call_trans2mkdir()・call_trans2open()・call_trans2qfilepathinfo()・call_trans2qfsinfo()・call_trans2setfilepathinfo()・process_trans2().
00587 { 00588 /* As we are using a protocol > LANMAN1 then the max_send 00589 variable must have been set in the sessetupX call. 00590 This takes precedence over the max_xmit field in the 00591 global struct. These different max_xmit variables should 00592 be merged as this is now too confusing */ 00593 00594 int data_to_send = datasize; 00595 int params_to_send = paramsize; 00596 int useable_space; 00597 const char *pp = params; 00598 const char *pd = pdata; 00599 int params_sent_thistime, data_sent_thistime, total_sent_thistime; 00600 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */ 00601 int data_alignment_offset = 0; 00602 00603 /* Initially set the wcnt area to be 10 - this is true for all trans2 replies */ 00604 00605 set_message(outbuf,10,0,True); 00606 00607 /* Modify the data_to_send and datasize and set the error if 00608 we're trying to send more than max_data_bytes. We still send 00609 the part of the packet(s) that fit. Strange, but needed 00610 for OS/2. */ 00611 00612 if (max_data_bytes > 0 && datasize > max_data_bytes) { 00613 DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n", 00614 max_data_bytes, datasize )); 00615 datasize = data_to_send = max_data_bytes; 00616 error_packet_set(outbuf,ERRDOS,ERRbufferoverflow,STATUS_BUFFER_OVERFLOW,__LINE__,__FILE__); 00617 } 00618 00619 /* If there genuinely are no parameters or data to send just send the empty packet */ 00620 00621 if(params_to_send == 0 && data_to_send == 0) { 00622 show_msg(outbuf); 00623 if (!send_smb(smbd_server_fd(),outbuf)) 00624 exit_server_cleanly("send_trans2_replies: send_smb failed."); 00625 return 0; 00626 } 00627 00628 /* When sending params and data ensure that both are nicely aligned */ 00629 /* Only do this alignment when there is also data to send - else 00630 can cause NT redirector problems. */ 00631 00632 if (((params_to_send % 4) != 0) && (data_to_send != 0)) 00633 data_alignment_offset = 4 - (params_to_send % 4); 00634 00635 /* Space is bufsize minus Netbios over TCP header minus SMB header */ 00636 /* The alignment_offset is to align the param bytes on an even byte 00637 boundary. NT 4.0 Beta needs this to work correctly. */ 00638 00639 useable_space = bufsize - ((smb_buf(outbuf)+ alignment_offset+data_alignment_offset) - outbuf); 00640 00641 /* useable_space can never be more than max_send minus the alignment offset. */ 00642 00643 useable_space = MIN(useable_space, max_send - (alignment_offset+data_alignment_offset)); 00644 00645 while (params_to_send || data_to_send) { 00646 /* Calculate whether we will totally or partially fill this packet */ 00647 00648 total_sent_thistime = params_to_send + data_to_send + alignment_offset + data_alignment_offset; 00649 00650 /* We can never send more than useable_space */ 00651 /* 00652 * Note that 'useable_space' does not include the alignment offsets, 00653 * but we must include the alignment offsets in the calculation of 00654 * the length of the data we send over the wire, as the alignment offsets 00655 * are sent here. Fix from Marc_Jacobsen@hp.com. 00656 */ 00657 00658 total_sent_thistime = MIN(total_sent_thistime, useable_space+ alignment_offset + data_alignment_offset); 00659 00660 set_message(outbuf, 10, total_sent_thistime, True); 00661 00662 /* Set total params and data to be sent */ 00663 SSVAL(outbuf,smb_tprcnt,paramsize); 00664 SSVAL(outbuf,smb_tdrcnt,datasize); 00665 00666 /* Calculate how many parameters and data we can fit into 00667 * this packet. Parameters get precedence 00668 */ 00669 00670 params_sent_thistime = MIN(params_to_send,useable_space); 00671 data_sent_thistime = useable_space - params_sent_thistime; 00672 data_sent_thistime = MIN(data_sent_thistime,data_to_send); 00673 00674 SSVAL(outbuf,smb_prcnt, params_sent_thistime); 00675 00676 /* smb_proff is the offset from the start of the SMB header to the 00677 parameter bytes, however the first 4 bytes of outbuf are 00678 the Netbios over TCP header. Thus use smb_base() to subtract 00679 them from the calculation */ 00680 00681 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf))); 00682 00683 if(params_sent_thistime == 0) 00684 SSVAL(outbuf,smb_prdisp,0); 00685 else 00686 /* Absolute displacement of param bytes sent in this packet */ 00687 SSVAL(outbuf,smb_prdisp,pp - params); 00688 00689 SSVAL(outbuf,smb_drcnt, data_sent_thistime); 00690 if(data_sent_thistime == 0) { 00691 SSVAL(outbuf,smb_droff,0); 00692 SSVAL(outbuf,smb_drdisp, 0); 00693 } else { 00694 /* The offset of the data bytes is the offset of the 00695 parameter bytes plus the number of parameters being sent this time */ 00696 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) - 00697 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset); 00698 SSVAL(outbuf,smb_drdisp, pd - pdata); 00699 } 00700 00701 /* Copy the param bytes into the packet */ 00702 00703 if(params_sent_thistime) 00704 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime); 00705 00706 /* Copy in the data bytes */ 00707 if(data_sent_thistime) 00708 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+ 00709 data_alignment_offset,pd,data_sent_thistime); 00710 00711 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n", 00712 params_sent_thistime, data_sent_thistime, useable_space)); 00713 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n", 00714 params_to_send, data_to_send, paramsize, datasize)); 00715 00716 /* Send the packet */ 00717 show_msg(outbuf); 00718 if (!send_smb(smbd_server_fd(),outbuf)) 00719 exit_server_cleanly("send_trans2_replies: send_smb failed."); 00720 00721 pp += params_sent_thistime; 00722 pd += data_sent_thistime; 00723 00724 params_to_send -= params_sent_thistime; 00725 data_to_send -= data_sent_thistime; 00726 00727 /* Sanity check */ 00728 if(params_to_send < 0 || data_to_send < 0) { 00729 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!", 00730 params_to_send, data_to_send)); 00731 return -1; 00732 } 00733 } 00734 00735 return 0; 00736 }
static int call_trans2open | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | bufsize, | |||
char ** | pparams, | |||
int | total_params, | |||
char ** | ppdata, | |||
int | total_data, | |||
unsigned int | max_data_bytes | |||
) | [static] |
参照先 check_name()・close_file()・files_struct::conn・ERROR_CLOSE・estimate_ea_size()・flags・files_struct::fnum・get_file_size()・files_struct::initial_allocation_size・inode・files_struct::is_directory・make_unix_date3()・map_open_params_to_ntcreate()・open_file_ntcreate()・open_was_deferred()・read_ea_list()・send_trans2_replies()・set_ea()・size・smb_roundup()・srv_put_dos_date2()・srvstr_get_path()・status・tmp_talloc_ctx()・unix_convert()・vfs_allocate_file_space().
参照元 handle_trans2().
00745 { 00746 char *params = *pparams; 00747 char *pdata = *ppdata; 00748 int deny_mode; 00749 int32 open_attr; 00750 BOOL oplock_request; 00751 #if 0 00752 BOOL return_additional_info; 00753 int16 open_sattr; 00754 time_t open_time; 00755 #endif 00756 int open_ofun; 00757 uint32 open_size; 00758 char *pname; 00759 pstring fname; 00760 SMB_OFF_T size=0; 00761 int fattr=0,mtime=0; 00762 SMB_INO_T inode = 0; 00763 SMB_STRUCT_STAT sbuf; 00764 int smb_action = 0; 00765 files_struct *fsp; 00766 struct ea_list *ea_list = NULL; 00767 uint16 flags = 0; 00768 NTSTATUS status; 00769 uint32 access_mask; 00770 uint32 share_mode; 00771 uint32 create_disposition; 00772 uint32 create_options = 0; 00773 00774 /* 00775 * Ensure we have enough parameters to perform the operation. 00776 */ 00777 00778 if (total_params < 29) { 00779 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 00780 } 00781 00782 flags = SVAL(params, 0); 00783 deny_mode = SVAL(params, 2); 00784 open_attr = SVAL(params,6); 00785 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; 00786 if (oplock_request) { 00787 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0; 00788 } 00789 00790 #if 0 00791 return_additional_info = BITSETW(params,0); 00792 open_sattr = SVAL(params, 4); 00793 open_time = make_unix_date3(params+8); 00794 #endif 00795 open_ofun = SVAL(params,12); 00796 open_size = IVAL(params,14); 00797 pname = ¶ms[28]; 00798 00799 if (IS_IPC(conn)) { 00800 return(ERROR_DOS(ERRSRV,ERRaccess)); 00801 } 00802 00803 srvstr_get_path(inbuf, fname, pname, sizeof(fname), total_params - 28, STR_TERMINATE, &status); 00804 if (!NT_STATUS_IS_OK(status)) { 00805 return ERROR_NT(status); 00806 } 00807 00808 DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n", 00809 fname, (unsigned int)deny_mode, (unsigned int)open_attr, 00810 (unsigned int)open_ofun, open_size)); 00811 00812 /* XXXX we need to handle passed times, sattr and flags */ 00813 00814 status = unix_convert(conn, fname, False, NULL, &sbuf); 00815 if (!NT_STATUS_IS_OK(status)) { 00816 return ERROR_NT(status); 00817 } 00818 00819 status = check_name(conn, fname); 00820 if (!NT_STATUS_IS_OK(status)) { 00821 return ERROR_NT(status); 00822 } 00823 00824 if (open_ofun == 0) { 00825 return ERROR_NT(NT_STATUS_OBJECT_NAME_COLLISION); 00826 } 00827 00828 if (!map_open_params_to_ntcreate(fname, deny_mode, open_ofun, 00829 &access_mask, 00830 &share_mode, 00831 &create_disposition, 00832 &create_options)) { 00833 return ERROR_DOS(ERRDOS, ERRbadaccess); 00834 } 00835 00836 /* Any data in this call is an EA list. */ 00837 if (total_data && (total_data != 4) && !lp_ea_support(SNUM(conn))) { 00838 return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED); 00839 } 00840 00841 if (total_data != 4) { 00842 if (total_data < 10) { 00843 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 00844 } 00845 00846 if (IVAL(pdata,0) > total_data) { 00847 DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n", 00848 IVAL(pdata,0), (unsigned int)total_data)); 00849 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 00850 } 00851 00852 ea_list = read_ea_list(tmp_talloc_ctx(), pdata + 4, 00853 total_data - 4); 00854 if (!ea_list) { 00855 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 00856 } 00857 } else if (IVAL(pdata,0) != 4) { 00858 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 00859 } 00860 00861 status = open_file_ntcreate(conn,fname,&sbuf, 00862 access_mask, 00863 share_mode, 00864 create_disposition, 00865 create_options, 00866 open_attr, 00867 oplock_request, 00868 &smb_action, &fsp); 00869 00870 if (!NT_STATUS_IS_OK(status)) { 00871 if (open_was_deferred(SVAL(inbuf,smb_mid))) { 00872 /* We have re-scheduled this call. */ 00873 return -1; 00874 } 00875 return ERROR_OPEN(status); 00876 } 00877 00878 size = get_file_size(sbuf); 00879 fattr = dos_mode(conn,fname,&sbuf); 00880 mtime = sbuf.st_mtime; 00881 inode = sbuf.st_ino; 00882 if (fattr & aDIR) { 00883 close_file(fsp,ERROR_CLOSE); 00884 return(ERROR_DOS(ERRDOS,ERRnoaccess)); 00885 } 00886 00887 /* Save the requested allocation size. */ 00888 /* Allocate space for the file if a size hint is supplied */ 00889 if ((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) { 00890 SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)open_size; 00891 if (allocation_size && (allocation_size > (SMB_BIG_UINT)size)) { 00892 fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size); 00893 if (fsp->is_directory) { 00894 close_file(fsp,ERROR_CLOSE); 00895 /* Can't set allocation size on a directory. */ 00896 return ERROR_NT(NT_STATUS_ACCESS_DENIED); 00897 } 00898 if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) { 00899 close_file(fsp,ERROR_CLOSE); 00900 return ERROR_NT(NT_STATUS_DISK_FULL); 00901 } 00902 00903 /* Adjust size here to return the right size in the reply. 00904 Windows does it this way. */ 00905 size = fsp->initial_allocation_size; 00906 } else { 00907 fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)size); 00908 } 00909 } 00910 00911 if (ea_list && smb_action == FILE_WAS_CREATED) { 00912 status = set_ea(conn, fsp, fname, ea_list); 00913 if (!NT_STATUS_IS_OK(status)) { 00914 close_file(fsp,ERROR_CLOSE); 00915 return ERROR_NT(status); 00916 } 00917 } 00918 00919 /* Realloc the size of parameters and data we will return */ 00920 *pparams = (char *)SMB_REALLOC(*pparams, 30); 00921 if(*pparams == NULL ) { 00922 return ERROR_NT(NT_STATUS_NO_MEMORY); 00923 } 00924 params = *pparams; 00925 00926 SSVAL(params,0,fsp->fnum); 00927 SSVAL(params,2,fattr); 00928 srv_put_dos_date2(params,4, mtime); 00929 SIVAL(params,8, (uint32)size); 00930 SSVAL(params,12,deny_mode); 00931 SSVAL(params,14,0); /* open_type - file or directory. */ 00932 SSVAL(params,16,0); /* open_state - only valid for IPC device. */ 00933 00934 if (oplock_request && lp_fake_oplocks(SNUM(conn))) { 00935 smb_action |= EXTENDED_OPLOCK_GRANTED; 00936 } 00937 00938 SSVAL(params,18,smb_action); 00939 00940 /* 00941 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes. 00942 */ 00943 SIVAL(params,20,inode); 00944 SSVAL(params,24,0); /* Padding. */ 00945 if (flags & 8) { 00946 uint32 ea_size = estimate_ea_size(conn, fsp, fname); 00947 SIVAL(params, 26, ea_size); 00948 } else { 00949 SIVAL(params, 26, 0); 00950 } 00951 00952 /* Send the required number of replies */ 00953 send_trans2_replies(outbuf, bufsize, params, 30, *ppdata, 0, max_data_bytes); 00954 00955 return -1; 00956 }
static BOOL exact_match | ( | connection_struct * | conn, | |
char * | str, | |||
char * | mask | |||
) | [static] |
参照先 connection_struct::case_sensitive・connection_struct::dirptr・dptr_has_wild()・StrCaseCmp().
00966 { 00967 if (mask[0] == '.' && mask[1] == 0) 00968 return False; 00969 if (conn->case_sensitive) 00970 return strcmp(str,mask)==0; 00971 if (StrCaseCmp(str,mask) != 0) { 00972 return False; 00973 } 00974 if (dptr_has_wild(conn->dirptr)) { 00975 return False; 00976 } 00977 return True; 00978 }
static uint32 unix_filetype | ( | mode_t | mode | ) | [static] |
00985 { 00986 if(S_ISREG(mode)) 00987 return UNIX_TYPE_FILE; 00988 else if(S_ISDIR(mode)) 00989 return UNIX_TYPE_DIR; 00990 #ifdef S_ISLNK 00991 else if(S_ISLNK(mode)) 00992 return UNIX_TYPE_SYMLINK; 00993 #endif 00994 #ifdef S_ISCHR 00995 else if(S_ISCHR(mode)) 00996 return UNIX_TYPE_CHARDEV; 00997 #endif 00998 #ifdef S_ISBLK 00999 else if(S_ISBLK(mode)) 01000 return UNIX_TYPE_BLKDEV; 01001 #endif 01002 #ifdef S_ISFIFO 01003 else if(S_ISFIFO(mode)) 01004 return UNIX_TYPE_FIFO; 01005 #endif 01006 #ifdef S_ISSOCK 01007 else if(S_ISSOCK(mode)) 01008 return UNIX_TYPE_SOCKET; 01009 #endif 01010 01011 DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode)); 01012 return UNIX_TYPE_UNKNOWN; 01013 }
static NTSTATUS unix_perms_from_wire | ( | connection_struct * | conn, | |
SMB_STRUCT_STAT * | psbuf, | |||
uint32 | perms, | |||
enum perm_type | ptype, | |||
mode_t * | ret_perms | |||
) | [static] |
参照先 PERM_EXISTING_DIR・PERM_EXISTING_FILE・PERM_NEW_DIR・PERM_NEW_FILE.
参照元 smb_posix_mkdir()・smb_posix_open()・smb_set_file_unix_basic()・smb_unix_mknod().
01026 { 01027 mode_t ret = 0; 01028 01029 if (perms == SMB_MODE_NO_CHANGE) { 01030 if (!VALID_STAT(*psbuf)) { 01031 return NT_STATUS_INVALID_PARAMETER; 01032 } else { 01033 *ret_perms = psbuf->st_mode; 01034 return NT_STATUS_OK; 01035 } 01036 } 01037 01038 ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0); 01039 ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0); 01040 ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0); 01041 ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0); 01042 ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0); 01043 ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0); 01044 ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0); 01045 ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0); 01046 ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0); 01047 #ifdef S_ISVTX 01048 ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0); 01049 #endif 01050 #ifdef S_ISGID 01051 ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0); 01052 #endif 01053 #ifdef S_ISUID 01054 ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0); 01055 #endif 01056 01057 switch (ptype) { 01058 case PERM_NEW_FILE: 01059 /* Apply mode mask */ 01060 ret &= lp_create_mask(SNUM(conn)); 01061 /* Add in force bits */ 01062 ret |= lp_force_create_mode(SNUM(conn)); 01063 break; 01064 case PERM_NEW_DIR: 01065 ret &= lp_dir_mask(SNUM(conn)); 01066 /* Add in force bits */ 01067 ret |= lp_force_dir_mode(SNUM(conn)); 01068 break; 01069 case PERM_EXISTING_FILE: 01070 /* Apply mode mask */ 01071 ret &= lp_security_mask(SNUM(conn)); 01072 /* Add in force bits */ 01073 ret |= lp_force_security_mode(SNUM(conn)); 01074 break; 01075 case PERM_EXISTING_DIR: 01076 /* Apply mode mask */ 01077 ret &= lp_dir_security_mask(SNUM(conn)); 01078 /* Add in force bits */ 01079 ret |= lp_force_dir_security_mode(SNUM(conn)); 01080 break; 01081 } 01082 01083 *ret_perms = ret; 01084 return NT_STATUS_OK; 01085 }
static BOOL get_lanman2_dir_entry | ( | connection_struct * | conn, | |
void * | inbuf, | |||
char * | outbuf, | |||
char * | path_mask, | |||
uint32 | dirtype, | |||
int | info_level, | |||
int | requires_resume_key, | |||
BOOL | dont_descend, | |||
char ** | ppdata, | |||
char * | base_data, | |||
char * | end_data, | |||
int | space_remaining, | |||
BOOL * | out_of_space, | |||
BOOL * | got_exact_match, | |||
int * | last_entry_off, | |||
struct ea_list * | name_list, | |||
TALLOC_CTX * | ea_ctx | |||
) | [static] |
参照先 align_string()・connection_struct::case_sensitive・convert_timespec_to_time_t()・dir_check_ftype()・connection_struct::dirpath・connection_struct::dirptr・dos_filetime_timespec()・dptr_DirCacheAdd()・dptr_ReadDirName()・dptr_SeekDir()・dptr_TellDir()・ea_list_union()・errno・estimate_ea_size()・exact_match()・fill_ea_buffer()・get_allocation_size()・get_atimespec()・get_create_timespec()・get_ea_list_from_file()・get_file_size()・get_mtimespec()・is_msdfs_link()・len・mangle_is_8_3()・mangle_map()・mask_match()・mode・connection_struct::params・put_long_date_timespec()・srv_put_dos_date2()・store_file_unix_basic()・store_file_unix_basic_info2()・strequal()・strerror()・strrchr_m().
参照元 call_trans2findfirst()・call_trans2findnext().
01099 { 01100 const char *dname; 01101 BOOL found = False; 01102 SMB_STRUCT_STAT sbuf; 01103 pstring mask; 01104 pstring pathreal; 01105 pstring fname; 01106 char *p, *q, *pdata = *ppdata; 01107 uint32 reskey=0; 01108 long prev_dirpos=0; 01109 uint32 mode=0; 01110 SMB_OFF_T file_size = 0; 01111 SMB_BIG_UINT allocation_size = 0; 01112 uint32 len; 01113 struct timespec mdate_ts, adate_ts, create_date_ts; 01114 time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0; 01115 char *nameptr; 01116 char *last_entry_ptr; 01117 BOOL was_8_3; 01118 uint32 nt_extmode; /* Used for NT connections instead of mode */ 01119 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/'); 01120 BOOL check_mangled_names = lp_manglednames(conn->params); 01121 01122 *fname = 0; 01123 *out_of_space = False; 01124 *got_exact_match = False; 01125 01126 ZERO_STRUCT(mdate_ts); 01127 ZERO_STRUCT(adate_ts); 01128 ZERO_STRUCT(create_date_ts); 01129 01130 if (!conn->dirptr) 01131 return(False); 01132 01133 p = strrchr_m(path_mask,'/'); 01134 if(p != NULL) { 01135 if(p[1] == '\0') 01136 pstrcpy(mask,"*.*"); 01137 else 01138 pstrcpy(mask, p+1); 01139 } else 01140 pstrcpy(mask, path_mask); 01141 01142 01143 while (!found) { 01144 BOOL got_match; 01145 BOOL ms_dfs_link = False; 01146 01147 /* Needed if we run out of space */ 01148 long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr); 01149 dname = dptr_ReadDirName(conn->dirptr,&curr_dirpos,&sbuf); 01150 01151 /* 01152 * Due to bugs in NT client redirectors we are not using 01153 * resume keys any more - set them to zero. 01154 * Check out the related comments in findfirst/findnext. 01155 * JRA. 01156 */ 01157 01158 reskey = 0; 01159 01160 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %ld\n", 01161 (long)conn->dirptr,curr_dirpos)); 01162 01163 if (!dname) 01164 return(False); 01165 01166 pstrcpy(fname,dname); 01167 01168 if(!(got_match = *got_exact_match = exact_match(conn, fname, mask))) 01169 got_match = mask_match(fname, mask, conn->case_sensitive); 01170 01171 if(!got_match && check_mangled_names && 01172 !mangle_is_8_3(fname, False, conn->params)) { 01173 01174 /* 01175 * It turns out that NT matches wildcards against 01176 * both long *and* short names. This may explain some 01177 * of the wildcard wierdness from old DOS clients 01178 * that some people have been seeing.... JRA. 01179 */ 01180 01181 pstring newname; 01182 pstrcpy( newname, fname); 01183 mangle_map( newname, True, False, conn->params); 01184 if(!(got_match = *got_exact_match = exact_match(conn, newname, mask))) 01185 got_match = mask_match(newname, mask, conn->case_sensitive); 01186 } 01187 01188 if(got_match) { 01189 BOOL isdots = (strequal(fname,"..") || strequal(fname,".")); 01190 if (dont_descend && !isdots) 01191 continue; 01192 01193 pstrcpy(pathreal,conn->dirpath); 01194 if(needslash) 01195 pstrcat(pathreal,"/"); 01196 pstrcat(pathreal,dname); 01197 01198 if (INFO_LEVEL_IS_UNIX(info_level)) { 01199 if (SMB_VFS_LSTAT(conn,pathreal,&sbuf) != 0) { 01200 DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n", 01201 pathreal,strerror(errno))); 01202 continue; 01203 } 01204 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) { 01205 pstring link_target; 01206 01207 /* Needed to show the msdfs symlinks as 01208 * directories */ 01209 01210 if(lp_host_msdfs() && 01211 lp_msdfs_root(SNUM(conn)) && 01212 ((ms_dfs_link = is_msdfs_link(conn, pathreal, link_target, &sbuf)) == True)) { 01213 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s " 01214 "as a directory\n", 01215 pathreal)); 01216 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR; 01217 01218 } else { 01219 01220 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n", 01221 pathreal,strerror(errno))); 01222 continue; 01223 } 01224 } 01225 01226 if (ms_dfs_link) { 01227 mode = dos_mode_msdfs(conn,pathreal,&sbuf); 01228 } else { 01229 mode = dos_mode(conn,pathreal,&sbuf); 01230 } 01231 01232 if (!dir_check_ftype(conn,mode,dirtype)) { 01233 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype)); 01234 continue; 01235 } 01236 01237 if (!(mode & aDIR)) 01238 file_size = get_file_size(sbuf); 01239 allocation_size = get_allocation_size(conn,NULL,&sbuf); 01240 01241 mdate_ts = get_mtimespec(&sbuf); 01242 adate_ts = get_atimespec(&sbuf); 01243 create_date_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn))); 01244 01245 if (lp_dos_filetime_resolution(SNUM(conn))) { 01246 dos_filetime_timespec(&create_date_ts); 01247 dos_filetime_timespec(&mdate_ts); 01248 dos_filetime_timespec(&adate_ts); 01249 } 01250 01251 create_date = convert_timespec_to_time_t(create_date_ts); 01252 mdate = convert_timespec_to_time_t(mdate_ts); 01253 adate = convert_timespec_to_time_t(adate_ts); 01254 01255 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname)); 01256 01257 found = True; 01258 01259 dptr_DirCacheAdd(conn->dirptr, dname, curr_dirpos); 01260 } 01261 } 01262 01263 mangle_map(fname,False,True,conn->params); 01264 01265 p = pdata; 01266 last_entry_ptr = p; 01267 01268 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL; 01269 01270 switch (info_level) { 01271 case SMB_FIND_INFO_STANDARD: 01272 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_INFO_STANDARD\n")); 01273 if(requires_resume_key) { 01274 SIVAL(p,0,reskey); 01275 p += 4; 01276 } 01277 srv_put_dos_date2(p,0,create_date); 01278 srv_put_dos_date2(p,4,adate); 01279 srv_put_dos_date2(p,8,mdate); 01280 SIVAL(p,12,(uint32)file_size); 01281 SIVAL(p,16,(uint32)allocation_size); 01282 SSVAL(p,20,mode); 01283 p += 23; 01284 nameptr = p; 01285 p += align_string(outbuf, p, 0); 01286 len = srvstr_push(outbuf, p, fname, PTR_DIFF(end_data, p), STR_TERMINATE); 01287 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) { 01288 if (len > 2) { 01289 SCVAL(nameptr, -1, len - 2); 01290 } else { 01291 SCVAL(nameptr, -1, 0); 01292 } 01293 } else { 01294 if (len > 1) { 01295 SCVAL(nameptr, -1, len - 1); 01296 } else { 01297 SCVAL(nameptr, -1, 0); 01298 } 01299 } 01300 p += len; 01301 break; 01302 01303 case SMB_FIND_EA_SIZE: 01304 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_SIZE\n")); 01305 if(requires_resume_key) { 01306 SIVAL(p,0,reskey); 01307 p += 4; 01308 } 01309 srv_put_dos_date2(p,0,create_date); 01310 srv_put_dos_date2(p,4,adate); 01311 srv_put_dos_date2(p,8,mdate); 01312 SIVAL(p,12,(uint32)file_size); 01313 SIVAL(p,16,(uint32)allocation_size); 01314 SSVAL(p,20,mode); 01315 { 01316 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal); 01317 SIVAL(p,22,ea_size); /* Extended attributes */ 01318 } 01319 p += 27; 01320 nameptr = p - 1; 01321 len = srvstr_push(outbuf, p, fname, PTR_DIFF(end_data, p), STR_TERMINATE | STR_NOALIGN); 01322 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) { 01323 if (len > 2) { 01324 len -= 2; 01325 } else { 01326 len = 0; 01327 } 01328 } else { 01329 if (len > 1) { 01330 len -= 1; 01331 } else { 01332 len = 0; 01333 } 01334 } 01335 SCVAL(nameptr,0,len); 01336 p += len; 01337 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */ 01338 break; 01339 01340 case SMB_FIND_EA_LIST: 01341 { 01342 struct ea_list *file_list = NULL; 01343 size_t ea_len = 0; 01344 01345 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_LIST\n")); 01346 if (!name_list) { 01347 return False; 01348 } 01349 if(requires_resume_key) { 01350 SIVAL(p,0,reskey); 01351 p += 4; 01352 } 01353 srv_put_dos_date2(p,0,create_date); 01354 srv_put_dos_date2(p,4,adate); 01355 srv_put_dos_date2(p,8,mdate); 01356 SIVAL(p,12,(uint32)file_size); 01357 SIVAL(p,16,(uint32)allocation_size); 01358 SSVAL(p,20,mode); 01359 p += 22; /* p now points to the EA area. */ 01360 01361 file_list = get_ea_list_from_file(ea_ctx, conn, NULL, pathreal, &ea_len); 01362 name_list = ea_list_union(name_list, file_list, &ea_len); 01363 01364 /* We need to determine if this entry will fit in the space available. */ 01365 /* Max string size is 255 bytes. */ 01366 if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) { 01367 /* Move the dirptr back to prev_dirpos */ 01368 dptr_SeekDir(conn->dirptr, prev_dirpos); 01369 *out_of_space = True; 01370 DEBUG(9,("get_lanman2_dir_entry: out of space\n")); 01371 return False; /* Not finished - just out of space */ 01372 } 01373 01374 /* Push the ea_data followed by the name. */ 01375 p += fill_ea_buffer(ea_ctx, p, space_remaining - (p - pdata), conn, name_list); 01376 nameptr = p; 01377 len = srvstr_push(outbuf, p + 1, fname, PTR_DIFF(end_data, p+1), STR_TERMINATE | STR_NOALIGN); 01378 if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) { 01379 if (len > 2) { 01380 len -= 2; 01381 } else { 01382 len = 0; 01383 } 01384 } else { 01385 if (len > 1) { 01386 len -= 1; 01387 } else { 01388 len = 0; 01389 } 01390 } 01391 SCVAL(nameptr,0,len); 01392 p += len + 1; 01393 SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */ 01394 break; 01395 } 01396 01397 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO: 01398 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n")); 01399 was_8_3 = mangle_is_8_3(fname, True, conn->params); 01400 p += 4; 01401 SIVAL(p,0,reskey); p += 4; 01402 put_long_date_timespec(p,create_date_ts); p += 8; 01403 put_long_date_timespec(p,adate_ts); p += 8; 01404 put_long_date_timespec(p,mdate_ts); p += 8; 01405 put_long_date_timespec(p,mdate_ts); p += 8; 01406 SOFF_T(p,0,file_size); p += 8; 01407 SOFF_T(p,0,allocation_size); p += 8; 01408 SIVAL(p,0,nt_extmode); p += 4; 01409 q = p; p += 4; /* q is placeholder for name length. */ 01410 { 01411 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal); 01412 SIVAL(p,0,ea_size); /* Extended attributes */ 01413 p += 4; 01414 } 01415 /* Clear the short name buffer. This is 01416 * IMPORTANT as not doing so will trigger 01417 * a Win2k client bug. JRA. 01418 */ 01419 if (!was_8_3 && check_mangled_names) { 01420 pstring mangled_name; 01421 pstrcpy(mangled_name, fname); 01422 mangle_map(mangled_name,True,True, 01423 conn->params); 01424 mangled_name[12] = 0; 01425 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE); 01426 if (len < 24) { 01427 memset(p + 2 + len,'\0',24 - len); 01428 } 01429 SSVAL(p, 0, len); 01430 } else { 01431 memset(p,'\0',26); 01432 } 01433 p += 2 + 24; 01434 len = srvstr_push(outbuf, p, fname, PTR_DIFF(end_data, p), STR_TERMINATE_ASCII); 01435 SIVAL(q,0,len); 01436 p += len; 01437 SIVAL(p,0,0); /* Ensure any padding is null. */ 01438 len = PTR_DIFF(p, pdata); 01439 len = (len + 3) & ~3; 01440 SIVAL(pdata,0,len); 01441 p = pdata + len; 01442 break; 01443 01444 case SMB_FIND_FILE_DIRECTORY_INFO: 01445 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n")); 01446 p += 4; 01447 SIVAL(p,0,reskey); p += 4; 01448 put_long_date_timespec(p,create_date_ts); p += 8; 01449 put_long_date_timespec(p,adate_ts); p += 8; 01450 put_long_date_timespec(p,mdate_ts); p += 8; 01451 put_long_date_timespec(p,mdate_ts); p += 8; 01452 SOFF_T(p,0,file_size); p += 8; 01453 SOFF_T(p,0,allocation_size); p += 8; 01454 SIVAL(p,0,nt_extmode); p += 4; 01455 len = srvstr_push(outbuf, p + 4, fname, PTR_DIFF(end_data, p+4), STR_TERMINATE_ASCII); 01456 SIVAL(p,0,len); 01457 p += 4 + len; 01458 SIVAL(p,0,0); /* Ensure any padding is null. */ 01459 len = PTR_DIFF(p, pdata); 01460 len = (len + 3) & ~3; 01461 SIVAL(pdata,0,len); 01462 p = pdata + len; 01463 break; 01464 01465 case SMB_FIND_FILE_FULL_DIRECTORY_INFO: 01466 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n")); 01467 p += 4; 01468 SIVAL(p,0,reskey); p += 4; 01469 put_long_date_timespec(p,create_date_ts); p += 8; 01470 put_long_date_timespec(p,adate_ts); p += 8; 01471 put_long_date_timespec(p,mdate_ts); p += 8; 01472 put_long_date_timespec(p,mdate_ts); p += 8; 01473 SOFF_T(p,0,file_size); p += 8; 01474 SOFF_T(p,0,allocation_size); p += 8; 01475 SIVAL(p,0,nt_extmode); p += 4; 01476 q = p; p += 4; /* q is placeholder for name length. */ 01477 { 01478 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal); 01479 SIVAL(p,0,ea_size); /* Extended attributes */ 01480 p +=4; 01481 } 01482 len = srvstr_push(outbuf, p, fname, PTR_DIFF(end_data, p), STR_TERMINATE_ASCII); 01483 SIVAL(q, 0, len); 01484 p += len; 01485 01486 SIVAL(p,0,0); /* Ensure any padding is null. */ 01487 len = PTR_DIFF(p, pdata); 01488 len = (len + 3) & ~3; 01489 SIVAL(pdata,0,len); 01490 p = pdata + len; 01491 break; 01492 01493 case SMB_FIND_FILE_NAMES_INFO: 01494 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n")); 01495 p += 4; 01496 SIVAL(p,0,reskey); p += 4; 01497 p += 4; 01498 /* this must *not* be null terminated or w2k gets in a loop trying to set an 01499 acl on a dir (tridge) */ 01500 len = srvstr_push(outbuf, p, fname, PTR_DIFF(end_data, p), STR_TERMINATE_ASCII); 01501 SIVAL(p, -4, len); 01502 p += len; 01503 SIVAL(p,0,0); /* Ensure any padding is null. */ 01504 len = PTR_DIFF(p, pdata); 01505 len = (len + 3) & ~3; 01506 SIVAL(pdata,0,len); 01507 p = pdata + len; 01508 break; 01509 01510 case SMB_FIND_ID_FULL_DIRECTORY_INFO: 01511 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n")); 01512 p += 4; 01513 SIVAL(p,0,reskey); p += 4; 01514 put_long_date_timespec(p,create_date_ts); p += 8; 01515 put_long_date_timespec(p,adate_ts); p += 8; 01516 put_long_date_timespec(p,mdate_ts); p += 8; 01517 put_long_date_timespec(p,mdate_ts); p += 8; 01518 SOFF_T(p,0,file_size); p += 8; 01519 SOFF_T(p,0,allocation_size); p += 8; 01520 SIVAL(p,0,nt_extmode); p += 4; 01521 q = p; p += 4; /* q is placeholder for name length. */ 01522 { 01523 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal); 01524 SIVAL(p,0,ea_size); /* Extended attributes */ 01525 p +=4; 01526 } 01527 SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */ 01528 SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */ 01529 SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */ 01530 len = srvstr_push(outbuf, p, fname, PTR_DIFF(end_data, p), STR_TERMINATE_ASCII); 01531 SIVAL(q, 0, len); 01532 p += len; 01533 SIVAL(p,0,0); /* Ensure any padding is null. */ 01534 len = PTR_DIFF(p, pdata); 01535 len = (len + 3) & ~3; 01536 SIVAL(pdata,0,len); 01537 p = pdata + len; 01538 break; 01539 01540 case SMB_FIND_ID_BOTH_DIRECTORY_INFO: 01541 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n")); 01542 was_8_3 = mangle_is_8_3(fname, True, conn->params); 01543 p += 4; 01544 SIVAL(p,0,reskey); p += 4; 01545 put_long_date_timespec(p,create_date_ts); p += 8; 01546 put_long_date_timespec(p,adate_ts); p += 8; 01547 put_long_date_timespec(p,mdate_ts); p += 8; 01548 put_long_date_timespec(p,mdate_ts); p += 8; 01549 SOFF_T(p,0,file_size); p += 8; 01550 SOFF_T(p,0,allocation_size); p += 8; 01551 SIVAL(p,0,nt_extmode); p += 4; 01552 q = p; p += 4; /* q is placeholder for name length */ 01553 { 01554 unsigned int ea_size = estimate_ea_size(conn, NULL, pathreal); 01555 SIVAL(p,0,ea_size); /* Extended attributes */ 01556 p +=4; 01557 } 01558 /* Clear the short name buffer. This is 01559 * IMPORTANT as not doing so will trigger 01560 * a Win2k client bug. JRA. 01561 */ 01562 if (!was_8_3 && check_mangled_names) { 01563 pstring mangled_name; 01564 pstrcpy(mangled_name, fname); 01565 mangle_map(mangled_name,True,True, 01566 conn->params); 01567 mangled_name[12] = 0; 01568 len = srvstr_push(outbuf, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE); 01569 SSVAL(p, 0, len); 01570 if (len < 24) { 01571 memset(p + 2 + len,'\0',24 - len); 01572 } 01573 SSVAL(p, 0, len); 01574 } else { 01575 memset(p,'\0',26); 01576 } 01577 p += 26; 01578 SSVAL(p,0,0); p += 2; /* Reserved ? */ 01579 SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */ 01580 SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */ 01581 len = srvstr_push(outbuf, p, fname, PTR_DIFF(end_data, p), STR_TERMINATE_ASCII); 01582 SIVAL(q,0,len); 01583 p += len; 01584 SIVAL(p,0,0); /* Ensure any padding is null. */ 01585 len = PTR_DIFF(p, pdata); 01586 len = (len + 3) & ~3; 01587 SIVAL(pdata,0,len); 01588 p = pdata + len; 01589 break; 01590 01591 /* CIFS UNIX Extension. */ 01592 01593 case SMB_FIND_FILE_UNIX: 01594 case SMB_FIND_FILE_UNIX_INFO2: 01595 p+= 4; 01596 SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */ 01597 01598 /* Begin of SMB_QUERY_FILE_UNIX_BASIC */ 01599 01600 if (info_level == SMB_FIND_FILE_UNIX) { 01601 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n")); 01602 p = store_file_unix_basic(conn, p, 01603 NULL, &sbuf); 01604 len = srvstr_push(outbuf, p, fname, PTR_DIFF(end_data, p), STR_TERMINATE); 01605 } else { 01606 DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n")); 01607 p = store_file_unix_basic_info2(conn, p, 01608 NULL, &sbuf); 01609 nameptr = p; 01610 p += 4; 01611 len = srvstr_push(outbuf, p, fname, PTR_DIFF(end_data, p), 0); 01612 SIVAL(nameptr, 0, len); 01613 } 01614 01615 p += len; 01616 SIVAL(p,0,0); /* Ensure any padding is null. */ 01617 01618 len = PTR_DIFF(p, pdata); 01619 len = (len + 3) & ~3; 01620 SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */ 01621 p = pdata + len; 01622 /* End of SMB_QUERY_FILE_UNIX_BASIC */ 01623 01624 break; 01625 01626 default: 01627 return(False); 01628 } 01629 01630 01631 if (PTR_DIFF(p,pdata) > space_remaining) { 01632 /* Move the dirptr back to prev_dirpos */ 01633 dptr_SeekDir(conn->dirptr, prev_dirpos); 01634 *out_of_space = True; 01635 DEBUG(9,("get_lanman2_dir_entry: out of space\n")); 01636 return False; /* Not finished - just out of space */ 01637 } 01638 01639 /* Setup the last entry pointer, as an offset from base_data */ 01640 *last_entry_off = PTR_DIFF(last_entry_ptr,base_data); 01641 /* Advance the data pointer to the next slot */ 01642 *ppdata = p; 01643 01644 return(found); 01645 }
static int call_trans2findfirst | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | bufsize, | |||
char ** | pparams, | |||
int | total_params, | |||
char ** | ppdata, | |||
int | total_data, | |||
unsigned int | max_data_bytes | |||
) | [static] |
参照先 connection_struct::case_sensitive・check_name()・connection_struct::dirpath・connection_struct::dirptr・dptr_close()・dptr_create()・dptr_dnum()・dptr_path()・get_lanman2_dir_entry()・in_list()・mangle_is_8_3_wildcards()・mangle_map()・ntstatus・connection_struct::params・Protocol・PROTOCOL_NT1・read_ea_name_list()・resolve_dfspath_wcard()・send_trans2_replies()・smb_fn_name()・srvstr_get_path_wcard()・strrchr_m()・talloc_init()・unix_convert().
参照元 handle_trans2().
01654 { 01655 /* We must be careful here that we don't return more than the 01656 allowed number of data bytes. If this means returning fewer than 01657 maxentries then so be it. We assume that the redirector has 01658 enough room for the fixed number of parameter bytes it has 01659 requested. */ 01660 char *params = *pparams; 01661 char *pdata = *ppdata; 01662 char *data_end; 01663 uint32 dirtype; 01664 int maxentries; 01665 uint16 findfirst_flags; 01666 BOOL close_after_first; 01667 BOOL close_if_end; 01668 BOOL requires_resume_key; 01669 int info_level; 01670 pstring directory; 01671 pstring mask; 01672 char *p; 01673 int last_entry_off=0; 01674 int dptr_num = -1; 01675 int numentries = 0; 01676 int i; 01677 BOOL finished = False; 01678 BOOL dont_descend = False; 01679 BOOL out_of_space = False; 01680 int space_remaining; 01681 BOOL mask_contains_wcard = False; 01682 SMB_STRUCT_STAT sbuf; 01683 TALLOC_CTX *ea_ctx = NULL; 01684 struct ea_list *ea_list = NULL; 01685 NTSTATUS ntstatus = NT_STATUS_OK; 01686 01687 if (total_params < 13) { 01688 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 01689 } 01690 01691 dirtype = SVAL(params,0); 01692 maxentries = SVAL(params,2); 01693 findfirst_flags = SVAL(params,4); 01694 close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE); 01695 close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END); 01696 requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME); 01697 info_level = SVAL(params,6); 01698 01699 *directory = *mask = 0; 01700 01701 DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \ 01702 close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", 01703 (unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key, 01704 info_level, max_data_bytes)); 01705 01706 if (!maxentries) { 01707 /* W2K3 seems to treat zero as 1. */ 01708 maxentries = 1; 01709 } 01710 01711 switch (info_level) { 01712 case SMB_FIND_INFO_STANDARD: 01713 case SMB_FIND_EA_SIZE: 01714 case SMB_FIND_EA_LIST: 01715 case SMB_FIND_FILE_DIRECTORY_INFO: 01716 case SMB_FIND_FILE_FULL_DIRECTORY_INFO: 01717 case SMB_FIND_FILE_NAMES_INFO: 01718 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO: 01719 case SMB_FIND_ID_FULL_DIRECTORY_INFO: 01720 case SMB_FIND_ID_BOTH_DIRECTORY_INFO: 01721 break; 01722 case SMB_FIND_FILE_UNIX: 01723 case SMB_FIND_FILE_UNIX_INFO2: 01724 if (!lp_unix_extensions()) { 01725 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 01726 } 01727 break; 01728 default: 01729 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 01730 } 01731 01732 srvstr_get_path_wcard(inbuf, directory, params+12, sizeof(directory), total_params - 12, STR_TERMINATE, &ntstatus, &mask_contains_wcard); 01733 if (!NT_STATUS_IS_OK(ntstatus)) { 01734 return ERROR_NT(ntstatus); 01735 } 01736 01737 ntstatus = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, directory, &mask_contains_wcard); 01738 if (!NT_STATUS_IS_OK(ntstatus)) { 01739 if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) { 01740 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 01741 } 01742 return ERROR_NT(ntstatus); 01743 } 01744 01745 ntstatus = unix_convert(conn, directory, True, NULL, &sbuf); 01746 if (!NT_STATUS_IS_OK(ntstatus)) { 01747 return ERROR_NT(ntstatus); 01748 } 01749 ntstatus = check_name(conn, directory); 01750 if (!NT_STATUS_IS_OK(ntstatus)) { 01751 return ERROR_NT(ntstatus); 01752 } 01753 01754 p = strrchr_m(directory,'/'); 01755 if(p == NULL) { 01756 /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */ 01757 if((directory[0] == '.') && (directory[1] == '\0')) { 01758 pstrcpy(mask,"*"); 01759 mask_contains_wcard = True; 01760 } else { 01761 pstrcpy(mask,directory); 01762 } 01763 pstrcpy(directory,"./"); 01764 } else { 01765 pstrcpy(mask,p+1); 01766 *p = 0; 01767 } 01768 01769 DEBUG(5,("dir=%s, mask = %s\n",directory, mask)); 01770 01771 if (info_level == SMB_FIND_EA_LIST) { 01772 uint32 ea_size; 01773 01774 if (total_data < 4) { 01775 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 01776 } 01777 01778 ea_size = IVAL(pdata,0); 01779 if (ea_size != total_data) { 01780 DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \ 01781 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) )); 01782 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 01783 } 01784 01785 if (!lp_ea_support(SNUM(conn))) { 01786 return ERROR_DOS(ERRDOS,ERReasnotsupported); 01787 } 01788 01789 if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) { 01790 return ERROR_NT(NT_STATUS_NO_MEMORY); 01791 } 01792 01793 /* Pull out the list of names. */ 01794 ea_list = read_ea_name_list(ea_ctx, pdata + 4, ea_size - 4); 01795 if (!ea_list) { 01796 talloc_destroy(ea_ctx); 01797 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 01798 } 01799 } 01800 01801 *ppdata = (char *)SMB_REALLOC( 01802 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); 01803 if(*ppdata == NULL ) { 01804 talloc_destroy(ea_ctx); 01805 return ERROR_NT(NT_STATUS_NO_MEMORY); 01806 } 01807 pdata = *ppdata; 01808 data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1; 01809 01810 /* Realloc the params space */ 01811 *pparams = (char *)SMB_REALLOC(*pparams, 10); 01812 if (*pparams == NULL) { 01813 talloc_destroy(ea_ctx); 01814 return ERROR_NT(NT_STATUS_NO_MEMORY); 01815 } 01816 params = *pparams; 01817 01818 /* Save the wildcard match and attribs we are using on this directory - 01819 needed as lanman2 assumes these are being saved between calls */ 01820 01821 ntstatus = dptr_create(conn, 01822 directory, 01823 False, 01824 True, 01825 SVAL(inbuf,smb_pid), 01826 mask, 01827 mask_contains_wcard, 01828 dirtype, 01829 &conn->dirptr); 01830 01831 if (!NT_STATUS_IS_OK(ntstatus)) { 01832 talloc_destroy(ea_ctx); 01833 return ERROR_NT(ntstatus); 01834 } 01835 01836 dptr_num = dptr_dnum(conn->dirptr); 01837 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype)); 01838 01839 /* We don't need to check for VOL here as this is returned by 01840 a different TRANS2 call. */ 01841 01842 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn)))); 01843 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive)) 01844 dont_descend = True; 01845 01846 p = pdata; 01847 space_remaining = max_data_bytes; 01848 out_of_space = False; 01849 01850 for (i=0;(i<maxentries) && !finished && !out_of_space;i++) { 01851 BOOL got_exact_match = False; 01852 01853 /* this is a heuristic to avoid seeking the dirptr except when 01854 absolutely necessary. It allows for a filename of about 40 chars */ 01855 if (space_remaining < DIRLEN_GUESS && numentries > 0) { 01856 out_of_space = True; 01857 finished = False; 01858 } else { 01859 finished = !get_lanman2_dir_entry(conn, 01860 inbuf, outbuf, 01861 mask,dirtype,info_level, 01862 requires_resume_key,dont_descend, 01863 &p,pdata,data_end,space_remaining, &out_of_space, &got_exact_match, 01864 &last_entry_off, ea_list, ea_ctx); 01865 } 01866 01867 if (finished && out_of_space) 01868 finished = False; 01869 01870 if (!finished && !out_of_space) 01871 numentries++; 01872 01873 /* 01874 * As an optimisation if we know we aren't looking 01875 * for a wildcard name (ie. the name matches the wildcard exactly) 01876 * then we can finish on any (first) match. 01877 * This speeds up large directory searches. JRA. 01878 */ 01879 01880 if(got_exact_match) 01881 finished = True; 01882 01883 space_remaining = max_data_bytes - PTR_DIFF(p,pdata); 01884 } 01885 01886 talloc_destroy(ea_ctx); 01887 01888 /* Check if we can close the dirptr */ 01889 if(close_after_first || (finished && close_if_end)) { 01890 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num)); 01891 dptr_close(&dptr_num); 01892 } 01893 01894 /* 01895 * If there are no matching entries we must return ERRDOS/ERRbadfile - 01896 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if 01897 * the protocol level is less than NT1. Tested with smbclient. JRA. 01898 * This should fix the OS/2 client bug #2335. 01899 */ 01900 01901 if(numentries == 0) { 01902 dptr_close(&dptr_num); 01903 if (Protocol < PROTOCOL_NT1) { 01904 return ERROR_DOS(ERRDOS,ERRnofiles); 01905 } else { 01906 return ERROR_BOTH(NT_STATUS_NO_SUCH_FILE,ERRDOS,ERRbadfile); 01907 } 01908 } 01909 01910 /* At this point pdata points to numentries directory entries. */ 01911 01912 /* Set up the return parameter block */ 01913 SSVAL(params,0,dptr_num); 01914 SSVAL(params,2,numentries); 01915 SSVAL(params,4,finished); 01916 SSVAL(params,6,0); /* Never an EA error */ 01917 SSVAL(params,8,last_entry_off); 01918 01919 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata), max_data_bytes); 01920 01921 if ((! *directory) && dptr_path(dptr_num)) 01922 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num)); 01923 01924 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n", 01925 smb_fn_name(CVAL(inbuf,smb_com)), 01926 mask, directory, dirtype, numentries ) ); 01927 01928 /* 01929 * Force a name mangle here to ensure that the 01930 * mask as an 8.3 name is top of the mangled cache. 01931 * The reasons for this are subtle. Don't remove 01932 * this code unless you know what you are doing 01933 * (see PR#13758). JRA. 01934 */ 01935 01936 if(!mangle_is_8_3_wildcards( mask, False, conn->params)) 01937 mangle_map(mask, True, True, conn->params); 01938 01939 return(-1); 01940 }
static int call_trans2findnext | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize, | |||
char ** | pparams, | |||
int | total_params, | |||
char ** | ppdata, | |||
int | total_data, | |||
unsigned int | max_data_bytes | |||
) | [static] |
参照先 connection_struct::case_sensitive・connection_struct::dirpath・connection_struct::dirptr・dptr_attr()・dptr_close()・dptr_fetch_lanman2()・dptr_path()・dptr_SearchDir()・dptr_TellDir()・dptr_wcard()・get_lanman2_dir_entry()・in_list()・mangle_check_cache()・mangle_is_mangled()・ntstatus・connection_struct::params・read_ea_name_list()・send_trans2_replies()・smb_fn_name()・srvstr_get_path_wcard()・string_set()・talloc_init().
参照元 handle_trans2().
01949 { 01950 /* We must be careful here that we don't return more than the 01951 allowed number of data bytes. If this means returning fewer than 01952 maxentries then so be it. We assume that the redirector has 01953 enough room for the fixed number of parameter bytes it has 01954 requested. */ 01955 char *params = *pparams; 01956 char *pdata = *ppdata; 01957 char *data_end; 01958 int dptr_num; 01959 int maxentries; 01960 uint16 info_level; 01961 uint32 resume_key; 01962 uint16 findnext_flags; 01963 BOOL close_after_request; 01964 BOOL close_if_end; 01965 BOOL requires_resume_key; 01966 BOOL continue_bit; 01967 BOOL mask_contains_wcard = False; 01968 pstring resume_name; 01969 pstring mask; 01970 pstring directory; 01971 char *p; 01972 uint16 dirtype; 01973 int numentries = 0; 01974 int i, last_entry_off=0; 01975 BOOL finished = False; 01976 BOOL dont_descend = False; 01977 BOOL out_of_space = False; 01978 int space_remaining; 01979 TALLOC_CTX *ea_ctx = NULL; 01980 struct ea_list *ea_list = NULL; 01981 NTSTATUS ntstatus = NT_STATUS_OK; 01982 01983 if (total_params < 13) { 01984 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 01985 } 01986 01987 dptr_num = SVAL(params,0); 01988 maxentries = SVAL(params,2); 01989 info_level = SVAL(params,4); 01990 resume_key = IVAL(params,6); 01991 findnext_flags = SVAL(params,10); 01992 close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE); 01993 close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END); 01994 requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME); 01995 continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE); 01996 01997 *mask = *directory = *resume_name = 0; 01998 01999 srvstr_get_path_wcard(inbuf, resume_name, params+12, sizeof(resume_name), total_params - 12, STR_TERMINATE, &ntstatus, &mask_contains_wcard); 02000 if (!NT_STATUS_IS_OK(ntstatus)) { 02001 /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to 02002 complain (it thinks we're asking for the directory above the shared 02003 path or an invalid name). Catch this as the resume name is only compared, never used in 02004 a file access. JRA. */ 02005 srvstr_pull(inbuf, resume_name, params+12, 02006 sizeof(resume_name), total_params - 12, 02007 STR_TERMINATE); 02008 02009 if (!(ISDOT(resume_name) || ISDOTDOT(resume_name))) { 02010 return ERROR_NT(ntstatus); 02011 } 02012 } 02013 02014 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \ 02015 close_after_request=%d, close_if_end = %d requires_resume_key = %d \ 02016 resume_key = %d resume name = %s continue=%d level = %d\n", 02017 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end, 02018 requires_resume_key, resume_key, resume_name, continue_bit, info_level)); 02019 02020 if (!maxentries) { 02021 /* W2K3 seems to treat zero as 1. */ 02022 maxentries = 1; 02023 } 02024 02025 switch (info_level) { 02026 case SMB_FIND_INFO_STANDARD: 02027 case SMB_FIND_EA_SIZE: 02028 case SMB_FIND_EA_LIST: 02029 case SMB_FIND_FILE_DIRECTORY_INFO: 02030 case SMB_FIND_FILE_FULL_DIRECTORY_INFO: 02031 case SMB_FIND_FILE_NAMES_INFO: 02032 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO: 02033 case SMB_FIND_ID_FULL_DIRECTORY_INFO: 02034 case SMB_FIND_ID_BOTH_DIRECTORY_INFO: 02035 break; 02036 case SMB_FIND_FILE_UNIX: 02037 case SMB_FIND_FILE_UNIX_INFO2: 02038 if (!lp_unix_extensions()) { 02039 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 02040 } 02041 break; 02042 default: 02043 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 02044 } 02045 02046 if (info_level == SMB_FIND_EA_LIST) { 02047 uint32 ea_size; 02048 02049 if (total_data < 4) { 02050 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 02051 } 02052 02053 ea_size = IVAL(pdata,0); 02054 if (ea_size != total_data) { 02055 DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \ 02056 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) )); 02057 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 02058 } 02059 02060 if (!lp_ea_support(SNUM(conn))) { 02061 return ERROR_DOS(ERRDOS,ERReasnotsupported); 02062 } 02063 02064 if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) { 02065 return ERROR_NT(NT_STATUS_NO_MEMORY); 02066 } 02067 02068 /* Pull out the list of names. */ 02069 ea_list = read_ea_name_list(ea_ctx, pdata + 4, ea_size - 4); 02070 if (!ea_list) { 02071 talloc_destroy(ea_ctx); 02072 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 02073 } 02074 } 02075 02076 *ppdata = (char *)SMB_REALLOC( 02077 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); 02078 if(*ppdata == NULL) { 02079 talloc_destroy(ea_ctx); 02080 return ERROR_NT(NT_STATUS_NO_MEMORY); 02081 } 02082 02083 pdata = *ppdata; 02084 data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1; 02085 02086 /* Realloc the params space */ 02087 *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD); 02088 if(*pparams == NULL ) { 02089 talloc_destroy(ea_ctx); 02090 return ERROR_NT(NT_STATUS_NO_MEMORY); 02091 } 02092 02093 params = *pparams; 02094 02095 /* Check that the dptr is valid */ 02096 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) { 02097 talloc_destroy(ea_ctx); 02098 return ERROR_DOS(ERRDOS,ERRnofiles); 02099 } 02100 02101 string_set(&conn->dirpath,dptr_path(dptr_num)); 02102 02103 /* Get the wildcard mask from the dptr */ 02104 if((p = dptr_wcard(dptr_num))== NULL) { 02105 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num)); 02106 talloc_destroy(ea_ctx); 02107 return ERROR_DOS(ERRDOS,ERRnofiles); 02108 } 02109 02110 pstrcpy(mask, p); 02111 pstrcpy(directory,conn->dirpath); 02112 02113 /* Get the attr mask from the dptr */ 02114 dirtype = dptr_attr(dptr_num); 02115 02116 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n", 02117 dptr_num, mask, dirtype, 02118 (long)conn->dirptr, 02119 dptr_TellDir(conn->dirptr))); 02120 02121 /* We don't need to check for VOL here as this is returned by 02122 a different TRANS2 call. */ 02123 02124 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn)))); 02125 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),conn->case_sensitive)) 02126 dont_descend = True; 02127 02128 p = pdata; 02129 space_remaining = max_data_bytes; 02130 out_of_space = False; 02131 02132 /* 02133 * Seek to the correct position. We no longer use the resume key but 02134 * depend on the last file name instead. 02135 */ 02136 02137 if(*resume_name && !continue_bit) { 02138 SMB_STRUCT_STAT st; 02139 02140 long current_pos = 0; 02141 /* 02142 * Remember, mangle_map is called by 02143 * get_lanman2_dir_entry(), so the resume name 02144 * could be mangled. Ensure we check the unmangled name. 02145 */ 02146 02147 if (mangle_is_mangled(resume_name, conn->params)) { 02148 mangle_check_cache(resume_name, sizeof(resume_name)-1, 02149 conn->params); 02150 } 02151 02152 /* 02153 * Fix for NT redirector problem triggered by resume key indexes 02154 * changing between directory scans. We now return a resume key of 0 02155 * and instead look for the filename to continue from (also given 02156 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the 02157 * findfirst/findnext (as is usual) then the directory pointer 02158 * should already be at the correct place. 02159 */ 02160 02161 finished = !dptr_SearchDir(conn->dirptr, resume_name, ¤t_pos, &st); 02162 } /* end if resume_name && !continue_bit */ 02163 02164 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) { 02165 BOOL got_exact_match = False; 02166 02167 /* this is a heuristic to avoid seeking the dirptr except when 02168 absolutely necessary. It allows for a filename of about 40 chars */ 02169 if (space_remaining < DIRLEN_GUESS && numentries > 0) { 02170 out_of_space = True; 02171 finished = False; 02172 } else { 02173 finished = !get_lanman2_dir_entry(conn, 02174 inbuf, outbuf, 02175 mask,dirtype,info_level, 02176 requires_resume_key,dont_descend, 02177 &p,pdata,data_end,space_remaining, &out_of_space, &got_exact_match, 02178 &last_entry_off, ea_list, ea_ctx); 02179 } 02180 02181 if (finished && out_of_space) 02182 finished = False; 02183 02184 if (!finished && !out_of_space) 02185 numentries++; 02186 02187 /* 02188 * As an optimisation if we know we aren't looking 02189 * for a wildcard name (ie. the name matches the wildcard exactly) 02190 * then we can finish on any (first) match. 02191 * This speeds up large directory searches. JRA. 02192 */ 02193 02194 if(got_exact_match) 02195 finished = True; 02196 02197 space_remaining = max_data_bytes - PTR_DIFF(p,pdata); 02198 } 02199 02200 talloc_destroy(ea_ctx); 02201 02202 /* Check if we can close the dirptr */ 02203 if(close_after_request || (finished && close_if_end)) { 02204 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num)); 02205 dptr_close(&dptr_num); /* This frees up the saved mask */ 02206 } 02207 02208 /* Set up the return parameter block */ 02209 SSVAL(params,0,numentries); 02210 SSVAL(params,2,finished); 02211 SSVAL(params,4,0); /* Never an EA error */ 02212 SSVAL(params,6,last_entry_off); 02213 02214 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata), max_data_bytes); 02215 02216 if ((! *directory) && dptr_path(dptr_num)) 02217 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num)); 02218 02219 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n", 02220 smb_fn_name(CVAL(inbuf,smb_com)), 02221 mask, directory, dirtype, numentries ) ); 02222 02223 return(-1); 02224 }
static void samba_extended_info_version | ( | struct smb_extended_info * | extended_info | ) | [static] |
参照先 smb_extended_info::samba_gitcommitdate・smb_extended_info::samba_magic・smb_extended_info::samba_subversion・smb_extended_info::samba_version・samba_version_string()・smb_extended_info::samba_version_string・snprintf()・unix_to_nt_time().
参照元 call_trans2qfsinfo().
02227 { 02228 SMB_ASSERT(extended_info != NULL); 02229 02230 extended_info->samba_magic = SAMBA_EXTENDED_INFO_MAGIC; 02231 extended_info->samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24) 02232 | ((SAMBA_VERSION_MINOR & 0xff) << 16) 02233 | ((SAMBA_VERSION_RELEASE & 0xff) << 8); 02234 #ifdef SAMBA_VERSION_REVISION 02235 extended_info->samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1) & 0xff; 02236 #endif 02237 extended_info->samba_subversion = 0; 02238 #ifdef SAMBA_VERSION_RC_RELEASE 02239 extended_info->samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24; 02240 #else 02241 #ifdef SAMBA_VERSION_PRE_RELEASE 02242 extended_info->samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16; 02243 #endif 02244 #endif 02245 #ifdef SAMBA_VERSION_VENDOR_PATCH 02246 extended_info->samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff); 02247 #endif 02248 extended_info->samba_subversion = 0; 02249 #ifdef SAMBA_VERSION_GIT_COMMIT_TIME 02250 unix_to_nt_time(&extended_info->samba_gitcommitdate, SAMBA_VERSION_GIT_COMMIT_TIME); 02251 #endif 02252 02253 memset(extended_info->samba_version_string, 0, 02254 sizeof(extended_info->samba_version_string)); 02255 02256 snprintf (extended_info->samba_version_string, 02257 sizeof(extended_info->samba_version_string), 02258 "%s", samba_version_string()); 02259 }
static int call_trans2qfsinfo | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize, | |||
char ** | pparams, | |||
int | total_params, | |||
char ** | ppdata, | |||
int | total_data, | |||
unsigned int | max_data_bytes | |||
) | [static] |
参照先 vfs_statvfs_struct::BlocksAvail・vfs_statvfs_struct::BlockSize・files_struct::conn・current_user・errno・flags・files_struct::fnum・vfs_statvfs_struct::FreeFileNodes・vfs_statvfs_struct::FsIdentifier・get_dfree_info()・get_local_machine_name()・_unix_token::gid・global_sid_Authenticated_Users・global_sid_Builtin_Guests・_unix_token::groups・_SMB_NTQUOTA_STRUCT::hardlim・len・_unix_token::ngroups・nt_token_check_sid()・current_user::nt_user_token・nt_user_token::num_sids・vfs_statvfs_struct::OptimalTransferSize・_SMB_NTQUOTA_STRUCT::qflags・samba_extended_info_version()・smb_extended_info::samba_gitcommitdate・smb_extended_info::samba_magic・smb_extended_info::samba_subversion・smb_extended_info::samba_version・smb_extended_info::samba_version_string・send_trans2_replies()・sid_linearize()・sid_size()・smb_fn_name()・SMB_USER_FS_QUOTA_TYPE・SMB_WHOAMI_GUEST・_SMB_NTQUOTA_STRUCT::softlim・str_checksum()・strequal()・strerror()・vfs_statvfs_struct::TotalBlocks・vfs_statvfs_struct::TotalFileNodes・_unix_token::uid・connection_struct::user・nt_user_token::user_sids・vfs_statvfs_struct::UserBlocksAvail・current_user::ut・vfs_get_ntquota().
参照元 handle_trans2().
02268 { 02269 char *pdata; 02270 char *params = *pparams; 02271 uint16 info_level; 02272 int data_len, len; 02273 SMB_STRUCT_STAT st; 02274 const char *vname = volume_label(SNUM(conn)); 02275 int snum = SNUM(conn); 02276 char *fstype = lp_fstype(SNUM(conn)); 02277 int quota_flag = 0; 02278 02279 if (total_params < 2) { 02280 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 02281 } 02282 02283 info_level = SVAL(params,0); 02284 02285 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level)); 02286 02287 if(SMB_VFS_STAT(conn,".",&st)!=0) { 02288 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno))); 02289 return ERROR_DOS(ERRSRV,ERRinvdevice); 02290 } 02291 02292 *ppdata = (char *)SMB_REALLOC( 02293 *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); 02294 if (*ppdata == NULL ) { 02295 return ERROR_NT(NT_STATUS_NO_MEMORY); 02296 } 02297 02298 pdata = *ppdata; 02299 memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); 02300 02301 switch (info_level) { 02302 case SMB_INFO_ALLOCATION: 02303 { 02304 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; 02305 data_len = 18; 02306 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) { 02307 return(UNIXERROR(ERRHRD,ERRgeneral)); 02308 } 02309 02310 block_size = lp_block_size(snum); 02311 if (bsize < block_size) { 02312 SMB_BIG_UINT factor = block_size/bsize; 02313 bsize = block_size; 02314 dsize /= factor; 02315 dfree /= factor; 02316 } 02317 if (bsize > block_size) { 02318 SMB_BIG_UINT factor = bsize/block_size; 02319 bsize = block_size; 02320 dsize *= factor; 02321 dfree *= factor; 02322 } 02323 bytes_per_sector = 512; 02324 sectors_per_unit = bsize/bytes_per_sector; 02325 02326 DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \ 02327 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit, 02328 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree)); 02329 02330 SIVAL(pdata,l1_idFileSystem,st.st_dev); 02331 SIVAL(pdata,l1_cSectorUnit,sectors_per_unit); 02332 SIVAL(pdata,l1_cUnit,dsize); 02333 SIVAL(pdata,l1_cUnitAvail,dfree); 02334 SSVAL(pdata,l1_cbSector,bytes_per_sector); 02335 break; 02336 } 02337 02338 case SMB_INFO_VOLUME: 02339 /* Return volume name */ 02340 /* 02341 * Add volume serial number - hash of a combination of 02342 * the called hostname and the service name. 02343 */ 02344 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) ); 02345 /* 02346 * Win2k3 and previous mess this up by sending a name length 02347 * one byte short. I believe only older clients (OS/2 Win9x) use 02348 * this call so try fixing this by adding a terminating null to 02349 * the pushed string. The change here was adding the STR_TERMINATE. JRA. 02350 */ 02351 len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, max_data_bytes - l2_vol_szVolLabel, STR_NOALIGN|STR_TERMINATE); 02352 SCVAL(pdata,l2_vol_cch,len); 02353 data_len = l2_vol_szVolLabel + len; 02354 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n", 02355 (unsigned)st.st_ctime, len, vname)); 02356 break; 02357 02358 case SMB_QUERY_FS_ATTRIBUTE_INFO: 02359 case SMB_FS_ATTRIBUTE_INFORMATION: 02360 02361 02362 #if defined(HAVE_SYS_QUOTAS) 02363 quota_flag = FILE_VOLUME_QUOTAS; 02364 #endif 02365 02366 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH| 02367 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)| 02368 FILE_UNICODE_ON_DISK| 02369 quota_flag); /* FS ATTRIBUTES */ 02370 02371 SIVAL(pdata,4,255); /* Max filename component length */ 02372 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it 02373 and will think we can't do long filenames */ 02374 len = srvstr_push(outbuf, pdata+12, fstype, max_data_bytes - 12, STR_UNICODE); 02375 SIVAL(pdata,8,len); 02376 data_len = 12 + len; 02377 break; 02378 02379 case SMB_QUERY_FS_LABEL_INFO: 02380 case SMB_FS_LABEL_INFORMATION: 02381 len = srvstr_push(outbuf, pdata+4, vname, max_data_bytes - 4, 0); 02382 data_len = 4 + len; 02383 SIVAL(pdata,0,len); 02384 break; 02385 02386 case SMB_QUERY_FS_VOLUME_INFO: 02387 case SMB_FS_VOLUME_INFORMATION: 02388 02389 /* 02390 * Add volume serial number - hash of a combination of 02391 * the called hostname and the service name. 02392 */ 02393 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^ 02394 (str_checksum(get_local_machine_name())<<16)); 02395 02396 /* Max label len is 32 characters. */ 02397 len = srvstr_push(outbuf, pdata+18, vname, max_data_bytes - 18, STR_UNICODE); 02398 SIVAL(pdata,12,len); 02399 data_len = 18+len; 02400 02401 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n", 02402 (int)strlen(vname),vname, lp_servicename(snum))); 02403 break; 02404 02405 case SMB_QUERY_FS_SIZE_INFO: 02406 case SMB_FS_SIZE_INFORMATION: 02407 { 02408 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; 02409 data_len = 24; 02410 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) { 02411 return(UNIXERROR(ERRHRD,ERRgeneral)); 02412 } 02413 block_size = lp_block_size(snum); 02414 if (bsize < block_size) { 02415 SMB_BIG_UINT factor = block_size/bsize; 02416 bsize = block_size; 02417 dsize /= factor; 02418 dfree /= factor; 02419 } 02420 if (bsize > block_size) { 02421 SMB_BIG_UINT factor = bsize/block_size; 02422 bsize = block_size; 02423 dsize *= factor; 02424 dfree *= factor; 02425 } 02426 bytes_per_sector = 512; 02427 sectors_per_unit = bsize/bytes_per_sector; 02428 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \ 02429 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit, 02430 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree)); 02431 SBIG_UINT(pdata,0,dsize); 02432 SBIG_UINT(pdata,8,dfree); 02433 SIVAL(pdata,16,sectors_per_unit); 02434 SIVAL(pdata,20,bytes_per_sector); 02435 break; 02436 } 02437 02438 case SMB_FS_FULL_SIZE_INFORMATION: 02439 { 02440 SMB_BIG_UINT dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector; 02441 data_len = 32; 02442 if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (SMB_BIG_UINT)-1) { 02443 return(UNIXERROR(ERRHRD,ERRgeneral)); 02444 } 02445 block_size = lp_block_size(snum); 02446 if (bsize < block_size) { 02447 SMB_BIG_UINT factor = block_size/bsize; 02448 bsize = block_size; 02449 dsize /= factor; 02450 dfree /= factor; 02451 } 02452 if (bsize > block_size) { 02453 SMB_BIG_UINT factor = bsize/block_size; 02454 bsize = block_size; 02455 dsize *= factor; 02456 dfree *= factor; 02457 } 02458 bytes_per_sector = 512; 02459 sectors_per_unit = bsize/bytes_per_sector; 02460 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \ 02461 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit, 02462 (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree)); 02463 SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */ 02464 SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */ 02465 SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */ 02466 SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */ 02467 SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */ 02468 break; 02469 } 02470 02471 case SMB_QUERY_FS_DEVICE_INFO: 02472 case SMB_FS_DEVICE_INFORMATION: 02473 data_len = 8; 02474 SIVAL(pdata,0,0); /* dev type */ 02475 SIVAL(pdata,4,0); /* characteristics */ 02476 break; 02477 02478 #ifdef HAVE_SYS_QUOTAS 02479 case SMB_FS_QUOTA_INFORMATION: 02480 /* 02481 * what we have to send --metze: 02482 * 02483 * Unknown1: 24 NULL bytes 02484 * Soft Quota Treshold: 8 bytes seems like SMB_BIG_UINT or so 02485 * Hard Quota Limit: 8 bytes seems like SMB_BIG_UINT or so 02486 * Quota Flags: 2 byte : 02487 * Unknown3: 6 NULL bytes 02488 * 02489 * 48 bytes total 02490 * 02491 * details for Quota Flags: 02492 * 02493 * 0x0020 Log Limit: log if the user exceeds his Hard Quota 02494 * 0x0010 Log Warn: log if the user exceeds his Soft Quota 02495 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota 02496 * 0x0001 Enable Quotas: enable quota for this fs 02497 * 02498 */ 02499 { 02500 /* we need to fake up a fsp here, 02501 * because its not send in this call 02502 */ 02503 files_struct fsp; 02504 SMB_NTQUOTA_STRUCT quotas; 02505 02506 ZERO_STRUCT(fsp); 02507 ZERO_STRUCT(quotas); 02508 02509 fsp.conn = conn; 02510 fsp.fnum = -1; 02511 02512 /* access check */ 02513 if (current_user.ut.uid != 0) { 02514 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n", 02515 lp_servicename(SNUM(conn)),conn->user)); 02516 return ERROR_DOS(ERRDOS,ERRnoaccess); 02517 } 02518 02519 if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) { 02520 DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn)))); 02521 return ERROR_DOS(ERRSRV,ERRerror); 02522 } 02523 02524 data_len = 48; 02525 02526 DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn)))); 02527 02528 /* Unknown1 24 NULL bytes*/ 02529 SBIG_UINT(pdata,0,(SMB_BIG_UINT)0); 02530 SBIG_UINT(pdata,8,(SMB_BIG_UINT)0); 02531 SBIG_UINT(pdata,16,(SMB_BIG_UINT)0); 02532 02533 /* Default Soft Quota 8 bytes */ 02534 SBIG_UINT(pdata,24,quotas.softlim); 02535 02536 /* Default Hard Quota 8 bytes */ 02537 SBIG_UINT(pdata,32,quotas.hardlim); 02538 02539 /* Quota flag 2 bytes */ 02540 SSVAL(pdata,40,quotas.qflags); 02541 02542 /* Unknown3 6 NULL bytes */ 02543 SSVAL(pdata,42,0); 02544 SIVAL(pdata,44,0); 02545 02546 break; 02547 } 02548 #endif /* HAVE_SYS_QUOTAS */ 02549 case SMB_FS_OBJECTID_INFORMATION: 02550 { 02551 /* 02552 * No object id, but we transmit version information. 02553 */ 02554 struct smb_extended_info extended_info; 02555 samba_extended_info_version (&extended_info); 02556 SIVAL(pdata,16,extended_info.samba_magic); 02557 SIVAL(pdata,20,extended_info.samba_version); 02558 SIVAL(pdata,24,extended_info.samba_subversion); 02559 SBIG_UINT(pdata,28,extended_info.samba_gitcommitdate); 02560 memcpy(pdata+36,extended_info.samba_version_string,28); 02561 data_len = 64; 02562 break; 02563 } 02564 02565 /* 02566 * Query the version and capabilities of the CIFS UNIX extensions 02567 * in use. 02568 */ 02569 02570 case SMB_QUERY_CIFS_UNIX_INFO: 02571 if (!lp_unix_extensions()) { 02572 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 02573 } 02574 data_len = 12; 02575 SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION); 02576 SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION); 02577 /* We have POSIX ACLs, pathname and locking capability. */ 02578 SBIG_UINT(pdata,4,((SMB_BIG_UINT)( 02579 CIFS_UNIX_POSIX_ACLS_CAP| 02580 CIFS_UNIX_POSIX_PATHNAMES_CAP| 02581 CIFS_UNIX_FCNTL_LOCKS_CAP| 02582 CIFS_UNIX_EXTATTR_CAP| 02583 CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP))); 02584 break; 02585 02586 case SMB_QUERY_POSIX_FS_INFO: 02587 { 02588 int rc; 02589 vfs_statvfs_struct svfs; 02590 02591 if (!lp_unix_extensions()) { 02592 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 02593 } 02594 02595 rc = SMB_VFS_STATVFS(conn, ".", &svfs); 02596 02597 if (!rc) { 02598 data_len = 56; 02599 SIVAL(pdata,0,svfs.OptimalTransferSize); 02600 SIVAL(pdata,4,svfs.BlockSize); 02601 SBIG_UINT(pdata,8,svfs.TotalBlocks); 02602 SBIG_UINT(pdata,16,svfs.BlocksAvail); 02603 SBIG_UINT(pdata,24,svfs.UserBlocksAvail); 02604 SBIG_UINT(pdata,32,svfs.TotalFileNodes); 02605 SBIG_UINT(pdata,40,svfs.FreeFileNodes); 02606 SBIG_UINT(pdata,48,svfs.FsIdentifier); 02607 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n")); 02608 #ifdef EOPNOTSUPP 02609 } else if (rc == EOPNOTSUPP) { 02610 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 02611 #endif /* EOPNOTSUPP */ 02612 } else { 02613 DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn)))); 02614 return ERROR_DOS(ERRSRV,ERRerror); 02615 } 02616 break; 02617 } 02618 02619 case SMB_QUERY_POSIX_WHOAMI: 02620 { 02621 uint32_t flags = 0; 02622 uint32_t sid_bytes; 02623 int i; 02624 02625 if (!lp_unix_extensions()) { 02626 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 02627 } 02628 02629 if (max_data_bytes < 40) { 02630 return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL); 02631 } 02632 02633 /* We ARE guest if global_sid_Builtin_Guests is 02634 * in our list of SIDs. 02635 */ 02636 if (nt_token_check_sid(&global_sid_Builtin_Guests, 02637 current_user.nt_user_token)) { 02638 flags |= SMB_WHOAMI_GUEST; 02639 } 02640 02641 /* We are NOT guest if global_sid_Authenticated_Users 02642 * is in our list of SIDs. 02643 */ 02644 if (nt_token_check_sid(&global_sid_Authenticated_Users, 02645 current_user.nt_user_token)) { 02646 flags &= ~SMB_WHOAMI_GUEST; 02647 } 02648 02649 /* NOTE: 8 bytes for UID/GID, irrespective of native 02650 * platform size. This matches 02651 * SMB_QUERY_FILE_UNIX_BASIC and friends. 02652 */ 02653 data_len = 4 /* flags */ 02654 + 4 /* flag mask */ 02655 + 8 /* uid */ 02656 + 8 /* gid */ 02657 + 4 /* ngroups */ 02658 + 4 /* num_sids */ 02659 + 4 /* SID bytes */ 02660 + 4 /* pad/reserved */ 02661 + (current_user.ut.ngroups * 8) 02662 /* groups list */ 02663 + (current_user.nt_user_token->num_sids * 02664 SID_MAX_SIZE) 02665 /* SID list */; 02666 02667 SIVAL(pdata, 0, flags); 02668 SIVAL(pdata, 4, SMB_WHOAMI_MASK); 02669 SBIG_UINT(pdata, 8, (SMB_BIG_UINT)current_user.ut.uid); 02670 SBIG_UINT(pdata, 16, (SMB_BIG_UINT)current_user.ut.gid); 02671 02672 02673 if (data_len >= max_data_bytes) { 02674 /* Potential overflow, skip the GIDs and SIDs. */ 02675 02676 SIVAL(pdata, 24, 0); /* num_groups */ 02677 SIVAL(pdata, 28, 0); /* num_sids */ 02678 SIVAL(pdata, 32, 0); /* num_sid_bytes */ 02679 SIVAL(pdata, 36, 0); /* reserved */ 02680 02681 data_len = 40; 02682 break; 02683 } 02684 02685 SIVAL(pdata, 24, current_user.ut.ngroups); 02686 SIVAL(pdata, 28, 02687 current_user.nt_user_token->num_sids); 02688 02689 /* We walk the SID list twice, but this call is fairly 02690 * infrequent, and I don't expect that it's performance 02691 * sensitive -- jpeach 02692 */ 02693 for (i = 0, sid_bytes = 0; 02694 i < current_user.nt_user_token->num_sids; ++i) { 02695 sid_bytes += 02696 sid_size(¤t_user.nt_user_token->user_sids[i]); 02697 } 02698 02699 /* SID list byte count */ 02700 SIVAL(pdata, 32, sid_bytes); 02701 02702 /* 4 bytes pad/reserved - must be zero */ 02703 SIVAL(pdata, 36, 0); 02704 data_len = 40; 02705 02706 /* GID list */ 02707 for (i = 0; i < current_user.ut.ngroups; ++i) { 02708 SBIG_UINT(pdata, data_len, 02709 (SMB_BIG_UINT)current_user.ut.groups[i]); 02710 data_len += 8; 02711 } 02712 02713 /* SID list */ 02714 for (i = 0; 02715 i < current_user.nt_user_token->num_sids; ++i) { 02716 int sid_len = 02717 sid_size(¤t_user.nt_user_token->user_sids[i]); 02718 02719 sid_linearize(pdata + data_len, sid_len, 02720 ¤t_user.nt_user_token->user_sids[i]); 02721 data_len += sid_len; 02722 } 02723 02724 break; 02725 } 02726 02727 case SMB_MAC_QUERY_FS_INFO: 02728 /* 02729 * Thursby MAC extension... ONLY on NTFS filesystems 02730 * once we do streams then we don't need this 02731 */ 02732 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) { 02733 data_len = 88; 02734 SIVAL(pdata,84,0x100); /* Don't support mac... */ 02735 break; 02736 } 02737 /* drop through */ 02738 default: 02739 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 02740 } 02741 02742 02743 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len, max_data_bytes); 02744 02745 DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) ); 02746 02747 return -1; 02748 }
static int call_trans2setfsinfo | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize, | |||
char ** | pparams, | |||
int | total_params, | |||
char ** | ppdata, | |||
int | total_data, | |||
unsigned int | max_data_bytes | |||
) | [static] |
参照先 current_user・file_fsp()・_SMB_NTQUOTA_STRUCT::hardlim・mangle_change_to_posix()・POSIX_LOCK・_SMB_NTQUOTA_STRUCT::qflags・set_message()・SMB_USER_FS_QUOTA_TYPE・_SMB_NTQUOTA_STRUCT::softlim・_unix_token::uid・connection_struct::user・current_user::ut・vfs_set_ntquota().
参照元 handle_trans2().
02757 { 02758 char *pdata = *ppdata; 02759 char *params = *pparams; 02760 uint16 info_level; 02761 int outsize; 02762 02763 DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",lp_servicename(SNUM(conn)))); 02764 02765 /* */ 02766 if (total_params < 4) { 02767 DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n", 02768 total_params)); 02769 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 02770 } 02771 02772 info_level = SVAL(params,2); 02773 02774 switch(info_level) { 02775 case SMB_SET_CIFS_UNIX_INFO: 02776 { 02777 uint16 client_unix_major; 02778 uint16 client_unix_minor; 02779 uint32 client_unix_cap_low; 02780 uint32 client_unix_cap_high; 02781 02782 if (!lp_unix_extensions()) { 02783 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 02784 } 02785 02786 /* There should be 12 bytes of capabilities set. */ 02787 if (total_data < 8) { 02788 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 02789 } 02790 client_unix_major = SVAL(pdata,0); 02791 client_unix_minor = SVAL(pdata,2); 02792 client_unix_cap_low = IVAL(pdata,4); 02793 client_unix_cap_high = IVAL(pdata,8); 02794 /* Just print these values for now. */ 02795 DEBUG(10,("call_trans2setfsinfo: set unix info. major = %u, minor = %u \ 02796 cap_low = 0x%x, cap_high = 0x%x\n", 02797 (unsigned int)client_unix_major, 02798 (unsigned int)client_unix_minor, 02799 (unsigned int)client_unix_cap_low, 02800 (unsigned int)client_unix_cap_high )); 02801 02802 /* Here is where we must switch to posix pathname processing... */ 02803 if (client_unix_cap_low & CIFS_UNIX_POSIX_PATHNAMES_CAP) { 02804 lp_set_posix_pathnames(); 02805 mangle_change_to_posix(); 02806 } 02807 02808 if ((client_unix_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) && 02809 !(client_unix_cap_low & CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP)) { 02810 /* Client that knows how to do posix locks, 02811 * but not posix open/mkdir operations. Set a 02812 * default type for read/write checks. */ 02813 02814 lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK); 02815 02816 } 02817 break; 02818 } 02819 case SMB_FS_QUOTA_INFORMATION: 02820 { 02821 files_struct *fsp = NULL; 02822 SMB_NTQUOTA_STRUCT quotas; 02823 02824 ZERO_STRUCT(quotas); 02825 02826 /* access check */ 02827 if ((current_user.ut.uid != 0)||!CAN_WRITE(conn)) { 02828 DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n", 02829 lp_servicename(SNUM(conn)),conn->user)); 02830 return ERROR_DOS(ERRSRV,ERRaccess); 02831 } 02832 02833 /* note: normaly there're 48 bytes, 02834 * but we didn't use the last 6 bytes for now 02835 * --metze 02836 */ 02837 fsp = file_fsp(params,0); 02838 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) { 02839 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n")); 02840 return ERROR_NT(NT_STATUS_INVALID_HANDLE); 02841 } 02842 02843 if (total_data < 42) { 02844 DEBUG(0,("call_trans2setfsinfo: SET_FS_QUOTA: requires total_data(%d) >= 42 bytes!\n", 02845 total_data)); 02846 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 02847 } 02848 02849 /* unknown_1 24 NULL bytes in pdata*/ 02850 02851 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/ 02852 quotas.softlim = (SMB_BIG_UINT)IVAL(pdata,24); 02853 #ifdef LARGE_SMB_OFF_T 02854 quotas.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32); 02855 #else /* LARGE_SMB_OFF_T */ 02856 if ((IVAL(pdata,28) != 0)&& 02857 ((quotas.softlim != 0xFFFFFFFF)|| 02858 (IVAL(pdata,28)!=0xFFFFFFFF))) { 02859 /* more than 32 bits? */ 02860 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 02861 } 02862 #endif /* LARGE_SMB_OFF_T */ 02863 02864 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/ 02865 quotas.hardlim = (SMB_BIG_UINT)IVAL(pdata,32); 02866 #ifdef LARGE_SMB_OFF_T 02867 quotas.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32); 02868 #else /* LARGE_SMB_OFF_T */ 02869 if ((IVAL(pdata,36) != 0)&& 02870 ((quotas.hardlim != 0xFFFFFFFF)|| 02871 (IVAL(pdata,36)!=0xFFFFFFFF))) { 02872 /* more than 32 bits? */ 02873 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 02874 } 02875 #endif /* LARGE_SMB_OFF_T */ 02876 02877 /* quota_flags 2 bytes **/ 02878 quotas.qflags = SVAL(pdata,40); 02879 02880 /* unknown_2 6 NULL bytes follow*/ 02881 02882 /* now set the quotas */ 02883 if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) { 02884 DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn)))); 02885 return ERROR_DOS(ERRSRV,ERRerror); 02886 } 02887 02888 break; 02889 } 02890 default: 02891 DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n", 02892 info_level)); 02893 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 02894 break; 02895 } 02896 02897 /* 02898 * sending this reply works fine, 02899 * but I'm not sure it's the same 02900 * like windows do... 02901 * --metze 02902 */ 02903 outsize = set_message(outbuf,10,0,True); 02904 02905 return outsize; 02906 }
static unsigned int count_acl_entries | ( | connection_struct * | conn, | |
SMB_ACL_T | posix_acl | |||
) | [static] |
参照元 call_trans2qfilepathinfo().
02914 { 02915 unsigned int ace_count = 0; 02916 int entry_id = SMB_ACL_FIRST_ENTRY; 02917 SMB_ACL_ENTRY_T entry; 02918 02919 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) { 02920 /* get_next... */ 02921 if (entry_id == SMB_ACL_FIRST_ENTRY) { 02922 entry_id = SMB_ACL_NEXT_ENTRY; 02923 } 02924 ace_count++; 02925 } 02926 return ace_count; 02927 }
static BOOL marshall_posix_acl | ( | connection_struct * | conn, | |
char * | pdata, | |||
SMB_STRUCT_STAT * | pst, | |||
SMB_ACL_T | posix_acl | |||
) | [static] |
参照先 perms・SMB_ACL_GROUP・SMB_ACL_GROUP_OBJ・SMB_ACL_MASK・SMB_ACL_OTHER・SMB_ACL_USER・SMB_ACL_USER_OBJ.
参照元 call_trans2qfilepathinfo().
02934 { 02935 int entry_id = SMB_ACL_FIRST_ENTRY; 02936 SMB_ACL_ENTRY_T entry; 02937 02938 while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) { 02939 SMB_ACL_TAG_T tagtype; 02940 SMB_ACL_PERMSET_T permset; 02941 unsigned char perms = 0; 02942 unsigned int own_grp; 02943 02944 /* get_next... */ 02945 if (entry_id == SMB_ACL_FIRST_ENTRY) { 02946 entry_id = SMB_ACL_NEXT_ENTRY; 02947 } 02948 02949 if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) { 02950 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n")); 02951 return False; 02952 } 02953 02954 if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) { 02955 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n")); 02956 return False; 02957 } 02958 02959 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0); 02960 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0); 02961 perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0); 02962 02963 SCVAL(pdata,1,perms); 02964 02965 switch (tagtype) { 02966 case SMB_ACL_USER_OBJ: 02967 SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ); 02968 own_grp = (unsigned int)pst->st_uid; 02969 SIVAL(pdata,2,own_grp); 02970 SIVAL(pdata,6,0); 02971 break; 02972 case SMB_ACL_USER: 02973 { 02974 uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry); 02975 if (!puid) { 02976 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n")); 02977 } 02978 own_grp = (unsigned int)*puid; 02979 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype); 02980 SCVAL(pdata,0,SMB_POSIX_ACL_USER); 02981 SIVAL(pdata,2,own_grp); 02982 SIVAL(pdata,6,0); 02983 break; 02984 } 02985 case SMB_ACL_GROUP_OBJ: 02986 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ); 02987 own_grp = (unsigned int)pst->st_gid; 02988 SIVAL(pdata,2,own_grp); 02989 SIVAL(pdata,6,0); 02990 break; 02991 case SMB_ACL_GROUP: 02992 { 02993 gid_t *pgid= (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry); 02994 if (!pgid) { 02995 DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n")); 02996 } 02997 own_grp = (unsigned int)*pgid; 02998 SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype); 02999 SCVAL(pdata,0,SMB_POSIX_ACL_GROUP); 03000 SIVAL(pdata,2,own_grp); 03001 SIVAL(pdata,6,0); 03002 break; 03003 } 03004 case SMB_ACL_MASK: 03005 SCVAL(pdata,0,SMB_POSIX_ACL_MASK); 03006 SIVAL(pdata,2,0xFFFFFFFF); 03007 SIVAL(pdata,6,0xFFFFFFFF); 03008 break; 03009 case SMB_ACL_OTHER: 03010 SCVAL(pdata,0,SMB_POSIX_ACL_OTHER); 03011 SIVAL(pdata,2,0xFFFFFFFF); 03012 SIVAL(pdata,6,0xFFFFFFFF); 03013 break; 03014 default: 03015 DEBUG(0,("marshall_posix_acl: unknown tagtype.\n")); 03016 return False; 03017 } 03018 pdata += SMB_POSIX_ACL_ENTRY_SIZE; 03019 } 03020 03021 return True; 03022 }
static void map_info2_flags_from_sbuf | ( | const SMB_STRUCT_STAT * | psbuf, | |
uint32 * | smb_fflags, | |||
uint32 * | smb_fmask | |||
) | [static] |
参照先 info2_flags_map・smb_fflag.
参照元 store_file_unix_basic_info2().
03117 { 03118 #ifdef HAVE_STAT_ST_FLAGS 03119 int i; 03120 03121 for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) { 03122 *smb_fmask |= info2_flags_map[i].smb_fflag; 03123 if (psbuf->st_flags & info2_flags_map[i].stat_fflag) { 03124 *smb_fflags |= info2_flags_map[i].smb_fflag; 03125 } 03126 } 03127 #endif /* HAVE_STAT_ST_FLAGS */ 03128 }
static BOOL map_info2_flags_to_sbuf | ( | const SMB_STRUCT_STAT * | psbuf, | |
const uint32 | smb_fflags, | |||
const uint32 | smb_fmask, | |||
int * | stat_fflags | |||
) | [static] |
参照先 info2_flags_map・smb_fflag.
参照元 smb_set_file_unix_info2().
03134 { 03135 #ifdef HAVE_STAT_ST_FLAGS 03136 uint32 max_fmask = 0; 03137 int i; 03138 03139 *stat_fflags = psbuf->st_flags; 03140 03141 /* For each flags requested in smb_fmask, check the state of the 03142 * corresponding flag in smb_fflags and set or clear the matching 03143 * stat flag. 03144 */ 03145 03146 for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) { 03147 max_fmask |= info2_flags_map[i].smb_fflag; 03148 if (smb_fmask & info2_flags_map[i].smb_fflag) { 03149 if (smb_fflags & info2_flags_map[i].smb_fflag) { 03150 *stat_fflags |= info2_flags_map[i].stat_fflag; 03151 } else { 03152 *stat_fflags &= ~info2_flags_map[i].stat_fflag; 03153 } 03154 } 03155 } 03156 03157 /* If smb_fmask is asking to set any bits that are not supported by 03158 * our flag mappings, we should fail. 03159 */ 03160 if ((smb_fmask & max_fmask) != smb_fmask) { 03161 return False; 03162 } 03163 03164 return True; 03165 #else 03166 return False; 03167 #endif /* HAVE_STAT_ST_FLAGS */ 03168 }
static int call_trans2qfilepathinfo | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize, | |||
unsigned int | tran_call, | |||
char ** | pparams, | |||
int | total_params, | |||
char ** | ppdata, | |||
int | total_data, | |||
unsigned int | max_data_bytes | |||
) | [static] |
参照先 check_name()・convert_timespec_to_time_t()・count_acl_entries()・dos_filetime_timespec()・dos_PutUniCode()・ea_list_union()・errno・estimate_ea_size()・file_find_di_first()・file_fsp()・fill_ea_buffer()・free_empty_sys_acl()・get_allocation_size()・get_atimespec()・get_create_timespec()・get_delete_on_close_flag()・get_ea_list_from_file()・get_file_size()・get_mtimespec()・files_struct::initial_allocation_size・len・mangle_is_8_3()・mangle_map()・marshall_posix_acl()・mode・no_acl_syscall_error()・nt_errstr()・null_timespec()・connection_struct::params・files_struct::pending_modtime・POSIX_LOCK・pstr_sprintf()・put_long_date_timespec()・query_lock()・read_ea_name_list()・READ_LOCK・resolve_dfspath()・send_trans2_replies()・short_name・srv_put_dos_date2()・srvstr_get_path()・status・store_file_unix_basic()・store_file_unix_basic_info2()・strequal()・strerror()・string_replace()・strrchr_m()・talloc_init()・unix_convert()・WRITE_LOCK.
参照元 handle_trans2().
03205 { 03206 char *params = *pparams; 03207 char *pdata = *ppdata; 03208 uint16 info_level; 03209 int mode=0; 03210 int nlink; 03211 SMB_OFF_T file_size=0; 03212 SMB_BIG_UINT allocation_size=0; 03213 unsigned int data_size = 0; 03214 unsigned int param_size = 2; 03215 SMB_STRUCT_STAT sbuf; 03216 pstring fname, dos_fname; 03217 char *fullpathname; 03218 char *base_name; 03219 char *p; 03220 SMB_OFF_T pos = 0; 03221 BOOL delete_pending = False; 03222 int len; 03223 time_t create_time, mtime, atime; 03224 struct timespec create_time_ts, mtime_ts, atime_ts; 03225 files_struct *fsp = NULL; 03226 TALLOC_CTX *data_ctx = NULL; 03227 struct ea_list *ea_list = NULL; 03228 uint32 access_mask = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */ 03229 char *lock_data = NULL; 03230 03231 if (!params) 03232 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 03233 03234 ZERO_STRUCT(sbuf); 03235 03236 if (tran_call == TRANSACT2_QFILEINFO) { 03237 if (total_params < 4) { 03238 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 03239 } 03240 03241 fsp = file_fsp(params,0); 03242 info_level = SVAL(params,2); 03243 03244 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level)); 03245 03246 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { 03247 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 03248 } 03249 03250 if(fsp && (fsp->fake_file_handle)) { 03251 /* 03252 * This is actually for the QUOTA_FAKE_FILE --metze 03253 */ 03254 03255 pstrcpy(fname, fsp->fsp_name); 03256 /* We know this name is ok, it's already passed the checks. */ 03257 03258 } else if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) { 03259 /* 03260 * This is actually a QFILEINFO on a directory 03261 * handle (returned from an NT SMB). NT5.0 seems 03262 * to do this call. JRA. 03263 */ 03264 /* We know this name is ok, it's already passed the checks. */ 03265 pstrcpy(fname, fsp->fsp_name); 03266 03267 if (INFO_LEVEL_IS_UNIX(info_level)) { 03268 /* Always do lstat for UNIX calls. */ 03269 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) { 03270 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno))); 03271 return UNIXERROR(ERRDOS,ERRbadpath); 03272 } 03273 } else if (SMB_VFS_STAT(conn,fname,&sbuf)) { 03274 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno))); 03275 return UNIXERROR(ERRDOS,ERRbadpath); 03276 } 03277 03278 delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino); 03279 } else { 03280 /* 03281 * Original code - this is an open file. 03282 */ 03283 CHECK_FSP(fsp,conn); 03284 03285 pstrcpy(fname, fsp->fsp_name); 03286 if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) { 03287 DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno))); 03288 return(UNIXERROR(ERRDOS,ERRbadfid)); 03289 } 03290 pos = fsp->fh->position_information; 03291 delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino); 03292 access_mask = fsp->access_mask; 03293 } 03294 } else { 03295 NTSTATUS status = NT_STATUS_OK; 03296 03297 /* qpathinfo */ 03298 if (total_params < 7) { 03299 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 03300 } 03301 03302 info_level = SVAL(params,0); 03303 03304 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level)); 03305 03306 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { 03307 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 03308 } 03309 03310 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), total_params - 6, STR_TERMINATE, &status); 03311 if (!NT_STATUS_IS_OK(status)) { 03312 return ERROR_NT(status); 03313 } 03314 03315 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname); 03316 if (!NT_STATUS_IS_OK(status)) { 03317 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 03318 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 03319 } 03320 return ERROR_NT(status); 03321 } 03322 03323 status = unix_convert(conn, fname, False, NULL, &sbuf); 03324 if (!NT_STATUS_IS_OK(status)) { 03325 return ERROR_NT(status); 03326 } 03327 status = check_name(conn, fname); 03328 if (!NT_STATUS_IS_OK(status)) { 03329 DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,nt_errstr(status))); 03330 return ERROR_NT(status); 03331 } 03332 03333 if (INFO_LEVEL_IS_UNIX(info_level)) { 03334 /* Always do lstat for UNIX calls. */ 03335 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) { 03336 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno))); 03337 return UNIXERROR(ERRDOS,ERRbadpath); 03338 } 03339 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) { 03340 DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno))); 03341 return UNIXERROR(ERRDOS,ERRbadpath); 03342 } 03343 03344 delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino); 03345 if (delete_pending) { 03346 return ERROR_NT(NT_STATUS_DELETE_PENDING); 03347 } 03348 } 03349 03350 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { 03351 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 03352 } 03353 03354 DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n", 03355 fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data)); 03356 03357 p = strrchr_m(fname,'/'); 03358 if (!p) 03359 base_name = fname; 03360 else 03361 base_name = p+1; 03362 03363 mode = dos_mode(conn,fname,&sbuf); 03364 if (!mode) 03365 mode = FILE_ATTRIBUTE_NORMAL; 03366 03367 nlink = sbuf.st_nlink; 03368 03369 if (nlink && (mode&aDIR)) { 03370 nlink = 1; 03371 } 03372 03373 if ((nlink > 0) && delete_pending) { 03374 nlink -= 1; 03375 } 03376 03377 fullpathname = fname; 03378 if (!(mode & aDIR)) 03379 file_size = get_file_size(sbuf); 03380 03381 /* Pull out any data sent here before we realloc. */ 03382 switch (info_level) { 03383 case SMB_INFO_QUERY_EAS_FROM_LIST: 03384 { 03385 /* Pull any EA list from the data portion. */ 03386 uint32 ea_size; 03387 03388 if (total_data < 4) { 03389 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 03390 } 03391 ea_size = IVAL(pdata,0); 03392 03393 if (total_data > 0 && ea_size != total_data) { 03394 DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \ 03395 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) )); 03396 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 03397 } 03398 03399 if (!lp_ea_support(SNUM(conn))) { 03400 return ERROR_DOS(ERRDOS,ERReasnotsupported); 03401 } 03402 03403 if ((data_ctx = talloc_init("ea_list")) == NULL) { 03404 return ERROR_NT(NT_STATUS_NO_MEMORY); 03405 } 03406 03407 /* Pull out the list of names. */ 03408 ea_list = read_ea_name_list(data_ctx, pdata + 4, ea_size - 4); 03409 if (!ea_list) { 03410 talloc_destroy(data_ctx); 03411 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 03412 } 03413 break; 03414 } 03415 03416 case SMB_QUERY_POSIX_LOCK: 03417 { 03418 if (fsp == NULL || fsp->fh->fd == -1) { 03419 return ERROR_NT(NT_STATUS_INVALID_HANDLE); 03420 } 03421 03422 if (total_data != POSIX_LOCK_DATA_SIZE) { 03423 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 03424 } 03425 03426 if ((data_ctx = talloc_init("lock_request")) == NULL) { 03427 return ERROR_NT(NT_STATUS_NO_MEMORY); 03428 } 03429 03430 /* Copy the lock range data. */ 03431 lock_data = (char *)TALLOC_MEMDUP( 03432 data_ctx, pdata, total_data); 03433 if (!lock_data) { 03434 talloc_destroy(data_ctx); 03435 return ERROR_NT(NT_STATUS_NO_MEMORY); 03436 } 03437 } 03438 default: 03439 break; 03440 } 03441 03442 *pparams = (char *)SMB_REALLOC(*pparams,2); 03443 if (*pparams == NULL) { 03444 talloc_destroy(data_ctx); 03445 return ERROR_NT(NT_STATUS_NO_MEMORY); 03446 } 03447 params = *pparams; 03448 SSVAL(params,0,0); 03449 data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN; 03450 *ppdata = (char *)SMB_REALLOC(*ppdata, data_size); 03451 if (*ppdata == NULL ) { 03452 talloc_destroy(data_ctx); 03453 return ERROR_NT(NT_STATUS_NO_MEMORY); 03454 } 03455 pdata = *ppdata; 03456 03457 create_time_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn))); 03458 mtime_ts = get_mtimespec(&sbuf); 03459 atime_ts = get_atimespec(&sbuf); 03460 03461 allocation_size = get_allocation_size(conn,fsp,&sbuf); 03462 03463 if (fsp) { 03464 if (!null_timespec(fsp->pending_modtime)) { 03465 /* the pending modtime overrides the current modtime */ 03466 mtime_ts = fsp->pending_modtime; 03467 } 03468 } else { 03469 /* Do we have this path open ? */ 03470 files_struct *fsp1 = file_find_di_first(sbuf.st_dev, sbuf.st_ino); 03471 if (fsp1 && !null_timespec(fsp1->pending_modtime)) { 03472 /* the pending modtime overrides the current modtime */ 03473 mtime_ts = fsp1->pending_modtime; 03474 } 03475 if (fsp1 && fsp1->initial_allocation_size) { 03476 allocation_size = get_allocation_size(conn, fsp1, &sbuf); 03477 } 03478 } 03479 03480 if (lp_dos_filetime_resolution(SNUM(conn))) { 03481 dos_filetime_timespec(&create_time_ts); 03482 dos_filetime_timespec(&mtime_ts); 03483 dos_filetime_timespec(&atime_ts); 03484 } 03485 03486 create_time = convert_timespec_to_time_t(create_time_ts); 03487 mtime = convert_timespec_to_time_t(mtime_ts); 03488 atime = convert_timespec_to_time_t(atime_ts); 03489 03490 /* NT expects the name to be in an exact form of the *full* 03491 filename. See the trans2 torture test */ 03492 if (strequal(base_name,".")) { 03493 pstrcpy(dos_fname, "\\"); 03494 } else { 03495 pstr_sprintf(dos_fname, "\\%s", fname); 03496 string_replace(dos_fname, '/', '\\'); 03497 } 03498 03499 switch (info_level) { 03500 case SMB_INFO_STANDARD: 03501 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n")); 03502 data_size = 22; 03503 srv_put_dos_date2(pdata,l1_fdateCreation,create_time); 03504 srv_put_dos_date2(pdata,l1_fdateLastAccess,atime); 03505 srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */ 03506 SIVAL(pdata,l1_cbFile,(uint32)file_size); 03507 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size); 03508 SSVAL(pdata,l1_attrFile,mode); 03509 break; 03510 03511 case SMB_INFO_QUERY_EA_SIZE: 03512 { 03513 unsigned int ea_size = estimate_ea_size(conn, fsp, fname); 03514 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n")); 03515 data_size = 26; 03516 srv_put_dos_date2(pdata,0,create_time); 03517 srv_put_dos_date2(pdata,4,atime); 03518 srv_put_dos_date2(pdata,8,mtime); /* write time */ 03519 SIVAL(pdata,12,(uint32)file_size); 03520 SIVAL(pdata,16,(uint32)allocation_size); 03521 SSVAL(pdata,20,mode); 03522 SIVAL(pdata,22,ea_size); 03523 break; 03524 } 03525 03526 case SMB_INFO_IS_NAME_VALID: 03527 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n")); 03528 if (tran_call == TRANSACT2_QFILEINFO) { 03529 /* os/2 needs this ? really ?*/ 03530 return ERROR_DOS(ERRDOS,ERRbadfunc); 03531 } 03532 data_size = 0; 03533 param_size = 0; 03534 break; 03535 03536 case SMB_INFO_QUERY_EAS_FROM_LIST: 03537 { 03538 size_t total_ea_len = 0; 03539 struct ea_list *ea_file_list = NULL; 03540 03541 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n")); 03542 03543 ea_file_list = get_ea_list_from_file(data_ctx, conn, fsp, fname, &total_ea_len); 03544 ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len); 03545 03546 if (!ea_list || (total_ea_len > data_size)) { 03547 talloc_destroy(data_ctx); 03548 data_size = 4; 03549 SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */ 03550 break; 03551 } 03552 03553 data_size = fill_ea_buffer(data_ctx, pdata, data_size, conn, ea_list); 03554 talloc_destroy(data_ctx); 03555 break; 03556 } 03557 03558 case SMB_INFO_QUERY_ALL_EAS: 03559 { 03560 /* We have data_size bytes to put EA's into. */ 03561 size_t total_ea_len = 0; 03562 03563 DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n")); 03564 03565 data_ctx = talloc_init("ea_ctx"); 03566 if (!data_ctx) { 03567 return ERROR_NT(NT_STATUS_NO_MEMORY); 03568 } 03569 03570 ea_list = get_ea_list_from_file(data_ctx, conn, fsp, fname, &total_ea_len); 03571 if (!ea_list || (total_ea_len > data_size)) { 03572 talloc_destroy(data_ctx); 03573 data_size = 4; 03574 SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */ 03575 break; 03576 } 03577 03578 data_size = fill_ea_buffer(data_ctx, pdata, data_size, conn, ea_list); 03579 talloc_destroy(data_ctx); 03580 break; 03581 } 03582 03583 case SMB_FILE_BASIC_INFORMATION: 03584 case SMB_QUERY_FILE_BASIC_INFO: 03585 03586 if (info_level == SMB_QUERY_FILE_BASIC_INFO) { 03587 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n")); 03588 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */ 03589 } else { 03590 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n")); 03591 data_size = 40; 03592 SIVAL(pdata,36,0); 03593 } 03594 put_long_date_timespec(pdata,create_time_ts); 03595 put_long_date_timespec(pdata+8,atime_ts); 03596 put_long_date_timespec(pdata+16,mtime_ts); /* write time */ 03597 put_long_date_timespec(pdata+24,mtime_ts); /* change time */ 03598 SIVAL(pdata,32,mode); 03599 03600 DEBUG(5,("SMB_QFBI - ")); 03601 DEBUG(5,("create: %s ", ctime(&create_time))); 03602 DEBUG(5,("access: %s ", ctime(&atime))); 03603 DEBUG(5,("write: %s ", ctime(&mtime))); 03604 DEBUG(5,("change: %s ", ctime(&mtime))); 03605 DEBUG(5,("mode: %x\n", mode)); 03606 break; 03607 03608 case SMB_FILE_STANDARD_INFORMATION: 03609 case SMB_QUERY_FILE_STANDARD_INFO: 03610 03611 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n")); 03612 data_size = 24; 03613 SOFF_T(pdata,0,allocation_size); 03614 SOFF_T(pdata,8,file_size); 03615 SIVAL(pdata,16,nlink); 03616 SCVAL(pdata,20,delete_pending?1:0); 03617 SCVAL(pdata,21,(mode&aDIR)?1:0); 03618 SSVAL(pdata,22,0); /* Padding. */ 03619 break; 03620 03621 case SMB_FILE_EA_INFORMATION: 03622 case SMB_QUERY_FILE_EA_INFO: 03623 { 03624 unsigned int ea_size = estimate_ea_size(conn, fsp, fname); 03625 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n")); 03626 data_size = 4; 03627 SIVAL(pdata,0,ea_size); 03628 break; 03629 } 03630 03631 /* Get the 8.3 name - used if NT SMB was negotiated. */ 03632 case SMB_QUERY_FILE_ALT_NAME_INFO: 03633 case SMB_FILE_ALTERNATE_NAME_INFORMATION: 03634 { 03635 pstring short_name; 03636 03637 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n")); 03638 pstrcpy(short_name,base_name); 03639 /* Mangle if not already 8.3 */ 03640 if(!mangle_is_8_3(short_name, True, conn->params)) { 03641 mangle_map(short_name,True,True,conn->params); 03642 } 03643 len = srvstr_push(outbuf, pdata+4, short_name, max_data_bytes - 4, STR_UNICODE); 03644 data_size = 4 + len; 03645 SIVAL(pdata,0,len); 03646 break; 03647 } 03648 03649 case SMB_QUERY_FILE_NAME_INFO: 03650 /* 03651 this must be *exactly* right for ACLs on mapped drives to work 03652 */ 03653 len = srvstr_push(outbuf, pdata+4, dos_fname, max_data_bytes - 4, STR_UNICODE); 03654 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n")); 03655 data_size = 4 + len; 03656 SIVAL(pdata,0,len); 03657 break; 03658 03659 case SMB_FILE_ALLOCATION_INFORMATION: 03660 case SMB_QUERY_FILE_ALLOCATION_INFO: 03661 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n")); 03662 data_size = 8; 03663 SOFF_T(pdata,0,allocation_size); 03664 break; 03665 03666 case SMB_FILE_END_OF_FILE_INFORMATION: 03667 case SMB_QUERY_FILE_END_OF_FILEINFO: 03668 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n")); 03669 data_size = 8; 03670 SOFF_T(pdata,0,file_size); 03671 break; 03672 03673 case SMB_QUERY_FILE_ALL_INFO: 03674 case SMB_FILE_ALL_INFORMATION: 03675 { 03676 unsigned int ea_size = estimate_ea_size(conn, fsp, fname); 03677 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n")); 03678 put_long_date_timespec(pdata,create_time_ts); 03679 put_long_date_timespec(pdata+8,atime_ts); 03680 put_long_date_timespec(pdata+16,mtime_ts); /* write time */ 03681 put_long_date_timespec(pdata+24,mtime_ts); /* change time */ 03682 SIVAL(pdata,32,mode); 03683 SIVAL(pdata,36,0); /* padding. */ 03684 pdata += 40; 03685 SOFF_T(pdata,0,allocation_size); 03686 SOFF_T(pdata,8,file_size); 03687 SIVAL(pdata,16,nlink); 03688 SCVAL(pdata,20,delete_pending); 03689 SCVAL(pdata,21,(mode&aDIR)?1:0); 03690 SSVAL(pdata,22,0); 03691 pdata += 24; 03692 SIVAL(pdata,0,ea_size); 03693 pdata += 4; /* EA info */ 03694 len = srvstr_push(outbuf, pdata+4, dos_fname, max_data_bytes - (pdata+4 - *ppdata), STR_UNICODE); 03695 SIVAL(pdata,0,len); 03696 pdata += 4 + len; 03697 data_size = PTR_DIFF(pdata,(*ppdata)); 03698 break; 03699 } 03700 case SMB_FILE_INTERNAL_INFORMATION: 03701 /* This should be an index number - looks like 03702 dev/ino to me :-) 03703 03704 I think this causes us to fail the IFSKIT 03705 BasicFileInformationTest. -tpot */ 03706 03707 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n")); 03708 SIVAL(pdata,0,sbuf.st_ino); /* FileIndexLow */ 03709 SIVAL(pdata,4,sbuf.st_dev); /* FileIndexHigh */ 03710 data_size = 8; 03711 break; 03712 03713 case SMB_FILE_ACCESS_INFORMATION: 03714 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n")); 03715 SIVAL(pdata,0,access_mask); 03716 data_size = 4; 03717 break; 03718 03719 case SMB_FILE_NAME_INFORMATION: 03720 /* Pathname with leading '\'. */ 03721 { 03722 size_t byte_len; 03723 byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False); 03724 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n")); 03725 SIVAL(pdata,0,byte_len); 03726 data_size = 4 + byte_len; 03727 break; 03728 } 03729 03730 case SMB_FILE_DISPOSITION_INFORMATION: 03731 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n")); 03732 data_size = 1; 03733 SCVAL(pdata,0,delete_pending); 03734 break; 03735 03736 case SMB_FILE_POSITION_INFORMATION: 03737 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n")); 03738 data_size = 8; 03739 SOFF_T(pdata,0,pos); 03740 break; 03741 03742 case SMB_FILE_MODE_INFORMATION: 03743 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n")); 03744 SIVAL(pdata,0,mode); 03745 data_size = 4; 03746 break; 03747 03748 case SMB_FILE_ALIGNMENT_INFORMATION: 03749 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n")); 03750 SIVAL(pdata,0,0); /* No alignment needed. */ 03751 data_size = 4; 03752 break; 03753 03754 #if 0 03755 /* 03756 * NT4 server just returns "invalid query" to this - if we try to answer 03757 * it then NTws gets a BSOD! (tridge). 03758 * W2K seems to want this. JRA. 03759 */ 03760 case SMB_QUERY_FILE_STREAM_INFO: 03761 #endif 03762 case SMB_FILE_STREAM_INFORMATION: 03763 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n")); 03764 if (mode & aDIR) { 03765 data_size = 0; 03766 } else { 03767 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", (size_t)0xE, False); 03768 SIVAL(pdata,0,0); /* ??? */ 03769 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */ 03770 SOFF_T(pdata,8,file_size); 03771 SOFF_T(pdata,16,allocation_size); 03772 data_size = 24 + byte_len; 03773 } 03774 break; 03775 03776 case SMB_QUERY_COMPRESSION_INFO: 03777 case SMB_FILE_COMPRESSION_INFORMATION: 03778 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n")); 03779 SOFF_T(pdata,0,file_size); 03780 SIVAL(pdata,8,0); /* ??? */ 03781 SIVAL(pdata,12,0); /* ??? */ 03782 data_size = 16; 03783 break; 03784 03785 case SMB_FILE_NETWORK_OPEN_INFORMATION: 03786 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n")); 03787 put_long_date_timespec(pdata,create_time_ts); 03788 put_long_date_timespec(pdata+8,atime_ts); 03789 put_long_date_timespec(pdata+16,mtime_ts); /* write time */ 03790 put_long_date_timespec(pdata+24,mtime_ts); /* change time */ 03791 SOFF_T(pdata,32,allocation_size); 03792 SOFF_T(pdata,40,file_size); 03793 SIVAL(pdata,48,mode); 03794 SIVAL(pdata,52,0); /* ??? */ 03795 data_size = 56; 03796 break; 03797 03798 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION: 03799 DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n")); 03800 SIVAL(pdata,0,mode); 03801 SIVAL(pdata,4,0); 03802 data_size = 8; 03803 break; 03804 03805 /* 03806 * CIFS UNIX Extensions. 03807 */ 03808 03809 case SMB_QUERY_FILE_UNIX_BASIC: 03810 03811 pdata = store_file_unix_basic(conn, pdata, fsp, &sbuf); 03812 data_size = PTR_DIFF(pdata,(*ppdata)); 03813 03814 { 03815 int i; 03816 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC ")); 03817 03818 for (i=0; i<100; i++) 03819 DEBUG(4,("%d=%x, ",i, (*ppdata)[i])); 03820 DEBUG(4,("\n")); 03821 } 03822 03823 break; 03824 03825 case SMB_QUERY_FILE_UNIX_INFO2: 03826 03827 pdata = store_file_unix_basic_info2(conn, pdata, fsp, &sbuf); 03828 data_size = PTR_DIFF(pdata,(*ppdata)); 03829 03830 { 03831 int i; 03832 DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 ")); 03833 03834 for (i=0; i<100; i++) 03835 DEBUG(4,("%d=%x, ",i, (*ppdata)[i])); 03836 DEBUG(4,("\n")); 03837 } 03838 03839 break; 03840 03841 case SMB_QUERY_FILE_UNIX_LINK: 03842 { 03843 pstring buffer; 03844 03845 DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n")); 03846 #ifdef S_ISLNK 03847 if(!S_ISLNK(sbuf.st_mode)) 03848 return(UNIXERROR(ERRSRV,ERRbadlink)); 03849 #else 03850 return(UNIXERROR(ERRDOS,ERRbadlink)); 03851 #endif 03852 len = SMB_VFS_READLINK(conn,fullpathname, buffer, sizeof(pstring)-1); /* read link */ 03853 if (len == -1) 03854 return(UNIXERROR(ERRDOS,ERRnoaccess)); 03855 buffer[len] = 0; 03856 len = srvstr_push(outbuf, pdata, buffer, max_data_bytes, STR_TERMINATE); 03857 pdata += len; 03858 data_size = PTR_DIFF(pdata,(*ppdata)); 03859 03860 break; 03861 } 03862 03863 #if defined(HAVE_POSIX_ACLS) 03864 case SMB_QUERY_POSIX_ACL: 03865 { 03866 SMB_ACL_T file_acl = NULL; 03867 SMB_ACL_T def_acl = NULL; 03868 uint16 num_file_acls = 0; 03869 uint16 num_def_acls = 0; 03870 03871 if (fsp && !fsp->is_directory && (fsp->fh->fd != -1)) { 03872 file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fh->fd); 03873 } else { 03874 file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS); 03875 } 03876 03877 if (file_acl == NULL && no_acl_syscall_error(errno)) { 03878 DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n", 03879 fname )); 03880 return ERROR_NT(NT_STATUS_NOT_IMPLEMENTED); 03881 } 03882 03883 if (S_ISDIR(sbuf.st_mode)) { 03884 if (fsp && fsp->is_directory) { 03885 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT); 03886 } else { 03887 def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT); 03888 } 03889 def_acl = free_empty_sys_acl(conn, def_acl); 03890 } 03891 03892 num_file_acls = count_acl_entries(conn, file_acl); 03893 num_def_acls = count_acl_entries(conn, def_acl); 03894 03895 if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) { 03896 DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n", 03897 data_size, 03898 (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + 03899 SMB_POSIX_ACL_HEADER_SIZE) )); 03900 if (file_acl) { 03901 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); 03902 } 03903 if (def_acl) { 03904 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); 03905 } 03906 return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL); 03907 } 03908 03909 SSVAL(pdata,0,SMB_POSIX_ACL_VERSION); 03910 SSVAL(pdata,2,num_file_acls); 03911 SSVAL(pdata,4,num_def_acls); 03912 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) { 03913 if (file_acl) { 03914 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); 03915 } 03916 if (def_acl) { 03917 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); 03918 } 03919 return ERROR_NT(NT_STATUS_INTERNAL_ERROR); 03920 } 03921 if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) { 03922 if (file_acl) { 03923 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); 03924 } 03925 if (def_acl) { 03926 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); 03927 } 03928 return ERROR_NT(NT_STATUS_INTERNAL_ERROR); 03929 } 03930 03931 if (file_acl) { 03932 SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); 03933 } 03934 if (def_acl) { 03935 SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); 03936 } 03937 data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE; 03938 break; 03939 } 03940 #endif 03941 03942 03943 case SMB_QUERY_POSIX_LOCK: 03944 { 03945 NTSTATUS status = NT_STATUS_INVALID_LEVEL; 03946 SMB_BIG_UINT count; 03947 SMB_BIG_UINT offset; 03948 uint32 lock_pid; 03949 enum brl_type lock_type; 03950 03951 if (total_data != POSIX_LOCK_DATA_SIZE) { 03952 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 03953 } 03954 03955 switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) { 03956 case POSIX_LOCK_TYPE_READ: 03957 lock_type = READ_LOCK; 03958 break; 03959 case POSIX_LOCK_TYPE_WRITE: 03960 lock_type = WRITE_LOCK; 03961 break; 03962 case POSIX_LOCK_TYPE_UNLOCK: 03963 default: 03964 /* There's no point in asking for an unlock... */ 03965 talloc_destroy(data_ctx); 03966 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 03967 } 03968 03969 lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET); 03970 #if defined(HAVE_LONGLONG) 03971 offset = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) | 03972 ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_START_OFFSET)); 03973 count = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) | 03974 ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_LEN_OFFSET)); 03975 #else /* HAVE_LONGLONG */ 03976 offset = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_START_OFFSET); 03977 count = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_LEN_OFFSET); 03978 #endif /* HAVE_LONGLONG */ 03979 03980 status = query_lock(fsp, 03981 &lock_pid, 03982 &count, 03983 &offset, 03984 &lock_type, 03985 POSIX_LOCK); 03986 03987 if (ERROR_WAS_LOCK_DENIED(status)) { 03988 /* Here we need to report who has it locked... */ 03989 data_size = POSIX_LOCK_DATA_SIZE; 03990 03991 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, lock_type); 03992 SSVAL(pdata, POSIX_LOCK_FLAGS_OFFSET, 0); 03993 SIVAL(pdata, POSIX_LOCK_PID_OFFSET, lock_pid); 03994 #if defined(HAVE_LONGLONG) 03995 SIVAL(pdata, POSIX_LOCK_START_OFFSET, (uint32)(offset & 0xFFFFFFFF)); 03996 SIVAL(pdata, POSIX_LOCK_START_OFFSET + 4, (uint32)((offset >> 32) & 0xFFFFFFFF)); 03997 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, (uint32)(count & 0xFFFFFFFF)); 03998 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET + 4, (uint32)((count >> 32) & 0xFFFFFFFF)); 03999 #else /* HAVE_LONGLONG */ 04000 SIVAL(pdata, POSIX_LOCK_START_OFFSET, offset); 04001 SIVAL(pdata, POSIX_LOCK_LEN_OFFSET, count); 04002 #endif /* HAVE_LONGLONG */ 04003 04004 } else if (NT_STATUS_IS_OK(status)) { 04005 /* For success we just return a copy of what we sent 04006 with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */ 04007 data_size = POSIX_LOCK_DATA_SIZE; 04008 memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE); 04009 SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK); 04010 } else { 04011 return ERROR_NT(status); 04012 } 04013 break; 04014 } 04015 04016 default: 04017 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 04018 } 04019 04020 send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size, max_data_bytes); 04021 04022 return(-1); 04023 }
NTSTATUS hardlink_internals | ( | connection_struct * | conn, | |
pstring | oldname, | |||
pstring | newname | |||
) |
参照先 check_name()・errno・map_nt_error_from_unix()・nt_errstr()・reduce_name()・status・unix_convert().
参照元 reply_ntrename()・smb_set_file_unix_hlink().
04031 { 04032 SMB_STRUCT_STAT sbuf1, sbuf2; 04033 pstring last_component_oldname; 04034 pstring last_component_newname; 04035 NTSTATUS status = NT_STATUS_OK; 04036 04037 ZERO_STRUCT(sbuf1); 04038 ZERO_STRUCT(sbuf2); 04039 04040 status = unix_convert(conn, oldname, False, last_component_oldname, &sbuf1); 04041 if (!NT_STATUS_IS_OK(status)) { 04042 return status; 04043 } 04044 04045 status = check_name(conn, oldname); 04046 if (!NT_STATUS_IS_OK(status)) { 04047 return status; 04048 } 04049 04050 /* source must already exist. */ 04051 if (!VALID_STAT(sbuf1)) { 04052 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 04053 } 04054 04055 status = unix_convert(conn, newname, False, last_component_newname, &sbuf2); 04056 if (!NT_STATUS_IS_OK(status)) { 04057 return status; 04058 } 04059 04060 status = check_name(conn, newname); 04061 if (!NT_STATUS_IS_OK(status)) { 04062 return status; 04063 } 04064 04065 /* Disallow if newname already exists. */ 04066 if (VALID_STAT(sbuf2)) { 04067 return NT_STATUS_OBJECT_NAME_COLLISION; 04068 } 04069 04070 /* No links from a directory. */ 04071 if (S_ISDIR(sbuf1.st_mode)) { 04072 return NT_STATUS_FILE_IS_A_DIRECTORY; 04073 } 04074 04075 /* Ensure this is within the share. */ 04076 status = reduce_name(conn, oldname); 04077 if (!NT_STATUS_IS_OK(status)) { 04078 return status; 04079 } 04080 04081 DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname )); 04082 04083 if (SMB_VFS_LINK(conn,oldname,newname) != 0) { 04084 status = map_nt_error_from_unix(errno); 04085 DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n", 04086 nt_errstr(status), newname, oldname)); 04087 } 04088 04089 return status; 04090 }
static NTSTATUS smb_set_file_time | ( | connection_struct * | conn, | |
files_struct * | fsp, | |||
const char * | fname, | |||
const SMB_STRUCT_STAT * | psbuf, | |||
struct timespec | ts[2] | |||
) | [static] |
参照先 convert_timespec_to_time_t()・errno・fsp_set_pending_modtime()・get_atimespec()・get_mtimespec()・map_nt_error_from_unix()・notify_fname()・null_timespec()・time_to_asc()・timespec_compare().
参照元 smb_set_file_basic_info()・smb_set_file_unix_basic()・smb_set_info_standard().
04101 { 04102 uint32 action = 04103 FILE_NOTIFY_CHANGE_LAST_ACCESS 04104 |FILE_NOTIFY_CHANGE_LAST_WRITE; 04105 04106 04107 if (!VALID_STAT(*psbuf)) { 04108 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 04109 } 04110 04111 /* get some defaults (no modifications) if any info is zero or -1. */ 04112 if (null_timespec(ts[0])) { 04113 ts[0] = get_atimespec(psbuf); 04114 action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS; 04115 } 04116 04117 if (null_timespec(ts[1])) { 04118 ts[1] = get_mtimespec(psbuf); 04119 action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE; 04120 } 04121 04122 DEBUG(6,("smb_set_file_time: actime: %s " , time_to_asc(convert_timespec_to_time_t(ts[0])) )); 04123 DEBUG(6,("smb_set_file_time: modtime: %s ", time_to_asc(convert_timespec_to_time_t(ts[1])) )); 04124 04125 /* 04126 * Try and set the times of this file if 04127 * they are different from the current values. 04128 */ 04129 04130 { 04131 struct timespec mts = get_mtimespec(psbuf); 04132 struct timespec ats = get_atimespec(psbuf); 04133 if ((timespec_compare(&ts[0], &ats) == 0) && (timespec_compare(&ts[1], &mts) == 0)) { 04134 return NT_STATUS_OK; 04135 } 04136 } 04137 04138 if(fsp != NULL) { 04139 /* 04140 * This was a setfileinfo on an open file. 04141 * NT does this a lot. We also need to 04142 * set the time here, as it can be read by 04143 * FindFirst/FindNext and with the patch for bug #2045 04144 * in smbd/fileio.c it ensures that this timestamp is 04145 * kept sticky even after a write. We save the request 04146 * away and will set it on file close and after a write. JRA. 04147 */ 04148 04149 if (!null_timespec(ts[1])) { 04150 DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n", 04151 time_to_asc(convert_timespec_to_time_t(ts[1])) )); 04152 fsp_set_pending_modtime(fsp, ts[1]); 04153 } 04154 04155 } 04156 DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n")); 04157 04158 if(file_ntimes(conn, fname, ts)!=0) { 04159 return map_nt_error_from_unix(errno); 04160 } 04161 if (action != 0) { 04162 notify_fname(conn, NOTIFY_ACTION_MODIFIED, action, fname); 04163 } 04164 return NT_STATUS_OK; 04165 }
static NTSTATUS smb_set_file_dosmode | ( | connection_struct * | conn, | |
const char * | fname, | |||
SMB_STRUCT_STAT * | psbuf, | |||
uint32 | dosmode | |||
) | [static] |
参照先 errno・map_nt_error_from_unix()・strerror().
参照元 smb_set_file_basic_info().
04175 { 04176 if (!VALID_STAT(*psbuf)) { 04177 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 04178 } 04179 04180 if (dosmode) { 04181 if (S_ISDIR(psbuf->st_mode)) { 04182 dosmode |= aDIR; 04183 } else { 04184 dosmode &= ~aDIR; 04185 } 04186 } 04187 04188 DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode)); 04189 04190 /* check the mode isn't different, before changing it */ 04191 if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, psbuf))) { 04192 04193 DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode 0x%x\n", 04194 fname, (unsigned int)dosmode )); 04195 04196 if(file_set_dosmode(conn, fname, dosmode, psbuf, False)) { 04197 DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of %s failed (%s)\n", 04198 fname, strerror(errno))); 04199 return map_nt_error_from_unix(errno); 04200 } 04201 } 04202 return NT_STATUS_OK; 04203 }
static NTSTATUS smb_set_file_size | ( | connection_struct * | conn, | |
files_struct * | fsp, | |||
const char * | fname, | |||
SMB_STRUCT_STAT * | psbuf, | |||
SMB_OFF_T | size | |||
) | [static] |
参照先 close_file()・errno・fd_handle::fd・files_struct::fh・get_file_size()・map_nt_error_from_unix()・NORMAL_CLOSE・open_file_ntcreate()・status・vfs_set_filelen().
参照元 smb_set_file_end_of_file_info()・smb_set_file_unix_basic().
04214 { 04215 NTSTATUS status = NT_STATUS_OK; 04216 files_struct *new_fsp = NULL; 04217 04218 if (!VALID_STAT(*psbuf)) { 04219 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 04220 } 04221 04222 DEBUG(6,("smb_set_file_size: size: %.0f ", (double)size)); 04223 04224 if (size == get_file_size(*psbuf)) { 04225 return NT_STATUS_OK; 04226 } 04227 04228 DEBUG(10,("smb_set_file_size: file %s : setting new size to %.0f\n", 04229 fname, (double)size )); 04230 04231 if (fsp && fsp->fh->fd != -1) { 04232 /* Handle based call. */ 04233 if (vfs_set_filelen(fsp, size) == -1) { 04234 return map_nt_error_from_unix(errno); 04235 } 04236 return NT_STATUS_OK; 04237 } 04238 04239 status = open_file_ntcreate(conn, fname, psbuf, 04240 FILE_WRITE_DATA, 04241 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 04242 FILE_OPEN, 04243 0, 04244 FILE_ATTRIBUTE_NORMAL, 04245 FORCE_OPLOCK_BREAK_TO_NONE, 04246 NULL, &new_fsp); 04247 04248 if (!NT_STATUS_IS_OK(status)) { 04249 /* NB. We check for open_was_deferred in the caller. */ 04250 return status; 04251 } 04252 04253 if (vfs_set_filelen(new_fsp, size) == -1) { 04254 status = map_nt_error_from_unix(errno); 04255 close_file(new_fsp,NORMAL_CLOSE); 04256 return status; 04257 } 04258 04259 close_file(new_fsp,NORMAL_CLOSE); 04260 return NT_STATUS_OK; 04261 }
static NTSTATUS smb_info_set_ea | ( | connection_struct * | conn, | |
const char * | pdata, | |||
int | total_data, | |||
files_struct * | fsp, | |||
const char * | fname | |||
) | [static] |
参照先 ctx・read_ea_list()・set_ea()・status・talloc_init().
参照元 call_trans2setfilepathinfo().
04272 { 04273 struct ea_list *ea_list = NULL; 04274 TALLOC_CTX *ctx = NULL; 04275 NTSTATUS status = NT_STATUS_OK; 04276 04277 if (total_data < 10) { 04278 04279 /* OS/2 workplace shell seems to send SET_EA requests of "null" 04280 length. They seem to have no effect. Bug #3212. JRA */ 04281 04282 if ((total_data == 4) && (IVAL(pdata,0) == 4)) { 04283 /* We're done. We only get EA info in this call. */ 04284 return NT_STATUS_OK; 04285 } 04286 04287 return NT_STATUS_INVALID_PARAMETER; 04288 } 04289 04290 if (IVAL(pdata,0) > total_data) { 04291 DEBUG(10,("smb_info_set_ea: bad total data size (%u) > %u\n", 04292 IVAL(pdata,0), (unsigned int)total_data)); 04293 return NT_STATUS_INVALID_PARAMETER; 04294 } 04295 04296 ctx = talloc_init("SMB_INFO_SET_EA"); 04297 if (!ctx) { 04298 return NT_STATUS_NO_MEMORY; 04299 } 04300 ea_list = read_ea_list(ctx, pdata + 4, total_data - 4); 04301 if (!ea_list) { 04302 talloc_destroy(ctx); 04303 return NT_STATUS_INVALID_PARAMETER; 04304 } 04305 status = set_ea(conn, fsp, fname, ea_list); 04306 talloc_destroy(ctx); 04307 04308 return status; 04309 }
static NTSTATUS smb_set_file_disposition_info | ( | connection_struct * | conn, | |
const char * | pdata, | |||
int | total_data, | |||
files_struct * | fsp, | |||
const char * | fname, | |||
SMB_STRUCT_STAT * | psbuf | |||
) | [static] |
参照先 can_set_delete_on_close()・current_user・files_struct::fsp_name・set_delete_on_close()・status・current_user::ut.
参照元 call_trans2setfilepathinfo().
04321 { 04322 NTSTATUS status = NT_STATUS_OK; 04323 BOOL delete_on_close; 04324 uint32 dosmode = 0; 04325 04326 if (total_data < 1) { 04327 return NT_STATUS_INVALID_PARAMETER; 04328 } 04329 04330 if (fsp == NULL) { 04331 return NT_STATUS_INVALID_HANDLE; 04332 } 04333 04334 delete_on_close = (CVAL(pdata,0) ? True : False); 04335 dosmode = dos_mode(conn, fname, psbuf); 04336 04337 DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, " 04338 "delete_on_close = %u\n", 04339 fsp->fsp_name, 04340 (unsigned int)dosmode, 04341 (unsigned int)delete_on_close )); 04342 04343 status = can_set_delete_on_close(fsp, delete_on_close, dosmode); 04344 04345 if (!NT_STATUS_IS_OK(status)) { 04346 return status; 04347 } 04348 04349 /* The set is across all open files on this dev/inode pair. */ 04350 if (!set_delete_on_close(fsp, delete_on_close, ¤t_user.ut)) { 04351 return NT_STATUS_ACCESS_DENIED; 04352 } 04353 return NT_STATUS_OK; 04354 }
static NTSTATUS smb_file_position_information | ( | connection_struct * | conn, | |
const char * | pdata, | |||
int | total_data, | |||
files_struct * | fsp | |||
) | [static] |
参照先 files_struct::fh・files_struct::fsp_name・fd_handle::position_information.
参照元 call_trans2setfilepathinfo().
04364 { 04365 SMB_BIG_UINT position_information; 04366 04367 if (total_data < 8) { 04368 return NT_STATUS_INVALID_PARAMETER; 04369 } 04370 04371 if (fsp == NULL) { 04372 /* Ignore on pathname based set. */ 04373 return NT_STATUS_OK; 04374 } 04375 04376 position_information = (SMB_BIG_UINT)IVAL(pdata,0); 04377 #ifdef LARGE_SMB_OFF_T 04378 position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32); 04379 #else /* LARGE_SMB_OFF_T */ 04380 if (IVAL(pdata,4) != 0) { 04381 /* more than 32 bits? */ 04382 return NT_STATUS_INVALID_PARAMETER; 04383 } 04384 #endif /* LARGE_SMB_OFF_T */ 04385 04386 DEBUG(10,("smb_file_position_information: Set file position information for file %s to %.0f\n", 04387 fsp->fsp_name, (double)position_information )); 04388 fsp->fh->position_information = position_information; 04389 return NT_STATUS_OK; 04390 }
static NTSTATUS smb_file_mode_information | ( | connection_struct * | conn, | |
const char * | pdata, | |||
int | total_data | |||
) | [static] |
参照先 mode.
参照元 call_trans2setfilepathinfo().
04399 { 04400 uint32 mode; 04401 04402 if (total_data < 4) { 04403 return NT_STATUS_INVALID_PARAMETER; 04404 } 04405 mode = IVAL(pdata,0); 04406 if (mode != 0 && mode != 2 && mode != 4 && mode != 6) { 04407 return NT_STATUS_INVALID_PARAMETER; 04408 } 04409 return NT_STATUS_OK; 04410 }
static NTSTATUS smb_set_file_unix_link | ( | connection_struct * | conn, | |
char * | inbuf, | |||
const char * | pdata, | |||
int | total_data, | |||
const char * | fname | |||
) | [static] |
参照先 check_name()・errno・map_nt_error_from_unix()・status・strrchr_m().
参照元 call_trans2setfilepathinfo().
04421 { 04422 pstring link_target; 04423 const char *newname = fname; 04424 NTSTATUS status = NT_STATUS_OK; 04425 04426 /* Set a symbolic link. */ 04427 /* Don't allow this if follow links is false. */ 04428 04429 if (total_data == 0) { 04430 return NT_STATUS_INVALID_PARAMETER; 04431 } 04432 04433 if (!lp_symlinks(SNUM(conn))) { 04434 return NT_STATUS_ACCESS_DENIED; 04435 } 04436 04437 srvstr_pull(inbuf, link_target, pdata, sizeof(link_target), total_data, STR_TERMINATE); 04438 04439 /* !widelinks forces the target path to be within the share. */ 04440 /* This means we can interpret the target as a pathname. */ 04441 if (!lp_widelinks(SNUM(conn))) { 04442 pstring rel_name; 04443 char *last_dirp = NULL; 04444 04445 if (*link_target == '/') { 04446 /* No absolute paths allowed. */ 04447 return NT_STATUS_ACCESS_DENIED; 04448 } 04449 pstrcpy(rel_name, newname); 04450 last_dirp = strrchr_m(rel_name, '/'); 04451 if (last_dirp) { 04452 last_dirp[1] = '\0'; 04453 } else { 04454 pstrcpy(rel_name, "./"); 04455 } 04456 pstrcat(rel_name, link_target); 04457 04458 status = check_name(conn, rel_name); 04459 if (!NT_STATUS_IS_OK(status)) { 04460 return status; 04461 } 04462 } 04463 04464 DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n", 04465 newname, link_target )); 04466 04467 if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0) { 04468 return map_nt_error_from_unix(errno); 04469 } 04470 04471 return NT_STATUS_OK; 04472 }
static NTSTATUS smb_set_file_unix_hlink | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
const char * | pdata, | |||
int | total_data, | |||
pstring | fname | |||
) | [static] |
参照先 hardlink_internals()・resolve_dfspath()・srvstr_get_path()・status.
参照元 call_trans2setfilepathinfo().
04484 { 04485 pstring oldname; 04486 NTSTATUS status = NT_STATUS_OK; 04487 04488 /* Set a hard link. */ 04489 if (total_data == 0) { 04490 return NT_STATUS_INVALID_PARAMETER; 04491 } 04492 04493 srvstr_get_path(inbuf, oldname, pdata, sizeof(oldname), total_data, STR_TERMINATE, &status); 04494 if (!NT_STATUS_IS_OK(status)) { 04495 return status; 04496 } 04497 04498 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, oldname); 04499 if (!NT_STATUS_IS_OK(status)) { 04500 return status; 04501 } 04502 04503 DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n", 04504 fname, oldname)); 04505 04506 return hardlink_internals(conn, oldname, fname); 04507 }
static NTSTATUS smb_file_rename_information | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
const char * | pdata, | |||
int | total_data, | |||
files_struct * | fsp, | |||
pstring | fname | |||
) | [static] |
参照先 files_struct::fnum・files_struct::fsp_name・len・rename_internals()・rename_internals_fsp()・resolve_dfspath_wcard()・srvstr_get_path_wcard()・status・strchr_m()・strrchr_m().
参照元 call_trans2setfilepathinfo().
04520 { 04521 BOOL overwrite; 04522 /* uint32 root_fid; */ /* Not used */ 04523 uint32 len; 04524 pstring newname; 04525 pstring base_name; 04526 BOOL dest_has_wcard = False; 04527 NTSTATUS status = NT_STATUS_OK; 04528 char *p; 04529 04530 if (total_data < 13) { 04531 return NT_STATUS_INVALID_PARAMETER; 04532 } 04533 04534 overwrite = (CVAL(pdata,0) ? True : False); 04535 /* root_fid = IVAL(pdata,4); */ 04536 len = IVAL(pdata,8); 04537 04538 if (len > (total_data - 12) || (len == 0)) { 04539 return NT_STATUS_INVALID_PARAMETER; 04540 } 04541 04542 srvstr_get_path_wcard(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status, &dest_has_wcard); 04543 if (!NT_STATUS_IS_OK(status)) { 04544 return status; 04545 } 04546 04547 status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newname, &dest_has_wcard); 04548 if (!NT_STATUS_IS_OK(status)) { 04549 return status; 04550 } 04551 04552 /* Check the new name has no '/' characters. */ 04553 if (strchr_m(newname, '/')) { 04554 return NT_STATUS_NOT_SUPPORTED; 04555 } 04556 04557 /* Create the base directory. */ 04558 pstrcpy(base_name, fname); 04559 p = strrchr_m(base_name, '/'); 04560 if (p) { 04561 p[1] = '\0'; 04562 } else { 04563 pstrcpy(base_name, "./"); 04564 } 04565 /* Append the new name. */ 04566 pstrcat(base_name, newname); 04567 04568 if (fsp) { 04569 DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n", 04570 fsp->fnum, fsp->fsp_name, base_name )); 04571 status = rename_internals_fsp(conn, fsp, base_name, 0, overwrite); 04572 } else { 04573 DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION %s -> %s\n", 04574 fname, newname )); 04575 status = rename_internals(conn, fname, base_name, 0, overwrite, False, dest_has_wcard); 04576 } 04577 04578 return status; 04579 }
static NTSTATUS smb_set_posix_acl | ( | connection_struct * | conn, | |
const char * | pdata, | |||
int | total_data, | |||
files_struct * | fsp, | |||
const char * | fname, | |||
SMB_STRUCT_STAT * | psbuf | |||
) | [static] |
参照先 errno・files_struct::fsp_name・map_nt_error_from_unix()・set_unix_posix_acl()・set_unix_posix_default_acl().
参照元 call_trans2setfilepathinfo().
04592 { 04593 uint16 posix_acl_version; 04594 uint16 num_file_acls; 04595 uint16 num_def_acls; 04596 BOOL valid_file_acls = True; 04597 BOOL valid_def_acls = True; 04598 04599 if (total_data < SMB_POSIX_ACL_HEADER_SIZE) { 04600 return NT_STATUS_INVALID_PARAMETER; 04601 } 04602 posix_acl_version = SVAL(pdata,0); 04603 num_file_acls = SVAL(pdata,2); 04604 num_def_acls = SVAL(pdata,4); 04605 04606 if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) { 04607 valid_file_acls = False; 04608 num_file_acls = 0; 04609 } 04610 04611 if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) { 04612 valid_def_acls = False; 04613 num_def_acls = 0; 04614 } 04615 04616 if (posix_acl_version != SMB_POSIX_ACL_VERSION) { 04617 return NT_STATUS_INVALID_PARAMETER; 04618 } 04619 04620 if (total_data < SMB_POSIX_ACL_HEADER_SIZE + 04621 (num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) { 04622 return NT_STATUS_INVALID_PARAMETER; 04623 } 04624 04625 DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n", 04626 fname ? fname : fsp->fsp_name, 04627 (unsigned int)num_file_acls, 04628 (unsigned int)num_def_acls)); 04629 04630 if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls, 04631 pdata + SMB_POSIX_ACL_HEADER_SIZE)) { 04632 return map_nt_error_from_unix(errno); 04633 } 04634 04635 if (valid_def_acls && !set_unix_posix_default_acl(conn, fname, psbuf, num_def_acls, 04636 pdata + SMB_POSIX_ACL_HEADER_SIZE + 04637 (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) { 04638 return map_nt_error_from_unix(errno); 04639 } 04640 return NT_STATUS_OK; 04641 }
static NTSTATUS smb_set_posix_lock | ( | connection_struct * | conn, | |
char * | inbuf, | |||
int | length, | |||
const char * | pdata, | |||
int | total_data, | |||
files_struct * | fsp | |||
) | [static] |
参照先 files_struct::can_write・do_lock()・do_unlock()・fd_handle::fd・files_struct::fh・byte_range_lock::fsp・files_struct::fsp_name・POSIX_LOCK・push_blocking_lock_request()・READ_LOCK・status・UNLOCK_LOCK・WRITE_LOCK.
参照元 call_trans2setfilepathinfo().
04654 { 04655 SMB_BIG_UINT count; 04656 SMB_BIG_UINT offset; 04657 uint32 lock_pid; 04658 BOOL blocking_lock = False; 04659 enum brl_type lock_type; 04660 NTSTATUS status = NT_STATUS_OK; 04661 04662 if (fsp == NULL || fsp->fh->fd == -1) { 04663 return NT_STATUS_INVALID_HANDLE; 04664 } 04665 04666 if (total_data != POSIX_LOCK_DATA_SIZE) { 04667 return NT_STATUS_INVALID_PARAMETER; 04668 } 04669 04670 switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) { 04671 case POSIX_LOCK_TYPE_READ: 04672 lock_type = READ_LOCK; 04673 break; 04674 case POSIX_LOCK_TYPE_WRITE: 04675 /* Return the right POSIX-mappable error code for files opened read-only. */ 04676 if (!fsp->can_write) { 04677 return NT_STATUS_INVALID_HANDLE; 04678 } 04679 lock_type = WRITE_LOCK; 04680 break; 04681 case POSIX_LOCK_TYPE_UNLOCK: 04682 lock_type = UNLOCK_LOCK; 04683 break; 04684 default: 04685 return NT_STATUS_INVALID_PARAMETER; 04686 } 04687 04688 if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_NOWAIT) { 04689 blocking_lock = False; 04690 } else if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_WAIT) { 04691 blocking_lock = True; 04692 } else { 04693 return NT_STATUS_INVALID_PARAMETER; 04694 } 04695 04696 if (!lp_blocking_locks(SNUM(conn))) { 04697 blocking_lock = False; 04698 } 04699 04700 lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET); 04701 #if defined(HAVE_LONGLONG) 04702 offset = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) | 04703 ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_START_OFFSET)); 04704 count = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) | 04705 ((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_LEN_OFFSET)); 04706 #else /* HAVE_LONGLONG */ 04707 offset = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_START_OFFSET); 04708 count = (SMB_BIG_UINT)IVAL(pdata,POSIX_LOCK_LEN_OFFSET); 04709 #endif /* HAVE_LONGLONG */ 04710 04711 DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u," 04712 "lock_pid = %u, count = %.0f, offset = %.0f\n", 04713 fsp->fsp_name, 04714 (unsigned int)lock_type, 04715 (unsigned int)lock_pid, 04716 (double)count, 04717 (double)offset )); 04718 04719 if (lock_type == UNLOCK_LOCK) { 04720 status = do_unlock(fsp, 04721 lock_pid, 04722 count, 04723 offset, 04724 POSIX_LOCK); 04725 } else { 04726 uint32 block_smbpid; 04727 04728 struct byte_range_lock *br_lck = do_lock(fsp, 04729 lock_pid, 04730 count, 04731 offset, 04732 lock_type, 04733 POSIX_LOCK, 04734 blocking_lock, 04735 &status, 04736 &block_smbpid); 04737 04738 if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) { 04739 /* 04740 * A blocking lock was requested. Package up 04741 * this smb into a queued request and push it 04742 * onto the blocking lock queue. 04743 */ 04744 if(push_blocking_lock_request(br_lck, 04745 inbuf, length, 04746 fsp, 04747 -1, /* infinite timeout. */ 04748 0, 04749 lock_pid, 04750 lock_type, 04751 POSIX_LOCK, 04752 offset, 04753 count, 04754 block_smbpid)) { 04755 TALLOC_FREE(br_lck); 04756 return status; 04757 } 04758 } 04759 TALLOC_FREE(br_lck); 04760 } 04761 04762 return status; 04763 }
static NTSTATUS smb_set_info_standard | ( | connection_struct * | conn, | |
const char * | pdata, | |||
int | total_data, | |||
files_struct * | fsp, | |||
const char * | fname, | |||
const SMB_STRUCT_STAT * | psbuf | |||
) | [static] |
参照先 convert_time_t_to_timespec()・files_struct::fsp_name・smb_set_file_time()・srv_make_unix_date2().
参照元 call_trans2setfilepathinfo().
04775 { 04776 struct timespec ts[2]; 04777 04778 if (total_data < 12) { 04779 return NT_STATUS_INVALID_PARAMETER; 04780 } 04781 04782 /* access time */ 04783 ts[0] = convert_time_t_to_timespec(srv_make_unix_date2(pdata+l1_fdateLastAccess)); 04784 /* write time */ 04785 ts[1] = convert_time_t_to_timespec(srv_make_unix_date2(pdata+l1_fdateLastWrite)); 04786 04787 DEBUG(10,("smb_set_info_standard: file %s\n", 04788 fname ? fname : fsp->fsp_name )); 04789 04790 return smb_set_file_time(conn, 04791 fsp, 04792 fname, 04793 psbuf, 04794 ts); 04795 }
static NTSTATUS smb_set_file_basic_info | ( | connection_struct * | conn, | |
const char * | pdata, | |||
int | total_data, | |||
files_struct * | fsp, | |||
const char * | fname, | |||
SMB_STRUCT_STAT * | psbuf | |||
) | [static] |
参照先 files_struct::fsp_name・interpret_long_date()・null_timespec()・smb_set_file_dosmode()・smb_set_file_time()・status・timespec_compare()・timespec_min().
参照元 call_trans2setfilepathinfo().
04807 { 04808 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */ 04809 struct timespec write_time; 04810 struct timespec changed_time; 04811 uint32 dosmode = 0; 04812 struct timespec ts[2]; 04813 NTSTATUS status = NT_STATUS_OK; 04814 04815 if (total_data < 36) { 04816 return NT_STATUS_INVALID_PARAMETER; 04817 } 04818 04819 /* Set the attributes */ 04820 dosmode = IVAL(pdata,32); 04821 status = smb_set_file_dosmode(conn, 04822 fname, 04823 psbuf, 04824 dosmode); 04825 if (!NT_STATUS_IS_OK(status)) { 04826 return status; 04827 } 04828 04829 /* Ignore create time at offset pdata. */ 04830 04831 /* access time */ 04832 ts[0] = interpret_long_date(pdata+8); 04833 04834 write_time = interpret_long_date(pdata+16); 04835 changed_time = interpret_long_date(pdata+24); 04836 04837 /* mtime */ 04838 ts[1] = timespec_min(&write_time, &changed_time); 04839 04840 if ((timespec_compare(&write_time, &ts[1]) == 1) && !null_timespec(write_time)) { 04841 ts[1] = write_time; 04842 } 04843 04844 /* Prefer a defined time to an undefined one. */ 04845 if (null_timespec(ts[1])) { 04846 ts[1] = null_timespec(write_time) ? changed_time : write_time; 04847 } 04848 04849 DEBUG(10,("smb_set_file_basic_info: file %s\n", 04850 fname ? fname : fsp->fsp_name )); 04851 04852 return smb_set_file_time(conn, 04853 fsp, 04854 fname, 04855 psbuf, 04856 ts); 04857 }
static NTSTATUS smb_set_file_allocation_info | ( | connection_struct * | conn, | |
const char * | pdata, | |||
int | total_data, | |||
files_struct * | fsp, | |||
const char * | fname, | |||
SMB_STRUCT_STAT * | psbuf | |||
) | [static] |
参照先 close_file()・files_struct::conn・errno・fd_handle::fd・files_struct::fh・files_struct::fsp_name・fsp_set_pending_modtime()・get_file_size()・map_nt_error_from_unix()・NORMAL_CLOSE・null_timespec()・open_file_ntcreate()・files_struct::pending_modtime・smb_roundup()・status・timespec_current()・vfs_allocate_file_space().
参照元 call_trans2setfilepathinfo().
04869 { 04870 SMB_BIG_UINT allocation_size = 0; 04871 NTSTATUS status = NT_STATUS_OK; 04872 files_struct *new_fsp = NULL; 04873 04874 if (!VALID_STAT(*psbuf)) { 04875 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 04876 } 04877 04878 if (total_data < 8) { 04879 return NT_STATUS_INVALID_PARAMETER; 04880 } 04881 04882 allocation_size = (SMB_BIG_UINT)IVAL(pdata,0); 04883 #ifdef LARGE_SMB_OFF_T 04884 allocation_size |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32); 04885 #else /* LARGE_SMB_OFF_T */ 04886 if (IVAL(pdata,4) != 0) { 04887 /* more than 32 bits? */ 04888 return NT_STATUS_INVALID_PARAMETER; 04889 } 04890 #endif /* LARGE_SMB_OFF_T */ 04891 04892 DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for file %s to %.0f\n", 04893 fname, (double)allocation_size )); 04894 04895 if (allocation_size) { 04896 allocation_size = smb_roundup(conn, allocation_size); 04897 } 04898 04899 DEBUG(10,("smb_set_file_allocation_info: file %s : setting new allocation size to %.0f\n", 04900 fname, (double)allocation_size )); 04901 04902 if (fsp && fsp->fh->fd != -1) { 04903 /* Open file handle. */ 04904 /* Only change if needed. */ 04905 if (allocation_size != get_file_size(*psbuf)) { 04906 if (vfs_allocate_file_space(fsp, allocation_size) == -1) { 04907 return map_nt_error_from_unix(errno); 04908 } 04909 } 04910 /* But always update the time. */ 04911 if (null_timespec(fsp->pending_modtime)) { 04912 /* 04913 * This is equivalent to a write. Ensure it's seen immediately 04914 * if there are no pending writes. 04915 */ 04916 set_filetime(fsp->conn, fsp->fsp_name, timespec_current()); 04917 } 04918 return NT_STATUS_OK; 04919 } 04920 04921 /* Pathname or stat or directory file. */ 04922 04923 status = open_file_ntcreate(conn, fname, psbuf, 04924 FILE_WRITE_DATA, 04925 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 04926 FILE_OPEN, 04927 0, 04928 FILE_ATTRIBUTE_NORMAL, 04929 FORCE_OPLOCK_BREAK_TO_NONE, 04930 NULL, &new_fsp); 04931 04932 if (!NT_STATUS_IS_OK(status)) { 04933 /* NB. We check for open_was_deferred in the caller. */ 04934 return status; 04935 } 04936 04937 /* Only change if needed. */ 04938 if (allocation_size != get_file_size(*psbuf)) { 04939 if (vfs_allocate_file_space(new_fsp, allocation_size) == -1) { 04940 status = map_nt_error_from_unix(errno); 04941 close_file(new_fsp,NORMAL_CLOSE); 04942 return status; 04943 } 04944 } 04945 04946 /* Changing the allocation size should set the last mod time. */ 04947 /* Don't need to call set_filetime as this will be flushed on 04948 * close. */ 04949 04950 fsp_set_pending_modtime(new_fsp, timespec_current()); 04951 04952 close_file(new_fsp,NORMAL_CLOSE); 04953 return NT_STATUS_OK; 04954 }
static NTSTATUS smb_set_file_end_of_file_info | ( | connection_struct * | conn, | |
const char * | pdata, | |||
int | total_data, | |||
files_struct * | fsp, | |||
const char * | fname, | |||
SMB_STRUCT_STAT * | psbuf | |||
) | [static] |
参照先 size・smb_set_file_size().
参照元 call_trans2setfilepathinfo().
04966 { 04967 SMB_OFF_T size; 04968 04969 if (total_data < 8) { 04970 return NT_STATUS_INVALID_PARAMETER; 04971 } 04972 04973 size = IVAL(pdata,0); 04974 #ifdef LARGE_SMB_OFF_T 04975 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32); 04976 #else /* LARGE_SMB_OFF_T */ 04977 if (IVAL(pdata,4) != 0) { 04978 /* more than 32 bits? */ 04979 return NT_STATUS_INVALID_PARAMETER; 04980 } 04981 #endif /* LARGE_SMB_OFF_T */ 04982 DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for " 04983 "file %s to %.0f\n", fname, (double)size )); 04984 04985 return smb_set_file_size(conn, 04986 fsp, 04987 fname, 04988 psbuf, 04989 size); 04990 }
static NTSTATUS smb_unix_mknod | ( | connection_struct * | conn, | |
const char * | pdata, | |||
int | total_data, | |||
const char * | fname, | |||
SMB_STRUCT_STAT * | psbuf | |||
) | [static] |
参照先 dev・errno・inherit_access_acl()・map_nt_error_from_unix()・parent_dirname()・PERM_NEW_FILE・status・unix_perms_from_wire().
参照元 smb_set_file_unix_basic().
05001 { 05002 uint32 file_type = IVAL(pdata,56); 05003 #if defined(HAVE_MAKEDEV) 05004 uint32 dev_major = IVAL(pdata,60); 05005 uint32 dev_minor = IVAL(pdata,68); 05006 #endif 05007 SMB_DEV_T dev = (SMB_DEV_T)0; 05008 uint32 raw_unixmode = IVAL(pdata,84); 05009 NTSTATUS status; 05010 mode_t unixmode; 05011 05012 if (total_data < 100) { 05013 return NT_STATUS_INVALID_PARAMETER; 05014 } 05015 05016 status = unix_perms_from_wire(conn, psbuf, raw_unixmode, PERM_NEW_FILE, &unixmode); 05017 if (!NT_STATUS_IS_OK(status)) { 05018 return status; 05019 } 05020 05021 #if defined(HAVE_MAKEDEV) 05022 dev = makedev(dev_major, dev_minor); 05023 #endif 05024 05025 switch (file_type) { 05026 #if defined(S_IFIFO) 05027 case UNIX_TYPE_FIFO: 05028 unixmode |= S_IFIFO; 05029 break; 05030 #endif 05031 #if defined(S_IFSOCK) 05032 case UNIX_TYPE_SOCKET: 05033 unixmode |= S_IFSOCK; 05034 break; 05035 #endif 05036 #if defined(S_IFCHR) 05037 case UNIX_TYPE_CHARDEV: 05038 unixmode |= S_IFCHR; 05039 break; 05040 #endif 05041 #if defined(S_IFBLK) 05042 case UNIX_TYPE_BLKDEV: 05043 unixmode |= S_IFBLK; 05044 break; 05045 #endif 05046 default: 05047 return NT_STATUS_INVALID_PARAMETER; 05048 } 05049 05050 DEBUG(10,("smb_unix_mknod: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \ 05051 0%o for file %s\n", (double)dev, (unsigned int)unixmode, fname )); 05052 05053 /* Ok - do the mknod. */ 05054 if (SMB_VFS_MKNOD(conn, fname, unixmode, dev) != 0) { 05055 return map_nt_error_from_unix(errno); 05056 } 05057 05058 /* If any of the other "set" calls fail we 05059 * don't want to end up with a half-constructed mknod. 05060 */ 05061 05062 if (lp_inherit_perms(SNUM(conn))) { 05063 inherit_access_acl( 05064 conn, parent_dirname(fname), 05065 fname, unixmode); 05066 } 05067 05068 if (SMB_VFS_STAT(conn, fname, psbuf) != 0) { 05069 status = map_nt_error_from_unix(errno); 05070 SMB_VFS_UNLINK(conn,fname); 05071 return status; 05072 } 05073 return NT_STATUS_OK; 05074 }
static NTSTATUS smb_set_file_unix_basic | ( | connection_struct * | conn, | |
const char * | pdata, | |||
int | total_data, | |||
files_struct * | fsp, | |||
const char * | fname, | |||
SMB_STRUCT_STAT * | psbuf | |||
) | [static] |
参照先 errno・get_atimespec()・get_file_size()・get_mtimespec()・interpret_long_date()・map_nt_error_from_unix()・PERM_EXISTING_DIR・PERM_EXISTING_FILE・PERM_NEW_FILE・size・smb_set_file_size()・smb_set_file_time()・smb_unix_mknod()・status・unix_perms_from_wire().
参照元 call_trans2setfilepathinfo()・smb_set_file_unix_info2().
05086 { 05087 struct timespec ts[2]; 05088 uint32 raw_unixmode; 05089 mode_t unixmode; 05090 SMB_OFF_T size = 0; 05091 uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE; 05092 gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE; 05093 NTSTATUS status = NT_STATUS_OK; 05094 BOOL delete_on_fail = False; 05095 enum perm_type ptype; 05096 05097 if (total_data < 100) { 05098 return NT_STATUS_INVALID_PARAMETER; 05099 } 05100 05101 if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO && 05102 IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) { 05103 size=IVAL(pdata,0); /* first 8 Bytes are size */ 05104 #ifdef LARGE_SMB_OFF_T 05105 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32); 05106 #else /* LARGE_SMB_OFF_T */ 05107 if (IVAL(pdata,4) != 0) { 05108 /* more than 32 bits? */ 05109 return NT_STATUS_INVALID_PARAMETER; 05110 } 05111 #endif /* LARGE_SMB_OFF_T */ 05112 } 05113 05114 ts[0] = interpret_long_date(pdata+24); /* access_time */ 05115 ts[1] = interpret_long_date(pdata+32); /* modification_time */ 05116 set_owner = (uid_t)IVAL(pdata,40); 05117 set_grp = (gid_t)IVAL(pdata,48); 05118 raw_unixmode = IVAL(pdata,84); 05119 05120 if (VALID_STAT(*psbuf)) { 05121 if (S_ISDIR(psbuf->st_mode)) { 05122 ptype = PERM_EXISTING_DIR; 05123 } else { 05124 ptype = PERM_EXISTING_FILE; 05125 } 05126 } else { 05127 ptype = PERM_NEW_FILE; 05128 } 05129 05130 status = unix_perms_from_wire(conn, psbuf, raw_unixmode, ptype, &unixmode); 05131 if (!NT_STATUS_IS_OK(status)) { 05132 return status; 05133 } 05134 05135 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = %s \ 05136 size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", 05137 fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode)); 05138 05139 if (!VALID_STAT(*psbuf)) { 05140 /* 05141 * The only valid use of this is to create character and block 05142 * devices, and named pipes. This is deprecated (IMHO) and 05143 * a new info level should be used for mknod. JRA. 05144 */ 05145 05146 status = smb_unix_mknod(conn, 05147 pdata, 05148 total_data, 05149 fname, 05150 psbuf); 05151 if (!NT_STATUS_IS_OK(status)) { 05152 return status; 05153 } 05154 05155 /* Ensure we don't try and change anything else. */ 05156 raw_unixmode = SMB_MODE_NO_CHANGE; 05157 size = get_file_size(*psbuf); 05158 ts[0] = get_atimespec(psbuf); 05159 ts[1] = get_mtimespec(psbuf); 05160 /* 05161 * We continue here as we might want to change the 05162 * owner uid/gid. 05163 */ 05164 delete_on_fail = True; 05165 } 05166 05167 #if 1 05168 /* Horrible backwards compatibility hack as an old server bug 05169 * allowed a CIFS client bug to remain unnoticed :-(. JRA. 05170 * */ 05171 05172 if (!size) { 05173 size = get_file_size(*psbuf); 05174 } 05175 #endif 05176 05177 /* 05178 * Deal with the UNIX specific mode set. 05179 */ 05180 05181 if (raw_unixmode != SMB_MODE_NO_CHANGE) { 05182 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n", 05183 (unsigned int)unixmode, fname )); 05184 if (SMB_VFS_CHMOD(conn, fname, unixmode) != 0) { 05185 return map_nt_error_from_unix(errno); 05186 } 05187 } 05188 05189 /* 05190 * Deal with the UNIX specific uid set. 05191 */ 05192 05193 if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (psbuf->st_uid != set_owner)) { 05194 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n", 05195 (unsigned int)set_owner, fname )); 05196 if (SMB_VFS_CHOWN(conn, fname, set_owner, (gid_t)-1) != 0) { 05197 status = map_nt_error_from_unix(errno); 05198 if (delete_on_fail) { 05199 SMB_VFS_UNLINK(conn,fname); 05200 } 05201 return status; 05202 } 05203 } 05204 05205 /* 05206 * Deal with the UNIX specific gid set. 05207 */ 05208 05209 if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (psbuf->st_gid != set_grp)) { 05210 DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n", 05211 (unsigned int)set_owner, fname )); 05212 if (SMB_VFS_CHOWN(conn, fname, (uid_t)-1, set_grp) != 0) { 05213 status = map_nt_error_from_unix(errno); 05214 if (delete_on_fail) { 05215 SMB_VFS_UNLINK(conn,fname); 05216 } 05217 return status; 05218 } 05219 } 05220 05221 /* Deal with any size changes. */ 05222 05223 status = smb_set_file_size(conn, 05224 fsp, 05225 fname, 05226 psbuf, 05227 size); 05228 if (!NT_STATUS_IS_OK(status)) { 05229 return status; 05230 } 05231 05232 /* Deal with any time changes. */ 05233 05234 return smb_set_file_time(conn, 05235 fsp, 05236 fname, 05237 psbuf, 05238 ts); 05239 }
static NTSTATUS smb_set_file_unix_info2 | ( | connection_struct * | conn, | |
const char * | pdata, | |||
int | total_data, | |||
files_struct * | fsp, | |||
const char * | fname, | |||
SMB_STRUCT_STAT * | psbuf | |||
) | [static] |
参照先 errno・fd_handle::fd・files_struct::fh・map_info2_flags_to_sbuf()・map_nt_error_from_unix()・smb_set_file_unix_basic()・status.
参照元 call_trans2setfilepathinfo().
05251 { 05252 NTSTATUS status; 05253 uint32 smb_fflags; 05254 uint32 smb_fmask; 05255 05256 if (total_data < 116) { 05257 return NT_STATUS_INVALID_PARAMETER; 05258 } 05259 05260 /* Start by setting all the fields that are common between UNIX_BASIC 05261 * and UNIX_INFO2. 05262 */ 05263 status = smb_set_file_unix_basic(conn, pdata, total_data, 05264 fsp, fname, psbuf); 05265 if (!NT_STATUS_IS_OK(status)) { 05266 return status; 05267 } 05268 05269 smb_fflags = IVAL(pdata, 108); 05270 smb_fmask = IVAL(pdata, 112); 05271 05272 /* NB: We should only attempt to alter the file flags if the client 05273 * sends a non-zero mask. 05274 */ 05275 if (smb_fmask != 0) { 05276 int stat_fflags = 0; 05277 05278 if (!map_info2_flags_to_sbuf(psbuf, smb_fflags, smb_fmask, 05279 &stat_fflags)) { 05280 /* Client asked to alter a flag we don't understand. */ 05281 return NT_STATUS_INVALID_PARAMETER; 05282 } 05283 05284 if (fsp && fsp->fh->fd != -1) { 05285 /* XXX: we should be using SMB_VFS_FCHFLAGS here. */ 05286 return NT_STATUS_NOT_SUPPORTED; 05287 } else { 05288 if (SMB_VFS_CHFLAGS(conn, fname, stat_fflags) != 0) { 05289 return map_nt_error_from_unix(errno); 05290 } 05291 } 05292 } 05293 05294 /* XXX: need to add support for changing the create_time here. You 05295 * can do this for paths on Darwin with setattrlist(2). The right way 05296 * to hook this up is probably by extending the VFS utimes interface. 05297 */ 05298 05299 return NT_STATUS_OK; 05300 }
static NTSTATUS smb_posix_mkdir | ( | connection_struct * | conn, | |
char ** | ppdata, | |||
int | total_data, | |||
const char * | fname, | |||
SMB_STRUCT_STAT * | psbuf, | |||
int * | pdata_return_size | |||
) | [static] |
参照先 close_file()・NORMAL_CLOSE・open_directory()・PERM_NEW_DIR・status・store_file_unix_basic()・store_file_unix_basic_info2()・unix_perms_from_wire().
参照元 smb_posix_open().
05312 { 05313 NTSTATUS status = NT_STATUS_OK; 05314 uint32 raw_unixmode = 0; 05315 uint32 mod_unixmode = 0; 05316 mode_t unixmode = (mode_t)0; 05317 files_struct *fsp = NULL; 05318 uint16 info_level_return = 0; 05319 int info; 05320 char *pdata = *ppdata; 05321 05322 if (total_data < 18) { 05323 return NT_STATUS_INVALID_PARAMETER; 05324 } 05325 05326 raw_unixmode = IVAL(pdata,8); 05327 /* Next 4 bytes are not yet defined. */ 05328 05329 status = unix_perms_from_wire(conn, psbuf, raw_unixmode, PERM_NEW_DIR, &unixmode); 05330 if (!NT_STATUS_IS_OK(status)) { 05331 return status; 05332 } 05333 05334 mod_unixmode = (uint32)unixmode | FILE_FLAG_POSIX_SEMANTICS; 05335 05336 DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n", 05337 fname, (unsigned int)unixmode )); 05338 05339 status = open_directory(conn, 05340 fname, 05341 psbuf, 05342 FILE_READ_ATTRIBUTES, /* Just a stat open */ 05343 FILE_SHARE_NONE, /* Ignored for stat opens */ 05344 FILE_CREATE, 05345 0, 05346 mod_unixmode, 05347 &info, 05348 &fsp); 05349 05350 if (NT_STATUS_IS_OK(status)) { 05351 close_file(fsp, NORMAL_CLOSE); 05352 } 05353 05354 info_level_return = SVAL(pdata,16); 05355 05356 if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) { 05357 *pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE; 05358 } else if (info_level_return == SMB_QUERY_FILE_UNIX_INFO2) { 05359 *pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE; 05360 } else { 05361 *pdata_return_size = 12; 05362 } 05363 05364 /* Realloc the data size */ 05365 *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size); 05366 if (*ppdata == NULL) { 05367 *pdata_return_size = 0; 05368 return NT_STATUS_NO_MEMORY; 05369 } 05370 pdata = *ppdata; 05371 05372 SSVAL(pdata,0,NO_OPLOCK_RETURN); 05373 SSVAL(pdata,2,0); /* No fnum. */ 05374 SIVAL(pdata,4,info); /* Was directory created. */ 05375 05376 switch (info_level_return) { 05377 case SMB_QUERY_FILE_UNIX_BASIC: 05378 SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC); 05379 SSVAL(pdata,10,0); /* Padding. */ 05380 store_file_unix_basic(conn, pdata + 12, fsp, psbuf); 05381 break; 05382 case SMB_QUERY_FILE_UNIX_INFO2: 05383 SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2); 05384 SSVAL(pdata,10,0); /* Padding. */ 05385 store_file_unix_basic_info2(conn, pdata + 12, fsp, psbuf); 05386 break; 05387 default: 05388 SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED); 05389 SSVAL(pdata,10,0); /* Padding. */ 05390 break; 05391 } 05392 05393 return status; 05394 }
static NTSTATUS smb_posix_open | ( | connection_struct * | conn, | |
char ** | ppdata, | |||
int | total_data, | |||
const char * | fname, | |||
SMB_STRUCT_STAT * | psbuf, | |||
int * | pdata_return_size | |||
) | [static] |
参照先 close_file()・ERROR_CLOSE・flags・files_struct::fnum・open_file_ntcreate()・files_struct::oplock_type・PERM_EXISTING_FILE・PERM_NEW_FILE・smb_posix_mkdir()・status・store_file_unix_basic()・store_file_unix_basic_info2()・unix_perms_from_wire().
参照元 call_trans2setfilepathinfo().
05406 { 05407 BOOL extended_oplock_granted = False; 05408 char *pdata = *ppdata; 05409 uint32 flags = 0; 05410 uint32 wire_open_mode = 0; 05411 uint32 raw_unixmode = 0; 05412 uint32 mod_unixmode = 0; 05413 uint32 create_disp = 0; 05414 uint32 access_mask = 0; 05415 uint32 create_options = 0; 05416 NTSTATUS status = NT_STATUS_OK; 05417 mode_t unixmode = (mode_t)0; 05418 files_struct *fsp = NULL; 05419 int oplock_request = 0; 05420 int info = 0; 05421 uint16 info_level_return = 0; 05422 05423 if (total_data < 18) { 05424 return NT_STATUS_INVALID_PARAMETER; 05425 } 05426 05427 flags = IVAL(pdata,0); 05428 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; 05429 if (oplock_request) { 05430 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0; 05431 } 05432 05433 wire_open_mode = IVAL(pdata,4); 05434 05435 if (wire_open_mode == (SMB_O_CREAT|SMB_O_DIRECTORY)) { 05436 return smb_posix_mkdir(conn, 05437 ppdata, 05438 total_data, 05439 fname, 05440 psbuf, 05441 pdata_return_size); 05442 } 05443 05444 switch (wire_open_mode & SMB_ACCMODE) { 05445 case SMB_O_RDONLY: 05446 access_mask = FILE_READ_DATA; 05447 break; 05448 case SMB_O_WRONLY: 05449 access_mask = FILE_WRITE_DATA; 05450 break; 05451 case SMB_O_RDWR: 05452 access_mask = FILE_READ_DATA|FILE_WRITE_DATA; 05453 break; 05454 default: 05455 DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n", 05456 (unsigned int)wire_open_mode )); 05457 return NT_STATUS_INVALID_PARAMETER; 05458 } 05459 05460 wire_open_mode &= ~SMB_ACCMODE; 05461 05462 if((wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL)) == (SMB_O_CREAT | SMB_O_EXCL)) { 05463 create_disp = FILE_CREATE; 05464 } else if((wire_open_mode & (SMB_O_CREAT | SMB_O_TRUNC)) == (SMB_O_CREAT | SMB_O_TRUNC)) { 05465 create_disp = FILE_OVERWRITE_IF; 05466 } else if((wire_open_mode & SMB_O_CREAT) == SMB_O_CREAT) { 05467 create_disp = FILE_OPEN_IF; 05468 } else { 05469 DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n", 05470 (unsigned int)wire_open_mode )); 05471 return NT_STATUS_INVALID_PARAMETER; 05472 } 05473 05474 raw_unixmode = IVAL(pdata,8); 05475 /* Next 4 bytes are not yet defined. */ 05476 05477 status = unix_perms_from_wire(conn, 05478 psbuf, 05479 raw_unixmode, 05480 VALID_STAT(*psbuf) ? PERM_EXISTING_FILE : PERM_NEW_FILE, 05481 &unixmode); 05482 05483 if (!NT_STATUS_IS_OK(status)) { 05484 return status; 05485 } 05486 05487 mod_unixmode = (uint32)unixmode | FILE_FLAG_POSIX_SEMANTICS; 05488 05489 if (wire_open_mode & SMB_O_SYNC) { 05490 create_options |= FILE_WRITE_THROUGH; 05491 } 05492 if (wire_open_mode & SMB_O_APPEND) { 05493 access_mask |= FILE_APPEND_DATA; 05494 } 05495 if (wire_open_mode & SMB_O_DIRECT) { 05496 mod_unixmode |= FILE_FLAG_NO_BUFFERING; 05497 } 05498 05499 DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n", 05500 fname, 05501 (unsigned int)wire_open_mode, 05502 (unsigned int)unixmode )); 05503 05504 status = open_file_ntcreate(conn, 05505 fname, 05506 psbuf, 05507 access_mask, 05508 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 05509 create_disp, 05510 0, /* no create options yet. */ 05511 mod_unixmode, 05512 oplock_request, 05513 &info, 05514 &fsp); 05515 05516 if (!NT_STATUS_IS_OK(status)) { 05517 return status; 05518 } 05519 05520 if (oplock_request && lp_fake_oplocks(SNUM(conn))) { 05521 extended_oplock_granted = True; 05522 } 05523 05524 if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { 05525 extended_oplock_granted = True; 05526 } 05527 05528 info_level_return = SVAL(pdata,16); 05529 05530 /* Allocate the correct return size. */ 05531 05532 if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) { 05533 *pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE; 05534 } else if (info_level_return == SMB_QUERY_FILE_UNIX_INFO2) { 05535 *pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE; 05536 } else { 05537 *pdata_return_size = 12; 05538 } 05539 05540 /* Realloc the data size */ 05541 *ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size); 05542 if (*ppdata == NULL) { 05543 close_file(fsp,ERROR_CLOSE); 05544 *pdata_return_size = 0; 05545 return NT_STATUS_NO_MEMORY; 05546 } 05547 pdata = *ppdata; 05548 05549 if (extended_oplock_granted) { 05550 if (flags & REQUEST_BATCH_OPLOCK) { 05551 SSVAL(pdata,0, BATCH_OPLOCK_RETURN); 05552 } else { 05553 SSVAL(pdata,0, EXCLUSIVE_OPLOCK_RETURN); 05554 } 05555 } else if (fsp->oplock_type == LEVEL_II_OPLOCK) { 05556 SSVAL(pdata,0, LEVEL_II_OPLOCK_RETURN); 05557 } else { 05558 SSVAL(pdata,0,NO_OPLOCK_RETURN); 05559 } 05560 05561 SSVAL(pdata,2,fsp->fnum); 05562 SIVAL(pdata,4,info); /* Was file created etc. */ 05563 05564 switch (info_level_return) { 05565 case SMB_QUERY_FILE_UNIX_BASIC: 05566 SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC); 05567 SSVAL(pdata,10,0); /* padding. */ 05568 store_file_unix_basic(conn, pdata + 12, fsp, psbuf); 05569 break; 05570 case SMB_QUERY_FILE_UNIX_INFO2: 05571 SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2); 05572 SSVAL(pdata,10,0); /* padding. */ 05573 store_file_unix_basic_info2(conn, pdata + 12, fsp, psbuf); 05574 break; 05575 default: 05576 SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED); 05577 SSVAL(pdata,10,0); /* padding. */ 05578 break; 05579 } 05580 return NT_STATUS_OK; 05581 }
static NTSTATUS smb_posix_unlink | ( | connection_struct * | conn, | |
const char * | pdata, | |||
int | total_data, | |||
const char * | fname, | |||
SMB_STRUCT_STAT * | psbuf | |||
) | [static] |
参照先 close_file()・files_struct::dev・flags・files_struct::fsp_name・get_share_mode_lock()・files_struct::inode・is_valid_share_mode_entry()・NORMAL_CLOSE・share_mode_lock::num_share_modes・open_directory()・open_file_ntcreate()・share_mode_lock::share_modes・status.
参照元 call_trans2setfilepathinfo().
05592 { 05593 NTSTATUS status = NT_STATUS_OK; 05594 files_struct *fsp = NULL; 05595 uint16 flags = 0; 05596 char del = 1; 05597 int info = 0; 05598 int i; 05599 struct share_mode_lock *lck = NULL; 05600 05601 if (total_data < 2) { 05602 return NT_STATUS_INVALID_PARAMETER; 05603 } 05604 05605 flags = SVAL(pdata,0); 05606 05607 if (!VALID_STAT(*psbuf)) { 05608 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 05609 } 05610 05611 if ((flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) && 05612 !VALID_STAT_OF_DIR(*psbuf)) { 05613 return NT_STATUS_NOT_A_DIRECTORY; 05614 } 05615 05616 DEBUG(10,("smb_posix_unlink: %s %s\n", 05617 (flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) ? "directory" : "file", 05618 fname)); 05619 05620 if (VALID_STAT_OF_DIR(*psbuf)) { 05621 status = open_directory(conn, 05622 fname, 05623 psbuf, 05624 DELETE_ACCESS, 05625 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 05626 FILE_OPEN, 05627 0, 05628 FILE_FLAG_POSIX_SEMANTICS|0777, 05629 &info, 05630 &fsp); 05631 } else { 05632 05633 status = open_file_ntcreate(conn, 05634 fname, 05635 psbuf, 05636 DELETE_ACCESS, 05637 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 05638 FILE_OPEN, 05639 0, 05640 FILE_FLAG_POSIX_SEMANTICS|0777, 05641 0, /* No oplock, but break existing ones. */ 05642 &info, 05643 &fsp); 05644 } 05645 05646 if (!NT_STATUS_IS_OK(status)) { 05647 return status; 05648 } 05649 05650 /* 05651 * Don't lie to client. If we can't really delete due to 05652 * non-POSIX opens return SHARING_VIOLATION. 05653 */ 05654 05655 lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL); 05656 if (lck == NULL) { 05657 DEBUG(0, ("smb_posix_unlink: Could not get share mode " 05658 "lock for file %s\n", fsp->fsp_name)); 05659 close_file(fsp, NORMAL_CLOSE); 05660 return NT_STATUS_INVALID_PARAMETER; 05661 } 05662 05663 /* 05664 * See if others still have the file open. If this is the case, then 05665 * don't delete. If all opens are POSIX delete we can set the delete 05666 * on close disposition. 05667 */ 05668 for (i=0; i<lck->num_share_modes; i++) { 05669 struct share_mode_entry *e = &lck->share_modes[i]; 05670 if (is_valid_share_mode_entry(e)) { 05671 if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) { 05672 continue; 05673 } 05674 /* Fail with sharing violation. */ 05675 close_file(fsp, NORMAL_CLOSE); 05676 TALLOC_FREE(lck); 05677 return NT_STATUS_SHARING_VIOLATION; 05678 } 05679 } 05680 05681 /* 05682 * Set the delete on close. 05683 */ 05684 status = smb_set_file_disposition_info(conn, 05685 &del, 05686 1, 05687 fsp, 05688 fname, 05689 psbuf); 05690 05691 if (!NT_STATUS_IS_OK(status)) { 05692 close_file(fsp, NORMAL_CLOSE); 05693 TALLOC_FREE(lck); 05694 return status; 05695 } 05696 TALLOC_FREE(lck); 05697 return close_file(fsp, NORMAL_CLOSE); 05698 }
static int call_trans2setfilepathinfo | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize, | |||
unsigned int | tran_call, | |||
char ** | pparams, | |||
int | total_params, | |||
char ** | ppdata, | |||
int | total_data, | |||
unsigned int | max_data_bytes | |||
) | [static] |
参照先 blocking_lock_was_deferred()・check_name()・errno・fd_handle::fd・files_struct::fh・file_fsp()・files_struct::fnum・files_struct::fsp_name・files_struct::is_directory・null_timespec()・open_was_deferred()・files_struct::pending_modtime・files_struct::print_file・fd_handle::private_options・resolve_dfspath()・send_trans2_replies()・set_mtimespec()・smb_file_mode_information()・smb_file_position_information()・smb_file_rename_information()・smb_info_set_ea()・smb_posix_open()・smb_posix_unlink()・smb_set_file_allocation_info()・smb_set_file_basic_info()・smb_set_file_disposition_info()・smb_set_file_end_of_file_info()・smb_set_file_unix_basic()・smb_set_file_unix_hlink()・smb_set_file_unix_info2()・smb_set_file_unix_link()・smb_set_info_standard()・smb_set_posix_acl()・smb_set_posix_lock()・srvstr_get_path()・status・strerror()・unix_convert().
参照元 handle_trans2().
05708 { 05709 char *params = *pparams; 05710 char *pdata = *ppdata; 05711 uint16 info_level; 05712 SMB_STRUCT_STAT sbuf; 05713 pstring fname; 05714 files_struct *fsp = NULL; 05715 NTSTATUS status = NT_STATUS_OK; 05716 int data_return_size = 0; 05717 05718 if (!params) { 05719 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 05720 } 05721 05722 ZERO_STRUCT(sbuf); 05723 05724 if (tran_call == TRANSACT2_SETFILEINFO) { 05725 if (total_params < 4) { 05726 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 05727 } 05728 05729 fsp = file_fsp(params,0); 05730 info_level = SVAL(params,2); 05731 05732 if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) { 05733 /* 05734 * This is actually a SETFILEINFO on a directory 05735 * handle (returned from an NT SMB). NT5.0 seems 05736 * to do this call. JRA. 05737 */ 05738 pstrcpy(fname, fsp->fsp_name); 05739 if (INFO_LEVEL_IS_UNIX(info_level)) { 05740 /* Always do lstat for UNIX calls. */ 05741 if (SMB_VFS_LSTAT(conn,fname,&sbuf)) { 05742 DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno))); 05743 return UNIXERROR(ERRDOS,ERRbadpath); 05744 } 05745 } else { 05746 if (SMB_VFS_STAT(conn,fname,&sbuf) != 0) { 05747 DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno))); 05748 return UNIXERROR(ERRDOS,ERRbadpath); 05749 } 05750 } 05751 } else if (fsp && fsp->print_file) { 05752 /* 05753 * Doing a DELETE_ON_CLOSE should cancel a print job. 05754 */ 05755 if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) { 05756 fsp->fh->private_options |= FILE_DELETE_ON_CLOSE; 05757 05758 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name )); 05759 05760 SSVAL(params,0,0); 05761 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes); 05762 return(-1); 05763 } else 05764 return (UNIXERROR(ERRDOS,ERRbadpath)); 05765 } else { 05766 /* 05767 * Original code - this is an open file. 05768 */ 05769 CHECK_FSP(fsp,conn); 05770 05771 pstrcpy(fname, fsp->fsp_name); 05772 05773 if (SMB_VFS_FSTAT(fsp, fsp->fh->fd, &sbuf) != 0) { 05774 DEBUG(3,("call_trans2setfilepathinfo: fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno))); 05775 return(UNIXERROR(ERRDOS,ERRbadfid)); 05776 } 05777 } 05778 } else { 05779 /* set path info */ 05780 if (total_params < 7) { 05781 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 05782 } 05783 05784 info_level = SVAL(params,0); 05785 srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), total_params - 6, STR_TERMINATE, &status); 05786 if (!NT_STATUS_IS_OK(status)) { 05787 return ERROR_NT(status); 05788 } 05789 05790 status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname); 05791 if (!NT_STATUS_IS_OK(status)) { 05792 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 05793 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 05794 } 05795 return ERROR_NT(status); 05796 } 05797 05798 status = unix_convert(conn, fname, False, NULL, &sbuf); 05799 if (!NT_STATUS_IS_OK(status)) { 05800 return ERROR_NT(status); 05801 } 05802 05803 status = check_name(conn, fname); 05804 if (!NT_STATUS_IS_OK(status)) { 05805 return ERROR_NT(status); 05806 } 05807 05808 if (INFO_LEVEL_IS_UNIX(info_level)) { 05809 /* 05810 * For CIFS UNIX extensions the target name may not exist. 05811 */ 05812 05813 /* Always do lstat for UNIX calls. */ 05814 SMB_VFS_LSTAT(conn,fname,&sbuf); 05815 05816 } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) { 05817 DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno))); 05818 return UNIXERROR(ERRDOS,ERRbadpath); 05819 } 05820 } 05821 05822 if (!CAN_WRITE(conn)) { 05823 return ERROR_DOS(ERRSRV,ERRaccess); 05824 } 05825 05826 if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { 05827 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 05828 } 05829 05830 DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n", 05831 tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data)); 05832 05833 /* Realloc the parameter size */ 05834 *pparams = (char *)SMB_REALLOC(*pparams,2); 05835 if (*pparams == NULL) { 05836 return ERROR_NT(NT_STATUS_NO_MEMORY); 05837 } 05838 params = *pparams; 05839 05840 SSVAL(params,0,0); 05841 05842 if (fsp && !null_timespec(fsp->pending_modtime)) { 05843 /* the pending modtime overrides the current modtime */ 05844 set_mtimespec(&sbuf, fsp->pending_modtime); 05845 } 05846 05847 switch (info_level) { 05848 05849 case SMB_INFO_STANDARD: 05850 { 05851 status = smb_set_info_standard(conn, 05852 pdata, 05853 total_data, 05854 fsp, 05855 fname, 05856 &sbuf); 05857 break; 05858 } 05859 05860 case SMB_INFO_SET_EA: 05861 { 05862 status = smb_info_set_ea(conn, 05863 pdata, 05864 total_data, 05865 fsp, 05866 fname); 05867 break; 05868 } 05869 05870 case SMB_SET_FILE_BASIC_INFO: 05871 case SMB_FILE_BASIC_INFORMATION: 05872 { 05873 status = smb_set_file_basic_info(conn, 05874 pdata, 05875 total_data, 05876 fsp, 05877 fname, 05878 &sbuf); 05879 break; 05880 } 05881 05882 case SMB_FILE_ALLOCATION_INFORMATION: 05883 case SMB_SET_FILE_ALLOCATION_INFO: 05884 { 05885 status = smb_set_file_allocation_info(conn, 05886 pdata, 05887 total_data, 05888 fsp, 05889 fname, 05890 &sbuf); 05891 break; 05892 } 05893 05894 case SMB_FILE_END_OF_FILE_INFORMATION: 05895 case SMB_SET_FILE_END_OF_FILE_INFO: 05896 { 05897 status = smb_set_file_end_of_file_info(conn, 05898 pdata, 05899 total_data, 05900 fsp, 05901 fname, 05902 &sbuf); 05903 break; 05904 } 05905 05906 case SMB_FILE_DISPOSITION_INFORMATION: 05907 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */ 05908 { 05909 #if 0 05910 /* JRA - We used to just ignore this on a path ? 05911 * Shouldn't this be invalid level on a pathname 05912 * based call ? 05913 */ 05914 if (tran_call != TRANSACT2_SETFILEINFO) { 05915 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 05916 } 05917 #endif 05918 status = smb_set_file_disposition_info(conn, 05919 pdata, 05920 total_data, 05921 fsp, 05922 fname, 05923 &sbuf); 05924 break; 05925 } 05926 05927 case SMB_FILE_POSITION_INFORMATION: 05928 { 05929 status = smb_file_position_information(conn, 05930 pdata, 05931 total_data, 05932 fsp); 05933 break; 05934 } 05935 05936 /* From tridge Samba4 : 05937 * MODE_INFORMATION in setfileinfo (I have no 05938 * idea what "mode information" on a file is - it takes a value of 0, 05939 * 2, 4 or 6. What could it be?). 05940 */ 05941 05942 case SMB_FILE_MODE_INFORMATION: 05943 { 05944 status = smb_file_mode_information(conn, 05945 pdata, 05946 total_data); 05947 break; 05948 } 05949 05950 /* 05951 * CIFS UNIX extensions. 05952 */ 05953 05954 case SMB_SET_FILE_UNIX_BASIC: 05955 { 05956 status = smb_set_file_unix_basic(conn, 05957 pdata, 05958 total_data, 05959 fsp, 05960 fname, 05961 &sbuf); 05962 break; 05963 } 05964 05965 case SMB_SET_FILE_UNIX_INFO2: 05966 { 05967 status = smb_set_file_unix_info2(conn, 05968 pdata, 05969 total_data, 05970 fsp, 05971 fname, 05972 &sbuf); 05973 break; 05974 } 05975 05976 case SMB_SET_FILE_UNIX_LINK: 05977 { 05978 if (tran_call != TRANSACT2_SETPATHINFO) { 05979 /* We must have a pathname for this. */ 05980 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 05981 } 05982 status = smb_set_file_unix_link(conn, 05983 inbuf, 05984 pdata, 05985 total_data, 05986 fname); 05987 break; 05988 } 05989 05990 case SMB_SET_FILE_UNIX_HLINK: 05991 { 05992 if (tran_call != TRANSACT2_SETPATHINFO) { 05993 /* We must have a pathname for this. */ 05994 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 05995 } 05996 status = smb_set_file_unix_hlink(conn, 05997 inbuf, 05998 outbuf, 05999 pdata, 06000 total_data, 06001 fname); 06002 break; 06003 } 06004 06005 case SMB_FILE_RENAME_INFORMATION: 06006 { 06007 status = smb_file_rename_information(conn, 06008 inbuf, 06009 outbuf, 06010 pdata, 06011 total_data, 06012 fsp, 06013 fname); 06014 break; 06015 } 06016 06017 #if defined(HAVE_POSIX_ACLS) 06018 case SMB_SET_POSIX_ACL: 06019 { 06020 status = smb_set_posix_acl(conn, 06021 pdata, 06022 total_data, 06023 fsp, 06024 fname, 06025 &sbuf); 06026 break; 06027 } 06028 #endif 06029 06030 case SMB_SET_POSIX_LOCK: 06031 { 06032 if (tran_call != TRANSACT2_SETFILEINFO) { 06033 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 06034 } 06035 status = smb_set_posix_lock(conn, 06036 inbuf, 06037 length, 06038 pdata, 06039 total_data, 06040 fsp); 06041 break; 06042 } 06043 06044 case SMB_POSIX_PATH_OPEN: 06045 { 06046 if (tran_call != TRANSACT2_SETPATHINFO) { 06047 /* We must have a pathname for this. */ 06048 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 06049 } 06050 06051 status = smb_posix_open(conn, 06052 ppdata, 06053 total_data, 06054 fname, 06055 &sbuf, 06056 &data_return_size); 06057 break; 06058 } 06059 06060 case SMB_POSIX_PATH_UNLINK: 06061 { 06062 if (tran_call != TRANSACT2_SETPATHINFO) { 06063 /* We must have a pathname for this. */ 06064 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 06065 } 06066 06067 status = smb_posix_unlink(conn, 06068 pdata, 06069 total_data, 06070 fname, 06071 &sbuf); 06072 break; 06073 } 06074 06075 default: 06076 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 06077 } 06078 06079 06080 if (!NT_STATUS_IS_OK(status)) { 06081 if (open_was_deferred(SVAL(inbuf,smb_mid))) { 06082 /* We have re-scheduled this call. */ 06083 return -1; 06084 } 06085 if (blocking_lock_was_deferred(SVAL(inbuf,smb_mid))) { 06086 /* We have re-scheduled this call. */ 06087 return -1; 06088 } 06089 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { 06090 return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); 06091 } 06092 if (info_level == SMB_POSIX_PATH_OPEN) { 06093 return ERROR_OPEN(status); 06094 } 06095 return ERROR_NT(status); 06096 } 06097 06098 SSVAL(params,0,0); 06099 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_return_size, max_data_bytes); 06100 06101 return -1; 06102 }
static int call_trans2mkdir | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize, | |||
char ** | pparams, | |||
int | total_params, | |||
char ** | ppdata, | |||
int | total_data, | |||
unsigned int | max_data_bytes | |||
) | [static] |
参照先 check_name()・create_directory()・nt_errstr()・read_ea_list()・send_trans2_replies()・set_ea()・srvstr_get_path()・status・tmp_talloc_ctx()・unix_convert().
参照元 handle_trans2().
06111 { 06112 char *params = *pparams; 06113 char *pdata = *ppdata; 06114 pstring directory; 06115 SMB_STRUCT_STAT sbuf; 06116 NTSTATUS status = NT_STATUS_OK; 06117 struct ea_list *ea_list = NULL; 06118 06119 if (!CAN_WRITE(conn)) 06120 return ERROR_DOS(ERRSRV,ERRaccess); 06121 06122 if (total_params < 5) { 06123 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 06124 } 06125 06126 srvstr_get_path(inbuf, directory, ¶ms[4], sizeof(directory), total_params - 4, STR_TERMINATE, &status); 06127 if (!NT_STATUS_IS_OK(status)) { 06128 return ERROR_NT(status); 06129 } 06130 06131 DEBUG(3,("call_trans2mkdir : name = %s\n", directory)); 06132 06133 status = unix_convert(conn, directory, False, NULL, &sbuf); 06134 if (!NT_STATUS_IS_OK(status)) { 06135 return ERROR_NT(status); 06136 } 06137 06138 status = check_name(conn, directory); 06139 if (!NT_STATUS_IS_OK(status)) { 06140 DEBUG(5,("call_trans2mkdir error (%s)\n", nt_errstr(status))); 06141 return ERROR_NT(status); 06142 } 06143 06144 /* Any data in this call is an EA list. */ 06145 if (total_data && (total_data != 4) && !lp_ea_support(SNUM(conn))) { 06146 return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED); 06147 } 06148 06149 /* 06150 * OS/2 workplace shell seems to send SET_EA requests of "null" 06151 * length (4 bytes containing IVAL 4). 06152 * They seem to have no effect. Bug #3212. JRA. 06153 */ 06154 06155 if (total_data != 4) { 06156 if (total_data < 10) { 06157 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 06158 } 06159 06160 if (IVAL(pdata,0) > total_data) { 06161 DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n", 06162 IVAL(pdata,0), (unsigned int)total_data)); 06163 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 06164 } 06165 06166 ea_list = read_ea_list(tmp_talloc_ctx(), pdata + 4, 06167 total_data - 4); 06168 if (!ea_list) { 06169 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 06170 } 06171 } else if (IVAL(pdata,0) != 4) { 06172 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 06173 } 06174 06175 status = create_directory(conn, directory); 06176 06177 if (!NT_STATUS_IS_OK(status)) { 06178 return ERROR_NT(status); 06179 } 06180 06181 /* Try and set any given EA. */ 06182 if (ea_list) { 06183 status = set_ea(conn, NULL, directory, ea_list); 06184 if (!NT_STATUS_IS_OK(status)) { 06185 return ERROR_NT(status); 06186 } 06187 } 06188 06189 /* Realloc the parameter and data sizes */ 06190 *pparams = (char *)SMB_REALLOC(*pparams,2); 06191 if(*pparams == NULL) { 06192 return ERROR_NT(NT_STATUS_NO_MEMORY); 06193 } 06194 params = *pparams; 06195 06196 SSVAL(params,0,0); 06197 06198 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes); 06199 06200 return(-1); 06201 }
static int call_trans2findnotifyfirst | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize, | |||
char ** | pparams, | |||
int | total_params, | |||
char ** | ppdata, | |||
int | total_data, | |||
unsigned int | max_data_bytes | |||
) | [static] |
参照元 handle_trans2().
06211 { 06212 static uint16 fnf_handle = 257; 06213 char *params = *pparams; 06214 uint16 info_level; 06215 06216 if (total_params < 6) { 06217 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 06218 } 06219 06220 info_level = SVAL(params,4); 06221 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level)); 06222 06223 switch (info_level) { 06224 case 1: 06225 case 2: 06226 break; 06227 default: 06228 return ERROR_NT(NT_STATUS_INVALID_LEVEL); 06229 } 06230 06231 /* Realloc the parameter and data sizes */ 06232 *pparams = (char *)SMB_REALLOC(*pparams,6); 06233 if (*pparams == NULL) { 06234 return ERROR_NT(NT_STATUS_NO_MEMORY); 06235 } 06236 params = *pparams; 06237 06238 SSVAL(params,0,fnf_handle); 06239 SSVAL(params,2,0); /* No changes */ 06240 SSVAL(params,4,0); /* No EA errors */ 06241 06242 fnf_handle++; 06243 06244 if(fnf_handle == 0) 06245 fnf_handle = 257; 06246 06247 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0, max_data_bytes); 06248 06249 return(-1); 06250 }
static int call_trans2findnotifynext | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize, | |||
char ** | pparams, | |||
int | total_params, | |||
char ** | ppdata, | |||
int | total_data, | |||
unsigned int | max_data_bytes | |||
) | [static] |
参照元 handle_trans2().
06260 { 06261 char *params = *pparams; 06262 06263 DEBUG(3,("call_trans2findnotifynext\n")); 06264 06265 /* Realloc the parameter and data sizes */ 06266 *pparams = (char *)SMB_REALLOC(*pparams,4); 06267 if (*pparams == NULL) { 06268 return ERROR_NT(NT_STATUS_NO_MEMORY); 06269 } 06270 params = *pparams; 06271 06272 SSVAL(params,0,0); /* No changes */ 06273 SSVAL(params,2,0); /* No EA errors */ 06274 06275 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0, max_data_bytes); 06276 06277 return(-1); 06278 }
static int call_trans2getdfsreferral | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize, | |||
char ** | pparams, | |||
int | total_params, | |||
char ** | ppdata, | |||
int | total_data, | |||
unsigned int | max_data_bytes | |||
) | [static] |
参照先 send_trans2_replies()・setup_dfs_referral()・status.
参照元 handle_trans2().
06287 { 06288 char *params = *pparams; 06289 pstring pathname; 06290 int reply_size = 0; 06291 int max_referral_level; 06292 NTSTATUS status = NT_STATUS_OK; 06293 06294 DEBUG(10,("call_trans2getdfsreferral\n")); 06295 06296 if (total_params < 3) { 06297 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 06298 } 06299 06300 max_referral_level = SVAL(params,0); 06301 06302 if(!lp_host_msdfs()) 06303 return ERROR_DOS(ERRDOS,ERRbadfunc); 06304 06305 srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), total_params - 2, STR_TERMINATE); 06306 if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata,&status)) < 0) 06307 return ERROR_NT(status); 06308 06309 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES); 06310 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size, max_data_bytes); 06311 06312 return(-1); 06313 }
static int call_trans2ioctl | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize, | |||
char ** | pparams, | |||
int | total_params, | |||
char ** | ppdata, | |||
int | total_data, | |||
unsigned int | max_data_bytes | |||
) | [static] |
参照先 file_fsp()・global_myname・files_struct::rap_print_jobid・send_trans2_replies().
参照元 handle_trans2().
06325 { 06326 char *pdata = *ppdata; 06327 files_struct *fsp = file_fsp(inbuf,smb_vwv15); 06328 06329 /* check for an invalid fid before proceeding */ 06330 06331 if (!fsp) 06332 return(ERROR_DOS(ERRDOS,ERRbadfid)); 06333 06334 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) && 06335 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) { 06336 *ppdata = (char *)SMB_REALLOC(*ppdata, 32); 06337 if (*ppdata == NULL) { 06338 return ERROR_NT(NT_STATUS_NO_MEMORY); 06339 } 06340 pdata = *ppdata; 06341 06342 /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2 06343 CAN ACCEPT THIS IN UNICODE. JRA. */ 06344 06345 SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */ 06346 srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */ 06347 srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */ 06348 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32, max_data_bytes); 06349 return(-1); 06350 } else { 06351 DEBUG(2,("Unknown TRANS2_IOCTL\n")); 06352 return ERROR_DOS(ERRSRV,ERRerror); 06353 } 06354 }
int reply_findclose | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize | |||
) |
参照先 dptr_close()・set_message().
06362 { 06363 int outsize = 0; 06364 int dptr_num=SVALS(inbuf,smb_vwv0); 06365 START_PROFILE(SMBfindclose); 06366 06367 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num)); 06368 06369 dptr_close(&dptr_num); 06370 06371 outsize = set_message(outbuf,0,0,False); 06372 06373 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num)); 06374 06375 END_PROFILE(SMBfindclose); 06376 return(outsize); 06377 }
int reply_findnclose | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | length, | |||
int | bufsize | |||
) |
参照先 set_message().
06385 { 06386 int outsize = 0; 06387 int dptr_num= -1; 06388 START_PROFILE(SMBfindnclose); 06389 06390 dptr_num = SVAL(inbuf,smb_vwv0); 06391 06392 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num)); 06393 06394 /* We never give out valid handles for a 06395 findnotifyfirst - so any dptr_num is ok here. 06396 Just ignore it. */ 06397 06398 outsize = set_message(outbuf,0,0,False); 06399 06400 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num)); 06401 06402 END_PROFILE(SMBfindnclose); 06403 return(outsize); 06404 }
int handle_trans2 | ( | connection_struct * | conn, | |
struct trans_state * | state, | |||
char * | inbuf, | |||
char * | outbuf, | |||
int | size, | |||
int | bufsize | |||
) |
参照先 trans_state::call・call_trans2findfirst()・call_trans2findnext()・call_trans2findnotifyfirst()・call_trans2findnotifynext()・call_trans2getdfsreferral()・call_trans2ioctl()・call_trans2mkdir()・call_trans2open()・call_trans2qfilepathinfo()・call_trans2qfsinfo()・call_trans2setfilepathinfo()・call_trans2setfsinfo()・trans_state::data・trans_state::max_data_return・trans_state::param・Protocol・PROTOCOL_NT1・trans_state::total_data・trans_state::total_param.
参照元 reply_trans2()・reply_transs2().
06409 { 06410 int outsize; 06411 06412 if (Protocol >= PROTOCOL_NT1) { 06413 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */ 06414 } 06415 06416 /* Now we must call the relevant TRANS2 function */ 06417 switch(state->call) { 06418 case TRANSACT2_OPEN: 06419 { 06420 START_PROFILE(Trans2_open); 06421 outsize = call_trans2open( 06422 conn, inbuf, outbuf, bufsize, 06423 &state->param, state->total_param, 06424 &state->data, state->total_data, 06425 state->max_data_return); 06426 END_PROFILE(Trans2_open); 06427 break; 06428 } 06429 06430 case TRANSACT2_FINDFIRST: 06431 { 06432 START_PROFILE(Trans2_findfirst); 06433 outsize = call_trans2findfirst( 06434 conn, inbuf, outbuf, bufsize, 06435 &state->param, state->total_param, 06436 &state->data, state->total_data, 06437 state->max_data_return); 06438 END_PROFILE(Trans2_findfirst); 06439 break; 06440 } 06441 06442 case TRANSACT2_FINDNEXT: 06443 { 06444 START_PROFILE(Trans2_findnext); 06445 outsize = call_trans2findnext( 06446 conn, inbuf, outbuf, size, bufsize, 06447 &state->param, state->total_param, 06448 &state->data, state->total_data, 06449 state->max_data_return); 06450 END_PROFILE(Trans2_findnext); 06451 break; 06452 } 06453 06454 case TRANSACT2_QFSINFO: 06455 { 06456 START_PROFILE(Trans2_qfsinfo); 06457 outsize = call_trans2qfsinfo( 06458 conn, inbuf, outbuf, size, bufsize, 06459 &state->param, state->total_param, 06460 &state->data, state->total_data, 06461 state->max_data_return); 06462 END_PROFILE(Trans2_qfsinfo); 06463 break; 06464 } 06465 06466 case TRANSACT2_SETFSINFO: 06467 { 06468 START_PROFILE(Trans2_setfsinfo); 06469 outsize = call_trans2setfsinfo( 06470 conn, inbuf, outbuf, size, bufsize, 06471 &state->param, state->total_param, 06472 &state->data, state->total_data, 06473 state->max_data_return); 06474 END_PROFILE(Trans2_setfsinfo); 06475 break; 06476 } 06477 06478 case TRANSACT2_QPATHINFO: 06479 case TRANSACT2_QFILEINFO: 06480 { 06481 START_PROFILE(Trans2_qpathinfo); 06482 outsize = call_trans2qfilepathinfo( 06483 conn, inbuf, outbuf, size, bufsize, state->call, 06484 &state->param, state->total_param, 06485 &state->data, state->total_data, 06486 state->max_data_return); 06487 END_PROFILE(Trans2_qpathinfo); 06488 break; 06489 } 06490 06491 case TRANSACT2_SETPATHINFO: 06492 case TRANSACT2_SETFILEINFO: 06493 { 06494 START_PROFILE(Trans2_setpathinfo); 06495 outsize = call_trans2setfilepathinfo( 06496 conn, inbuf, outbuf, size, bufsize, state->call, 06497 &state->param, state->total_param, 06498 &state->data, state->total_data, 06499 state->max_data_return); 06500 END_PROFILE(Trans2_setpathinfo); 06501 break; 06502 } 06503 06504 case TRANSACT2_FINDNOTIFYFIRST: 06505 { 06506 START_PROFILE(Trans2_findnotifyfirst); 06507 outsize = call_trans2findnotifyfirst( 06508 conn, inbuf, outbuf, size, bufsize, 06509 &state->param, state->total_param, 06510 &state->data, state->total_data, 06511 state->max_data_return); 06512 END_PROFILE(Trans2_findnotifyfirst); 06513 break; 06514 } 06515 06516 case TRANSACT2_FINDNOTIFYNEXT: 06517 { 06518 START_PROFILE(Trans2_findnotifynext); 06519 outsize = call_trans2findnotifynext( 06520 conn, inbuf, outbuf, size, bufsize, 06521 &state->param, state->total_param, 06522 &state->data, state->total_data, 06523 state->max_data_return); 06524 END_PROFILE(Trans2_findnotifynext); 06525 break; 06526 } 06527 06528 case TRANSACT2_MKDIR: 06529 { 06530 START_PROFILE(Trans2_mkdir); 06531 outsize = call_trans2mkdir( 06532 conn, inbuf, outbuf, size, bufsize, 06533 &state->param, state->total_param, 06534 &state->data, state->total_data, 06535 state->max_data_return); 06536 END_PROFILE(Trans2_mkdir); 06537 break; 06538 } 06539 06540 case TRANSACT2_GET_DFS_REFERRAL: 06541 { 06542 START_PROFILE(Trans2_get_dfs_referral); 06543 outsize = call_trans2getdfsreferral( 06544 conn, inbuf, outbuf, size, bufsize, 06545 &state->param, state->total_param, 06546 &state->data, state->total_data, 06547 state->max_data_return); 06548 END_PROFILE(Trans2_get_dfs_referral); 06549 break; 06550 } 06551 06552 case TRANSACT2_IOCTL: 06553 { 06554 START_PROFILE(Trans2_ioctl); 06555 outsize = call_trans2ioctl( 06556 conn, inbuf, outbuf, size, bufsize, 06557 &state->param, state->total_param, 06558 &state->data, state->total_data, 06559 state->max_data_return); 06560 END_PROFILE(Trans2_ioctl); 06561 break; 06562 } 06563 06564 default: 06565 /* Error in request */ 06566 DEBUG(2,("Unknown request %d in trans2 call\n", state->call)); 06567 outsize = ERROR_DOS(ERRSRV,ERRerror); 06568 } 06569 06570 return outsize; 06571 }
int reply_trans2 | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | size, | |||
int | bufsize | |||
) |
参照先 allow_new_trans()・trans_state::call・trans_state::close_on_completion・trans_state::cmd・trans_state::data・handle_trans2()・trans_state::max_data_return・trans_state::max_param_return・trans_state::max_setup_return・connection_struct::mem_ctx・trans_state::mid・nt_errstr()・trans_state::one_way・trans_state::param・connection_struct::pending_trans・trans_state::received_data・trans_state::received_param・result・set_message()・trans_state::setup・trans_state::setup_count・show_msg()・trans_state::total_data・trans_state::total_param・trans_state::vuid.
06579 { 06580 int outsize = 0; 06581 unsigned int dsoff = SVAL(inbuf, smb_dsoff); 06582 unsigned int dscnt = SVAL(inbuf, smb_dscnt); 06583 unsigned int psoff = SVAL(inbuf, smb_psoff); 06584 unsigned int pscnt = SVAL(inbuf, smb_pscnt); 06585 unsigned int tran_call = SVAL(inbuf, smb_setup0); 06586 unsigned int av_size = size-4; 06587 struct trans_state *state; 06588 NTSTATUS result; 06589 06590 START_PROFILE(SMBtrans2); 06591 06592 result = allow_new_trans(conn->pending_trans, SVAL(inbuf, smb_mid)); 06593 if (!NT_STATUS_IS_OK(result)) { 06594 DEBUG(2, ("Got invalid trans2 request: %s\n", 06595 nt_errstr(result))); 06596 END_PROFILE(SMBtrans2); 06597 return ERROR_NT(result); 06598 } 06599 06600 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN) 06601 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) { 06602 END_PROFILE(SMBtrans2); 06603 return ERROR_DOS(ERRSRV,ERRaccess); 06604 } 06605 06606 if ((state = TALLOC_P(conn->mem_ctx, struct trans_state)) == NULL) { 06607 DEBUG(0, ("talloc failed\n")); 06608 END_PROFILE(SMBtrans2); 06609 return ERROR_NT(NT_STATUS_NO_MEMORY); 06610 } 06611 06612 state->cmd = SMBtrans2; 06613 06614 state->mid = SVAL(inbuf, smb_mid); 06615 state->vuid = SVAL(inbuf, smb_uid); 06616 state->setup_count = SVAL(inbuf, smb_suwcnt); 06617 state->setup = NULL; 06618 state->total_param = SVAL(inbuf, smb_tpscnt); 06619 state->param = NULL; 06620 state->total_data = SVAL(inbuf, smb_tdscnt); 06621 state->data = NULL; 06622 state->max_param_return = SVAL(inbuf, smb_mprcnt); 06623 state->max_data_return = SVAL(inbuf, smb_mdrcnt); 06624 state->max_setup_return = SVAL(inbuf, smb_msrcnt); 06625 state->close_on_completion = BITSETW(inbuf+smb_vwv5,0); 06626 state->one_way = BITSETW(inbuf+smb_vwv5,1); 06627 06628 state->call = tran_call; 06629 06630 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this 06631 is so as a sanity check */ 06632 if (state->setup_count != 1) { 06633 /* 06634 * Need to have rc=0 for ioctl to get job id for OS/2. 06635 * Network printing will fail if function is not successful. 06636 * Similar function in reply.c will be used if protocol 06637 * is LANMAN1.0 instead of LM1.2X002. 06638 * Until DosPrintSetJobInfo with PRJINFO3 is supported, 06639 * outbuf doesn't have to be set(only job id is used). 06640 */ 06641 if ( (state->setup_count == 4) && (tran_call == TRANSACT2_IOCTL) && 06642 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) && 06643 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) { 06644 DEBUG(2,("Got Trans2 DevIOctl jobid\n")); 06645 } else { 06646 DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count)); 06647 DEBUG(2,("Transaction is %d\n",tran_call)); 06648 TALLOC_FREE(state); 06649 END_PROFILE(SMBtrans2); 06650 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 06651 } 06652 } 06653 06654 if ((dscnt > state->total_data) || (pscnt > state->total_param)) 06655 goto bad_param; 06656 06657 if (state->total_data) { 06658 /* Can't use talloc here, the core routines do realloc on the 06659 * params and data. */ 06660 state->data = (char *)SMB_MALLOC(state->total_data); 06661 if (state->data == NULL) { 06662 DEBUG(0,("reply_trans2: data malloc fail for %u " 06663 "bytes !\n", (unsigned int)state->total_data)); 06664 TALLOC_FREE(state); 06665 END_PROFILE(SMBtrans2); 06666 return(ERROR_DOS(ERRDOS,ERRnomem)); 06667 } 06668 06669 if (dscnt > state->total_data || 06670 dsoff+dscnt < dsoff) { 06671 goto bad_param; 06672 } 06673 06674 if (dsoff > av_size || 06675 dscnt > av_size || 06676 dsoff+dscnt > av_size) { 06677 goto bad_param; 06678 } 06679 06680 memcpy(state->data,smb_base(inbuf)+dsoff,dscnt); 06681 } 06682 06683 if (state->total_param) { 06684 /* Can't use talloc here, the core routines do realloc on the 06685 * params and data. */ 06686 state->param = (char *)SMB_MALLOC(state->total_param); 06687 if (state->param == NULL) { 06688 DEBUG(0,("reply_trans: param malloc fail for %u " 06689 "bytes !\n", (unsigned int)state->total_param)); 06690 SAFE_FREE(state->data); 06691 TALLOC_FREE(state); 06692 END_PROFILE(SMBtrans2); 06693 return(ERROR_DOS(ERRDOS,ERRnomem)); 06694 } 06695 06696 if (pscnt > state->total_param || 06697 psoff+pscnt < psoff) { 06698 goto bad_param; 06699 } 06700 06701 if (psoff > av_size || 06702 pscnt > av_size || 06703 psoff+pscnt > av_size) { 06704 goto bad_param; 06705 } 06706 06707 memcpy(state->param,smb_base(inbuf)+psoff,pscnt); 06708 } 06709 06710 state->received_data = dscnt; 06711 state->received_param = pscnt; 06712 06713 if ((state->received_param == state->total_param) && 06714 (state->received_data == state->total_data)) { 06715 06716 outsize = handle_trans2(conn, state, inbuf, outbuf, 06717 size, bufsize); 06718 SAFE_FREE(state->data); 06719 SAFE_FREE(state->param); 06720 TALLOC_FREE(state); 06721 END_PROFILE(SMBtrans2); 06722 return outsize; 06723 } 06724 06725 DLIST_ADD(conn->pending_trans, state); 06726 06727 /* We need to send an interim response then receive the rest 06728 of the parameter/data bytes */ 06729 outsize = set_message(outbuf,0,0,False); 06730 show_msg(outbuf); 06731 END_PROFILE(SMBtrans2); 06732 return outsize; 06733 06734 bad_param: 06735 06736 DEBUG(0,("reply_trans2: invalid trans parameters\n")); 06737 SAFE_FREE(state->data); 06738 SAFE_FREE(state->param); 06739 TALLOC_FREE(state); 06740 END_PROFILE(SMBtrans2); 06741 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 06742 }
int reply_transs2 | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | size, | |||
int | bufsize | |||
) |
参照先 trans_state::cmd・trans_state::data・handle_trans2()・trans_state::mid・trans_state::next・trans_state::param・connection_struct::pending_trans・trans_state::received_data・trans_state::received_param・show_msg()・trans_state::total_data・trans_state::total_param.
06751 { 06752 int outsize = 0; 06753 unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp; 06754 unsigned int av_size = size-4; 06755 struct trans_state *state; 06756 06757 START_PROFILE(SMBtranss2); 06758 06759 show_msg(inbuf); 06760 06761 for (state = conn->pending_trans; state != NULL; 06762 state = state->next) { 06763 if (state->mid == SVAL(inbuf,smb_mid)) { 06764 break; 06765 } 06766 } 06767 06768 if ((state == NULL) || (state->cmd != SMBtrans2)) { 06769 END_PROFILE(SMBtranss2); 06770 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 06771 } 06772 06773 /* Revise state->total_param and state->total_data in case they have 06774 changed downwards */ 06775 06776 if (SVAL(inbuf, smb_tpscnt) < state->total_param) 06777 state->total_param = SVAL(inbuf, smb_tpscnt); 06778 if (SVAL(inbuf, smb_tdscnt) < state->total_data) 06779 state->total_data = SVAL(inbuf, smb_tdscnt); 06780 06781 pcnt = SVAL(inbuf, smb_spscnt); 06782 poff = SVAL(inbuf, smb_spsoff); 06783 pdisp = SVAL(inbuf, smb_spsdisp); 06784 06785 dcnt = SVAL(inbuf, smb_sdscnt); 06786 doff = SVAL(inbuf, smb_sdsoff); 06787 ddisp = SVAL(inbuf, smb_sdsdisp); 06788 06789 state->received_param += pcnt; 06790 state->received_data += dcnt; 06791 06792 if ((state->received_data > state->total_data) || 06793 (state->received_param > state->total_param)) 06794 goto bad_param; 06795 06796 if (pcnt) { 06797 if (pdisp > state->total_param || 06798 pcnt > state->total_param || 06799 pdisp+pcnt > state->total_param || 06800 pdisp+pcnt < pdisp) { 06801 goto bad_param; 06802 } 06803 06804 if (poff > av_size || 06805 pcnt > av_size || 06806 poff+pcnt > av_size || 06807 poff+pcnt < poff) { 06808 goto bad_param; 06809 } 06810 06811 memcpy(state->param+pdisp,smb_base(inbuf)+poff, 06812 pcnt); 06813 } 06814 06815 if (dcnt) { 06816 if (ddisp > state->total_data || 06817 dcnt > state->total_data || 06818 ddisp+dcnt > state->total_data || 06819 ddisp+dcnt < ddisp) { 06820 goto bad_param; 06821 } 06822 06823 if (doff > av_size || 06824 dcnt > av_size || 06825 doff+dcnt > av_size || 06826 doff+dcnt < doff) { 06827 goto bad_param; 06828 } 06829 06830 memcpy(state->data+ddisp, smb_base(inbuf)+doff, 06831 dcnt); 06832 } 06833 06834 if ((state->received_param < state->total_param) || 06835 (state->received_data < state->total_data)) { 06836 END_PROFILE(SMBtranss2); 06837 return -1; 06838 } 06839 06840 /* construct_reply_common has done us the favor to pre-fill the 06841 * command field with SMBtranss2 which is wrong :-) 06842 */ 06843 SCVAL(outbuf,smb_com,SMBtrans2); 06844 06845 outsize = handle_trans2(conn, state, inbuf, outbuf, size, bufsize); 06846 06847 DLIST_REMOVE(conn->pending_trans, state); 06848 SAFE_FREE(state->data); 06849 SAFE_FREE(state->param); 06850 TALLOC_FREE(state); 06851 06852 if (outsize == 0) { 06853 END_PROFILE(SMBtranss2); 06854 return(ERROR_DOS(ERRSRV,ERRnosupport)); 06855 } 06856 06857 END_PROFILE(SMBtranss2); 06858 return(outsize); 06859 06860 bad_param: 06861 06862 DEBUG(0,("reply_transs2: invalid trans parameters\n")); 06863 DLIST_REMOVE(conn->pending_trans, state); 06864 SAFE_FREE(state->data); 06865 SAFE_FREE(state->param); 06866 TALLOC_FREE(state); 06867 END_PROFILE(SMBtranss2); 06868 return ERROR_NT(NT_STATUS_INVALID_PARAMETER); 06869 }
enum protocol_types Protocol |
int smb_read_error |
uint32 global_client_caps |
sesssetup.c の 32 行で定義されています。
struct current_user current_user |
const char* prohibited_ea_names[] [static] |
初期値:
{ SAMBA_POSIX_INHERITANCE_EA_NAME, SAMBA_XATTR_DOS_ATTRIB, NULL }
unsigned stat_fflag |
unsigned smb_fflag |
struct { ... }
info2_flags_map[] [static] |