diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/close.c | 2 | ||||
-rw-r--r-- | source3/smbd/dir.c | 12 | ||||
-rw-r--r-- | source3/smbd/dosmode.c | 69 | ||||
-rw-r--r-- | source3/smbd/file_access.c | 14 | ||||
-rw-r--r-- | source3/smbd/fileio.c | 2 | ||||
-rw-r--r-- | source3/smbd/filename.c | 2 | ||||
-rw-r--r-- | source3/smbd/globals.c | 1 | ||||
-rw-r--r-- | source3/smbd/globals.h | 20 | ||||
-rw-r--r-- | source3/smbd/msdfs.c | 2 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 28 | ||||
-rw-r--r-- | source3/smbd/open.c | 56 | ||||
-rw-r--r-- | source3/smbd/posix_acls.c | 58 | ||||
-rw-r--r-- | source3/smbd/process.c | 18 | ||||
-rw-r--r-- | source3/smbd/reply.c | 71 | ||||
-rw-r--r-- | source3/smbd/server.c | 19 | ||||
-rw-r--r-- | source3/smbd/service.c | 4 | ||||
-rw-r--r-- | source3/smbd/signing.c | 26 | ||||
-rw-r--r-- | source3/smbd/smb2_negprot.c | 23 | ||||
-rw-r--r-- | source3/smbd/smb2_server.c | 116 | ||||
-rw-r--r-- | source3/smbd/smb2_sesssetup.c | 70 | ||||
-rw-r--r-- | source3/smbd/smb2_signing.c | 135 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 165 | ||||
-rw-r--r-- | source3/smbd/vfs.c | 28 |
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(¤t_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(¤t_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, "as)!=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, "as)!=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); } |