summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h8
-rw-r--r--source3/rpc_server/srv_srvsvc_nt.c19
-rw-r--r--source3/smbd/dosmode.c28
-rw-r--r--source3/smbd/file_access.c11
-rw-r--r--source3/smbd/nttrans.c40
-rw-r--r--source3/smbd/open.c1
-rw-r--r--source3/smbd/posix_acls.c31
-rw-r--r--source3/smbd/reply.c36
8 files changed, 72 insertions, 102 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 6fc28259d6..598d83aee6 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -6290,9 +6290,9 @@ bool smbd_setup_mdns_registration(struct tevent_context *ev,
mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname,
const char *inherit_from_dir);
-uint32 dos_mode_msdfs(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf);
+uint32 dos_mode_msdfs(connection_struct *conn, const char *path, const SMB_STRUCT_STAT *sbuf);
int dos_attributes_to_stat_dos_flags(uint32_t dosmode);
-uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf);
+uint32 dos_mode(connection_struct *conn, const char *path, const SMB_STRUCT_STAT *sbuf);
int file_set_dosmode(connection_struct *conn, const char *fname,
uint32 dosmode, SMB_STRUCT_STAT *st,
const char *parent_dir,
@@ -6339,8 +6339,8 @@ bool can_access_file_acl(struct connection_struct *conn,
uint32_t access_mask);
bool can_delete_file_in_directory(connection_struct *conn,
const struct smb_filename *smb_fname);
-bool can_access_file_data(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf, uint32 access_mask);
-bool can_write_to_file(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf);
+bool can_access_file_data(connection_struct *conn, const char *fname, const SMB_STRUCT_STAT *psbuf, uint32 access_mask);
+bool can_write_to_file(connection_struct *conn, const char *fname, const SMB_STRUCT_STAT *psbuf);
bool directory_has_default_acl(connection_struct *conn, const char *fname);
/* The following definitions come from smbd/fileio.c */
diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c
index 1b07fc213e..070f7fd0ca 100644
--- a/source3/rpc_server/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srv_srvsvc_nt.c
@@ -2067,23 +2067,17 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
goto error_exit;
}
- nt_status = resolve_dfspath(talloc_tos(),
+ nt_status = filename_convert(talloc_tos(),
conn,
false,
r->in.file,
+ &smb_fname,
&fname);
if (!NT_STATUS_IS_OK(nt_status)) {
werr = ntstatus_to_werror(nt_status);
goto error_exit;
}
- nt_status = unix_convert(talloc_tos(), conn, fname, &smb_fname,
- 0);
- if (!NT_STATUS_IS_OK(nt_status)) {
- werr = ntstatus_to_werror(nt_status);
- goto error_exit;
- }
-
nt_status = SMB_VFS_CREATE_FILE(
conn, /* conn */
NULL, /* req */
@@ -2203,21 +2197,16 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
goto error_exit;
}
- nt_status = resolve_dfspath(talloc_tos(),
+ nt_status = filename_convert(talloc_tos(),
conn,
false,
r->in.file,
+ &smb_fname,
&fname);
if (!NT_STATUS_IS_OK(nt_status)) {
werr = ntstatus_to_werror(nt_status);
goto error_exit;
}
- nt_status = unix_convert(talloc_tos(), conn, fname, &smb_fname,
- 0);
- if (!NT_STATUS_IS_OK(nt_status)) {
- werr = ntstatus_to_werror(nt_status);
- goto error_exit;
- }
nt_status = SMB_VFS_CREATE_FILE(
conn, /* conn */
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index eeed76329c..8149eea7f5 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -140,7 +140,7 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname,
Change a unix mode to a dos mode.
****************************************************************************/
-static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf)
+static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, const SMB_STRUCT_STAT *sbuf)
{
int result = 0;
enum mapreadonly_options ro_opts = (enum mapreadonly_options)lp_map_readonly(SNUM(conn));
@@ -188,7 +188,7 @@ static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_
Get DOS attributes from an EA.
****************************************************************************/
-static bool get_ea_dos_attribute(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf, uint32 *pattr)
+static bool get_ea_dos_attribute(connection_struct *conn, const char *path, const SMB_STRUCT_STAT *sbuf, uint32 *pattr)
{
ssize_t sizeret;
fstring attrstr;
@@ -306,13 +306,14 @@ static bool set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_
Change a unix mode to a dos mode for an ms dfs link.
****************************************************************************/
-uint32 dos_mode_msdfs(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
+uint32 dos_mode_msdfs(connection_struct *conn, const char *path, const SMB_STRUCT_STAT *psbuf)
{
+ SMB_STRUCT_STAT sbuf = *psbuf;
uint32 result = 0;
DEBUG(8,("dos_mode_msdfs: %s\n", path));
- if (!VALID_STAT(*sbuf)) {
+ if (!VALID_STAT(sbuf)) {
return 0;
}
@@ -333,7 +334,7 @@ uint32 dos_mode_msdfs(connection_struct *conn, const char *path,SMB_STRUCT_STAT
}
}
- result |= dos_mode_from_sbuf(conn, path, sbuf);
+ result |= dos_mode_from_sbuf(conn, path, &sbuf);
/* Optimization : Only call is_hidden_path if it's not already
hidden. */
@@ -466,14 +467,15 @@ static bool set_stat_dos_flags(connection_struct *conn,
Change a unix mode to a dos mode.
****************************************************************************/
-uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
+uint32 dos_mode(connection_struct *conn, const char *path, const SMB_STRUCT_STAT *psbuf)
{
+ SMB_STRUCT_STAT sbuf = *psbuf;
uint32 result = 0;
bool offline, used_stat_dos_flags = false;
DEBUG(8,("dos_mode: %s\n", path));
- if (!VALID_STAT(*sbuf)) {
+ if (!VALID_STAT(sbuf)) {
return 0;
}
@@ -495,19 +497,19 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
}
#ifdef HAVE_STAT_DOS_FLAGS
- used_stat_dos_flags = get_stat_dos_flags(conn, path, sbuf, &result);
+ used_stat_dos_flags = get_stat_dos_flags(conn, path, &sbuf, &result);
#endif
if (!used_stat_dos_flags) {
/* Get the DOS attributes from an EA by preference. */
- if (get_ea_dos_attribute(conn, path, sbuf, &result)) {
- result |= set_sparse_flag(sbuf);
+ if (get_ea_dos_attribute(conn, path, &sbuf, &result)) {
+ result |= set_sparse_flag(&sbuf);
} else {
- result |= dos_mode_from_sbuf(conn, path, sbuf);
+ result |= dos_mode_from_sbuf(conn, path, &sbuf);
}
}
- offline = SMB_VFS_IS_OFFLINE(conn, path, sbuf);
- if (S_ISREG(sbuf->st_ex_mode) && offline) {
+ offline = SMB_VFS_IS_OFFLINE(conn, path, &sbuf);
+ if (S_ISREG(sbuf.st_ex_mode) && offline) {
result |= FILE_ATTRIBUTE_OFFLINE;
}
diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c
index 8b282e25b6..195f722471 100644
--- a/source3/smbd/file_access.c
+++ b/source3/smbd/file_access.c
@@ -155,7 +155,7 @@ bool can_delete_file_in_directory(connection_struct *conn,
Note this doesn't take into account share write permissions.
****************************************************************************/
-bool can_access_file_data(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf, uint32 access_mask)
+bool can_access_file_data(connection_struct *conn, const char *fname, const SMB_STRUCT_STAT *psbuf, uint32 access_mask)
{
if (!(access_mask & (FILE_READ_DATA|FILE_WRITE_DATA))) {
return False;
@@ -172,12 +172,7 @@ bool can_access_file_data(connection_struct *conn, const char *fname, SMB_STRUCT
return True;
}
- if (!VALID_STAT(*psbuf)) {
- /* Get the file permission mask and owners. */
- if(SMB_VFS_STAT(conn, fname, psbuf) != 0) {
- return False;
- }
- }
+ SMB_ASSERT(psbuf && VALID_STAT(*psbuf));
/* Check primary owner access. */
if (conn->server_info->utok.uid == psbuf->st_ex_uid) {
@@ -208,7 +203,7 @@ bool can_access_file_data(connection_struct *conn, const char *fname, SMB_STRUCT
Note this doesn't take into account share write permissions.
****************************************************************************/
-bool can_write_to_file(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf)
+bool can_write_to_file(connection_struct *conn, const char *fname, const SMB_STRUCT_STAT *psbuf)
{
return can_access_file_data(conn, fname, psbuf, FILE_WRITE_DATA);
}
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 73c062e69f..222caae516 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -1205,12 +1205,10 @@ void reply_ntcancel(struct smb_request *req)
static NTSTATUS copy_internals(TALLOC_CTX *ctx,
connection_struct *conn,
struct smb_request *req,
- const char *oldname_in,
- const char *newname_in,
+ struct smb_filename *smb_fname_src,
+ struct smb_filename *smb_fname_dst,
uint32 attrs)
{
- struct smb_filename *smb_fname_src = NULL;
- struct smb_filename *smb_fname_dst = NULL;
char *oldname = NULL;
char *newname = NULL;
files_struct *fsp1,*fsp2;
@@ -1225,16 +1223,6 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx,
goto out;
}
- status = unix_convert(ctx, conn, oldname_in, &smb_fname_src, 0);
- if (!NT_STATUS_IS_OK(status)) {
- goto out;
- }
-
- status = check_name(conn, smb_fname_src->base_name);
- if (!NT_STATUS_IS_OK(status)) {
- goto out;
- }
-
/* Source must already exist. */
if (!VALID_STAT(smb_fname_src->st)) {
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -1253,16 +1241,6 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx,
goto out;
}
- status = unix_convert(ctx, conn, newname_in, &smb_fname_dst, 0);
- if (!NT_STATUS_IS_OK(status)) {
- goto out;
- }
-
- status = check_name(conn, smb_fname_dst->base_name);
- if (!NT_STATUS_IS_OK(status)) {
- goto out;
- }
-
/* Disallow if dst file already exists. */
if (VALID_STAT(smb_fname_dst->st)) {
status = NT_STATUS_OBJECT_NAME_COLLISION;
@@ -1275,12 +1253,6 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx,
goto out;
}
- /* Ensure this is within the share. */
- status = check_reduced_name(conn, smb_fname_src->base_name);
- if (!NT_STATUS_IS_OK(status)) {
- goto out;
- }
-
DEBUG(10,("copy_internals: doing file copy %s to %s\n",
smb_fname_str_dbg(smb_fname_src),
smb_fname_str_dbg(smb_fname_dst)));
@@ -1374,8 +1346,6 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx,
smb_fname_str_dbg(smb_fname_dst)));
}
- TALLOC_FREE(smb_fname_src);
- TALLOC_FREE(smb_fname_dst);
TALLOC_FREE(oldname);
TALLOC_FREE(newname);
@@ -1501,8 +1471,10 @@ void reply_ntrename(struct smb_request *req)
/* No wildcards. */
status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
} else {
- status = copy_internals(ctx, conn, req, oldname,
- newname, attrs);
+ status = copy_internals(ctx, conn, req,
+ smb_fname_old,
+ smb_fname_new,
+ attrs);
}
break;
case RENAME_FLAG_MOVE_CLUSTER_INFORMATION:
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 5d82738f6a..d6331ee487 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -3401,7 +3401,6 @@ NTSTATUS create_file_default(connection_struct *conn,
uint64_t allocation_size,
struct security_descriptor *sd,
struct ea_list *ea_list,
-
files_struct **result,
int *pinfo)
{
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 2d0062ab94..6eed92cb3e 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -2548,9 +2548,8 @@ static bool current_user_in_group(gid_t gid)
static bool acl_group_override(connection_struct *conn,
gid_t prim_gid,
- const char *fname)
+ files_struct *fsp)
{
- SMB_STRUCT_STAT sbuf;
if ((errno != EPERM) && (errno != EACCES)) {
return false;
@@ -2563,9 +2562,23 @@ static bool acl_group_override(connection_struct *conn,
}
/* user has writeable permission */
- if (lp_dos_filemode(SNUM(conn)) &&
- can_write_to_file(conn, fname, &sbuf)) {
- return true;
+ if (lp_dos_filemode(SNUM(conn))) {
+ SMB_STRUCT_STAT sbuf;
+ int ret;
+
+ if (fsp->posix_open) {
+ ret = SMB_VFS_LSTAT(conn,fsp->fsp_name,&sbuf);
+ } else {
+ ret = SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf);
+ }
+
+ if (ret == -1) {
+ return false;
+ }
+
+ if (can_write_to_file(conn, fsp->fsp_name, &sbuf)) {
+ return true;
+ }
}
return false;
@@ -2754,7 +2767,7 @@ static bool set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, bool defau
*pacl_set_support = False;
}
- if (acl_group_override(conn, prim_gid, fsp->fsp_name)) {
+ if (acl_group_override(conn, prim_gid, fsp)) {
int sret;
DEBUG(5,("set_canon_ace_list: acl group control on and current user in file %s primary group.\n",
@@ -2785,7 +2798,7 @@ static bool set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, bool defau
*pacl_set_support = False;
}
- if (acl_group_override(conn, prim_gid, fsp->fsp_name)) {
+ if (acl_group_override(conn, prim_gid, fsp)) {
int sret;
DEBUG(5,("set_canon_ace_list: acl group control on and current user in file %s primary group.\n",
@@ -3831,7 +3844,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_ex_gid, fsp->fsp_name)) {
+ if (acl_group_override(conn, sbuf.st_ex_gid, fsp)) {
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 ));
@@ -3893,7 +3906,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_ex_gid, fsp->fsp_name)) {
+ if (acl_group_override(conn, sbuf.st_ex_gid, fsp)) {
DEBUG(5,("set_nt_acl: acl group control on and "
"current user in file %s primary group. Override chmod\n",
fsp->fsp_name ));
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index f11f3bfed7..9544b845da 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -1323,6 +1323,7 @@ static NTSTATUS split_fname_dir_mask(TALLOC_CTX *ctx, const char *fname_in,
void reply_search(struct smb_request *req)
{
connection_struct *conn = req->conn;
+ char *path = NULL;
const char *mask = NULL;
char *directory = NULL;
char *fname = NULL;
@@ -1335,7 +1336,6 @@ void reply_search(struct smb_request *req)
bool finished = False;
const char *p;
int status_len;
- char *path = NULL;
char status[21];
int dptr_num= -1;
bool check_descend = False;
@@ -1377,23 +1377,6 @@ void reply_search(struct smb_request *req)
return;
}
- nt_status = resolve_dfspath_wcard(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
- path,
- &path,
- &mask_contains_wcard);
- if (!NT_STATUS_IS_OK(nt_status)) {
- if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) {
- reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
- ERRSRV, ERRbadpath);
- END_PROFILE(SMBsearch);
- return;
- }
- reply_nterror(req, nt_status);
- END_PROFILE(SMBsearch);
- return;
- }
-
p++;
status_len = SVAL(p, 0);
p += 2;
@@ -1403,6 +1386,23 @@ void reply_search(struct smb_request *req)
if (status_len == 0) {
struct smb_filename *smb_fname = NULL;
+ nt_status = resolve_dfspath_wcard(ctx, conn,
+ req->flags2 & FLAGS2_DFS_PATHNAMES,
+ path,
+ &path,
+ &mask_contains_wcard);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) {
+ reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
+ ERRSRV, ERRbadpath);
+ END_PROFILE(SMBsearch);
+ return;
+ }
+ reply_nterror(req, nt_status);
+ END_PROFILE(SMBsearch);
+ return;
+ }
+
nt_status = unix_convert(ctx, conn, path, &smb_fname,
UCF_ALLOW_WCARD_LCOMP);
if (!NT_STATUS_IS_OK(nt_status)) {