summaryrefslogtreecommitdiffstats
path: root/source/smbd
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2006-05-23 15:21:55 +0000
committerGerald Carter <jerry@samba.org>2006-05-23 15:21:55 +0000
commit3f7bb704a9e62e7a46a05838ec9300c2f6916c16 (patch)
treee2ca7f1b8da68d725e5359d7746f391fedcad6be /source/smbd
parent34b471724d1c8eb9e020fce02fc538bd0993d1c4 (diff)
downloadsamba-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.c140
-rw-r--r--source/smbd/dir.c2
-rw-r--r--source/smbd/fake_file.c6
-rw-r--r--source/smbd/files.c28
-rw-r--r--source/smbd/ipc.c4
-rw-r--r--source/smbd/msdfs.c5
-rw-r--r--source/smbd/notify.c14
-rw-r--r--source/smbd/notify_hash.c20
-rw-r--r--source/smbd/nttrans.c31
-rw-r--r--source/smbd/open.c2
-rw-r--r--source/smbd/oplock.c44
-rw-r--r--source/smbd/oplock_irix.c13
-rw-r--r--source/smbd/oplock_linux.c7
-rw-r--r--source/smbd/password.c10
-rw-r--r--source/smbd/process.c1
-rw-r--r--source/smbd/reply.c15
-rw-r--r--source/smbd/server.c2
-rw-r--r--source/smbd/service.c41
-rw-r--r--source/smbd/sesssetup.c93
-rw-r--r--source/smbd/share_access.c3
-rw-r--r--source/smbd/trans2.c41
-rw-r--r--source/smbd/vfs-wrap.c2
-rw-r--r--source/smbd/vfs.c2
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;