files_struct *fsp,
const SMB_STRUCT_STAT *psbuf);
+static uint32_t generate_volume_serial_number(
+ const struct loadparm_substitution *lp_sub,
+ int snum);
+
/****************************************************************************
Check if an open file handle is a symlink.
****************************************************************************/
status = SMB_VFS_CREATE_FILE(
conn, /* conn */
req, /* req */
+ NULL, /* dirfsp */
smb_fname, /* fname */
access_mask, /* access_mask */
share_access, /* share_access */
SMB_STRUCT_STAT st;
NTSTATUS status = NT_STATUS_OK;
uint64_t df_ret;
+ uint32_t serial;
if (fname == NULL || fname->base_name == NULL) {
filename = ".";
* Add volume serial number - hash of a combination of
* the called hostname and the service name.
*/
- SIVAL(pdata,0,str_checksum(lp_servicename(talloc_tos(), lp_sub, snum)) ^ (str_checksum(get_local_machine_name())<<16) );
+ serial = generate_volume_serial_number(lp_sub, snum);
+ SIVAL(pdata,0,serial);
/*
* Win2k3 and previous mess this up by sending a name length
* one byte short. I believe only older clients (OS/2 Win9x) use
}
SCVAL(pdata,l2_vol_cch,len);
data_len = l2_vol_szVolLabel + len;
- DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %u, name = %s\n",
+ DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %u, "
+ "name = %s serial = 0x%04"PRIx32"\n",
(unsigned)convert_timespec_to_time_t(st.st_ex_ctime),
- (unsigned)len, vname));
+ (unsigned)len, vname, serial));
break;
case SMB_QUERY_FS_ATTRIBUTE_INFO:
case SMB_QUERY_FS_VOLUME_INFO:
case SMB_FS_VOLUME_INFORMATION:
-
+ put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER,
+ pdata, &st.st_ex_btime);
/*
* Add volume serial number - hash of a combination of
* the called hostname and the service name.
*/
- SIVAL(pdata,8,str_checksum(lp_servicename(talloc_tos(), lp_sub, snum)) ^
- (str_checksum(get_local_machine_name())<<16));
+ serial = generate_volume_serial_number(lp_sub, snum);
+ SIVAL(pdata,8,serial);
/* Max label len is 32 characters. */
status = srvstr_push(pdata, flags2, pdata+18, vname,
SIVAL(pdata,12,len);
data_len = 18+len;
- DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
- (int)strlen(vname),vname,
- lp_servicename(talloc_tos(), lp_sub, snum)));
+ DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO "
+ "namelen = %d, vol=%s serv=%s "
+ "serial=0x%04"PRIx32"\n",
+ (int)strlen(vname),vname,
+ lp_servicename(talloc_tos(), lp_sub, snum),
+ serial));
if (max_data_bytes >= 24 && data_len > max_data_bytes) {
/* the client only requested a portion of the
volume label */
case SMB_QUERY_POSIX_FS_INFO:
{
int rc;
- vfs_statvfs_struct svfs;
+ struct vfs_statvfs_struct svfs;
if (!lp_smb1_unix_extensions()) {
return NT_STATUS_INVALID_LEVEL;
status = unlink_internals(conn,
req,
FILE_ATTRIBUTE_NORMAL,
+ NULL, /* new_dirfsp */
smb_fname_new);
if (!NT_STATUS_IS_OK(status)) {
goto out;
status = SMB_VFS_CREATE_FILE(
conn, /* conn */
req, /* req */
+ NULL, /* dirfsp */
smb_fname, /* fname */
FILE_WRITE_DATA, /* access_mask */
(FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
DEBUG(10,("smb2_file_rename_information: got name |%s|\n",
newname));
- status = filename_convert(ctx,
- conn,
- newname,
- ucf_flags,
- 0,
- &smb_fname_dst);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- if (fsp->base_fsp) {
- /* newname must be a stream name. */
- if (newname[0] != ':') {
- return NT_STATUS_NOT_SUPPORTED;
- }
-
+ if (newname[0] == ':') {
/* Create an smb_fname to call rename_internals_fsp() with. */
smb_fname_dst = synthetic_smb_fname(talloc_tos(),
fsp->base_fsp->fsp_name->base_name,
status = NT_STATUS_NO_MEMORY;
goto out;
}
+ } else {
+ status = filename_convert(ctx,
+ conn,
+ newname,
+ ucf_flags,
+ 0,
+ &smb_fname_dst);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
}
/*
return NT_STATUS_INVALID_PARAMETER;
}
- overwrite = (CVAL(pdata,0) ? True : False);
+ overwrite = (CVAL(pdata,0) != 0);
root_fid = IVAL(pdata,4);
len = IVAL(pdata,8);
status = rename_internals(ctx,
conn,
req,
+ NULL, /* src_dirfsp */
smb_fname_src,
+ NULL, /* dst_dirfsp */
smb_fname_dst,
dst_original_lcomp,
0,
status = SMB_VFS_CREATE_FILE(
conn, /* conn */
req, /* req */
+ NULL, /* dirfsp */
smb_fname, /* fname */
FILE_WRITE_DATA, /* access_mask */
(FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
status = SMB_VFS_CREATE_FILE(
conn, /* conn */
req, /* req */
+ NULL, /* dirfsp */
smb_fname, /* fname */
FILE_READ_ATTRIBUTES, /* access_mask */
FILE_SHARE_NONE, /* share_access */
status = SMB_VFS_CREATE_FILE(
conn, /* conn */
req, /* req */
+ NULL, /* dirfsp */
smb_fname, /* fname */
access_mask, /* access_mask */
(FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
status = SMB_VFS_CREATE_FILE(
conn, /* conn */
req, /* req */
+ NULL, /* dirfsp */
smb_fname, /* fname */
DELETE_ACCESS, /* access_mask */
(FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
*ret_data_size = data_return_size;
return NT_STATUS_OK;
}
+
+static uint32_t generate_volume_serial_number(
+ const struct loadparm_substitution *lp_sub,
+ int snum)
+{
+ int serial = lp_volume_serial_number(snum);
+ return serial != -1 ? serial:
+ str_checksum(lp_servicename(talloc_tos(), lp_sub, snum)) ^
+ (str_checksum(get_local_machine_name())<<16);
+}