added correct client-side credential generation / checking to the LSA SAM
authorLuke Leighton <lkcl@samba.org>
Sat, 25 Oct 1997 17:38:37 +0000 (17:38 +0000)
committerLuke Leighton <lkcl@samba.org>
Sat, 25 Oct 1997 17:38:37 +0000 (17:38 +0000)
Logon query.  i think i even got the client-side checking of the response
credentials right!
(This used to be commit f14c111835e18e361468cc6a1666a02654afe743)

source3/client/ntclient.c
source3/include/smb.h
source3/lsaparse.c

index 706cf0fa633a7f91f4d0b8946698023adc906fb0..f92fab9032a860ef2f08f49790b54a875e2ac235 100644 (file)
@@ -185,13 +185,11 @@ static BOOL do_lsa_req_chal(uint16 fnum,
 }
 
 /****************************************************************************
-do a LSA SAM Logon
+do a LSA Authenticate 2
 ****************************************************************************/
-static BOOL do_lsa_sam_logon(uint16 fnum,
-               char *logon_srv, char *comp_name,
-        DOM_CRED *clnt_cred, DOM_CRED *rtn_cred,
-               uint16 logon_level, uint16 switch_value, DOM_ID_INFO_1 *id1,
-               DOM_CRED *srv_cred)
+static BOOL do_lsa_auth2(uint16 fnum,
+               char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
+        DOM_CHAL *clnt_chal, uint32 neg_flags, DOM_CHAL *srv_chal)
 {
        char *rparam = NULL;
        char *rdata = NULL;
@@ -199,29 +197,27 @@ static BOOL do_lsa_sam_logon(uint16 fnum,
        int rdrcnt,rprcnt;
        pstring data; /* only 1024 bytes */
        uint16 setup[2]; /* only need 2 uint16 setup parameters */
-       LSA_Q_SAM_LOGON q_s;
+       LSA_Q_AUTH_2 q_a;
        int call_id = 0x1;
-    BOOL valid_cred = False;
+    BOOL valid_chal = False;
 
-       if (srv_cred == NULL || clnt_cred == NULL || rtn_cred == NULL) return False;
+       if (srv_chal == NULL || clnt_chal == NULL) return False;
 
-       /* create and send a MSRPC command with api LSA_SAMLOGON */
+       /* create and send a MSRPC command with api LSA_AUTH2 */
 
-       DEBUG(4,("LSA SAM Logon: srv:%s mc:%s clnt %lx %lx %lx rtn: %lx %lx %lx ll: %d\n",
-                 logon_srv, comp_name,
-                 clnt_cred->challenge.data[0], clnt_cred->challenge.data[1], clnt_cred->timestamp.time,
-                 rtn_cred ->challenge.data[0], rtn_cred ->challenge.data[1], rtn_cred ->timestamp.time,
-                 logon_level));
+       DEBUG(4,("LSA Authenticate 2: srv:%s acct:%s sc:%x mc: %s chal %lx %lx neg: %lx\n",
+                 logon_srv, acct_name, sec_chan, comp_name,
+                 clnt_chal->data[0], clnt_chal->data[1], neg_flags));
 
        /* store the parameters */
-       make_sam_info(&(q_s.sam_id), logon_srv, comp_name,
-                    clnt_cred, rtn_cred, logon_level, switch_value, id1);
+       make_q_auth_2(&q_a, logon_srv, acct_name, sec_chan, comp_name,
+                    clnt_chal, neg_flags);
 
        /* turn parameters into data stream */
-       p = lsa_io_q_sam_logon(False, &q_s, data + 0x18, data, 4, 0);
+       p = lsa_io_q_auth_2(False, &q_a, data + 0x18, data, 4, 0);
 
        /* create the request RPC_HDR _after_ the main data: length is now known */
-       create_rpc_request(call_id, LSA_SAMLOGON, data, PTR_DIFF(p, data));
+       create_rpc_request(call_id, LSA_AUTH2, data, PTR_DIFF(p, data));
 
        /* create setup parameters. */
        SIVAL(setup, 0, 0x0026); /* 0x26 indicates "transact named pipe" */
@@ -234,7 +230,6 @@ static BOOL do_lsa_sam_logon(uint16 fnum,
                                NULL, data, setup,
                                &rparam,&rdata))
        {
-#if 0
                LSA_R_AUTH_2 r_a;
                RPC_HDR hdr;
                int hdr_len;
@@ -290,22 +285,22 @@ static BOOL do_lsa_sam_logon(uint16 fnum,
                        memcpy(srv_chal, r_a.srv_chal.data, sizeof(srv_chal->data));
                        valid_chal = True;
                }
-#endif
        }
 
        if (rparam) free(rparam);
        if (rdata) free(rdata);
 
-       return valid_cred;
+       return valid_chal;
 }
 
-
 /****************************************************************************
-do a LSA Authenticate 2
+do a LSA SAM Logon
 ****************************************************************************/
-static BOOL do_lsa_auth2(uint16 fnum,
-               char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
-        DOM_CHAL *clnt_chal, uint32 neg_flags, DOM_CHAL *srv_chal)
+static BOOL do_lsa_sam_logon(uint16 fnum, uint32 sess_key[2], DOM_CHAL *clnt_chal,
+               char *logon_srv, char *comp_name,
+        DOM_CRED *clnt_cred, DOM_CRED *rtn_cred,
+               uint16 logon_level, uint16 switch_value, DOM_ID_INFO_1 *id1,
+               DOM_CRED *srv_cred)
 {
        char *rparam = NULL;
        char *rdata = NULL;
@@ -313,27 +308,29 @@ static BOOL do_lsa_auth2(uint16 fnum,
        int rdrcnt,rprcnt;
        pstring data; /* only 1024 bytes */
        uint16 setup[2]; /* only need 2 uint16 setup parameters */
-       LSA_Q_AUTH_2 q_a;
+       LSA_Q_SAM_LOGON q_s;
        int call_id = 0x1;
-    BOOL valid_chal = False;
+    BOOL valid_cred = False;
 
-       if (srv_chal == NULL || clnt_chal == NULL) return False;
+       if (srv_cred == NULL || clnt_cred == NULL || rtn_cred == NULL) return False;
 
-       /* create and send a MSRPC command with api LSA_AUTH2 */
+       /* create and send a MSRPC command with api LSA_SAMLOGON */
 
-       DEBUG(4,("LSA Authenticate 2: srv:%s acct:%s sc:%x mc: %s chal %lx %lx neg: %lx\n",
-                 logon_srv, acct_name, sec_chan, comp_name,
-                 clnt_chal->data[0], clnt_chal->data[1], neg_flags));
+       DEBUG(4,("LSA SAM Logon: srv:%s mc:%s clnt %lx %lx %lx rtn: %lx %lx %lx ll: %d\n",
+                 logon_srv, comp_name,
+                 clnt_cred->challenge.data[0], clnt_cred->challenge.data[1], clnt_cred->timestamp.time,
+                 rtn_cred ->challenge.data[0], rtn_cred ->challenge.data[1], rtn_cred ->timestamp.time,
+                 logon_level));
 
        /* store the parameters */
-       make_q_auth_2(&q_a, logon_srv, acct_name, sec_chan, comp_name,
-                    clnt_chal, neg_flags);
+       make_sam_info(&(q_s.sam_id), logon_srv, comp_name,
+                    clnt_cred, rtn_cred, logon_level, switch_value, id1);
 
        /* turn parameters into data stream */
-       p = lsa_io_q_auth_2(False, &q_a, data + 0x18, data, 4, 0);
+       p = lsa_io_q_sam_logon(False, &q_s, data + 0x18, data, 4, 0);
 
        /* create the request RPC_HDR _after_ the main data: length is now known */
-       create_rpc_request(call_id, LSA_AUTH2, data, PTR_DIFF(p, data));
+       create_rpc_request(call_id, LSA_SAMLOGON, data, PTR_DIFF(p, data));
 
        /* create setup parameters. */
        SIVAL(setup, 0, 0x0026); /* 0x26 indicates "transact named pipe" */
@@ -346,11 +343,32 @@ static BOOL do_lsa_auth2(uint16 fnum,
                                NULL, data, setup,
                                &rparam,&rdata))
        {
+               DOM_CRED clnt_cred1;
+
+               DEBUG(5, ("cli_call_api: return OK\n"));
+
+               clnt_cred1.timestamp.time = clnt_cred->timestamp.time + 1;
+
+               /* calculate sam logon credentials at time+1, just like server does */
+               cred_create(sess_key, clnt_chal, clnt_cred1.timestamp,
+                                            &(clnt_cred1.challenge));
+
+#if 0
                LSA_R_AUTH_2 r_a;
                RPC_HDR hdr;
                int hdr_len;
                int pkt_len;
 
+               /* check sam logon credentials at time+1, just like server does */
+               if (cred_assert(r_s....creds, sess_key, clnt_chal, clnt_cred->timestamp + 1))
+               {
+                       DEBUG(5, ("do_lsa_sam_logon: server credential check OK\n"));
+               }
+               else
+               {
+                       DEBUG(5, ("do_lsa_sam_logon: server credential check failed\n"));
+               }
+
                DEBUG(5, ("cli_call_api: return OK\n"));
 
                p = rdata;
@@ -401,12 +419,13 @@ static BOOL do_lsa_auth2(uint16 fnum,
                        memcpy(srv_chal, r_a.srv_chal.data, sizeof(srv_chal->data));
                        valid_chal = True;
                }
+#endif
        }
 
        if (rparam) free(rparam);
        if (rdata) free(rdata);
 
-       return valid_chal;
+       return valid_cred;
 }
 
 /****************************************************************************
@@ -448,13 +467,16 @@ BOOL do_nt_login(char *desthost, char *myhostname,
                return False;
        }
        
-       /* open the \PIPE\NETLOGON file */
+       /******************* open the \PIPE\NETLOGON file *****************/
+
        if ((fnum = open_rpc_pipe(inbuf, outbuf, PIPE_NETLOGON, Client, cnum)) == 0xffff)
        {
                free(inbuf); free(outbuf);
                return False;
        }
 
+       /******************* Request Challenge ********************/
+
        fstrcpy(mach_acct, myhostname);
        strlower(mach_pwd);
 
@@ -472,6 +494,7 @@ BOOL do_nt_login(char *desthost, char *myhostname,
                return False;
        }
 
+       /************ Long-term Session key (default) **********/
 
 #if 0
        /* DAMN!  can't get the machine password - need become_root() to do it! */
@@ -499,6 +522,9 @@ BOOL do_nt_login(char *desthost, char *myhostname,
        /* calculate the session key */
        cred_session_key(&clnt_chal, &srv_chal, nt_owf_mach_pwd, sess_key);
 
+
+       /******************* Authenticate 2 ********************/
+
        /* calculate auth-2 credentials */
        cred_create(sess_key, &clnt_chal, zerotime, &auth2_clnt_chal);
 
@@ -511,13 +537,26 @@ BOOL do_nt_login(char *desthost, char *myhostname,
                return False;
        }
 
+
+       /*********************** SAM Info ***********************/
+
+       /* this is used in both the SAM Logon and the SAM Logoff */
        make_id_info1(&id1, workgroup, 0,
                      getuid(), 0,
                      username, myhostname,
                      NULL, NULL);
 
+       /*********************** SAM Logon **********************/
+
+       sam_log_clnt_cred.timestamp.time = time(NULL);
+
+       /* calculate sam logon credentials, using the auth2 client challenge */
+       cred_create(sess_key, &auth2_clnt_chal, sam_log_clnt_cred.timestamp,
+                                         &(sam_log_clnt_cred.challenge));
+
        /* send client sam-logon challenge; receive a sam-logon challenge */
-       if (!do_lsa_sam_logon(fnum, desthost, mach_acct, 
+       if (!do_lsa_sam_logon(fnum, sess_key, &auth2_clnt_chal, 
+                         desthost, mach_acct, 
                          &sam_log_clnt_cred, &sam_log_rtn_cred,
                          1, 1, &id1,
                          &sam_log_srv_cred))
@@ -528,7 +567,6 @@ BOOL do_nt_login(char *desthost, char *myhostname,
        }
 
 #if 0
-       cli_lsa_sam_logon();
        cli_lsa_sam_logoff();
 #endif
 
index b19fbfb4ca46f2243051eabb6704e485138f08f2..1869020c0d16befe041326ba0fea7b3429da8f8c 100644 (file)
@@ -809,7 +809,7 @@ typedef struct lsa_q_user_info
        uint32 buffer_groups; /* undocumented buffer pointer to groups. */
        uint32 user_flgs;     /* user flags */
 
-       char sess_key[16]; /* unused user session key */
+       char user_sess_key[16]; /* unused user session key */
 
        UNIHDR hdr_logon_srv; /* logon server unicode string header */
        UNIHDR hdr_logon_dom; /* logon domain unicode string header */
index eab20690133788e9ca536e6e8c8cd2c8f1903b71..33813ce7afdf2cff9a0a6de564c8cf7b84f3c9cb 100644 (file)
@@ -434,7 +434,7 @@ char* lsa_io_user_info(BOOL io, LSA_USER_INFO *usr, char *q, char *base, int ali
                DBG_RW_IVAL("buffer_groups ", depth, base, io, q, usr->buffer_groups); q += 4; /* undocumented buffer pointer to groups. */
                DBG_RW_IVAL("user_flgs     ", depth, base, io, q, usr->user_flgs    ); q += 4;     /* user flags */
 
-               DBG_RW_PCVAL("sess_key     ", depth, base, io, q, usr->sess_key, 16); q += 16; /* unused user session key */
+               DBG_RW_PCVAL("user_sess_key", depth, base, io, q, usr->user_sess_key, 16); q += 16; /* unused user session key */
 
                q = smb_io_unihdr(io, &(usr->hdr_logon_srv), q, base, align, depth); /* logon server unicode string header */
                q = smb_io_unihdr(io, &(usr->hdr_logon_dom), q, base, align, depth); /* logon domain unicode string header */