summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/password.c23
-rw-r--r--source3/smbd/sesssetup.c32
2 files changed, 40 insertions, 15 deletions
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index 958ed663e6..494d9ecd43 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -77,6 +77,8 @@ void invalidate_vuid(uint16 vuid)
free_server_info(&vuser->server_info);
+ data_blob_free(&vuser->session_key);
+
DLIST_REMOVE(validated_users, vuser);
/* clear the vuid from the 'cache' on each connection, and
@@ -109,25 +111,36 @@ void invalidate_all_vuids(void)
* @param server_info The token returned from the authentication process.
* (now 'owned' by register_vuid)
*
+ * @param session_key The User session key for the login session (now also 'owned' by register_vuid)
+ *
+ * @param respose_blob The NT challenge-response, if available. (May be freed after this call)
+ *
+ * @param smb_name The untranslated name of the user
+ *
* @return Newly allocated vuid, biased by an offset. (This allows us to
* tell random client vuid's (normally zero) from valid vuids.)
*
*/
-int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB response_blob, const char *smb_name)
+int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, DATA_BLOB response_blob, const char *smb_name)
{
user_struct *vuser = NULL;
/* Ensure no vuid gets registered in share level security. */
- if(lp_security() == SEC_SHARE)
+ if(lp_security() == SEC_SHARE) {
+ data_blob_free(&session_key);
return UID_FIELD_INVALID;
+ }
/* Limit allowed vuids to 16bits - VUID_OFFSET. */
- if (num_validated_vuids >= 0xFFFF-VUID_OFFSET)
+ if (num_validated_vuids >= 0xFFFF-VUID_OFFSET) {
+ data_blob_free(&session_key);
return UID_FIELD_INVALID;
+ }
if((vuser = (user_struct *)malloc( sizeof(user_struct) )) == NULL) {
DEBUG(0,("Failed to malloc users struct!\n"));
+ data_blob_free(&session_key);
return UID_FIELD_INVALID;
}
@@ -156,6 +169,7 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB response_blob
if (vuser->n_groups) {
if (!(vuser->groups = memdup(server_info->groups, sizeof(gid_t) * vuser->n_groups))) {
DEBUG(0,("register_vuid: failed to memdup vuser->groups\n"));
+ data_blob_free(&session_key);
free(vuser);
free_server_info(&server_info);
return UID_FIELD_INVALID;
@@ -197,7 +211,7 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB response_blob
}
}
- memcpy(vuser->session_key, server_info->session_key, sizeof(vuser->session_key));
+ vuser->session_key = session_key;
DEBUG(10,("register_vuid: (%u,%u) %s %s %s guest=%d\n",
(unsigned int)vuser->uid,
@@ -211,6 +225,7 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB response_blob
} else {
DEBUG(1, ("server_info does not contain a user_token - cannot continue\n"));
free_server_info(&server_info);
+ data_blob_free(&session_key);
SAFE_FREE(vuser->homedir);
SAFE_FREE(vuser->unix_homedir);
SAFE_FREE(vuser->logon_script);
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 314ffbb4a9..64c25db2ab 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -149,7 +149,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
DATA_BLOB auth_data;
DATA_BLOB ap_rep, ap_rep_wrapped, response;
auth_serversupplied_info *server_info = NULL;
- uint8 session_key[16];
+ DATA_BLOB session_key;
uint8 tok_id[2];
BOOL foreign = False;
DATA_BLOB nullblob = data_blob(NULL, 0);
@@ -164,7 +164,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
}
- ret = ads_verify_ticket(lp_realm(), &ticket, &client, &auth_data, &ap_rep, session_key);
+ ret = ads_verify_ticket(lp_realm(), &ticket, &client, &auth_data, &ap_rep, &session_key);
data_blob_free(&ticket);
@@ -223,11 +223,8 @@ static int reply_spnego_kerberos(connection_struct *conn,
return ERROR_NT(ret);
}
- /* Copy out the session key from the AP_REQ. */
- memcpy(server_info->session_key, session_key, sizeof(session_key));
-
/* register_vuid keeps the server info */
- sess_vuid = register_vuid(server_info, nullblob, user);
+ sess_vuid = register_vuid(server_info, session_key, nullblob, user);
free(user);
@@ -297,9 +294,10 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out
if (NT_STATUS_IS_OK(nt_status)) {
int sess_vuid;
DATA_BLOB nullblob = data_blob(NULL, 0);
+ 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, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user);
+ sess_vuid = register_vuid(server_info, session_key, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user);
(*auth_ntlmssp_state)->server_info = NULL;
if (sess_vuid == -1) {
@@ -566,6 +564,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
NTSTATUS nt_status;
BOOL doencrypt = global_encrypted_passwords_negotiated;
+
+ DATA_BLOB session_key;
START_PROFILE(SMBsesssetupX);
@@ -766,18 +766,28 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
free_user_info(&user_info);
- data_blob_free(&lm_resp);
- data_blob_clear_free(&plaintext_password);
-
if (!NT_STATUS_IS_OK(nt_status)) {
nt_status = do_map_to_guest(nt_status, &server_info, user, domain);
}
if (!NT_STATUS_IS_OK(nt_status)) {
data_blob_free(&nt_resp);
+ data_blob_free(&lm_resp);
+ data_blob_clear_free(&plaintext_password);
return ERROR_NT(nt_status_squash(nt_status));
}
+ if (server_info->nt_session_key.data) {
+ session_key = data_blob(server_info->nt_session_key.data, server_info->nt_session_key.length);
+ } else if (server_info->lm_session_key.length >= 8 && lm_resp.length == 24) {
+ session_key = data_blob(NULL, 16);
+ SMBsesskeygen_lmv1(server_info->lm_session_key.data, lm_resp.data,
+ session_key.data);
+ }
+
+ data_blob_free(&lm_resp);
+ data_blob_clear_free(&plaintext_password);
+
/* it's ok - setup a reply */
set_message(outbuf,3,0,True);
if (Protocol >= PROTOCOL_NT1) {
@@ -795,7 +805,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
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, nt_resp, sub_user);
+ sess_vuid = register_vuid(server_info, session_key, nt_resp, sub_user);
data_blob_free(&nt_resp);
if (sess_vuid == -1) {