Better explanation message for dmalloc.
[ira/wip.git] / source3 / rpc_server / srv_netlog_nt.c
index 2047aaf255d10ca1cbd8ee4307f6ce30dc99600d..a07ebc9a3fc3ceb66c028c1d518c62390c194b76 100644 (file)
@@ -6,6 +6,7 @@
  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
  *  Copyright (C) Paul Ashton                       1997.
  *  Copyright (C) Jeremy Allison               1998-2001.
+ *  Copyirht  (C) Andrew Bartlett                   2001.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
 
 #include "includes.h"
 
-extern int DEBUGLEVEL;
-
-extern BOOL sam_logon_in_ssb;
-extern pstring samlogon_user;
 extern pstring global_myname;
 extern DOM_SID global_sam_sid;
 
@@ -38,7 +35,7 @@ extern DOM_SID global_sam_sid;
  *************************************************************************/
 
 static void init_net_r_req_chal(NET_R_REQ_CHAL *r_c,
-                                DOM_CHAL *srv_chal, int status)
+                                DOM_CHAL *srv_chal, NTSTATUS status)
 {
        DEBUG(6,("init_net_r_req_chal: %d\n", __LINE__));
        memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(srv_chal->data));
@@ -52,25 +49,78 @@ static void init_net_r_req_chal(NET_R_REQ_CHAL *r_c,
 #define ERROR_NO_SUCH_DOMAIN   0x54b
 #define ERROR_NO_LOGON_SERVERS 0x51f
 
+/*************************************************************************
+ net_reply_logon_ctrl:
+ *************************************************************************/
+
+/* Some flag values reverse engineered from NLTEST.EXE */
+
+#define LOGON_CTRL_IN_SYNC          0x00
+#define LOGON_CTRL_REPL_NEEDED      0x01
+#define LOGON_CTRL_REPL_IN_PROGRESS 0x02
+
+NTSTATUS _net_logon_ctrl(pipes_struct *p, NET_Q_LOGON_CTRL *q_u, 
+                      NET_R_LOGON_CTRL *r_u)
+{
+       uint32 flags = 0x0;
+       uint32 pdc_connection_status = 0x00; /* Maybe a win32 error code? */
+       
+       /* Setup the Logon Control response */
+
+       init_net_r_logon_ctrl(r_u, q_u->query_level, flags, 
+                             pdc_connection_status);
+
+       return r_u->status;
+}
+
+/****************************************************************************
+Send a message to smbd to do a sam synchronisation
+**************************************************************************/
+static void send_sync_message(void)
+{
+        TDB_CONTEXT *tdb;
+
+        tdb = tdb_open_log(lock_path("connections.tdb"), 0,
+                           TDB_DEFAULT, O_RDONLY, 0);
+
+        if (!tdb) {
+                DEBUG(3, ("send_sync_message(): failed to open connections "
+                          "database\n"));
+                return;
+        }
+
+        DEBUG(3, ("sending sam synchronisation message\n"));
+        
+        message_send_all(tdb, MSG_SMB_SAM_SYNC, NULL, 0, False, NULL);
+
+        tdb_close(tdb);
+}
+
 /*************************************************************************
  net_reply_logon_ctrl2:
  *************************************************************************/
 
-uint32 _net_logon_ctrl2(pipes_struct *p, NET_Q_LOGON_CTRL2 *q_u, NET_R_LOGON_CTRL2 *r_u)
+NTSTATUS _net_logon_ctrl2(pipes_struct *p, NET_Q_LOGON_CTRL2 *q_u, NET_R_LOGON_CTRL2 *r_u)
 {
-    /* lkclXXXX - guess what - absolutely no idea what these are! */
-    uint32 flags = 0x0;
-    uint32 pdc_connection_status = 0x0;
-    uint32 logon_attempts = 0x0;
-    uint32 tc_status = ERROR_NO_LOGON_SERVERS;
-    char *trusted_domain = "test_domain";
+        uint32 flags = 0x0;
+        uint32 pdc_connection_status = 0x0;
+        uint32 logon_attempts = 0x0;
+        uint32 tc_status = ERROR_NO_LOGON_SERVERS;
+        char *trusted_domain = "test_domain";
+
+        DEBUG(0, ("*** net long ctrl2 %d, %d, %d\n",
+                  q_u->function_code, q_u->query_level, q_u->switch_value));
 
        DEBUG(6,("_net_logon_ctrl2: %d\n", __LINE__));
 
+
        /* set up the Logon Control2 response */
-       init_r_logon_ctrl2(r_u, q_u->query_level,
-                          flags, pdc_connection_status, logon_attempts,
-                          tc_status, trusted_domain);
+       init_net_r_logon_ctrl2(r_u, q_u->query_level,
+                              flags, pdc_connection_status, logon_attempts,
+                              tc_status, trusted_domain);
+
+        if (lp_server_role() == ROLE_DOMAIN_BDC)
+                send_sync_message();
 
        DEBUG(6,("_net_logon_ctrl2: %d\n", __LINE__));
 
@@ -81,7 +131,7 @@ uint32 _net_logon_ctrl2(pipes_struct *p, NET_Q_LOGON_CTRL2 *q_u, NET_R_LOGON_CTR
  net_reply_trust_dom_list:
  *************************************************************************/
 
-uint32 _net_trust_dom_list(pipes_struct *p, NET_Q_TRUST_DOM_LIST *q_u, NET_R_TRUST_DOM_LIST *r_u)
+NTSTATUS _net_trust_dom_list(pipes_struct *p, NET_Q_TRUST_DOM_LIST *q_u, NET_R_TRUST_DOM_LIST *r_u)
 {
        char *trusted_domain = "test_domain";
        uint32 num_trust_domains = 1;
@@ -101,7 +151,7 @@ uint32 _net_trust_dom_list(pipes_struct *p, NET_Q_TRUST_DOM_LIST *q_u, NET_R_TRU
  ***********************************************************************************/
 
 static void init_net_r_srv_pwset(NET_R_SRV_PWSET *r_s,
-                             DOM_CRED *srv_cred, int status)  
+                             DOM_CRED *srv_cred, NTSTATUS status)  
 {
        DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__));
 
@@ -118,7 +168,7 @@ static void init_net_r_srv_pwset(NET_R_SRV_PWSET *r_s,
 static BOOL get_md4pw(char *md4pw, char *mach_acct)
 {
        SAM_ACCOUNT *sampass = NULL;
-       uint8 *pass;
+       const uint8 *pass;
        BOOL ret;
 
 #if 0
@@ -149,19 +199,19 @@ static BOOL get_md4pw(char *md4pw, char *mach_acct)
  
        if (ret==False) {
                DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
-               pdb_clear_sam(sampass);
+               pdb_free_sam(&sampass);
                return False;
        }
 
        if (!(pdb_get_acct_ctrl(sampass) & ACB_DISABLED) && ((pass=pdb_get_nt_passwd(sampass)) != NULL)) {
                memcpy(md4pw, pass, 16);
                dump_data(5, md4pw, 16);
-               pdb_clear_sam(sampass);
+               pdb_free_sam(&sampass);
                return True;
        }
        
        DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
-       pdb_clear_sam(sampass);
+       pdb_free_sam(&sampass);
        return False;
 
 }
@@ -170,16 +220,15 @@ static BOOL get_md4pw(char *md4pw, char *mach_acct)
  _net_req_chal
  *************************************************************************/
 
-uint32 _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u)
+NTSTATUS _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u)
 {
-       uint32 status = NT_STATUS_NOPROBLEMO;
+       NTSTATUS status = NT_STATUS_OK;
        fstring mach_acct;
 
        if (!get_valid_user_struct(p->vuid))
                return NT_STATUS_NO_SUCH_USER;
 
-       fstrcpy(mach_acct, dos_unistrn2(q_u->uni_logon_clnt.buffer,
-                                   q_u->uni_logon_clnt.uni_str_len));
+       rpcstr_pull(mach_acct,q_u->uni_logon_clnt.buffer,sizeof(fstring),q_u->uni_logon_clnt.uni_str_len*2,0);
 
        strlower(mach_acct);
        fstrcat(mach_acct, "$");
@@ -219,7 +268,7 @@ uint32 _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u)
  init_net_r_auth:
  *************************************************************************/
 
-static void init_net_r_auth(NET_R_AUTH *r_a, DOM_CHAL *resp_cred, int status)
+static void init_net_r_auth(NET_R_AUTH *r_a, DOM_CHAL *resp_cred, NTSTATUS status)
 {
        memcpy(r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
        r_a->status = status;
@@ -229,9 +278,9 @@ static void init_net_r_auth(NET_R_AUTH *r_a, DOM_CHAL *resp_cred, int status)
  _net_auth
  *************************************************************************/
 
-uint32 _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u)
+NTSTATUS _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u)
 {
-       uint32 status = NT_STATUS_NOPROBLEMO;
+       NTSTATUS status = NT_STATUS_OK;
        DOM_CHAL srv_cred;
        UTIME srv_time;
 
@@ -264,7 +313,7 @@ uint32 _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u)
  *************************************************************************/
 
 static void init_net_r_auth_2(NET_R_AUTH_2 *r_a,
-                              DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status)
+                              DOM_CHAL *resp_cred, NEG_FLAGS *flgs, NTSTATUS status)
 {
        memcpy(r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
        memcpy(&r_a->srv_flgs, flgs, sizeof(r_a->srv_flgs));
@@ -275,9 +324,9 @@ static void init_net_r_auth_2(NET_R_AUTH_2 *r_a,
  _net_auth_2
  *************************************************************************/
 
-uint32 _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
+NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
 {
-       uint32 status = NT_STATUS_NOPROBLEMO;
+       NTSTATUS status = NT_STATUS_OK;
        DOM_CHAL srv_cred;
        UTIME srv_time;
        NEG_FLAGS srv_flgs;
@@ -312,9 +361,9 @@ uint32 _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
  _net_srv_pwset
  *************************************************************************/
 
-uint32 _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_u)
+NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_u)
 {
-       uint32 status = NT_STATUS_WRONG_PASSWORD;
+       NTSTATUS status = NT_STATUS_WRONG_PASSWORD;
        DOM_CRED srv_cred;
        pstring mach_acct;
        SAM_ACCOUNT *sampass=NULL;
@@ -333,11 +382,21 @@ uint32 _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_
 
        DEBUG(5,("_net_srv_pwset: %d\n", __LINE__));
 
-       pstrcpy(mach_acct, dos_unistrn2(q_u->clnt_id.login.uni_acct_name.buffer,
-                                   q_u->clnt_id.login.uni_acct_name.uni_str_len));
+       rpcstr_pull(mach_acct,q_u->clnt_id.login.uni_acct_name.buffer,
+                       sizeof(mach_acct),q_u->clnt_id.login.uni_acct_name.uni_str_len*2,0);
 
        DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
        
+       /*
+        * Check the machine account name we're changing is the same
+        * as the one we've authenticated from. This prevents arbitrary
+        * machines changing other machine account passwords.
+        */
+
+       if (!strequal(mach_acct, p->dc.mach_acct)) {
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
        pdb_init_sam(&sampass);
 
        become_root();
@@ -347,21 +406,9 @@ uint32 _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_
        /* Ensure the account exists and is a machine account. */
 
        if (ret==False || !(pdb_get_acct_ctrl(sampass) & ACB_WSTRUST)) {
-               pdb_clear_sam(sampass);
+               pdb_free_sam(&sampass);
                return NT_STATUS_NO_SUCH_USER;
        }
-
-       /*
-        * Check the machine account name we're changing is the same
-        * as the one we've authenticated from. This prevents arbitrary
-        * machines changing other machine account passwords.
-        */
-
-       if (!strequal(mach_acct, p->dc.mach_acct)) {
-               pdb_clear_sam(sampass);
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
        
        DEBUG(100,("Server password set : new given value was :\n"));
        for(i = 0; i < 16; i++)
@@ -371,21 +418,39 @@ uint32 _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_
        cred_hash3( pwd, q_u->pwd, p->dc.sess_key, 0);
 
        /* lies!  nt and lm passwords are _not_ the same: don't care */
-       pdb_set_lanman_passwd (sampass, pwd);
-       pdb_set_nt_passwd     (sampass, pwd);
-       pdb_set_acct_ctrl     (sampass, ACB_WSTRUST);
+       if (!pdb_set_lanman_passwd (sampass, pwd)) {
+               pdb_free_sam(&sampass);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (!pdb_set_nt_passwd     (sampass, pwd)) {
+               pdb_free_sam(&sampass);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (!pdb_set_acct_ctrl     (sampass, ACB_WSTRUST)) {
+               pdb_free_sam(&sampass);
+               /* Not quite sure what this one qualifies as, but this will do */
+               return NT_STATUS_NO_MEMORY; 
+       }
+       if (!pdb_set_pass_changed_now     (sampass)) {
+               pdb_free_sam(&sampass);
+               /* Not quite sure what this one qualifies as, but this will do */
+               return NT_STATUS_NO_MEMORY; 
+       }
  
        become_root();
        ret = pdb_update_sam_account (sampass,False);
        unbecome_root();
  
        if (ret)
-               status = NT_STATUS_NOPROBLEMO;
+               status = NT_STATUS_OK;
 
        /* set up the LSA Server Password Set response */
        init_net_r_srv_pwset(r_u, &srv_cred, status);
 
-       pdb_clear_sam(sampass);
+       pdb_free_sam(&sampass);
        return r_u->status;
 }
 
@@ -394,7 +459,7 @@ uint32 _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_
  _net_sam_logoff:
  *************************************************************************/
 
-uint32 _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOFF *r_u)
+NTSTATUS _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOFF *r_u)
 {
        DOM_CRED srv_cred;
 
@@ -412,118 +477,30 @@ uint32 _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOFF
        r_u->buffer_creds = 1; /* yes, we have valid server credentials */
        memcpy(&r_u->srv_creds, &srv_cred, sizeof(r_u->srv_creds));
 
-       r_u->status = NT_STATUS_NOPROBLEMO;
+       r_u->status = NT_STATUS_OK;
 
        return r_u->status;
 }
 
-/*************************************************************************
- net_login_interactive:
- *************************************************************************/
-
-static uint32 net_login_interactive(NET_ID_INFO_1 *id1, SAM_ACCOUNT *sampass, pipes_struct *p)
-{
-       uint32 status = 0x0;
-
-       char nt_pwd[16];
-       char lm_pwd[16];
-       unsigned char key[16];
-
-       memset(key, 0, 16);
-       memcpy(key, p->dc.sess_key, 8);
-
-       memcpy(lm_pwd, id1->lm_owf.data, 16);
-       memcpy(nt_pwd, id1->nt_owf.data, 16);
-
-#ifdef DEBUG_PASSWORD
-       DEBUG(100,("key:"));
-       dump_data(100, (char *)key, 16);
-
-       DEBUG(100,("lm owf password:"));
-       dump_data(100, lm_pwd, 16);
-
-       DEBUG(100,("nt owf password:"));
-       dump_data(100, nt_pwd, 16);
-#endif
-
-       SamOEMhash((uchar *)lm_pwd, key, False);
-       SamOEMhash((uchar *)nt_pwd, key, False);
-
-#ifdef DEBUG_PASSWORD
-       DEBUG(100,("decrypt of lm owf password:"));
-       dump_data(100, lm_pwd, 16);
-
-       DEBUG(100,("decrypt of nt owf password:"));
-       dump_data(100, nt_pwd, 16);
-#endif
-
-       if (memcmp(pdb_get_lanman_passwd(sampass), lm_pwd, 16) != 0 ||
-           memcmp(pdb_get_nt_passwd(sampass), nt_pwd, 16) != 0) {
-               status = NT_STATUS_WRONG_PASSWORD;
-       }
-
-       return status;
-}
-
-/*************************************************************************
- _net_login_network:
- *************************************************************************/
-
-static uint32 net_login_network(NET_ID_INFO_2 *id2, SAM_ACCOUNT *sampass)
-{
-       uint8    *nt_pwd, *lanman_pwd;
-
-       DEBUG(5,("net_login_network: lm_len: %d nt_len: %d\n",
-               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. */
-
-       nt_pwd = pdb_get_nt_passwd(sampass);
-       lanman_pwd = pdb_get_lanman_passwd(sampass);
-
-       if (id2->hdr_nt_chal_resp.str_str_len == 24 && nt_pwd) {
-               if(smb_password_check((char *)id2->nt_chal_resp.buffer,
-                                  nt_pwd, id2->lm_chal)) 
-                       return NT_STATUS_NOPROBLEMO;
-               else
-                       return NT_STATUS_WRONG_PASSWORD;
-       }
-
-       /* lkclXXXX this is not a good place to put disabling of LM hashes in.
-          if that is to be done, first move this entire function into a
-          library routine that calls the two smb_password_check() functions.
-          if disabling LM hashes (which nt can do for security reasons) then
-          an attempt should be made to disable them everywhere (which nt does
-          not do, for various security-hole reasons).
-        */
-
-       if (id2->hdr_lm_chal_resp.str_str_len == 24 && lanman_pwd &&
-               smb_password_check((char *)id2->lm_chal_resp.buffer,
-                                  lanman_pwd, id2->lm_chal))
-               return NT_STATUS_NOPROBLEMO;
-
-       /* oops! neither password check succeeded */
-
-       return NT_STATUS_WRONG_PASSWORD;
-}
 
 /*************************************************************************
  _net_sam_logon
  *************************************************************************/
 
-uint32 _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_u)
+NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_u)
 {
-       uint32 status = NT_STATUS_NOPROBLEMO;
+       NTSTATUS status = NT_STATUS_OK;
        NET_USER_INFO_3 *usr_info = NULL;
+       NET_ID_INFO_CTR *ctr = q_u->sam_id.ctr;
        DOM_CRED srv_cred;
-       SAM_ACCOUNT *sampass = NULL;
-       uint16 acct_ctrl;
        UNISTR2 *uni_samlogon_user = NULL;
-       fstring nt_username;
-       BOOL ret;
-   
+       UNISTR2 *uni_samlogon_domain = NULL;
+       UNISTR2 *uni_samlogon_workstation = NULL;
+       fstring nt_username, nt_domain, nt_workstation;
+       auth_usersupplied_info *user_info = NULL;
+       auth_serversupplied_info *server_info = NULL;
+       extern userdom_struct current_user_info;
+               
        usr_info = (NET_USER_INFO_3 *)talloc(p->mem_ctx, sizeof(NET_USER_INFO_3));
        if (!usr_info)
                return NT_STATUS_NO_MEMORY;
@@ -552,12 +529,17 @@ uint32 _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_
     
        switch (q_u->sam_id.logon_level) {
        case INTERACTIVE_LOGON_TYPE:
-               uni_samlogon_user = &q_u->sam_id.ctr->auth.id1.uni_user_name;
+               uni_samlogon_user = &ctr->auth.id1.uni_user_name;
+               uni_samlogon_domain = &ctr->auth.id1.uni_domain_name;
+
+                uni_samlogon_workstation = &ctr->auth.id1.uni_wksta_name;
             
                DEBUG(3,("SAM Logon (Interactive). Domain:[%s].  ", lp_workgroup()));
                break;
        case NET_LOGON_TYPE:
-               uni_samlogon_user = &q_u->sam_id.ctr->auth.id2.uni_user_name;
+               uni_samlogon_user = &ctr->auth.id2.uni_user_name;
+               uni_samlogon_domain = &ctr->auth.id2.uni_domain_name;
+               uni_samlogon_workstation = &ctr->auth.id2.uni_wksta_name;
             
                DEBUG(3,("SAM Logon (Network). Domain:[%s].  ", lp_workgroup()));
                break;
@@ -568,75 +550,111 @@ uint32 _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_
 
        /* check username exists */
 
-       pstrcpy(nt_username, dos_unistrn2(uni_samlogon_user->buffer, uni_samlogon_user->uni_str_len));
+       rpcstr_pull(nt_username,uni_samlogon_user->buffer,sizeof(nt_username),uni_samlogon_user->uni_str_len*2,0);
+       rpcstr_pull(nt_domain,uni_samlogon_domain->buffer,sizeof(nt_domain),uni_samlogon_domain->uni_str_len*2,0);
+       rpcstr_pull(nt_workstation,uni_samlogon_workstation->buffer,sizeof(nt_workstation),uni_samlogon_workstation->uni_str_len*2,0);
 
-       DEBUG(3,("User:[%s]\n", nt_username));
-        
+       DEBUG(3,("User:[%s@%s] Requested Domain:[%s]\n", nt_username, 
+                 nt_workstation, nt_domain));
+       
+       pstrcpy(current_user_info.smb_name, nt_username);
+     
        /*
         * Convert to a UNIX username.
         */
 
-       map_username(nt_username);
-
-       pdb_init_sam(&sampass);
+       DEBUG(5,("Attempting validation level %d for unmapped username %s.\n", q_u->sam_id.ctr->switch_value, nt_username));
 
-       /* get the account information */
-       become_root();
-       ret = pdb_getsampwnam(sampass, nt_username);
-       unbecome_root();
+       switch (ctr->switch_value) {
+       case NET_LOGON_TYPE:
+       {
+               struct auth_context *auth_context = NULL;
+               if (!NT_STATUS_IS_OK(status = make_auth_context_fixed(&auth_context, ctr->auth.id2.lm_chal))) {
+                       return status;
+               }
 
-       if (ret == False){
-               pdb_clear_sam(sampass);
-               return NT_STATUS_NO_SUCH_USER;
+               /* Standard challenge/response authenticaion */
+               if (!make_user_info_netlogon_network(&user_info, 
+                                                    nt_username, nt_domain, 
+                                                    nt_workstation, 
+                                                    ctr->auth.id2.lm_chal_resp.buffer,
+                                                    ctr->auth.id2.lm_chal_resp.str_str_len,
+                                                    ctr->auth.id2.nt_chal_resp.buffer,
+                                                    ctr->auth.id2.nt_chal_resp.str_str_len)) {
+                       status = NT_STATUS_NO_MEMORY;
+               } else {
+                       status = auth_context->check_ntlm_password(auth_context, user_info, &server_info);
+               }
+               (auth_context->free)(&auth_context);
+                       
+               break;
        }
+       case INTERACTIVE_LOGON_TYPE:
+               /* 'Interactive' autheticaion, supplies the password in its
+                  MD4 form, encrypted with the session key.  We will
+                  convert this to chellange/responce for the auth
+                  subsystem to chew on */
+       {
+               struct auth_context *auth_context = NULL;
+               const uint8 *chal;
+               if (!NT_STATUS_IS_OK(status = make_auth_context_subsystem(&auth_context))) {
+                       return status;
+               }
+               
+               chal = auth_context->get_ntlm_challenge(auth_context);
+
+               if (!make_user_info_netlogon_interactive(&user_info, 
+                                                        nt_username, nt_domain, 
+                                                        nt_workstation, chal,
+                                                        ctr->auth.id1.lm_owf.data, 
+                                                        ctr->auth.id1.nt_owf.data, 
+                                                        p->dc.sess_key)) {
+                       status = NT_STATUS_NO_MEMORY;
+               } else {
+                       status = auth_context->check_ntlm_password(auth_context, user_info, &server_info);
+               }
 
-       acct_ctrl = pdb_get_acct_ctrl(sampass);
+               (auth_context->free)(&auth_context);
 
-       if (acct_ctrl & ACB_DISABLED) {
-               pdb_clear_sam(sampass);
-               return NT_STATUS_ACCOUNT_DISABLED;
-       }
-    
-       /* Validate password - if required. */
-    
-       if (!(acct_ctrl & ACB_PWNOTREQ)) {
-               switch (q_u->sam_id.logon_level) {
-               case INTERACTIVE_LOGON_TYPE:
-                       /* interactive login. */
-                       status = net_login_interactive(&q_u->sam_id.ctr->auth.id1, sampass, p);
-                       break;
-               case NET_LOGON_TYPE:
-                       /* network login.  lm challenge and 24 byte responses */
-                       status = net_login_network(&q_u->sam_id.ctr->auth.id2, sampass);
-                       break;
-               }
+               break;
        }
+       default:
+               DEBUG(2,("SAM Logon: unsupported switch value\n"));
+               return NT_STATUS_INVALID_INFO_CLASS;
+       } /* end switch */
+       
+       free_user_info(&user_info);
+       
+       DEBUG(5, ("_net_sam_logon: check_password returned status %s\n", 
+                 get_nt_error_msg(status)));
+
+       /* Check account and password */
     
-       if (status != NT_STATUS_NOPROBLEMO) {
-               pdb_clear_sam(sampass);
+       if (!NT_STATUS_IS_OK(status)) {
+               free_server_info(&server_info);
                return status;
        }
 
-       /* lkclXXXX this is the point at which, if the login was
-               successful, that the SAM Local Security Authority should
-               record that the user is logged in to the domain.
-       */
+       if (server_info->guest) {
+               /* We don't like guest domain logons... */
+               DEBUG(5,("_net_sam_logon: Attempted domain logon as GUEST denied.\n"));
+               free_server_info(&server_info);
+               return NT_STATUS_LOGON_FAILURE;
+       }
+
+       /* This is the point at which, if the login was successful, that
+           the SAM Local Security Authority should record that the user is
+           logged in to the domain.  */
     
        {
                DOM_GID *gids = NULL;
                int num_gids = 0;
                pstring my_name;
                pstring my_workgroup;
-               pstring domain_groups;
        
                /* set up pointer indicating user/password failed to be found */
                usr_info->ptr_user_info = 0;
         
-               /* XXXX hack to get standard_sub_basic() to use sam logon username */
-               /* possibly a better way would be to do a become_user() call */
-               sam_logon_in_ssb = True;
-               pstrcpy(samlogon_user, nt_username);
-
                pstrcpy(my_workgroup, lp_workgroup());
                pstrcpy(my_name, global_myname);
                strupper(my_name);
@@ -648,29 +666,25 @@ uint32 _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_
                 * rids and then into machine sids for this user.
                 * JRA.
                 */
+
+               gids = NULL;
+               get_domain_user_groups(p->mem_ctx, &num_gids, &gids, server_info->sam_account);
         
-               get_domain_user_groups(domain_groups, nt_username);
-        
-               /*
-                * make_dom_gids allocates the gids array. JRA.
-                */
-               gids = NULL;
-               num_gids = make_dom_gids(p->mem_ctx, domain_groups, &gids);
-        
-               sam_logon_in_ssb = False;
-        
-               init_net_user_info3(p->mem_ctx, usr_info, sampass,
+               init_net_user_info3(p->mem_ctx, usr_info, server_info->sam_account,
                             0, /* logon_count */
                             0, /* bad_pw_count */
                             num_gids,    /* uint32 num_groups */
                             gids    , /* DOM_GID *gids */
                             0x20    , /* uint32 user_flgs (?) */
-                            NULL, /* char sess_key[16] */
+                            NULL, /* uchar sess_key[16] */
                             my_name     , /* char *logon_srv */
                             my_workgroup, /* char *logon_dom */
                             &global_sam_sid,     /* DOM_SID *dom_sid */
                             NULL); /* char *other_sids */
+
        }
-       pdb_clear_sam(sampass);
+       free_server_info(&server_info);
        return status;
 }
+
+