summaryrefslogtreecommitdiffstats
path: root/source/smbd
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2006-06-08 20:07:34 +0000
committerGerald Carter <jerry@samba.org>2006-06-08 20:07:34 +0000
commit3a5cc58fde0d53d83d46e37f80670ad6bd67f892 (patch)
treeaf90a90140ba6578e973247176d40c6af54a167a /source/smbd
parenta1b3f2f9bac039395fa20f0be779367f7e23400a (diff)
downloadsamba-3a5cc58fde0d53d83d46e37f80670ad6bd67f892.tar.gz
samba-3a5cc58fde0d53d83d46e37f80670ad6bd67f892.tar.xz
samba-3a5cc58fde0d53d83d46e37f80670ad6bd67f892.zip
r16104: Set version to 3.0.23rc2
Bring release tree up to current 3.0 tree (svn merge -r15845:16103 $SVNURL/branches/SAMBA_3_0)
Diffstat (limited to 'source/smbd')
-rw-r--r--source/smbd/chgpasswd.c2
-rw-r--r--source/smbd/dmapi.c6
-rw-r--r--source/smbd/ipc.c6
-rw-r--r--source/smbd/nttrans.c15
-rw-r--r--source/smbd/open.c45
-rw-r--r--source/smbd/oplock.c1
-rw-r--r--source/smbd/pipes.c10
-rw-r--r--source/smbd/reply.c6
-rw-r--r--source/smbd/server.c9
-rw-r--r--source/smbd/trans2.c48
10 files changed, 101 insertions, 47 deletions
diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c
index 16b44a54bf9..011122ee575 100644
--- a/source/smbd/chgpasswd.c
+++ b/source/smbd/chgpasswd.c
@@ -241,7 +241,7 @@ static int expect(int master, char *issue, char *expected)
if (lp_passwd_chat_debug())
DEBUG(100, ("expect: sending [%s]\n", issue));
- if ((len = write(master, issue, strlen(issue))) != strlen(issue)) {
+ if ((len = sys_write(master, issue, strlen(issue))) != strlen(issue)) {
DEBUG(2,("expect: (short) write returned %d\n", len ));
return False;
}
diff --git a/source/smbd/dmapi.c b/source/smbd/dmapi.c
index 4a6cba293bc..a9d83c782bb 100644
--- a/source/smbd/dmapi.c
+++ b/source/smbd/dmapi.c
@@ -24,12 +24,6 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_DMAPI
-#if defined(HAVE_LIBDM) || defined(HAVE_LIBJFSDM) || defined(HAVE_LIBXDSM)
-#if defined(HAVE_XFS_DMAPI_H) || defined(HAVE_SYS_DMI_H) || defined(HAVE_SYS_JFSDMAPI_H) || defined(HAVE_SYS_DMAPI_H)
-#define USE_DMAPI 1
-#endif
-#endif
-
#ifndef USE_DMAPI
int dmapi_init_session(void) { return -1; }
diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c
index 7f9505606cc..32503879099 100644
--- a/source/smbd/ipc.c
+++ b/source/smbd/ipc.c
@@ -291,6 +291,12 @@ static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf,
return ERROR_NT(NT_STATUS_INVALID_HANDLE);
}
+ if (vuid != p->vuid) {
+ DEBUG(1, ("Got pipe request (pnum %x) using invalid VUID %d, "
+ "expected %d\n", pnum, vuid, p->vuid));
+ return ERROR_NT(NT_STATUS_INVALID_HANDLE);
+ }
+
DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)\n", subcommand, p->name, pnum));
/* record maximum data length that can be transmitted in an SMBtrans */
diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c
index 3cdc4997b23..5d19d496fd9 100644
--- a/source/smbd/nttrans.c
+++ b/source/smbd/nttrans.c
@@ -1652,11 +1652,11 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
fsp1 = open_file_ntcreate(conn,oldname,&sbuf1,
FILE_READ_DATA, /* Read-only. */
- 0, /* No sharing. */
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_OPEN,
0, /* No create options. */
FILE_ATTRIBUTE_NORMAL,
- INTERNAL_OPEN_ONLY,
+ NO_OPLOCK,
&info);
if (!fsp1) {
@@ -1669,12 +1669,12 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
}
fsp2 = open_file_ntcreate(conn,newname,&sbuf2,
- FILE_WRITE_DATA, /* Read-only. */
- 0, /* No sharing. */
+ FILE_WRITE_DATA, /* Write-only. */
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_CREATE,
0, /* No create options. */
fattr,
- INTERNAL_OPEN_ONLY,
+ NO_OPLOCK,
&info);
if (!fsp2) {
@@ -1704,8 +1704,9 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
close_ret = close_file(fsp2,NORMAL_CLOSE);
- /* Grrr. We have to do this as open_file_shared1 adds aARCH when it
- creates the file. This isn't the correct thing to do in the copy case. JRA */
+ /* Grrr. We have to do this as open_file_ntcreate adds aARCH when it
+ creates the file. This isn't the correct thing to do in the copy
+ case. JRA */
file_set_dosmode(conn, newname, fattr, &sbuf2, True);
if (ret < (SMB_OFF_T)sbuf1.st_size) {
diff --git a/source/smbd/open.c b/source/smbd/open.c
index 3d537b2f394..633e70ac314 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -245,7 +245,7 @@ static BOOL open_file(files_struct *fsp,
/*
* We can't actually truncate here as the file may be locked.
- * open_file_shared will take care of the truncate later. JRA.
+ * open_file_ntcreate will take care of the truncate later. JRA.
*/
local_flags &= ~O_TRUNC;
@@ -599,7 +599,7 @@ static BOOL is_delete_request(files_struct *fsp) {
}
/*
- * 1) No files open at all: Grant whatever the client wants.
+ * 1) No files open at all or internal open: Grant whatever the client wants.
*
* 2) Exclusive (or batch) oplock around: If the requested access is a delete
* request, break if the oplock around is a batch oplock. If it's another
@@ -608,7 +608,10 @@ static BOOL is_delete_request(files_struct *fsp) {
* 3) Only level2 around: Grant level2 and do nothing else.
*/
-static BOOL delay_for_oplocks(struct share_mode_lock *lck, files_struct *fsp, int pass_number)
+static BOOL delay_for_oplocks(struct share_mode_lock *lck,
+ files_struct *fsp,
+ int pass_number,
+ int oplock_request)
{
int i;
struct share_mode_entry *exclusive = NULL;
@@ -616,7 +619,7 @@ static BOOL delay_for_oplocks(struct share_mode_lock *lck, files_struct *fsp, in
BOOL delay_it = False;
BOOL have_level2 = False;
- if (is_stat_open(fsp->access_mask)) {
+ if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) {
fsp->oplock_type = NO_OPLOCK;
return False;
}
@@ -683,8 +686,16 @@ static BOOL delay_for_oplocks(struct share_mode_lock *lck, files_struct *fsp, in
procid_str_static(&exclusive->pid)));
exclusive->op_mid = get_current_mid();
+ /* Create the message. */
share_mode_entry_to_message(msg, exclusive);
+ /* Add in the FORCE_OPLOCK_BREAK_TO_NONE bit in the message if set. We don't
+ want this set in the share mode struct pointed to by lck. */
+
+ if (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE) {
+ SSVAL(msg,6,exclusive->op_type | FORCE_OPLOCK_BREAK_TO_NONE);
+ }
+
become_root();
ret = message_send_pid(exclusive->pid, MSG_SMB_BREAK_REQUEST,
msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True);
@@ -692,7 +703,6 @@ static BOOL delay_for_oplocks(struct share_mode_lock *lck, files_struct *fsp, in
if (!ret) {
DEBUG(3, ("Could not send oplock break message\n"));
}
- file_free(fsp);
}
return delay_it;
@@ -1087,7 +1097,6 @@ files_struct *open_file_ntcreate(connection_struct *conn,
int flags2=0;
BOOL file_existed = VALID_STAT(*psbuf);
BOOL def_acl = False;
- BOOL internal_only_open = False;
SMB_DEV_T dev = 0;
SMB_INO_T inode = 0;
BOOL fsp_open = False;
@@ -1130,11 +1139,6 @@ files_struct *open_file_ntcreate(connection_struct *conn,
create_disposition, create_options, unx_mode,
oplock_request));
- if (oplock_request == INTERNAL_OPEN_ONLY) {
- internal_only_open = True;
- oplock_request = 0;
- }
-
if ((pml = get_open_deferred_message(mid)) != NULL) {
struct deferred_open_record *state =
(struct deferred_open_record *)pml->private_data.data;
@@ -1171,7 +1175,8 @@ files_struct *open_file_ntcreate(connection_struct *conn,
/* ignore any oplock requests if oplocks are disabled */
if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
IS_VETO_OPLOCK_PATH(conn, fname)) {
- oplock_request = 0;
+ /* Mask off everything except the private Samba bits. */
+ oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
}
/* this is for OS/2 long file names - say we don't support them */
@@ -1346,7 +1351,8 @@ files_struct *open_file_ntcreate(connection_struct *conn,
fsp->share_access = share_access;
fsp->fh->private_options = create_options;
fsp->access_mask = access_mask;
- fsp->oplock_type = oplock_request;
+ /* Ensure no SAMBA_PRIVATE bits can be set. */
+ fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
if (timeval_is_zero(&request_time)) {
request_time = fsp->open_time;
@@ -1361,15 +1367,17 @@ files_struct *open_file_ntcreate(connection_struct *conn,
fname);
if (lck == NULL) {
+ file_free(fsp);
DEBUG(0, ("Could not get share mode lock\n"));
set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION);
return NULL;
}
/* First pass - send break only on batch oplocks. */
- if (delay_for_oplocks(lck, fsp, 1)) {
+ if (delay_for_oplocks(lck, fsp, 1, oplock_request)) {
schedule_defer_open(lck, request_time);
TALLOC_FREE(lck);
+ file_free(fsp);
return NULL;
}
@@ -1380,9 +1388,10 @@ files_struct *open_file_ntcreate(connection_struct *conn,
if (NT_STATUS_IS_OK(status)) {
/* We might be going to allow this open. Check oplock status again. */
/* Second pass - send break for both batch or exclusive oplocks. */
- if (delay_for_oplocks(lck, fsp, 2)) {
+ if (delay_for_oplocks(lck, fsp, 2, oplock_request)) {
schedule_defer_open(lck, request_time);
TALLOC_FREE(lck);
+ file_free(fsp);
return NULL;
}
}
@@ -1456,7 +1465,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
* cope with the braindead 1 second delay.
*/
- if (!internal_only_open &&
+ if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
lp_defer_sharing_violations()) {
struct timeval timeout;
struct deferred_open_record state;
@@ -1742,7 +1751,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
if (ret == -1 && errno == ENOSYS) {
errno = saved_errno; /* Ignore ENOSYS */
} else {
- DEBUG(5, ("open_file_shared: reset "
+ DEBUG(5, ("open_file_ntcreate: reset "
"attributes of file %s to 0%o\n",
fname, (unsigned int)new_unx_mode));
ret = 0; /* Don't do the fchmod below. */
@@ -1751,7 +1760,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
if ((ret == -1) &&
(SMB_VFS_FCHMOD(fsp, fsp->fh->fd, new_unx_mode) == -1))
- DEBUG(5, ("open_file_shared: failed to reset "
+ DEBUG(5, ("open_file_ntcreate: failed to reset "
"attributes of file %s to 0%o\n",
fname, (unsigned int)new_unx_mode));
}
diff --git a/source/smbd/oplock.c b/source/smbd/oplock.c
index 42c64a28435..1f731e17291 100644
--- a/source/smbd/oplock.c
+++ b/source/smbd/oplock.c
@@ -540,6 +540,7 @@ static void process_oplock_break_message(int msg_type, struct process_id src,
}
if ((global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
+ !(msg.op_type & FORCE_OPLOCK_BREAK_TO_NONE) &&
!koplocks && /* NOTE: we force levelII off for kernel oplocks -
* this will change when it is supported */
lp_level2_oplocks(SNUM(fsp->conn))) {
diff --git a/source/smbd/pipes.c b/source/smbd/pipes.c
index 12f3d180b1e..2d90383706b 100644
--- a/source/smbd/pipes.c
+++ b/source/smbd/pipes.c
@@ -121,6 +121,7 @@ int reply_open_pipe_and_X(connection_struct *conn,
int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize)
{
smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
+ uint16 vuid = SVAL(inbuf,smb_uid);
size_t numtowrite = SVAL(inbuf,smb_vwv1);
int nwritten;
int outsize;
@@ -130,6 +131,10 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize)
return(ERROR_DOS(ERRDOS,ERRbadfid));
}
+ if (p->vuid != vuid) {
+ return ERROR_NT(NT_STATUS_INVALID_HANDLE);
+ }
+
data = smb_buf(inbuf) + 3;
if (numtowrite == 0) {
@@ -161,6 +166,7 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize)
int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
{
smb_np_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2);
+ uint16 vuid = SVAL(inbuf,smb_uid);
size_t numtowrite = SVAL(inbuf,smb_vwv10);
int nwritten = -1;
int smb_doff = SVAL(inbuf, smb_vwv11);
@@ -172,6 +178,10 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
return(ERROR_DOS(ERRDOS,ERRbadfid));
}
+ if (p->vuid != vuid) {
+ return ERROR_NT(NT_STATUS_INVALID_HANDLE);
+ }
+
data = smb_base(inbuf) + smb_doff;
if (numtowrite == 0) {
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index 387ed4a47f4..d333ebf32eb 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -1433,9 +1433,9 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
uint32 smb_attr = SVAL(inbuf,smb_vwv5);
/* Breakout the oplock request bits so we can set the
reply bits separately. */
- BOOL ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
- BOOL core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
- BOOL oplock_request = ex_oplock_request | core_oplock_request;
+ int ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
+ int core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
+ int oplock_request = ex_oplock_request | core_oplock_request;
#if 0
int smb_sattr = SVAL(inbuf,smb_vwv4);
uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
diff --git a/source/smbd/server.c b/source/smbd/server.c
index d16579f24a8..2bfeae9f541 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -744,16 +744,17 @@ void build_options(BOOL screen);
poptContext pc;
struct poptOption long_options[] = {
- POPT_AUTOHELP
+ POPT_AUTOHELP
{"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon (default)" },
{"interactive", 'i', POPT_ARG_VAL, &interactive, True, "Run interactive (not a daemon)"},
- {"foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in foreground (for daemontools & etc)" },
- {"no-process-group", 0, POPT_ARG_VAL, &no_process_group, True, "Don't create a new process group" },
+ {"foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in foreground (for daemontools, etc.)" },
+ {"no-process-group", '\0', POPT_ARG_VAL, &no_process_group, True, "Don't create a new process group" },
{"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" },
{"build-options", 'b', POPT_ARG_NONE, NULL, 'b', "Print build options" },
{"port", 'p', POPT_ARG_STRING, &ports, 0, "Listen on the specified ports"},
POPT_COMMON_SAMBA
- { NULL }
+ POPT_COMMON_DYNCONFIG
+ POPT_TABLEEND
};
load_case_tables();
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index fc14772c57c..eda4837ba4b 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -727,7 +727,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
time_t open_time;
#endif
int open_ofun;
- int32 open_size;
+ uint32 open_size;
char *pname;
pstring fname;
SMB_OFF_T size=0;
@@ -860,6 +860,30 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
return(ERROR_DOS(ERRDOS,ERRnoaccess));
}
+ /* Save the requested allocation size. */
+ /* Allocate space for the file if a size hint is supplied */
+ if ((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) {
+ SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)open_size;
+ if (allocation_size && (allocation_size > (SMB_BIG_UINT)size)) {
+ fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
+ if (fsp->is_directory) {
+ close_file(fsp,ERROR_CLOSE);
+ /* Can't set allocation size on a directory. */
+ return ERROR_NT(NT_STATUS_ACCESS_DENIED);
+ }
+ if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
+ close_file(fsp,ERROR_CLOSE);
+ return ERROR_NT(NT_STATUS_DISK_FULL);
+ }
+
+ /* Adjust size here to return the right size in the reply.
+ Windows does it this way. */
+ size = fsp->initial_allocation_size;
+ } else {
+ fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)size);
+ }
+ }
+
if (total_data && smb_action == FILE_WAS_CREATED) {
status = set_ea(conn, fsp, fname, ea_list);
talloc_destroy(ctx);
@@ -3996,15 +4020,19 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
new_fsp = open_file_ntcreate(conn, fname, &sbuf,
FILE_WRITE_DATA,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_OPEN,
0,
FILE_ATTRIBUTE_NORMAL,
- INTERNAL_OPEN_ONLY,
+ FORCE_OPLOCK_BREAK_TO_NONE,
NULL);
if (new_fsp == NULL) {
- return(UNIXERROR(ERRDOS,ERRbadpath));
+ if (open_was_deferred(SVAL(inbuf,smb_mid))) {
+ /* We have re-scheduled this call. */
+ return -1;
+ }
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
}
ret = vfs_allocate_file_space(new_fsp, allocation_size);
if (SMB_VFS_FSTAT(new_fsp,new_fsp->fh->fd,&new_sbuf) != 0) {
@@ -4537,7 +4565,6 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
POSIX_LOCK,
&my_lock_ctx);
- /* TODO: Deal with rescheduling blocking lock fail here... */
if (lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
/*
* A blocking lock was requested. Package up
@@ -4636,15 +4663,19 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
new_fsp = open_file_ntcreate(conn, fname, &sbuf,
FILE_WRITE_DATA,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_OPEN,
0,
FILE_ATTRIBUTE_NORMAL,
- INTERNAL_OPEN_ONLY,
+ FORCE_OPLOCK_BREAK_TO_NONE,
NULL);
if (new_fsp == NULL) {
- return(UNIXERROR(ERRDOS,ERRbadpath));
+ if (open_was_deferred(SVAL(inbuf,smb_mid))) {
+ /* We have re-scheduled this call. */
+ return -1;
+ }
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
}
ret = vfs_set_filelen(new_fsp, size);
close_file(new_fsp,NORMAL_CLOSE);
@@ -5238,6 +5269,7 @@ int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf,
} else {
DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count));
DEBUG(2,("Transaction is %d\n",tran_call));
+ TALLOC_FREE(state);
END_PROFILE(SMBtrans2);
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}