uint8 pass[516];
} SAM_USER_INFO_24;
+/*
+ * NB. This structure is *definately* incorrect. It's my best guess
+ * currently for W2K SP2. The password field is encrypted in a different
+ * way than normal... And there are definately other problems. JRA.
+ */
+
+/* SAM_USER_INFO_25 */
+typedef struct sam_user_info_25
+{
+ /* TIMES MAY NOT IN RIGHT ORDER!!!! */
+ NTTIME logon_time; /* logon time */
+ NTTIME logoff_time; /* logoff time */
+ NTTIME kickoff_time; /* kickoff time */
+ NTTIME pass_last_set_time; /* password last set time */
+ NTTIME pass_can_change_time; /* password can change time */
+ NTTIME pass_must_change_time; /* password must change time */
+
+ UNIHDR hdr_user_name; /* NULL - user name unicode string header */
+ UNIHDR hdr_full_name; /* user's full name unicode string header */
+ UNIHDR hdr_home_dir; /* home directory unicode string header */
+ UNIHDR hdr_dir_drive; /* home drive unicode string header */
+ UNIHDR hdr_logon_script; /* logon script unicode string header */
+ UNIHDR hdr_profile_path; /* profile path unicode string header */
+ UNIHDR hdr_acct_desc ; /* user description */
+ UNIHDR hdr_workstations; /* comma-separated workstations user can log in from */
+ UNIHDR hdr_unknown_str ; /* don't know what this is, yet. */
+ UNIHDR hdr_munged_dial ; /* munged path name and dial-back tel number */
+
+ uint8 lm_pwd[16]; /* lm user passwords */
+ uint8 nt_pwd[16]; /* nt user passwords */
+
+ uint32 user_rid; /* Primary User ID */
+ uint32 group_rid; /* Primary Group ID */
+
+ uint32 acb_info; /* account info (ACB_xxxx bit-mask) */
+
+ uint32 unknown_6[6];
+
+ uint8 pass[532];
+
+ UNISTR2 uni_user_name; /* NULL - username unicode string */
+ UNISTR2 uni_full_name; /* user's full name unicode string */
+ UNISTR2 uni_home_dir; /* home directory unicode string */
+ UNISTR2 uni_dir_drive; /* home directory drive unicode string */
+ UNISTR2 uni_logon_script; /* logon script unicode string */
+ UNISTR2 uni_profile_path; /* profile path unicode string */
+ UNISTR2 uni_acct_desc ; /* user description unicode string */
+ UNISTR2 uni_workstations; /* login from workstations unicode string */
+ UNISTR2 uni_unknown_str ; /* don't know what this is, yet. */
+ UNISTR2 uni_munged_dial ; /* munged path name and dial-back tel no */
+} SAM_USER_INFO_25;
+
/* SAM_USER_INFO_21 */
typedef struct sam_user_info_21
SAM_USER_INFO_21 *id21; /* auth-level 21 */
SAM_USER_INFO_23 *id23; /* auth-level 0x17 */
SAM_USER_INFO_24 *id24; /* auth-level 0x18 */
+ SAM_USER_INFO_25 *id25; /* auth-level 0x19 */
void* id; /* to make typecasting easy */
} info;
return True;
}
+/*******************************************************************
+ reads or writes a structure.
+ NB. This structure is *definately* incorrect. It's my best guess
+ currently for W2K SP2. The password field is encrypted in a different
+ way than normal... And there are definately other problems. JRA.
+********************************************************************/
+
+static BOOL sam_io_user_info25(char *desc, SAM_USER_INFO_25 * usr, prs_struct *ps, int depth)
+{
+ if (usr == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "sam_io_user_info23");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_time("logon_time ", &usr->logon_time, ps, depth))
+ return False;
+ if(!smb_io_time("logoff_time ", &usr->logoff_time, ps, depth))
+ return False;
+ if(!smb_io_time("kickoff_time ", &usr->kickoff_time, ps, depth))
+ return False;
+ if(!smb_io_time("pass_last_set_time ", &usr->pass_last_set_time, ps, depth))
+ return False;
+ if(!smb_io_time("pass_can_change_time ", &usr->pass_can_change_time, ps, depth))
+ return False;
+ if(!smb_io_time("pass_must_change_time", &usr->pass_must_change_time, ps, depth))
+ return False;
+
+ if(!smb_io_unihdr("hdr_user_name ", &usr->hdr_user_name, ps, depth)) /* username unicode string header */
+ return False;
+ if(!smb_io_unihdr("hdr_full_name ", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */
+ return False;
+ if(!smb_io_unihdr("hdr_home_dir ", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */
+ return False;
+ if(!smb_io_unihdr("hdr_dir_drive ", &usr->hdr_dir_drive, ps, depth)) /* home directory drive */
+ return False;
+ if(!smb_io_unihdr("hdr_logon_script", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */
+ return False;
+ if(!smb_io_unihdr("hdr_profile_path", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */
+ return False;
+ if(!smb_io_unihdr("hdr_acct_desc ", &usr->hdr_acct_desc, ps, depth)) /* account desc */
+ return False;
+ if(!smb_io_unihdr("hdr_workstations", &usr->hdr_workstations, ps, depth)) /* wkstas user can log on from */
+ return False;
+ if(!smb_io_unihdr("hdr_unknown_str ", &usr->hdr_unknown_str, ps, depth)) /* unknown string */
+ return False;
+ if(!smb_io_unihdr("hdr_munged_dial ", &usr->hdr_munged_dial, ps, depth)) /* wkstas user can log on from */
+ return False;
+
+ if(!prs_uint8s(False, "lm_pwd ", ps, depth, usr->lm_pwd, sizeof(usr->lm_pwd)))
+ return False;
+ if(!prs_uint8s(False, "nt_pwd ", ps, depth, usr->nt_pwd, sizeof(usr->nt_pwd)))
+ return False;
+
+ if(!prs_uint32("user_rid ", ps, depth, &usr->user_rid)) /* User ID */
+ return False;
+ if(!prs_uint32("group_rid ", ps, depth, &usr->group_rid)) /* Group ID */
+ return False;
+ if(!prs_uint32("acb_info ", ps, depth, &usr->acb_info))
+ return False;
+
+ if(!prs_uint32s(False, "unknown_6 ", ps, depth, usr->unknown_6, 6))
+ return False;
+
+ if(!prs_uint8s(False, "password ", ps, depth, usr->pass, sizeof(usr->pass)))
+ return False;
+
+ /* here begins pointed-to data */
+
+ if(!smb_io_unistr2("uni_user_name ", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
+ return False;
+
+ if(!smb_io_unistr2("uni_full_name ", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
+ return False;
+
+ if(!smb_io_unistr2("uni_home_dir ", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */
+ return False;
+
+ if(!smb_io_unistr2("uni_dir_drive ", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */
+ return False;
+
+ if(!smb_io_unistr2("uni_logon_script", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */
+ return False;
+
+ if(!smb_io_unistr2("uni_profile_path", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */
+ return False;
+
+ if(!smb_io_unistr2("uni_acct_desc ", &usr->uni_acct_desc, usr->hdr_acct_desc.buffer, ps, depth)) /* user desc unicode string */
+ return False;
+
+ if(!smb_io_unistr2("uni_workstations", &usr->uni_workstations, usr->hdr_workstations.buffer, ps, depth)) /* worksations user can log on from */
+ return False;
+
+ if(!smb_io_unistr2("uni_unknown_str ", &usr->uni_unknown_str, usr->hdr_unknown_str.buffer, ps, depth)) /* unknown string */
+ return False;
+
+ if(!smb_io_unistr2("uni_munged_dial ", &usr->uni_munged_dial, usr->hdr_munged_dial.buffer, ps, depth))
+ return False;
+
+#if 0 /* JRA - unknown... */
+ /* ok, this is only guess-work (as usual) */
+ if (usr->ptr_logon_hrs) {
+ if(!prs_uint32("unknown_6 ", ps, depth, &usr->unknown_6))
+ return False;
+ if(!prs_uint32("padding4 ", ps, depth, &usr->padding4))
+ return False;
+ if(!sam_io_logon_hrs("logon_hrs", &usr->logon_hrs, ps, depth))
+ return False;
+ } else if (UNMARSHALLING(ps)) {
+ usr->unknown_6 = 0;
+ usr->padding4 = 0;
+ }
+#endif
+
+ return True;
+}
+
/*************************************************************************
init_sam_user_info21W
switch (switch_value) {
case 0x18:
- SamOEMhash(ctr->info.id24->pass, sess_key, 1);
+ SamOEMhash(ctr->info.id24->pass, sess_key, 516);
dump_data(100, (char *)sess_key, 16);
dump_data(100, (char *)ctr->info.id24->pass, 516);
break;
case 0x17:
- SamOEMhash(ctr->info.id23->pass, sess_key, 1);
+ SamOEMhash(ctr->info.id23->pass, sess_key, 516);
dump_data(100, (char *)sess_key, 16);
dump_data(100, (char *)ctr->info.id23->pass, 516);
break;
}
ret = sam_io_user_info24("", ctr->info.id24, ps, depth);
break;
+ case 25:
+ if (UNMARSHALLING(ps))
+ ctr->info.id25 = (SAM_USER_INFO_25 *)prs_alloc_mem(ps,sizeof(SAM_USER_INFO_25));
+
+ if (ctr->info.id25 == NULL) {
+ DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
+ return False;
+ }
+ ret = sam_io_user_info25("", ctr->info.id25, ps, depth);
+ break;
default:
DEBUG(2, ("samr_io_userinfo_ctr: unknown switch level 0x%x\n", ctr->switch_value));
ret = False;
switch (switch_value) {
case 0x12:
- SamOEMhash(ctr->info.id12->lm_pwd, sess_key, 0);
- SamOEMhash(ctr->info.id12->nt_pwd, sess_key, 0);
+ SamOEMhash(ctr->info.id12->lm_pwd, sess_key, 16);
+ SamOEMhash(ctr->info.id12->nt_pwd, sess_key, 16);
dump_data(100, (char *)sess_key, 16);
dump_data(100, (char *)ctr->info.id12->lm_pwd, 16);
dump_data(100, (char *)ctr->info.id12->nt_pwd, 16);
}
/*******************************************************************
- set_user_info_24
+ set_user_info_pw
********************************************************************/
-static BOOL set_user_info_24(SAM_USER_INFO_24 *id24, uint32 rid)
+static BOOL set_user_info_pw(char *pass, uint32 rid)
{
SAM_ACCOUNT *pwd = NULL;
uchar nt_hash[16];
memset(buf, 0, sizeof(buf));
- if (!decode_pw_buffer((char*)id24->pass, buf, 256, &len, nt_hash, lm_hash)) {
+ if (!decode_pw_buffer(pass, buf, 256, &len, nt_hash, lm_hash)) {
pdb_free_sam(pwd);
return False;
}
memset(buf, 0, sizeof(buf));
- DEBUG(0,("set_user_info_24: pdb_update_sam_account()\n"));
+ DEBUG(5,("set_user_info_pw: pdb_update_sam_account()\n"));
/* update the SAMBA password */
if(!pdb_update_sam_account(pwd, True)) {
break;
case 24:
- SamOEMhash(ctr->info.id24->pass, sess_key, 1);
- if (!set_user_info_24(ctr->info.id24, rid))
+ SamOEMhash(ctr->info.id24->pass, sess_key, 516);
+
+ dump_data(100, (char *)ctr->info.id24->pass, 516);
+
+ if (!set_user_info_pw(ctr->info.id24->pass, rid))
return NT_STATUS_ACCESS_DENIED;
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.
+ */
+
+ SamOEMhash(ctr->info.id25->pass, sess_key, 532);
+
+ dump_data(100, (char *)ctr->info.id25->pass, 532);
+
+ if (!set_user_info_pw(ctr->info.id25->pass, rid))
+ return NT_STATUS_ACCESS_DENIED;
+ break;
+#endif
+ return NT_STATUS_INVALID_INFO_CLASS;
+
case 23:
- SamOEMhash(ctr->info.id23->pass, sess_key, 1);
+ SamOEMhash(ctr->info.id23->pass, sess_key, 516);
+
+ dump_data(100, (char *)ctr->info.id23->pass, 516);
+
if (!set_user_info_23(ctr->info.id23, rid))
return NT_STATUS_ACCESS_DENIED;
break;