updated the 3.0 branch from the head branch - ready for alpha18
[samba.git] / source3 / rpc_server / srv_netlog_nt.c
index 6f0d2384d555e3d779353b3a27f271b7767835b4..4ab9c470d0803cc8d25dddb2190f0acada1bc89e 100644 (file)
@@ -1,6 +1,5 @@
 /* 
- *  Unix SMB/Netbios implementation.
- *  Version 1.9.
+ *  Unix SMB/CIFS implementation.
  *  RPC Pipe client / server routines
  *  Copyright (C) Andrew Tridgell              1992-1997,
  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
 
 #include "includes.h"
 
-extern BOOL sam_logon_in_ssb;
-extern pstring samlogon_user;
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_SRV
+
 extern pstring global_myname;
-extern DOM_SID global_sam_sid;
 
 /*************************************************************************
  init_net_r_req_chal:
@@ -93,7 +92,7 @@ static void send_sync_message(void)
 
         DEBUG(3, ("sending sam synchronisation message\n"));
         
-        message_send_all(tdb, MSG_SMB_SAM_SYNC, NULL, 0, False);
+        message_send_all(tdb, MSG_SMB_SAM_SYNC, NULL, 0, False, NULL);
 
         tdb_close(tdb);
 }
@@ -153,7 +152,7 @@ NTSTATUS _net_trust_dom_list(pipes_struct *p, NET_Q_TRUST_DOM_LIST *q_u, NET_R_T
  ***********************************************************************************/
 
 static void init_net_r_srv_pwset(NET_R_SRV_PWSET *r_s,
-                             DOM_CRED *srv_cred, NTSTATUS status)  
+                                DOM_CRED *srv_cred, NTSTATUS status)  
 {
        DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__));
 
@@ -172,6 +171,7 @@ static BOOL get_md4pw(char *md4pw, char *mach_acct)
        SAM_ACCOUNT *sampass = NULL;
        const uint8 *pass;
        BOOL ret;
+       uint32 acct_ctrl;
 
 #if 0
     /*
@@ -191,7 +191,7 @@ static BOOL get_md4pw(char *md4pw, char *mach_acct)
        }
 #endif /* 0 */
 
-       if(!pdb_init_sam(&sampass))
+       if(!NT_STATUS_IS_OK(pdb_init_sam(&sampass)))
                return False;
 
        /* JRA. This is ok as it is only used for generating the challenge. */
@@ -205,7 +205,12 @@ static BOOL get_md4pw(char *md4pw, char *mach_acct)
                return False;
        }
 
-       if (!(pdb_get_acct_ctrl(sampass) & ACB_DISABLED) && ((pass=pdb_get_nt_passwd(sampass)) != NULL)) {
+       acct_ctrl = pdb_get_acct_ctrl(sampass);
+       if (!(acct_ctrl & ACB_DISABLED) &&
+           ((acct_ctrl & ACB_DOMTRUST) ||
+            (acct_ctrl & ACB_WSTRUST) ||
+            (acct_ctrl & ACB_SVRTRUST)) &&
+           ((pass=pdb_get_nt_passwd(sampass)) != NULL)) {
                memcpy(md4pw, pass, 16);
                dump_data(5, md4pw, 16);
                pdb_free_sam(&sampass);
@@ -225,45 +230,25 @@ static BOOL get_md4pw(char *md4pw, char *mach_acct)
 NTSTATUS _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u)
 {
        NTSTATUS status = NT_STATUS_OK;
-       fstring mach_acct;
-
-       if (!get_valid_user_struct(p->vuid))
-               return NT_STATUS_NO_SUCH_USER;
-
-       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, "$");
 
-       if (get_md4pw((char *)p->dc.md4pw, mach_acct)) {
-               /* copy the client credentials */
-               memcpy(p->dc.clnt_chal.data          , q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
-               memcpy(p->dc.clnt_cred.challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
+       rpcstr_pull(p->dc.remote_machine,q_u->uni_logon_clnt.buffer,sizeof(fstring),q_u->uni_logon_clnt.uni_str_len*2,0);
 
-               /* create a server challenge for the client */
-               /* Set these to random values. */
-               generate_random_buffer(p->dc.srv_chal.data, 8, False);
-
-               memcpy(p->dc.srv_cred.challenge.data, p->dc.srv_chal.data, 8);
-
-               memset((char *)p->dc.sess_key, '\0', sizeof(p->dc.sess_key));
-
-               /* from client / server challenges and md4 password, generate sess key */
-               cred_session_key(&p->dc.clnt_chal, &p->dc.srv_chal,
-                                (char *)p->dc.md4pw, p->dc.sess_key);
+       /* create a server challenge for the client */
+       /* Set these to random values. */
+       generate_random_buffer(p->dc.srv_chal.data, 8, False);
+       
+       memcpy(p->dc.srv_cred.challenge.data, p->dc.srv_chal.data, 8);
 
-               /* Save the machine account name. */
-               fstrcpy(p->dc.mach_acct, mach_acct);
+       memcpy(p->dc.clnt_chal.data          , q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
+       memcpy(p->dc.clnt_cred.challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
 
-       } else {
-               /* lkclXXXX take a guess at a good error message to return :-) */
-               status = NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
-       }
+       memset((char *)p->dc.sess_key, '\0', sizeof(p->dc.sess_key));
 
+       p->dc.challenge_sent = True;
        /* set up the LSA REQUEST CHALLENGE response */
        init_net_r_req_chal(r_u, &p->dc.srv_chal, status);
-
-       return r_u->status;
+       
+       return status;
 }
 
 /*************************************************************************
@@ -285,26 +270,41 @@ NTSTATUS _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u)
        NTSTATUS status = NT_STATUS_OK;
        DOM_CHAL srv_cred;
        UTIME srv_time;
-
-       if (!get_valid_user_struct(p->vuid))
-               return NT_STATUS_NO_SUCH_USER;
+       fstring mach_acct;
 
        srv_time.time = 0;
 
-       /* check that the client credentials are valid */
-       if (cred_assert(&q_u->clnt_chal, p->dc.sess_key, &p->dc.clnt_cred.challenge, srv_time)) {
+       rpcstr_pull(mach_acct, q_u->clnt_id.uni_acct_name.buffer,sizeof(fstring),q_u->clnt_id.uni_acct_name.uni_str_len*2,0);
 
-               /* create server challenge for inclusion in the reply */
-               cred_create(p->dc.sess_key, &p->dc.srv_cred.challenge, srv_time, &srv_cred);
+       if (p->dc.challenge_sent && get_md4pw((char *)p->dc.md4pw, mach_acct)) {
 
-               /* copy the received client credentials for use next time */
-               memcpy(p->dc.clnt_cred.challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
-               memcpy(p->dc.srv_cred .challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
+               /* from client / server challenges and md4 password, generate sess key */
+               cred_session_key(&p->dc.clnt_chal, &p->dc.srv_chal,
+                                (char *)p->dc.md4pw, p->dc.sess_key);
+               
+               /* check that the client credentials are valid */
+               if (cred_assert(&q_u->clnt_chal, p->dc.sess_key, &p->dc.clnt_cred.challenge, srv_time)) {
+                       
+                       /* create server challenge for inclusion in the reply */
+                       cred_create(p->dc.sess_key, &p->dc.srv_cred.challenge, srv_time, &srv_cred);
+               
+                       /* copy the received client credentials for use next time */
+                       memcpy(p->dc.clnt_cred.challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
+                       memcpy(p->dc.srv_cred .challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
+                       
+                       /* Save the machine account name. */
+                       fstrcpy(p->dc.mach_acct, mach_acct);
+               
+                       p->dc.authenticated = True;
+
+               } else {
+                       status = NT_STATUS_ACCESS_DENIED;
+               }
        } else {
                status = NT_STATUS_ACCESS_DENIED;
        }
-
-       /* set up the LSA AUTH response */
+       
+       /* set up the LSA AUTH response */
        init_net_r_auth(r_u, &srv_cred, status);
 
        return r_u->status;
@@ -332,25 +332,40 @@ NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
        DOM_CHAL srv_cred;
        UTIME srv_time;
        NEG_FLAGS srv_flgs;
-
-       if (!get_valid_user_struct(p->vuid))
-               return NT_STATUS_NO_SUCH_USER;
+       fstring mach_acct;
 
        srv_time.time = 0;
 
-       /* check that the client credentials are valid */
-       if (cred_assert(&q_u->clnt_chal, p->dc.sess_key, &p->dc.clnt_cred.challenge, srv_time)) {
+       rpcstr_pull(mach_acct, q_u->clnt_id.uni_acct_name.buffer,sizeof(fstring),q_u->clnt_id.uni_acct_name.uni_str_len*2,0);
 
-               /* create server challenge for inclusion in the reply */
-               cred_create(p->dc.sess_key, &p->dc.srv_cred.challenge, srv_time, &srv_cred);
+       if (p->dc.challenge_sent && get_md4pw((char *)p->dc.md4pw, mach_acct)) {
+               
+               /* from client / server challenges and md4 password, generate sess key */
+               cred_session_key(&p->dc.clnt_chal, &p->dc.srv_chal,
+                                (char *)p->dc.md4pw, p->dc.sess_key);
+               
+               /* check that the client credentials are valid */
+               if (cred_assert(&q_u->clnt_chal, p->dc.sess_key, &p->dc.clnt_cred.challenge, srv_time)) {
+                       
+                       /* create server challenge for inclusion in the reply */
+                       cred_create(p->dc.sess_key, &p->dc.srv_cred.challenge, srv_time, &srv_cred);
+                       
+                       /* copy the received client credentials for use next time */
+                       memcpy(p->dc.clnt_cred.challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
+                       memcpy(p->dc.srv_cred .challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
+                       
+                       /* Save the machine account name. */
+                       fstrcpy(p->dc.mach_acct, mach_acct);
+                       
+                       p->dc.authenticated = True;
 
-               /* copy the received client credentials for use next time */
-               memcpy(p->dc.clnt_cred.challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
-               memcpy(p->dc.srv_cred .challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
+               } else {
+                       status = NT_STATUS_ACCESS_DENIED;
+               }
        } else {
                status = NT_STATUS_ACCESS_DENIED;
        }
-
+       
        srv_flgs.neg_flags = 0x000001ff;
 
        /* set up the LSA AUTH 2 response */
@@ -365,53 +380,51 @@ NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
 
 NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_u)
 {
-       NTSTATUS status = NT_STATUS_WRONG_PASSWORD;
+       NTSTATUS status = NT_STATUS_ACCESS_DENIED;
        DOM_CRED srv_cred;
-       pstring mach_acct;
+       pstring workstation;
        SAM_ACCOUNT *sampass=NULL;
        BOOL ret = False;
        unsigned char pwd[16];
        int i;
-
-       if (!get_valid_user_struct(p->vuid))
-               return NT_STATUS_NO_SUCH_USER;
+       uint32 acct_ctrl;
 
        /* checks and updates credentials.  creates reply credentials */
-       if (!deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->clnt_id.cred, &srv_cred))
+       if (!(p->dc.authenticated && deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->clnt_id.cred, &srv_cred)))
                return NT_STATUS_INVALID_HANDLE;
 
        memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred));
 
        DEBUG(5,("_net_srv_pwset: %d\n", __LINE__));
 
-       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);
+       rpcstr_pull(workstation,q_u->clnt_id.login.uni_comp_name.buffer,
+                   sizeof(workstation),q_u->clnt_id.login.uni_comp_name.uni_str_len*2,0);
 
-       DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
+       DEBUG(3,("Server Password Set by Wksta:[%s] on account [%s]\n", workstation, p->dc.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();
-       ret=pdb_getsampwnam(sampass, mach_acct);
+       ret=pdb_getsampwnam(sampass, p->dc.mach_acct);
        unbecome_root();
 
        /* Ensure the account exists and is a machine account. */
+       
+       acct_ctrl = pdb_get_acct_ctrl(sampass);
 
-       if (ret==False || !(pdb_get_acct_ctrl(sampass) & ACB_WSTRUST)) {
+       if (!(ret 
+             && (acct_ctrl & ACB_WSTRUST ||
+                     acct_ctrl & ACB_SVRTRUST ||
+                     acct_ctrl & ACB_DOMTRUST))) {
                pdb_free_sam(&sampass);
                return NT_STATUS_NO_SUCH_USER;
        }
        
+       if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED) {
+               pdb_free_sam(&sampass);
+               return NT_STATUS_ACCOUNT_DISABLED;
+       }
+
        DEBUG(100,("Server password set : new given value was :\n"));
        for(i = 0; i < 16; i++)
                DEBUG(100,("%02X ", q_u->pwd[i]));
@@ -430,20 +443,14 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *
                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
+               return NT_STATUS_UNSUCCESSFUL
        }
  
        become_root();
-       ret = pdb_update_sam_account (sampass,False);
+       ret = pdb_update_sam_account (sampass);
        unbecome_root();
  
        if (ret)
@@ -469,8 +476,8 @@ NTSTATUS _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOF
                return NT_STATUS_NO_SUCH_USER;
 
        /* checks and updates credentials.  creates reply credentials */
-       if (!deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, 
-                       &q_u->sam_id.client.cred, &srv_cred))
+       if (!(p->dc.authenticated && deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, 
+                                                    &q_u->sam_id.client.cred, &srv_cred)))
                return NT_STATUS_INVALID_HANDLE;
 
        memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred));
@@ -501,31 +508,33 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
        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;
+       SAM_ACCOUNT *sampw;
                
        usr_info = (NET_USER_INFO_3 *)talloc(p->mem_ctx, sizeof(NET_USER_INFO_3));
        if (!usr_info)
                return NT_STATUS_NO_MEMORY;
 
        ZERO_STRUCTP(usr_info);
+
+       /* store the user information, if there is any. */
+       r_u->user = usr_info;
+       r_u->switch_value = 0; /* indicates no info */
+       r_u->auth_resp = 1; /* authoritative response */
+       r_u->switch_value = 3; /* indicates type of validation user info */
  
        if (!get_valid_user_struct(p->vuid))
                return NT_STATUS_NO_SUCH_USER;
     
        /* checks and updates credentials.  creates reply credentials */
-       if (!deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->sam_id.client.cred, &srv_cred))
+       if (!(p->dc.authenticated && deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->sam_id.client.cred, &srv_cred)))
                return NT_STATUS_INVALID_HANDLE;
-       else
-               memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred));
+
+       memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred));
     
        r_u->buffer_creds = 1; /* yes, we have valid server credentials */
        memcpy(&r_u->srv_creds, &srv_cred, sizeof(r_u->srv_creds));
 
-       /* store the user information, if there is any. */
-       r_u->user = usr_info;
-       r_u->switch_value = 0; /* indicates no info */
-       r_u->auth_resp = 1; /* authoritative response */
-       r_u->switch_value = 3; /* indicates type of validation user info */
-
        /* find the username */
     
        switch (q_u->sam_id.logon_level) {
@@ -557,7 +566,9 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
 
        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.
         */
@@ -567,44 +578,53 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
        switch (ctr->switch_value) {
        case NET_LOGON_TYPE:
        {
-               auth_authsupplied_info *auth_info = NULL;
-               make_auth_info_fixed(&auth_info, ctr->auth.id2.lm_chal);
-               /* Standard challange/response authenticaion */
-               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 = check_password(user_info, auth_info, &server_info);
-               free_auth_info(&auth_info);
+               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;
+               }
+
+               /* 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 challange/responce for the 
-                  auth subsystem to chew on */
+               /* '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 */
        {
-               auth_authsupplied_info *auth_info = NULL;
-               DATA_BLOB chal;
-               if (!make_auth_info_subsystem(&auth_info)) {
-                       return NT_STATUS_NO_MEMORY;
+               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_get_challange(auth_info);
-
-               make_user_info_netlogon_interactive(&user_info, 
-                                                   nt_username, nt_domain, 
-                                                   nt_workstation, chal.data,
-                                                   ctr->auth.id1.lm_owf.data, 
-                                                   ctr->auth.id1.nt_owf.data, 
-                                                   p->dc.sess_key);
-               status = check_password(user_info, auth_info, &server_info);
-               data_blob_free(&chal);
-               free_auth_info(&auth_info);
+               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);
+               }
+
+               (auth_context->free)(&auth_context);
 
                break;
        }
@@ -616,11 +636,11 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
        free_user_info(&user_info);
        
        DEBUG(5, ("_net_sam_logon: check_password returned status %s\n", 
-                 get_nt_error_msg(status)));
+                 nt_errstr(status)));
 
        /* Check account and password */
     
-       if (NT_STATUS_IS_ERR(status)) {
+       if (!NT_STATUS_IS_OK(status)) {
                free_server_info(&server_info);
                return status;
        }
@@ -638,20 +658,35 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
     
        {
                DOM_GID *gids = NULL;
+               const DOM_SID *user_sid = NULL;
+               const DOM_SID *group_sid = NULL;
+               DOM_SID domain_sid;
+               uint32 user_rid, group_rid; 
+
                int num_gids = 0;
                pstring my_name;
-               pstring my_workgroup;
-               pstring domain_groups;
-       
+               fstring user_sid_string;
+               fstring group_sid_string;
+               
+               sampw = server_info->sam_account;
+
                /* 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 change_to_user() call */
-               sam_logon_in_ssb = True;
-               pstrcpy(samlogon_user, nt_username);
 
-               pstrcpy(my_workgroup, lp_workgroup());
+               user_sid = pdb_get_user_sid(sampw);
+               group_sid = pdb_get_group_sid(sampw);
+
+               sid_copy(&domain_sid, user_sid);
+               sid_split_rid(&domain_sid, &user_rid);
+
+               if (!sid_peek_check_rid(&domain_sid, group_sid, &group_rid)) {
+                       DEBUG(1, ("_net_sam_logon: user %s\\%s has user sid %s\n but group sid %s.\nThe conflicting domain portions are not supported for NETLOGON calls\n",        
+                                 pdb_get_domain(sampw), pdb_get_username(sampw),
+                                 sid_to_string(user_sid_string, user_sid),
+                                 sid_to_string(group_sid_string, group_sid)));
+                       return NT_STATUS_UNSUCCESSFUL;
+               }
+               
                pstrcpy(my_name, global_myname);
                strupper(my_name);
 
@@ -663,29 +698,38 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
                 * JRA.
                 */
 
-               *domain_groups = 0;
-  
-               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, 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, /* 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 */
+               gids = NULL;
+               get_domain_user_groups(p->mem_ctx, &num_gids, &gids, server_info->sam_account);
+
+               init_net_user_info3(p->mem_ctx, usr_info, 
+                                   user_rid,
+                                   group_rid,
+                                   
+                                   pdb_get_username(sampw),
+                                   pdb_get_fullname(sampw),
+                                   pdb_get_homedir(sampw),
+                                   pdb_get_dirdrive(sampw),
+                                   pdb_get_logon_script(sampw),
+                                   pdb_get_profile_path(sampw),
+                                   pdb_get_logon_time(sampw),
+                                   pdb_get_logoff_time(sampw),
+                                   pdb_get_kickoff_time(sampw),
+                                   pdb_get_pass_last_set_time(sampw),
+                                   pdb_get_pass_can_change_time(sampw),
+                                   pdb_get_pass_must_change_time(sampw),
+                                   
+                                   0, /* logon_count */
+                                   0, /* bad_pw_count */
+                                   num_gids,    /* uint32 num_groups */
+                                   gids    , /* DOM_GID *gids */
+                                   0x20    , /* uint32 user_flgs (?) */
+                                   NULL, /* uchar sess_key[16] */
+                                   my_name     , /* char *logon_srv */
+                                   pdb_get_domain(sampw),
+                                   &domain_sid,     /* DOM_SID *dom_sid */  
+                                   /* Should be users domain sid, not servers - for trusted domains */
+                                 
+                                   NULL); /* char *other_sids */
        }
        free_server_info(&server_info);
        return status;