This is the checkin that adds the security=domain functionality.
authorJeremy Allison <jra@samba.org>
Wed, 29 Apr 1998 00:02:57 +0000 (00:02 +0000)
committerJeremy Allison <jra@samba.org>
Wed, 29 Apr 1998 00:02:57 +0000 (00:02 +0000)
WARNING - so far this has only been tested against a Samba PDC
(still waiting for IS to add me the machine accounts :-).

Still missing is the code in smbpasswd that will add a machine
account password and change it on the domain controller, but
this is not hard, and I will check it in soon.

Jeremy.
(This used to be commit 17b94a7084621b3f0106dd4d3386f05cdfc56d19)

14 files changed:
source3/include/proto.h
source3/include/rpc_netlogon.h
source3/include/smb.h
source3/libsmb/nterr.c
source3/libsmb/smbdes.c
source3/param/loadparm.c
source3/passdb/smbpass.c
source3/rpc_client/cli_login.c
source3/rpc_client/cli_netlogon.c
source3/rpc_parse/parse_net.c
source3/rpc_server/srv_netlog.c
source3/smbd/password.c
source3/smbd/reply.c
source3/smbd/server.c

index b999e6a4b619043c349c98dec0f1c00e5246e2ca..60f04bde879f091c2d90264422b7793f7e131148 100644 (file)
@@ -60,6 +60,7 @@ BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len,
                   char **rparam, uint32 *rparam_count,
                   char **rdata, uint32 *rdata_count);
 BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation);
+BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(char *, uint32, char *));
 BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
                       void (*fn)(char *, uint32, char *));
 BOOL cli_session_setup(struct cli_state *cli, 
@@ -222,6 +223,44 @@ int reply_trans(char *inbuf,char *outbuf, int size, int bufsize);
 void interpret_coding_system(char *str);
 void initialize_multibyte_vectors( int client_codepage);
 
+/*The following definitions come from  lib/rpc/client/cli_login.c  */
+
+BOOL cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16]);
+BOOL cli_nt_srv_pwset(struct cli_state *cli, unsigned char *new_hashof_mach_pwd);
+BOOL cli_nt_login_interactive(struct cli_state *cli, char *domain, char *username, 
+                              uint32 smb_userid_low, char *password,
+                              NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3);
+BOOL cli_nt_login_network(struct cli_state *cli, char *domain, char *username, 
+                          uint32 smb_userid_low, char lm_chal[8], char lm_chal_resp[24],
+                          char nt_chal_resp[24],
+                          NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3);
+BOOL cli_nt_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr);
+
+/*The following definitions come from  lib/rpc/client/cli_netlogon.c  */
+
+BOOL cli_net_logon_ctrl2(struct cli_state *cli, uint32 status_level);
+BOOL cli_net_auth2(struct cli_state *cli, uint16 sec_chan, 
+                   uint32 neg_flags, DOM_CHAL *srv_chal);
+BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal);
+BOOL cli_net_srv_pwset(struct cli_state *cli, uint8 hashed_mach_pwd[16]);
+BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr, 
+                       NET_USER_INFO_3 *user_info3);
+BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr);
+
+/*The following definitions come from  lib/rpc/client/cli_pipe.c  */
+
+uint32 get_rpc_call_id(void);
+BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, 
+                  prs_struct *param , prs_struct *data,
+                  prs_struct *rparam, prs_struct *rdata);
+BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
+                      prs_struct *data, prs_struct *rdata);
+BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint16 device_state);
+BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name,
+                   RPC_IFACE *abstract, RPC_IFACE *transfer, BOOL ntlmssp_auth);
+BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted);
+void nt_session_close(struct cli_state *cli);
+
 /*The following definitions come from  lib/rpc/parse/parse_lsa.c  */
 
 void make_lsa_trans_name(LSA_TRANS_NAME *trn, uint32 sid_name_use, char *name, uint32 idx);
@@ -347,9 +386,8 @@ void make_q_auth_2(NET_Q_AUTH_2 *q_a,
                DOM_CHAL *clnt_chal, uint32 clnt_flgs);
 void net_io_q_auth_2(char *desc,  NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth);
 void net_io_r_auth_2(char *desc,  NET_R_AUTH_2 *r_a, prs_struct *ps, int depth);
-void make_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char sess_key[16],
-               char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
-               DOM_CRED *cred, char nt_cypher[16]);
+void make_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char *logon_srv, char *acct_name, 
+                uint16 sec_chan, char *comp_name, DOM_CRED *cred, char nt_cypher[16]);
 void net_io_q_srv_pwset(char *desc,  NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth);
 void net_io_r_srv_pwset(char *desc,  NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth);
 void make_id_info1(NET_ID_INFO_1 *id, char *domain_name,
@@ -1707,7 +1745,7 @@ void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out);
 void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out);
 void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key);
 void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key);
-void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key);
+void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw);
 void SamOEMhash( unsigned char *data, unsigned char *key, int val);
 
 /*The following definitions come from  smbencrypt.c  */
index 1fc65968213b78ce6441bb0f9a94a03107c907fe..ca8231fc5bca2024ab4e26f23873f4c53d13b533 100644 (file)
@@ -301,6 +301,9 @@ typedef struct id_info_1
 
 } NET_ID_INFO_1;
 
+#define INTERACTIVE_LOGON_TYPE 1
+#define NET_LOGON_TYPE 2
+
 /* NET_ID_INFO_CTR */
 typedef struct net_id_info_ctr_info
 {
index 1bf5b318b343b86840e1b716c4492a628a746372..33b38706dfc9b76de03e4cd775367b5e6ea9913c 100644 (file)
@@ -335,8 +335,8 @@ struct cli_state {
   uint16 nt_pipe_fnum;               /* Pipe handle. */
   unsigned char sess_key[16];        /* Current session key. */
   DOM_CRED clnt_cred;                /* Client credential. */
-  fstring mach_acct;
-  fstring srv_name;
+  fstring mach_acct;                 /* MYNAME$. */
+  fstring srv_name_slash;            /* \\remote server. */
 };
 
 
@@ -1070,11 +1070,7 @@ char *Strstr(char *s, char *p);
 enum protocol_types {PROTOCOL_NONE,PROTOCOL_CORE,PROTOCOL_COREPLUS,PROTOCOL_LANMAN1,PROTOCOL_LANMAN2,PROTOCOL_NT1};
 
 /* security levels */
-#ifdef DOMAIN_CLIENT
 enum security_types {SEC_SHARE,SEC_USER,SEC_SERVER,SEC_DOMAIN};
-#else /* DOMAIN_CLIENT */
-enum security_types {SEC_SHARE,SEC_USER,SEC_SERVER};
-#endif /* DOMAIN_CLIENT */
 
 /* printing types */
 enum printing_types {PRINT_BSD,PRINT_SYSV,PRINT_AIX,PRINT_HPUX,
index dca97ab923814209064ba28508d0cf85de9fe067..0788ae1b60ac1a2f624d97559c789382766789ac 100644 (file)
@@ -527,6 +527,8 @@ char *get_nt_error_msg(uint32 nt_code)
 
        strcpy(msg, "Unknown NT error");
 
+        nt_code &= 0xFFFF;
+
        while (nt_errs[idx].nt_errstr != NULL)
        {
                if (nt_errs[idx].nt_errcode == nt_code)
@@ -536,6 +538,6 @@ char *get_nt_error_msg(uint32 nt_code)
                }
                idx++;
        }
-       return NULL;
+       return msg;
 }
 
index cf46e53ff5ba6513fd7c49b0ee5d41ca9244d513..4daf616588dcaa947ccbbded6b56f1107219b64c 100644 (file)
@@ -347,13 +347,13 @@ void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key)
        smbhash(out, buf, key2, 1);
 }
 
-void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key)
+void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw)
 {
         static unsigned char key2[8];
 
-        smbhash(out, in, key, 0);
+        smbhash(out, in, key, forw);
         key2[0] = key[7];
-        smbhash(out + 8, in + 8, key2, 0);
+        smbhash(out + 8, in + 8, key2, forw);
 }
 
 void SamOEMhash( unsigned char *data, unsigned char *key, int val)
index c96669dba4fe2ee2cb958cf26cadbb35ee5a9564..2249c8b473f1866165083397c2169bf0b422574c 100644 (file)
@@ -402,14 +402,9 @@ static struct enum_list enum_protocol[] = {{PROTOCOL_NT1, "NT1"}, {PROTOCOL_LANM
                                           {PROTOCOL_COREPLUS, "COREPLUS"}, 
                                           {PROTOCOL_COREPLUS, "CORE+"}, {-1, NULL}};
 
-#ifdef DOMAIN_CLIENT
 static struct enum_list enum_security[] = {{SEC_SHARE, "SHARE"},  {SEC_USER, "USER"}, 
                                           {SEC_SERVER, "SERVER"}, {SEC_DOMAIN, "DOMAIN"},
                                            {-1, NULL}};
-#else /* DOMAIN_CLIENT */
-static struct enum_list enum_security[] = {{SEC_SHARE, "SHARE"},  {SEC_USER, "USER"}, 
-                                          {SEC_SERVER, "SERVER"}, {-1, NULL}};
-#endif /* DOMAIN_CLIENT */
 
 static struct enum_list enum_printing[] = {{PRINT_SYSV, "sysv"}, {PRINT_AIX, "aix"}, 
                                           {PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"},
index f3b38c43e73d80e8efef6a72643f087e173153cb..15f1d4d37fe07a203ba121028b9c58a6b3412678 100644 (file)
@@ -1072,8 +1072,6 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd)
   return True;
 }
 
-#ifdef DOMAIN_CLIENT
-
 static int mach_passwd_lock_depth;
 
 /************************************************************************
@@ -1250,4 +1248,3 @@ machine account is now invalid. Please recreate. Error was %s.\n", strerror(errn
   fflush(fp);
   return True;
 }
-#endif /* DOMAIN_CLIENT */
index fe00c39e4cc04aa257909e74997c67d9910aa746..1feda1cfe38fd57766cb0631a3cbe9b9c6c77dc0 100644 (file)
@@ -75,67 +75,45 @@ BOOL cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16])
   return True;
 }
 
-#if 0
 /****************************************************************************
- server password set
+ Set machine password.
  ****************************************************************************/
 
-BOOL do_nt_srv_pwset(struct cli_state *cli, 
-                     uint8 sess_key[16], DOM_CRED *clnt_cred, DOM_CRED *rtn_cred,
-                     char *new_mach_pwd,
-                     char *dest_host, char *mach_acct, char *myhostname)
+BOOL cli_nt_srv_pwset(struct cli_state *cli, unsigned char *new_hashof_mach_pwd)
 {
-  DOM_CRED cred;
-  char nt_cypher[16];
-  uint8 mode = 1;
-  char nt_owf_new_mach_pwd[16];
+  unsigned char processed_new_pwd[16];
 
-#ifdef DEBUG_PASSWORD
-  DEBUG(100,("generating nt owf from new machine pwd: %s\n", new_mach_pwd));
-#endif
-  nt_owf_gen(new_mach_pwd, nt_owf_new_mach_pwd);
+  DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__));
 
 #ifdef DEBUG_PASSWORD
-  dump_data(6, nt_owf_new_mach_pwd, 16);
+  dump_data(6, new_hashof_mach_pwd, 16);
 #endif
 
-  if (!obfuscate_pwd(nt_cypher, nt_owf_new_mach_pwd, mode))
-  {
-    DEBUG(5,("do_nt_srv_pwset: encrypt mach pwd failed\n"));
-    return False;
-  }
-       
-  clnt_cred->timestamp.time = time(NULL);
-
-  memcpy(&cred, clnt_cred, sizeof(cred));
-
-  /* calculate credentials */
-  cred_create(sess_key, &(clnt_cred->challenge),
-              cred.timestamp, &(cred.challenge));
+  /* Process the new password. */
+  cred_hash3( processed_new_pwd, new_hashof_mach_pwd, cli->sess_key, 0);
 
   /* send client srv_pwset challenge */
-  return do_net_srv_pwset(cli, fnum, sess_key, clnt_cred,
-                          dest_host, mach_acct, 2, myhostname,
-                          &cred, rtn_cred, nt_cypher);
+  return cli_net_srv_pwset(cli, processed_new_pwd);
 }
 
 /****************************************************************************
- make interactive sam login info
+NT login - interactive.
+*NEVER* use this code. This method of doing a logon (sending the cleartext
+password equivalents, protected by the session key) is inherently insecure
+given the current design of the NT Domain system. JRA.
  ****************************************************************************/
 
-void make_nt_login_interactive(NET_ID_INFO_CTR *ctr,
-                               uchar sess_key[16],
-                               char *domain, char *myhostname,
-                               uint32 smb_userid, char *username)
+BOOL cli_nt_login_interactive(struct cli_state *cli, char *domain, char *username, 
+                              uint32 smb_userid_low, char *password,
+                              NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3)
 {
-  /****************** SAM Info Preparation *******************/
-
-  char *smb_user_passwd = getpass("Enter NT Login Password:");
+  unsigned char lm_owf_user_pwd[16];
+  unsigned char nt_owf_user_pwd[16];
+  BOOL ret;
 
-  char lm_owf_user_pwd[16];
-  char nt_owf_user_pwd[16];
+  DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__));
 
-  nt_lm_owf_gen(smb_user_passwd, nt_owf_user_pwd, lm_owf_user_pwd);
+  nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd);
 
 #ifdef DEBUG_PASSWORD
 
@@ -147,18 +125,35 @@ void make_nt_login_interactive(NET_ID_INFO_CTR *ctr,
 
 #endif
 
-  /* indicate an "interactive" login */
-  ctr->switch_value = 1;
+  DEBUG(5,("cli_nt_login_network: %d\n", __LINE__));
 
-  /* this is used in both the SAM Logon and the SAM Logoff */
-  make_id_info1(&ctr->auth.id1, domain, 0,
-                smb_userid, 0, username, myhostname,
-                sess_key, lm_owf_user_pwd, nt_owf_user_pwd);
+  /* indicate a "network" login */
+  ctr->switch_value = INTERACTIVE_LOGON_TYPE;
+
+  /* Create the structure needed for SAM logon. */
+  make_id_info1(&ctr->auth.id1, domain, 0, 
+                smb_userid_low, 0,
+                username, global_myname,
+                cli->sess_key, lm_owf_user_pwd, nt_owf_user_pwd);
+
+  /* Ensure we overwrite all the plaintext password
+     equivalents. */
+  memset(lm_owf_user_pwd, '\0', sizeof(lm_owf_user_pwd));
+  memset(nt_owf_user_pwd, '\0', sizeof(nt_owf_user_pwd));
+
+  /* Send client sam-logon request - update credentials on success. */
+  ret = cli_net_sam_logon(cli, ctr, user_info3);
+
+  memset(ctr->auth.id1.lm_owf.data, '\0', sizeof(lm_owf_user_pwd));
+  memset(ctr->auth.id1.nt_owf.data, '\0', sizeof(nt_owf_user_pwd));
+
+  return ret;
 }
-#endif
 
 /****************************************************************************
-NT login.
+NT login - network.
+*ALWAYS* use this call to validate a user as it does not expose plaintext
+password equivalents over the network. JRA.
 ****************************************************************************/
 
 BOOL cli_nt_login_network(struct cli_state *cli, char *domain, char *username, 
index 91dbd274212a27b961ccbf9b8ca376153014191c..a8aba1c5dc5cbe3a594caaff671768062c20bd05 100644 (file)
@@ -33,11 +33,30 @@ extern int DEBUGLEVEL;
 extern pstring global_myname;
 extern fstring global_myworkgroup;
 
+/****************************************************************************
+Generate the next creds to use.
+****************************************************************************/
+
+static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred)
+{
+  /*
+   * Create the new client credentials.
+   */
+
+  cli->clnt_cred.timestamp.time = time(NULL);
+
+  memcpy(new_clnt_cred, &cli->clnt_cred, sizeof(*new_clnt_cred));
+
+  /* Calculate the new credentials. */
+  cred_create(cli->sess_key, &(cli->clnt_cred.challenge),
+              new_clnt_cred->timestamp, &(new_clnt_cred->challenge));
+}
+
 /****************************************************************************
 do a LSA Logon Control2
 ****************************************************************************/
 
-BOOL do_net_logon_ctrl2(struct cli_state *cli, uint32 status_level)
+BOOL cli_net_logon_ctrl2(struct cli_state *cli, uint32 status_level)
 {
   prs_struct rbuf;
   prs_struct buf; 
@@ -224,38 +243,33 @@ BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_
   return valid_chal;
 }
 
-#if 0
 /***************************************************************************
-do a LSA Server Password Set
+LSA Server Password Set.
 ****************************************************************************/
 
-BOOL do_net_srv_pwset(struct cli_state *cli, uint16 fnum,
-                      uchar sess_key[16], DOM_CRED *sto_clnt_cred,
-                      char *logon_srv, char *mach_acct, uint16 sec_chan_type,
-                      char *comp_name, DOM_CRED *clnt_cred, DOM_CRED *srv_cred,
-                      uint8 nt_owf_new_mach_pwd[16])
+BOOL cli_net_srv_pwset(struct cli_state *cli, uint8 hashed_mach_pwd[16])
 {
   prs_struct rbuf;
   prs_struct buf; 
+  DOM_CRED new_clnt_cred;
   NET_Q_SRV_PWSET q_s;
-  BOOL valid_cred = False;
+  BOOL ok = False;
+  uint16 sec_chan_type = 2;
 
-  if (srv_cred == NULL || clnt_cred == NULL)
-    return False;
+  gen_next_creds( cli, &new_clnt_cred);
 
   prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
   prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
 
-
   /* create and send a MSRPC command with api NET_SRV_PWSET */
 
-  DEBUG(4,("LSA Server Password Set: srv:%s acct:%s sc: %d mc: %s clnt %s %lx\n",
-           cli->srv_name_slash, mach_acct, sec_chan_type, comp_name,
-           credstr(clnt_cred->challenge.data), clnt_cred->timestamp.time));
+  DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s clnt %s %lx\n",
+           cli->srv_name_slash, cli->mach_acct, sec_chan_type, global_myname,
+           credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time));
 
   /* store the parameters */
-  make_q_srv_pwset(&q_s, sess_key, logon_srv, mach_acct, sec_chan_type,
-                   comp_name, clnt_cred, nt_owf_new_mach_pwd);
+  make_q_srv_pwset(&q_s, cli->srv_name_slash, cli->mach_acct, sec_chan_type,
+                   global_myname, &new_clnt_cred, hashed_mach_pwd);
 
   /* turn parameters into data stream */
   net_io_q_srv_pwset("", &q_s,  &buf, 0);
@@ -264,7 +278,6 @@ BOOL do_net_srv_pwset(struct cli_state *cli, uint16 fnum,
   if (rpc_api_pipe_req(cli, NET_SRVPWSET, &buf, &rbuf))
   {
     NET_R_SRV_PWSET r_s;
-    BOOL ok;
 
     net_io_r_srv_pwset("", &r_s, &rbuf, 0);
     ok = (rbuf.offset != 0);
@@ -277,31 +290,26 @@ BOOL do_net_srv_pwset(struct cli_state *cli, uint16 fnum,
       ok = False;
     }
 
-    if (ok)
+    /* Update the credentials. */
+    if (clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_cred)) == 0)
     {
-      if (clnt_deal_with_creds(sess_key, sto_clnt_cred, &(r_s.srv_cred)))
-      {
-        DEBUG(5, ("do_net_srv_pwset: server credential check OK\n"));
-        /* ok, at last: we're happy. return the challenge */
-        memcpy(srv_cred, &(r_s.srv_cred), sizeof(r_s.srv_cred));
-        valid_cred = True;
-      }
-      else
-      {
-        DEBUG(5, ("do_net_srv_pwset: server credential check failed\n"));
-      }
+      /*
+       * Server replied with bad credential. Fail.
+       */
+      DEBUG(0,("cli_net_srv_pwset: server %s replied with bad credential (bad machine \
+password ?).\n", cli->desthost ));
+      ok = False;
     }
   }
 
   prs_mem_free(&rbuf);
   prs_mem_free(&buf );
 
-  return valid_cred;
+  return ok;
 }
-#endif
 
 /***************************************************************************
-LSA SAM Logon.
+LSA SAM Logon - interactive or network.
 ****************************************************************************/
 
 BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr, 
@@ -314,17 +322,7 @@ BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr,
   NET_Q_SAM_LOGON q_s;
   BOOL ok = False;
 
-  /*
-   * Create the new client credentials.
-   */
-
-  cli->clnt_cred.timestamp.time = time(NULL);
-
-  memcpy(&new_clnt_cred, &cli->clnt_cred, sizeof(new_clnt_cred));
-
-  /* Calculate the new credentials. */
-  cred_create(cli->sess_key, &(cli->clnt_cred.challenge),
-              new_clnt_cred.timestamp, &(new_clnt_cred.challenge));
+  gen_next_creds( cli, &new_clnt_cred);
 
   prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
   prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
@@ -400,17 +398,7 @@ BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr)
   uint16 validation_level = 3;
   BOOL ok = False;
 
-  /*
-   * Create the new client credentials.
-   */
-
-  cli->clnt_cred.timestamp.time = time(NULL);
-
-  memcpy(&new_clnt_cred, &cli->clnt_cred, sizeof(new_clnt_cred));
-
-  /* Calculate the new credentials. */
-  cred_create(cli->sess_key, &(cli->clnt_cred.challenge),
-              new_clnt_cred.timestamp, &(new_clnt_cred.challenge));
+  gen_next_creds( cli, &new_clnt_cred);
 
   prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
   prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
@@ -453,7 +441,7 @@ BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr)
        */
       DEBUG(0,("cli_net_sam_logoff: server %s replied with bad credential (bad machine \
 password ?).\n", cli->desthost ));
-        ok = False;
+      ok = False;
     }
   }
 
index c5dd23a00eda0c6a826f755fa4a04d16561f58ac..84a88e4b92fc7820f0a51000dd0d0ac1a48e715e 100644 (file)
@@ -499,9 +499,8 @@ void net_io_r_auth_2(char *desc,  NET_R_AUTH_2 *r_a, prs_struct *ps, int depth)
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
-void make_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char sess_key[16],
-               char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
-               DOM_CRED *cred, char nt_cypher[16])
+void make_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char *logon_srv, char *acct_name, 
+                uint16 sec_chan, char *comp_name, DOM_CRED *cred, char nt_cypher[16])
 {
        if (q_s == NULL || cred == NULL) return;
 
@@ -748,7 +747,7 @@ void make_id_info2(NET_ID_INFO_2 *id, char *domain_name,
 }
 
 /*******************************************************************
-reads or writes an NET_ID_INFO_1 structure.
+reads or writes an NET_ID_INFO_2 structure.
 ********************************************************************/
 void net_io_id_info2(char *desc,  NET_ID_INFO_2 *id, prs_struct *ps, int depth)
 {
index 6aa1cd707e5adcfad8cf4277e197ae53f5526bf4..1f76d545f69d4f4e4bfc1eaa606aebdaf2c24212 100644 (file)
@@ -383,14 +383,14 @@ static void api_net_srv_pwset( int uid,
 
                DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
 
-               pstrcpy(mach_acct, unistrn2(q_a.clnt_id.login.uni_acct_name.buffer,
-                                                                       q_a.clnt_id.login.uni_acct_name.uni_str_len));
+                pstrcpy(mach_acct, unistrn2(q_a.clnt_id.login.uni_acct_name.buffer,
+                        q_a.clnt_id.login.uni_acct_name.uni_str_len));
 
-               DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
+                DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
 
-               become_root(True);
-               smb_pass = getsmbpwnam(mach_acct);
-               unbecome_root(True);
+                become_root(True);
+                smb_pass = getsmbpwnam(mach_acct);
+                unbecome_root(True);
 
                if (smb_pass != NULL)
                {
@@ -402,7 +402,7 @@ static void api_net_srv_pwset( int uid,
                     DEBUG(100,("%02X ", q_a.pwd[i]));
                   DEBUG(100,("\n"));
 
-                  cred_hash3( pwd, q_a.pwd, vuser->dc.sess_key);
+                  cred_hash3( pwd, q_a.pwd, vuser->dc.sess_key, 1);
 
                   /* lies!  nt and lm passwords are _not_ the same: don't care */
                   smb_pass->smb_passwd    = pwd;
@@ -515,13 +515,13 @@ static uint32 net_login_network(NET_ID_INFO_2 *id2,
                                user_struct *vuser)
 {
        DEBUG(5,("net_login_network: lm_len: %d nt_len: %d\n",
-               id2->lm_chal_resp.str_str_len, 
-               id2->nt_chal_resp.str_str_len));
+               id2->hdr_lm_chal_resp.str_str_len, 
+               id2->hdr_nt_chal_resp.str_str_len));
 
        /* JRA. Check the NT password first if it exists - this is a higher quality 
            password, if it exists and it doesn't match - fail. */
 
-       if (id2->nt_chal_resp.str_str_len == 24 && 
+       if (id2->hdr_nt_chal_resp.str_str_len == 24 && 
                smb_pass->smb_nt_passwd != NULL)
        {
                if(smb_password_check(id2->nt_chal_resp.buffer,
@@ -540,7 +540,7 @@ static uint32 net_login_network(NET_ID_INFO_2 *id2,
           not do, for various security-hole reasons).
         */
 
-       if (id2->lm_chal_resp.str_str_len == 24 &&
+       if (id2->hdr_lm_chal_resp.str_str_len == 24 &&
                smb_password_check(id2->lm_chal_resp.buffer,
                                   smb_pass->smb_passwd,
                                   id2->lm_chal))
index 0e9ec620b17d2b9d085e80b42f212199a625d8d0..21424592f1b51636b3e63ba1269d19bac2f4c09b 100644 (file)
@@ -32,6 +32,7 @@ extern int Protocol;
 static pstring session_users="";
 
 extern pstring global_myname;
+extern fstring global_myworkgroup;
 
 /* these are kept here to keep the string_combinations function simple */
 static char this_user[100]="";
@@ -1865,7 +1866,6 @@ use this machine as the password server.\n"));
        return(True);
 }
 
-#ifdef DOMAIN_CLIENT
 /***********************************************************************
  Do the same as security=server, but using NT Domain calls and a session
  key from the machine password.
@@ -1875,17 +1875,20 @@ BOOL domain_client_validate( char *user, char *domain,
                              char *smb_apasswd, int smb_apasslen, 
                              char *smb_ntpasswd, int smb_ntpasslen)
 {
-  unsigned char local_lm_hash[21];
-  unsigned char local_nt_hash[21];
   unsigned char local_challenge[8];
   unsigned char local_lm_response[24];
   unsigned char local_nt_reponse[24];
-  BOOL encrypted = True;
+  unsigned char machine_passwd[16];
+  time_t lct;
   fstring remote_machine;
   char *p;
   struct in_addr dest_ip;
+  NET_ID_INFO_CTR ctr;
+  NET_USER_INFO_3 info3;
   struct cli_state cli;
+  uint32 smb_uid_low;
   BOOL connected_ok = False;
+  void *vp;
 
   /* 
    * Check that the requested domain is not our own machine name.
@@ -1909,14 +1912,9 @@ BOOL domain_client_validate( char *user, char *domain,
      */
 
     DEBUG(3,("domain_client_validate: User passwords not in encrypted format.\n"));
-    encrypted = False;
-    memset(local_lm_hash, '\0', sizeof(local_lm_hash));
-    E_P16((uchar *) smb_apasswd, local_lm_hash);
-    memset(local_nt_hash, '\0', sizeof(local_nt_hash));
-    E_md4hash((uchar *) smb_ntpasswd, local_nt_hash);
     generate_random_buffer( local_challenge, 8, False);
-    E_P24(local_lm_hash, local_challenge, local_lm_response);
-    E_P24(local_nt_hash, local_challenge, local_nt_reponse);
+    SMBencrypt( smb_apasswd, local_challenge, local_lm_response);
+    SMBNTencrypt( smb_ntpasswd, local_challenge, local_nt_reponse);
     smb_apasslen = 24;
     smb_ntpasslen = 24;
     smb_apasswd = (char *)local_lm_response;
@@ -1934,6 +1932,29 @@ BOOL domain_client_validate( char *user, char *domain,
     }
   }
 
+  /*
+   * Get the machine account password.
+   */
+  if((vp = machine_password_lock( global_myworkgroup, global_myname, False)) == NULL) {
+    DEBUG(0,("domain_client_validate: unable to open the machine account password file for \
+machine %s in domain %s.\n", global_myname, global_myworkgroup ));
+    return False;
+  }
+
+  if(get_machine_account_password( vp, machine_passwd, &lct) == False) {
+    DEBUG(0,("domain_client_validate: unable to read the machine account password for \
+machine %s in domain %s.\n", global_myname, global_myworkgroup ));
+    machine_password_unlock(vp);
+    return False;
+  }
+
+  machine_password_unlock(vp);
+
+  /* 
+   * Here we should check the last change time to see if the machine
+   * password needs changing..... TODO... JRA. 
+   */
+
   /*
    * At this point, smb_apasswd points to the lanman response to
    * the challenge in local_challenge, and smb_ntpasswd points to
@@ -1942,6 +1963,12 @@ BOOL domain_client_validate( char *user, char *domain,
    * see if they were valid.
    */
 
+  memset(&cli, '\0', sizeof(struct cli_state));
+  if(cli_initialise(&cli) == False) {
+    DEBUG(0,("domain_client_validate: unable to initialize client connection.\n"));
+    return False;
+  }
+
   /*
    * Treat each name in the 'password server =' line as a potential
    * PDC/BDC. Contact each in turn and try and authenticate.
@@ -1963,8 +1990,6 @@ BOOL domain_client_validate( char *user, char *domain,
       continue;
     }
       
-    memset(&cli, '\0', sizeof(struct cli_state));
-
     if (!cli_connect(&cli, remote_machine, &dest_ip)) {
       DEBUG(0,("domain_client_validate: unable to connect to SMB server on \
 machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
@@ -2032,7 +2057,6 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
     return False;
   }
 
-#if 0 /* for now... JRA */
   /*
    * Ok - we have an anonymous connection to the IPC$ share.
    * Now start the NT Domain stuff :-).
@@ -2041,14 +2065,49 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
   if(cli_nt_session_open(&cli, PIPE_NETLOGON, False) == False) {
     DEBUG(0,("domain_client_validate: unable to open the domain client session to \
 machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
-    cli_close(&cli, fnum);
+    cli_close(&cli, cli.nt_pipe_fnum);
     cli_ulogoff(&cli);
     cli_shutdown(&cli);
     return False; 
   }
 
-  if(cli_nt_setup_creds(&cli,) HERE 
-#endif
-  return False;
+  if(cli_nt_setup_creds(&cli, machine_passwd) == False) {
+    DEBUG(0,("domain_client_validate: unable to setup the PDC credentials to machine \
+%s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
+    cli_close(&cli, cli.nt_pipe_fnum);
+    cli_ulogoff(&cli);
+    cli_shutdown(&cli);
+    return False;
+  }
+
+  /* We really don't care what LUID we give the user. */
+  generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False);
+
+  if(cli_nt_login_network(&cli, domain, user, smb_uid_low, local_challenge,
+                          smb_apasswd, smb_ntpasswd, &ctr, &info3) == False) {
+    DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \
+%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli)));
+    cli_close(&cli, cli.nt_pipe_fnum);
+    cli_ulogoff(&cli);
+    cli_shutdown(&cli);
+    return False;
+  }
+
+  /*
+   * Here, if we really want it, we have lots of info about the user in info3.
+   */
+
+  if(cli_nt_logoff(&cli, &ctr) == False) {
+    DEBUG(0,("domain_client_validate: unable to log off user %s in domain \
+%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli)));        
+    cli_close(&cli, cli.nt_pipe_fnum);
+    cli_ulogoff(&cli);
+    cli_shutdown(&cli);
+    return False;
+  }
+
+  cli_close(&cli, cli.nt_pipe_fnum);
+  cli_ulogoff(&cli);
+  cli_shutdown(&cli);
+  return True;
 }
-#endif /* DOMAIN_CLIENT */
index fe1de65be39d800a4604e989383834d625d393ca..a8a0c2f98cf20bbff5f046cf9d2c74b077c861c5 100644 (file)
@@ -516,11 +516,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
     passlen1 = MIN(passlen1, MAX_PASS_LEN);
     passlen2 = MIN(passlen2, MAX_PASS_LEN);
 
-#ifdef DOMAIN_CLIENT
     if(doencrypt || ((lp_security() == SEC_SERVER) || (lp_security() == SEC_DOMAIN))) {
-#else /* DOMAIN_CLIENT */
-    if(doencrypt || lp_security() == SEC_SERVER) {
-#endif /* DOMAIN_CLIENT */
       /* Save the lanman2 password and the NT md4 password. */
       smb_apasslen = passlen1;
       memcpy(smb_apasswd,p,smb_apasslen);
@@ -608,12 +604,10 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
                  server_validate(user, domain, 
                                  smb_apasswd, smb_apasslen, 
                                  smb_ntpasswd, smb_ntpasslen)) &&
-#ifdef DOMAIN_CLIENT
                 !(lp_security() == SEC_DOMAIN &&
                   domain_client_validate(user, domain,
                                   smb_apasswd, smb_apasslen,
                                   smb_ntpasswd, smb_ntpasslen)) &&
-#endif /* DOMAIN_CLIENT */
       !check_hosts_equiv(user))
     {
 
index 167911e4978c84be938fafdf9759cb59dbdae9de..ac18bb40388d5a352f9b759efc05d3078753edeb 100644 (file)
@@ -4133,11 +4133,7 @@ static int reply_negprot(char *inbuf,char *outbuf, int dum_size, int dum_buffsiz
     
   /* a special case to stop password server loops */
   if (Index == 1 && strequal(remote_machine,myhostname) && 
-#ifdef DOMAIN_CLIENT
       (lp_security()==SEC_SERVER || lp_security()==SEC_DOMAIN))
-#else /* DOMAIN_CLIENT */
-      lp_security()==SEC_SERVER)
-#endif /* DOMAIN_CLIENT */
     exit_server("Password server loop!");
   
   /* Check for protocols, most desirable first */