Add some const to the stat struct in the dosmode calls.
authorJeremy Allison <jra@samba.org>
Thu, 18 Jun 2009 22:07:14 +0000 (15:07 -0700)
committerJeremy Allison <jra@samba.org>
Thu, 18 Jun 2009 22:07:14 +0000 (15:07 -0700)
Fix a couple more unix_convert uses to filename_convert.
Fix bug in acl_group_override() where an uninitialized
struct could be used. Move unix_convert with wildcard
use in SMBsearch reply to boilerplate code.
Jeremy.

source3/include/proto.h
source3/rpc_server/srv_srvsvc_nt.c
source3/smbd/dosmode.c
source3/smbd/file_access.c
source3/smbd/nttrans.c
source3/smbd/open.c
source3/smbd/posix_acls.c
source3/smbd/reply.c

index 6fc28259d69430db4764c3c8911c525b997f8e06..598d83aee6065b8596a4433647af603521bf7071 100644 (file)
@@ -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  */
index 1b07fc213e683f7ce9e534d14a4c664a7ee2048e..070f7fd0ca262a5bc98f6ee5622b0956b27bf37d 100644 (file)
@@ -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 */
index eeed76329cc09d49931fd878b539bc030521f6c1..8149eea7f59ad8726ac20c40fea9d55269723046 100644 (file)
@@ -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;
        }
 
index 8b282e25b6690339be29fc3402c0c728d4bdd5f4..195f722471d13409f57b8cf849b97b7978e3019d 100644 (file)
@@ -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);
 }
index 73c062e69feffbc2f51e8ab39f069d365d726807..222caae5169ca55f8d45caf0a97662e33a0d34a1 100644 (file)
@@ -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:
index 5d82738f6abd2198d00b6a8c36426bf8ec461770..d6331ee487a760245e64558359b426c5279ee334 100644 (file)
@@ -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)
 {
index 2d0062ab947c6b6f99db7586d7e2083e6f924156..6eed92cb3ed0a0fd424eee9ee5e991d7c3e33646 100644 (file)
@@ -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 ));
index f11f3bfed7d62863de8c35b8c793c545c02f3471..9544b845da5b0998a4993a2b892484dd79b1b12a 100644 (file)
@@ -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)) {