diff options
author | Gerald Carter <jerry@samba.org> | 2006-06-08 20:07:34 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2006-06-08 20:07:34 +0000 |
commit | 3a5cc58fde0d53d83d46e37f80670ad6bd67f892 (patch) | |
tree | af90a90140ba6578e973247176d40c6af54a167a /source/smbd | |
parent | a1b3f2f9bac039395fa20f0be779367f7e23400a (diff) | |
download | samba-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.c | 2 | ||||
-rw-r--r-- | source/smbd/dmapi.c | 6 | ||||
-rw-r--r-- | source/smbd/ipc.c | 6 | ||||
-rw-r--r-- | source/smbd/nttrans.c | 15 | ||||
-rw-r--r-- | source/smbd/open.c | 45 | ||||
-rw-r--r-- | source/smbd/oplock.c | 1 | ||||
-rw-r--r-- | source/smbd/pipes.c | 10 | ||||
-rw-r--r-- | source/smbd/reply.c | 6 | ||||
-rw-r--r-- | source/smbd/server.c | 9 | ||||
-rw-r--r-- | source/smbd/trans2.c | 48 |
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); } |