]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: split out POSIX info_levels from smbd_do_setfilepathinfo() into own function
authorRalph Boehme <slow@samba.org>
Thu, 22 Oct 2020 10:26:17 +0000 (12:26 +0200)
committerRalph Boehme <slow@samba.org>
Fri, 23 Oct 2020 09:19:12 +0000 (09:19 +0000)
smbd_do_setfilepathinfo() can be made fully handle based for all non-POSIX
infolevels with pathref fsps, but for a POSIX create we may not have a fsp if
the path points at a symlink.

Splitting the POSIX from the non-POSIX logic allows for cleaner handling of this
in the future with pathref fsps.

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Ralph Böhme <slow@samba.org>
Autobuild-Date(master): Fri Oct 23 09:19:12 UTC 2020 on sn-devel-184

source3/smbd/trans2.c

index 424b9bf5cfb638da2c09c0afb31a744480fd878a..2e2b9e899a570e1e6339ae531c104b8693ef46d5 100644 (file)
@@ -8954,6 +8954,144 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
        return close_file(req, fsp, NORMAL_CLOSE);
 }
 
+static NTSTATUS smbd_do_posix_setfilepathinfo(struct connection_struct *conn,
+                                             struct smb_request *req,
+                                             TALLOC_CTX *mem_ctx,
+                                             uint16_t info_level,
+                                             struct smb_filename *smb_fname,
+                                             files_struct *fsp,
+                                             char **ppdata,
+                                             int total_data,
+                                             int *ret_data_size)
+{
+       char *pdata = *ppdata;
+       NTSTATUS status = NT_STATUS_OK;
+       int data_return_size = 0;
+
+       *ret_data_size = 0;
+
+       if (!CAN_WRITE(conn)) {
+               /* Allow POSIX opens. The open path will deny
+                * any non-readonly opens. */
+               if (info_level != SMB_POSIX_PATH_OPEN) {
+                       return NT_STATUS_DOS(ERRSRV, ERRaccess);
+               }
+       }
+
+       DBG_DEBUG("file=%s (%s) info_level=%d totdata=%d\n",
+                 smb_fname_str_dbg(smb_fname),
+                 fsp_fnum_dbg(fsp),
+                 info_level,
+                 total_data);
+
+       switch (info_level) {
+               case SMB_SET_FILE_UNIX_BASIC:
+               {
+                       status = smb_set_file_unix_basic(conn, req,
+                                                       pdata,
+                                                       total_data,
+                                                       fsp,
+                                                       smb_fname);
+                       break;
+               }
+
+               case SMB_SET_FILE_UNIX_INFO2:
+               {
+                       status = smb_set_file_unix_info2(conn, req,
+                                                       pdata,
+                                                       total_data,
+                                                       fsp,
+                                                       smb_fname);
+                       break;
+               }
+
+               case SMB_SET_FILE_UNIX_LINK:
+               {
+                       if (smb_fname == NULL) {
+                               /* We must have a pathname for this. */
+                               return NT_STATUS_INVALID_LEVEL;
+                       }
+                       status = smb_set_file_unix_link(conn, req, pdata,
+                                                       total_data, smb_fname);
+                       break;
+               }
+
+               case SMB_SET_FILE_UNIX_HLINK:
+               {
+                       if (smb_fname == NULL) {
+                               /* We must have a pathname for this. */
+                               return NT_STATUS_INVALID_LEVEL;
+                       }
+                       status = smb_set_file_unix_hlink(conn, req,
+                                                        pdata, total_data,
+                                                        smb_fname);
+                       break;
+               }
+
+#if defined(HAVE_POSIX_ACLS)
+               case SMB_SET_POSIX_ACL:
+               {
+                       status = smb_set_posix_acl(conn,
+                                               req,
+                                               pdata,
+                                               total_data,
+                                               fsp,
+                                               smb_fname);
+                       break;
+               }
+#endif
+
+               case SMB_SET_POSIX_LOCK:
+               {
+                       if (fsp == NULL) {
+                               return NT_STATUS_INVALID_LEVEL;
+                       }
+                       status = smb_set_posix_lock(conn, req,
+                                                   pdata, total_data, fsp);
+                       break;
+               }
+
+               case SMB_POSIX_PATH_OPEN:
+               {
+                       if (smb_fname == NULL) {
+                               /* We must have a pathname for this. */
+                               return NT_STATUS_INVALID_LEVEL;
+                       }
+
+                       status = smb_posix_open(conn, req,
+                                               ppdata,
+                                               total_data,
+                                               smb_fname,
+                                               &data_return_size);
+                       break;
+               }
+
+               case SMB_POSIX_PATH_UNLINK:
+               {
+                       if (smb_fname == NULL) {
+                               /* We must have a pathname for this. */
+                               return NT_STATUS_INVALID_LEVEL;
+                       }
+
+                       status = smb_posix_unlink(conn, req,
+                                               pdata,
+                                               total_data,
+                                               smb_fname);
+                       break;
+               }
+
+               default:
+                       return NT_STATUS_INVALID_LEVEL;
+       }
+
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       *ret_data_size = data_return_size;
+       return NT_STATUS_OK;
+}
+
 NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
                                struct smb_request *req,
                                TALLOC_CTX *mem_ctx,
@@ -8967,20 +9105,29 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
        NTSTATUS status = NT_STATUS_OK;
        int data_return_size = 0;
 
-       *ret_data_size = 0;
-
-       if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
-               return NT_STATUS_INVALID_LEVEL;
-       }
+       if (INFO_LEVEL_IS_UNIX(info_level)) {
+               if (!lp_unix_extensions()) {
+                       return NT_STATUS_INVALID_LEVEL;
+               }
 
-       if (!CAN_WRITE(conn)) {
-               /* Allow POSIX opens. The open path will deny
-                * any non-readonly opens. */
-               if (info_level != SMB_POSIX_PATH_OPEN) {
-                       return NT_STATUS_DOS(ERRSRV, ERRaccess);
+               status = smbd_do_posix_setfilepathinfo(conn,
+                                                      req,
+                                                      req,
+                                                      info_level,
+                                                      smb_fname,
+                                                      fsp,
+                                                      ppdata,
+                                                      total_data,
+                                                      &data_return_size);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
                }
+               *ret_data_size = data_return_size;
+               return NT_STATUS_OK;
        }
 
+       *ret_data_size = 0;
+
        DEBUG(3,("smbd_do_setfilepathinfo: %s (%s) info_level=%d "
                 "totdata=%d\n", smb_fname_str_dbg(smb_fname),
                 fsp_fnum_dbg(fsp),
@@ -9109,53 +9256,6 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
                case SMB_FILE_SHORT_NAME_INFORMATION:
                        return NT_STATUS_NOT_SUPPORTED;
 
-               /*
-                * CIFS UNIX extensions.
-                */
-
-               case SMB_SET_FILE_UNIX_BASIC:
-               {
-                       status = smb_set_file_unix_basic(conn, req,
-                                                       pdata,
-                                                       total_data,
-                                                       fsp,
-                                                       smb_fname);
-                       break;
-               }
-
-               case SMB_SET_FILE_UNIX_INFO2:
-               {
-                       status = smb_set_file_unix_info2(conn, req,
-                                                       pdata,
-                                                       total_data,
-                                                       fsp,
-                                                       smb_fname);
-                       break;
-               }
-
-               case SMB_SET_FILE_UNIX_LINK:
-               {
-                       if (fsp) {
-                               /* We must have a pathname for this. */
-                               return NT_STATUS_INVALID_LEVEL;
-                       }
-                       status = smb_set_file_unix_link(conn, req, pdata,
-                                                       total_data, smb_fname);
-                       break;
-               }
-
-               case SMB_SET_FILE_UNIX_HLINK:
-               {
-                       if (fsp) {
-                               /* We must have a pathname for this. */
-                               return NT_STATUS_INVALID_LEVEL;
-                       }
-                       status = smb_set_file_unix_hlink(conn, req,
-                                                        pdata, total_data,
-                                                        smb_fname);
-                       break;
-               }
-
                case SMB_FILE_RENAME_INFORMATION:
                {
                        status = smb_file_rename_information(conn, req,
@@ -9181,58 +9281,6 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
                        break;
                }
 
-#if defined(HAVE_POSIX_ACLS)
-               case SMB_SET_POSIX_ACL:
-               {
-                       status = smb_set_posix_acl(conn,
-                                               req,
-                                               pdata,
-                                               total_data,
-                                               fsp,
-                                               smb_fname);
-                       break;
-               }
-#endif
-
-               case SMB_SET_POSIX_LOCK:
-               {
-                       if (!fsp) {
-                               return NT_STATUS_INVALID_LEVEL;
-                       }
-                       status = smb_set_posix_lock(conn, req,
-                                                   pdata, total_data, fsp);
-                       break;
-               }
-
-               case SMB_POSIX_PATH_OPEN:
-               {
-                       if (fsp) {
-                               /* We must have a pathname for this. */
-                               return NT_STATUS_INVALID_LEVEL;
-                       }
-
-                       status = smb_posix_open(conn, req,
-                                               ppdata,
-                                               total_data,
-                                               smb_fname,
-                                               &data_return_size);
-                       break;
-               }
-
-               case SMB_POSIX_PATH_UNLINK:
-               {
-                       if (fsp) {
-                               /* We must have a pathname for this. */
-                               return NT_STATUS_INVALID_LEVEL;
-                       }
-
-                       status = smb_posix_unlink(conn, req,
-                                               pdata,
-                                               total_data,
-                                               smb_fname);
-                       break;
-               }
-
                default:
                        return NT_STATUS_INVALID_LEVEL;
        }