summaryrefslogtreecommitdiff
path: root/source3/smbd/sesssetup.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-08-21 01:43:22 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:30:08 -0500
commit57e2718e097bba57c96632064956f6ce048d8f28 (patch)
tree87afa5d9f5602334409b989cf122529a58fc0b20 /source3/smbd/sesssetup.c
parentb0b080799c542d1314870dcbfebd8e84d8002392 (diff)
downloadsamba-57e2718e097bba57c96632064956f6ce048d8f28.tar.gz
samba-57e2718e097bba57c96632064956f6ce048d8f28.tar.bz2
samba-57e2718e097bba57c96632064956f6ce048d8f28.zip
r24589: Refactor our vuid code so that we keep the same
vuid that was allocated whilst the connection is being constructed and after the connection has been set up. This is what Windows does and at least one client (and HP printer) depends on this behaviour. As it depends on the req struct not yet ported to SAMBA_3_2_0 (Volker, hint hint.... :-) I am not yet adding this to that branch, but will investigate that tomorrow. Jeremy. (This used to be commit a54f2805df92c67e74a6764568eedebe394fd500)
Diffstat (limited to 'source3/smbd/sesssetup.c')
-rw-r--r--source3/smbd/sesssetup.c122
1 files changed, 79 insertions, 43 deletions
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 22ad43ff75..e63511c368 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -249,8 +249,8 @@ static void reply_spnego_kerberos(connection_struct *conn,
fstring netbios_domain_name;
struct passwd *pw;
fstring user;
- int sess_vuid;
- NTSTATUS ret;
+ int sess_vuid = SVAL(req->inbuf, smb_uid);
+ NTSTATUS ret = NT_STATUS_OK;
PAC_DATA *pac_data;
DATA_BLOB ap_rep, ap_rep_wrapped, response;
auth_serversupplied_info *server_info = NULL;
@@ -535,18 +535,28 @@ static void reply_spnego_kerberos(connection_struct *conn,
}
}
- /* register_vuid keeps the server info */
- /* register_vuid takes ownership of session_key, no need to free after this.
- A better interface would copy it.... */
- sess_vuid = register_vuid(server_info, session_key, nullblob, client);
+ /* register_existing_vuid keeps the server info */
+ /* register_existing_vuid takes ownership of session_key on success,
+ * no need to free after this on success. A better interface would copy
+ * it.... */
+
+ if (!is_partial_auth_vuid(sess_vuid)) {
+ sess_vuid = register_initial_vuid();
+ }
+ sess_vuid = register_existing_vuid(sess_vuid,
+ server_info,
+ session_key,
+ nullblob,
+ client);
SAFE_FREE(client);
reply_outbuf(req, 4, 0);
- SSVAL(req->outbuf,smb_uid,vuid);
+ SSVAL(req->outbuf,smb_uid,sess_vuid);
if (sess_vuid == UID_FIELD_INVALID ) {
ret = NT_STATUS_LOGON_FAILURE;
+ data_blob_free(&session_key);
} else {
/* current_user_info is changed on new vuid */
reload_services( True );
@@ -560,6 +570,8 @@ static void reply_spnego_kerberos(connection_struct *conn,
SSVAL(req->outbuf, smb_uid, sess_vuid);
sessionsetup_start_signing_engine(server_info, req->inbuf);
+ /* Successful logon. Keep this vuid. */
+ *p_invalidate_vuid = False;
}
/* wrap that up in a nice GSS-API wrapping */
@@ -611,33 +623,43 @@ static void reply_spnego_ntlmssp(connection_struct *conn,
SSVAL(req->outbuf, smb_uid, vuid);
if (NT_STATUS_IS_OK(nt_status)) {
- int sess_vuid;
DATA_BLOB nullblob = data_blob_null;
DATA_BLOB session_key = data_blob((*auth_ntlmssp_state)->ntlmssp_state->session_key.data, (*auth_ntlmssp_state)->ntlmssp_state->session_key.length);
- /* register_vuid keeps the server info */
- sess_vuid = register_vuid(server_info, session_key, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user);
+ if (!is_partial_auth_vuid(vuid)) {
+ data_blob_free(&session_key);
+ nt_status = NT_STATUS_LOGON_FAILURE;
+ goto out;
+ }
+ /* register_existing_vuid keeps the server info */
+ if (register_existing_vuid(vuid,
+ server_info,
+ session_key, nullblob,
+ (*auth_ntlmssp_state)->ntlmssp_state->user) !=
+ vuid) {
+ data_blob_free(&session_key);
+ nt_status = NT_STATUS_LOGON_FAILURE;
+ goto out;
+ }
+
(*auth_ntlmssp_state)->server_info = NULL;
- if (sess_vuid == UID_FIELD_INVALID ) {
- nt_status = NT_STATUS_LOGON_FAILURE;
- } else {
-
- /* current_user_info is changed on new vuid */
- reload_services( True );
+ /* current_user_info is changed on new vuid */
+ reload_services( True );
- SSVAL(req->outbuf, smb_vwv3, 0);
-
- if (server_info->guest) {
- SSVAL(req->outbuf,smb_vwv2,1);
- }
-
- SSVAL(req->outbuf,smb_uid,sess_vuid);
+ SSVAL(req->outbuf, smb_vwv3, 0);
- sessionsetup_start_signing_engine(server_info, req->inbuf);
+ if (server_info->guest) {
+ SSVAL(req->outbuf,smb_vwv2,1);
}
+
+ SSVAL(req->outbuf,smb_uid,vuid);
+
+ sessionsetup_start_signing_engine(server_info, req->inbuf);
}
+ out:
+
if (wrap) {
response = spnego_gen_auth_response(ntlmssp_blob, nt_status, OID_NTLMSSP);
} else {
@@ -655,8 +677,10 @@ static void reply_spnego_ntlmssp(connection_struct *conn,
if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
/* NB. This is *NOT* an error case. JRA */
auth_ntlmssp_end(auth_ntlmssp_state);
- /* Kill the intermediate vuid */
- invalidate_vuid(vuid);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ /* Kill the intermediate vuid */
+ invalidate_vuid(vuid);
+ }
}
}
@@ -1111,36 +1135,36 @@ static void reply_sesssetup_and_X_spnego(connection_struct *conn,
}
}
- vuser = get_partial_auth_user_struct(vuid);
- if (!vuser) {
+ /* Did we get a valid vuid ? */
+ if (!is_partial_auth_vuid(vuid)) {
+ /* No, then try and see if this is an intermediate sessionsetup
+ * for a large SPNEGO packet. */
struct pending_auth_data *pad = get_pending_auth_data(smbpid);
if (pad) {
DEBUG(10,("reply_sesssetup_and_X_spnego: found pending vuid %u\n",
(unsigned int)pad->vuid ));
vuid = pad->vuid;
- vuser = get_partial_auth_user_struct(vuid);
}
}
- if (!vuser) {
- vuid = register_vuid(NULL, data_blob_null, data_blob_null, NULL);
- if (vuid == UID_FIELD_INVALID ) {
+ /* Do we have a valid vuid now ? */
+ if (!is_partial_auth_vuid(vuid)) {
+ /* No, start a new authentication setup. */
+ vuid = register_initial_vuid();
+ if (vuid == UID_FIELD_INVALID) {
data_blob_free(&blob1);
reply_nterror(req, nt_status_squash(
NT_STATUS_INVALID_PARAMETER));
return;
}
-
- vuser = get_partial_auth_user_struct(vuid);
}
+ vuser = get_partial_auth_user_struct(vuid);
+ /* This MUST be valid. */
if (!vuser) {
- data_blob_free(&blob1);
- reply_nterror(req, nt_status_squash(
- NT_STATUS_INVALID_PARAMETER));
- return;
+ smb_panic("reply_sesssetup_and_X_spnego: invalid vuid.");
}
-
+
/* Large (greater than 4k) SPNEGO blobs are split into multiple
* sessionsetup requests as the Windows limit on the security blob
* field is 4k. Bug #4400. JRA.
@@ -1617,13 +1641,25 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req)
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);
+ /* Ignore the initial vuid. */
+ sess_vuid = register_initial_vuid();
if (sess_vuid == UID_FIELD_INVALID) {
data_blob_free(&nt_resp);
data_blob_free(&lm_resp);
+ data_blob_free(&session_key);
+ reply_nterror(req, nt_status_squash(
+ NT_STATUS_LOGON_FAILURE));
+ }
+ /* register_existing_vuid keeps the server info */
+ sess_vuid = register_existing_vuid(sess_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);
+ data_blob_free(&session_key);
reply_nterror(req, nt_status_squash(
NT_STATUS_LOGON_FAILURE));
return;