summaryrefslogtreecommitdiff
path: root/source3/smbd/files.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd/files.c')
-rw-r--r--source3/smbd/files.c70
1 files changed, 44 insertions, 26 deletions
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index e020d8e13a..7069818dee 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -59,7 +59,7 @@ static unsigned long get_gen_count(void)
Find first available file slot.
****************************************************************************/
-files_struct *file_new(connection_struct *conn)
+NTSTATUS file_new(connection_struct *conn, files_struct **result)
{
int i;
static int first_file;
@@ -82,14 +82,12 @@ files_struct *file_new(connection_struct *conn)
/* TODO: We have to unconditionally return a DOS error here,
* W2k3 even returns ERRDOS/ERRnofids for ntcreate&x with
* NTSTATUS negotiated */
- set_saved_ntstatus(NT_STATUS_TOO_MANY_OPENED_FILES);
- return NULL;
+ return NT_STATUS_TOO_MANY_OPENED_FILES;
}
fsp = SMB_MALLOC_P(files_struct);
if (!fsp) {
- set_saved_ntstatus(NT_STATUS_NO_MEMORY);
- return NULL;
+ return NT_STATUS_NO_MEMORY;
}
ZERO_STRUCTP(fsp);
@@ -97,8 +95,7 @@ files_struct *file_new(connection_struct *conn)
fsp->fh = SMB_MALLOC_P(struct fd_handle);
if (!fsp->fh) {
SAFE_FREE(fsp);
- set_saved_ntstatus(NT_STATUS_NO_MEMORY);
- return NULL;
+ return NT_STATUS_NO_MEMORY;
}
ZERO_STRUCTP(fsp->fh);
@@ -131,8 +128,9 @@ files_struct *file_new(connection_struct *conn)
if (fsp_fi_cache.fsp == NULL) {
ZERO_STRUCT(fsp_fi_cache);
}
-
- return fsp;
+
+ *result = fsp;
+ return NT_STATUS_OK;
}
/****************************************************************************
@@ -464,24 +462,16 @@ void file_free(files_struct *fsp)
}
/****************************************************************************
- Get a fsp from a packet given the offset of a 16 bit fnum.
+ Get an fsp from a 16 bit fnum.
****************************************************************************/
-files_struct *file_fsp(char *buf, int where)
+files_struct *file_fnum(uint16 fnum)
{
- int fnum, count=0;
files_struct *fsp;
-
- if (chain_fsp)
- return chain_fsp;
-
- if (!buf)
- return NULL;
- fnum = SVAL(buf, where);
+ int count=0;
for (fsp=Files;fsp;fsp=fsp->next, count++) {
if (fsp->fnum == fnum) {
- chain_fsp = fsp;
if (count > 10) {
DLIST_PROMOTE(Files, fsp);
}
@@ -492,6 +482,29 @@ files_struct *file_fsp(char *buf, int where)
}
/****************************************************************************
+ Get an fsp from a packet given the offset of a 16 bit fnum.
+****************************************************************************/
+
+files_struct *file_fsp(char *buf, int where)
+{
+ files_struct *fsp;
+
+ if (chain_fsp) {
+ return chain_fsp;
+ }
+
+ if (!buf) {
+ return NULL;
+ }
+
+ fsp = file_fnum(SVAL(buf, where));
+ if (fsp) {
+ chain_fsp = fsp;
+ }
+ return fsp;
+}
+
+/****************************************************************************
Reset the chained fsp - done at the start of a packet reply.
****************************************************************************/
@@ -504,15 +517,19 @@ void file_chain_reset(void)
Duplicate the file handle part for a DOS or FCB open.
****************************************************************************/
-files_struct *dup_file_fsp(files_struct *fsp,
+NTSTATUS dup_file_fsp(files_struct *fsp,
uint32 access_mask,
uint32 share_access,
- uint32 create_options)
+ uint32 create_options,
+ files_struct **result)
{
- files_struct *dup_fsp = file_new(fsp->conn);
+ NTSTATUS status;
+ files_struct *dup_fsp;
- if (!dup_fsp) {
- return NULL;
+ status = file_new(fsp->conn, &dup_fsp);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
SAFE_FREE(dup_fsp->fh);
@@ -547,5 +564,6 @@ files_struct *dup_file_fsp(files_struct *fsp,
dup_fsp->aio_write_behind = fsp->aio_write_behind;
string_set(&dup_fsp->fsp_name,fsp->fsp_name);
- return dup_fsp;
+ *result = dup_fsp;
+ return NT_STATUS_OK;
}