1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-12 09:18:10 +03:00

SAM database "set user info".

----------------------------

- removed DOM_RID4

- removed SAMR_UNKNOWN_32

- added SAMR_SET_USERINFO (opcode 0x32)

- added level 0x1 to SAMR_QUERY_DOM_INFO (needed for create user)

- fixed pwdb_gethexpwd() it was failing on XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

- added mod_sam21pwd_entry()

- preparing to call mod_sam21pwd_entry()

- added "user session key" to user_struct.dc.  this is md4(nt#) and is
  needed to decode user's clear-text passwords in SAMR_SET_USERINFO.

- split code out in chgpasswd.c to decode 516 byte password buffers.
This commit is contained in:
Luke Leighton 0001-01-01 00:00:00 +00:00
parent 68841eeb64
commit 2e58ed7424
18 changed files with 772 additions and 170 deletions

View File

@ -492,7 +492,7 @@ void pwdb_set_can_change_time(char *p, int max_len, time_t t);
void pwdb_set_must_change_time(char *p, int max_len, time_t t);
void pwdb_set_last_set_time(char *p, int max_len, time_t t);
void pwdb_sethexpwd(char *p, const char *pwd, uint16 acct_ctrl);
BOOL pwdb_gethexpwd(const char *p, char *pwd);
BOOL pwdb_gethexpwd(const char *p, char *pwd, uint32 *acct_ctrl);
BOOL pwdb_initialise(BOOL is_server);
/*The following definitions come from lib/util_sid.c */
@ -1507,6 +1507,7 @@ BOOL initialise_sam_password_db(void);
void *startsam21pwent(BOOL update);
void endsam21pwent(void *vp);
struct sam_passwd *getsam21pwent(void *vp);
BOOL mod_sam21pwd_entry(struct sam_passwd* pwd, BOOL override);
struct sam_passwd *iterate_getsam21pwntnam(const char *ntname);
struct sam_passwd *iterate_getsam21pwrid(uint32 rid);
struct sam_passwd *iterate_getsam21pwuid(uid_t uid);
@ -1973,7 +1974,6 @@ void make_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type, uint32 idx);
void smb_io_dom_rid2(char *desc, DOM_RID2 *rid2, prs_struct *ps, int depth);
void make_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type);
void smb_io_dom_rid3(char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth);
void make_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid);
void make_log_info(DOM_LOG_INFO *log,
const char *logon_srv, const char *acct_name,
uint16 sec_chan, const char *comp_name);
@ -2264,6 +2264,8 @@ void make_unk_info7(SAM_UNK_INFO_7 *u_7);
void sam_io_unk_info7(char *desc, SAM_UNK_INFO_7 *u_7, prs_struct *ps, int depth);
void make_unk_info2(SAM_UNK_INFO_2 *u_2, char *domain, char *server);
void sam_io_unk_info2(char *desc, SAM_UNK_INFO_2 *u_2, prs_struct *ps, int depth);
void make_unk_info1(SAM_UNK_INFO_1 *u_1);
void sam_io_unk_info1(char *desc, SAM_UNK_INFO_1 *u_1, prs_struct *ps, int depth);
void make_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO *r_u,
uint16 switch_value, SAM_UNK_CTR *ctr,
uint32 status);
@ -2456,6 +2458,10 @@ void make_samr_q_create_user(SAMR_Q_CREATE_USER *q_u,
const char *name,
uint16 acb_info, uint32 unk_1);
void samr_io_q_create_user(char *desc, SAMR_Q_CREATE_USER *q_u, prs_struct *ps, int depth);
void make_samr_r_create_user(SAMR_R_CREATE_USER *r_u,
POLICY_HND *user_pol,
uint32 unk_0, uint32 user_rid,
uint32 status);
void samr_io_r_create_user(char *desc, SAMR_R_CREATE_USER *r_u, prs_struct *ps, int depth);
void make_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
POLICY_HND *hnd, uint16 switch_value);
@ -2470,6 +2476,36 @@ void make_sam_user_info11(SAM_USER_INFO_11 *usr,
uint32 rid_group,
uint16 acct_ctrl);
void sam_io_user_info11(char *desc, SAM_USER_INFO_11 *usr, prs_struct *ps, int depth);
void make_sam_user_info23(SAM_USER_INFO_23 *usr,
NTTIME *logon_time, /* all zeros */
NTTIME *logoff_time, /* all zeros */
NTTIME *kickoff_time, /* all zeros */
NTTIME *pass_last_set_time, /* all zeros */
NTTIME *pass_can_change_time, /* all zeros */
NTTIME *pass_must_change_time, /* all zeros */
char *user_name, /* NULL */
char *full_name,
char *home_dir,
char *dir_drive,
char *logon_script,
char *profile_path,
char *description,
char *workstations,
char *unknown_str,
char *munged_dial,
uint32 user_rid, /* 0x0000 0000 */
uint32 group_rid,
uint16 acb_info,
uint32 unknown_3,
uint16 logon_divs,
LOGON_HRS *hrs,
uint32 unknown_5,
char newpass[516],
uint32 unknown_6);
void make_sam_user_info21(SAM_USER_INFO_21 *usr,
NTTIME *logon_time,
@ -2502,8 +2538,12 @@ void make_sam_user_info21(SAM_USER_INFO_21 *usr,
void make_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO *r_u,
uint16 switch_value, void *info, uint32 status);
void samr_io_r_query_userinfo(char *desc, SAMR_R_QUERY_USERINFO *r_u, prs_struct *ps, int depth);
void samr_io_q_unknown_32(char *desc, SAMR_Q_UNKNOWN_32 *q_u, prs_struct *ps, int depth);
void samr_io_r_unknown_32(char *desc, SAMR_R_UNKNOWN_32 *r_u, prs_struct *ps, int depth);
void make_samr_q_set_userinfo(SAMR_Q_SET_USERINFO *q_u,
POLICY_HND *hnd,
uint16 switch_value, void *info);
void samr_io_q_set_userinfo(char *desc, SAMR_Q_SET_USERINFO *q_u, prs_struct *ps, int depth);
void make_samr_r_set_userinfo(SAMR_R_SET_USERINFO *r_u, uint32 status);
void samr_io_r_set_userinfo(char *desc, SAMR_R_SET_USERINFO *r_u, prs_struct *ps, int depth);
void make_samr_q_connect(SAMR_Q_CONNECT *q_u,
char *srv_name, uint32 unknown_0);
void samr_io_q_connect(char *desc, SAMR_Q_CONNECT *q_u, prs_struct *ps, int depth);
@ -2932,6 +2972,8 @@ BOOL change_lanman_password(struct smb_passwd *smbpw, uchar *pass1, uchar *pass2
BOOL pass_oem_change(char *user,
uchar *lmdata, uchar *lmhash,
uchar *ntdata, uchar *nthash);
BOOL decode_pw_buffer(const char buffer[516], char *new_passwd,
int new_passwd_size, BOOL nt_pass_set);
BOOL check_oem_password(char *user,
uchar *lmdata, uchar *lmhash,
uchar *ntdata, uchar *nthash,
@ -3119,15 +3161,16 @@ BOOL set_challenge(unsigned char *challenge);
user_struct *get_valid_user_struct(uint16 vuid);
void invalidate_vuid(uint16 vuid);
char *validated_username(uint16 vuid);
uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, BOOL guest);
uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, BOOL guest, uchar user_sess_key[16]);
void add_session_user(char *user);
BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8);
BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8],
uchar lm_pass[24], uchar nt_pass[24]);
BOOL pass_check_smb(char *user, char *domain,
uchar *chal, uchar *lm_pwd, uchar *nt_pwd,
struct passwd *pwd);
BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd);
struct passwd *pwd, uchar user_sess_key[16]);
BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd,
uchar user_sess_key[16]);
BOOL user_ok(char *user,int snum);
BOOL authorise_login(int snum,char *user,char *password, int pwlen,
BOOL *guest,BOOL *force,uint16 vuid);

View File

@ -212,15 +212,6 @@ typedef struct domrid3_info
} DOM_RID3;
/* DOM_RID4 - rid + user attributes */
typedef struct domrid4_info
{
uint32 unknown;
uint16 attr;
uint32 rid; /* user RID */
} DOM_RID4;
/* DOM_CLNT_SRV - client / server names */
typedef struct clnt_srv_info
{

View File

@ -68,7 +68,7 @@ SamrRemoveMultipleMembersFromAlias
x SamrSetInformationAlias
SamrSetInformationDomain
x SamrSetInformationGroup
SamrSetInformationUser
x SamrSetInformationUser
SamrSetMemberAttributesOfGroup
SamrSetSecurityObject
SamrShutdownSamServer
@ -114,6 +114,7 @@ SamrTestPrivateFunctionsUser
#define SAMR_OPEN_USER 0x22
#define SAMR_CREATE_USER 0x32
#define SAMR_SET_USERINFO 0x3A
#define SAMR_QUERY_USERINFO 0x24
#define SAMR_QUERY_USERGROUPS 0x27
@ -122,7 +123,6 @@ SamrTestPrivateFunctionsUser
#define SAMR_UNKNOWN_2C 0x2c
#define SAMR_QUERY_DISPINFO3 0x30 /* Alias for SAMR_QUERY_DISPINFO
with info level 3 */
#define SAMR_UNKNOWN_32 0x32
#define SAMR_QUERY_DISPINFO4 0x33 /* Alias for SAMR_QUERY_DISPINFO
with info level 4 */
#define SAMR_UNKNOWN_34 0x34
@ -140,6 +140,67 @@ typedef struct logon_hours_info
} LOGON_HRS;
/* SAM_USER_INFO_23 */
typedef struct sam_user_info_23
{
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 */
uint16 acb_info; /* account info (ACB_xxxx bit-mask) */
/* uint8 pad[2] */
uint32 unknown_3; /* 0x09f8 27fa */
uint16 logon_divs; /* 0x0000 00a8 which is 168 which is num hrs in a week */
/* uint8 pad[2] */
uint32 ptr_logon_hrs; /* pointer to logon hours */
uint8 padding1[8];
uint32 unknown_5; /* 0x0001 0000 */
uint8 pass[516];
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 number */
uint32 unknown_6; /* 0x0000 04ec */
uint32 padding4;
LOGON_HRS logon_hrs;
} SAM_USER_INFO_23;
/* SAM_USER_INFO_21 */
typedef struct sam_user_info_21
{
@ -375,7 +436,7 @@ SAMR_Q_QUERY_DOMAIN_INFO - probably a query on domain group info.
typedef struct q_samr_query_domain_info
{
POLICY_HND domain_pol; /* policy handle */
uint16 switch_value; /* 0x0002 */
uint16 switch_value; /* 0x0002, 0x0001 */
} SAMR_Q_QUERY_DOMAIN_INFO;
@ -394,7 +455,7 @@ typedef struct sam_unknown_info_7_info
} SAM_UNK_INFO_7;
typedef struct sam_unknown_info_2_info
typedef struct sam_unknown_info_2_inf
{
uint32 unknown_0; /* 0x0000 0000 */
uint32 unknown_1; /* 0x8000 0000 */
@ -425,11 +486,21 @@ typedef struct sam_unknown_info_2_info
} SAM_UNK_INFO_2;
typedef struct sam_unknown_info_1_inf
{
uint8 padding[12]; /* 12 bytes zeros */
uint32 unknown_1; /* 0x8000 0000 */
uint32 unknown_2; /* 0x0000 0000 */
uint32 unknown_3; /* 0x0000 0000 */
} SAM_UNK_INFO_1;
typedef struct sam_unknown_ctr_info
{
union
{
SAM_UNK_INFO_1 inf1;
SAM_UNK_INFO_2 inf2;
SAM_UNK_INFO_6 inf6;
SAM_UNK_INFO_7 inf7;
@ -1035,6 +1106,30 @@ typedef struct r_samr_query_usergroup_info
} SAMR_R_QUERY_USERGROUPS;
/* SAMR_Q_SET_USERINFO - set sam info */
typedef struct q_samr_set_user_info
{
POLICY_HND pol; /* policy handle associated with user */
uint16 switch_value; /* 0x0017 */
uint16 switch_value2; /* 0x0017 */
union
{
SAM_USER_INFO_23 *id23; /* auth-level 0x17 */
void* id; /* to make typecasting easy */
} info;
} SAMR_Q_SET_USERINFO;
/* SAMR_R_SET_USERINFO - set sam info */
typedef struct r_samr_set_user_info
{
uint32 status; /* return status */
} SAMR_R_SET_USERINFO;
/* SAMR_Q_QUERY_USERINFO - probably a get sam info */
typedef struct q_samr_query_user_info
{
@ -1230,33 +1325,6 @@ typedef struct r_samr_create_user_info
/* SAMR_Q_UNKNOWN_32 - probably a "create SAM entry" */
typedef struct q_samr_unknown_32_info
{
POLICY_HND pol; /* policy handle */
UNIHDR hdr_mach_acct; /* unicode machine account name header */
UNISTR2 uni_mach_acct; /* unicode machine account name */
uint32 acct_ctrl; /* 32 bit ACB_XXXX */
uint16 unknown_1; /* 16 bit unknown - 0x00B0 */
uint16 unknown_2; /* 16 bit unknown - 0xe005 */
} SAMR_Q_UNKNOWN_32;
/* SAMR_R_UNKNOWN_32 - probably a "create SAM entry" */
typedef struct r_samr_unknown_32_info
{
POLICY_HND pol; /* policy handle */
/* rid4.unknown - fail: 0030 success: 0x03ff */
DOM_RID4 rid4; /* rid and attributes */
uint32 status; /* return status - fail: 0xC000 0099: user exists */
} SAMR_R_UNKNOWN_32;
/* SAMR_Q_QUERY_GROUPMEM - query group members */
typedef struct q_samr_query_groupmem_info
{

View File

@ -613,6 +613,7 @@ typedef struct connection_struct
char *connectpath;
char *origpath;
char *user; /* name of user who *opened* this connection */
uid_t uid; /* uid of user who *opened* this connection */
gid_t gid; /* gid of user who *opened* this connection */
@ -709,6 +710,7 @@ struct dcinfo
uchar sess_key[8]; /* Session key */
uchar md4pw[16]; /* md4(machine password) */
uchar user_sess_key[16]; /* user session key (md4 nt#) */
};
typedef struct

View File

@ -415,9 +415,26 @@ void pwdb_sethexpwd(char *p, const char *pwd, uint16 acct_ctrl)
Routine to get the 32 hex characters and turn them
into a 16 byte array.
**************************************************************/
BOOL pwdb_gethexpwd(const char *p, char *pwd)
BOOL pwdb_gethexpwd(const char *p, char *pwd, uint32 *acct_ctrl)
{
return strhex_to_str(pwd, 32, p) == 16;
if (strnequal(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 32))
{
if (acct_ctrl != NULL)
{
*acct_ctrl |= ACB_PWNOTREQ;
}
pwd[0] = 0;
return True;
}
else if (strnequal(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 32))
{
pwd[0] = 0;
return True;
}
else
{
return strhex_to_str(pwd, 32, p) == 16;
}
}

View File

@ -187,7 +187,7 @@ struct smb_passwd *ldap_getpw(void)
smbpw.acct_ctrl = ACB_NORMAL;
if(ldap_get_attribute("lmPassword", temp)) {
pwdb_gethexpwd(temp, smblmpwd);
pwdb_gethexpwd(temp, smblmpwd, NULL);
smbpw.smb_passwd = smblmpwd;
} else {
smbpw.smb_passwd = NULL;
@ -195,7 +195,7 @@ struct smb_passwd *ldap_getpw(void)
}
if(ldap_get_attribute("ntPassword", temp)) {
pwdb_gethexpwd(temp, smbntpwd);
pwdb_gethexpwd(temp, smbntpwd, NULL);
smbpw.smb_nt_passwd = smbntpwd;
} else {
smbpw.smb_nt_passwd = NULL;

View File

@ -123,6 +123,20 @@ struct sam_passwd *getsam21pwent(void *vp)
return pwdb_sam_map_names(pwdb_ops->getsam21pwent(vp));
}
/************************************************************************
Routine to search the smb passwd file for an entry matching the username.
and then modify its password entry. We can't use the startsampwent()/
getsampwent()/endsampwent() interfaces here as we depend on looking
in the actual file to decide how much room we have to write data.
override = False, normal
override = True, override XXXXXXXX'd out password or NO PASS
************************************************************************/
BOOL mod_sam21pwd_entry(struct sam_passwd* pwd, BOOL override)
{
return pwdb_ops->mod_sam21pwd_entry(pwdb_sam_map_names(pwd), override);
}
/************************************************************************
Utility function to search sam passwd by name. use this if your database
does not have search facilities.

View File

@ -158,7 +158,7 @@ struct smb_passwd *getsmbfilepwent(void *vp)
}
else
{
if (!pwdb_gethexpwd(p, (char *)smbpwd))
if (!pwdb_gethexpwd(p, (char *)smbpwd, NULL))
{
DEBUG(0, ("getsmbfilepwent: Malformed Lanman password entry (non hex chars)\n"));
continue;
@ -178,7 +178,7 @@ struct smb_passwd *getsmbfilepwent(void *vp)
{
if (*p != '*' && *p != 'X')
{
if(pwdb_gethexpwd(p,(char *)smbntpwd))
if(pwdb_gethexpwd(p,(char *)smbntpwd, NULL))
{
pw_buf.smb_nt_passwd = smbntpwd;
}

View File

@ -167,7 +167,7 @@ BOOL get_trust_account_password( unsigned char *ret_pwd, time_t *pass_last_set_t
* Get the hex password.
*/
if (!pwdb_gethexpwd((char *)linebuf, (char *)ret_pwd) || linebuf[32] != ':' ||
if (!pwdb_gethexpwd((char *)linebuf, (char *)ret_pwd, NULL) || linebuf[32] != ':' ||
strncmp(&linebuf[33], "TLC-", 4)) {
DEBUG(0,("get_trust_account_password: Malformed trust password file (incorrect format).\n"));
#ifdef DEBUG_PASSWORD

View File

@ -702,16 +702,6 @@ void smb_io_dom_rid3(char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth)
prs_uint32("unk ", ps, depth, &(rid3->unk ));
}
/*******************************************************************
creates a DOM_RID4 structure.
********************************************************************/
void make_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid)
{
rid4->unknown = unknown;
rid4->attr = attr;
rid4->rid = rid;
}
/*******************************************************************
makes a DOM_CLNT_SRV structure.
********************************************************************/

View File

@ -449,6 +449,38 @@ void sam_io_unk_info2(char *desc, SAM_UNK_INFO_2 *u_2, prs_struct *ps, int depth
}
/*******************************************************************
makes a structure.
********************************************************************/
void make_unk_info1(SAM_UNK_INFO_1 *u_1)
{
if (u_1 == NULL) return;
memset(u_1->padding, 0, sizeof(u_1->padding)); /* 12 bytes zeros */
u_1->unknown_1 = 0x80000000;
u_1->unknown_2 = 0x00000000;
u_1->unknown_3 = 0x00000000;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
void sam_io_unk_info1(char *desc, SAM_UNK_INFO_1 *u_1, prs_struct *ps, int depth)
{
if (u_1 == NULL) return;
prs_debug(ps, depth, desc, "sam_io_unk_info1");
depth++;
prs_uint8s(False, "padding", ps, depth, u_1->padding, sizeof(u_1->padding)); /* 12 bytes zeros */
prs_uint32("unknown_1", ps, depth, &u_1->unknown_1); /* 0x8000 0000 */
prs_uint32("unknown_2", ps, depth, &u_1->unknown_2); /* 0x0000 0000 */
prs_uint32("unknown_3", ps, depth, &u_1->unknown_3); /* 0x0000 0000 */
prs_align(ps);
}
/*******************************************************************
makes a SAMR_R_QUERY_DOMAIN_INFO structure.
********************************************************************/
@ -507,6 +539,11 @@ void samr_io_r_query_dom_info(char *desc, SAMR_R_QUERY_DOMAIN_INFO *r_u, prs_str
sam_io_unk_info2("unk_inf2", &r_u->ctr->info.inf2, ps, depth);
break;
}
case 0x01:
{
sam_io_unk_info1("unk_inf1", &r_u->ctr->info.inf1, ps, depth);
break;
}
default:
{
DEBUG(3,("samr_io_r_query_dom_info: unknown switch level 0x%x\n",
@ -3847,6 +3884,25 @@ void samr_io_q_create_user(char *desc, SAMR_Q_CREATE_USER *q_u, prs_struct *ps,
prs_align(ps);
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
void make_samr_r_create_user(SAMR_R_CREATE_USER *r_u,
POLICY_HND *user_pol,
uint32 unk_0, uint32 user_rid,
uint32 status)
{
if (r_u == NULL) return;
DEBUG(5,("samr_make_samr_r_create_user\n"));
memcpy(&r_u->user_pol, user_pol, sizeof(r_u->user_pol));
r_u->unknown_0 = unk_0;
r_u->user_rid = user_rid;
r_u->status = status;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
@ -4049,6 +4105,186 @@ void sam_io_user_info11(char *desc, SAM_USER_INFO_11 *usr, prs_struct *ps, int
prs_uint8s (False, "padding_9", ps, depth, usr->padding_9, sizeof(usr->padding_9));
}
/*************************************************************************
make_sam_user_info23
unknown_3 = 0x09f8 27fa
unknown_5 = 0x0001 0000
unknown_6 = 0x0000 04ec
*************************************************************************/
void make_sam_user_info23(SAM_USER_INFO_23 *usr,
NTTIME *logon_time, /* all zeros */
NTTIME *logoff_time, /* all zeros */
NTTIME *kickoff_time, /* all zeros */
NTTIME *pass_last_set_time, /* all zeros */
NTTIME *pass_can_change_time, /* all zeros */
NTTIME *pass_must_change_time, /* all zeros */
char *user_name, /* NULL */
char *full_name,
char *home_dir,
char *dir_drive,
char *logon_script,
char *profile_path,
char *description,
char *workstations,
char *unknown_str,
char *munged_dial,
uint32 user_rid, /* 0x0000 0000 */
uint32 group_rid,
uint16 acb_info,
uint32 unknown_3,
uint16 logon_divs,
LOGON_HRS *hrs,
uint32 unknown_5,
char newpass[516],
uint32 unknown_6)
{
int len_user_name = user_name != NULL ? strlen(user_name ) : 0;
int len_full_name = full_name != NULL ? strlen(full_name ) : 0;
int len_home_dir = home_dir != NULL ? strlen(home_dir ) : 0;
int len_dir_drive = dir_drive != NULL ? strlen(dir_drive ) : 0;
int len_logon_script = logon_script != NULL ? strlen(logon_script) : 0;
int len_profile_path = profile_path != NULL ? strlen(profile_path) : 0;
int len_description = description != NULL ? strlen(description ) : 0;
int len_workstations = workstations != NULL ? strlen(workstations) : 0;
int len_unknown_str = unknown_str != NULL ? strlen(unknown_str ) : 0;
int len_munged_dial = munged_dial != NULL ? strlen(munged_dial ) : 0;
usr->logon_time = *logon_time; /* all zeros */
usr->logoff_time = *logoff_time; /* all zeros */
usr->kickoff_time = *kickoff_time; /* all zeros */
usr->pass_last_set_time = *pass_last_set_time; /* all zeros */
usr->pass_can_change_time = *pass_can_change_time; /* all zeros */
usr->pass_must_change_time = *pass_must_change_time; /* all zeros */
make_uni_hdr(&(usr->hdr_user_name ), len_user_name ); /* NULL */
make_uni_hdr(&(usr->hdr_full_name ), len_full_name );
make_uni_hdr(&(usr->hdr_home_dir ), len_home_dir );
make_uni_hdr(&(usr->hdr_dir_drive ), len_dir_drive );
make_uni_hdr(&(usr->hdr_logon_script), len_logon_script);
make_uni_hdr(&(usr->hdr_profile_path), len_profile_path);
make_uni_hdr(&(usr->hdr_acct_desc ), len_description );
make_uni_hdr(&(usr->hdr_workstations), len_workstations);
make_uni_hdr(&(usr->hdr_unknown_str ), len_unknown_str );
make_uni_hdr(&(usr->hdr_munged_dial ), len_munged_dial );
bzero(usr->nt_pwd, sizeof(usr->nt_pwd));
bzero(usr->lm_pwd, sizeof(usr->lm_pwd));
usr->user_rid = user_rid; /* 0x0000 0000 */
usr->group_rid = group_rid;
usr->acb_info = acb_info;
usr->unknown_3 = unknown_3; /* 09f8 27fa */
usr->logon_divs = logon_divs; /* should be 168 (hours/week) */
usr->ptr_logon_hrs = hrs ? 1 : 0;
bzero(usr->padding1, sizeof(usr->padding1));
usr->unknown_5 = unknown_5; /* 0x0001 0000 */
memcpy(usr->pass, newpass, sizeof(usr->pass));
make_unistr2(&(usr->uni_user_name ), user_name , len_user_name ); /* NULL */
make_unistr2(&(usr->uni_full_name ), full_name , len_full_name );
make_unistr2(&(usr->uni_home_dir ), home_dir , len_home_dir );
make_unistr2(&(usr->uni_dir_drive ), dir_drive , len_dir_drive );
make_unistr2(&(usr->uni_logon_script), logon_script, len_logon_script);
make_unistr2(&(usr->uni_profile_path), profile_path, len_profile_path);
make_unistr2(&(usr->uni_acct_desc ), description , len_description );
make_unistr2(&(usr->uni_workstations), workstations, len_workstations);
make_unistr2(&(usr->uni_unknown_str ), unknown_str , len_unknown_str );
make_unistr2(&(usr->uni_munged_dial ), munged_dial , len_munged_dial );
usr->unknown_6 = unknown_6; /* 0x0000 04ec */
usr->padding4 = 0;
if (hrs)
{
memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
}
else
{
memset(&(usr->logon_hrs), 0xff, sizeof(usr->logon_hrs));
}
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
static void sam_io_user_info23(char *desc, SAM_USER_INFO_23 *usr, prs_struct *ps, int depth)
{
if (usr == NULL) return;
prs_debug(ps, depth, desc, "lsa_io_user_info");
depth++;
prs_align(ps);
smb_io_time("logon_time ", &(usr->logon_time) , ps, depth);
smb_io_time("logoff_time ", &(usr->logoff_time) , ps, depth);
smb_io_time("kickoff_time ", &(usr->kickoff_time) , ps, depth);
smb_io_time("pass_last_set_time ", &(usr->pass_last_set_time) , ps, depth);
smb_io_time("pass_can_change_time ", &(usr->pass_can_change_time) , ps, depth);
smb_io_time("pass_must_change_time", &(usr->pass_must_change_time), ps, depth);
smb_io_unihdr("hdr_user_name ", &(usr->hdr_user_name) , ps, depth); /* username unicode string header */
smb_io_unihdr("hdr_full_name ", &(usr->hdr_full_name) , ps, depth); /* user's full name unicode string header */
smb_io_unihdr("hdr_home_dir ", &(usr->hdr_home_dir) , ps, depth); /* home directory unicode string header */
smb_io_unihdr("hdr_dir_drive ", &(usr->hdr_dir_drive) , ps, depth); /* home directory drive */
smb_io_unihdr("hdr_logon_script", &(usr->hdr_logon_script), ps, depth); /* logon script unicode string header */
smb_io_unihdr("hdr_profile_path", &(usr->hdr_profile_path), ps, depth); /* profile path unicode string header */
smb_io_unihdr("hdr_acct_desc ", &(usr->hdr_acct_desc ) , ps, depth); /* account description */
smb_io_unihdr("hdr_workstations", &(usr->hdr_workstations), ps, depth); /* workstations user can log on from */
smb_io_unihdr("hdr_unknown_str ", &(usr->hdr_unknown_str ), ps, depth); /* unknown string */
smb_io_unihdr("hdr_munged_dial ", &(usr->hdr_munged_dial ), ps, depth); /* workstations user can log on from */
prs_uint8s (False, "lm_pwd ", ps, depth, usr->lm_pwd , sizeof(usr->lm_pwd ));
prs_uint8s (False, "nt_pwd ", ps, depth, usr->nt_pwd , sizeof(usr->nt_pwd ));
prs_uint32("user_rid ", ps, depth, &(usr->user_rid )); /* User ID */
prs_uint32("group_rid ", ps, depth, &(usr->group_rid )); /* Group ID */
prs_uint16("acb_info ", ps, depth, &(usr->acb_info )); /* Group ID */
prs_align(ps);
prs_uint32("unknown_3 ", ps, depth, &(usr->unknown_3 ));
prs_uint16("logon_divs ", ps, depth, &(usr->logon_divs )); /* logon divisions per week */
prs_align(ps);
prs_uint32("ptr_logon_hrs ", ps, depth, &(usr->ptr_logon_hrs));
prs_uint8s (False, "padding1 ", ps, depth, usr->padding1, sizeof(usr->padding1));
prs_uint32("unknown_5 ", ps, depth, &(usr->unknown_5 ));
prs_uint8s (False, "password ", ps, depth, usr->pass, sizeof(usr->pass));
/* here begins pointed-to data */
smb_io_unistr2("uni_user_name ", &(usr->uni_user_name) , usr->hdr_user_name .buffer, ps, depth); /* username unicode string */
smb_io_unistr2("uni_full_name ", &(usr->uni_full_name) , usr->hdr_full_name .buffer, ps, depth); /* user's full name unicode string */
smb_io_unistr2("uni_home_dir ", &(usr->uni_home_dir) , usr->hdr_home_dir .buffer, ps, depth); /* home directory unicode string */
smb_io_unistr2("uni_dir_drive ", &(usr->uni_dir_drive) , usr->hdr_dir_drive .buffer, ps, depth); /* home directory drive unicode string */
smb_io_unistr2("uni_logon_script", &(usr->uni_logon_script), usr->hdr_logon_script.buffer, ps, depth); /* logon script unicode string */
smb_io_unistr2("uni_profile_path", &(usr->uni_profile_path), usr->hdr_profile_path.buffer, ps, depth); /* profile path unicode string */
smb_io_unistr2("uni_acct_desc ", &(usr->uni_acct_desc ), usr->hdr_acct_desc .buffer, ps, depth); /* user description unicode string */
smb_io_unistr2("uni_workstations", &(usr->uni_workstations), usr->hdr_workstations.buffer, ps, depth); /* worksations user can log on from */
smb_io_unistr2("uni_unknown_str ", &(usr->uni_unknown_str ), usr->hdr_unknown_str .buffer, ps, depth); /* unknown string */
smb_io_unistr2("uni_munged_dial ", &(usr->uni_munged_dial ), usr->hdr_munged_dial .buffer, ps, depth); /* worksations user can log on from */
prs_uint32("unknown_6 ", ps, depth, &(usr->unknown_6 ));
prs_uint32("padding4 ", ps, depth, &(usr->padding4 ));
if (usr->ptr_logon_hrs)
{
sam_io_logon_hrs("logon_hrs", &(usr->logon_hrs) , ps, depth);
prs_align(ps);
}
}
/*************************************************************************
make_sam_user_info21
@ -4353,14 +4589,47 @@ void samr_io_r_query_userinfo(char *desc, SAMR_R_QUERY_USERINFO *r_u, prs_struc
prs_uint32("status", ps, depth, &(r_u->status));
}
/*******************************************************************
makes a SAMR_Q_SET_USERINFO structure.
********************************************************************/
void make_samr_q_set_userinfo(SAMR_Q_SET_USERINFO *q_u,
POLICY_HND *hnd,
uint16 switch_value, void *info)
{
if (q_u == NULL || hnd == NULL) return;
DEBUG(5,("make_samr_q_set_userinfo\n"));
memcpy(&(q_u->pol), hnd, sizeof(q_u->pol));
q_u->switch_value = switch_value;
q_u->switch_value2 = switch_value;
switch (switch_value)
{
case 0x17:
{
q_u->info.id23 = (SAM_USER_INFO_23*)info;
break;
}
default:
{
DEBUG(4,("make_samr_q_set_userinfo: unsupported switch level\n"));
break;
}
}
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
void samr_io_q_unknown_32(char *desc, SAMR_Q_UNKNOWN_32 *q_u, prs_struct *ps, int depth)
void samr_io_q_set_userinfo(char *desc, SAMR_Q_SET_USERINFO *q_u, prs_struct *ps, int depth)
{
if (q_u == NULL) return;
prs_debug(ps, depth, desc, "samr_io_q_unknown_32");
prs_debug(ps, depth, desc, "samr_io_q_set_userinfo");
depth++;
prs_align(ps);
@ -4368,35 +4637,66 @@ void samr_io_q_unknown_32(char *desc, SAMR_Q_UNKNOWN_32 *q_u, prs_struct *ps, i
smb_io_pol_hnd("pol", &(q_u->pol), ps, depth);
prs_align(ps);
smb_io_unihdr ("", &(q_u->hdr_mach_acct), ps, depth);
smb_io_unistr2("", &(q_u->uni_mach_acct), q_u->hdr_mach_acct.buffer, ps, depth);
prs_uint16("switch_value ", ps, depth, &(q_u->switch_value ));
prs_uint16("switch_value2", ps, depth, &(q_u->switch_value2));
prs_align(ps);
prs_uint32("acct_ctrl", ps, depth, &(q_u->acct_ctrl));
prs_uint16("unknown_1", ps, depth, &(q_u->unknown_1));
prs_uint16("unknown_2", ps, depth, &(q_u->unknown_2));
switch (q_u->switch_value)
{
case 0:
{
break;
}
case 23:
{
q_u->info.id = Realloc(NULL, sizeof(*q_u->info.id23));
if (q_u->info.id == NULL)
{
DEBUG(2,("samr_io_q_query_userinfo: info pointer not initialised\n"));
return;
}
sam_io_user_info23("", q_u->info.id23, ps, depth);
break;
}
default:
{
DEBUG(2,("samr_io_q_query_userinfo: unknown switch level\n"));
break;
}
}
prs_align(ps);
}
/*******************************************************************
makes a SAMR_R_SET_USERINFO structure.
********************************************************************/
void make_samr_r_set_userinfo(SAMR_R_SET_USERINFO *r_u, uint32 status)
{
if (r_u == NULL) return;
DEBUG(5,("make_samr_r_set_userinfo\n"));
r_u->status = status; /* return status */
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
void samr_io_r_unknown_32(char *desc, SAMR_R_UNKNOWN_32 *r_u, prs_struct *ps, int depth)
void samr_io_r_set_userinfo(char *desc, SAMR_R_SET_USERINFO *r_u, prs_struct *ps, int depth)
{
if (r_u == NULL) return;
prs_debug(ps, depth, desc, "samr_io_r_unknown_32");
prs_debug(ps, depth, desc, "samr_io_r_set_userinfo");
depth++;
prs_align(ps);
smb_io_pol_hnd("pol", &(r_u->pol), ps, depth);
prs_align(ps);
prs_uint32("status", ps, depth, &(r_u->status));
}
/*******************************************************************
makes a SAMR_Q_CONNECT structure.
********************************************************************/

View File

@ -211,8 +211,16 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p)
uchar nt_owf[24];
struct smb_passwd *smb_pass = NULL;
user_struct *vuser = get_valid_user_struct(p->vuid);
DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n"));
if (vuser == NULL)
{
DEBUG(0,("get user struct %d failed\n", p->vuid));
return False;
}
if (p->ntlmssp_resp.hdr_lm_resp.str_str_len == 0) return False;
if (p->ntlmssp_resp.hdr_nt_resp.str_str_len == 0) return False;
if (p->ntlmssp_resp.hdr_usr .str_str_len == 0) return False;
@ -256,7 +264,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p)
become_root(True);
p->ntlmssp_validated = pass_check_smb(p->user_name, p->domain,
(uchar*)p->ntlmssp_chal.challenge,
lm_owf, nt_owf, NULL);
lm_owf, nt_owf, NULL, vuser->dc.user_sess_key);
smb_pass = getsmbpwnam(p->user_name);
unbecome_root(True);

View File

@ -140,7 +140,7 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
p->ntlmssp_auth = False;
fstrcpy(p->name, pipe_name);
DEBUG(4,("Opened pipe %s with handle %x (pipes_open=%d)\n",
pipe_name, i, pipes_open));

View File

@ -1943,6 +1943,27 @@ static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
}
/*******************************************************************
set_user_info_23
********************************************************************/
static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
{
static struct sam_passwd *pwd;
fstring new_pw;
if (!decode_pw_buffer(id23->pass, new_pw, sizeof(new_pw), True))
{
return False;
}
#ifdef DEBUG_PASSWORD
DEBUG(0,("New Password: %s\n", new_pw));
#endif
#if 0
return mod_sam21pwd_entry(&pwd, True);
#else
return True;
#endif
}
/*******************************************************************
api_samr_query_userinfo
********************************************************************/
@ -1954,6 +1975,87 @@ static void api_samr_query_userinfo( uint16 vuid, prs_struct *data, prs_struct *
}
/*******************************************************************
samr_reply_set_userinfo
********************************************************************/
static void samr_reply_set_userinfo(SAMR_Q_SET_USERINFO *q_u,
prs_struct *rdata, uchar user_sess_key[16])
{
SAMR_R_SET_USERINFO r_u;
uint32 status = 0x0;
uint32 rid = 0x0;
DEBUG(5,("samr_reply_set_userinfo: %d\n", __LINE__));
/* search for the handle */
if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
{
status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
}
/* find the user's rid */
if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
{
status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
}
DEBUG(5,("samr_reply_set_userinfo: rid:0x%x\n", rid));
/* ok! user info levels (there are lots: see MSDEV help), off we go... */
if (status == 0x0)
{
switch (q_u->switch_value)
{
case 23:
{
SAM_USER_INFO_23 *id23 = q_u->info.id23;
SamOEMhash(id23->pass, user_sess_key, True);
status = set_user_info_23(id23, rid) ? 0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
break;
}
default:
{
status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
break;
}
}
}
make_samr_r_set_userinfo(&r_u, status);
/* store the response in the SMB stream */
samr_io_r_set_userinfo("", &r_u, rdata, 0);
DEBUG(5,("samr_reply_set_userinfo: %d\n", __LINE__));
}
/*******************************************************************
api_samr_set_userinfo
********************************************************************/
static void api_samr_set_userinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
user_struct *vuser = get_valid_user_struct(vuid);
SAMR_Q_SET_USERINFO q_u;
ZERO_STRUCT(q_u);
#ifdef DEBUG_PASSWORD
DEBUG(100,("set user info: sess_key: "));
dump_data(100, vuser->dc.user_sess_key, 16);
#endif
samr_io_q_set_userinfo("", &q_u, data, 0);
samr_reply_set_userinfo(&q_u, rdata, vuser->dc.user_sess_key);
if (q_u.info.id != NULL)
{
free(q_u.info.id);
}
}
/*******************************************************************
samr_reply_query_usergroups
********************************************************************/
@ -2310,6 +2412,13 @@ static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
break;
}
case 0x01:
{
switch_value = 0x1;
make_unk_info1(&ctr.info.inf1);
break;
}
default:
{
status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
@ -2340,50 +2449,19 @@ static void api_samr_query_dom_info( uint16 vuid, prs_struct *data, prs_struct *
/*******************************************************************
samr_reply_unknown_32
samr_reply_create_user
********************************************************************/
static void samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
prs_struct *rdata,
int status)
static void samr_reply_create_user(SAMR_Q_CREATE_USER *q_u,
prs_struct *rdata)
{
int i;
SAMR_R_UNKNOWN_32 r_u;
/* set up the SAMR unknown_32 response */
bzero(r_u.pol.data, POL_HND_SIZE);
if (status == 0)
{
for (i = 4; i < POL_HND_SIZE; i++)
{
r_u.pol.data[i] = i+1;
}
}
make_dom_rid4(&(r_u.rid4), 0x0030, 0, 0);
r_u.status = status;
DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
/* store the response in the SMB stream */
samr_io_r_unknown_32("", &r_u, rdata, 0);
DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
}
/*******************************************************************
api_samr_unknown_32
********************************************************************/
static void api_samr_unknown_32( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
uint32 status = 0;
struct sam_passwd *sam_pass;
fstring mach_acct;
fstring user_name;
SAMR_Q_UNKNOWN_32 q_u;
/* grab the samr unknown 32 */
samr_io_q_unknown_32("", &q_u, data, 0);
SAMR_R_CREATE_USER r_u;
POLICY_HND pol;
uint32 status = 0x0;
uint32 user_rid = 0xffffffff;
BOOL pol_open = False;
/* find the machine account: tell the caller if it exists.
lkclXXXX i have *no* idea if this is a problem or not
@ -2391,26 +2469,91 @@ static void api_samr_unknown_32( uint16 vuid, prs_struct *data, prs_struct *rdat
reply if the account already exists...
*/
unistr2_to_ascii(mach_acct, &q_u.uni_mach_acct, sizeof(mach_acct)-1);
/* find the policy handle. open a policy on it. */
if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
{
status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
}
become_root(True);
sam_pass = getsam21pwntnam(mach_acct);
unbecome_root(True);
/* get a (unique) handle. open a policy on it. */
if (status == 0x0 && !(pol_open = open_lsa_policy_hnd(&pol)))
{
status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
unistr2_to_ascii(user_name, &q_u->uni_name, sizeof(user_name)-1);
sam_pass = getsam21pwntnam(user_name);
if (sam_pass != NULL)
{
/* machine account exists: say so */
/* account exists: say so */
status = 0xC0000000 | NT_STATUS_USER_EXISTS;
}
else
{
/* this could cause trouble... */
DEBUG(0,("trouble!\n"));
status = 0;
pstring err_str;
pstring msg_str;
if (!local_password_change(user_name, True,
q_u->acb_info | ACB_DISABLED, 0xffff,
NULL,
err_str, sizeof(err_str),
msg_str, sizeof(msg_str)))
{
DEBUG(0,("%s\n", err_str));
status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
}
else
{
sam_pass = getsam21pwntnam(user_name);
if (sam_pass == NULL)
{
/* account doesn't exist: say so */
status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
}
else
{
user_rid = sam_pass->user_rid;
}
}
}
/* associate the RID with the (unique) handle. */
if (status == 0x0 && !set_lsa_policy_samr_rid(&pol, user_rid))
{
/* oh, whoops. don't know what error message to return, here */
status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
if (status != 0 && pol_open)
{
close_lsa_policy_hnd(&pol);
}
DEBUG(5,("samr_create_user: %d\n", __LINE__));
make_samr_r_create_user(&r_u, &pol, 0x000703ff, user_rid, status);
/* store the response in the SMB stream */
samr_io_r_create_user("", &r_u, rdata, 0);
DEBUG(5,("samr_create_user: %d\n", __LINE__));
}
/*******************************************************************
api_samr_create_user
********************************************************************/
static void api_samr_create_user( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_CREATE_USER q_u;
/* grab the samr unknown 32 */
samr_io_q_create_user("", &q_u, data, 0);
/* construct reply. */
samr_reply_unknown_32(&q_u, rdata, status);
samr_reply_create_user(&q_u, rdata);
}
@ -2709,6 +2852,7 @@ static struct api_struct api_samr_cmds [] =
{ "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
{ "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
{ "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
{ "SAMR_SET_USERINFO" , SAMR_SET_USERINFO , api_samr_set_userinfo },
{ "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
{ "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
{ "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
@ -2716,7 +2860,7 @@ static struct api_struct api_samr_cmds [] =
{ "SAMR_QUERY_DISPINFO4" , SAMR_QUERY_DISPINFO4 , api_samr_query_dispinfo },
{ "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
{ "SAMR_QUERY_GROUPINFO" , SAMR_QUERY_GROUPINFO , api_samr_query_groupinfo },
{ "SAMR_0x32" , SAMR_UNKNOWN_32 , api_samr_unknown_32 },
{ "SAMR_CREATE_USER" , SAMR_CREATE_USER , api_samr_create_user },
{ "SAMR_LOOKUP_RIDS" , SAMR_LOOKUP_RIDS , api_samr_lookup_rids },
{ "SAMR_UNKNOWN_38" , SAMR_UNKNOWN_38 , api_samr_unknown_38 },
{ "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },

View File

@ -603,6 +603,42 @@ BOOL pass_oem_change(char *user,
return ret;
}
/***********************************************************
decode a password buffer
************************************************************/
BOOL decode_pw_buffer(const char buffer[516], char *new_passwd,
int new_passwd_size, BOOL nt_pass_set)
{
/*
* The length of the new password is in the last 4 bytes of
* the data buffer.
*/
uint32 new_pw_len = IVAL(buffer, 512);
if (new_pw_len < 0 || new_pw_len > new_passwd_size - 1)
{
DEBUG(0,("check_oem_password: incorrect password length (%d).\n", new_pw_len));
return False;
}
if (nt_pass_set)
{
/*
* nt passwords are in unicode
*/
int uni_pw_len = new_pw_len;
new_pw_len /= 2;
unibuf_to_ascii(new_passwd, &buffer[512-uni_pw_len], new_pw_len);
}
else
{
memcpy(new_passwd, &buffer[512-new_pw_len], new_pw_len);
new_passwd[new_pw_len] = '\0';
}
return True;
}
/***********************************************************
Code to check the OEM hashed password.
@ -619,7 +655,6 @@ BOOL check_oem_password(char *user,
static uchar null_pw[16];
static uchar null_ntpw[16];
struct smb_passwd *smbpw = NULL;
int new_pw_len;
uchar new_ntp16[16];
uchar unenc_old_ntpw[16];
uchar new_p16[16];
@ -681,33 +716,11 @@ BOOL check_oem_password(char *user,
*/
SamOEMhash( (uchar *)lmdata, (uchar *)smbpw->smb_passwd, True);
/*
* The length of the new password is in the last 4 bytes of
* the data buffer.
*/
new_pw_len = IVAL(lmdata, 512);
if (new_pw_len < 0 || new_pw_len > new_passwd_size - 1)
if (!decode_pw_buffer(lmdata, new_passwd, new_passwd_size, nt_pass_set))
{
DEBUG(0,("check_oem_password: incorrect password length (%d).\n", new_pw_len));
return False;
}
if (nt_pass_set)
{
/*
* nt passwords are in unicode
*/
int uni_pw_len = new_pw_len;
new_pw_len /= 2;
unibuf_to_ascii(new_passwd, &lmdata[512-uni_pw_len], new_pw_len);
}
else
{
memcpy(new_passwd, &lmdata[512-new_pw_len], new_pw_len);
new_passwd[new_pw_len] = '\0';
}
/*
* To ensure we got the correct new password, hash it and
* use it as a key to test the passed old password.

View File

@ -1680,7 +1680,7 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param
* Older versions of Windows seem to do this.
*/
if (password_ok(user, pass1,strlen(pass1),NULL) &&
if (password_ok(user, pass1,strlen(pass1),NULL, NULL) &&
chgpasswd(user,pass1,pass2,False))
{
SSVAL(*rparam,0,NERR_Success);

View File

@ -156,7 +156,7 @@ register a uid/name pair as being valid and that a valid password
has been given. vuid is biased by an offset. This allows us to
tell random client vuid's (normally zero) from valid vuids.
****************************************************************************/
uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, BOOL guest)
uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, BOOL guest, uchar user_sess_key[16])
{
user_struct *vuser;
struct passwd *pwfile; /* for getting real name from passwd file */
@ -205,6 +205,7 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
vuser->guest = guest;
fstrcpy(vuser->name,unix_name);
fstrcpy(vuser->requested_name,requested_name);
memcpy(vuser->dc.user_sess_key, user_sess_key, sizeof(vuser->dc.user_sess_key));
vuser->n_sids = 0;
vuser->sids = NULL;
@ -412,7 +413,7 @@ return True if the password is correct, False otherwise
BOOL pass_check_smb(char *user, char *domain,
uchar *chal, uchar *lm_pwd, uchar *nt_pwd,
struct passwd *pwd)
struct passwd *pwd, uchar user_sess_key[16])
{
struct passwd *pass;
struct smb_passwd *smb_pass;
@ -467,6 +468,14 @@ BOOL pass_check_smb(char *user, char *domain,
if (smb_password_ok(smb_pass, chal, lm_pwd, nt_pwd))
{
if (user_sess_key != NULL)
{
mdfour(user_sess_key, smb_pass->smb_nt_passwd, 16);
#ifdef DEBUG_PASSWORD
DEBUG(100,("user session key: "));
dump_data(100, user_sess_key, 16);
#endif
}
return(True);
}
@ -479,7 +488,8 @@ check if a username/password pair is OK either via the system password
database or the encrypted SMB password database
return True if the password is correct, False otherwise
****************************************************************************/
BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd)
BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd,
uchar user_sess_key[16])
{
if (pwlen == 24 || (lp_encrypted_passwords() && (pwlen == 0) && lp_null_passwords()))
{
@ -493,7 +503,7 @@ BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd)
}
return pass_check_smb(user, global_myworkgroup,
challenge, (uchar *)password, (uchar *)password, pwd);
challenge, (uchar *)password, (uchar *)password, pwd, user_sess_key);
}
return pass_check(user, password, pwlen, pwd,
@ -536,7 +546,8 @@ BOOL user_ok(char *user,int snum)
/****************************************************************************
validate a group username entry. Return the username or NULL
****************************************************************************/
static char *validate_group(char *group,char *password,int pwlen,int snum)
static char *validate_group(char *group,char *password,int pwlen,int snum,
uchar user_sess_key[16])
{
#if defined(HAVE_NETGROUP) && defined(HAVE_GETNETGRENT) && defined(HAVE_SETNETGRENT) && defined(HAVE_ENDNETGRENT)
{
@ -545,7 +556,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum)
while (getnetgrent(&host, &user, &domain)) {
if (user) {
if (user_ok(user, snum) &&
password_ok(user,password,pwlen,NULL)) {
password_ok(user,password,pwlen,NULL, user_sess_key)) {
endnetgrent();
return(user);
}
@ -567,7 +578,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum)
static fstring name;
fstrcpy(name,*member);
if (user_ok(name,snum) &&
password_ok(name,password,pwlen,NULL))
password_ok(name,password,pwlen,NULL, user_sess_key))
return(&name[0]);
member++;
}
@ -580,7 +591,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum)
while (pwd = getpwent ()) {
if (*(pwd->pw_passwd) && pwd->pw_gid == gptr->gr_gid) {
/* This Entry have PASSWORD and same GID then check pwd */
if (password_ok(NULL, password, pwlen, pwd)) {
if (password_ok(NULL, password, pwlen, pwd, user_sess_key)) {
fstrcpy(tm, pwd->pw_name);
endpwent ();
return tm;
@ -633,14 +644,14 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen,
/* check the given username and password */
if (!ok && (*user) && user_ok(user,snum)) {
ok = password_ok(user,password, pwlen, NULL);
ok = password_ok(user,password, pwlen, NULL, vuser->dc.user_sess_key);
if (ok) DEBUG(3,("ACCEPTED: given username password ok\n"));
}
/* check for a previously registered guest username */
if (!ok && (vuser != 0) && vuser->guest) {
if (user_ok(vuser->name,snum) &&
password_ok(vuser->name, password, pwlen, NULL)) {
password_ok(vuser->name, password, pwlen, NULL, vuser->dc.user_sess_key)) {
fstrcpy(user, vuser->name);
vuser->guest = False;
DEBUG(3,("ACCEPTED: given password with registered user %s\n", user));
@ -664,7 +675,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen,
fstrcpy(user2,auser);
if (!user_ok(user2,snum)) continue;
if (password_ok(user2,password, pwlen, NULL)) {
if (password_ok(user2,password, pwlen, NULL, vuser->dc.user_sess_key)) {
ok = True;
fstrcpy(user,user2);
DEBUG(3,("ACCEPTED: session list username and given password ok\n"));
@ -703,7 +714,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen,
{
if (*auser == '@')
{
auser = validate_group(auser+1,password,pwlen,snum);
auser = validate_group(auser+1,password,pwlen,snum, vuser->dc.user_sess_key);
if (auser)
{
ok = True;
@ -716,7 +727,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen,
fstring user2;
fstrcpy(user2,auser);
if (user_ok(user2,snum) &&
password_ok(user2,password,pwlen,NULL))
password_ok(user2,password,pwlen,NULL, vuser->dc.user_sess_key))
{
ok = True;
fstrcpy(user,user2);

View File

@ -511,6 +511,7 @@ reply to a session setup command
int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
{
uint16 sess_vuid;
uchar user_sess_key[16];
int gid;
int uid;
int smb_bufsize;
@ -706,13 +707,13 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
if(smb_ntpasslen)
{
if(!password_ok(user, smb_ntpasswd,smb_ntpasslen,NULL))
if(!password_ok(user, smb_ntpasswd,smb_ntpasslen,NULL,user_sess_key))
DEBUG(0,("NT Password did not match ! Defaulting to Lanman\n"));
else
valid_nt_password = True;
}
if (!valid_nt_password && !password_ok(user, smb_apasswd,smb_apasslen,NULL))
if (!valid_nt_password && !password_ok(user, smb_apasswd,smb_apasslen,NULL,user_sess_key))
{
if (lp_security() >= SEC_USER)
{
@ -791,7 +792,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
/* register the name and uid as being validated, so further connections
to a uid can get through without a password, on the same VC */
sess_vuid = register_vuid(uid,gid,user,sesssetup_user,guest);
sess_vuid = register_vuid(uid,gid,user,sesssetup_user,guest,user_sess_key);
SSVAL(outbuf,smb_uid,sess_vuid);
SSVAL(inbuf,smb_uid,sess_vuid);