r13396: Add in userinfo26, re-enable userinfo25 - took the knowledge
authorJeremy Allison <jra@samba.org>
Wed, 8 Feb 2006 22:16:03 +0000 (22:16 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:09:59 +0000 (11:09 -0500)
from Samba4 on how to decode the 532 byte password buffers.
Getting closer to passing samba4 RPC-SCHANNEL test.
Jeremy.
(This used to be commit 205db6968a26c43dec64c14d8053d8e66807086f)

source3/include/rpc_samr.h
source3/libsmb/smbencrypt.c
source3/rpc_parse/parse_samr.c
source3/rpc_server/srv_samr_nt.c

index e53bc1ede815db386b23f43c71c087dffad6899c..e0b179224d82425ffc8f38f0b27f3837ae9fc521 100644 (file)
@@ -277,6 +277,13 @@ typedef struct sam_user_info_25
        UNISTR2 uni_munged_dial ; /* munged path name and dial-back tel no */
 } SAM_USER_INFO_25;
 
+/* SAM_USER_INFO_26 */
+typedef struct sam_user_info_26
+{
+       uint8 pass[532];
+       uint8 pw_len;
+} SAM_USER_INFO_26;
+
 
 /* SAM_USER_INFO_21 */
 typedef struct sam_user_info_21
@@ -1272,6 +1279,7 @@ typedef struct sam_userinfo_ctr_info
                SAM_USER_INFO_23 *id23;
                SAM_USER_INFO_24 *id24;
                SAM_USER_INFO_25 *id25;
+               SAM_USER_INFO_26 *id26;
                void* id; /* to make typecasting easy */
 
        } info;
index 99f99f23f8c7627e9e3ee149d5f0eada84f7c988..5bdd0acd3ea6edd2fbf4fe934baacf55fd734a8f 100644 (file)
@@ -530,6 +530,25 @@ BOOL decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd,
        return True;
 }
 
+/***********************************************************
+ Decode an arc4 encrypted password change buffer.
+************************************************************/
+
+void encode_or_decode_arc4_passwd_buffer(char pw_buf[532], const DATA_BLOB *psession_key)
+{
+       struct MD5Context tctx;
+       unsigned char key_out[16];
+
+       /* Confounder is last 16 bytes. */
+
+       MD5Init(&tctx);
+       MD5Update(&tctx, &pw_buf[516], 16);
+       MD5Update(&tctx, psession_key->data, psession_key->length);
+       MD5Final(key_out, &tctx);
+       /* arc4 with key_out. */
+       SamOEMhash(pw_buf, key_out, 516);
+}
+
 /***********************************************************
  Encrypt/Decrypt used for LSA secrets and trusted domain
  passwords.
index d13d3c9d4a80c9d6ec27aff45c228f0143a3f282..a0108d9eb7b75f024487bc23662118d52a4655b3 100644 (file)
@@ -5404,13 +5404,41 @@ static BOOL sam_io_user_info24(const char *desc, SAM_USER_INFO_24 * usr,
        if (MARSHALLING(ps) && (usr->pw_len != 0)) {
                if (!prs_uint16("pw_len", ps, depth, &usr->pw_len))
                        return False;
+       } else if (UNMARSHALLING(ps)) {
+               if (!prs_uint16("pw_len", ps, depth, &usr->pw_len))
+                       return False;
        }
+
+       return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+static BOOL sam_io_user_info26(const char *desc, SAM_USER_INFO_26 * usr,
+                              prs_struct *ps, int depth)
+{
+       if (usr == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "sam_io_user_info26");
+       depth++;
+
        if(!prs_align(ps))
                return False;
 
+       if(!prs_uint8s(False, "password", ps, depth, usr->pass, 
+                      sizeof(usr->pass)))
+               return False;
+       
+       if (!prs_uint8("pw_len", ps, depth, &usr->pw_len))
+               return False;
+
        return True;
 }
 
+
 /*************************************************************************
  init_sam_user_info23
 
@@ -6475,6 +6503,16 @@ static BOOL samr_io_userinfo_ctr(const char *desc, SAM_USERINFO_CTR **ppctr,
                }
                ret = sam_io_user_info25("", ctr->info.id25, ps, depth);
                break;
+       case 26:
+               if (UNMARSHALLING(ps))
+                       ctr->info.id26 = PRS_ALLOC_MEM(ps,SAM_USER_INFO_26,1);
+
+               if (ctr->info.id26 == NULL) {
+                       DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
+                       return False;
+               }
+               ret = sam_io_user_info26("", ctr->info.id26, ps,  depth);
+               break;
        default:
                DEBUG(2, ("samr_io_userinfo_ctr: unknown switch level 0x%x\n", ctr->switch_value));
                ret = False;
index 81344cdc1eca9db84a667889ef46973b76ddeec7..52f922b9242bd3db8ba083d4b159f82e5a5a99cf 100644 (file)
@@ -3316,27 +3316,27 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
                        break;
 
                case 25:
-#if 0
-                       /*
-                        * Currently we don't really know how to unmarshall
-                        * the level 25 struct, and the password encryption
-                        * is different. This is a placeholder for when we
-                        * do understand it. In the meantime just return INVALID
-                        * info level and W2K SP2 drops down to level 23... JRA.
-                        */
-
                        if (!p->session_key.length) {
                                r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
                        }
-                       SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
+                       encode_or_decode_arc4_passwd_buffer(ctr->info.id25->pass, &p->session_key);
 
                        dump_data(100, (char *)ctr->info.id25->pass, 532);
 
-                       if (!set_user_info_pw(ctr->info.id25->pass, &sid))
+                       if (!set_user_info_pw(ctr->info.id25->pass, pwd))
                                r_u->status = NT_STATUS_ACCESS_DENIED;
                        break;
-#endif
-                       r_u->status = NT_STATUS_INVALID_INFO_CLASS;
+
+               case 26:
+                       if (!p->session_key.length) {
+                               r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
+                       }
+                       encode_or_decode_arc4_passwd_buffer(ctr->info.id26->pass, &p->session_key);
+
+                       dump_data(100, (char *)ctr->info.id26->pass, 516);
+
+                       if (!set_user_info_pw(ctr->info.id26->pass, pwd))
+                               r_u->status = NT_STATUS_ACCESS_DENIED;
                        break;
 
                case 23:
@@ -3432,7 +3432,7 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
                        has_enough_rights = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
        }
        
-       DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
+       DEBUG(5, ("_samr_set_userinfo2: %s does%s possess sufficient rights\n",
                p->pipe_user_name, has_enough_rights ? "" : " not"));
 
        /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
@@ -3464,6 +3464,28 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
                        if (!set_user_info_21(ctr->info.id21, pwd))
                                return NT_STATUS_ACCESS_DENIED;
                        break;
+               case 23:
+                       if (!p->session_key.length) {
+                               r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
+                       }
+                       SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
+
+                       dump_data(100, (char *)ctr->info.id23->pass, 516);
+
+                       if (!set_user_info_23(ctr->info.id23, pwd))
+                               r_u->status = NT_STATUS_ACCESS_DENIED;
+                       break;
+               case 26:
+                       if (!p->session_key.length) {
+                               r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
+                       }
+                       encode_or_decode_arc4_passwd_buffer(ctr->info.id26->pass, &p->session_key);
+
+                       dump_data(100, (char *)ctr->info.id26->pass, 516);
+
+                       if (!set_user_info_pw(ctr->info.id26->pass, pwd))
+                               r_u->status = NT_STATUS_ACCESS_DENIED;
+                       break;
                default:
                        r_u->status = NT_STATUS_INVALID_INFO_CLASS;
        }