summaryrefslogtreecommitdiff
path: root/source3/smbd/sesssetup.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2012-04-25 19:36:20 +0200
committerStefan Metzmacher <metze@samba.org>2012-06-25 20:55:06 +0200
commite77000259c9ccd8762f8b752555ff92c8fc41559 (patch)
tree8e274f416818d243bc131f2f54a0653cf5dec0d7 /source3/smbd/sesssetup.c
parent842f1c85b67b7a621a1ed98260809be85300494c (diff)
downloadsamba-e77000259c9ccd8762f8b752555ff92c8fc41559.tar.gz
samba-e77000259c9ccd8762f8b752555ff92c8fc41559.tar.bz2
samba-e77000259c9ccd8762f8b752555ff92c8fc41559.zip
s3:smbd/sesssetup: implement dynamic re-authentication and expire session if client supports it
metze
Diffstat (limited to 'source3/smbd/sesssetup.c')
-rw-r--r--source3/smbd/sesssetup.c82
1 files changed, 78 insertions, 4 deletions
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index be838a8656..dc3e2540f4 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -132,11 +132,12 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
uint16_t action = 0;
NTTIME now = timeval_to_nttime(&req->request_time);
struct smbXsrv_session *session = NULL;
+ uint32_t client_caps = IVAL(req->vwv+10, 0);
DEBUG(3,("Doing spnego session setup\n"));
if (global_client_caps == 0) {
- global_client_caps = IVAL(req->vwv+10, 0);
+ global_client_caps = client_caps;
if (!(global_client_caps & CAP_STATUS32)) {
remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
@@ -204,9 +205,13 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
reply_force_doserror(req, ERRSRV, ERRbaduid);
return;
}
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
+ status = NT_STATUS_OK;
+ }
if (NT_STATUS_IS_OK(status)) {
- reply_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
- return;
+ session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
+ status = NT_STATUS_MORE_PROCESSING_REQUIRED;
+ TALLOC_FREE(session->gensec);
}
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
reply_nterror(req, nt_status_squash(status));
@@ -258,7 +263,7 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
return;
}
- if (NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_IS_OK(status) && session->global->auth_session_info == NULL) {
struct auth_session_info *session_info = NULL;
status = gensec_session_info(session->gensec,
@@ -327,6 +332,72 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
session->global->auth_session_info_seqnum += 1;
session->global->channels[0].auth_session_info_seqnum =
session->global->auth_session_info_seqnum;
+ if (client_caps & CAP_DYNAMIC_REAUTH) {
+ session->global->expiration_time =
+ gensec_expire_time(session->gensec);
+ } else {
+ session->global->expiration_time =
+ GENSEC_EXPIRE_TIME_INFINITY;
+ }
+
+ status = smbXsrv_session_update(session);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
+ (unsigned long long)session->compat->vuid,
+ nt_errstr(status)));
+ data_blob_free(&out_blob);
+ TALLOC_FREE(session);
+ reply_nterror(req, NT_STATUS_LOGON_FAILURE);
+ return;
+ }
+
+ /* current_user_info is changed on new vuid */
+ reload_services(sconn, conn_snum_used, true);
+ } else if (NT_STATUS_IS_OK(status)) {
+ struct auth_session_info *session_info = NULL;
+
+ status = gensec_session_info(session->gensec,
+ session,
+ &session_info);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1,("Failed to generate session_info "
+ "(user and group token) for session setup: %s\n",
+ nt_errstr(status)));
+ data_blob_free(&out_blob);
+ TALLOC_FREE(session);
+ reply_nterror(req, nt_status_squash(status));
+ return;
+ }
+
+ if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
+ action = 1;
+ }
+
+ session->compat->session_info = session_info;
+ session->compat->vuid = session->global->session_wire_id;
+
+ if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
+ session->compat->homes_snum =
+ register_homes_share(session_info->unix_info->unix_name);
+ }
+
+ set_current_user_info(session_info->unix_info->sanitized_username,
+ session_info->unix_info->unix_name,
+ session_info->info->domain_name);
+
+ session->status = NT_STATUS_OK;
+ TALLOC_FREE(session->global->auth_session_info);
+ session->global->auth_session_info = session_info;
+ session->global->auth_session_info_seqnum += 1;
+ session->global->channels[0].auth_session_info_seqnum =
+ session->global->auth_session_info_seqnum;
+ if (client_caps & CAP_DYNAMIC_REAUTH) {
+ session->global->expiration_time =
+ gensec_expire_time(session->gensec);
+ } else {
+ session->global->expiration_time =
+ GENSEC_EXPIRE_TIME_INFINITY;
+ }
status = smbXsrv_session_update(session);
if (!NT_STATUS_IS_OK(status)) {
@@ -339,6 +410,8 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
return;
}
+ conn_clear_vuid_caches(sconn, session->compat->vuid);
+
/* current_user_info is changed on new vuid */
reload_services(sconn, conn_snum_used, true);
}
@@ -875,6 +948,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
session->global->auth_session_info_seqnum += 1;
session->global->channels[0].auth_session_info_seqnum =
session->global->auth_session_info_seqnum;
+ session->global->expiration_time = GENSEC_EXPIRE_TIME_INFINITY;
nt_status = smbXsrv_session_update(session);
if (!NT_STATUS_IS_OK(nt_status)) {