summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2008-03-05 19:42:15 +0100
committerJelmer Vernooij <jelmer@samba.org>2008-03-05 19:42:15 +0100
commit63036a6f3380652c0cb54627bdeabcd212fa2f8c (patch)
tree90194f23cb1e6ca483e7773233c326a9b705f85f /source3/smbd
parentd41d580c600e3228ff8fee5c16c47580f661a240 (diff)
parent932c287a406048759fa1ac4bf86e29d96991ded1 (diff)
downloadsamba-63036a6f3380652c0cb54627bdeabcd212fa2f8c.tar.gz
samba-63036a6f3380652c0cb54627bdeabcd212fa2f8c.tar.bz2
samba-63036a6f3380652c0cb54627bdeabcd212fa2f8c.zip
Merge branch 'v3-2-test' of ssh://git.samba.org/data/git/samba into v3-2-test
(This used to be commit 3482cd9b0e81bbc801f1cec33fca82fc45a3ddef)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/aio.c45
-rw-r--r--source3/smbd/notify_inotify.c8
-rw-r--r--source3/smbd/nttrans.c10
-rw-r--r--source3/smbd/open.c9
-rw-r--r--source3/smbd/password.c4
-rw-r--r--source3/smbd/reply.c22
-rw-r--r--source3/smbd/seal.c20
-rw-r--r--source3/smbd/server.c3
-rw-r--r--source3/smbd/sesssetup.c120
-rw-r--r--source3/smbd/trans2.c4
10 files changed, 175 insertions, 70 deletions
diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c
index 86fdfe31b7..2889e3c13f 100644
--- a/source3/smbd/aio.c
+++ b/source3/smbd/aio.c
@@ -141,21 +141,27 @@ static struct aio_extra *find_aio_ex(uint16 mid)
We can have these many aio buffers in flight.
*****************************************************************************/
-#define AIO_PENDING_SIZE 10
+static int aio_pending_size;
static sig_atomic_t signals_received;
static int outstanding_aio_calls;
-static uint16 aio_pending_array[AIO_PENDING_SIZE];
+static uint16 *aio_pending_array;
/****************************************************************************
Signal handler when an aio request completes.
*****************************************************************************/
-static void signal_handler(int sig, siginfo_t *info, void *unused)
+void aio_request_done(uint16_t mid)
{
- if (signals_received < AIO_PENDING_SIZE) {
- aio_pending_array[signals_received] = info->si_value.sival_int;
+ if (signals_received < aio_pending_size) {
+ aio_pending_array[signals_received] = mid;
signals_received++;
- } /* Else signal is lost. */
+ }
+ /* Else signal is lost. */
+}
+
+static void signal_handler(int sig, siginfo_t *info, void *unused)
+{
+ aio_request_done(info->si_value.sival_int);
sys_select_signal(RT_SIGNAL_AIO);
}
@@ -176,6 +182,10 @@ void initialize_async_io_handler(void)
{
struct sigaction act;
+ aio_pending_size = lp_maxmux();
+ aio_pending_array = SMB_MALLOC_ARRAY(uint16, aio_pending_size);
+ SMB_ASSERT(aio_pending_array != NULL);
+
ZERO_STRUCT(act);
act.sa_sigaction = signal_handler;
act.sa_flags = SA_SIGINFO;
@@ -202,6 +212,12 @@ bool schedule_aio_read_and_X(connection_struct *conn,
size_t bufsize;
size_t min_aio_read_size = lp_aio_read_size(SNUM(conn));
+ if (fsp->base_fsp != NULL) {
+ /* No AIO on streams yet */
+ DEBUG(10, ("AIO on streams not yet supported\n"));
+ return false;
+ }
+
if ((!min_aio_read_size || (smb_maxcnt < min_aio_read_size))
&& !SMB_VFS_AIO_FORCE(fsp)) {
/* Too small a read for aio request. */
@@ -219,7 +235,7 @@ bool schedule_aio_read_and_X(connection_struct *conn,
return False;
}
- if (outstanding_aio_calls >= AIO_PENDING_SIZE) {
+ if (outstanding_aio_calls >= aio_pending_size) {
DEBUG(10,("schedule_aio_read_and_X: Already have %d aio "
"activities outstanding.\n",
outstanding_aio_calls ));
@@ -285,6 +301,12 @@ bool schedule_aio_write_and_X(connection_struct *conn,
bool write_through = BITSETW(req->inbuf+smb_vwv7,0);
size_t min_aio_write_size = lp_aio_write_size(SNUM(conn));
+ if (fsp->base_fsp != NULL) {
+ /* No AIO on streams yet */
+ DEBUG(10, ("AIO on streams not yet supported\n"));
+ return false;
+ }
+
if ((!min_aio_write_size || (numtowrite < min_aio_write_size))
&& !SMB_VFS_AIO_FORCE(fsp)) {
/* Too small a write for aio request. */
@@ -302,7 +324,7 @@ bool schedule_aio_write_and_X(connection_struct *conn,
return False;
}
- if (outstanding_aio_calls >= AIO_PENDING_SIZE) {
+ if (outstanding_aio_calls >= aio_pending_size) {
DEBUG(3,("schedule_aio_write_and_X: Already have %d aio "
"activities outstanding.\n",
outstanding_aio_calls ));
@@ -351,6 +373,8 @@ bool schedule_aio_write_and_X(connection_struct *conn,
return False;
}
+ release_level_2_oplocks_on_change(fsp);
+
if (!write_through && !lp_syncalways(SNUM(fsp->conn))
&& fsp->aio_write_behind) {
/* Lie to the client and immediately claim we finished the
@@ -421,6 +445,9 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
SSVAL(outbuf,smb_vwv7,((nread >> 16) & 1));
SSVAL(smb_buf(outbuf),-2,nread);
+ aio_ex->fsp->fh->pos = aio_ex->acb.aio_offset + nread;
+ aio_ex->fsp->fh->position_information = aio_ex->fsp->fh->pos;
+
DEBUG( 3, ( "handle_aio_read_complete file %s max=%d "
"nread=%d\n",
aio_ex->fsp->fsp_name,
@@ -522,6 +549,8 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
DEBUG(5,("handle_aio_write: sync_file for %s returned %s\n",
fsp->fsp_name, nt_errstr(status) ));
}
+
+ aio_ex->fsp->fh->pos = aio_ex->acb.aio_offset + nwritten;
}
show_msg(outbuf);
diff --git a/source3/smbd/notify_inotify.c b/source3/smbd/notify_inotify.c
index 73cee440d4..fa0f0ed51d 100644
--- a/source3/smbd/notify_inotify.c
+++ b/source3/smbd/notify_inotify.c
@@ -29,10 +29,12 @@
#include <asm/types.h>
#endif
+#ifndef HAVE_INOTIFY_INIT
+
#include <linux/inotify.h>
#include <asm/unistd.h>
-#ifndef HAVE_INOTIFY_INIT
+
/*
glibc doesn't define these functions yet (as of March 2006)
*/
@@ -50,6 +52,10 @@ static int inotify_rm_watch(int fd, int wd)
{
return syscall(__NR_inotify_rm_watch, fd, wd);
}
+#else
+
+#include <sys/inotify.h>
+
#endif
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 9381174af0..5293ca5347 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -558,7 +558,7 @@ void reply_ntcreate_and_X(struct smb_request *req)
}
file_len = sbuf.st_size;
- fattr = dos_mode(conn,fname,&sbuf);
+ fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
if (fattr == 0) {
fattr = FILE_ATTRIBUTE_NORMAL;
}
@@ -626,7 +626,7 @@ void reply_ntcreate_and_X(struct smb_request *req)
uint32 perms = 0;
p += 25;
if (fsp->is_directory
- || can_write_to_file(conn, fname, &sbuf)) {
+ || can_write_to_file(conn, fsp->fsp_name, &sbuf)) {
perms = FILE_GENERIC_ALL;
} else {
perms = FILE_GENERIC_READ|FILE_EXECUTE;
@@ -1007,7 +1007,7 @@ static void call_nt_transact_create(connection_struct *conn,
}
file_len = sbuf.st_size;
- fattr = dos_mode(conn,fname,&sbuf);
+ fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
if (fattr == 0) {
fattr = FILE_ATTRIBUTE_NORMAL;
}
@@ -1075,7 +1075,7 @@ static void call_nt_transact_create(connection_struct *conn,
uint32 perms = 0;
p += 25;
if (fsp->is_directory
- || can_write_to_file(conn, fname, &sbuf)) {
+ || can_write_to_file(conn, fsp->fsp_name, &sbuf)) {
perms = FILE_GENERIC_ALL;
} else {
perms = FILE_GENERIC_READ|FILE_EXECUTE;
@@ -1083,7 +1083,7 @@ static void call_nt_transact_create(connection_struct *conn,
SIVAL(p,0,perms);
}
- DEBUG(5,("call_nt_transact_create: open name = %s\n", fname));
+ DEBUG(5,("call_nt_transact_create: open name = %s\n", fsp->fsp_name));
/* Send the required number of replies */
send_nt_replies(conn, req, NT_STATUS_OK, params, param_len, *ppdata, 0);
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index aa4bc48f3d..cc78503379 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -2671,8 +2671,9 @@ NTSTATUS create_file_unixpath(connection_struct *conn,
status = split_ntfs_stream_name(talloc_tos(), fname,
&base, NULL);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10, ("split_ntfs_stream_name failed: %s\n",
- nt_errstr(status)));
+ DEBUG(10, ("create_file_unixpath: "
+ "split_ntfs_stream_name failed: %s\n",
+ nt_errstr(status)));
goto fail;
}
@@ -2840,7 +2841,7 @@ NTSTATUS create_file_unixpath(connection_struct *conn,
}
}
- DEBUG(10, ("create_file: info=%d\n", info));
+ DEBUG(10, ("create_file_unixpath: info=%d\n", info));
/*
* Set fsp->base_fsp late enough that we can't "goto fail" anymore. In
@@ -2867,7 +2868,7 @@ NTSTATUS create_file_unixpath(connection_struct *conn,
return NT_STATUS_OK;
fail:
- DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
+ DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
if (fsp != NULL) {
close_file(fsp, ERROR_CLOSE);
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index 687b67950a..80eba562c5 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -121,6 +121,10 @@ void invalidate_vuid(uint16 vuid)
data_blob_free(&vuser->session_key);
+ if (vuser->auth_ntlmssp_state) {
+ auth_ntlmssp_end(&vuser->auth_ntlmssp_state);
+ }
+
DLIST_REMOVE(validated_users, vuser);
/* clear the vuid from the 'cache' on each connection, and
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 669dad2e3a..818ff319e4 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -1639,11 +1639,11 @@ void reply_open(struct smb_request *req)
}
size = sbuf.st_size;
- fattr = dos_mode(conn,fname,&sbuf);
+ fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
mtime = sbuf.st_mtime;
if (fattr & aDIR) {
- DEBUG(3,("attempt to open a directory %s\n",fname));
+ DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name));
close_file(fsp,ERROR_CLOSE);
reply_doserror(req, ERRDOS,ERRnoaccess);
END_PROFILE(SMBopen);
@@ -1802,7 +1802,7 @@ void reply_open_and_X(struct smb_request *req)
sbuf.st_size = get_allocation_size(conn,fsp,&sbuf);
}
- fattr = dos_mode(conn,fname,&sbuf);
+ fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
mtime = sbuf.st_mtime;
if (fattr & aDIR) {
close_file(fsp,ERROR_CLOSE);
@@ -1985,7 +1985,7 @@ void reply_mknew(struct smb_request *req)
}
ts[0] = get_atimespec(&sbuf); /* atime. */
- file_ntimes(conn, fname, ts);
+ file_ntimes(conn, fsp->fsp_name, ts);
reply_outbuf(req, 1, 0);
SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
@@ -2000,9 +2000,9 @@ void reply_mknew(struct smb_request *req)
CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
}
- DEBUG( 2, ( "reply_mknew: file %s\n", fname ) );
+ DEBUG( 2, ( "reply_mknew: file %s\n", fsp->fsp_name ) );
DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n",
- fname, fsp->fh->fd, (unsigned int)fattr ) );
+ fsp->fsp_name, fsp->fh->fd, (unsigned int)fattr ) );
END_PROFILE(SMBcreate);
return;
@@ -2125,9 +2125,9 @@ void reply_ctemp(struct smb_request *req)
SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
/* the returned filename is relative to the directory */
- s = strrchr_m(fname, '/');
+ s = strrchr_m(fsp->fsp_name, '/');
if (!s) {
- s = fname;
+ s = fsp->fsp_name;
} else {
s++;
}
@@ -2154,9 +2154,9 @@ void reply_ctemp(struct smb_request *req)
CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
}
- DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fname ) );
- DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fname, fsp->fh->fd,
- (unsigned int)sbuf.st_mode ) );
+ DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fsp->fsp_name ) );
+ DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fsp->fsp_name,
+ fsp->fh->fd, (unsigned int)sbuf.st_mode ) );
END_PROFILE(SMBctemp);
return;
diff --git a/source3/smbd/seal.c b/source3/smbd/seal.c
index ea017e08d8..d4394e5bca 100644
--- a/source3/smbd/seal.c
+++ b/source3/smbd/seal.c
@@ -496,12 +496,15 @@ static NTSTATUS srv_enc_spnego_negotiate(connection_struct *conn,
srv_free_encryption_context(&partial_srv_trans_enc_ctx);
+ if (got_kerberos_mechanism) {
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
- if (got_kerberos_mechanism && lp_use_kerberos_keytab() ) {
status = srv_enc_spnego_gss_negotiate(ppdata, p_data_size, secblob);
- } else
+#else
+ /* Currently we don't SPNEGO negotiate
+ * back to NTLMSSP as we do in sessionsetupX. We should... */
+ return NT_STATUS_LOGON_FAILURE;
#endif
- {
+ } else {
status = srv_enc_ntlm_negotiate(ppdata, p_data_size, secblob, true);
}
@@ -558,7 +561,16 @@ static NTSTATUS srv_enc_spnego_ntlm_auth(connection_struct *conn,
status = auth_ntlmssp_update(ec->auth_ntlmssp_state, auth, &auth_reply);
data_blob_free(&auth);
- response = spnego_gen_auth_response(&auth_reply, status, OID_NTLMSSP);
+ /* From RFC4178.
+ *
+ * supportedMech
+ *
+ * This field SHALL only be present in the first reply from the
+ * target.
+ * So set mechOID to NULL here.
+ */
+
+ response = spnego_gen_auth_response(&auth_reply, status, NULL);
data_blob_free(&auth_reply);
if (NT_STATUS_IS_OK(status)) {
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 7116027adf..7bf11abfbd 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -988,7 +988,8 @@ static bool init_structs(void )
init_dptrs();
- secrets_init();
+ if (!secrets_init())
+ return False;
return True;
}
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 1e4e208951..9baa02977a 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -259,7 +259,7 @@ static void reply_spnego_kerberos(struct smb_request *req,
fstring user;
int sess_vuid = req->vuid;
NTSTATUS ret = NT_STATUS_OK;
- PAC_DATA *pac_data = NULL;
+ struct PAC_DATA *pac_data = NULL;
DATA_BLOB ap_rep, ap_rep_wrapped, response;
auth_serversupplied_info *server_info = NULL;
DATA_BLOB session_key = data_blob_null;
@@ -268,7 +268,7 @@ static void reply_spnego_kerberos(struct smb_request *req,
fstring real_username;
bool map_domainuser_to_guest = False;
bool username_was_mapped;
- PAC_LOGON_INFO *logon_info = NULL;
+ struct PAC_LOGON_INFO *logon_info = NULL;
ZERO_STRUCT(ticket);
ZERO_STRUCT(ap_rep);
@@ -394,10 +394,9 @@ static void reply_spnego_kerberos(struct smb_request *req,
domain = p+1;
- if (logon_info && logon_info->info3.hdr_logon_dom.uni_str_len) {
- unistr2_to_ascii(netbios_domain_name,
- &logon_info->info3.uni_logon_dom,
- sizeof(netbios_domain_name));
+ if (logon_info && logon_info->info3.base.domain.string) {
+ fstrcpy(netbios_domain_name,
+ logon_info->info3.base.domain.string);
domain = netbios_domain_name;
DEBUG(10, ("Mapped to [%s] (using PAC)\n", domain));
@@ -620,6 +619,7 @@ static void reply_spnego_ntlmssp(struct smb_request *req,
uint16 vuid,
AUTH_NTLMSSP_STATE **auth_ntlmssp_state,
DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status,
+ const char *OID,
bool wrap)
{
DATA_BLOB response;
@@ -680,7 +680,7 @@ static void reply_spnego_ntlmssp(struct smb_request *req,
if (wrap) {
response = spnego_gen_auth_response(ntlmssp_blob,
- nt_status, OID_NTLMSSP);
+ nt_status, OID);
} else {
response = *ntlmssp_blob;
}
@@ -745,6 +745,28 @@ NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out,
}
/****************************************************************************
+ Fall back from krb5 to NTLMSSP.
+****************************************************************************/
+
+static void reply_spnego_downgrade_to_ntlmssp(struct smb_request *req,
+ uint16 vuid)
+{
+ DATA_BLOB response;
+
+ reply_outbuf(req, 4, 0);
+ SSVAL(req->outbuf,smb_uid,vuid);
+
+ DEBUG(3,("reply_spnego_downgrade_to_ntlmssp: Got krb5 ticket in SPNEGO "
+ "but set to downgrade to NTLMSSP\n"));
+
+ response = spnego_gen_auth_response(NULL,
+ NT_STATUS_MORE_PROCESSING_REQUIRED,
+ OID_NTLMSSP);
+ reply_sesssetup_blob(req, response, NT_STATUS_MORE_PROCESSING_REQUIRED);
+ data_blob_free(&response);
+}
+
+/****************************************************************************
Reply to a session setup spnego negotiate packet.
****************************************************************************/
@@ -789,6 +811,15 @@ static void reply_spnego_negotiate(struct smb_request *req,
auth_ntlmssp_end(auth_ntlmssp_state);
}
+ if (got_kerberos_mechanism) {
+ data_blob_free(&secblob);
+ /* The mechtoken is a krb5 ticket, but
+ * we need to fall back to NTLM. */
+ reply_spnego_downgrade_to_ntlmssp(req,
+ vuid);
+ return;
+ }
+
status = auth_ntlmssp_start(auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
/* Kill the intermediate vuid */
@@ -803,7 +834,7 @@ static void reply_spnego_negotiate(struct smb_request *req,
data_blob_free(&secblob);
reply_spnego_ntlmssp(req, vuid, auth_ntlmssp_state,
- &chal, status, True);
+ &chal, status, OID_NTLMSSP, true);
data_blob_free(&chal);
@@ -823,7 +854,7 @@ static void reply_spnego_auth(struct smb_request *req,
DATA_BLOB auth = data_blob_null;
DATA_BLOB auth_reply = data_blob_null;
DATA_BLOB secblob = data_blob_null;
- NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
+ NTSTATUS status = NT_STATUS_LOGON_FAILURE;
if (!spnego_parse_auth(blob1, &auth)) {
#if 0
@@ -833,7 +864,7 @@ static void reply_spnego_auth(struct smb_request *req,
invalidate_vuid(vuid);
reply_nterror(req, nt_status_squash(
- NT_STATUS_INVALID_PARAMETER));
+ NT_STATUS_LOGON_FAILURE));
return;
}
@@ -843,24 +874,43 @@ static void reply_spnego_auth(struct smb_request *req,
bool got_krb5_mechanism = False;
status = parse_spnego_mechanisms(auth, &secblob,
&got_krb5_mechanism);
- if (NT_STATUS_IS_OK(status)) {
- DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n",
- (unsigned long)secblob.length));
+
+ if (!NT_STATUS_IS_OK(status)) {
+ /* Kill the intermediate vuid */
+ invalidate_vuid(vuid);
+ reply_nterror(req, nt_status_squash(status));
+ return;
+ }
+
+ DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n",
+ (unsigned long)secblob.length));
#ifdef HAVE_KRB5
- if ( got_krb5_mechanism && ((lp_security()==SEC_ADS) ||
- lp_use_kerberos_keytab()) ) {
- bool destroy_vuid = True;
- reply_spnego_kerberos(req, &secblob,
- vuid, &destroy_vuid);
- data_blob_free(&secblob);
- data_blob_free(&auth);
- if (destroy_vuid) {
- /* Kill the intermediate vuid */
- invalidate_vuid(vuid);
- }
- return;
+ if ( got_krb5_mechanism && ((lp_security()==SEC_ADS) ||
+ lp_use_kerberos_keytab()) ) {
+ bool destroy_vuid = True;
+ reply_spnego_kerberos(req, &secblob,
+ vuid, &destroy_vuid);
+ data_blob_free(&secblob);
+ data_blob_free(&auth);
+ if (destroy_vuid) {
+ /* Kill the intermediate vuid */
+ invalidate_vuid(vuid);
}
+ return;
+ }
#endif
+ /* Can't blunder into NTLMSSP auth if we have
+ * a krb5 ticket. */
+
+ if (got_krb5_mechanism) {
+ /* Kill the intermediate vuid */
+ invalidate_vuid(vuid);
+ DEBUG(3,("reply_spnego_auth: network "
+ "misconfiguration, client sent us a "
+ "krb5 ticket and kerberos security "
+ "not enabled"));
+ reply_nterror(req, nt_status_squash(
+ NT_STATUS_LOGON_FAILURE));
}
}
@@ -868,13 +918,13 @@ static void reply_spnego_auth(struct smb_request *req,
data_blob_free(&secblob);
if (!*auth_ntlmssp_state) {
- /* Kill the intermediate vuid */
- invalidate_vuid(vuid);
-
- /* auth before negotiatiate? */
- reply_nterror(req, nt_status_squash(
- NT_STATUS_INVALID_PARAMETER));
- return;
+ status = auth_ntlmssp_start(auth_ntlmssp_state);
+ if (!NT_STATUS_IS_OK(status)) {
+ /* Kill the intermediate vuid */
+ invalidate_vuid(vuid);
+ reply_nterror(req, nt_status_squash(status));
+ return;
+ }
}
status = auth_ntlmssp_update(*auth_ntlmssp_state,
@@ -882,9 +932,11 @@ static void reply_spnego_auth(struct smb_request *req,
data_blob_free(&auth);
+ /* Don't send the mechid as we've already sent this (RFC4178). */
+
reply_spnego_ntlmssp(req, vuid,
auth_ntlmssp_state,
- &auth_reply, status, True);
+ &auth_reply, status, NULL, true);
data_blob_free(&auth_reply);
@@ -1251,7 +1303,7 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
reply_spnego_ntlmssp(req, vuid,
&vuser->auth_ntlmssp_state,
- &chal, status, False);
+ &chal, status, OID_NTLMSSP, false);
data_blob_free(&chal);
return;
}
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 1f7af82670..dc908846b3 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -1017,7 +1017,7 @@ static void call_trans2open(connection_struct *conn,
}
size = get_file_size(sbuf);
- fattr = dos_mode(conn,fname,&sbuf);
+ fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
mtime = sbuf.st_mtime;
inode = sbuf.st_ino;
if (fattr & aDIR) {
@@ -1054,7 +1054,7 @@ static void call_trans2open(connection_struct *conn,
SIVAL(params,20,inode);
SSVAL(params,24,0); /* Padding. */
if (flags & 8) {
- uint32 ea_size = estimate_ea_size(conn, fsp, fname);
+ uint32 ea_size = estimate_ea_size(conn, fsp, fsp->fsp_name);
SIVAL(params, 26, ea_size);
} else {
SIVAL(params, 26, 0);