diff options
author | Gerald Carter <jerry@samba.org> | 2006-05-23 15:21:55 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2006-05-23 15:21:55 +0000 |
commit | 3f7bb704a9e62e7a46a05838ec9300c2f6916c16 (patch) | |
tree | e2ca7f1b8da68d725e5359d7746f391fedcad6be /source/smbd | |
parent | 34b471724d1c8eb9e020fce02fc538bd0993d1c4 (diff) | |
download | samba-3f7bb704a9e62e7a46a05838ec9300c2f6916c16.tar.gz samba-3f7bb704a9e62e7a46a05838ec9300c2f6916c16.tar.xz samba-3f7bb704a9e62e7a46a05838ec9300c2f6916c16.zip |
r15837: starting sync up for 3.0.23rc1 (in sync with SAMBA_3_0 r15822)
Diffstat (limited to 'source/smbd')
-rw-r--r-- | source/smbd/close.c | 140 | ||||
-rw-r--r-- | source/smbd/dir.c | 2 | ||||
-rw-r--r-- | source/smbd/fake_file.c | 6 | ||||
-rw-r--r-- | source/smbd/files.c | 28 | ||||
-rw-r--r-- | source/smbd/ipc.c | 4 | ||||
-rw-r--r-- | source/smbd/msdfs.c | 5 | ||||
-rw-r--r-- | source/smbd/notify.c | 14 | ||||
-rw-r--r-- | source/smbd/notify_hash.c | 20 | ||||
-rw-r--r-- | source/smbd/nttrans.c | 31 | ||||
-rw-r--r-- | source/smbd/open.c | 2 | ||||
-rw-r--r-- | source/smbd/oplock.c | 44 | ||||
-rw-r--r-- | source/smbd/oplock_irix.c | 13 | ||||
-rw-r--r-- | source/smbd/oplock_linux.c | 7 | ||||
-rw-r--r-- | source/smbd/password.c | 10 | ||||
-rw-r--r-- | source/smbd/process.c | 1 | ||||
-rw-r--r-- | source/smbd/reply.c | 15 | ||||
-rw-r--r-- | source/smbd/server.c | 2 | ||||
-rw-r--r-- | source/smbd/service.c | 41 | ||||
-rw-r--r-- | source/smbd/sesssetup.c | 93 | ||||
-rw-r--r-- | source/smbd/share_access.c | 3 | ||||
-rw-r--r-- | source/smbd/trans2.c | 41 | ||||
-rw-r--r-- | source/smbd/vfs-wrap.c | 2 | ||||
-rw-r--r-- | source/smbd/vfs.c | 2 |
23 files changed, 326 insertions, 200 deletions
diff --git a/source/smbd/close.c b/source/smbd/close.c index bc1182032d7..8a63d3b227b 100644 --- a/source/smbd/close.c +++ b/source/smbd/close.c @@ -143,54 +143,15 @@ static void notify_deferred_opens(struct share_mode_lock *lck) } /**************************************************************************** - Close a file. - - close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE. - printing and magic scripts are only run on normal close. - delete on close is done on normal and shutdown close. + Deal with removing a share mode on last close. ****************************************************************************/ -static int close_normal_file(files_struct *fsp, enum file_close_type close_type) +static int close_remove_share_mode(files_struct *fsp, enum file_close_type close_type) { - BOOL delete_file = False; connection_struct *conn = fsp->conn; - int saved_errno = 0; - int err = 0; - int err1 = 0; + BOOL delete_file = False; struct share_mode_lock *lck; - remove_pending_lock_requests_by_fid(fsp); - - if (fsp->aio_write_behind) { - /* - * If we're finishing write behind on a close we can get a write - * error here, we must remember this. - */ - int ret = wait_for_aio_completion(fsp); - if (ret) { - saved_errno = ret; - err1 = -1; - } - } else { - cancel_aio_by_fsp(fsp); - } - - /* - * If we're flushing on a close we can get a write - * error here, we must remember this. - */ - - if (close_filestruct(fsp) == -1) { - saved_errno = errno; - err1 = -1; - } - - if (fsp->print_file) { - print_fsp_end(fsp, close_type); - file_free(fsp); - return 0; - } - /* * Lock the share entries, and determine if we should delete * on close. If so delete whilst the lock is still in effect. @@ -200,12 +161,12 @@ static int close_normal_file(files_struct *fsp, enum file_close_type close_type) lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL); if (lck == NULL) { - DEBUG(0, ("close_file: Could not get share mode lock for file %s\n", fsp->fsp_name)); + DEBUG(0, ("close_remove_share_mode: Could not get share mode lock for file %s\n", fsp->fsp_name)); return EINVAL; } if (!del_share_mode(lck, fsp)) { - DEBUG(0, ("close_file: Could not delete share entry for file %s\n", fsp->fsp_name)); + DEBUG(0, ("close_remove_share_mode: Could not delete share entry for file %s\n", fsp->fsp_name)); } delete_file = (lck->delete_on_close | lck->initial_delete_on_close); @@ -236,13 +197,13 @@ static int close_normal_file(files_struct *fsp, enum file_close_type close_type) lck->delete_token) { SMB_STRUCT_STAT sbuf; - DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n", + DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set - deleting file.\n", fsp->fsp_name)); /* Become the user who requested the delete. */ if (!push_sec_ctx()) { - smb_panic("close_file: file %s. failed to push sec_ctx.\n"); + smb_panic("close_remove_share_mode: file %s. failed to push sec_ctx.\n"); } set_sec_ctx(lck->delete_token->uid, @@ -253,17 +214,17 @@ static int close_normal_file(files_struct *fsp, enum file_close_type close_type) /* We can only delete the file if the name we have is still valid and hasn't been renamed. */ - + if(SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf) != 0) { - DEBUG(5,("close_file: file %s. Delete on close was set " + DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set " "and stat failed with error %s\n", fsp->fsp_name, strerror(errno) )); } else { if(sbuf.st_dev != fsp->dev || sbuf.st_ino != fsp->inode) { - DEBUG(5,("close_file: file %s. Delete on close was set and " + DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set and " "dev and/or inode does not match\n", fsp->fsp_name )); - DEBUG(5,("close_file: file %s. stored dev = %x, inode = %.0f " + DEBUG(5,("close_remove_share_mode: file %s. stored dev = %x, inode = %.0f " "stat dev = %x, inode = %.0f\n", fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, @@ -277,21 +238,80 @@ static int close_normal_file(files_struct *fsp, enum file_close_type close_type) * we log this but not at debug level zero. */ - DEBUG(5,("close_file: file %s. Delete on close was set " + DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set " "and unlink failed with error %s\n", fsp->fsp_name, strerror(errno) )); } } /* unbecome user. */ pop_sec_ctx(); - + process_pending_change_notify_queue((time_t)0); } TALLOC_FREE(lck); + return 0; +} + +/**************************************************************************** + Close a file. + + close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE. + printing and magic scripts are only run on normal close. + delete on close is done on normal and shutdown close. +****************************************************************************/ + +static int close_normal_file(files_struct *fsp, enum file_close_type close_type) +{ + connection_struct *conn = fsp->conn; + int saved_errno = 0; + int err = 0; + int err1 = 0; - if(fsp->oplock_type) + remove_pending_lock_requests_by_fid(fsp); + + if (fsp->aio_write_behind) { + /* + * If we're finishing write behind on a close we can get a write + * error here, we must remember this. + */ + int ret = wait_for_aio_completion(fsp); + if (ret) { + saved_errno = ret; + err1 = -1; + } + } else { + cancel_aio_by_fsp(fsp); + } + + /* + * If we're flushing on a close we can get a write + * error here, we must remember this. + */ + + if (close_filestruct(fsp) == -1) { + saved_errno = errno; + err1 = -1; + } + + if (fsp->print_file) { + print_fsp_end(fsp, close_type); + file_free(fsp); + return 0; + } + + /* If this is an old DOS or FCB open and we have multiple opens on + the same handle we only have one share mode. Ensure we only remove + the share mode on the last close. */ + + if (fsp->fh->ref_count == 1) { + /* Should we return on error here... ? */ + close_remove_share_mode(fsp, close_type); + } + + if(fsp->oplock_type) { release_file_oplock(fsp); + } locking_close_file(fsp); @@ -323,9 +343,6 @@ static int close_normal_file(files_struct *fsp, enum file_close_type close_type) conn->num_files_open, (err == -1 || err1 == -1) ? strerror(saved_errno) : "")); - if (fsp->fsp_name) - string_free(&fsp->fsp_name); - file_free(fsp); if (err == -1 || err1 == -1) { @@ -410,11 +427,6 @@ static int close_directory(files_struct *fsp, enum file_close_type close_type) * Do the code common to files and directories. */ close_filestruct(fsp); - - if (fsp->fsp_name) { - string_free(&fsp->fsp_name); - } - file_free(fsp); return 0; } @@ -429,10 +441,6 @@ static int close_stat(files_struct *fsp) * Do the code common to files and directories. */ close_filestruct(fsp); - - if (fsp->fsp_name) - string_free(&fsp->fsp_name); - file_free(fsp); return 0; } @@ -447,6 +455,8 @@ int close_file(files_struct *fsp, enum file_close_type close_type) return close_directory(fsp, close_type); else if (fsp->is_stat) return close_stat(fsp); + else if (fsp->fake_file_handle != NULL) + return close_fake_file(fsp); else return close_normal_file(fsp, close_type); } diff --git a/source/smbd/dir.c b/source/smbd/dir.c index cd6c1b0bda3..27a4182c220 100644 --- a/source/smbd/dir.c +++ b/source/smbd/dir.c @@ -719,7 +719,7 @@ struct dptr_struct *dptr_fetch_lanman2(int dptr_num) } /**************************************************************************** - Check a filetype for being valid. + Check that a file matches a particular file type. ****************************************************************************/ BOOL dir_check_ftype(connection_struct *conn, uint32 mode, uint32 dirtype) diff --git a/source/smbd/fake_file.c b/source/smbd/fake_file.c index 1356baf1a81..b4f1f02b724 100644 --- a/source/smbd/fake_file.c +++ b/source/smbd/fake_file.c @@ -156,3 +156,9 @@ void destroy_fake_file_handle(FAKE_FILE_HANDLE **fh) talloc_destroy((*fh)->mem_ctx); (*fh) = NULL; } + +int close_fake_file(files_struct *fsp) +{ + file_free(fsp); + return 0; +} diff --git a/source/smbd/files.c b/source/smbd/files.c index ba4baa93b10..e020d8e13a6 100644 --- a/source/smbd/files.c +++ b/source/smbd/files.c @@ -32,8 +32,6 @@ static files_struct *Files; /* a fsp to use when chaining */ static files_struct *chain_fsp = NULL; -/* a fsp to use to save when breaking an oplock. */ -static files_struct *oplock_save_chain_fsp = NULL; static int files_used; @@ -109,7 +107,7 @@ files_struct *file_new(connection_struct *conn) fsp->fh->fd = -1; fsp->conn = conn; - fsp->file_id = get_gen_count(); + fsp->fh->file_id = get_gen_count(); GetTimeOfDay(&fsp->open_time); first_file = (i+1) % real_max_open_files; @@ -238,7 +236,7 @@ void file_dump_open_table(void) for (fsp=Files;fsp;fsp=fsp->next,count++) { DEBUG(10,("Files[%d], fnum = %d, name %s, fd = %d, fileid = %lu, dev = %x, inode = %.0f\n", - count, fsp->fnum, fsp->fsp_name, fsp->fh->fd, (unsigned long)fsp->file_id, + count, fsp->fnum, fsp->fsp_name, fsp->fh->fd, (unsigned long)fsp->fh->file_id, (unsigned int)fsp->dev, (double)fsp->inode )); } } @@ -277,7 +275,7 @@ files_struct *file_find_dif(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_i /* We can have a fsp->fh->fd == -1 here as it could be a stat open. */ if (fsp->dev == dev && fsp->inode == inode && - fsp->file_id == file_id ) { + fsp->fh->file_id == file_id ) { if (count > 10) { DLIST_PROMOTE(Files, fsp); } @@ -287,7 +285,7 @@ files_struct *file_find_dif(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_i (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) { DEBUG(0,("file_find_dif: file %s dev = %x, inode = %.0f, file_id = %u \ oplock_type = %u is a stat open with oplock type !\n", fsp->fsp_name, (unsigned int)fsp->dev, - (double)fsp->inode, (unsigned int)fsp->file_id, + (double)fsp->inode, (unsigned int)fsp->fh->file_id, (unsigned int)fsp->oplock_type )); smb_panic("file_find_dif\n"); } @@ -503,24 +501,6 @@ void file_chain_reset(void) } /**************************************************************************** - Save the chained fsp - done when about to do an oplock break. -****************************************************************************/ - -void file_chain_save(void) -{ - oplock_save_chain_fsp = chain_fsp; -} - -/**************************************************************************** - Restore the chained fsp - done after an oplock break. -****************************************************************************/ - -void file_chain_restore(void) -{ - chain_fsp = oplock_save_chain_fsp; -} - -/**************************************************************************** Duplicate the file handle part for a DOS or FCB open. ****************************************************************************/ diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c index 1b5a5f39c72..7f9505606cc 100644 --- a/source/smbd/ipc.c +++ b/source/smbd/ipc.c @@ -433,8 +433,8 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, START_PROFILE(SMBtrans); - if (!NT_STATUS_IS_OK(allow_new_trans(conn->pending_trans, - SVAL(inbuf, smb_mid)))) { + result = allow_new_trans(conn->pending_trans, SVAL(inbuf, smb_mid)); + if (!NT_STATUS_IS_OK(result)) { DEBUG(2, ("Got invalid trans request: %s\n", nt_errstr(result))); END_PROFILE(SMBtrans); diff --git a/source/smbd/msdfs.c b/source/smbd/msdfs.c index 4606441c3a9..700aa2ae81c 100644 --- a/source/smbd/msdfs.c +++ b/source/smbd/msdfs.c @@ -419,7 +419,10 @@ BOOL dfs_redirect( pstring pathname, connection_struct *conn, BOOL search_wcard_ return False; } - if (!strequal(dp.servicename, lp_servicename(SNUM(conn)) )) { + if ( !( strequal(dp.servicename, lp_servicename(SNUM(conn))) + || ( strequal(dp.servicename, HOMES_NAME) + && strequal(lp_servicename(SNUM(conn)), get_current_username()) )) ) + { return False; } diff --git a/source/smbd/notify.c b/source/smbd/notify.c index b2d0fc33262..829ca3a736d 100644 --- a/source/smbd/notify.c +++ b/source/smbd/notify.c @@ -135,7 +135,19 @@ void remove_pending_change_notify_requests_by_filename(files_struct *fsp, NTSTAT } /**************************************************************************** - Return true if there are pending change notifies. + Set the current change notify timeout to the lowest value across all service + values. +****************************************************************************/ + +void set_change_notify_timeout(int val) +{ + if (val > 0) { + cnotify->select_time = MIN(cnotify->select_time, val); + } +} + +/**************************************************************************** + Longest time to sleep for before doing a change notify scan. ****************************************************************************/ int change_notify_timeout(void) diff --git a/source/smbd/notify_hash.c b/source/smbd/notify_hash.c index a98a028fae0..0787a3eec5e 100644 --- a/source/smbd/notify_hash.c +++ b/source/smbd/notify_hash.c @@ -81,6 +81,11 @@ static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags, return True; } + if (lp_change_notify_timeout(SNUM(conn)) <= 0) { + /* It change notify timeout has been disabled, never scan the directory. */ + return True; + } + /* * If we are to watch for changes that are only stored * in inodes of files, not in the directory inode, we must @@ -179,9 +184,17 @@ static BOOL hash_check_notify(connection_struct *conn, uint16 vuid, char *path, { struct change_data *data = (struct change_data *)datap; struct change_data data2; + int cnto = lp_change_notify_timeout(SNUM(conn)); + + if (t && cnto <= 0) { + /* Change notify turned off on this share. + * Only scan when (t==0) - we think something changed. */ + return False; + } - if (t && t < data->last_check_time + lp_change_notify_timeout()) + if (t && t < data->last_check_time + cnto) { return False; + } if (!change_to_user(conn,vuid)) return True; @@ -201,8 +214,9 @@ static BOOL hash_check_notify(connection_struct *conn, uint16 vuid, char *path, return True; } - if (t) + if (t) { data->last_check_time = t; + } change_to_root_user(); @@ -229,7 +243,7 @@ struct cnotify_fns *hash_notify_init(void) cnotify.register_notify = hash_register_notify; cnotify.check_notify = hash_check_notify; cnotify.remove_notify = hash_remove_notify; - cnotify.select_time = lp_change_notify_timeout(); + cnotify.select_time = 60; /* Start with 1 minute default. */ cnotify.notification_fd = -1; return &cnotify; diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c index 839eb7bb279..3cdc4997b23 100644 --- a/source/smbd/nttrans.c +++ b/source/smbd/nttrans.c @@ -2719,6 +2719,7 @@ static int handle_nttrans(connection_struct *conn, /* Now we must call the relevant NT_TRANS function */ switch(state->call) { case NT_TRANSACT_CREATE: + { START_PROFILE_NESTED(NT_transact_create); outsize = call_nt_transact_create(conn, inbuf, outbuf, size, bufsize, @@ -2728,7 +2729,10 @@ static int handle_nttrans(connection_struct *conn, state->max_data_return); END_PROFILE_NESTED(NT_transact_create); break; + } + case NT_TRANSACT_IOCTL: + { START_PROFILE_NESTED(NT_transact_ioctl); outsize = call_nt_transact_ioctl(conn, inbuf, outbuf, size, bufsize, @@ -2737,7 +2741,10 @@ static int handle_nttrans(connection_struct *conn, &state->data, state->total_data, state->max_data_return); END_PROFILE_NESTED(NT_transact_ioctl); break; + } + case NT_TRANSACT_SET_SECURITY_DESC: + { START_PROFILE_NESTED(NT_transact_set_security_desc); outsize = call_nt_transact_set_security_desc(conn, inbuf, outbuf, size, bufsize, @@ -2746,7 +2753,10 @@ static int handle_nttrans(connection_struct *conn, &state->data, state->total_data, state->max_data_return); END_PROFILE_NESTED(NT_transact_set_security_desc); break; + } + case NT_TRANSACT_NOTIFY_CHANGE: + { START_PROFILE_NESTED(NT_transact_notify_change); outsize = call_nt_transact_notify_change(conn, inbuf, outbuf, size, bufsize, @@ -2755,7 +2765,10 @@ static int handle_nttrans(connection_struct *conn, &state->data, state->total_data, state->max_data_return); END_PROFILE_NESTED(NT_transact_notify_change); break; + } + case NT_TRANSACT_RENAME: + { START_PROFILE_NESTED(NT_transact_rename); outsize = call_nt_transact_rename(conn, inbuf, outbuf, size, bufsize, @@ -2764,8 +2777,10 @@ static int handle_nttrans(connection_struct *conn, &state->data, state->total_data, state->max_data_return); END_PROFILE_NESTED(NT_transact_rename); break; + } case NT_TRANSACT_QUERY_SECURITY_DESC: + { START_PROFILE_NESTED(NT_transact_query_security_desc); outsize = call_nt_transact_query_security_desc(conn, inbuf, outbuf, size, bufsize, @@ -2774,8 +2789,11 @@ static int handle_nttrans(connection_struct *conn, &state->data, state->total_data, state->max_data_return); END_PROFILE_NESTED(NT_transact_query_security_desc); break; + } + #ifdef HAVE_SYS_QUOTAS case NT_TRANSACT_GET_USER_QUOTA: + { START_PROFILE_NESTED(NT_transact_get_user_quota); outsize = call_nt_transact_get_user_quota(conn, inbuf, outbuf, size, bufsize, @@ -2784,7 +2802,10 @@ static int handle_nttrans(connection_struct *conn, &state->data, state->total_data, state->max_data_return); END_PROFILE_NESTED(NT_transact_get_user_quota); break; + } + case NT_TRANSACT_SET_USER_QUOTA: + { START_PROFILE_NESTED(NT_transact_set_user_quota); outsize = call_nt_transact_set_user_quota(conn, inbuf, outbuf, size, bufsize, @@ -2793,7 +2814,9 @@ static int handle_nttrans(connection_struct *conn, &state->data, state->total_data, state->max_data_return); END_PROFILE_NESTED(NT_transact_set_user_quota); break; + } #endif /* HAVE_SYS_QUOTAS */ + default: /* Error in request */ DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", @@ -2827,8 +2850,8 @@ int reply_nttrans(connection_struct *conn, return ERROR_DOS(ERRSRV,ERRaccess); } - if (!NT_STATUS_IS_OK(allow_new_trans(conn->pending_trans, - SVAL(inbuf, smb_mid)))) { + result = allow_new_trans(conn->pending_trans, SVAL(inbuf, smb_mid)); + if (!NT_STATUS_IS_OK(result)) { DEBUG(2, ("Got invalid nttrans request: %s\n", nt_errstr(result))); END_PROFILE(SMBnttrans); return ERROR_NT(result); @@ -2881,7 +2904,7 @@ int reply_nttrans(connection_struct *conn, DEBUG(0,("reply_nttrans: data malloc fail for %u " "bytes !\n", state->total_data)); TALLOC_FREE(state); - END_PROFILE(SMBtrans); + END_PROFILE(SMBnttrans); return(ERROR_DOS(ERRDOS,ERRnomem)); } if ((dsoff+dscnt < dsoff) || (dsoff+dscnt < dscnt)) @@ -2901,7 +2924,7 @@ int reply_nttrans(connection_struct *conn, "bytes !\n", state->total_param)); SAFE_FREE(state->data); TALLOC_FREE(state); - END_PROFILE(SMBtrans); + END_PROFILE(SMBnttrans); return(ERROR_DOS(ERRDOS,ERRnomem)); } if ((psoff+pscnt < psoff) || (psoff+pscnt < pscnt)) diff --git a/source/smbd/open.c b/source/smbd/open.c index edc5bc98b6e..3d537b2f394 100644 --- a/source/smbd/open.c +++ b/source/smbd/open.c @@ -1308,7 +1308,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, */ #if defined(O_SYNC) - if (create_options & FILE_WRITE_THROUGH) { + if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) { flags2 |= O_SYNC; } #endif /* O_SYNC */ diff --git a/source/smbd/oplock.c b/source/smbd/oplock.c index 70e5bf4d727..42c64a28435 100644 --- a/source/smbd/oplock.c +++ b/source/smbd/oplock.c @@ -20,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define DBGC_CLASS DBGC_LOCKING #include "includes.h" /* Current number of oplocks we have outstanding. */ @@ -88,7 +89,7 @@ void process_kernel_oplocks(fd_set *pfds) /* Put the kernel break info into the message. */ SDEV_T_VAL(msg,0,fsp->dev); SINO_T_VAL(msg,8,fsp->inode); - SIVAL(msg,16,fsp->file_id); + SIVAL(msg,16,fsp->fh->file_id); /* Don't need to be root here as we're only ever sending to ourselves. */ @@ -118,10 +119,11 @@ BOOL set_file_oplock(files_struct *fsp, int oplock_type) exclusive_oplocks_open++; } - DEBUG(5,("set_file_oplock: granted oplock on file %s, dev = %x, inode = %.0f, file_id = %lu, \ -tv_sec = %x, tv_usec = %x\n", - fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id, - (int)fsp->open_time.tv_sec, (int)fsp->open_time.tv_usec )); + DEBUG(5,("set_file_oplock: granted oplock on file %s, 0x%x/%.0f/%lu, " + "tv_sec = %x, tv_usec = %x\n", + fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, + fsp->fh->file_id, (int)fsp->open_time.tv_sec, + (int)fsp->open_time.tv_usec )); return True; } @@ -191,7 +193,7 @@ BOOL remove_oplock(files_struct *fsp) ret = remove_share_oplock(lck, fsp); if (!ret) { DEBUG(0,("remove_oplock: failed to remove share oplock for " - "file %s fnum %d, dev = %x, inode = %.0f\n", + "file %s fnum %d, 0x%x/%.0f\n", fsp->fsp_name, fsp->fnum, (unsigned int)dev, (double)inode)); } @@ -292,8 +294,8 @@ static files_struct *initial_break_processing(SMB_DEV_T dev, SMB_INO_T inode, un files_struct *fsp = NULL; if( DEBUGLVL( 3 ) ) { - dbgtext( "initial_break_processing: called for dev = 0x%x, inode = %.0f file_id = %lu\n", - (unsigned int)dev, (double)inode, file_id); + dbgtext( "initial_break_processing: called for 0x%x/%.0f/%u\n", + (unsigned int)dev, (double)inode, (int)file_id); dbgtext( "Current oplocks_open (exclusive = %d, levelII = %d)\n", exclusive_oplocks_open, level_II_oplocks_open ); } @@ -331,7 +333,7 @@ static files_struct *initial_break_processing(SMB_DEV_T dev, SMB_INO_T inode, un if( DEBUGLVL( 3 ) ) { dbgtext( "initial_break_processing: file %s ", fsp->fsp_name ); dbgtext( "(dev = %x, inode = %.0f, file_id = %lu) has no oplock.\n", - (unsigned int)dev, (double)inode, fsp->file_id ); + (unsigned int)dev, (double)inode, fsp->fh->file_id ); dbgtext( "Allowing break to succeed regardless.\n" ); } return NULL; @@ -403,9 +405,9 @@ static void process_oplock_async_level2_break_message(int msg_type, struct proce /* De-linearize incoming message. */ message_to_share_mode_entry(&msg, buf); - DEBUG(10, ("Got oplock async level 2 break message from pid %d: 0x%x/%.0f/%d\n", - (int)procid_to_pid(&src), (unsigned int)msg.dev, (double)msg.inode, - (int)msg.share_file_id)); + DEBUG(10, ("Got oplock async level 2 break message from pid %d: 0x%x/%.0f/%lu\n", + (int)procid_to_pid(&src), (unsigned int)msg.dev, + (double)msg.inode, msg.share_file_id)); fsp = initial_break_processing(msg.dev, msg.inode, msg.share_file_id); @@ -490,9 +492,9 @@ static void process_oplock_break_message(int msg_type, struct process_id src, /* De-linearize incoming message. */ message_to_share_mode_entry(&msg, buf); - DEBUG(10, ("Got oplock break message from pid %d: 0x%x/%.0f/%d\n", - (int)procid_to_pid(&src), (unsigned int)msg.dev, (double)msg.inode, - (int)msg.share_file_id)); + DEBUG(10, ("Got oplock break message from pid %d: 0x%x/%.0f/%lu\n", + (int)procid_to_pid(&src), (unsigned int)msg.dev, + (double)msg.inode, msg.share_file_id)); fsp = initial_break_processing(msg.dev, msg.inode, msg.share_file_id); @@ -693,9 +695,10 @@ static void process_oplock_break_response(int msg_type, struct process_id src, /* De-linearize incoming message. */ message_to_share_mode_entry(&msg, buf); - DEBUG(10, ("Got oplock break response from pid %d: 0x%x/%.0f/%u mid %u\n", - (int)procid_to_pid(&src), (unsigned int)msg.dev, (double)msg.inode, - (unsigned int)msg.share_file_id, (unsigned int)msg.op_mid)); + DEBUG(10, ("Got oplock break response from pid %d: 0x%x/%.0f/%lu mid %u\n", + (int)procid_to_pid(&src), (unsigned int)msg.dev, + (double)msg.inode, msg.share_file_id, + (unsigned int)msg.op_mid)); /* Here's the hack from open.c, store the mid in the 'port' field */ schedule_deferred_open_smb_message(msg.op_mid); @@ -719,8 +722,9 @@ static void process_open_retry_message(int msg_type, struct process_id src, /* De-linearize incoming message. */ message_to_share_mode_entry(&msg, buf); - DEBUG(10, ("Got open retry msg from pid %d: 0x%x/%.0f mid %u\n", - (int)procid_to_pid(&src), (unsigned int)msg.dev, (double)msg.inode, + DEBUG(10, ("Got open retry msg from pid %d: 0x%x/%.0f/%lu mid %u\n", + (int)procid_to_pid(&src), (unsigned int)msg.dev, + (double)msg.inode, msg.share_file_id, (unsigned int)msg.op_mid)); schedule_deferred_open_smb_message(msg.op_mid); diff --git a/source/smbd/oplock_irix.c b/source/smbd/oplock_irix.c index 83883444a7b..248d9020283 100644 --- a/source/smbd/oplock_irix.c +++ b/source/smbd/oplock_irix.c @@ -18,6 +18,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define DBGC_CLASS DBGC_LOCKING #include "includes.h" #if HAVE_KERNEL_OPLOCKS_IRIX @@ -144,7 +145,7 @@ static files_struct *irix_oplock_receive_message(fd_set *fds) DEBUG(5,("irix_oplock_receive_message: kernel oplock break request " "received for dev = %x, inode = %.0f\n, file_id = %ul", - (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id )); + (unsigned int)fsp->dev, (double)fsp->inode, fsp->fh->file_id )); return fsp; } @@ -159,18 +160,18 @@ static BOOL irix_set_kernel_oplock(files_struct *fsp, int oplock_type) if(errno != EAGAIN) { DEBUG(0,("irix_set_kernel_oplock: Unable to get kernel oplock on file %s, dev = %x, \ inode = %.0f, file_id = %ul. Error was %s\n", - fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id, + fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->fh->file_id, strerror(errno) )); } else { DEBUG(5,("irix_set_kernel_oplock: Refused oplock on file %s, fd = %d, dev = %x, \ inode = %.0f, file_id = %ul. Another process had the file open.\n", - fsp->fsp_name, fsp->fh->fd, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id )); + fsp->fsp_name, fsp->fh->fd, (unsigned int)fsp->dev, (double)fsp->inode, fsp->fh->file_id )); } return False; } DEBUG(10,("irix_set_kernel_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f, file_id = %ul\n", - fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id)); + fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->fh->file_id)); return True; } @@ -189,7 +190,7 @@ static void irix_release_kernel_oplock(files_struct *fsp) int state = sys_fcntl_long(fsp->fh->fd, F_OPLKACK, -1); dbgtext("irix_release_kernel_oplock: file %s, dev = %x, inode = %.0f file_id = %ul, has kernel \ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev, - (double)fsp->inode, fsp->file_id, state ); + (double)fsp->inode, fsp->fh->file_id, state ); } /* @@ -200,7 +201,7 @@ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev, dbgtext("irix_release_kernel_oplock: Error when removing kernel oplock on file " ); dbgtext("%s, dev = %x, inode = %.0f, file_id = %ul. Error was %s\n", fsp->fsp_name, (unsigned int)fsp->dev, - (double)fsp->inode, fsp->file_id, strerror(errno) ); + (double)fsp->inode, fsp->fh->file_id, strerror(errno) ); } } } diff --git a/source/smbd/oplock_linux.c b/source/smbd/oplock_linux.c index ab0c08f7fcc..f186c13ebdd 100644 --- a/source/smbd/oplock_linux.c +++ b/source/smbd/oplock_linux.c @@ -18,6 +18,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define DBGC_CLASS DBGC_LOCKING #include "includes.h" #if HAVE_KERNEL_OPLOCKS_LINUX @@ -163,7 +164,7 @@ inode = %.0f. (%s)\n", } DEBUG(3,("linux_set_kernel_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f, file_id = %lu\n", - fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id)); + fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->fh->file_id)); return True; } @@ -182,7 +183,7 @@ static void linux_release_kernel_oplock(files_struct *fsp) int state = fcntl(fsp->fh->fd, F_GETLEASE, 0); dbgtext("linux_release_kernel_oplock: file %s, dev = %x, inode = %.0f file_id = %lu has kernel \ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev, - (double)fsp->inode, fsp->file_id, state ); + (double)fsp->inode, fsp->fh->file_id, state ); } /* @@ -193,7 +194,7 @@ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev, dbgtext("linux_release_kernel_oplock: Error when removing kernel oplock on file " ); dbgtext("%s, dev = %x, inode = %.0f, file_id = %lu. Error was %s\n", fsp->fsp_name, (unsigned int)fsp->dev, - (double)fsp->inode, fsp->file_id, strerror(errno) ); + (double)fsp->inode, fsp->fh->file_id, strerror(errno) ); } } } diff --git a/source/smbd/password.c b/source/smbd/password.c index 8d33c1deed1..73b0ebb4b32 100644 --- a/source/smbd/password.c +++ b/source/smbd/password.c @@ -155,10 +155,9 @@ int register_vuid(auth_serversupplied_info *server_info, { user_struct *vuser = NULL; - /* Ensure no vuid gets registered in share level security. */ + /* Paranoia check. */ if(lp_security() == SEC_SHARE) { - data_blob_free(&session_key); - return UID_FIELD_INVALID; + smb_panic("Tried to register uid in security=share\n"); } /* Limit allowed vuids to 16bits - VUID_OFFSET. */ @@ -189,6 +188,11 @@ int register_vuid(auth_serversupplied_info *server_info, vuser->vuid = next_vuid; if (!server_info) { + /* + * This happens in an unfinished NTLMSSP session setup. We + * need to allocate a vuid between the first and second calls + * to NTLMSSP. + */ next_vuid++; num_validated_vuids++; diff --git a/source/smbd/process.c b/source/smbd/process.c index aaf98203a25..440d0ac0a50 100644 --- a/source/smbd/process.c +++ b/source/smbd/process.c @@ -43,7 +43,6 @@ int max_send = BUFFER_SIZE; int max_recv = BUFFER_SIZE; extern int last_message; -extern userdom_struct current_user_info; extern int smb_read_error; SIG_ATOMIC_T reload_after_sighup = 0; SIG_ATOMIC_T got_sig_term = 0; diff --git a/source/smbd/reply.c b/source/smbd/reply.c index 0524078310f..387ed4a47f4 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -1085,12 +1085,13 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size BOOL mask_contains_wcard = False; BOOL allow_long_path_components = (SVAL(inbuf,smb_flg2) & FLAGS2_LONG_PATH_COMPONENTS) ? True : False; + START_PROFILE(SMBsearch); + if (lp_posix_pathnames()) { + END_PROFILE(SMBsearch); return reply_unknown(inbuf, outbuf); } - START_PROFILE(SMBsearch); - *mask = *directory = *fname = 0; /* If we were called as SMBffirst then we must expect close. */ @@ -1284,12 +1285,13 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size NTSTATUS err; BOOL path_contains_wcard = False; + START_PROFILE(SMBfclose); + if (lp_posix_pathnames()) { + END_PROFILE(SMBfclose); return reply_unknown(inbuf, outbuf); } - START_PROFILE(SMBfclose); - outsize = set_message(outbuf,1,0,True); p = smb_buf(inbuf) + 1; p += srvstr_get_path_wcard(inbuf, path, p, sizeof(path), 0, STR_TERMINATE, &err, &path_contains_wcard); @@ -1517,13 +1519,13 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size); if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) { close_file(fsp,ERROR_CLOSE); - END_PROFILE(SMBntcreateX); + END_PROFILE(SMBopenX); return ERROR_NT(NT_STATUS_DISK_FULL); } retval = vfs_set_filelen(fsp, (SMB_OFF_T)allocation_size); if (retval < 0) { close_file(fsp,ERROR_CLOSE); - END_PROFILE(SMBwrite); + END_PROFILE(SMBopenX); return ERROR_NT(NT_STATUS_DISK_FULL); } size = get_allocation_size(conn,fsp,&sbuf); @@ -2629,7 +2631,6 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length nread = read_file(fsp,data,startpos,smb_maxcnt); if (nread < 0) { - END_PROFILE(SMBreadX); return(UNIXERROR(ERRDOS,ERRnoaccess)); } diff --git a/source/smbd/server.c b/source/smbd/server.c index b76ade957c2..d16579f24a8 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -22,6 +22,8 @@ #include "includes.h" +static_decl_rpc; + static int am_parent = 1; /* the last message the was processed */ diff --git a/source/smbd/service.c b/source/smbd/service.c index ba87d0743da..cb9bfcc27ae 100644 --- a/source/smbd/service.c +++ b/source/smbd/service.c @@ -523,8 +523,12 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, return NULL; } + conn->nt_user_token = NULL; + if (lp_guest_only(snum)) { const char *guestname = lp_guestaccount(); + NTSTATUS status2; + char *found_username; guest = True; pass = getpwnam_alloc(NULL, guestname); if (!pass) { @@ -534,11 +538,18 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, *status = NT_STATUS_NO_SUCH_USER; return NULL; } - fstrcpy(user,pass->pw_name); + status2 = create_token_from_username(NULL, pass->pw_name, True, + &conn->uid, &conn->gid, + &found_username, + &conn->nt_user_token); + if (!NT_STATUS_IS_OK(status2)) { + conn_free(conn); + *status = status2; + return NULL; + } + fstrcpy(user, found_username); + string_set(&conn->user,user); conn->force_user = True; - conn->uid = pass->pw_uid; - conn->gid = pass->pw_gid; - string_set(&conn->user,pass->pw_name); TALLOC_FREE(pass); DEBUG(3,("Guest only user %s\n",user)); } else if (vuser) { @@ -570,6 +581,8 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, fstrcpy(user,vuser->user.unix_name); guest = vuser->guest; } else if (lp_security() == SEC_SHARE) { + NTSTATUS status2; + char *found_username; /* add it as a possible user name if we are in share mode security */ add_session_user(lp_servicename(snum)); @@ -582,12 +595,18 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, return NULL; } pass = Get_Pwnam(user); + status2 = create_token_from_username(NULL, pass->pw_name, True, + &conn->uid, &conn->gid, + &found_username, + &conn->nt_user_token); + if (!NT_STATUS_IS_OK(status2)) { + conn_free(conn); + *status = status2; + return NULL; + } + fstrcpy(user, found_username); + string_set(&conn->user,user); conn->force_user = True; - conn->uid = pass->pw_uid; - conn->gid = pass->pw_gid; - string_set(&conn->user, pass->pw_name); - fstrcpy(user, pass->pw_name); - } else { DEBUG(0, ("invalid VUID (vuser) but not in security=share\n")); conn_free(conn); @@ -626,7 +645,6 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, conn->aio_write_behind_list = NULL; string_set(&conn->dirpath,""); string_set(&conn->user,user); - conn->nt_user_token = NULL; conn->read_only = lp_readonly(conn->service); conn->admin_user = False; @@ -930,6 +948,9 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, dbgtext( "(pid %d)\n", (int)sys_getpid() ); } + /* Setup the minimum value for a change notify wait time (seconds). */ + set_change_notify_timeout(lp_change_notify_timeout(snum)); + /* we've finished with the user stuff - go back to root */ change_to_root_user(); return(conn); diff --git a/source/smbd/sesssetup.c b/source/smbd/sesssetup.c index 7c90263a5b0..46acb20bdad 100644 --- a/source/smbd/sesssetup.c +++ b/source/smbd/sesssetup.c @@ -96,7 +96,7 @@ static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf, char *p; if (!NT_STATUS_IS_OK(nt_status) && !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - ERROR_NT(nt_status); + ERROR_NT(nt_status_squash(nt_status)); } else { set_message(outbuf,4,0,True); @@ -176,6 +176,7 @@ static int reply_spnego_kerberos(connection_struct *conn, DATA_BLOB nullblob = data_blob(NULL, 0); fstring real_username; BOOL map_domainuser_to_guest = False; + BOOL username_was_mapped; PAC_LOGON_INFO *logon_info = NULL; ZERO_STRUCT(ticket); @@ -186,21 +187,21 @@ static int reply_spnego_kerberos(connection_struct *conn, mem_ctx = talloc_init("reply_spnego_kerberos"); if (mem_ctx == NULL) - return ERROR_NT(NT_STATUS_NO_MEMORY); + return ERROR_NT(nt_status_squash(NT_STATUS_NO_MEMORY)); if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) { talloc_destroy(mem_ctx); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } - ret = ads_verify_ticket(mem_ctx, lp_realm(), &ticket, &client, &pac_data, &ap_rep, &session_key); + ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket, &client, &pac_data, &ap_rep, &session_key); data_blob_free(&ticket); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1,("Failed to verify incoming ticket!\n")); talloc_destroy(mem_ctx); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } DEBUG(3,("Ticket name is [%s]\n", client)); @@ -212,7 +213,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&session_key); SAFE_FREE(client); talloc_destroy(mem_ctx); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } *p = 0; @@ -233,7 +234,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&session_key); SAFE_FREE(client); talloc_destroy(mem_ctx); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } } @@ -288,7 +289,7 @@ static int reply_spnego_kerberos(connection_struct *conn, /* lookup the passwd struct, create a new user if necessary */ - map_username( user ); + username_was_mapped = map_username( user ); pw = smb_getpwnam( mem_ctx, user, real_username, True ); if (!pw) { @@ -311,7 +312,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&session_key); talloc_destroy(mem_ctx); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } } @@ -322,7 +323,7 @@ static int reply_spnego_kerberos(connection_struct *conn, if ( map_domainuser_to_guest ) { make_server_info_guest(&server_info); } else if (logon_info) { - ret = make_server_info_info3(mem_ctx, real_username, real_username, domain, + ret = make_server_info_info3(mem_ctx, real_username, domain, &server_info, &logon_info->info3); if ( !NT_STATUS_IS_OK(ret) ) { DEBUG(1,("make_server_info_info3 failed: %s!\n", @@ -331,7 +332,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&session_key); talloc_destroy(mem_ctx); - return ERROR_NT(ret); + return ERROR_NT(nt_status_squash(ret)); } } else { @@ -344,7 +345,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&session_key); talloc_destroy(mem_ctx); - return ERROR_NT(ret); + return ERROR_NT(nt_status_squash(ret)); } /* make_server_info_pw does not set the domain. Without this @@ -355,6 +356,8 @@ static int reply_spnego_kerberos(connection_struct *conn, pdb_set_domain(server_info->sam_account, domain, PDB_SET); } } + + server_info->was_mapped |= username_was_mapped; /* we need to build the token for the user. make_server_info_guest() already does this */ @@ -367,7 +370,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&session_key); TALLOC_FREE( mem_ctx ); TALLOC_FREE( server_info ); - return ERROR_NT(ret); + return ERROR_NT(nt_status_squash(ret)); } } @@ -520,7 +523,7 @@ static int reply_spnego_negotiate(connection_struct *conn, /* Kill the intermediate vuid */ invalidate_vuid(vuid); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } /* only look at the first OID for determining the mechToken -- @@ -567,7 +570,7 @@ static int reply_spnego_negotiate(connection_struct *conn, /* Kill the intermediate vuid */ invalidate_vuid(vuid); - return ERROR_NT(nt_status); + return ERROR_NT(nt_status_squash(nt_status)); } nt_status = auth_ntlmssp_update(*auth_ntlmssp_state, @@ -604,7 +607,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, /* Kill the intermediate vuid */ invalidate_vuid(vuid); - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); } if (!*auth_ntlmssp_state) { @@ -612,7 +615,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, invalidate_vuid(vuid); /* auth before negotiatiate? */ - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); } nt_status = auth_ntlmssp_update(*auth_ntlmssp_state, @@ -664,7 +667,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, if (data_blob_len == 0) { /* an invalid request */ - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } bufrem = smb_bufrem(inbuf, p); @@ -696,14 +699,14 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, if (!vuser) { vuid = register_vuid(NULL, data_blob(NULL, 0), data_blob(NULL, 0), NULL); if (vuid == UID_FIELD_INVALID ) { - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); } vuser = get_partial_auth_user_struct(vuid); } if (!vuser) { - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); } SSVAL(outbuf,smb_uid,vuid); @@ -733,7 +736,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, /* Kill the intermediate vuid */ invalidate_vuid(vuid); - return ERROR_NT(nt_status); + return ERROR_NT(nt_status_squash(nt_status)); } } @@ -754,7 +757,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, data_blob_free(&blob1); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } /**************************************************************************** @@ -846,7 +849,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) { if (!global_spnego_negotiated) { DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at SPNEGO session setup when it was not negoitiated.\n")); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } if (SVAL(inbuf,smb_vwv4) == 0) { @@ -864,7 +867,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES); if ((passlen1 > MAX_PASS_LEN) || (passlen1 > smb_bufrem(inbuf, smb_buf(inbuf)))) { - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); } if (doencrypt) { @@ -925,11 +928,11 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, /* check for nasty tricks */ if (passlen1 > MAX_PASS_LEN || passlen1 > smb_bufrem(inbuf, p)) { - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); } if (passlen2 > MAX_PASS_LEN || passlen2 > smb_bufrem(inbuf, p+passlen1)) { - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); } /* Save the lanman2 password and the NT md4 password. */ @@ -1007,7 +1010,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, /* This has to be here, because this is a perfectly valid behaviour for guest logons :-( */ DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at 'normal' session setup after negotiating spnego.\n")); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } fstrcpy(sub_user, user); } else { @@ -1038,7 +1041,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, } else if (doencrypt) { if (!negprot_global_auth_context) { DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted session setup without negprot denied!\n")); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } nt_status = make_user_info_for_reply_enc(&user_info, user, domain, lm_resp, nt_resp); @@ -1087,7 +1090,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, /* Ensure we can't possible take a code path leading to a null defref. */ if (!server_info) { - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } nt_status = create_local_token(server_info); @@ -1124,20 +1127,30 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, /* register the name and uid as being validated, so further connections to a uid can get through without a password, on the same VC */ - /* register_vuid keeps the server info */ - sess_vuid = register_vuid(server_info, session_key, nt_resp.data ? nt_resp : lm_resp, sub_user); - data_blob_free(&nt_resp); - data_blob_free(&lm_resp); - - if (sess_vuid == UID_FIELD_INVALID) { - return ERROR_NT(NT_STATUS_LOGON_FAILURE); - } + if (lp_security() == SEC_SHARE) { + sess_vuid = UID_FIELD_INVALID; + data_blob_free(&session_key); + TALLOC_FREE(server_info); + } else { + /* register_vuid keeps the server info */ + sess_vuid = register_vuid(server_info, session_key, + nt_resp.data ? nt_resp : lm_resp, + sub_user); + if (sess_vuid == UID_FIELD_INVALID) { + data_blob_free(&nt_resp); + data_blob_free(&lm_resp); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); + } - /* current_user_info is changed on new vuid */ - reload_services( True ); + /* current_user_info is changed on new vuid */ + reload_services( True ); - sessionsetup_start_signing_engine(server_info, inbuf); + sessionsetup_start_signing_engine(server_info, inbuf); + } + data_blob_free(&nt_resp); + data_blob_free(&lm_resp); + SSVAL(outbuf,smb_uid,sess_vuid); SSVAL(inbuf,smb_uid,sess_vuid); diff --git a/source/smbd/share_access.c b/source/smbd/share_access.c index df5f445587f..468f61560b9 100644 --- a/source/smbd/share_access.c +++ b/source/smbd/share_access.c @@ -204,7 +204,8 @@ BOOL user_ok_token(const char *username, struct nt_user_token *token, int snum) if (!token_contains_name_in_list(username, lp_servicename(snum), token, lp_valid_users(snum))) { - DEBUG(10, ("User %s no in 'valid users'\n", username)); + DEBUG(10, ("User %s not in 'valid users'\n", + username)); return False; } } diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c index b229807bfdc..fc14772c57c 100644 --- a/source/smbd/trans2.c +++ b/source/smbd/trans2.c @@ -5011,6 +5011,7 @@ int handle_trans2(connection_struct *conn, /* Now we must call the relevant TRANS2 function */ switch(state->call) { case TRANSACT2_OPEN: + { START_PROFILE_NESTED(Trans2_open); outsize = call_trans2open( conn, inbuf, outbuf, bufsize, @@ -5019,8 +5020,10 @@ int handle_trans2(connection_struct *conn, state->max_data_return); END_PROFILE_NESTED(Trans2_open); break; + } case TRANSACT2_FINDFIRST: + { START_PROFILE_NESTED(Trans2_findfirst); outsize = call_trans2findfirst( conn, inbuf, outbuf, bufsize, @@ -5029,8 +5032,10 @@ int handle_trans2(connection_struct *conn, state->max_data_return); END_PROFILE_NESTED(Trans2_findfirst); break; + } case TRANSACT2_FINDNEXT: + { START_PROFILE_NESTED(Trans2_findnext); outsize = call_trans2findnext( conn, inbuf, outbuf, size, bufsize, @@ -5039,8 +5044,10 @@ int handle_trans2(connection_struct *conn, state->max_data_return); END_PROFILE_NESTED(Trans2_findnext); break; + } case TRANSACT2_QFSINFO: + { START_PROFILE_NESTED(Trans2_qfsinfo); outsize = call_trans2qfsinfo( conn, inbuf, outbuf, size, bufsize, @@ -5049,8 +5056,10 @@ int handle_trans2(connection_struct *conn, state->max_data_return); END_PROFILE_NESTED(Trans2_qfsinfo); break; + } case TRANSACT2_SETFSINFO: + { START_PROFILE_NESTED(Trans2_setfsinfo); outsize = call_trans2setfsinfo( conn, inbuf, outbuf, size, bufsize, @@ -5059,9 +5068,11 @@ int handle_trans2(connection_struct *conn, state->max_data_return); END_PROFILE_NESTED(Trans2_setfsinfo); break; + } case TRANSACT2_QPATHINFO: case TRANSACT2_QFILEINFO: + { START_PROFILE_NESTED(Trans2_qpathinfo); outsize = call_trans2qfilepathinfo( conn, inbuf, outbuf, size, bufsize, state->call, @@ -5070,8 +5081,11 @@ int handle_trans2(connection_struct *conn, state->max_data_return); END_PROFILE_NESTED(Trans2_qpathinfo); break; + } + case TRANSACT2_SETPATHINFO: case TRANSACT2_SETFILEINFO: + { START_PROFILE_NESTED(Trans2_setpathinfo); outsize = call_trans2setfilepathinfo( conn, inbuf, outbuf, size, bufsize, state->call, @@ -5080,8 +5094,10 @@ int handle_trans2(connection_struct *conn, state->max_data_return); END_PROFILE_NESTED(Trans2_setpathinfo); break; + } case TRANSACT2_FINDNOTIFYFIRST: + { START_PROFILE_NESTED(Trans2_findnotifyfirst); outsize = call_trans2findnotifyfirst( conn, inbuf, outbuf, size, bufsize, @@ -5090,8 +5106,10 @@ int handle_trans2(connection_struct *conn, state->max_data_return); END_PROFILE_NESTED(Trans2_findnotifyfirst); break; + } case TRANSACT2_FINDNOTIFYNEXT: + { START_PROFILE_NESTED(Trans2_findnotifynext); outsize = call_trans2findnotifynext( conn, inbuf, outbuf, size, bufsize, @@ -5100,7 +5118,10 @@ int handle_trans2(connection_struct *conn, state->max_data_return); END_PROFILE_NESTED(Trans2_findnotifynext); break; + } + case TRANSACT2_MKDIR: + { START_PROFILE_NESTED(Trans2_mkdir); outsize = call_trans2mkdir( conn, inbuf, outbuf, size, bufsize, @@ -5109,8 +5130,10 @@ int handle_trans2(connection_struct *conn, state->max_data_return); END_PROFILE_NESTED(Trans2_mkdir); break; + } case TRANSACT2_GET_DFS_REFERRAL: + { START_PROFILE_NESTED(Trans2_get_dfs_referral); outsize = call_trans2getdfsreferral( conn, inbuf, outbuf, size, bufsize, @@ -5119,7 +5142,10 @@ int handle_trans2(connection_struct *conn, state->max_data_return); END_PROFILE_NESTED(Trans2_get_dfs_referral); break; + } + case TRANSACT2_IOCTL: + { START_PROFILE_NESTED(Trans2_ioctl); outsize = call_trans2ioctl( conn, inbuf, outbuf, size, bufsize, @@ -5128,11 +5154,14 @@ int handle_trans2(connection_struct *conn, state->max_data_return); END_PROFILE_NESTED(Trans2_ioctl); break; + } + default: /* Error in request */ DEBUG(2,("Unknown request %d in trans2 call\n", state->call)); outsize = ERROR_DOS(ERRSRV,ERRerror); } + return outsize; } @@ -5154,8 +5183,8 @@ int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf, START_PROFILE(SMBtrans2); - if (!NT_STATUS_IS_OK(allow_new_trans(conn->pending_trans, - SVAL(inbuf, smb_mid)))) { + result = allow_new_trans(conn->pending_trans, SVAL(inbuf, smb_mid)); + if (!NT_STATUS_IS_OK(result)) { DEBUG(2, ("Got invalid trans2 request: %s\n", nt_errstr(result))); END_PROFILE(SMBtrans2); @@ -5246,7 +5275,7 @@ int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf, "bytes !\n", state->total_param)); SAFE_FREE(state->data); TALLOC_FREE(state); - END_PROFILE(SMBtrans); + END_PROFILE(SMBtrans2); return(ERROR_DOS(ERRDOS,ERRnomem)); } if ((psoff+pscnt < psoff) || (psoff+pscnt < pscnt)) @@ -5269,7 +5298,7 @@ int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf, SAFE_FREE(state->data); SAFE_FREE(state->param); TALLOC_FREE(state); - END_PROFILE(SMBtrans); + END_PROFILE(SMBtrans2); return outsize; } @@ -5379,7 +5408,7 @@ int reply_transs2(connection_struct *conn, if ((state->received_param < state->total_param) || (state->received_data < state->total_data)) { - END_PROFILE(SMBtranss); + END_PROFILE(SMBtranss2); return -1; } @@ -5396,7 +5425,7 @@ int reply_transs2(connection_struct *conn, TALLOC_FREE(state); if (outsize == 0) { - END_PROFILE(SMBtranss); + END_PROFILE(SMBtranss2); return(ERROR_DOS(ERRSRV,ERRnosupport)); } diff --git a/source/smbd/vfs-wrap.c b/source/smbd/vfs-wrap.c index 55bf146c20f..ee251c17d8d 100644 --- a/source/smbd/vfs-wrap.c +++ b/source/smbd/vfs-wrap.c @@ -549,7 +549,7 @@ int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t { int saved_errno = errno; /* We might get ENOSYS */ if ((result = SMB_VFS_FCHMOD_ACL(fsp, fd, mode)) == 0) { - END_PROFILE(syscall_chmod); + END_PROFILE(syscall_fchmod); return result; } /* Error - return the old errno. */ diff --git a/source/smbd/vfs.c b/source/smbd/vfs.c index 9a6327b33b5..2c9403a0790 100644 --- a/source/smbd/vfs.c +++ b/source/smbd/vfs.c @@ -27,6 +27,8 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_VFS +static_decl_vfs; + struct vfs_init_function_entry { char *name; vfs_op_tuple *vfs_op_tuples; |