summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/close.c2
-rw-r--r--source3/smbd/dir.c12
-rw-r--r--source3/smbd/dosmode.c69
-rw-r--r--source3/smbd/file_access.c14
-rw-r--r--source3/smbd/fileio.c2
-rw-r--r--source3/smbd/filename.c2
-rw-r--r--source3/smbd/globals.c1
-rw-r--r--source3/smbd/globals.h20
-rw-r--r--source3/smbd/msdfs.c2
-rw-r--r--source3/smbd/nttrans.c28
-rw-r--r--source3/smbd/open.c56
-rw-r--r--source3/smbd/posix_acls.c58
-rw-r--r--source3/smbd/process.c18
-rw-r--r--source3/smbd/reply.c71
-rw-r--r--source3/smbd/server.c19
-rw-r--r--source3/smbd/service.c4
-rw-r--r--source3/smbd/signing.c26
-rw-r--r--source3/smbd/smb2_negprot.c23
-rw-r--r--source3/smbd/smb2_server.c116
-rw-r--r--source3/smbd/smb2_sesssetup.c70
-rw-r--r--source3/smbd/smb2_signing.c135
-rw-r--r--source3/smbd/trans2.c165
-rw-r--r--source3/smbd/vfs.c28
23 files changed, 588 insertions, 353 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index d23b509af2..9aab3a7405 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -103,7 +103,7 @@ static void check_magic(struct files_struct *fsp)
return;
}
- transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_size);
+ transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_ex_size);
close(tmp_fd);
close(outfd);
TALLOC_FREE(ctx);
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index ab4a0d27e3..f5a9e22d14 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -824,7 +824,7 @@ bool get_dir_entry(TALLOC_CTX *ctx,
char **pp_fname_out,
SMB_OFF_T *size,
uint32 *mode,
- time_t *date,
+ struct timespec *date,
bool check_descend,
bool ask_sharemode)
{
@@ -910,8 +910,8 @@ bool get_dir_entry(TALLOC_CTX *ctx,
continue;
}
- *size = sbuf.st_size;
- *date = sbuf.st_mtime;
+ *size = sbuf.st_ex_size;
+ *date = sbuf.st_ex_mtime;
if (ask_sharemode) {
struct timespec write_time_ts;
@@ -920,7 +920,7 @@ bool get_dir_entry(TALLOC_CTX *ctx,
fileid = vfs_file_id_from_sbuf(conn, &sbuf);
get_file_infos(fileid, NULL, &write_time_ts);
if (!null_timespec(write_time_ts)) {
- *date = convert_timespec_to_time_t(write_time_ts);
+ *date = write_time_ts;
}
}
@@ -989,7 +989,7 @@ static bool user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_
/* Pseudo-open the file */
- if(S_ISDIR(pst->st_mode)) {
+ if(S_ISDIR(pst->st_ex_mode)) {
return True;
}
@@ -1012,7 +1012,7 @@ static bool file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT
SMB_ASSERT(VALID_STAT(*pst));
- if (S_ISREG(pst->st_mode) || S_ISDIR(pst->st_mode) || S_ISLNK(pst->st_mode))
+ if (S_ISREG(pst->st_ex_mode) || S_ISDIR(pst->st_ex_mode) || S_ISLNK(pst->st_ex_mode))
return False;
return True;
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 5ae7151303..6468544748 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -3,17 +3,17 @@
dos mode handling functions
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) James Peach 2006
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -23,7 +23,7 @@
static int set_sparse_flag(const SMB_STRUCT_STAT * const sbuf)
{
#if defined (HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
- if (sbuf->st_size > sbuf->st_blocks * (SMB_OFF_T)STAT_ST_BLOCKSIZE) {
+ if (sbuf->st_ex_size > sbuf->st_ex_blocks * (SMB_OFF_T)STAT_ST_BLOCKSIZE) {
return FILE_ATTRIBUTE_SPARSE;
}
#endif
@@ -88,7 +88,7 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname,
}
/* Save for later - but explicitly remove setuid bit for safety. */
- dir_mode = sbuf.st_mode & ~S_ISUID;
+ dir_mode = sbuf.st_ex_mode & ~S_ISUID;
DEBUG(2,("unix_mode(%s) inherit mode %o\n",fname,(int)dir_mode));
/* Clear "result" */
result = 0;
@@ -117,7 +117,7 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname,
if (lp_map_system(SNUM(conn)) && IS_DOS_SYSTEM(dosmode))
result |= S_IXGRP;
-
+
if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode))
result |= S_IXOTH;
@@ -147,7 +147,7 @@ static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_
if (ro_opts == MAP_READONLY_YES) {
/* Original Samba method - map inverse of user "w" bit. */
- if ((sbuf->st_mode & S_IWUSR) == 0) {
+ if ((sbuf->st_ex_mode & S_IWUSR) == 0) {
result |= aRONLY;
}
} else if (ro_opts == MAP_READONLY_PERMISSIONS) {
@@ -157,16 +157,16 @@ static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_
}
} /* Else never set the readonly bit. */
- if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0))
+ if (MAP_ARCHIVE(conn) && ((sbuf->st_ex_mode & S_IXUSR) != 0))
result |= aARCH;
- if (MAP_SYSTEM(conn) && ((sbuf->st_mode & S_IXGRP) != 0))
+ if (MAP_SYSTEM(conn) && ((sbuf->st_ex_mode & S_IXGRP) != 0))
result |= aSYSTEM;
-
- if (MAP_HIDDEN(conn) && ((sbuf->st_mode & S_IXOTH) != 0))
+
+ if (MAP_HIDDEN(conn) && ((sbuf->st_ex_mode & S_IXOTH) != 0))
result |= aHIDDEN;
-
- if (S_ISDIR(sbuf->st_mode))
+
+ if (S_ISDIR(sbuf->st_ex_mode))
result = aDIR | (result & aRONLY);
result |= set_sparse_flag(sbuf);
@@ -179,7 +179,7 @@ static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_
if (result & aSYSTEM) DEBUG(8, ("s"));
if (result & aDIR ) DEBUG(8, ("d"));
if (result & aARCH ) DEBUG(8, ("a"));
-
+
DEBUG(8,("\n"));
return result;
}
@@ -225,7 +225,7 @@ static bool get_ea_dos_attribute(connection_struct *conn, const char *path,SMB_S
return False;
}
- if (S_ISDIR(sbuf->st_mode)) {
+ if (S_ISDIR(sbuf->st_ex_mode)) {
dosattr |= aDIR;
}
*pattr = (uint32)(dosattr & SAMBA_ATTRIBUTES_MASK);
@@ -237,7 +237,7 @@ static bool get_ea_dos_attribute(connection_struct *conn, const char *path,SMB_S
if (dosattr & aSYSTEM) DEBUG(8, ("s"));
if (dosattr & aDIR ) DEBUG(8, ("d"));
if (dosattr & aARCH ) DEBUG(8, ("a"));
-
+
DEBUG(8,("\n"));
return True;
@@ -332,7 +332,7 @@ uint32 dos_mode_msdfs(connection_struct *conn, const char *path,SMB_STRUCT_STAT
result |= aHIDDEN;
}
}
-
+
result |= dos_mode_from_sbuf(conn, path, sbuf);
/* Optimization : Only call is_hidden_path if it's not already
@@ -349,7 +349,7 @@ uint32 dos_mode_msdfs(connection_struct *conn, const char *path,SMB_STRUCT_STAT
if (result & aDIR ) DEBUG(8, ("d"));
if (result & aARCH ) DEBUG(8, ("a"));
if (result & FILE_ATTRIBUTE_SPARSE ) DEBUG(8, ("[sparse]"));
-
+
DEBUG(8,("\n"));
return(result);
@@ -406,7 +406,7 @@ static bool get_stat_dos_flags(connection_struct *conn,
*dosmode |= aSYSTEM;
if (sbuf->st_flags & UF_DOS_NOINDEX)
*dosmode |= FILE_ATTRIBUTE_NONINDEXED;
- if (S_ISDIR(sbuf->st_mode))
+ if (S_ISDIR(sbuf->st_ex_mode))
*dosmode |= aDIR;
*dosmode |= set_sparse_flag(sbuf);
@@ -493,7 +493,7 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
result |= aHIDDEN;
}
}
-
+
#ifdef HAVE_STAT_DOS_FLAGS
used_stat_dos_flags = get_stat_dos_flags(conn, path, sbuf, &result);
#endif
@@ -506,9 +506,8 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
}
}
-
offline = SMB_VFS_IS_OFFLINE(conn, path, sbuf);
- if (S_ISREG(sbuf->st_mode) && offline) {
+ if (S_ISREG(sbuf->st_ex_mode) && offline) {
result |= FILE_ATTRIBUTE_OFFLINE;
}
@@ -526,7 +525,7 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
if (result & aDIR ) DEBUG(8, ("d"));
if (result & aARCH ) DEBUG(8, ("a"));
if (result & FILE_ATTRIBUTE_SPARSE ) DEBUG(8, ("[sparse]"));
-
+
DEBUG(8,("\n"));
return(result);
@@ -563,17 +562,17 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
return(-1);
}
- unixmode = st->st_mode;
+ unixmode = st->st_ex_mode;
- get_acl_group_bits(conn, fname, &st->st_mode);
+ get_acl_group_bits(conn, fname, &st->st_ex_mode);
- if (S_ISDIR(st->st_mode))
+ if (S_ISDIR(st->st_ex_mode))
dosmode |= aDIR;
else
dosmode &= ~aDIR;
old_mode = dos_mode(conn,fname,st);
-
+
if (dosmode & FILE_ATTRIBUTE_OFFLINE) {
if (!(old_mode & FILE_ATTRIBUTE_OFFLINE)) {
lret = SMB_VFS_SET_OFFLINE(conn, fname);
@@ -590,7 +589,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
old_mode &= ~FILE_ATTRIBUTE_OFFLINE;
if (old_mode == dosmode) {
- st->st_mode = unixmode;
+ st->st_ex_mode = unixmode;
return(0);
}
@@ -605,7 +604,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
}
- st->st_mode = unixmode;
+ st->st_ex_mode = unixmode;
return 0;
}
}
@@ -617,7 +616,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
}
- st->st_mode = unixmode;
+ st->st_ex_mode = unixmode;
return 0;
}
@@ -639,10 +638,10 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
if (!MAP_HIDDEN(conn))
mask |= S_IXOTH;
- unixmode |= (st->st_mode & mask);
+ unixmode |= (st->st_ex_mode & mask);
/* if we previously had any r bits set then leave them alone */
- if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
+ if ((tmp = st->st_ex_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
unixmode |= tmp;
}
@@ -650,7 +649,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
/* if we previously had any w bits set then leave them alone
whilst adding in the new w bits, if the new mode is not rdonly */
if (!IS_DOS_READONLY(dosmode)) {
- unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
+ unixmode |= (st->st_ex_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
}
ret = SMB_VFS_CHMOD(conn, fname, unixmode);
@@ -659,7 +658,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
}
- st->st_mode = unixmode;
+ st->st_ex_mode = unixmode;
return 0;
}
@@ -696,7 +695,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
}
if (ret == 0) {
- st->st_mode = unixmode;
+ st->st_ex_mode = unixmode;
}
}
diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c
index abffcd2f4f..a248dd9f3b 100644
--- a/source3/smbd/file_access.c
+++ b/source3/smbd/file_access.c
@@ -80,7 +80,7 @@ bool can_delete_file_in_directory(connection_struct *conn, const char *fname)
/* fast paths first */
- if (!S_ISDIR(sbuf.st_mode)) {
+ if (!S_ISDIR(sbuf.st_ex_mode)) {
return False;
}
if (conn->server_info->utok.uid == 0 || conn->admin_user) {
@@ -90,7 +90,7 @@ bool can_delete_file_in_directory(connection_struct *conn, const char *fname)
#ifdef S_ISVTX
/* sticky bit means delete only by owner or root. */
- if (sbuf.st_mode & S_ISVTX) {
+ if (sbuf.st_ex_mode & S_ISVTX) {
SMB_STRUCT_STAT sbuf_file;
if(SMB_VFS_STAT(conn, fname, &sbuf_file) != 0) {
if (errno == ENOENT) {
@@ -105,7 +105,7 @@ bool can_delete_file_in_directory(connection_struct *conn, const char *fname)
* for bug #3348. Don't assume owning sticky bit
* directory means write access allowed.
*/
- if (conn->server_info->utok.uid != sbuf_file.st_uid) {
+ if (conn->server_info->utok.uid != sbuf_file.st_ex_uid) {
return False;
}
}
@@ -156,17 +156,17 @@ bool can_access_file_data(connection_struct *conn, const char *fname, SMB_STRUCT
}
/* Check primary owner access. */
- if (conn->server_info->utok.uid == psbuf->st_uid) {
+ if (conn->server_info->utok.uid == psbuf->st_ex_uid) {
switch (access_mask) {
case FILE_READ_DATA:
- return (psbuf->st_mode & S_IRUSR) ? True : False;
+ return (psbuf->st_ex_mode & S_IRUSR) ? True : False;
case FILE_WRITE_DATA:
- return (psbuf->st_mode & S_IWUSR) ? True : False;
+ return (psbuf->st_ex_mode & S_IWUSR) ? True : False;
default: /* FILE_READ_DATA|FILE_WRITE_DATA */
- if ((psbuf->st_mode & (S_IWUSR|S_IRUSR)) == (S_IWUSR|S_IRUSR)) {
+ if ((psbuf->st_ex_mode & (S_IWUSR|S_IRUSR)) == (S_IWUSR|S_IRUSR)) {
return True;
} else {
return False;
diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
index adf664b396..de5f83c868 100644
--- a/source3/smbd/fileio.c
+++ b/source3/smbd/fileio.c
@@ -296,7 +296,7 @@ ssize_t write_file(struct smb_request *req,
*/
if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !wcp) {
- setup_write_cache(fsp, st.st_size);
+ setup_write_cache(fsp, st.st_ex_size);
wcp = fsp->wcp;
}
}
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 36503483a8..72b4ab7aa6 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -424,7 +424,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
* It exists. it must either be a directory or this must
* be the last part of the path for it to be OK.
*/
- if (end && !(st.st_mode & S_IFDIR)) {
+ if (end && !S_ISDIR(st.st_ex_mode)) {
/*
* An intermediate part of the name isn't
* a directory.
diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c
index 9e7d103562..3dc057e18d 100644
--- a/source3/smbd/globals.c
+++ b/source3/smbd/globals.c
@@ -127,7 +127,6 @@ int max_send = BUFFER_SIZE;
int max_recv = BUFFER_SIZE;
uint16 last_session_tag = UID_FIELD_INVALID;
int trans_num = 0;
-char *orig_inbuf = NULL;
pid_t mypid = 0;
time_t last_smb_conf_reload_time = 0;
time_t last_printer_reload_time = 0;
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 9d5eead939..2f9f7afd65 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -125,7 +125,6 @@ extern int max_send;
extern int max_recv;
extern uint16 last_session_tag;
extern int trans_num;
-extern char *orig_inbuf;
extern pid_t mypid;
extern time_t last_smb_conf_reload_time;
@@ -206,6 +205,13 @@ struct smbd_smb2_tcon;
DATA_BLOB negprot_spnego(void);
+NTSTATUS smb2_signing_sign_pdu(DATA_BLOB session_key,
+ struct iovec *vector,
+ int count);
+NTSTATUS smb2_signing_check_pdu(DATA_BLOB session_key,
+ const struct iovec *vector,
+ int count);
+
bool smbd_is_smb2_header(const uint8_t *inbuf, size_t size);
void reply_smb2002(struct smb_request *req, uint16_t choice);
@@ -244,6 +250,7 @@ struct smbd_smb2_request {
struct smbd_smb2_tcon *tcon;
int current_idx;
+ bool do_signing;
struct {
/* the NBT header is not allocated */
@@ -299,6 +306,9 @@ struct smbd_smb2_session {
NTSTATUS status;
uint64_t vuid;
AUTH_NTLMSSP_STATE *auth_ntlmssp_state;
+ struct auth_serversupplied_info *server_info;
+ DATA_BLOB session_key;
+ bool do_signing;
struct {
/* an id tree used to allocate tids */
@@ -319,11 +329,13 @@ struct smbd_smb2_tcon {
};
struct smbd_server_connection {
- struct fd_event *fde;
- uint64_t num_requests;
- struct smb_signing_state *signing_state;
bool allow_smb2;
struct {
+ struct fd_event *fde;
+ uint64_t num_requests;
+ struct smb_signing_state *signing_state;
+ } smb1;
+ struct {
struct tevent_context *event_ctx;
struct tevent_queue *recv_queue;
struct tevent_queue *send_queue;
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 7f99a186aa..e2f31f077c 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -443,7 +443,7 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx,
goto err;
}
- if (!S_ISLNK(sbufp->st_mode)) {
+ if (!S_ISLNK(sbufp->st_ex_mode)) {
DEBUG(5,("is_msdfs_link_read_target: %s is not a link.\n",
path));
goto err;
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 204cdf9e31..d6be35d29b 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -570,7 +570,7 @@ void reply_ntcreate_and_X(struct smb_request *req)
oplock_granted = NO_OPLOCK_RETURN;
}
- file_len = sbuf.st_size;
+ file_len = sbuf.st_ex_size;
fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
if (fattr == 0) {
fattr = FILE_ATTRIBUTE_NORMAL;
@@ -604,10 +604,9 @@ void reply_ntcreate_and_X(struct smb_request *req)
p += 4;
/* Create time. */
- c_timespec = get_create_timespec(
- &sbuf,lp_fake_dir_create_times(SNUM(conn)));
- a_timespec = get_atimespec(&sbuf);
- m_timespec = get_mtimespec(&sbuf);
+ c_timespec = sbuf.st_ex_btime;
+ a_timespec = sbuf.st_ex_atime;
+ m_timespec = sbuf.st_ex_mtime;
if (lp_dos_filetime_resolution(SNUM(conn))) {
dos_filetime_timespec(&c_timespec);
@@ -1037,7 +1036,7 @@ static void call_nt_transact_create(connection_struct *conn,
oplock_granted = NO_OPLOCK_RETURN;
}
- file_len = sbuf.st_size;
+ file_len = sbuf.st_ex_size;
fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
if (fattr == 0) {
fattr = FILE_ATTRIBUTE_NORMAL;
@@ -1071,10 +1070,9 @@ static void call_nt_transact_create(connection_struct *conn,
p += 8;
/* Create time. */
- c_timespec = get_create_timespec(
- &sbuf,lp_fake_dir_create_times(SNUM(conn)));
- a_timespec = get_atimespec(&sbuf);
- m_timespec = get_mtimespec(&sbuf);
+ c_timespec = sbuf.st_ex_btime;
+ a_timespec = sbuf.st_ex_atime;
+ m_timespec = sbuf.st_ex_mtime;
if (lp_dos_filetime_resolution(SNUM(conn))) {
dos_filetime_timespec(&c_timespec);
@@ -1220,7 +1218,7 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx,
}
/* No links from a directory. */
- if (S_ISDIR(smb_fname->st.st_mode)) {
+ if (S_ISDIR(smb_fname->st.st_ex_mode)) {
status = NT_STATUS_FILE_IS_A_DIRECTORY;
goto out;
}
@@ -1283,8 +1281,8 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx,
goto out;
}
- if (smb_fname->st.st_size) {
- ret = vfs_transfer_file(fsp1, fsp2, smb_fname->st.st_size);
+ if (smb_fname->st.st_ex_size) {
+ ret = vfs_transfer_file(fsp1, fsp2, smb_fname->st.st_ex_size);
}
/*
@@ -1296,7 +1294,7 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx,
close_file(NULL, fsp1, NORMAL_CLOSE);
/* Ensure the modtime is set correctly on the destination file. */
- set_close_write_time(fsp2, get_mtimespec(&smb_fname->st));
+ set_close_write_time(fsp2, smb_fname->st.st_ex_mtime);
status = close_file(NULL, fsp2, NORMAL_CLOSE);
@@ -1311,7 +1309,7 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx,
false);
TALLOC_FREE(parent);
- if (ret < (SMB_OFF_T)smb_fname->st.st_size) {
+ if (ret < (SMB_OFF_T)smb_fname->st.st_ex_size) {
status = NT_STATUS_DISK_FULL;
goto out;
}
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index e6f523a162..c1b29f68f3 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -206,19 +206,19 @@ void change_file_owner_to_parent(connection_struct *conn,
}
become_root();
- ret = SMB_VFS_FCHOWN(fsp, parent_st.st_uid, (gid_t)-1);
+ ret = SMB_VFS_FCHOWN(fsp, parent_st.st_ex_uid, (gid_t)-1);
unbecome_root();
if (ret == -1) {
DEBUG(0,("change_file_owner_to_parent: failed to fchown "
"file %s to parent directory uid %u. Error "
"was %s\n", fsp->fsp_name,
- (unsigned int)parent_st.st_uid,
+ (unsigned int)parent_st.st_ex_uid,
strerror(errno) ));
}
DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
"parent directory uid %u.\n", fsp->fsp_name,
- (unsigned int)parent_st.st_uid ));
+ (unsigned int)parent_st.st_ex_uid ));
}
NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
@@ -276,9 +276,9 @@ NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
}
/* Ensure we're pointing at the same place. */
- if (sbuf.st_dev != psbuf->st_dev ||
- sbuf.st_ino != psbuf->st_ino ||
- sbuf.st_mode != psbuf->st_mode ) {
+ if (sbuf.st_ex_dev != psbuf->st_ex_dev ||
+ sbuf.st_ex_ino != psbuf->st_ex_ino ||
+ sbuf.st_ex_mode != psbuf->st_ex_mode ) {
DEBUG(0,("change_dir_owner_to_parent: "
"device/inode/mode on directory %s changed. "
"Refusing to chown !\n", fname ));
@@ -287,20 +287,20 @@ NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
}
become_root();
- ret = SMB_VFS_CHOWN(conn, ".", parent_st.st_uid, (gid_t)-1);
+ ret = SMB_VFS_CHOWN(conn, ".", parent_st.st_ex_uid, (gid_t)-1);
unbecome_root();
if (ret == -1) {
status = map_nt_error_from_unix(errno);
DEBUG(10,("change_dir_owner_to_parent: failed to chown "
"directory %s to parent directory uid %u. "
"Error was %s\n", fname,
- (unsigned int)parent_st.st_uid, strerror(errno) ));
+ (unsigned int)parent_st.st_ex_uid, strerror(errno) ));
goto out;
}
DEBUG(10,("change_dir_owner_to_parent: changed ownership of new "
"directory %s to parent directory uid %u.\n",
- fname, (unsigned int)parent_st.st_uid ));
+ fname, (unsigned int)parent_st.st_ex_uid ));
out:
@@ -396,7 +396,7 @@ static NTSTATUS open_file(files_struct *fsp,
* open flags. JRA.
*/
- if (file_existed && S_ISFIFO(psbuf->st_mode)) {
+ if (file_existed && S_ISFIFO(psbuf->st_ex_mode)) {
local_flags |= O_NONBLOCK;
}
#endif
@@ -498,7 +498,7 @@ static NTSTATUS open_file(files_struct *fsp,
}
} else if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
fsp->posix_open &&
- S_ISLNK(psbuf->st_mode)) {
+ S_ISLNK(psbuf->st_ex_mode)) {
/* This is a POSIX stat open for delete
* or rename on a symlink that points
* nowhere. Allow. */
@@ -543,13 +543,13 @@ static NTSTATUS open_file(files_struct *fsp,
* so catch a directory open and return an EISDIR. JRA.
*/
- if(S_ISDIR(psbuf->st_mode)) {
+ if(S_ISDIR(psbuf->st_ex_mode)) {
fd_close(fsp);
errno = EISDIR;
return NT_STATUS_FILE_IS_A_DIRECTORY;
}
- fsp->mode = psbuf->st_mode;
+ fsp->mode = psbuf->st_ex_mode;
fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
fsp->file_pid = req ? req->smbpid : 0;
@@ -1583,7 +1583,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
DEBUG(5,("open_file_ntcreate: FILE_CREATE "
"requested for file %s and file "
"already exists.\n", fname ));
- if (S_ISDIR(psbuf->st_mode)) {
+ if (S_ISDIR(psbuf->st_ex_mode)) {
errno = EISDIR;
} else {
errno = EEXIST;
@@ -1610,13 +1610,13 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
(create_disposition == FILE_OVERWRITE_IF))) {
if (!open_match_attributes(conn, fname,
existing_dos_attributes,
- new_dos_attributes, psbuf->st_mode,
+ new_dos_attributes, psbuf->st_ex_mode,
unx_mode, &new_unx_mode)) {
DEBUG(5,("open_file_ntcreate: attributes missmatch "
"for file %s (%x %x) (0%o, 0%o)\n",
fname, existing_dos_attributes,
new_dos_attributes,
- (unsigned int)psbuf->st_mode,
+ (unsigned int)psbuf->st_ex_mode,
(unsigned int)unx_mode ));
errno = EACCES;
return NT_STATUS_ACCESS_DENIED;
@@ -1715,7 +1715,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
}
if (file_existed) {
- struct timespec old_write_time = get_mtimespec(psbuf);
+ struct timespec old_write_time = psbuf->st_ex_mtime;
id = vfs_file_id_from_sbuf(conn, psbuf);
lck = get_share_mode_lock(talloc_tos(), id,
@@ -1919,7 +1919,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
}
if (!file_existed) {
- struct timespec old_write_time = get_mtimespec(psbuf);
+ struct timespec old_write_time = psbuf->st_ex_mtime;
/*
* Deal with the race condition where two smbd's detect the
* file doesn't exist and do the create at the same time. One
@@ -2134,7 +2134,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
new_dos_attributes | aARCH,
&tmp_sbuf, parent_dir,
true) == 0) {
- unx_mode = tmp_sbuf.st_mode;
+ unx_mode = tmp_sbuf.st_ex_mode;
}
}
}
@@ -2305,7 +2305,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
return map_nt_error_from_unix(errno);
}
- if (!S_ISDIR(psbuf->st_mode)) {
+ if (!S_ISDIR(psbuf->st_ex_mode)) {
DEBUG(0, ("Directory just '%s' created is not a directory\n",
name));
return NT_STATUS_ACCESS_DENIED;
@@ -2331,9 +2331,9 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
* Consider bits automagically set by UNIX, i.e. SGID bit from parent
* dir.
*/
- if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) && (mode & ~psbuf->st_mode)) {
+ if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) && (mode & ~psbuf->st_ex_mode)) {
SMB_VFS_CHMOD(conn, name,
- psbuf->st_mode | (mode & ~psbuf->st_mode));
+ psbuf->st_ex_mode | (mode & ~psbuf->st_ex_mode));
}
}
@@ -2475,7 +2475,7 @@ static NTSTATUS open_directory(connection_struct *conn,
return NT_STATUS_INVALID_PARAMETER;
}
- if(!S_ISDIR(psbuf->st_mode)) {
+ if(!S_ISDIR(psbuf->st_ex_mode)) {
DEBUG(5,("open_directory: %s is not a directory !\n",
fname ));
return NT_STATUS_NOT_A_DIRECTORY;
@@ -2524,7 +2524,7 @@ static NTSTATUS open_directory(connection_struct *conn,
* Setup the files_struct for it.
*/
- fsp->mode = psbuf->st_mode;
+ fsp->mode = psbuf->st_ex_mode;
fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
fsp->file_pid = req ? req->smbpid : 0;
@@ -2547,7 +2547,7 @@ static NTSTATUS open_directory(connection_struct *conn,
string_set(&fsp->fsp_name,fname);
- mtimespec = get_mtimespec(psbuf);
+ mtimespec = psbuf->st_ex_mtime;
lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
conn->connectpath,
@@ -3161,7 +3161,7 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
}
}
- if (!fsp->is_directory && S_ISDIR(sbuf.st_mode)) {
+ if (!fsp->is_directory && S_ISDIR(sbuf.st_ex_mode)) {
status = NT_STATUS_ACCESS_DENIED;
goto fail;
}
@@ -3169,7 +3169,7 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
/* Save the requested allocation size. */
if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
if (allocation_size
- && (allocation_size > sbuf.st_size)) {
+ && (allocation_size > sbuf.st_ex_size)) {
fsp->initial_allocation_size = smb_roundup(
fsp->conn, allocation_size);
if (fsp->is_directory) {
@@ -3184,7 +3184,7 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
}
} else {
fsp->initial_allocation_size = smb_roundup(
- fsp->conn, (uint64_t)sbuf.st_size);
+ fsp->conn, (uint64_t)sbuf.st_ex_size);
}
}
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 8d172e17bd..08b1c8c41a 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -884,8 +884,8 @@ static int map_acl_perms_to_permset(connection_struct *conn, mode_t mode, SMB_AC
void create_file_sids(const SMB_STRUCT_STAT *psbuf, DOM_SID *powner_sid, DOM_SID *pgroup_sid)
{
- uid_to_sid( powner_sid, psbuf->st_uid );
- gid_to_sid( pgroup_sid, psbuf->st_gid );
+ uid_to_sid( powner_sid, psbuf->st_ex_uid );
+ gid_to_sid( pgroup_sid, psbuf->st_ex_gid );
}
/****************************************************************************
@@ -1369,7 +1369,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace,
ZERO_STRUCTP(pace);
pace->type = SMB_ACL_USER_OBJ;
pace->owner_type = UID_ACE;
- pace->unix_ug.uid = pst->st_uid;
+ pace->unix_ug.uid = pst->st_ex_uid;
pace->trustee = *pfile_owner_sid;
pace->attr = ALLOW_ACE;
@@ -1399,7 +1399,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace,
apply_default_perms(params, is_directory, pace, S_IRUSR);
} else {
- pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRUSR, S_IWUSR, S_IXUSR);
+ pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRUSR, S_IWUSR, S_IXUSR);
}
DLIST_ADD(*pp_ace, pace);
@@ -1414,7 +1414,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace,
ZERO_STRUCTP(pace);
pace->type = SMB_ACL_GROUP_OBJ;
pace->owner_type = GID_ACE;
- pace->unix_ug.uid = pst->st_gid;
+ pace->unix_ug.uid = pst->st_ex_gid;
pace->trustee = *pfile_grp_sid;
pace->attr = ALLOW_ACE;
if (setting_acl) {
@@ -1425,7 +1425,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace,
pace->perms = 0;
apply_default_perms(params, is_directory, pace, S_IRGRP);
} else {
- pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRGRP, S_IWGRP, S_IXGRP);
+ pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRGRP, S_IWGRP, S_IXGRP);
}
DLIST_ADD(*pp_ace, pace);
@@ -1447,7 +1447,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace,
pace->perms = 0;
apply_default_perms(params, is_directory, pace, S_IROTH);
} else
- pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IROTH, S_IWOTH, S_IXOTH);
+ pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IROTH, S_IWOTH, S_IXOTH);
DLIST_ADD(*pp_ace, pace);
}
@@ -1625,7 +1625,7 @@ static bool create_canon_ace_lists(files_struct *fsp,
current_ace->type = SMB_ACL_OTHER;
} else if (sid_equal(&current_ace->trustee, &global_sid_Creator_Owner)) {
current_ace->owner_type = UID_ACE;
- current_ace->unix_ug.uid = pst->st_uid;
+ current_ace->unix_ug.uid = pst->st_ex_uid;
current_ace->type = SMB_ACL_USER_OBJ;
/*
@@ -1638,7 +1638,7 @@ static bool create_canon_ace_lists(files_struct *fsp,
psa->flags |= SEC_ACE_FLAG_INHERIT_ONLY;
} else if (sid_equal(&current_ace->trustee, &global_sid_Creator_Group)) {
current_ace->owner_type = GID_ACE;
- current_ace->unix_ug.gid = pst->st_gid;
+ current_ace->unix_ug.gid = pst->st_ex_gid;
current_ace->type = SMB_ACL_GROUP_OBJ;
/*
@@ -1653,7 +1653,7 @@ static bool create_canon_ace_lists(files_struct *fsp,
current_ace->owner_type = UID_ACE;
/* If it's the owning user, this is a user_obj, not
* a user. */
- if (current_ace->unix_ug.uid == pst->st_uid) {
+ if (current_ace->unix_ug.uid == pst->st_ex_uid) {
current_ace->type = SMB_ACL_USER_OBJ;
} else {
current_ace->type = SMB_ACL_USER;
@@ -1662,7 +1662,7 @@ static bool create_canon_ace_lists(files_struct *fsp,
current_ace->owner_type = GID_ACE;
/* If it's the primary group, this is a group_obj, not
* a group. */
- if (current_ace->unix_ug.gid == pst->st_gid) {
+ if (current_ace->unix_ug.gid == pst->st_ex_gid) {
current_ace->type = SMB_ACL_GROUP_OBJ;
} else {
current_ace->type = SMB_ACL_GROUP;
@@ -2272,7 +2272,7 @@ static bool unpack_canon_ace(files_struct *fsp,
* A default 3 element mode entry for a directory should be rwx --- ---.
*/
- pst->st_mode = create_default_mode(fsp, False);
+ pst->st_ex_mode = create_default_mode(fsp, False);
if (!ensure_canon_entry_valid(&file_ace, fsp->conn->params, fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst, True)) {
free_canon_ace_list(file_ace);
@@ -2288,7 +2288,7 @@ static bool unpack_canon_ace(files_struct *fsp,
* it's a directory.
*/
- pst->st_mode = create_default_mode(fsp, True);
+ pst->st_ex_mode = create_default_mode(fsp, True);
if (dir_ace && !ensure_canon_entry_valid(&dir_ace, fsp->conn->params, fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst, True)) {
free_canon_ace_list(file_ace);
@@ -2402,7 +2402,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn,
case SMB_ACL_USER_OBJ:
/* Get the SID from the owner. */
sid_copy(&sid, powner);
- unix_ug.uid = psbuf->st_uid;
+ unix_ug.uid = psbuf->st_ex_uid;
owner_type = UID_ACE;
break;
case SMB_ACL_USER:
@@ -2419,7 +2419,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn,
* entries out of the blue when setting ACLs, so a get/set
* cycle will drop them.
*/
- if (the_acl_type == SMB_ACL_TYPE_ACCESS && *puid == psbuf->st_uid) {
+ if (the_acl_type == SMB_ACL_TYPE_ACCESS && *puid == psbuf->st_ex_uid) {
SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
continue;
}
@@ -2432,7 +2432,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn,
case SMB_ACL_GROUP_OBJ:
/* Get the SID from the owning group. */
sid_copy(&sid, pgroup);
- unix_ug.gid = psbuf->st_gid;
+ unix_ug.gid = psbuf->st_ex_gid;
owner_type = GID_ACE;
break;
case SMB_ACL_GROUP:
@@ -2486,7 +2486,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn,
*/
if (!ensure_canon_entry_valid(&l_head, conn->params,
- S_ISDIR(psbuf->st_mode), powner, pgroup,
+ S_ISDIR(psbuf->st_ex_mode), powner, pgroup,
psbuf, False))
goto fail;
@@ -3097,7 +3097,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn,
goto done;
}
- if (S_ISDIR(sbuf->st_mode) && def_acl) {
+ if (S_ISDIR(sbuf->st_ex_mode) && def_acl) {
dir_ace = canonicalise_acl(conn, name, def_acl,
sbuf,
&global_sid_Creator_Owner,
@@ -3181,7 +3181,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn,
uint32_t acc = map_canon_ace_perms(SNUM(conn),
&nt_acl_type,
ace->perms,
- S_ISDIR(sbuf->st_mode));
+ S_ISDIR(sbuf->st_ex_mode));
init_sec_ace(&nt_ace_list[num_aces++],
&ace->trustee,
nt_acl_type,
@@ -3202,7 +3202,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn,
uint32_t acc = map_canon_ace_perms(SNUM(conn),
&nt_acl_type,
ace->perms,
- S_ISDIR(sbuf->st_mode));
+ S_ISDIR(sbuf->st_ex_mode));
init_sec_ace(&nt_ace_list[num_aces++],
&ace->trustee,
nt_acl_type,
@@ -3357,7 +3357,7 @@ NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name,
posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_ACCESS);
/* If it's a directory get the default POSIX ACL. */
- if(S_ISDIR(sbuf.st_mode)) {
+ if(S_ISDIR(sbuf.st_ex_mode)) {
def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_DEFAULT);
def_acl = free_empty_sys_acl(conn, def_acl);
}
@@ -3687,7 +3687,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
}
/* Save the original element we check against. */
- orig_mode = sbuf.st_mode;
+ orig_mode = sbuf.st_ex_mode;
/*
* Unpack the user/group/world id's.
@@ -3704,7 +3704,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
* Noticed by Simo.
*/
- if (((user != (uid_t)-1) && (sbuf.st_uid != user)) || (( grp != (gid_t)-1) && (sbuf.st_gid != grp))) {
+ if (((user != (uid_t)-1) && (sbuf.st_ex_uid != user)) || (( grp != (gid_t)-1) && (sbuf.st_ex_gid != grp))) {
DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n",
fsp->fsp_name, (unsigned int)user, (unsigned int)grp ));
@@ -3741,7 +3741,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
}
/* Save the original element we check against. */
- orig_mode = sbuf.st_mode;
+ orig_mode = sbuf.st_ex_mode;
/* If we successfully chowned, we know we must
* be able to set the acl, so do it as root.
@@ -3785,7 +3785,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
if (set_acl_as_root) {
become_root();
}
- ret = set_canon_ace_list(fsp, file_ace_list, False, sbuf.st_gid, &acl_set_support);
+ ret = set_canon_ace_list(fsp, file_ace_list, False, sbuf.st_ex_gid, &acl_set_support);
if (set_acl_as_root) {
unbecome_root();
}
@@ -3802,7 +3802,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
if (set_acl_as_root) {
become_root();
}
- ret = set_canon_ace_list(fsp, dir_ace_list, True, sbuf.st_gid, &acl_set_support);
+ ret = set_canon_ace_list(fsp, dir_ace_list, True, sbuf.st_ex_gid, &acl_set_support);
if (set_acl_as_root) {
unbecome_root();
}
@@ -3827,7 +3827,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
unbecome_root();
}
if (sret == -1) {
- if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) {
+ if (acl_group_override(conn, sbuf.st_ex_gid, fsp->fsp_name)) {
DEBUG(5,("set_nt_acl: acl group control on and "
"current user in file %s primary group. Override delete_def_acl\n",
fsp->fsp_name ));
@@ -3889,7 +3889,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
unbecome_root();
}
if(sret == -1) {
- if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) {
+ if (acl_group_override(conn, sbuf.st_ex_gid, fsp->fsp_name)) {
DEBUG(5,("set_nt_acl: acl group control on and "
"current user in file %s primary group. Override chmod\n",
fsp->fsp_name ));
@@ -4285,7 +4285,7 @@ bool set_unix_posix_default_acl(connection_struct *conn, const char *fname, SMB_
{
SMB_ACL_T def_acl = NULL;
- if (!S_ISDIR(psbuf->st_mode)) {
+ if (!S_ISDIR(psbuf->st_ex_mode)) {
if (num_def_acls) {
DEBUG(5,("set_unix_posix_default_acl: Can't set default ACL on non-directory file %s\n", fname ));
errno = EISDIR;
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 5cad8bfc9a..e014965147 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -1462,7 +1462,7 @@ static void process_smb(struct smbd_server_connection *conn,
trans_num++;
done:
- conn->num_requests++;
+ conn->smb1.num_requests++;
/* The timeout_processing function isn't run nearly
often enough to implement 'max log size' without
@@ -1471,7 +1471,7 @@ done:
level 10. Checking every 50 SMBs is a nice
tradeoff of performance vs log file size overrun. */
- if ((conn->num_requests % 50) == 0 &&
+ if ((conn->smb1.num_requests % 50) == 0 &&
need_to_check_log_size()) {
change_to_root_user();
check_log_size();
@@ -2158,13 +2158,13 @@ void smbd_process(void)
max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
- smbd_server_conn->fde = event_add_fd(smbd_event_context(),
- smbd_server_conn,
- smbd_server_fd(),
- EVENT_FD_READ,
- smbd_server_connection_handler,
- smbd_server_conn);
- if (!smbd_server_conn->fde) {
+ smbd_server_conn->smb1.fde = event_add_fd(smbd_event_context(),
+ smbd_server_conn,
+ smbd_server_fd(),
+ EVENT_FD_READ,
+ smbd_server_connection_handler,
+ smbd_server_conn);
+ if (!smbd_server_conn->smb1.fde) {
exit_server("failed to create smbd_server_connection fde");
}
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index d5ee918b82..8657bd6e18 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -1022,7 +1022,7 @@ void reply_checkpath(struct smb_request *req)
goto path_err;
}
- if (!S_ISDIR(smb_fname->st.st_mode)) {
+ if (!S_ISDIR(smb_fname->st.st_ex_mode)) {
reply_botherror(req, NT_STATUS_NOT_A_DIRECTORY,
ERRDOS, ERRbadpath);
goto out;
@@ -1135,8 +1135,8 @@ void reply_getatr(struct smb_request *req)
}
mode = dos_mode(conn, fname, &smb_fname->st);
- size = smb_fname->st.st_size;
- mtime = smb_fname->st.st_mtime;
+ size = smb_fname->st.st_ex_size;
+ mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
if (mode & aDIR) {
size = 0;
}
@@ -1336,7 +1336,7 @@ void reply_search(struct smb_request *req)
char *fname = NULL;
SMB_OFF_T size;
uint32 mode;
- time_t date;
+ struct timespec date;
uint32 dirtype;
unsigned int numentries = 0;
unsigned int maxentries = 0;
@@ -1555,7 +1555,7 @@ void reply_search(struct smb_request *req)
fname,
size,
mode,
- date,
+ convert_timespec_to_time_t(date),
!allow_long_path_components)) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
END_PROFILE(SMBsearch);
@@ -1775,9 +1775,9 @@ void reply_open(struct smb_request *req)
return;
}
- size = sbuf.st_size;
+ size = sbuf.st_ex_size;
fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
- mtime = sbuf.st_mtime;
+ mtime = convert_timespec_to_time_t(sbuf.st_ex_mtime);
if (fattr & aDIR) {
DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name));
@@ -1939,11 +1939,11 @@ void reply_open_and_X(struct smb_request *req)
END_PROFILE(SMBopenX);
return;
}
- sbuf.st_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf);
+ sbuf.st_ex_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf);
}
fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
- mtime = sbuf.st_mtime;
+ mtime = convert_timespec_to_time_t(sbuf.st_ex_mtime);
if (fattr & aDIR) {
close_file(req, fsp, ERROR_CLOSE);
reply_doserror(req, ERRDOS, ERRnoaccess);
@@ -1992,7 +1992,7 @@ void reply_open_and_X(struct smb_request *req)
} else {
srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime);
}
- SIVAL(req->outbuf,smb_vwv6,(uint32)sbuf.st_size);
+ SIVAL(req->outbuf,smb_vwv6,(uint32)sbuf.st_ex_size);
SSVAL(req->outbuf,smb_vwv8,GET_OPENX_MODE(deny_mode));
SSVAL(req->outbuf,smb_vwv11,smb_action);
@@ -2124,7 +2124,7 @@ void reply_mknew(struct smb_request *req)
return;
}
- ft.atime = get_atimespec(&sbuf); /* atime. */
+ ft.atime = sbuf.st_ex_atime; /* atime. */
status = smb_set_file_time(conn, fsp, fsp->fsp_name, &sbuf, &ft, true);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBcreate);
@@ -2306,7 +2306,7 @@ void reply_ctemp(struct smb_request *req)
DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fsp->fsp_name ) );
DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fsp->fsp_name,
- fsp->fh->fd, (unsigned int)smb_fname->st.st_mode));
+ fsp->fh->fd, (unsigned int)smb_fname->st.st_ex_mode));
out:
TALLOC_FREE(smb_fname);
END_PROFILE(SMBctemp);
@@ -2331,7 +2331,7 @@ static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
return NT_STATUS_NO_SUCH_FILE;
}
- if (S_ISDIR(pst->st_mode)) {
+ if (S_ISDIR(pst->st_ex_mode)) {
if (fsp->posix_open) {
return NT_STATUS_OK;
}
@@ -2893,7 +2893,7 @@ static void send_file_readbraw(connection_struct *conn,
if ( !req_is_in_chain(req) && (nread > 0) && (fsp->base_fsp == NULL) &&
(fsp->wcp == NULL) &&
- lp_use_sendfile(SNUM(conn), smbd_server_conn->signing_state) ) {
+ lp_use_sendfile(SNUM(conn), smbd_server_conn->smb1.signing_state) ) {
ssize_t sendfile_read = -1;
char header[4];
DATA_BLOB header_blob;
@@ -3104,7 +3104,7 @@ void reply_readbraw(struct smb_request *req)
}
if (SMB_VFS_FSTAT(fsp, &st) == 0) {
- size = st.st_size;
+ size = st.st_ex_size;
}
if (startpos >= size) {
@@ -3393,8 +3393,8 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
return;
}
- if (!S_ISREG(sbuf.st_mode) || (startpos > sbuf.st_size)
- || (smb_maxcnt > (sbuf.st_size - startpos))) {
+ if (!S_ISREG(sbuf.st_ex_mode) || (startpos > sbuf.st_ex_size)
+ || (smb_maxcnt > (sbuf.st_ex_size - startpos))) {
/*
* We already know that we would do a short read, so don't
* try the sendfile() path.
@@ -3412,7 +3412,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
if (!req_is_in_chain(req) &&
!is_encrypted_packet(req->inbuf) && (fsp->base_fsp == NULL) &&
(fsp->wcp == NULL) &&
- lp_use_sendfile(SNUM(conn), smbd_server_conn->signing_state) ) {
+ lp_use_sendfile(SNUM(conn), smbd_server_conn->smb1.signing_state) ) {
uint8 headerbuf[smb_size + 12 * 2];
DATA_BLOB header;
@@ -4442,7 +4442,7 @@ void reply_lseek(struct smb_request *req)
return;
}
- current_pos += sbuf.st_size;
+ current_pos += sbuf.st_ex_size;
if(current_pos < 0)
res = SMB_VFS_LSEEK(fsp,0,SEEK_SET);
}
@@ -5287,7 +5287,7 @@ static bool recursive_rmdir(TALLOC_CTX *ctx,
break;
}
- if(st.st_mode & S_IFDIR) {
+ if(st.st_ex_mode & S_IFDIR) {
if(!recursive_rmdir(ctx, conn, fullname)) {
ret = False;
break;
@@ -5322,12 +5322,12 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx,
return map_nt_error_from_unix(errno);
}
- if (S_ISLNK(st.st_mode)) {
+ if (S_ISLNK(st.st_ex_mode)) {
/* Is what it points to a directory ? */
if(SMB_VFS_STAT(conn, directory, &st) != 0) {
return map_nt_error_from_unix(errno);
}
- if (!(S_ISDIR(st.st_mode))) {
+ if (!(S_ISDIR(st.st_ex_mode))) {
return NT_STATUS_NOT_A_DIRECTORY;
}
ret = SMB_VFS_UNLINK(conn,directory);
@@ -5404,7 +5404,7 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx,
if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
break;
}
- if(st.st_mode & S_IFDIR) {
+ if(st.st_ex_mode & S_IFDIR) {
if(!recursive_rmdir(ctx, conn, fullname)) {
break;
}
@@ -6103,7 +6103,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
SMB_VFS_STAT(conn, directory, &smb_fname->st);
}
- if (S_ISDIR(smb_fname->st.st_mode)) {
+ if (S_ISDIR(smb_fname->st.st_ex_mode)) {
create_options |= FILE_DIRECTORY_FILE;
}
@@ -6229,7 +6229,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
create_options = 0;
- if (S_ISDIR(smb_fname->st.st_mode)) {
+ if (S_ISDIR(smb_fname->st.st_ex_mode)) {
create_options |= FILE_DIRECTORY_FILE;
}
@@ -6510,18 +6510,18 @@ NTSTATUS copy_file(TALLOC_CTX *ctx,
* Stop the copy from occurring.
*/
ret = -1;
- src_sbuf.st_size = 0;
+ src_sbuf.st_ex_size = 0;
}
}
- if (src_sbuf.st_size) {
- ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size);
+ if (src_sbuf.st_ex_size) {
+ ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_ex_size);
}
close_file(NULL, fsp1, NORMAL_CLOSE);
/* Ensure the modtime is set correctly on the destination file. */
- set_close_write_time(fsp2, get_mtimespec(&src_sbuf));
+ set_close_write_time(fsp2, src_sbuf.st_ex_mtime);
/*
* As we are opening fsp1 read-only we only expect
@@ -6535,7 +6535,7 @@ NTSTATUS copy_file(TALLOC_CTX *ctx,
return status;
}
- if (ret != (SMB_OFF_T)src_sbuf.st_size) {
+ if (ret != (SMB_OFF_T)src_sbuf.st_ex_size) {
return NT_STATUS_DISK_FULL;
}
@@ -7551,19 +7551,20 @@ void reply_getattrE(struct smb_request *req)
reply_outbuf(req, 11, 0);
- create_ts = get_create_timespec(&sbuf,
- lp_fake_dir_create_times(SNUM(conn)));
+ create_ts = sbuf.st_ex_btime;
srv_put_dos_date2((char *)req->outbuf, smb_vwv0, create_ts.tv_sec);
- srv_put_dos_date2((char *)req->outbuf, smb_vwv2, sbuf.st_atime);
+ srv_put_dos_date2((char *)req->outbuf, smb_vwv2,
+ convert_timespec_to_time_t(sbuf.st_ex_atime));
/* Should we check pending modtime here ? JRA */
- srv_put_dos_date2((char *)req->outbuf, smb_vwv4, sbuf.st_mtime);
+ srv_put_dos_date2((char *)req->outbuf, smb_vwv4,
+ convert_timespec_to_time_t(sbuf.st_ex_mtime));
if (mode & aDIR) {
SIVAL(req->outbuf, smb_vwv6, 0);
SIVAL(req->outbuf, smb_vwv8, 0);
} else {
uint32 allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp, &sbuf);
- SIVAL(req->outbuf, smb_vwv6, (uint32)sbuf.st_size);
+ SIVAL(req->outbuf, smb_vwv6, (uint32)sbuf.st_ex_size);
SIVAL(req->outbuf, smb_vwv8, allocation_size);
}
SSVAL(req->outbuf,smb_vwv10, mode);
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 67836f785b..685b26fa1a 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -356,6 +356,7 @@ static void smbd_accept_connection(struct tevent_context *ev,
pid = sys_fork();
if (pid == 0) {
+ NTSTATUS status = NT_STATUS_OK;
/* Child code ... */
am_parent = 0;
@@ -374,10 +375,15 @@ static void smbd_accept_connection(struct tevent_context *ev,
talloc_free(s->parent);
s = NULL;
- if (!reinit_after_fork(
- smbd_messaging_context(),
- smbd_event_context(),
- true)) {
+ status = reinit_after_fork(smbd_messaging_context(),
+ smbd_event_context(), true);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(status,
+ NT_STATUS_TOO_MANY_OPENED_FILES)) {
+ DEBUG(0,("child process cannot initialize "
+ "because too many files are open\n"));
+ goto exit;
+ }
DEBUG(0,("reinit_after_fork() failed\n"));
smb_panic("reinit_after_fork() failed");
}
@@ -386,6 +392,7 @@ static void smbd_accept_connection(struct tevent_context *ev,
smbd_setup_sig_hup_handler();
smbd_process();
+ exit:
exit_server_cleanly("end of child");
return;
} else if (pid < 0) {
@@ -1122,8 +1129,8 @@ extern void build_options(bool screen);
if (is_daemon)
pidfile_create("smbd");
- if (!reinit_after_fork(smbd_messaging_context(),
- smbd_event_context(), false)) {
+ if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(),
+ smbd_event_context(), false))) {
DEBUG(0,("reinit_after_fork() failed\n"));
exit(1);
}
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index bc07f0b90d..75c19ce131 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -993,8 +993,8 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
I have disabled this chdir check (tridge) */
/* the alternative is just to check the directory exists */
if ((ret = SMB_VFS_STAT(conn, conn->connectpath, &st)) != 0 ||
- !S_ISDIR(st.st_mode)) {
- if (ret == 0 && !S_ISDIR(st.st_mode)) {
+ !S_ISDIR(st.st_ex_mode)) {
+ if (ret == 0 && !S_ISDIR(st.st_ex_mode)) {
DEBUG(0,("'%s' is not a directory, when connecting to "
"[%s]\n", conn->connectpath,
lp_servicename(snum)));
diff --git a/source3/smbd/signing.c b/source3/smbd/signing.c
index b56eb71f45..9b5e3452f9 100644
--- a/source3/smbd/signing.c
+++ b/source3/smbd/signing.c
@@ -35,8 +35,8 @@ bool srv_check_sign_mac(struct smbd_server_connection *conn,
return true;
}
- *seqnum = smb_signing_next_seqnum(conn->signing_state, false);
- return smb_signing_check_pdu(conn->signing_state,
+ *seqnum = smb_signing_next_seqnum(conn->smb1.signing_state, false);
+ return smb_signing_check_pdu(conn->smb1.signing_state,
(const uint8_t *)inbuf,
*seqnum);
}
@@ -53,7 +53,7 @@ void srv_calculate_sign_mac(struct smbd_server_connection *conn,
return;
}
- smb_signing_sign_pdu(conn->signing_state, (uint8_t *)outbuf, seqnum);
+ smb_signing_sign_pdu(conn->smb1.signing_state, (uint8_t *)outbuf, seqnum);
}
@@ -62,7 +62,7 @@ void srv_calculate_sign_mac(struct smbd_server_connection *conn,
************************************************************/
void srv_cancel_sign_response(struct smbd_server_connection *conn)
{
- smb_signing_cancel_reply(conn->signing_state, true);
+ smb_signing_cancel_reply(conn->smb1.signing_state, true);
}
/***********************************************************
@@ -87,9 +87,9 @@ bool srv_init_signing(struct smbd_server_connection *conn)
break;
}
- conn->signing_state = smb_signing_init(smbd_event_context(),
- allowed, mandatory);
- if (!conn->signing_state) {
+ conn->smb1.signing_state = smb_signing_init(smbd_event_context(),
+ allowed, mandatory);
+ if (!conn->smb1.signing_state) {
return false;
}
@@ -98,7 +98,7 @@ bool srv_init_signing(struct smbd_server_connection *conn)
void srv_set_signing_negotiated(struct smbd_server_connection *conn)
{
- smb_signing_set_negotiated(conn->signing_state);
+ smb_signing_set_negotiated(conn->smb1.signing_state);
}
/***********************************************************
@@ -108,7 +108,7 @@ void srv_set_signing_negotiated(struct smbd_server_connection *conn)
bool srv_is_signing_active(struct smbd_server_connection *conn)
{
- return smb_signing_is_active(conn->signing_state);
+ return smb_signing_is_active(conn->smb1.signing_state);
}
@@ -119,7 +119,7 @@ bool srv_is_signing_active(struct smbd_server_connection *conn)
bool srv_is_signing_negotiated(struct smbd_server_connection *conn)
{
- return smb_signing_is_negotiated(conn->signing_state);
+ return smb_signing_is_negotiated(conn->smb1.signing_state);
}
/***********************************************************
@@ -136,8 +136,8 @@ void srv_set_signing(struct smbd_server_connection *conn,
if (!user_session_key.length)
return;
- negotiated = smb_signing_is_negotiated(conn->signing_state);
- mandatory = smb_signing_is_mandatory(conn->signing_state);
+ negotiated = smb_signing_is_negotiated(conn->smb1.signing_state);
+ mandatory = smb_signing_is_mandatory(conn->smb1.signing_state);
if (!negotiated && !mandatory) {
DEBUG(5,("srv_set_signing: signing negotiated = %u, "
@@ -146,7 +146,7 @@ void srv_set_signing(struct smbd_server_connection *conn,
return;
}
- if (!smb_signing_activate(conn->signing_state,
+ if (!smb_signing_activate(conn->smb1.signing_state,
user_session_key, response)) {
return;
}
diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index b976ea2399..e9464900f2 100644
--- a/source3/smbd/smb2_negprot.c
+++ b/source3/smbd/smb2_negprot.c
@@ -74,8 +74,10 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
size_t body_size;
size_t expected_dyn_size = 0;
size_t c;
+ uint16_t security_mode;
uint16_t dialect_count;
uint16_t dialect;
+ uint32_t capabilities;
/* TODO: drop the connection with INVALI_PARAMETER */
@@ -103,12 +105,12 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
for (c=0; c < dialect_count; c++) {
dialect = SVAL(indyn, c*2);
- if (dialect == 0x0202) {
+ if (dialect == SMB2_DIALECT_REVISION_202) {
break;
}
}
- if (dialect != 0x0202) {
+ if (dialect != SMB2_DIALECT_REVISION_202) {
return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
}
@@ -129,6 +131,16 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
}
+ security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
+ if (lp_server_signing() == Required) {
+ security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
+ }
+
+ capabilities = 0;
+ if (lp_host_msdfs()) {
+ capabilities |= SMB2_CAP_DFS;
+ }
+
security_offset = SMB2_HDR_BODY + 0x40;
security_buffer = data_blob_const(negprot_spnego_blob.data + 16,
negprot_spnego_blob.length - 16);
@@ -142,13 +154,14 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
}
SSVAL(outbody.data, 0x00, 0x40 + 1); /* struct size */
-/*TODO: indicate signing enabled */
- SSVAL(outbody.data, 0x02, 0); /* security mode */
+ SSVAL(outbody.data, 0x02,
+ security_mode); /* security mode */
SSVAL(outbody.data, 0x04, dialect); /* dialect revision */
SSVAL(outbody.data, 0x06, 0); /* reserved */
memcpy(outbody.data + 0x08,
negprot_spnego_blob.data, 16); /* server guid */
- SIVAL(outbody.data, 0x18, 0); /* capabilities */
+ SIVAL(outbody.data, 0x18,
+ capabilities); /* capabilities */
SIVAL(outbody.data, 0x1C, 0x00010000); /* max transact size */
SIVAL(outbody.data, 0x20, 0x00010000); /* max read size */
SIVAL(outbody.data, 0x24, 0x00010000); /* max write size */
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 32bb5543ae..0d901714e0 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -41,7 +41,7 @@ static NTSTATUS smbd_initialize_smb2(struct smbd_server_connection *conn)
NTSTATUS status;
int ret;
- TALLOC_FREE(conn->fde);
+ TALLOC_FREE(conn->smb1.fde);
conn->smb2.event_ctx = smbd_event_context();
@@ -288,14 +288,45 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
const uint8_t *inhdr;
int i = req->current_idx;
uint16_t opcode;
+ uint32_t flags;
NTSTATUS status;
+ NTSTATUS session_status;
inhdr = (const uint8_t *)req->in.vector[i].iov_base;
/* TODO: verify more things */
+ flags = IVAL(inhdr, SMB2_HDR_FLAGS);
opcode = IVAL(inhdr, SMB2_HDR_OPCODE);
DEBUG(10,("smbd_smb2_request_dispatch: opcode[%u]\n", opcode));
+
+#define TMP_SMB2_ALLOWED_FLAGS ( \
+ SMB2_HDR_FLAG_CHAINED | \
+ SMB2_HDR_FLAG_SIGNED | \
+ SMB2_HDR_FLAG_DFS)
+ if ((flags & ~TMP_SMB2_ALLOWED_FLAGS) != 0) {
+ return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+ }
+#undef TMP_SMB2_ALLOWED_FLAGS
+
+ session_status = smbd_smb2_request_check_session(req);
+
+ req->do_signing = false;
+ if (flags & SMB2_HDR_FLAG_SIGNED) {
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
+ }
+
+ req->do_signing = true;
+ status = smb2_signing_check_pdu(req->session->session_key,
+ &req->in.vector[i], 3);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
+ } else if (req->session && req->session->do_signing) {
+ return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED);
+ }
+
switch (opcode) {
case SMB2_OP_NEGPROT:
return smbd_smb2_request_process_negprot(req);
@@ -304,13 +335,15 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_process_sesssetup(req);
case SMB2_OP_LOGOFF:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
return smbd_smb2_request_process_logoff(req);
case SMB2_OP_TCON:
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
+ }
status = smbd_smb2_request_check_session(req);
if (!NT_STATUS_IS_OK(status)) {
return smbd_smb2_request_error(req, status);
@@ -318,9 +351,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_process_tcon(req);
case SMB2_OP_TDIS:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -329,9 +361,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_process_tdis(req);
case SMB2_OP_CREATE:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -340,9 +371,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_CLOSE:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -351,9 +381,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_FLUSH:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -362,9 +391,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_READ:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -373,9 +401,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_WRITE:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -384,9 +411,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_LOCK:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -395,9 +421,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_IOCTL:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -412,9 +437,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_process_keepalive(req);
case SMB2_OP_FIND:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -423,9 +447,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_NOTIFY:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -434,9 +457,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_GETINFO:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -445,9 +467,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_SETINFO:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -456,9 +477,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED);
case SMB2_OP_BREAK:
- status = smbd_smb2_request_check_session(req);
- if (!NT_STATUS_IS_OK(status)) {
- return smbd_smb2_request_error(req, status);
+ if (!NT_STATUS_IS_OK(session_status)) {
+ return smbd_smb2_request_error(req, session_status);
}
status = smbd_smb2_request_check_tcon(req);
if (!NT_STATUS_IS_OK(status)) {
@@ -481,6 +501,16 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
+ if (req->do_signing) {
+ int i = req->current_idx;
+ NTSTATUS status;
+ status = smb2_signing_sign_pdu(req->session->session_key,
+ &req->out.vector[i], 3);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ }
+
req->current_idx += 3;
if (req->current_idx > req->in.vector_count) {
diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index fafda24ca4..be37aec04d 100644
--- a/source3/smbd/smb2_sesssetup.c
+++ b/source3/smbd/smb2_sesssetup.c
@@ -24,7 +24,9 @@
static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req,
uint64_t in_session_id,
+ uint8_t in_security_mode,
DATA_BLOB in_security_buffer,
+ uint16_t *out_session_flags,
DATA_BLOB *out_security_buffer,
uint64_t *out_session_id);
@@ -39,9 +41,11 @@ NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *req)
size_t expected_body_size = 0x19;
size_t body_size;
uint64_t in_session_id;
+ uint8_t in_security_mode;
uint16_t in_security_offset;
uint16_t in_security_length;
DATA_BLOB in_security_buffer;
+ uint16_t out_session_flags;
uint64_t out_session_id;
uint16_t out_security_offset;
DATA_BLOB out_security_buffer;
@@ -72,12 +76,15 @@ NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *req)
}
in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
+ in_security_mode = CVAL(inbody, 0x03);
in_security_buffer.data = (uint8_t *)req->in.vector[i+2].iov_base;
in_security_buffer.length = in_security_length;
status = smbd_smb2_session_setup(req,
in_session_id,
+ in_security_mode,
in_security_buffer,
+ &out_session_flags,
&out_security_buffer,
&out_session_id);
if (!NT_STATUS_IS_OK(status) &&
@@ -98,7 +105,8 @@ NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *req)
SBVAL(outhdr, SMB2_HDR_SESSION_ID, out_session_id);
SSVAL(outbody.data, 0x00, 0x08 + 1); /* struct size */
- SSVAL(outbody.data, 0x02, 0); /* session flags */
+ SSVAL(outbody.data, 0x02,
+ out_session_flags); /* session flags */
SSVAL(outbody.data, 0x04,
out_security_offset); /* security buffer offset */
SSVAL(outbody.data, 0x06,
@@ -132,13 +140,17 @@ static int smbd_smb2_session_destructor(struct smbd_smb2_session *session)
static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req,
uint64_t in_session_id,
+ uint8_t in_security_mode,
DATA_BLOB in_security_buffer,
+ uint16_t *out_session_flags,
DATA_BLOB *out_security_buffer,
uint64_t *out_session_id)
{
struct smbd_smb2_session *session;
NTSTATUS status;
+ *out_session_flags = 0;
+
if (in_session_id == 0) {
int id;
@@ -185,6 +197,7 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req,
if (session->auth_ntlmssp_state == NULL) {
status = auth_ntlmssp_start(&session->auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(session);
return status;
}
}
@@ -193,19 +206,54 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req,
in_security_buffer,
out_security_buffer);
if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- /* nothing to do */
- } else if (NT_STATUS_IS_OK(status)) {
- /* TODO: setup session key for signing */
- session->status = NT_STATUS_OK;
- /*
- * we attach the session to the request
- * so that the response can be signed
- */
- req->session = session;
- } else {
+ *out_session_id = session->vuid;
+ return status;
+ } else if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(session);
return status;
}
+ /* TODO: setup session key for signing */
+
+ if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) ||
+ lp_server_signing() == Required) {
+ session->do_signing = true;
+ }
+
+ if (session->auth_ntlmssp_state->server_info->guest) {
+ /* we map anonymous to guest internally */
+ *out_session_flags |= SMB2_SESSION_FLAG_IS_GUEST;
+ *out_session_flags |= SMB2_SESSION_FLAG_IS_NULL;
+ /* force no signing */
+ session->do_signing = false;
+ }
+
+ session->server_info = session->auth_ntlmssp_state->server_info;
+ data_blob_free(&session->server_info->user_session_key);
+ session->server_info->user_session_key =
+ data_blob_talloc(
+ session->server_info,
+ session->auth_ntlmssp_state->ntlmssp_state->session_key.data,
+ session->auth_ntlmssp_state->ntlmssp_state->session_key.length);
+ if (session->auth_ntlmssp_state->ntlmssp_state->session_key.length > 0) {
+ if (session->server_info->user_session_key.data == NULL) {
+ TALLOC_FREE(session);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+ session->session_key = session->server_info->user_session_key;
+
+ session->status = NT_STATUS_OK;
+
+ /*
+ * we attach the session to the request
+ * so that the response can be signed
+ */
+ req->session = session;
+ if (session->do_signing) {
+ req->do_signing = true;
+ }
+
*out_session_id = session->vuid;
return status;
}
diff --git a/source3/smbd/smb2_signing.c b/source3/smbd/smb2_signing.c
new file mode 100644
index 0000000000..55ed4f6d1c
--- /dev/null
+++ b/source3/smbd/smb2_signing.c
@@ -0,0 +1,135 @@
+/*
+ Unix SMB/CIFS implementation.
+ SMB2 signing
+
+ Copyright (C) Stefan Metzmacher 2009
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "smbd/globals.h"
+#include "../source4/libcli/smb2/smb2_constants.h"
+#include "../lib/crypto/crypto.h"
+
+NTSTATUS smb2_signing_sign_pdu(DATA_BLOB session_key,
+ struct iovec *vector,
+ int count)
+{
+ uint8_t *hdr;
+ uint64_t session_id;
+ struct HMACSHA256Context m;
+ uint8_t res[SHA256_DIGEST_LENGTH];
+ int i;
+
+ if (count < 2) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (vector[0].iov_len != SMB2_HDR_BODY) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ hdr = (uint8_t *)vector[0].iov_base;
+
+ session_id = BVAL(hdr, SMB2_HDR_SESSION_ID);
+ if (session_id == 0) {
+ /*
+ * do not sign messages with a zero session_id.
+ * See MS-SMB2 3.2.4.1.1
+ */
+ return NT_STATUS_OK;
+ }
+
+ if (session_key.length == 0) {
+ DEBUG(2,("Wrong session key length %u for SMB2 signing\n",
+ (unsigned)session_key.length));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ memset(hdr + SMB2_HDR_SIGNATURE, 0, 16);
+
+ SIVAL(hdr, SMB2_HDR_FLAGS, IVAL(hdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_SIGNED);
+
+ ZERO_STRUCT(m);
+ hmac_sha256_init(session_key.data, MIN(session_key.length, 16), &m);
+ for (i=0; i < count; i++) {
+ hmac_sha256_update((const uint8_t *)vector[i].iov_base,
+ vector[i].iov_len, &m);
+ }
+ hmac_sha256_final(res, &m);
+ DEBUG(5,("signed SMB2 message\n"));
+
+ memcpy(hdr + SMB2_HDR_SIGNATURE, res, 16);
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS smb2_signing_check_pdu(DATA_BLOB session_key,
+ const struct iovec *vector,
+ int count)
+{
+ const uint8_t *hdr;
+ const uint8_t *sig;
+ uint64_t session_id;
+ struct HMACSHA256Context m;
+ uint8_t res[SHA256_DIGEST_LENGTH];
+ static const uint8_t zero_sig[16];
+ int i;
+
+ if (count < 2) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (vector[0].iov_len != SMB2_HDR_BODY) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ hdr = (const uint8_t *)vector[0].iov_base;
+
+ session_id = BVAL(hdr, SMB2_HDR_SESSION_ID);
+ if (session_id == 0) {
+ /*
+ * do not sign messages with a zero session_id.
+ * See MS-SMB2 3.2.4.1.1
+ */
+ return NT_STATUS_OK;
+ }
+
+ if (session_key.length == 0) {
+ /* we don't have the session key yet */
+ return NT_STATUS_OK;
+ }
+
+ sig = hdr+SMB2_HDR_SIGNATURE;
+
+ ZERO_STRUCT(m);
+ hmac_sha256_init(session_key.data, MIN(session_key.length, 16), &m);
+ hmac_sha256_update(hdr, SMB2_HDR_SIGNATURE, &m);
+ hmac_sha256_update(zero_sig, 16, &m);
+ for (i=1; i < count; i++) {
+ hmac_sha256_update((const uint8_t *)vector[i].iov_base,
+ vector[i].iov_len, &m);
+ }
+ hmac_sha256_final(res, &m);
+
+ if (memcmp(res, sig, 16) != 0) {
+ DEBUG(0,("Bad SMB2 signature for message\n"));
+ dump_data(0, sig, 16);
+ dump_data(0, res, 16);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_OK;
+}
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 1748cfa0b8..1d95c207ba 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -1015,8 +1015,8 @@ static void call_trans2open(connection_struct *conn,
size = get_file_size_stat(&sbuf);
fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
- mtime = sbuf.st_mtime;
- inode = sbuf.st_ino;
+ mtime = convert_timespec_to_time_t(sbuf.st_ex_mtime);
+ inode = sbuf.st_ex_ino;
if (fattr & aDIR) {
close_file(req, fsp, ERROR_CLOSE);
reply_doserror(req, ERRDOS,ERRnoaccess);
@@ -1136,7 +1136,7 @@ static NTSTATUS unix_perms_from_wire( connection_struct *conn,
if (!VALID_STAT(*psbuf)) {
return NT_STATUS_INVALID_PARAMETER;
} else {
- *ret_perms = psbuf->st_mode;
+ *ret_perms = psbuf->st_ex_mode;
return NT_STATUS_OK;
}
}
@@ -1207,7 +1207,7 @@ static bool check_msdfs_link(connection_struct *conn,
DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
"as a directory\n",
pathname));
- psbuf->st_mode = (psbuf->st_mode & 0xFFF) | S_IFDIR;
+ psbuf->st_ex_mode = (psbuf->st_ex_mode & 0xFFF) | S_IFDIR;
errno = saved_errno;
return true;
}
@@ -1417,10 +1417,9 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
}
allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,NULL,&sbuf);
- mdate_ts = get_mtimespec(&sbuf);
- adate_ts = get_atimespec(&sbuf);
- create_date_ts = get_create_timespec(&sbuf,
- lp_fake_dir_create_times(SNUM(conn)));
+ mdate_ts = sbuf.st_ex_mtime;
+ adate_ts = sbuf.st_ex_atime;
+ create_date_ts = sbuf.st_ex_btime;
if (ask_sharemode) {
struct timespec write_time_ts;
@@ -1737,8 +1736,8 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
p +=4;
}
SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
- SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */
- SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */
+ SIVAL(p,0,sbuf.st_ex_ino); p += 4; /* FileIndexLow */
+ SIVAL(p,0,sbuf.st_ex_dev); p += 4; /* FileIndexHigh */
len = srvstr_push(base_data, flags2, p,
fname, PTR_DIFF(end_data, p),
STR_TERMINATE_ASCII);
@@ -1793,8 +1792,8 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
}
p += 26;
SSVAL(p,0,0); p += 2; /* Reserved ? */
- SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */
- SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */
+ SIVAL(p,0,sbuf.st_ex_ino); p += 4; /* FileIndexLow */
+ SIVAL(p,0,sbuf.st_ex_dev); p += 4; /* FileIndexHigh */
len = srvstr_push(base_data, flags2, p,
fname, PTR_DIFF(end_data, p),
STR_TERMINATE_ASCII);
@@ -2579,7 +2578,7 @@ static void call_trans2qfsinfo(connection_struct *conn,
int snum = SNUM(conn);
char *fstype = lp_fstype(SNUM(conn));
uint32 additional_flags = 0;
-
+
if (total_params < 2) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
@@ -2654,10 +2653,10 @@ static void call_trans2qfsinfo(connection_struct *conn,
sectors_per_unit = bsize/bytes_per_sector;
DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
-cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
+cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
(unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
- SIVAL(pdata,l1_idFileSystem,st.st_dev);
+ SIVAL(pdata,l1_idFileSystem,st.st_ex_dev);
SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
SIVAL(pdata,l1_cUnit,dsize);
SIVAL(pdata,l1_cUnitAvail,dfree);
@@ -2686,7 +2685,8 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsi
SCVAL(pdata,l2_vol_cch,len);
data_len = l2_vol_szVolLabel + len;
DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
- (unsigned)st.st_ctime, len, vname));
+ (unsigned)convert_timespec_to_time_t(st.st_ex_ctime),
+ len, vname));
break;
case SMB_QUERY_FS_ATTRIBUTE_INFO:
@@ -2849,13 +2849,13 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
*/
files_struct fsp;
SMB_NTQUOTA_STRUCT quotas;
-
+
ZERO_STRUCT(fsp);
ZERO_STRUCT(quotas);
-
+
fsp.conn = conn;
fsp.fnum = -1;
-
+
/* access check */
if (conn->server_info->utok.uid != 0) {
DEBUG(0,("set_user_quota: access_denied "
@@ -2865,7 +2865,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
reply_doserror(req, ERRDOS, ERRnoaccess);
return;
}
-
+
if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
reply_doserror(req, ERRSRV, ERRerror);
@@ -2875,25 +2875,25 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
data_len = 48;
DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
-
+
/* Unknown1 24 NULL bytes*/
SBIG_UINT(pdata,0,(uint64_t)0);
SBIG_UINT(pdata,8,(uint64_t)0);
SBIG_UINT(pdata,16,(uint64_t)0);
-
+
/* Default Soft Quota 8 bytes */
SBIG_UINT(pdata,24,quotas.softlim);
/* Default Hard Quota 8 bytes */
SBIG_UINT(pdata,32,quotas.hardlim);
-
+
/* Quota flag 2 bytes */
SSVAL(pdata,40,quotas.qflags);
-
+
/* Unknown3 6 NULL bytes */
SSVAL(pdata,42,0);
SIVAL(pdata,44,0);
-
+
break;
}
#endif /* HAVE_SYS_QUOTAS */
@@ -3300,7 +3300,7 @@ cap_low = 0x%x, cap_high = 0x%x\n",
{
files_struct *fsp = NULL;
SMB_NTQUOTA_STRUCT quotas;
-
+
ZERO_STRUCT(quotas);
/* access check */
@@ -3335,9 +3335,9 @@ cap_low = 0x%x, cap_high = 0x%x\n",
NT_STATUS_INVALID_PARAMETER);
return;
}
-
+
/* unknown_1 24 NULL bytes in pdata*/
-
+
/* the soft quotas 8 bytes (uint64_t)*/
quotas.softlim = (uint64_t)IVAL(pdata,24);
#ifdef LARGE_SMB_OFF_T
@@ -3353,7 +3353,7 @@ cap_low = 0x%x, cap_high = 0x%x\n",
return;
}
#endif /* LARGE_SMB_OFF_T */
-
+
/* the hard quotas 8 bytes (uint64_t)*/
quotas.hardlim = (uint64_t)IVAL(pdata,32);
#ifdef LARGE_SMB_OFF_T
@@ -3369,19 +3369,19 @@ cap_low = 0x%x, cap_high = 0x%x\n",
return;
}
#endif /* LARGE_SMB_OFF_T */
-
+
/* quota_flags 2 bytes **/
quotas.qflags = SVAL(pdata,40);
-
+
/* unknown_2 6 NULL bytes follow*/
-
+
/* now set the quotas */
if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
reply_doserror(req, ERRSRV, ERRerror);
return;
}
-
+
break;
}
default:
@@ -3461,7 +3461,7 @@ static bool marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_
switch (tagtype) {
case SMB_ACL_USER_OBJ:
SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
- own_grp = (unsigned int)pst->st_uid;
+ own_grp = (unsigned int)pst->st_ex_uid;
SIVAL(pdata,2,own_grp);
SIVAL(pdata,6,0);
break;
@@ -3481,7 +3481,7 @@ static bool marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_
}
case SMB_ACL_GROUP_OBJ:
SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
- own_grp = (unsigned int)pst->st_gid;
+ own_grp = (unsigned int)pst->st_ex_gid;
SIVAL(pdata,2,own_grp);
SIVAL(pdata,6,0);
break;
@@ -3530,7 +3530,7 @@ static char *store_file_unix_basic(connection_struct *conn,
const SMB_STRUCT_STAT *psbuf)
{
DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
- DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_mode));
+ DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_ex_mode));
SOFF_T(pdata,0,get_file_size_stat(psbuf)); /* File size 64 Bit */
pdata += 8;
@@ -3538,38 +3538,38 @@ static char *store_file_unix_basic(connection_struct *conn,
SOFF_T(pdata,0,SMB_VFS_GET_ALLOC_SIZE(conn,fsp,psbuf)); /* Number of bytes used on disk - 64 Bit */
pdata += 8;
- put_long_date_timespec(pdata,get_ctimespec(psbuf)); /* Change Time 64 Bit */
- put_long_date_timespec(pdata+8,get_atimespec(psbuf)); /* Last access time 64 Bit */
- put_long_date_timespec(pdata+16,get_mtimespec(psbuf)); /* Last modification time 64 Bit */
+ put_long_date_timespec(pdata, psbuf->st_ex_ctime); /* Change Time 64 Bit */
+ put_long_date_timespec(pdata+8, psbuf->st_ex_atime); /* Last access time 64 Bit */
+ put_long_date_timespec(pdata+16, psbuf->st_ex_mtime); /* Last modification time 64 Bit */
pdata += 24;
- SIVAL(pdata,0,psbuf->st_uid); /* user id for the owner */
+ SIVAL(pdata,0,psbuf->st_ex_uid); /* user id for the owner */
SIVAL(pdata,4,0);
pdata += 8;
- SIVAL(pdata,0,psbuf->st_gid); /* group id of owner */
+ SIVAL(pdata,0,psbuf->st_ex_gid); /* group id of owner */
SIVAL(pdata,4,0);
pdata += 8;
- SIVAL(pdata,0,unix_filetype(psbuf->st_mode));
+ SIVAL(pdata,0,unix_filetype(psbuf->st_ex_mode));
pdata += 4;
- SIVAL(pdata,0,unix_dev_major(psbuf->st_rdev)); /* Major device number if type is device */
+ SIVAL(pdata,0,unix_dev_major(psbuf->st_ex_rdev)); /* Major device number if type is device */
SIVAL(pdata,4,0);
pdata += 8;
- SIVAL(pdata,0,unix_dev_minor(psbuf->st_rdev)); /* Minor device number if type is device */
+ SIVAL(pdata,0,unix_dev_minor(psbuf->st_ex_rdev)); /* Minor device number if type is device */
SIVAL(pdata,4,0);
pdata += 8;
- SINO_T_VAL(pdata,0,(SMB_INO_T)psbuf->st_ino); /* inode number */
+ SINO_T_VAL(pdata,0,(SMB_INO_T)psbuf->st_ex_ino); /* inode number */
pdata += 8;
-
- SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_mode)); /* Standard UNIX file permissions */
+
+ SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_ex_mode)); /* Standard UNIX file permissions */
SIVAL(pdata,4,0);
pdata += 8;
- SIVAL(pdata,0,psbuf->st_nlink); /* number of hard links */
+ SIVAL(pdata,0,psbuf->st_ex_nlink); /* number of hard links */
SIVAL(pdata,4,0);
pdata += 8;
@@ -3613,16 +3613,14 @@ static const struct {unsigned stat_fflag; unsigned smb_fflag;}
static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT *psbuf,
uint32 *smb_fflags, uint32 *smb_fmask)
{
-#ifdef HAVE_STAT_ST_FLAGS
int i;
for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
*smb_fmask |= info2_flags_map[i].smb_fflag;
- if (psbuf->st_flags & info2_flags_map[i].stat_fflag) {
+ if (psbuf->st_ex_flags & info2_flags_map[i].stat_fflag) {
*smb_fflags |= info2_flags_map[i].smb_fflag;
}
}
-#endif /* HAVE_STAT_ST_FLAGS */
}
static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf,
@@ -3630,11 +3628,10 @@ static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf,
const uint32 smb_fmask,
int *stat_fflags)
{
-#ifdef HAVE_STAT_ST_FLAGS
uint32 max_fmask = 0;
int i;
- *stat_fflags = psbuf->st_flags;
+ *stat_fflags = psbuf->st_ex_flags;
/* For each flags requested in smb_fmask, check the state of the
* corresponding flag in smb_fflags and set or clear the matching
@@ -3660,9 +3657,6 @@ static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf,
}
return True;
-#else
- return False;
-#endif /* HAVE_STAT_ST_FLAGS */
}
@@ -3680,7 +3674,7 @@ static char *store_file_unix_basic_info2(connection_struct *conn,
pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
/* Create (birth) time 64 bit */
- put_long_date_timespec(pdata, get_create_timespec(psbuf, False));
+ put_long_date_timespec(pdata, psbuf->st_ex_btime);
pdata += 8;
map_info2_flags_from_sbuf(psbuf, &file_flags, &flags_mask);
@@ -4101,7 +4095,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
if (!mode)
mode = FILE_ATTRIBUTE_NORMAL;
- nlink = sbuf.st_nlink;
+ nlink = sbuf.st_ex_nlink;
if (nlink && (mode&aDIR)) {
nlink = 1;
@@ -4195,9 +4189,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
dstart = pdata;
dend = dstart + data_size - 1;
- create_time_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
- mtime_ts = get_mtimespec(&sbuf);
- atime_ts = get_atimespec(&sbuf);
+ create_time_ts = sbuf.st_ex_btime;
+ mtime_ts = sbuf.st_ex_mtime;
+ atime_ts = sbuf.st_ex_atime;
allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf);
@@ -4454,8 +4448,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
BasicFileInformationTest. -tpot */
DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
- SIVAL(pdata,0,sbuf.st_ino); /* FileIndexLow */
- SIVAL(pdata,4,sbuf.st_dev); /* FileIndexHigh */
+ SIVAL(pdata,0,sbuf.st_ex_ino); /* FileIndexLow */
+ SIVAL(pdata,4,sbuf.st_ex_dev); /* FileIndexHigh */
data_size = 8;
break;
@@ -4624,7 +4618,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
#ifdef S_ISLNK
- if(!S_ISLNK(sbuf.st_mode)) {
+ if(!S_ISLNK(sbuf.st_ex_mode)) {
reply_unixerror(req, ERRSRV,
ERRbadlink);
return;
@@ -4674,7 +4668,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
return;
}
- if (S_ISDIR(sbuf.st_mode)) {
+ if (S_ISDIR(sbuf.st_ex_mode)) {
if (fsp && fsp->is_directory) {
def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
} else {
@@ -4890,7 +4884,7 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
}
/* No links from a directory. */
- if (S_ISDIR(smb_fname->st.st_mode)) {
+ if (S_ISDIR(smb_fname->st.st_ex_mode)) {
status = NT_STATUS_FILE_IS_A_DIRECTORY;
goto out;
}
@@ -4935,12 +4929,12 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
/* get some defaults (no modifications) if any info is zero or -1. */
if (null_timespec(ft->atime)) {
- ft->atime= get_atimespec(psbuf);
+ ft->atime= psbuf->st_ex_atime;
action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS;
}
if (null_timespec(ft->mtime)) {
- ft->mtime = get_mtimespec(psbuf);
+ ft->mtime = psbuf->st_ex_mtime;
action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
}
@@ -4964,8 +4958,8 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
*/
{
- struct timespec mts = get_mtimespec(psbuf);
- struct timespec ats = get_atimespec(psbuf);
+ struct timespec mts = psbuf->st_ex_mtime;
+ struct timespec ats = psbuf->st_ex_atime;
if ((timespec_compare(&ft->atime, &ats) == 0) &&
(timespec_compare(&ft->mtime, &mts) == 0)) {
return NT_STATUS_OK;
@@ -5035,9 +5029,9 @@ static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
fname = fsp->fsp_name;
}
}
-
+
if (dosmode) {
- if (S_ISDIR(psbuf->st_mode)) {
+ if (S_ISDIR(psbuf->st_ex_mode)) {
dosmode |= aDIR;
} else {
dosmode &= ~aDIR;
@@ -6099,7 +6093,7 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
raw_unixmode = IVAL(pdata,84);
if (VALID_STAT(*psbuf)) {
- if (S_ISDIR(psbuf->st_mode)) {
+ if (S_ISDIR(psbuf->st_ex_mode)) {
ptype = PERM_EXISTING_DIR;
} else {
ptype = PERM_EXISTING_FILE;
@@ -6136,8 +6130,8 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
/* Ensure we don't try and change anything else. */
raw_unixmode = SMB_MODE_NO_CHANGE;
size = get_file_size_stat(psbuf);
- ft.atime = get_atimespec(psbuf);
- ft.mtime = get_mtimespec(psbuf);
+ ft.atime = psbuf->st_ex_atime;
+ ft.mtime = psbuf->st_ex_mtime;
/*
* We continue here as we might want to change the
* owner uid/gid.
@@ -6171,13 +6165,13 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
* Deal with the UNIX specific uid set.
*/
- if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (psbuf->st_uid != set_owner)) {
+ if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (psbuf->st_ex_uid != set_owner)) {
int ret;
DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC changing owner %u for path %s\n",
(unsigned int)set_owner, fname ));
- if (S_ISLNK(psbuf->st_mode)) {
+ if (S_ISLNK(psbuf->st_ex_mode)) {
ret = SMB_VFS_LCHOWN(conn, fname, set_owner, (gid_t)-1);
} else {
ret = SMB_VFS_CHOWN(conn, fname, set_owner, (gid_t)-1);
@@ -6196,7 +6190,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
* Deal with the UNIX specific gid set.
*/
- if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (psbuf->st_gid != set_grp)) {
+ if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (psbuf->st_ex_gid != set_grp)) {
DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
(unsigned int)set_owner, fname ));
if (SMB_VFS_CHOWN(conn, fname, (uid_t)-1, set_grp) != 0) {
@@ -7123,7 +7117,6 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
return;
}
-
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
/* We have re-scheduled this call. */
@@ -7150,7 +7143,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
SSVAL(params,0,0);
send_trans2_replies(conn, req, params, 2, *ppdata, data_return_size,
max_data_bytes);
-
+
return;
}
@@ -7253,7 +7246,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
reply_nterror(req, status);
return;
}
-
+
/* Try and set any given EA. */
if (ea_list) {
status = set_ea(conn, NULL, directory, ea_list);
@@ -7274,7 +7267,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
SSVAL(params,0,0);
send_trans2_replies(conn, req, params, 2, *ppdata, 0, max_data_bytes);
-
+
return;
}
@@ -7327,7 +7320,7 @@ static void call_trans2findnotifyfirst(connection_struct *conn,
fnf_handle = 257;
send_trans2_replies(conn, req, params, 6, *ppdata, 0, max_data_bytes);
-
+
return;
}
@@ -7358,7 +7351,7 @@ static void call_trans2findnotifynext(connection_struct *conn,
SSVAL(params,2,0); /* No EA errors */
send_trans2_replies(conn, req, params, 4, *ppdata, 0, max_data_bytes);
-
+
return;
}
@@ -7508,7 +7501,7 @@ void reply_findnclose(struct smb_request *req)
END_PROFILE(SMBfindnclose);
return;
}
-
+
dptr_num = SVAL(req->vwv+0, 0);
DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
@@ -7928,7 +7921,7 @@ void reply_transs2(struct smb_request *req)
state->received_param += pcnt;
state->received_data += dcnt;
-
+
if ((state->received_data > state->total_data) ||
(state->received_param > state->total_param))
goto bad_param;
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index f219e5554c..0f70669772 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -353,7 +353,7 @@ bool vfs_directory_exist(connection_struct *conn, const char *dname, SMB_STRUCT_
if (SMB_VFS_STAT(conn,dname,st) != 0)
return(False);
- ret = S_ISDIR(st->st_mode);
+ ret = S_ISDIR(st->st_ex_mode);
if(!ret)
errno = ENOTDIR;
@@ -393,7 +393,7 @@ bool vfs_file_exist(connection_struct *conn, const char *fname,SMB_STRUCT_STAT *
if (SMB_VFS_STAT(conn,fname,sbuf) == -1)
return False;
- return(S_ISREG(sbuf->st_mode));
+ return(S_ISREG(sbuf->st_ex_mode));
}
/****************************************************************************
@@ -542,14 +542,14 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
if (ret == -1)
return ret;
- if (len == (uint64_t)st.st_size)
+ if (len == (uint64_t)st.st_ex_size)
return 0;
- if (len < (uint64_t)st.st_size) {
+ if (len < (uint64_t)st.st_ex_size) {
/* Shrink - use ftruncate. */
DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current size %.0f\n",
- fsp->fsp_name, (double)st.st_size ));
+ fsp->fsp_name, (double)st.st_ex_size ));
contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
@@ -571,7 +571,7 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
if (!lp_strict_allocate(SNUM(fsp->conn)))
return 0;
- len -= st.st_size;
+ len -= st.st_ex_size;
len /= 1024; /* Len is now number of 1k blocks needed. */
space_avail = get_dfree_info(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize);
if (space_avail == (uint64_t)-1) {
@@ -579,7 +579,7 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
}
DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, needed blocks = %.0f, space avail = %.0f\n",
- fsp->fsp_name, (double)st.st_size, (double)len, (double)space_avail ));
+ fsp->fsp_name, (double)st.st_ex_size, (double)len, (double)space_avail ));
if (len > space_avail) {
errno = ENOSPC;
@@ -639,12 +639,12 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
return ret;
}
- if (len <= st.st_size) {
+ if (len <= st.st_ex_size) {
return 0;
}
DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to len %.0f (%.0f bytes)\n",
- fsp->fsp_name, (double)st.st_size, (double)len, (double)(len - st.st_size)));
+ fsp->fsp_name, (double)st.st_ex_size, (double)len, (double)(len - st.st_ex_size)));
contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
@@ -659,8 +659,8 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
}
}
- offset = st.st_size;
- num_to_write = len - st.st_size;
+ offset = st.st_ex_size;
+ num_to_write = len - st.st_ex_size;
total = 0;
while (total < num_to_write) {
@@ -816,8 +816,8 @@ char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
&& (cache_value.data[cache_value.length-1] == '\0'));
if ((SMB_VFS_STAT(conn, (char *)cache_value.data, &st2) == 0)
- && (st.st_dev == st2.st_dev) && (st.st_ino == st2.st_ino)
- && (S_ISDIR(st.st_mode))) {
+ && (st.st_ex_dev == st2.st_ex_dev) && (st.st_ex_ino == st2.st_ex_ino)
+ && (S_ISDIR(st.st_ex_mode))) {
/*
* Ok, we're done
*/
@@ -973,7 +973,7 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
if (!lp_symlinks(SNUM(conn))) {
SMB_STRUCT_STAT statbuf;
if ( (SMB_VFS_LSTAT(conn,fname,&statbuf) != -1) &&
- (S_ISLNK(statbuf.st_mode)) ) {
+ (S_ISLNK(statbuf.st_ex_mode)) ) {
if (free_resolved_name) {
SAFE_FREE(resolved_name);
}