pysmbd: extract init_files_struct function
authorJoe Guo <joeg@catalyst.net.nz>
Fri, 1 Jun 2018 01:45:25 +0000 (13:45 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 28 Jun 2018 07:25:09 +0000 (09:25 +0200)
Extract initialization code from set_nt_acl_conn for reuse.

Signed-off-by: Joe Guo <joeg@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
source3/smbd/pysmbd.c

index a63194aa16613151c76f017a5c0686090f9d1c31..cd6ff1f53c5f5c09345890a0e264b99c37592168 100644 (file)
@@ -37,6 +37,13 @@ extern const struct generic_mapping file_generic_mapping;
 #undef  DBGC_CLASS
 #define DBGC_CLASS DBGC_ACLS
 
+#ifdef O_DIRECTORY
+#define DIRECTORY_FLAGS O_RDONLY|O_DIRECTORY
+#else
+/* POSIX allows us to open a directory with O_RDONLY. */
+#define DIRECTORY_FLAGS O_RDONLY
+#endif
+
 static connection_struct *get_conn_tos(const char *service)
 {
        struct conn_struct_tos *c = NULL;
@@ -100,25 +107,24 @@ static int set_sys_acl_conn(const char *fname,
        return ret;
 }
 
-static NTSTATUS set_nt_acl_conn(const char *fname,
-                               uint32_t security_info_sent, const struct security_descriptor *sd,
-                               connection_struct *conn)
+
+static NTSTATUS init_files_struct(TALLOC_CTX *mem_ctx,
+                                 const char *fname,
+                                 struct connection_struct *conn,
+                                 int flags,
+                                 struct files_struct **_fsp)
 {
-       TALLOC_CTX *frame = talloc_stackframe();
-       NTSTATUS status = NT_STATUS_OK;
-       files_struct *fsp;
        struct smb_filename *smb_fname = NULL;
-       int flags, ret;
+       int ret;
        mode_t saved_umask;
+       struct files_struct *fsp;
 
-       fsp = talloc_zero(frame, struct files_struct);
+       fsp = talloc_zero(mem_ctx, struct files_struct);
        if (fsp == NULL) {
-               TALLOC_FREE(frame);
                return NT_STATUS_NO_MEMORY;
        }
        fsp->fh = talloc(fsp, struct fd_handle);
        if (fsp->fh == NULL) {
-               TALLOC_FREE(frame);
                return NT_STATUS_NO_MEMORY;
        }
        fsp->conn = conn;
@@ -128,42 +134,26 @@ static NTSTATUS set_nt_acl_conn(const char *fname,
        saved_umask = umask(0);
 
        smb_fname = synthetic_smb_fname_split(fsp,
-                                       fname,
-                                       lp_posix_pathnames());
+                                             fname,
+                                             lp_posix_pathnames());
        if (smb_fname == NULL) {
-               TALLOC_FREE(frame);
                umask(saved_umask);
                return NT_STATUS_NO_MEMORY;
        }
 
        fsp->fsp_name = smb_fname;
-
-#ifdef O_DIRECTORY
-       flags = O_RDONLY|O_DIRECTORY;
-#else
-       /* POSIX allows us to open a directory with O_RDONLY. */
-       flags = O_RDONLY;
-#endif
-
-       fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, O_RDWR, 00400);
-       if (fsp->fh->fd == -1 && errno == EISDIR) {
-               fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, 00400);
-       }
+       fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, 00644);
        if (fsp->fh->fd == -1) {
-               printf("open: error=%d (%s)\n", errno, strerror(errno));
-               TALLOC_FREE(frame);
                umask(saved_umask);
-               return NT_STATUS_UNSUCCESSFUL;
+               return NT_STATUS_INVALID_PARAMETER;
        }
 
        ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
        if (ret == -1) {
                /* If we have an fd, this stat should succeed. */
-               DEBUG(0,("Error doing fstat on open file %s "
-                       "(%s)\n",
-                       smb_fname_str_dbg(smb_fname),
-                       strerror(errno) ));
-               TALLOC_FREE(frame);
+               DEBUG(0,("Error doing fstat on open file %s (%s)\n",
+                        smb_fname_str_dbg(smb_fname),
+                        strerror(errno) ));
                umask(saved_umask);
                return map_nt_error_from_unix(errno);
        }
@@ -179,7 +169,42 @@ static NTSTATUS set_nt_acl_conn(const char *fname,
        fsp->sent_oplock_break = NO_BREAK_SENT;
        fsp->is_directory = S_ISDIR(smb_fname->st.st_ex_mode);
 
-       status = SMB_VFS_FSET_NT_ACL( fsp, security_info_sent, sd);
+       *_fsp = fsp;
+
+       return NT_STATUS_OK;
+}
+
+static NTSTATUS set_nt_acl_conn(const char *fname,
+                               uint32_t security_info_sent, const struct security_descriptor *sd,
+                               connection_struct *conn)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct files_struct *fsp = NULL;
+       NTSTATUS status = NT_STATUS_OK;
+
+       /* first, try to open it as a file with flag O_RDWR */
+       status = init_files_struct(frame,
+                                  fname,
+                                  conn,
+                                  O_RDWR,
+                                  &fsp);
+       if (!NT_STATUS_IS_OK(status) && errno == EISDIR) {
+               /* if fail, try to open as dir */
+               status = init_files_struct(frame,
+                                          fname,
+                                          conn,
+                                          DIRECTORY_FLAGS,
+                                          &fsp);
+       }
+
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("open: error=%d (%s)\n", errno, strerror(errno));
+               SMB_VFS_CLOSE(fsp);
+               TALLOC_FREE(frame);
+               return status;
+       }
+
+       status = SMB_VFS_FSET_NT_ACL(fsp, security_info_sent, sd);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("set_nt_acl_no_snum: fset_nt_acl returned %s.\n", nt_errstr(status)));
        }
@@ -187,8 +212,6 @@ static NTSTATUS set_nt_acl_conn(const char *fname,
        SMB_VFS_CLOSE(fsp);
 
        TALLOC_FREE(frame);
-
-       umask(saved_umask);
        return status;
 }