summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/sesssetup.c66
1 files changed, 58 insertions, 8 deletions
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 7eb8f4e694..0202a247cd 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -26,7 +26,9 @@
/****************************************************************************
reply to a session setup spnego negotiate packet for kerberos
****************************************************************************/
-static int reply_spnego_kerberos(connection_struct *conn, char *outbuf,
+static int reply_spnego_kerberos(connection_struct *conn,
+ char *inbuf, char *outbuf,
+ int length, int bufsize,
DATA_BLOB *secblob)
{
DATA_BLOB ticket;
@@ -37,9 +39,15 @@ static int reply_spnego_kerberos(connection_struct *conn, char *outbuf,
krb5_data packet;
krb5_ticket *tkt = NULL;
int ret;
- char *realm, *client;
+ char *realm, *client, *p;
fstring service;
extern pstring global_myname;
+ const struct passwd *pw;
+ char *user;
+ gid_t gid;
+ uid_t uid;
+ char *full_name;
+ int sess_vuid;
realm = lp_realm();
@@ -79,11 +87,48 @@ static int reply_spnego_kerberos(connection_struct *conn, char *outbuf,
DEBUG(3,("Ticket name is [%s]\n", client));
- /* well, if we got a client above then I think we have authenticated the user
- but fail it for now until I understand it */
+ p = strchr_m(client, '@');
+ if (!p) {
+ DEBUG(3,("Doesn't look like a valid principle\n"));
+ return ERROR_NT(NT_STATUS_LOGON_FAILURE);
+ }
+
+ *p = 0;
+ if (strcasecmp(p+1, realm) != 0) {
+ DEBUG(3,("Ticket for incorrect realm %s\n", p+1));
+ return ERROR_NT(NT_STATUS_LOGON_FAILURE);
+ }
+
+ user = client;
+
+ /* the password is good - let them in */
+ pw = smb_getpwnam(user,False);
+ if (!pw) {
+ DEBUG(1,("Username %s is invalid on this system\n",user));
+ return ERROR_NT(NT_STATUS_LOGON_FAILURE);
+ }
+ gid = pw->pw_gid;
+ uid = pw->pw_uid;
+ full_name = pw->pw_gecos;
+ sess_vuid = register_vuid(uid,gid,user,user,realm,False, full_name);
+
+ if (sess_vuid == -1) {
+ return ERROR_NT(NT_STATUS_LOGON_FAILURE);
+ }
+
+ set_message(outbuf,4,0,True);
+ SSVAL(outbuf, smb_vwv3, 0);
+ p = smb_buf(outbuf);
+ p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE);
+ p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE);
+ p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE);
+ set_message_end(outbuf,p);
+
+ SSVAL(outbuf,smb_uid,sess_vuid);
+ SSVAL(inbuf,smb_uid,sess_vuid);
- return ERROR_NT(NT_STATUS_LOGON_FAILURE);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
#endif
@@ -118,7 +163,10 @@ static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf,
/****************************************************************************
reply to a session setup spnego negotiate packet
****************************************************************************/
-static int reply_spnego_negotiate(connection_struct *conn, char *outbuf,
+static int reply_spnego_negotiate(connection_struct *conn,
+ char *inbuf,
+ char *outbuf,
+ int length, int bufsize,
DATA_BLOB blob1)
{
char *OIDs[ASN1_MAX_OIDS];
@@ -145,7 +193,8 @@ static int reply_spnego_negotiate(connection_struct *conn, char *outbuf,
#if HAVE_KRB5
if (got_kerberos) {
- int ret = reply_spnego_kerberos(conn, outbuf, &secblob);
+ int ret = reply_spnego_kerberos(conn, inbuf, outbuf,
+ length, bufsize, &secblob);
data_blob_free(&secblob);
return ret;
}
@@ -331,12 +380,13 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,cha
blob1 = data_blob(p, SVAL(inbuf, smb_vwv7));
#if 0
+ chdir("/home/tridge");
file_save("negotiate.dat", blob1.data, blob1.length);
#endif
if (blob1.data[0] == ASN1_APPLICATION(0)) {
/* its a negTokenTarg packet */
- ret = reply_spnego_negotiate(conn, outbuf, blob1);
+ ret = reply_spnego_negotiate(conn, inbuf, outbuf, length, bufsize, blob1);
data_blob_free(&blob1);
return ret;
}