summaryrefslogtreecommitdiff
path: root/source3/smbd/sesssetup.c
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2005-09-30 17:13:37 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:04:48 -0500
commit54abd2aa66069e6baf7769c496f46d9dba18db39 (patch)
tree9cf8e88168011797319ba9e9866749201b1eac1e /source3/smbd/sesssetup.c
parent4a2cc231d22a82ed21771a72508f15d21ed63227 (diff)
downloadsamba-54abd2aa66069e6baf7769c496f46d9dba18db39.tar.gz
samba-54abd2aa66069e6baf7769c496f46d9dba18db39.tar.bz2
samba-54abd2aa66069e6baf7769c496f46d9dba18db39.zip
r10656: BIG merge from trunk. Features not copied over
* \PIPE\unixinfo * winbindd's {group,alias}membership new functions * winbindd's lookupsids() functionality * swat (trunk changes to be reverted as per discussion with Deryck) (This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3)
Diffstat (limited to 'source3/smbd/sesssetup.c')
-rw-r--r--source3/smbd/sesssetup.c70
1 files changed, 57 insertions, 13 deletions
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index bf7287aab9..fc2d8b4abb 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -139,6 +139,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
int length, int bufsize,
DATA_BLOB *secblob)
{
+ TALLOC_CTX *mem_ctx;
DATA_BLOB ticket;
char *client, *p, *domain;
fstring netbios_domain_name;
@@ -146,7 +147,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
fstring user;
int sess_vuid;
NTSTATUS ret;
- DATA_BLOB auth_data;
+ PAC_DATA *pac_data;
DATA_BLOB ap_rep, ap_rep_wrapped, response;
auth_serversupplied_info *server_info = NULL;
DATA_BLOB session_key = data_blob(NULL, 0);
@@ -154,18 +155,24 @@ static int reply_spnego_kerberos(connection_struct *conn,
DATA_BLOB nullblob = data_blob(NULL, 0);
fstring real_username;
BOOL map_domainuser_to_guest = False;
+ PAC_LOGON_INFO *logon_info = NULL;
+ int i;
ZERO_STRUCT(ticket);
- ZERO_STRUCT(auth_data);
+ ZERO_STRUCT(pac_data);
ZERO_STRUCT(ap_rep);
ZERO_STRUCT(ap_rep_wrapped);
ZERO_STRUCT(response);
+ mem_ctx = talloc_init("reply_spnego_kerberos");
+ if (mem_ctx == NULL)
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+
if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) {
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(mem_ctx, lp_realm(), &ticket, &client, &pac_data, &ap_rep, &session_key);
data_blob_free(&ticket);
@@ -174,7 +181,18 @@ static int reply_spnego_kerberos(connection_struct *conn,
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
}
- data_blob_free(&auth_data);
+ if (pac_data) {
+
+ /* get the logon_info */
+ for (i=0; i < pac_data->num_buffers; i++) {
+
+ if (pac_data->pac_buffer[i].type != PAC_TYPE_LOGON_INFO)
+ continue;
+
+ logon_info = pac_data->pac_buffer[i].ctr->pac.logon_info;
+ break;
+ }
+ }
DEBUG(3,("Ticket name is [%s]\n", client));
@@ -203,7 +221,14 @@ static int reply_spnego_kerberos(connection_struct *conn,
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, -1);
+ domain = netbios_domain_name;
+ DEBUG(10, ("Mapped to [%s] (using PAC)\n", domain));
+
+ } else {
+
/* If we have winbind running, we can (and must) shorten the
username by using the short netbios name. Otherwise we will
have inconsistent user names. With Kerberos, we get the
@@ -231,7 +256,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
wb_response.data.domain_info.name);
domain = netbios_domain_name;
- DEBUG(10, ("Mapped to [%s]\n", domain));
+ DEBUG(10, ("Mapped to [%s] (using Winbind)\n", domain));
} else {
DEBUG(3, ("Could not find short name -- winbind "
"not running?\n"));
@@ -274,8 +299,21 @@ static int reply_spnego_kerberos(connection_struct *conn,
reload_services(True);
if ( map_domainuser_to_guest ) {
make_server_info_guest(&server_info);
+ } else if (logon_info) {
+ ret = make_server_info_pac(&server_info, real_username, pw, logon_info);
+
+ if ( !NT_STATUS_IS_OK(ret) ) {
+ DEBUG(1,("make_server_info_pac failed!\n"));
+ SAFE_FREE(client);
+ data_blob_free(&ap_rep);
+ data_blob_free(&session_key);
+ passwd_free(&pw);
+ return ERROR_NT(ret);
+ }
+
} else {
ret = make_server_info_pw(&server_info, real_username, pw);
+
if ( !NT_STATUS_IS_OK(ret) ) {
DEBUG(1,("make_server_info_from_pw failed!\n"));
SAFE_FREE(client);
@@ -284,15 +322,17 @@ static int reply_spnego_kerberos(connection_struct *conn,
passwd_free(&pw);
return ERROR_NT(ret);
}
+
+ /* make_server_info_pw does not set the domain. Without this we end up
+ * with the local netbios name in substitutions for %D. */
+
+ if (server_info->sam_account != NULL) {
+ pdb_set_domain(server_info->sam_account, domain, PDB_SET);
+ }
}
- passwd_free(&pw);
- /* make_server_info_pw does not set the domain. Without this we end up
- * with the local netbios name in substitutions for %D. */
- if (server_info->sam_account != NULL) {
- pdb_set_domain(server_info->sam_account, domain, PDB_SET);
- }
+ passwd_free(&pw);
/* register_vuid keeps the server info */
/* register_vuid takes ownership of session_key, no need to free after this.
@@ -339,6 +379,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
data_blob_free(&ap_rep);
data_blob_free(&ap_rep_wrapped);
data_blob_free(&response);
+ talloc_destroy(mem_ctx);
return -1; /* already replied */
}
@@ -348,6 +389,8 @@ static int reply_spnego_kerberos(connection_struct *conn,
Send a session setup reply, wrapped in SPNEGO.
Get vuid and check first.
End the NTLMSSP exchange context if we are OK/complete fail
+ This should be split into two functions, one to handle each
+ leg of the NTLM auth steps.
***************************************************************************/
static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *outbuf,
@@ -422,6 +465,7 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out
and the other end, that we are not finished yet. */
if (!ret || !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);
@@ -660,7 +704,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,
return ret;
}
- if (strncmp(blob1.data, "NTLMSSP", 7) == 0) {
+ if (strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0) {
DATA_BLOB chal;
NTSTATUS nt_status;
if (!vuser->auth_ntlmssp_state) {