#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;
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;
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);
}
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)));
}
SMB_VFS_CLOSE(fsp);
TALLOC_FREE(frame);
-
- umask(saved_umask);
return status;
}