summaryrefslogtreecommitdiff
path: root/source3/smbd/open.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-02-06 21:05:34 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:17:47 -0500
commit7a5fa7f12ec439ef5a4af29aa86498f799b6b9a5 (patch)
tree611c3787938bb8eb77a127a18a4932890ae2fd03 /source3/smbd/open.c
parentc04068a42b230541559939004f33d72f1e76f075 (diff)
downloadsamba-7a5fa7f12ec439ef5a4af29aa86498f799b6b9a5.tar.gz
samba-7a5fa7f12ec439ef5a4af29aa86498f799b6b9a5.tar.bz2
samba-7a5fa7f12ec439ef5a4af29aa86498f799b6b9a5.zip
r21191: Add in the POSIX open/mkdir/unlink calls.
Move more error code returns to NTSTATUS. Client test code to follow... See if this passes the build-farm before I add it into 3.0.25. Jeremy. (This used to be commit 83dbbdff345fa9e427c9579183f4380004bf3dd7)
Diffstat (limited to 'source3/smbd/open.c')
-rw-r--r--source3/smbd/open.c109
1 files changed, 74 insertions, 35 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 2415433fe9..c9e29cf0e5 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -67,14 +67,13 @@ static BOOL fd_open(struct connection_struct *conn,
Close the file associated with a fsp.
****************************************************************************/
-int fd_close(struct connection_struct *conn,
- files_struct *fsp)
+NTSTATUS fd_close(struct connection_struct *conn, files_struct *fsp)
{
if (fsp->fh->fd == -1) {
- return 0; /* What we used to call a stat open. */
+ return NT_STATUS_OK; /* What we used to call a stat open. */
}
if (fsp->fh->ref_count > 1) {
- return 0; /* Shared handle. Only close last reference. */
+ return NT_STATUS_OK; /* Shared handle. Only close last reference. */
}
return fd_close_posix(conn, fsp);
}
@@ -1118,6 +1117,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
int flags2=0;
BOOL file_existed = VALID_STAT(*psbuf);
BOOL def_acl = False;
+ BOOL posix_open = False;
SMB_DEV_T dev = 0;
SMB_INO_T inode = 0;
NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
@@ -1156,10 +1156,16 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
return NT_STATUS_NO_MEMORY;
}
- /* We add aARCH to this as this mode is only used if the file is
- * created new. */
- unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
- parent_dir);
+ if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
+ posix_open = True;
+ unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
+ new_dos_attributes = 0;
+ } else {
+ /* We add aARCH to this as this mode is only used if the file is
+ * created new. */
+ unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
+ parent_dir);
+ }
DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
"access_mask=0x%x share_access=0x%x "
@@ -1197,9 +1203,11 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
return status;
}
- new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
- if (file_existed) {
- existing_dos_attributes = dos_mode(conn, fname, psbuf);
+ if (!posix_open) {
+ new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
+ if (file_existed) {
+ existing_dos_attributes = dos_mode(conn, fname, psbuf);
+ }
}
/* ignore any oplock requests if oplocks are disabled */
@@ -1294,7 +1302,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
/* We only care about matching attributes on file exists and
* overwrite. */
- if (file_existed && ((create_disposition == FILE_OVERWRITE) ||
+ if (!posix_open && file_existed && ((create_disposition == FILE_OVERWRITE) ||
(create_disposition == FILE_OVERWRITE_IF))) {
if (!open_match_attributes(conn, fname,
existing_dos_attributes,
@@ -1359,7 +1367,11 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
}
#endif /* O_SYNC */
- if (!CAN_WRITE(conn)) {
+ if (posix_open & (access_mask & FILE_APPEND_DATA)) {
+ flags2 |= O_APPEND;
+ }
+
+ if (!posix_open && !CAN_WRITE(conn)) {
/*
* We should really return a permission denied error if either
* O_CREAT or O_TRUNC are set, but for compatibility with
@@ -1393,6 +1405,8 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
fsp->access_mask = open_access_mask; /* We change this to the
* requested access_mask after
* the open is done. */
+ fsp->posix_open = posix_open;
+
/* Ensure no SAMBA_PRIVATE bits can be set. */
fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
@@ -1769,9 +1783,11 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
/* Files should be initially set as archive */
if (lp_map_archive(SNUM(conn)) ||
lp_store_dos_attributes(SNUM(conn))) {
- file_set_dosmode(conn, fname,
+ if (!posix_open) {
+ file_set_dosmode(conn, fname,
new_dos_attributes | aARCH, NULL,
parent_dir);
+ }
}
}
@@ -1780,7 +1796,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
* selected.
*/
- if (!file_existed && !def_acl) {
+ if (!posix_open && !file_existed && !def_acl) {
int saved_errno = errno; /* We might get ENOSYS in the next
* call.. */
@@ -1873,15 +1889,17 @@ NTSTATUS open_file_fchmod(connection_struct *conn, const char *fname,
Close the fchmod file fd - ensure no locks are lost.
****************************************************************************/
-int close_file_fchmod(files_struct *fsp)
+NTSTATUS close_file_fchmod(files_struct *fsp)
{
- int ret = fd_close(fsp->conn, fsp);
+ NTSTATUS status = fd_close(fsp->conn, fsp);
file_free(fsp);
- return ret;
+ return status;
}
-static NTSTATUS mkdir_internal(connection_struct *conn, const char *name,
- SMB_STRUCT_STAT *psbuf)
+static NTSTATUS mkdir_internal(connection_struct *conn,
+ const char *name,
+ uint32 file_attributes,
+ SMB_STRUCT_STAT *psbuf)
{
int ret= -1;
mode_t mode;
@@ -1905,7 +1923,11 @@ static NTSTATUS mkdir_internal(connection_struct *conn, const char *name,
return NT_STATUS_NO_MEMORY;
}
- mode = unix_mode(conn, aDIR, name, parent_dir);
+ if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
+ mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
+ } else {
+ mode = unix_mode(conn, aDIR, name, parent_dir);
+ }
if ((ret=SMB_VFS_MKDIR(conn, name, mode)) != 0) {
return map_nt_error_from_unix(errno);
@@ -1930,15 +1952,17 @@ static NTSTATUS mkdir_internal(connection_struct *conn, const char *name,
inherit_access_acl(conn, parent_dir, name, mode);
}
- /*
- * Check if high bits should have been set,
- * then (if bits are missing): add them.
- * Consider bits automagically set by UNIX, i.e. SGID bit from parent
- * dir.
- */
- if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) && (mode & ~psbuf->st_mode)) {
- SMB_VFS_CHMOD(conn, name,
- psbuf->st_mode | (mode & ~psbuf->st_mode));
+ if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
+ /*
+ * Check if high bits should have been set,
+ * then (if bits are missing): add them.
+ * Consider bits automagically set by UNIX, i.e. SGID bit from parent
+ * dir.
+ */
+ if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) && (mode & ~psbuf->st_mode)) {
+ SMB_VFS_CHMOD(conn, name,
+ psbuf->st_mode | (mode & ~psbuf->st_mode));
+ }
}
/* Change the owner if required. */
@@ -1963,6 +1987,7 @@ NTSTATUS open_directory(connection_struct *conn,
uint32 share_access,
uint32 create_disposition,
uint32 create_options,
+ uint32 file_attributes,
int *pinfo,
files_struct **result)
{
@@ -1974,12 +1999,13 @@ NTSTATUS open_directory(connection_struct *conn,
DEBUG(5,("open_directory: opening directory %s, access_mask = 0x%x, "
"share_access = 0x%x create_options = 0x%x, "
- "create_disposition = 0x%x\n",
+ "create_disposition = 0x%x, file_attributes = 0x%x\n",
fname,
(unsigned int)access_mask,
(unsigned int)share_access,
(unsigned int)create_options,
- (unsigned int)create_disposition));
+ (unsigned int)create_disposition,
+ (unsigned int)file_attributes));
if (is_ntfs_stream_name(fname)) {
DEBUG(0,("open_directory: %s is a stream name!\n", fname ));
@@ -2006,7 +2032,11 @@ NTSTATUS open_directory(connection_struct *conn,
/* If directory exists error. If directory doesn't
* exist create. */
- status = mkdir_internal(conn, fname, psbuf);
+ status = mkdir_internal(conn,
+ fname,
+ file_attributes,
+ psbuf);
+
if (!NT_STATUS_IS_OK(status)) {
DEBUG(2, ("open_directory: unable to create "
"%s. Error was %s\n", fname,
@@ -2023,7 +2053,10 @@ NTSTATUS open_directory(connection_struct *conn,
* exist create.
*/
- status = mkdir_internal(conn, fname, psbuf);
+ status = mkdir_internal(conn,
+ fname,
+ file_attributes,
+ psbuf);
if (NT_STATUS_IS_OK(status)) {
info = FILE_WAS_CREATED;
@@ -2081,6 +2114,8 @@ NTSTATUS open_directory(connection_struct *conn,
fsp->sent_oplock_break = NO_BREAK_SENT;
fsp->is_directory = True;
fsp->is_stat = False;
+ fsp->posix_open = (file_attributes & FILE_FLAG_POSIX_SEMANTICS) ? True : False;
+
string_set(&fsp->fsp_name,fname);
lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode,
@@ -2145,7 +2180,11 @@ NTSTATUS create_directory(connection_struct *conn, const char *directory)
status = open_directory(conn, directory, &sbuf,
FILE_READ_ATTRIBUTES, /* Just a stat open */
FILE_SHARE_NONE, /* Ignored for stat opens */
- FILE_CREATE, 0, NULL, &fsp);
+ FILE_CREATE,
+ 0,
+ FILE_ATTRIBUTE_DIRECTORY,
+ NULL,
+ &fsp);
if (NT_STATUS_IS_OK(status)) {
close_file(fsp, NORMAL_CLOSE);