summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h31
-rw-r--r--source3/include/rpc_samr_old.h236
-rw-r--r--source3/libsmb/smbencrypt.c44
-rw-r--r--source3/passdb/passdb.c209
-rw-r--r--source3/rpc_client/cli_samr.c12
-rw-r--r--source3/rpc_parse/parse_samr.c706
-rw-r--r--source3/rpc_server/srv_lsa_hnd.c31
-rw-r--r--source3/rpc_server/srv_pipe.c2
-rw-r--r--source3/rpc_server/srv_samr.c687
9 files changed, 1697 insertions, 261 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index c1c1cd8e35..27fcb6a921 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -867,6 +867,8 @@ void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]);
void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]);
void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24);
BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode);
+BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd,
+ int new_pwrd_size, uint32 *new_pw_len);
/*The following definitions come from libsmb/smberr.c */
@@ -1627,11 +1629,16 @@ struct sam_disp_info *getsamdisprid(uint32 rid);
struct sam_passwd *getsam21pwent(void *vp);
struct sam_passwd *getsam21pwnam(char *name);
struct sam_passwd *getsam21pwrid(uint32 rid);
+BOOL add_sam21pwd_entry(struct sam_passwd *pwd);
+BOOL mod_sam21pwd_entry(struct sam_passwd *pwd, BOOL override);
void pdb_init_smb(struct smb_passwd *user);
void pdb_init_sam(struct sam_passwd *user);
struct sam_disp_info *pdb_sam_to_dispinfo(struct sam_passwd *user);
struct smb_passwd *pdb_sam_to_smb(struct sam_passwd *user);
struct sam_passwd *pdb_smb_to_sam(struct smb_passwd *user);
+void copy_id23_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_23 *from);
+void copy_id21_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_21 *from);
+void copy_sam_passwd(struct sam_passwd *to, const struct sam_passwd *from);
char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length);
uint16 pdb_decode_acct_ctrl(const char *p);
time_t pdb_get_last_set_time(const char *p);
@@ -2539,8 +2546,13 @@ BOOL samr_io_q_unknown_3(char *desc, SAMR_Q_UNKNOWN_3 *q_u, prs_struct *ps, int
void init_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
POLICY_HND *domain_pol, uint16 switch_value);
BOOL samr_io_q_query_dom_info(char *desc, SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct *ps, int depth);
+BOOL init_unk_info1(SAM_UNK_INFO_1 *u_1);
void init_unk_info2(SAM_UNK_INFO_2 *u_2, char *domain, char *server);
BOOL sam_io_unk_info2(char *desc, SAM_UNK_INFO_2 *u_2, prs_struct *ps, int depth);
+BOOL init_unk_info3(SAM_UNK_INFO_3 * u_3);
+BOOL init_unk_info6(SAM_UNK_INFO_6 * u_6);
+BOOL init_unk_info7(SAM_UNK_INFO_7 *u_7);
+BOOL init_unk_info12(SAM_UNK_INFO_12 * u_12);
void init_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO *r_u,
uint16 switch_value, SAM_UNK_CTR *ctr,
uint32 status);
@@ -2601,11 +2613,11 @@ BOOL samr_io_q_lookup_names(char *desc, SAMR_Q_LOOKUP_NAMES *q_u, prs_struct *p
void init_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_u,
uint32 num_rids, uint32 *rid, enum SID_NAME_USE *type, uint32 status);
BOOL samr_io_r_lookup_names(char *desc, SAMR_R_LOOKUP_NAMES *r_u, prs_struct *ps, int depth);
-BOOL samr_io_q_unknown_12(char *desc, SAMR_Q_UNKNOWN_12 *q_u, prs_struct *ps, int depth);
-void init_samr_r_unknown_12(SAMR_R_UNKNOWN_12 *r_u,
+BOOL samr_io_q_lookup_rids(char *desc, SAMR_Q_LOOKUP_RIDS *q_u, prs_struct *ps, int depth);
+void init_samr_r_lookup_rids(SAMR_R_LOOKUP_RIDS *r_u,
uint32 num_aliases, fstring *als_name, uint32 *num_als_usrs,
uint32 status);
-BOOL samr_io_r_unknown_12(char *desc, SAMR_R_UNKNOWN_12 *r_u, prs_struct *ps, int depth);
+BOOL samr_io_r_lookup_rids(char *desc, SAMR_R_LOOKUP_RIDS *r_u, prs_struct *ps, int depth);
void init_samr_q_open_user(SAMR_Q_OPEN_USER *q_u,
POLICY_HND *pol,
uint32 unk_0, uint32 rid);
@@ -2672,9 +2684,9 @@ BOOL samr_io_q_connect_anon(char *desc, SAMR_Q_CONNECT_ANON *q_u, prs_struct *p
BOOL samr_io_r_connect_anon(char *desc, SAMR_R_CONNECT_ANON *r_u, prs_struct *ps, int depth);
void init_samr_q_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
uint32 unknown_0, uint32 rid);
-BOOL samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, int depth);
+BOOL samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, int depth);
BOOL samr_io_r_open_alias(char *desc, SAMR_R_OPEN_ALIAS *r_u, prs_struct *ps, int depth);
-void init_samr_q_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
+void init_samr_q_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u,
POLICY_HND *pol, uint32 rid,
uint32 num_gids, uint32 *gid);
void init_samr_q_unknown_21(SAMR_Q_UNKNOWN_21 *q_c,
@@ -2707,6 +2719,14 @@ BOOL init_samr_r_enum_domains(SAMR_R_ENUM_DOMAINS * r_u,
uint32 next_idx, fstring* domains, uint32 num_sam_entries);
BOOL samr_io_r_enum_domains(char *desc, SAMR_R_ENUM_DOMAINS * r_u,
prs_struct *ps, int depth);
+void free_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr);
+BOOL samr_io_q_set_userinfo(char *desc, SAMR_Q_SET_USERINFO *q_u, prs_struct *ps, int depth);
+void free_samr_q_set_userinfo(SAMR_Q_SET_USERINFO * q_u);
+BOOL samr_io_r_set_userinfo(char *desc, SAMR_R_SET_USERINFO *r_u, prs_struct *ps, int depth);
+BOOL samr_io_q_set_userinfo2(char *desc, SAMR_Q_SET_USERINFO2 *q_u, prs_struct *ps, int depth);
+void free_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u);
+BOOL make_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 *r_u, uint32 status);
+BOOL samr_io_r_set_userinfo2(char *desc, SAMR_R_SET_USERINFO2 *r_u, prs_struct *ps, int depth);
#endif
/*The following definitions come from rpc_parse/parse_sec.c */
@@ -3074,7 +3094,6 @@ BOOL api_ntlsa_rpc(pipes_struct *p);
void init_lsa_policy_hnd(void);
BOOL open_lsa_policy_hnd(POLICY_HND *hnd);
int find_lsa_policy_by_hnd(POLICY_HND *hnd);
-BOOL set_lsa_policy_samr_rid(POLICY_HND *hnd, uint32 rid);
BOOL set_lsa_policy_samr_pol_status(POLICY_HND *hnd, uint32 pol_status);
BOOL set_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid);
BOOL get_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid);
diff --git a/source3/include/rpc_samr_old.h b/source3/include/rpc_samr_old.h
index 620f5bc628..656a9de434 100644
--- a/source3/include/rpc_samr_old.h
+++ b/source3/include/rpc_samr_old.h
@@ -77,32 +77,34 @@ SamrTestPrivateFunctionsUser
********************************************************************/
+#define SAMR_CONNECT_ANON 0x00
#define SAMR_CLOSE_HND 0x01
+#define SAMR_UNKNOWN_3 0x03
#define SAMR_LOOKUP_DOMAIN 0x05
#define SAMR_ENUM_DOMAINS 0x06
#define SAMR_OPEN_DOMAIN 0x07
#define SAMR_QUERY_DOMAIN_INFO 0x08
+#define SAMR_ENUM_DOM_USERS 0x0d
+#define SAMR_ENUM_DOM_ALIASES 0x0f
#define SAMR_LOOKUP_IDS 0x10
#define SAMR_LOOKUP_NAMES 0x11
-#define SAMR_UNKNOWN_3 0x03
-#define SAMR_QUERY_DISPINFO 0x28
+#define SAMR_LOOKUP_RIDS 0x12
+#define SAMR_OPEN_ALIAS 0x1b
+#define SAMR_QUERY_ALIASINFO 0x1c
+#define SAMR_UNKNOWN_21 0x21
#define SAMR_OPEN_USER 0x22
#define SAMR_QUERY_USERINFO 0x24
+#define SAMR_SET_USERINFO2 0x25
#define SAMR_QUERY_USERGROUPS 0x27
-#define SAMR_UNKNOWN_12 0x12
-#define SAMR_UNKNOWN_21 0x21
+#define SAMR_QUERY_DISPINFO 0x28
#define SAMR_UNKNOWN_2C 0x2c
+#define SAMR_ENUM_DOM_GROUPS 0x30
#define SAMR_CREATE_USER 0x32
#define SAMR_UNKNOWN_34 0x34
#define SAMR_CHGPASSWD_USER 0x37
#define SAMR_UNKNOWN_38 0x38
#define SAMR_CONNECT 0x39
-#define SAMR_CONNECT_ANON 0x00
-#define SAMR_OPEN_ALIAS 0x1b
-#define SAMR_QUERY_ALIASINFO 0x1c
-#define SAMR_ENUM_DOM_USERS 0x0d
-#define SAMR_ENUM_DOM_ALIASES 0x0f
-#define SAMR_ENUM_DOM_GROUPS 0x30
+#define SAMR_SET_USERINFO 0x3A
typedef struct logon_hours_info
@@ -139,7 +141,7 @@ typedef struct sam_user_info_21
uint32 user_rid; /* Primary User ID */
uint32 group_rid; /* Primary Group ID */
- uint16 acb_info; /* account info (ACB_xxxx bit-mask) */
+ uint32 acb_info; /* account info (ACB_xxxx bit-mask) */
/* uint8 pad[2] */
uint32 unknown_3; /* 0x00ff ffff */
@@ -351,6 +353,14 @@ typedef struct q_samr_query_domain_info
} SAMR_Q_QUERY_DOMAIN_INFO;
+typedef struct sam_unknown_info_1_inf
+{
+ uint8 padding[12]; /* 12 bytes zeros */
+ uint32 unknown_1; /* 0x8000 0000 */
+ uint32 unknown_2; /* 0x0000 0000 */
+
+} SAM_UNK_INFO_1;
+
typedef struct sam_unkown_info_2_info
{
uint32 unknown_0; /* 0x0000 0000 */
@@ -382,13 +392,49 @@ typedef struct sam_unkown_info_2_info
} SAM_UNK_INFO_2;
+typedef struct sam_unknown_info_3_info
+{
+ uint32 unknown_0; /* 0x0000 0000 */
+ uint32 unknown_1; /* 0x8000 0000 */
+
+} SAM_UNK_INFO_3;
+
+typedef struct sam_unknown_info_6_info
+{
+ uint32 unknown_0; /* 0x0000 0000 */
+
+ uint32 ptr_0; /* pointer to unknown structure */
+ uint8 padding[12]; /* 12 bytes zeros */
+
+} SAM_UNK_INFO_6;
+
+typedef struct sam_unknown_info_7_info
+{
+ uint16 unknown_0; /* 0x0003 */
+
+} SAM_UNK_INFO_7;
+
+typedef struct sam_unknown_info_12_inf
+{
+ uint32 unknown_0; /* 0xcf1d cc00 */
+ uint32 unknown_1; /* 0xffff fffb */
+ uint32 unknown_2; /* 0xcf1d cc00 */
+ uint32 unknown_3; /* 0xffff fffb */
+
+ uint32 unknown_4; /* 0x8a88 0000 */
+
+} SAM_UNK_INFO_12;
typedef struct sam_unknown_ctr_info
{
union
{
+ SAM_UNK_INFO_1 inf1;
SAM_UNK_INFO_2 inf2;
-
+ SAM_UNK_INFO_3 inf3;
+ SAM_UNK_INFO_6 inf6;
+ SAM_UNK_INFO_7 inf7;
+ SAM_UNK_INFO_12 inf12;
} info;
} SAM_UNK_CTR;
@@ -896,12 +942,12 @@ typedef struct r_samr_lookup_names_info
} SAMR_R_LOOKUP_NAMES;
/****************************************************************************
-SAMR_Q_UNKNOWN_12 - do a conversion from RID groups to something.
+SAMR_Q_LOOKUP_RIDS - do a conversion from RID groups to something.
called to resolve domain RID groups.
*****************************************************************************/
-/* SAMR_Q_UNKNOWN_12 */
-typedef struct q_samr_unknown_12_info
+/* SAMR_Q_LOOKUP_RIDS */
+typedef struct q_samr_lookup_rids_info
{
POLICY_HND pol; /* policy handle */
@@ -912,17 +958,17 @@ typedef struct q_samr_unknown_12_info
uint32 gid[MAX_LOOKUP_SIDS]; /* domain RIDs being looked up */
-} SAMR_Q_UNKNOWN_12;
+} SAMR_Q_LOOKUP_RIDS;
/****************************************************************************
-SAMR_R_UNKNOWN_12 - do a conversion from group RID to names
+SAMR_R_LOOKUP_RIDS - do a conversion from group RID to names
*****************************************************************************/
-/* SAMR_R_UNKNOWN_12 */
-typedef struct r_samr_unknown_12_info
+/* SAMR_R_LOOKUP_RIDS */
+typedef struct r_samr_lookup_rids_info
{
- POLICY_HND pol; /* policy handle */
+ POLICY_HND pol; /* policy handle */
uint32 num_aliases1; /* number of aliases being looked up */
uint32 ptr_aliases; /* pointer to aliases */
@@ -939,13 +985,13 @@ typedef struct r_samr_unknown_12_info
uint32 status;
-} SAMR_R_UNKNOWN_12;
+} SAMR_R_LOOKUP_RIDS;
/* SAMR_Q_OPEN_USER - probably an open */
typedef struct q_samr_open_user_info
{
- POLICY_HND domain_pol; /* policy handle */
+ POLICY_HND domain_pol; /* policy handle */
uint32 unknown_0; /* 32 bit unknown - 0x02011b */
uint32 user_rid; /* user RID */
@@ -955,7 +1001,7 @@ typedef struct q_samr_open_user_info
/* SAMR_R_OPEN_USER - probably an open */
typedef struct r_samr_open_user_info
{
- POLICY_HND user_pol; /* policy handle associated with unknown id */
+ POLICY_HND user_pol; /* policy handle associated with unknown id */
uint32 status; /* return status */
} SAMR_R_OPEN_USER;
@@ -964,7 +1010,7 @@ typedef struct r_samr_open_user_info
/* SAMR_Q_UNKNOWN_13 - probably an open alias in domain */
typedef struct q_samr_unknown_13_info
{
- POLICY_HND alias_pol; /* policy handle */
+ POLICY_HND alias_pol; /* policy handle */
uint16 unknown_1; /* 16 bit unknown - 0x0200 */
uint16 unknown_2; /* 16 bit unknown - 0x0000 */
@@ -975,7 +1021,7 @@ typedef struct q_samr_unknown_13_info
/* SAMR_Q_UNKNOWN_21 - probably an open group in domain */
typedef struct q_samr_unknown_21_info
{
- POLICY_HND group_pol; /* policy handle */
+ POLICY_HND group_pol; /* policy handle */
uint16 unknown_1; /* 16 bit unknown - 0x0477 */
uint16 unknown_2; /* 16 bit unknown - 0x0000 */
@@ -1011,6 +1057,7 @@ typedef struct r_samr_create_user_info
/* SAMR_Q_OPEN_ALIAS - probably an open */
typedef struct q_samr_open_alias_info
{
+ POLICY_HND dom_pol; /* policy handle */
uint32 unknown_0; /* 0x0000 0008 */
uint32 rid_alias; /* rid */
@@ -1127,5 +1174,144 @@ typedef struct r_samr_chgpasswd_user_info
} SAMR_R_CHGPASSWD_USER;
+
+/* SAM_USER_INFO_7 */
+typedef struct sam_user_info_7
+{
+ UNIHDR hdr_user_name;
+ UNISTR2 uni_user_name;
+
+} SAM_USER_INFO_7;
+
+/* SAM_USER_INFO_12 */
+typedef struct sam_user_info_12
+{
+ uint8 lm_pwd[16]; /* lm user passwords */
+ uint8 nt_pwd[16]; /* nt user passwords */
+
+ uint8 lm_pwd_active;
+ uint8 nt_pwd_active;
+
+} SAM_USER_INFO_12;
+
+/* SAM_USER_INFO_23 */
+typedef struct sam_user_info_23
+{
+ /* 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_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 no */
+
+ uint32 unknown_6; /* 0x0000 04ec */
+ uint32 padding4;
+
+ LOGON_HRS logon_hrs;
+
+} SAM_USER_INFO_23;
+
+/* SAM_USER_INFO_24 */
+typedef struct sam_user_info_24
+{
+ uint8 pass[516];
+ uint16 unk_0;
+
+} SAM_USER_INFO_24;
+
+/* SAM_USERINFO_CTR - sam user info */
+typedef struct sam_userinfo_ctr_info
+{
+ uint16 switch_value;
+ union
+ {
+ SAM_USER_INFO_7 *id7;
+ SAM_USER_INFO_10 *id10; /* auth-level 0x10 */
+ SAM_USER_INFO_11 *id11; /* auth-level 0x11 */
+ SAM_USER_INFO_12 *id12; /* auth-level 0x12 */
+ SAM_USER_INFO_21 *id21; /* auth-level 21 */
+ SAM_USER_INFO_23 *id23; /* auth-level 0x17 */
+ SAM_USER_INFO_24 *id24; /* auth-level 0x18 */
+ void* id; /* to make typecasting easy */
+ } info;
+
+} SAM_USERINFO_CTR;
+
+/* 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;
+ SAM_USERINFO_CTR *ctr;
+
+} 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_SET_USERINFO2 - set sam info */
+typedef struct q_samr_set_user_info2
+{
+ POLICY_HND pol; /* policy handle associated with user */
+ uint16 switch_value; /* 0x0010 */
+
+ SAM_USERINFO_CTR *ctr;
+
+} SAMR_Q_SET_USERINFO2;
+
+/* SAMR_R_SET_USERINFO2 - set sam info */
+typedef struct r_samr_set_user_info2
+{
+ uint32 status; /* return status */
+
+} SAMR_R_SET_USERINFO2;
+
#endif /* _RPC_SAMR_H */
diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c
index b927e193dd..16f2493947 100644
--- a/source3/libsmb/smbencrypt.c
+++ b/source3/libsmb/smbencrypt.c
@@ -228,3 +228,47 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[
return True;
}
+/***********************************************************
+ decode a password buffer
+************************************************************/
+BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd,
+ int new_pwrd_size, uint32 *new_pw_len)
+{
+ int uni_pw_len=0;
+ char *pw;
+ /*
+ Warning !!! : This function is called from some rpc call.
+ The password IN the buffer is a UNICODE string.
+ The password IN new_pwrd is an ASCII string
+ If you reuse that code somewhere else check first.
+ */
+
+
+ /*
+ * The length of the new password is in the last 4 bytes of
+ * the data buffer.
+ */
+
+ *new_pw_len = IVAL(buffer, 512);
+
+#ifdef DEBUG_PASSWORD
+ dump_data(100, buffer, 516);
+#endif
+
+ if ((*new_pw_len) < 0 || (*new_pw_len) > new_pwrd_size - 1) {
+ DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", (*new_pw_len)));
+ return False;
+ }
+
+ uni_pw_len = *new_pw_len;
+ *new_pw_len /= 2;
+ pw = dos_unistrn2((uint16 *)(&buffer[512 - uni_pw_len]), uni_pw_len);
+ memcpy(new_pwrd, pw, *new_pw_len + 1);
+
+#ifdef DEBUG_PASSWORD
+ dump_data(100, new_pwrd, (*new_pw_len));
+#endif
+
+ return True;
+}
+
diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c
index a05783ac36..8b2deb4af8 100644
--- a/source3/passdb/passdb.c
+++ b/source3/passdb/passdb.c
@@ -411,6 +411,23 @@ struct sam_passwd *getsam21pwrid(uint32 rid)
return pdb_ops->getsam21pwrid(rid);
}
+/************************************************************************
+ Routine to add a SAM entry to the smb passwd file.
+*************************************************************************/
+
+BOOL add_sam21pwd_entry(struct sam_passwd *pwd)
+{
+ return pdb_ops->add_sam21pwd_entry(pwd);
+}
+
+/************************************************************************
+ Routine to modify a SAM entry to the smb passwd file.
+*************************************************************************/
+
+BOOL mod_sam21pwd_entry(struct sam_passwd *pwd, BOOL override)
+{
+ return pdb_ops->mod_sam21pwd_entry(pwd, override);
+}
/**********************************************************
**********************************************************
@@ -521,6 +538,198 @@ struct sam_passwd *pdb_smb_to_sam(struct smb_passwd *user)
return &pw_buf;
}
+static void select_name(fstring *string, char **name, const UNISTR2 *from)
+{
+ if (from->buffer != 0)
+ {
+ unistr2_to_ascii(*string, from, sizeof(*string));
+ *name = *string;
+ }
+}
+
+/*************************************************************
+ copies a sam passwd.
+ **************************************************************/
+void copy_id23_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_23 *from)
+{
+ static fstring smb_name;
+ static fstring full_name;
+ static fstring home_dir;
+ static fstring dir_drive;
+ static fstring logon_script;
+ static fstring profile_path;
+ static fstring acct_desc;
+ static fstring workstations;
+ static fstring unknown_str;
+ static fstring munged_dial;
+
+ if (from == NULL || to == NULL) return;
+
+ to->logon_time = nt_time_to_unix(&from->logon_time);
+ to->logoff_time = nt_time_to_unix(&from->logoff_time);
+ to->kickoff_time = nt_time_to_unix(&from->kickoff_time);
+ to->pass_last_set_time = nt_time_to_unix(&from->pass_last_set_time);
+ to->pass_can_change_time = nt_time_to_unix(&from->pass_can_change_time);
+ to->pass_must_change_time = nt_time_to_unix(&from->pass_must_change_time);
+
+ select_name(&smb_name , &to->smb_name , &from->uni_user_name );
+ select_name(&full_name , &to->full_name , &from->uni_full_name );
+ select_name(&home_dir , &to->home_dir , &from->uni_home_dir );
+ select_name(&dir_drive , &to->dir_drive , &from->uni_dir_drive );
+ select_name(&logon_script, &to->logon_script, &from->uni_logon_script);
+ select_name(&profile_path, &to->profile_path, &from->uni_profile_path);
+ select_name(&acct_desc , &to->acct_desc , &from->uni_acct_desc );
+ select_name(&workstations, &to->workstations, &from->uni_workstations);
+ select_name(&unknown_str , &to->unknown_str , &from->uni_unknown_str );
+ select_name(&munged_dial , &to->munged_dial , &from->uni_munged_dial );
+
+ to->smb_userid = (uid_t)-1;
+ to->smb_grpid = (gid_t)-1;
+ to->user_rid = from->user_rid;
+ to->group_rid = from->group_rid;
+
+ to->smb_passwd = NULL;
+ to->smb_nt_passwd = NULL;
+
+ to->acct_ctrl = from->acb_info;
+ to->unknown_3 = from->unknown_3;
+
+ to->logon_divs = from->logon_divs;
+ to->hours_len = from->logon_hrs.len;
+ memcpy(to->hours, from->logon_hrs.hours, MAX_HOURS_LEN);
+
+ to->unknown_5 = from->unknown_5;
+ to->unknown_6 = from->unknown_6;
+}
+
+/*************************************************************
+ copies a sam passwd.
+ **************************************************************/
+void copy_id21_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_21 *from)
+{
+ static fstring smb_name;
+ static fstring full_name;
+ static fstring home_dir;
+ static fstring dir_drive;
+ static fstring logon_script;
+ static fstring profile_path;
+ static fstring acct_desc;
+ static fstring workstations;
+ static fstring unknown_str;
+ static fstring munged_dial;
+
+ if (from == NULL || to == NULL) return;
+
+ to->logon_time = nt_time_to_unix(&from->logon_time);
+ to->logoff_time = nt_time_to_unix(&from->logoff_time);
+ to->kickoff_time = nt_time_to_unix(&from->kickoff_time);
+ to->pass_last_set_time = nt_time_to_unix(&from->pass_last_set_time);
+ to->pass_can_change_time = nt_time_to_unix(&from->pass_can_change_time);
+ to->pass_must_change_time = nt_time_to_unix(&from->pass_must_change_time);
+
+ select_name(&smb_name , &to->smb_name , &from->uni_user_name );
+ select_name(&full_name , &to->full_name , &from->uni_full_name );
+ select_name(&home_dir , &to->home_dir , &from->uni_home_dir );
+ select_name(&dir_drive , &to->dir_drive , &from->uni_dir_drive );
+ select_name(&logon_script, &to->logon_script, &from->uni_logon_script);
+ select_name(&profile_path, &to->profile_path, &from->uni_profile_path);
+ select_name(&acct_desc , &to->acct_desc , &from->uni_acct_desc );
+ select_name(&workstations, &to->workstations, &from->uni_workstations);
+ select_name(&unknown_str , &to->unknown_str , &from->uni_unknown_str );
+ select_name(&munged_dial , &to->munged_dial , &from->uni_munged_dial );
+
+ to->smb_userid = (uid_t)-1;
+ to->smb_grpid = (gid_t)-1;
+ to->user_rid = from->user_rid;
+ to->group_rid = from->group_rid;
+
+ to->smb_passwd = NULL;
+ to->smb_nt_passwd = NULL;
+
+ to->acct_ctrl = from->acb_info;
+ to->unknown_3 = from->unknown_3;
+
+ to->logon_divs = from->logon_divs;
+ to->hours_len = from->logon_hrs.len;
+ memcpy(to->hours, from->logon_hrs.hours, MAX_HOURS_LEN);
+
+ to->unknown_5 = from->unknown_5;
+ to->unknown_6 = from->unknown_6;
+}
+
+
+/*************************************************************
+ copies a sam passwd.
+ **************************************************************/
+void copy_sam_passwd(struct sam_passwd *to, const struct sam_passwd *from)
+{
+ static fstring smb_name="";
+ static fstring unix_name="";
+ static fstring full_name="";
+ static fstring home_dir="";
+ static fstring dir_drive="";
+ static fstring logon_script="";
+ static fstring profile_path="";
+ static fstring acct_desc="";
+ static fstring workstations="";
+ static fstring unknown_str="";
+ static fstring munged_dial="";
+
+ if (from == NULL || to == NULL) return;
+
+ memcpy(to, from, sizeof(*from));
+
+ if (from->smb_name != NULL) {
+ fstrcpy(smb_name , from->smb_name);
+ to->smb_name = smb_name;
+ }
+
+ if (from->full_name != NULL) {
+ fstrcpy(full_name, from->full_name);
+ to->full_name = full_name;
+ }
+
+ if (from->home_dir != NULL) {
+ fstrcpy(home_dir , from->home_dir);
+ to->home_dir = home_dir;
+ }
+
+ if (from->dir_drive != NULL) {
+ fstrcpy(dir_drive , from->dir_drive);
+ to->dir_drive = dir_drive;
+ }
+
+ if (from->logon_script != NULL) {
+ fstrcpy(logon_script , from->logon_script);
+ to->logon_script = logon_script;
+ }
+
+ if (from->profile_path != NULL) {
+ fstrcpy(profile_path , from->profile_path);
+ to->profile_path = profile_path;
+ }
+
+ if (from->acct_desc != NULL) {
+ fstrcpy(acct_desc , from->acct_desc);
+ to->acct_desc = acct_desc;
+ }
+
+ if (from->workstations != NULL) {
+ fstrcpy(workstations , from->workstations);
+ to->workstations = workstations;
+ }
+
+ if (from->unknown_str != NULL) {
+ fstrcpy(unknown_str , from->unknown_str);
+ to->unknown_str = unknown_str;
+ }
+
+ if (from->munged_dial != NULL) {
+ fstrcpy(munged_dial , from->munged_dial);
+ to->munged_dial = munged_dial;
+ }
+}
+
/**********************************************************
Encode the account control bits into a string.
length = length of string to encode into (including terminating
diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c
index 521c42ce2c..dbc10f7682 100644
--- a/source3/rpc_client/cli_samr.c
+++ b/source3/rpc_client/cli_samr.c
@@ -552,8 +552,8 @@ BOOL do_samr_query_unknown_12(struct cli_state *cli,
{
prs_struct data;
prs_struct rdata;
- SAMR_Q_UNKNOWN_12 q_o;
- SAMR_R_UNKNOWN_12 r_o;
+ SAMR_Q_LOOKUP_RIDS q_o;
+ SAMR_R_LOOKUP_RIDS r_o;
if (pol == NULL || rid == 0 || num_gids == 0 || gids == NULL ||
num_aliases == NULL || als_names == NULL || num_als_users == NULL )
@@ -567,17 +567,17 @@ BOOL do_samr_query_unknown_12(struct cli_state *cli,
DEBUG(4,("SAMR Query Unknown 12.\n"));
/* store the parameters */
- init_samr_q_unknown_12(&q_o, pol, rid, num_gids, gids);
+ init_samr_q_lookup_rids(&q_o, pol, rid, num_gids, gids);
/* turn parameters into data stream */
- if(!samr_io_q_unknown_12("", &q_o, &data, 0)) {
+ if(!samr_io_q_lookup_rids("", &q_o, &data, 0)) {
prs_mem_free(&data);
prs_mem_free(&rdata);
return False;
}
/* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, SAMR_UNKNOWN_12, &data, &rdata)) {
+ if (!rpc_api_pipe_req(cli, SAMR_LOOKUP_RIDS, &data, &rdata)) {
prs_mem_free(&data);
prs_mem_free(&rdata);
return False;
@@ -585,7 +585,7 @@ BOOL do_samr_query_unknown_12(struct cli_state *cli,
prs_mem_free(&data);
- if(!samr_io_r_unknown_12("", &r_o, &rdata, 0)) {
+ if(!samr_io_r_lookup_rids("", &r_o, &rdata, 0)) {
prs_mem_free(&rdata);
return False;
}
diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c
index c6b219d382..0bd1c29710 100644
--- a/source3/rpc_parse/parse_samr.c
+++ b/source3/rpc_parse/parse_samr.c
@@ -319,6 +319,46 @@ BOOL samr_io_q_query_dom_info(char *desc, SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_st
}
/*******************************************************************
+Inits a structure.
+********************************************************************/
+BOOL init_unk_info1(SAM_UNK_INFO_1 *u_1)
+{
+ if (u_1 == NULL)
+ return False;
+
+ memset(u_1->padding, 0, sizeof(u_1->padding)); /* 12 bytes zeros */
+ u_1->unknown_1 = 0x80000000;
+ u_1->unknown_2 = 0x00000000;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL sam_io_unk_info1(char *desc, SAM_UNK_INFO_1 *u_1, prs_struct *ps, int depth)
+{
+ if (u_1 == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "sam_io_unk_info1");
+ depth++;
+
+ if(!prs_uint8s(False, "padding", ps, depth, u_1->padding, sizeof(u_1->padding)))
+ return False;
+
+ if(!prs_uint32("unknown_1", ps, depth, &u_1->unknown_1)) /* 0x8000 0000 */
+ return False;
+ if(!prs_uint32("unknown_2", ps, depth, &u_1->unknown_2)) /* 0x0000 0000 */
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
Inits a structure.
********************************************************************/
@@ -404,6 +444,9 @@ BOOL sam_io_unk_info2(char *desc, SAM_UNK_INFO_2 *u_2, prs_struct *ps, int depth
if(!smb_io_unistr2( "uni_domain", &u_2->uni_domain, u_2->hdr_domain.buffer, ps, depth)) /* domain name unicode string */
return False;
+ if(!prs_align(ps))
+ return False;
+
if(!smb_io_unistr2( "uni_server", &u_2->uni_server, u_2->hdr_server.buffer, ps, depth)) /* server name unicode string */
return False;
@@ -414,6 +457,160 @@ BOOL sam_io_unk_info2(char *desc, SAM_UNK_INFO_2 *u_2, prs_struct *ps, int depth
}
/*******************************************************************
+Inits a structure.
+********************************************************************/
+BOOL init_unk_info3(SAM_UNK_INFO_3 * u_3)
+{
+ if (u_3 == NULL)
+ return False;
+
+ u_3->unknown_0 = 0x00000000;
+ u_3->unknown_1 = 0x80000000;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL sam_io_unk_info3(char *desc, SAM_UNK_INFO_3 *u_3, prs_struct *ps, int depth)
+{
+ if (u_3 == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "sam_io_unk_info3");
+ depth++;
+
+ if(!prs_uint32("unknown_0", ps, depth, &u_3->unknown_0)) /* 0x0000 0000 */
+ return False;
+ if(!prs_uint32("unknown_1", ps, depth, &u_3->unknown_1)) /* 0x8000 0000 */
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+Inits a structure.
+********************************************************************/
+BOOL init_unk_info6(SAM_UNK_INFO_6 * u_6)
+{
+ if (u_6 == NULL)
+ return False;
+
+ u_6->unknown_0 = 0x00000000;
+ u_6->ptr_0 = 1;
+ memset(u_6->padding, 0, sizeof(u_6->padding)); /* 12 bytes zeros */
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL sam_io_unk_info6(char *desc, SAM_UNK_INFO_6 *u_6, prs_struct *ps, int depth)
+{
+ if (u_6 == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "sam_io_unk_info6");
+ depth++;
+
+ if(!prs_uint32("unknown_0", ps, depth, &u_6->unknown_0)) /* 0x0000 0000 */
+ return False;
+ if(!prs_uint32("ptr_0", ps, depth, &u_6->ptr_0)) /* pointer to unknown structure */
+ return False;
+ if(!prs_uint8s(False, "padding", ps, depth, u_6->padding, sizeof(u_6->padding))) /* 12 bytes zeros */
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+Inits a structure.
+********************************************************************/
+BOOL init_unk_info7(SAM_UNK_INFO_7 *u_7)
+{
+ if (u_7 == NULL)
+ return False;
+
+ u_7->unknown_0 = 0x0003;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL sam_io_unk_info7(char *desc, SAM_UNK_INFO_7 *u_7, prs_struct *ps, int depth)
+{
+ if (u_7 == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "sam_io_unk_info7");
+ depth++;
+
+ if(!prs_uint16("unknown_0", ps, depth, &u_7->unknown_0)) /* 0x0003 */
+ return False;
+ if(!prs_align(ps))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+Inits a structure.
+********************************************************************/
+BOOL init_unk_info12(SAM_UNK_INFO_12 * u_12)
+{
+ if (u_12 == NULL)
+ return False;
+
+ u_12->unknown_0 = 0xcf1dcc00;
+ u_12->unknown_1 = 0xfffffffb;
+ u_12->unknown_2 = 0xcf1dcc00;
+ u_12->unknown_3 = 0xfffffffb;
+
+ u_12->unknown_4 = 0x8a880000;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL sam_io_unk_info12(char *desc, SAM_UNK_INFO_12 * u_12,
+ prs_struct *ps, int depth)
+{
+ if (u_12 == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "sam_io_unk_info12");
+ depth++;
+
+ if(!prs_uint32("unknown_0", ps, depth, &u_12->unknown_0))
+ return False;
+ if(!prs_uint32("unknown_1", ps, depth, &u_12->unknown_1))
+ return False;
+ if(!prs_uint32("unknown_2", ps, depth, &u_12->unknown_2))
+ return False;
+ if(!prs_uint32("unknown_3", ps, depth, &u_12->unknown_3))
+ return False;
+ if(!prs_uint32("unknown_4", ps, depth, &u_12->unknown_4))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
Inits a SAMR_R_QUERY_DOMAIN_INFO structure.
********************************************************************/
@@ -451,17 +648,38 @@ BOOL samr_io_r_query_dom_info(char *desc, SAMR_R_QUERY_DOMAIN_INFO *r_u, prs_str
if(!prs_uint32("ptr_0 ", ps, depth, &r_u->ptr_0))
return False;
- if(!prs_uint16("switch_value", ps, depth, &r_u->switch_value))
- return False;
- if(!prs_align(ps))
- return False;
if (r_u->ptr_0 != 0 && r_u->ctr != NULL) {
+ if(!prs_uint16("switch_value", ps, depth, &r_u->switch_value))
+ return False;
+ if(!prs_align(ps))
+ return False;
+
switch (r_u->switch_value) {
+ case 0x01:
+ if(!sam_io_unk_info1("unk_inf1", &r_u->ctr->info.inf1, ps, depth))
+ return False;
+ break;
case 0x02:
if(!sam_io_unk_info2("unk_inf2", &r_u->ctr->info.inf2, ps, depth))
return False;
break;
+ case 0x03:
+ if(!sam_io_unk_info3("unk_inf3", &r_u->ctr->info.inf3, ps, depth))
+ return False;
+ break;
+ case 0x06:
+ if(!sam_io_unk_info6("unk_inf6", &r_u->ctr->info.inf6, ps, depth))
+ return False;
+ break;
+ case 0x07:
+ if(!sam_io_unk_info7("unk_inf7", &r_u->ctr->info.inf7, ps, depth))
+ return False;
+ break;
+ case 0x0c:
+ if(!sam_io_unk_info12("unk_inf12", &r_u->ctr->info.inf12, ps, depth))
+ return False;
+ break;
default:
DEBUG(3,("samr_io_r_query_dom_info: unknown switch level 0x%x\n",
r_u->switch_value));
@@ -469,6 +687,9 @@ BOOL samr_io_r_query_dom_info(char *desc, SAMR_R_QUERY_DOMAIN_INFO *r_u, prs_str
}
}
+ if(!prs_uint32("status", ps, depth, &r_u->status))
+ return False;
+
return True;
}
@@ -2178,7 +2399,7 @@ BOOL samr_io_r_lookup_names(char *desc, SAMR_R_LOOKUP_NAMES *r_u, prs_struct *p
Reads or writes a structure.
********************************************************************/
-BOOL samr_io_q_unknown_12(char *desc, SAMR_Q_UNKNOWN_12 *q_u, prs_struct *ps, int depth)
+BOOL samr_io_q_lookup_rids(char *desc, SAMR_Q_LOOKUP_RIDS *q_u, prs_struct *ps, int depth)
{
int i;
fstring tmp;
@@ -2186,7 +2407,7 @@ BOOL samr_io_q_unknown_12(char *desc, SAMR_Q_UNKNOWN_12 *q_u, prs_struct *ps, i
if (q_u == NULL)
return False;
- prs_debug(ps, depth, desc, "samr_io_q_unknown_12");
+ prs_debug(ps, depth, desc, "samr_io_q_lookup_rids");
depth++;
if(!prs_align(ps))
@@ -2214,9 +2435,6 @@ BOOL samr_io_q_unknown_12(char *desc, SAMR_Q_UNKNOWN_12 *q_u, prs_struct *ps, i
return False;
}
- if(!prs_align(ps))
- return False;
-
return True;
}
@@ -2224,13 +2442,13 @@ BOOL samr_io_q_unknown_12(char *desc, SAMR_Q_UNKNOWN_12 *q_u, prs_struct *ps, i
Inits a SAMR_R_UNKNOWN_12 structure.
********************************************************************/
-void init_samr_r_unknown_12(SAMR_R_UNKNOWN_12 *r_u,
+void init_samr_r_lookup_rids(SAMR_R_LOOKUP_RIDS *r_u,
uint32 num_aliases, fstring *als_name, uint32 *num_als_usrs,
uint32 status)
{
int i;
- DEBUG(5,("init_samr_r_unknown_12\n"));
+ DEBUG(5,("init_samr_r_lookup_rids\n"));
if (status == 0x0) {
r_u->num_aliases1 = num_aliases;
@@ -2266,7 +2484,7 @@ void init_samr_r_unknown_12(SAMR_R_UNKNOWN_12 *r_u,
Reads or writes a structure.
********************************************************************/
-BOOL samr_io_r_unknown_12(char *desc, SAMR_R_UNKNOWN_12 *r_u, prs_struct *ps, int depth)
+BOOL samr_io_r_lookup_rids(char *desc, SAMR_R_LOOKUP_RIDS *r_u, prs_struct *ps, int depth)
{
int i;
fstring tmp;
@@ -2274,7 +2492,7 @@ BOOL samr_io_r_unknown_12(char *desc, SAMR_R_UNKNOWN_12 *r_u, prs_struct *ps, i
if (r_u == NULL)
return False;
- prs_debug(ps, depth, desc, "samr_io_r_unknown_12");
+ prs_debug(ps, depth, desc, "samr_io_r_lookup_rids");
depth++;
if(!prs_align(ps))
@@ -2299,6 +2517,8 @@ BOOL samr_io_r_unknown_12(char *desc, SAMR_R_UNKNOWN_12 *r_u, prs_struct *ps, i
slprintf(tmp, sizeof(tmp) - 1, "als_str[%02d] ", i);
if(!smb_io_unistr2("", &r_u->uni_als_name[i], r_u->hdr_als_name[i].buffer, ps, depth))
return False;
+ if(!prs_align(ps))
+ return False;
}
}
@@ -2559,7 +2779,7 @@ static BOOL sam_io_logon_hrs(char *desc, LOGON_HRS *hrs, prs_struct *ps, int de
if(!prs_align(ps))
return False;
- if(!prs_uint32 ( "len ", ps, depth, &hrs->len))
+ if(!prs_uint32 ("len ", ps, depth, &hrs->len))
return False;
if (hrs->len > 64) {
@@ -2838,12 +3058,12 @@ void init_sam_user_info21(SAM_USER_INFO_21 *usr,
Reads or writes a structure.
********************************************************************/
-static BOOL sam_io_user_info21(char *desc, SAM_USER_INFO_21 *usr, prs_struct *ps, int depth)
+static BOOL sam_io_user_info21(char *desc, SAM_USER_INFO_21 *usr, prs_struct *ps, int depth)
{
if (usr == NULL)
return False;
- prs_debug(ps, depth, desc, "lsa_io_user_info");
+ prs_debug(ps, depth, desc, "sam_io_user_info21");
depth++;
if(!prs_align(ps))
@@ -2892,9 +3112,7 @@ static BOOL sam_io_user_info21(char *desc, SAM_USER_INFO_21 *usr, prs_struct *p
return False;
if(!prs_uint32("group_rid ", ps, depth, &usr->group_rid)) /* Group ID */
return False;
- if(!prs_uint16("acb_info ", ps, depth, &usr->acb_info)) /* Group ID */
- return False;
- if(!prs_align(ps))
+ if(!prs_uint32("acb_info ", ps, depth, &usr->acb_info)) /* Group ID */
return False;
if(!prs_uint32("unknown_3 ", ps, depth, &usr->unknown_3))
@@ -2915,36 +3133,53 @@ static BOOL sam_io_user_info21(char *desc, SAM_USER_INFO_21 *usr, prs_struct *p
if(!smb_io_unistr2("uni_user_name ", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
return False;
+ if(!prs_align(ps))
+ 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(!prs_align(ps))
+ 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(!prs_align(ps))
+ 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(!prs_align(ps))
+ 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(!prs_align(ps))
+ 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(!prs_align(ps))
+ return False;
if(!smb_io_unistr2("uni_acct_desc ", &usr->uni_acct_desc, usr->hdr_acct_desc.buffer, ps, depth)) /* user description unicode string */
return False;
+ if(!prs_align(ps))
+ 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(!prs_align(ps))
+ 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(!prs_align(ps))
+ return False;
if(!smb_io_unistr2("uni_munged_dial ", &usr->uni_munged_dial, usr->hdr_munged_dial .buffer, ps, depth)) /* worksations user can log on from */
return False;
+ if(!prs_align(ps))
+ return False;
if(!prs_uint32("unknown_6 ", ps, depth, &usr->unknown_6))
return False;
if(!prs_uint32("padding4 ", ps, depth, &usr->padding4))
return False;
- if (usr->ptr_logon_hrs) {
+ if (usr->ptr_logon_hrs)
if(!sam_io_logon_hrs("logon_hrs", &usr->logon_hrs, ps, depth))
return False;
- if(!prs_align(ps))
- return False;
- }
return True;
}
@@ -3048,6 +3283,9 @@ BOOL samr_io_r_query_userinfo(char *desc, SAMR_R_QUERY_USERINFO *r_u, prs_struc
}
}
+ if(!prs_align(ps))
+ return False;
+
if(!prs_uint32("status", ps, depth, &r_u->status))
return False;
@@ -3279,7 +3517,7 @@ void init_samr_q_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
Reads or writes a structure.
********************************************************************/
-BOOL samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, int depth)
+BOOL samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, int depth)
{
if (q_u == NULL)
return False;
@@ -3290,6 +3528,9 @@ BOOL samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, i
if(!prs_align(ps))
return False;
+ if(!smb_io_pol_hnd("domain_pol", &(q_u->dom_pol), ps, depth))
+ return False;
+
if(!prs_uint32("unknown_0", ps, depth, &q_u->unknown_0))
return False;
if(!prs_uint32("rid_alias", ps, depth, &q_u->rid_alias))
@@ -3328,13 +3569,13 @@ BOOL samr_io_r_open_alias(char *desc, SAMR_R_OPEN_ALIAS *r_u, prs_struct *ps, i
Inits a SAMR_Q_UNKNOWN_12 structure.
********************************************************************/
-void init_samr_q_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
+void init_samr_q_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u,
POLICY_HND *pol, uint32 rid,
uint32 num_gids, uint32 *gid)
{
int i;
- DEBUG(5,("init_samr_r_unknwon_12\n"));
+ DEBUG(5,("init_samr_q_lookup_rids\n"));
memcpy(&q_u->pol, pol, sizeof(*pol));
@@ -3858,4 +4099,417 @@ BOOL samr_io_r_enum_domains(char *desc, SAMR_R_ENUM_DOMAINS * r_u,
return True;
}
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL sam_io_user_info12(char *desc, SAM_USER_INFO_12 *u, prs_struct *ps, int depth)
+{
+ if (u == NULL)
+ return False;
+
+ DEBUG(0, ("possible security breach!\n"));
+
+ prs_debug(ps, depth, desc, "samr_io_r_user_info12");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint8s(False, "lm_pwd", ps, depth, u->lm_pwd, sizeof(u->lm_pwd)))
+ return False;
+ if(!prs_uint8s(False, "nt_pwd", ps, depth, u->nt_pwd, sizeof(u->nt_pwd)))
+ return False;
+
+ if(!prs_uint8("lm_pwd_active", ps, depth, &u->lm_pwd_active))
+ return False;
+ if(!prs_uint8("nt_pwd_active", ps, depth, &u->nt_pwd_active))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL sam_io_user_info23(char *desc, SAM_USER_INFO_23 *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_uint32("unknown_3", ps, depth, &usr->unknown_3))
+ return False;
+ if(!prs_uint16("logon_divs", ps, depth, &usr->logon_divs)) /* logon divisions per week */
+ return False;
+ if(!prs_align(ps))
+ return False;
+ if(!prs_uint32("ptr_logon_hrs", ps, depth, &usr->ptr_logon_hrs))
+ return False;
+ if(!prs_uint8s(False, "padding1", ps, depth, usr->padding1, sizeof(usr->padding1)))
+ return False;
+ if(!prs_uint32("unknown_5", ps, depth, &usr->unknown_5))
+ 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(!prs_align(ps))
+ 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(!prs_align(ps))
+ 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(!prs_align(ps))
+ 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(!prs_align(ps))
+ 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(!prs_align(ps))
+ 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(!prs_align(ps))
+ 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(!prs_align(ps))
+ 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(!prs_align(ps))
+ 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(!prs_align(ps))
+ return False;
+ if(!smb_io_unistr2("uni_munged_dial", &usr->uni_munged_dial, usr->hdr_munged_dial.buffer, ps, depth)) /* worksations user can log on from */
+ return False;
+ if(!prs_align(ps))
+ return False;
+
+ /* ok, this is only guess-work (as usual) */
+ if (usr->unknown_3 != 0x0) {
+ if(!prs_uint32("unknown_6", ps, depth, &usr->unknown_6))
+ return False;
+ if(!prs_uint32("padding4", ps, depth, &usr->padding4))
+ return False;
+ } else if (UNMARSHALLING(ps)) {
+ usr->unknown_6 = 0;
+ usr->padding4 = 0;
+ }
+
+ if (usr->ptr_logon_hrs) {
+ if(!sam_io_logon_hrs("logon_hrs", &usr->logon_hrs, ps, depth))
+ return False;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL sam_io_user_info24(char *desc, SAM_USER_INFO_24 *usr, prs_struct *ps, int depth)
+{
+ if (usr == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "sam_io_user_info24");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint8s(False, "password", ps, depth, usr->pass, sizeof(usr->pass)))
+ return False;
+ if(!prs_uint16("unk_0", ps, depth, &usr->unk_0)) /* unknown */
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL samr_io_userinfo_ctr(char *desc, SAM_USERINFO_CTR *ctr, prs_struct *ps, int depth)
+{
+ if (ctr == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "samr_io_userinfo_ctr");
+ depth++;
+
+ /* lkclXXXX DO NOT ALIGN BEFORE READING SWITCH VALUE! */
+
+ if(!prs_uint16("switch_value", ps, depth, &ctr->switch_value))
+ return False;
+ if(!prs_align(ps))
+ return False;
+
+ switch (ctr->switch_value) {
+ case 0x10:
+ if (UNMARSHALLING(ps)) /* reading */
+ ctr->info.id10 = (SAM_USER_INFO_10 *)malloc(sizeof(SAM_USER_INFO_10));
+ if (ctr->info.id10 == NULL) {
+ DEBUG(2, ("samr_io_userinfo_ctr: info pointer not initialised\n"));
+ return False;
+ }
+ if(!sam_io_user_info10("", ctr->info.id10, ps, depth))
+ return False;
+ break;
+ case 0x11:
+ if (UNMARSHALLING(ps)) /* reading */
+ ctr->info.id11 = (SAM_USER_INFO_11 *)malloc(sizeof(SAM_USER_INFO_11));
+ if (ctr->info.id11 == NULL) {
+ DEBUG(2, ("samr_io_userinfo_ctr: info pointer not initialised\n"));
+ return False;
+ }
+ if(!sam_io_user_info11("", ctr->info.id11, ps, depth))
+ return False;
+ break;
+ case 0x12:
+ if (UNMARSHALLING(ps)) /* reading */
+ ctr->info.id12 = (SAM_USER_INFO_12 *)malloc(sizeof(SAM_USER_INFO_12));
+ if (ctr->info.id12 == NULL) {
+ DEBUG(2, ("samr_io_userinfo_ctr: info pointer not initialised\n"));
+ return False;
+ }
+ if(!sam_io_user_info12("", ctr->info.id12, ps, depth))
+ return False;
+ break;
+ case 21:
+ if (UNMARSHALLING(ps)) /* reading */
+ ctr->info.id21 = (SAM_USER_INFO_21 *)malloc(sizeof(SAM_USER_INFO_21));
+ if (ctr->info.id21 == NULL) {
+ DEBUG(2, ("samr_io_userinfo_ctr: info pointer not initialised\n"));
+ return False;
+ }
+ if(!sam_io_user_info21("", ctr->info.id21, ps, depth))
+ return False;
+ break;
+ case 23:
+ if (UNMARSHALLING(ps)) /* reading */
+ ctr->info.id23 = (SAM_USER_INFO_23 *)malloc(sizeof(SAM_USER_INFO_23));
+ if (ctr->info.id23 == NULL) {
+ DEBUG(2, ("samr_io_userinfo_ctr: info pointer not initialised\n"));
+ return False;
+ }
+ if(!sam_io_user_info23("", ctr->info.id23, ps, depth))
+ return False;
+ break;
+ case 24:
+ if (UNMARSHALLING(ps)) /* reading */
+ ctr->info.id24 = (SAM_USER_INFO_24 *)malloc(sizeof(SAM_USER_INFO_24));
+ if (ctr->info.id24 == NULL) {
+ DEBUG(2, ("samr_io_userinfo_ctr: info pointer not initialised\n"));
+ return False;
+ }
+ if(!sam_io_user_info24("", ctr->info.id24, ps, depth))
+ return False;
+ break;
+ default:
+ DEBUG(2, ("samr_io_userinfo_ctr: unknown switch level 0x%x\n", ctr->switch_value));
+ return False;
+ break;
+
+ }
+
+ return True;
+}
+
+/*******************************************************************
+frees a structure.
+********************************************************************/
+void free_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr)
+{
+ if (ctr == NULL)
+ return;
+ safe_free(ctr->info.id);
+ ctr->info.id = NULL;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_set_userinfo(char *desc, SAMR_Q_SET_USERINFO *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_set_userinfo");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
+ return False;
+
+ if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value))
+ return False;
+ if(!samr_io_userinfo_ctr("ctr", q_u->ctr, ps, depth))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+frees a structure.
+********************************************************************/
+void free_samr_q_set_userinfo(SAMR_Q_SET_USERINFO * q_u)
+{
+ if (q_u == NULL)
+ return;
+ free_samr_userinfo_ctr(q_u->ctr);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_set_userinfo(char *desc, SAMR_R_SET_USERINFO *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_set_userinfo");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_set_userinfo2(char *desc, SAMR_Q_SET_USERINFO2 *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_set_userinfo2");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
+ return False;
+
+ if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value))
+ return False;
+ if(!samr_io_userinfo_ctr("ctr", q_u->ctr, ps, depth))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+frees a structure.
+********************************************************************/
+void free_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u)
+{
+ free_samr_userinfo_ctr(q_u->ctr);
+}
+
+/*******************************************************************
+makes a SAMR_R_SET_USERINFO2 structure.
+********************************************************************/
+BOOL make_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 *r_u, uint32 status)
+{
+ if (r_u == NULL)
+ return False;
+
+ DEBUG(5, ("make_samr_r_set_userinfo2\n"));
+
+ r_u->status = status; /* return status */
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_set_userinfo2(char *desc, SAMR_R_SET_USERINFO2 *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_set_userinfo2");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+
#undef OLD_NTDOMAIN
diff --git a/source3/rpc_server/srv_lsa_hnd.c b/source3/rpc_server/srv_lsa_hnd.c
index 5670178732..0782c8c4b2 100644
--- a/source3/rpc_server/srv_lsa_hnd.c
+++ b/source3/rpc_server/srv_lsa_hnd.c
@@ -32,16 +32,15 @@ extern int DEBUGLEVEL;
struct reg_info
{
- /* for use by \PIPE\winreg */
+ /* for use by \PIPE\winreg */
fstring name; /* name of registry key */
};
struct samr_info
{
- /* for use by the \PIPE\samr policy */
+ /* for use by the \PIPE\samr policy */
DOM_SID sid;
- uint32 rid; /* relative id associated with the pol_hnd */
- uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
+ uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
};
static struct policy
@@ -162,25 +161,6 @@ int find_lsa_policy_by_hnd(POLICY_HND *hnd)
return p?p->pnum:-1;
}
-/****************************************************************************
- set samr rid
-****************************************************************************/
-BOOL set_lsa_policy_samr_rid(POLICY_HND *hnd, uint32 rid)
-{
- struct policy *p = find_lsa_policy(hnd);
-
- if (p && p->open) {
- DEBUG(3,("Setting policy device rid=%x pnum=%x\n",
- rid, p->pnum));
-
- p->dev.samr.rid = rid;
- return True;
- }
-
- DEBUG(3,("Error setting policy rid=%x\n",rid));
- return False;
-}
-
/****************************************************************************
set samr pol status. absolutely no idea what this is.
@@ -230,8 +210,7 @@ BOOL get_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
{
struct policy *p = find_lsa_policy(hnd);
- if (p != NULL && p->open)
- {
+ if (p != NULL && p->open) {
fstring sidstr;
memcpy(sid, &p->dev.samr.sid, sizeof(*sid));
DEBUG(3,("Getting policy sid=%s pnum=%x\n",
@@ -252,7 +231,7 @@ uint32 get_lsa_policy_samr_rid(POLICY_HND *hnd)
struct policy *p = find_lsa_policy(hnd);
if (p && p->open) {
- uint32 rid = p->dev.samr.rid;
+ uint32 rid = p->dev.samr.sid.sub_auths[p->dev.samr.sid.num_auths-1];
DEBUG(3,("Getting policy device rid=%x pnum=%x\n",
rid, p->pnum));
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index 44bca13c1a..01d9568477 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -1195,7 +1195,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name,
/* do the actual command */
if(!api_rpc_cmds[fn_num].fn(p)) {
- DEBUG(0,("api_rpcTNP: %s: failed.\n", rpc_name));
+ DEBUG(0,("api_rpcTNP: %s: %s failed.\n", rpc_name, api_rpc_cmds[fn_num].name));
prs_mem_free(&p->out_data.rdata);
return False;
}
diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c
index 7891fc16dc..59a541abd9 100644
--- a/source3/rpc_server/srv_samr.c
+++ b/source3/rpc_server/srv_samr.c
@@ -1306,9 +1306,9 @@ static BOOL api_samr_unknown_38(pipes_struct *p)
/*******************************************************************
- samr_reply_unknown_12
+ samr_reply_lookup_rids
********************************************************************/
-static BOOL samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
+static BOOL samr_reply_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u,
prs_struct *rdata)
{
fstring group_names[MAX_SAM_ENTRIES];
@@ -1316,9 +1316,9 @@ static BOOL samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
uint32 status = 0;
int num_gids = q_u->num_gids1;
- SAMR_R_UNKNOWN_12 r_u;
+ SAMR_R_LOOKUP_RIDS r_u;
- DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
+ DEBUG(5,("samr_reply_lookup_rids: %d\n", __LINE__));
/* find the policy handle. open a policy on it. */
if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
@@ -1332,7 +1332,7 @@ static BOOL samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
if (num_gids > MAX_SAM_ENTRIES)
{
num_gids = MAX_SAM_ENTRIES;
- DEBUG(5,("samr_unknown_12: truncating entries to %d\n", num_gids));
+ DEBUG(5,("samr_reply_lookup_rids: truncating entries to %d\n", num_gids));
}
for (i = 0; i < num_gids && status == 0; i++)
@@ -1342,32 +1342,32 @@ static BOOL samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
}
}
- init_samr_r_unknown_12(&r_u, num_gids, group_names, group_attrs, status);
+ init_samr_r_lookup_rids(&r_u, num_gids, group_names, group_attrs, status);
/* store the response in the SMB stream */
- if(!samr_io_r_unknown_12("", &r_u, rdata, 0))
+ if(!samr_io_r_lookup_rids("", &r_u, rdata, 0))
return False;
- DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
+ DEBUG(5,("samr_reply_lookup_rids: %d\n", __LINE__));
return True;
}
/*******************************************************************
- api_samr_unknown_12
+ api_samr_lookup_rids
********************************************************************/
-static BOOL api_samr_unknown_12(pipes_struct *p)
+static BOOL api_samr_lookup_rids(pipes_struct *p)
{
- SAMR_Q_UNKNOWN_12 q_u;
+ SAMR_Q_LOOKUP_RIDS q_u;
prs_struct *data = &p->in_data.data;
prs_struct *rdata = &p->out_data.rdata;
/* grab the samr lookup names */
- if(!samr_io_q_unknown_12("", &q_u, data, 0))
+ if(!samr_io_q_lookup_rids("", &q_u, data, 0))
return False;
/* construct reply. always indicate success */
- if(!samr_reply_unknown_12(&q_u, rdata))
+ if(!samr_reply_lookup_rids(&q_u, rdata))
return False;
return True;
@@ -1375,62 +1375,51 @@ static BOOL api_samr_unknown_12(pipes_struct *p)
/*******************************************************************
- samr_reply_open_user
+ _api_samr_open_user
********************************************************************/
-static BOOL samr_reply_open_user(SAMR_Q_OPEN_USER *q_u, prs_struct *rdata, int status)
+static uint32 _api_samr_open_user(POLICY_HND domain_pol, uint32 user_rid, POLICY_HND *user_pol)
{
- SAMR_R_OPEN_USER r_u;
struct sam_passwd *sam_pass;
- BOOL pol_open = False;
-
- /* set up the SAMR open_user response */
- memset((char *)r_u.user_pol.data, '\0', POL_HND_SIZE);
+ DOM_SID sid;
- r_u.status = 0x0;
-
- /* find the policy handle. open a policy on it. */
- if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
- {
- r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
+ /* find the domain policy handle. */
+ if (find_lsa_policy_by_hnd(&domain_pol) == -1)
+ return NT_STATUS_INVALID_HANDLE;
/* get a (unique) handle. open a policy on it. */
- if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.user_pol))))
- {
- r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
+ if (!open_lsa_policy_hnd(user_pol))
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
become_root();
- sam_pass = getsam21pwrid(q_u->user_rid);
+ sam_pass = getsam21pwrid(user_rid);
unbecome_root();
/* check that the RID exists in our domain. */
- if (r_u.status == 0x0 && sam_pass == NULL)
- {
- r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
+ if (sam_pass == NULL) {
+ close_lsa_policy_hnd(user_pol);
+ return NT_STATUS_NO_SUCH_USER;
}
-
- /* associate the RID with the (unique) handle. */
- if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
- {
- /* oh, whoops. don't know what error message to return, here */
- r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+
+ /* Get the domain SID stored in the domain policy */
+ if(!get_lsa_policy_samr_sid(&domain_pol, &sid)) {
+ close_lsa_policy_hnd(user_pol);
+ return NT_STATUS_INVALID_HANDLE;
}
- if (r_u.status != 0 && pol_open)
- {
- close_lsa_policy_hnd(&(r_u.user_pol));
+ /* append the user's RID to it */
+ if(!sid_append_rid(&sid, user_rid)) {
+ close_lsa_policy_hnd(user_pol);
+ return NT_STATUS_NO_SUCH_USER;
}
- DEBUG(5,("samr_open_user: %d\n", __LINE__));
-
- /* store the response in the SMB stream */
- if(!samr_io_r_open_user("", &r_u, rdata, 0))
- return False;
-
- DEBUG(5,("samr_open_user: %d\n", __LINE__));
+ /* associate the user's SID with the handle. */
+ if (!set_lsa_policy_samr_sid(user_pol, &sid)) {
+ /* oh, whoops. don't know what error message to return, here */
+ close_lsa_policy_hnd(user_pol);
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
- return True;
+ return NT_STATUS_NO_PROBLEMO;
}
/*******************************************************************
@@ -1439,21 +1428,28 @@ static BOOL samr_reply_open_user(SAMR_Q_OPEN_USER *q_u, prs_struct *rdata, int s
static BOOL api_samr_open_user(pipes_struct *p)
{
SAMR_Q_OPEN_USER q_u;
+ SAMR_R_OPEN_USER r_u;
prs_struct *data = &p->in_data.data;
prs_struct *rdata = &p->out_data.rdata;
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
/* grab the samr unknown 22 */
if(!samr_io_q_open_user("", &q_u, data, 0))
return False;
- /* construct reply. always indicate success */
- if(!samr_reply_open_user(&q_u, rdata, 0x0))
+ r_u.status = _api_samr_open_user(q_u.domain_pol, q_u.user_rid, &r_u.user_pol);
+
+ /* store the response in the SMB stream */
+ if(!samr_io_r_open_user("", &r_u, rdata, 0))
return False;
+ DEBUG(5,("samr_open_user: %d\n", __LINE__));
+
return True;
}
-
/*************************************************************************
get_user_info_10
*************************************************************************/
@@ -1753,45 +1749,64 @@ static BOOL api_samr_query_usergroups(pipes_struct *p)
/*******************************************************************
- samr_reply_query_dom_info
+ api_samr_query_dom_info
********************************************************************/
-static BOOL samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct *rdata)
+static BOOL api_samr_query_dom_info(pipes_struct *p)
{
+ SAMR_Q_QUERY_DOMAIN_INFO q_u;
SAMR_R_QUERY_DOMAIN_INFO r_u;
SAM_UNK_CTR ctr;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
uint16 switch_value = 0x0;
uint32 status = 0x0;
+ ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
ZERO_STRUCT(ctr);
- r_u.ctr = &ctr;
+ DEBUG(5,("api_samr_query_dom_info: %d\n", __LINE__));
- DEBUG(5,("samr_reply_query_dom_info: %d\n", __LINE__));
+ /* grab the samr unknown 8 command */
+ if(!samr_io_q_query_dom_info("", &q_u, data, 0))
+ return False;
/* find the policy handle. open a policy on it. */
- if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
- {
- r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- DEBUG(5,("samr_reply_query_dom_info: invalid handle\n"));
+ if (find_lsa_policy_by_hnd(&q_u.domain_pol) == -1) {
+ status = NT_STATUS_INVALID_HANDLE;
+ DEBUG(5,("api_samr_query_dom_info: invalid handle\n"));
}
- if (status == 0x0)
- {
- switch (q_u->switch_value)
- {
+ if (status == 0x0) {
+ switch (q_u.switch_value) {
+ case 0x01:
+ switch_value = 0x1;
+ init_unk_info1(&ctr.info.inf1);
+ break;
case 0x02:
- {
switch_value = 0x2;
init_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname);
-
break;
- }
+ case 0x03:
+ switch_value = 0x3;
+ init_unk_info3(&ctr.info.inf3);
+ break;
+ case 0x06:
+ switch_value = 0x6;
+ init_unk_info6(&ctr.info.inf6);
+ break;
+ case 0x07:
+ switch_value = 0x7;
+ init_unk_info7(&ctr.info.inf7);
+ break;
+ case 0x0c:
+ switch_value = 0xc;
+ init_unk_info12(&ctr.info.inf12);
+ break;
default:
- {
- status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+ status = NT_STATUS_INVALID_INFO_CLASS;
break;
- }
}
}
@@ -1801,65 +1816,28 @@ static BOOL samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct
if(!samr_io_r_query_dom_info("", &r_u, rdata, 0))
return False;
- DEBUG(5,("samr_query_dom_info: %d\n", __LINE__));
-
- return True;
-}
-
-/*******************************************************************
- api_samr_query_dom_info
- ********************************************************************/
-static BOOL api_samr_query_dom_info(pipes_struct *p)
-{
- SAMR_Q_QUERY_DOMAIN_INFO q_e;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- /* grab the samr unknown 8 command */
- if(!samr_io_q_query_dom_info("", &q_e, data, 0))
- return False;
-
- /* construct reply. */
- if(!samr_reply_query_dom_info(&q_e, rdata))
- return False;
+ DEBUG(5,("api_samr_query_dom_info: %d\n", __LINE__));
return True;
}
/*******************************************************************
- api_samr_create_user
+ _api_samr_create_user
********************************************************************/
-static BOOL api_samr_create_user(pipes_struct *p)
+static BOOL _api_samr_create_user(POLICY_HND dom_pol, UNISTR2 user_account, uint32 acb_info, uint32 access_mask,
+ POLICY_HND *user_pol, uint32 *unknown0, uint32 *user_rid)
{
struct sam_passwd *sam_pass;
fstring mach_acct;
pstring err_str;
pstring msg_str;
int local_flags=0;
+ DOM_SID sid;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- SAMR_Q_CREATE_USER q_u;
- SAMR_R_CREATE_USER r_u;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- DEBUG(5,("api_samr_create_user: %d\n", __LINE__));
-
- /* grab the samr create user */
- if (!samr_io_q_create_user("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_create_user: Unable to unmarshall SAMR_Q_CREATE_USER.\n"));
- return False;
- }
-
/* find the policy handle. open a policy on it. */
- if ((find_lsa_policy_by_hnd(&q_u.pol) == -1)) {
- r_u.status = NT_STATUS_INVALID_HANDLE;
- goto out;
- }
+ if (find_lsa_policy_by_hnd(&dom_pol) == -1)
+ return NT_STATUS_INVALID_HANDLE;
/* find the machine account: tell the caller if it exists.
lkclXXXX i have *no* idea if this is a problem or not
@@ -1867,7 +1845,7 @@ static BOOL api_samr_create_user(pipes_struct *p)
reply if the account already exists...
*/
- fstrcpy(mach_acct, dos_unistrn2(q_u.uni_mach_acct.buffer, q_u.uni_mach_acct.uni_str_len));
+ fstrcpy(mach_acct, dos_unistrn2(user_account.buffer, user_account.uni_str_len));
strlower(mach_acct);
become_root();
@@ -1875,18 +1853,15 @@ static BOOL api_samr_create_user(pipes_struct *p)
unbecome_root();
if (sam_pass != NULL) {
/* machine account exists: say so */
- r_u.status = NT_STATUS_USER_EXISTS;
- goto out;
+ return NT_STATUS_USER_EXISTS;
}
/* get a (unique) handle. open a policy on it. */
- if (!open_lsa_policy_hnd(&r_u.pol)) {
- r_u.status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- goto out;
- }
+ if (!open_lsa_policy_hnd(user_pol))
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD;
- local_flags|= (q_u.acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
+ local_flags|= (acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
/*
* NB. VERY IMPORTANT ! This call must be done as the current pipe user,
@@ -1897,10 +1872,8 @@ static BOOL api_samr_create_user(pipes_struct *p)
if (!local_password_change(mach_acct, local_flags, NULL, err_str, sizeof(err_str), msg_str, sizeof(msg_str))) {
DEBUG(0, ("%s\n", err_str));
- r_u.status = NT_STATUS_ACCESS_DENIED;
- close_lsa_policy_hnd(&r_u.pol);
- memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
- goto out;
+ close_lsa_policy_hnd(user_pol);
+ return NT_STATUS_ACCESS_DENIED;
}
become_root();
@@ -1908,31 +1881,62 @@ static BOOL api_samr_create_user(pipes_struct *p)
unbecome_root();
if (sam_pass == NULL) {
/* account doesn't exist: say so */
- r_u.status = NT_STATUS_ACCESS_DENIED;
- close_lsa_policy_hnd(&r_u.pol);
- memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
- goto out;
+ close_lsa_policy_hnd(user_pol);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* Get the domain SID stored in the domain policy */
+ if(!get_lsa_policy_samr_sid(&dom_pol, &sid)) {
+ close_lsa_policy_hnd(user_pol);
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* append the user's RID to it */
+ if(!sid_append_rid(&sid, sam_pass->user_rid)) {
+ close_lsa_policy_hnd(user_pol);
+ return NT_STATUS_NO_SUCH_USER;
}
/* associate the RID with the (unique) handle. */
- if (!set_lsa_policy_samr_rid(&r_u.pol, sam_pass->user_rid)) {
+ if (!set_lsa_policy_samr_sid(user_pol, &sid)) {
/* oh, whoops. don't know what error message to return, here */
- r_u.status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- close_lsa_policy_hnd(&r_u.pol);
- memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
- goto out;
+ close_lsa_policy_hnd(user_pol);
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ *unknown0=0x000703ff;
+ *user_rid=sam_pass->user_rid;
+
+ return NT_STATUS_NO_PROBLEMO;
+}
+
+/*******************************************************************
+ api_samr_create_user
+ ********************************************************************/
+static BOOL api_samr_create_user(pipes_struct *p)
+{
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ SAMR_Q_CREATE_USER q_u;
+ SAMR_R_CREATE_USER r_u;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ /* grab the samr create user */
+ if (!samr_io_q_create_user("", &q_u, data, 0)) {
+ DEBUG(0,("api_samr_create_user: Unable to unmarshall SAMR_Q_CREATE_USER.\n"));
+ return False;
}
- r_u.unknown_0=0x000703ff;
- r_u.user_rid=sam_pass->user_rid;
+ r_u.status=_api_samr_create_user(q_u.pol, q_u.uni_mach_acct, q_u.acb_info, q_u.access_mask,
+ &r_u.pol, &r_u.unknown_0, &r_u.user_rid);
- out:
/* store the response in the SMB stream */
if(!samr_io_r_create_user("", &r_u, rdata, 0))
return False;
- DEBUG(5,("api_samr_create_user: %d\n", __LINE__));
-
return True;
}
@@ -2146,67 +2150,406 @@ static BOOL api_samr_enum_domains(pipes_struct *p)
return True;
}
+
/*******************************************************************
- samr_reply_open_alias
+ api_samr_open_alias
********************************************************************/
-static BOOL samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u, prs_struct *rdata)
+static uint32 _api_samr_open_alias(POLICY_HND domain_pol, uint32 alias_rid, POLICY_HND *alias_pol)
{
- SAMR_R_OPEN_ALIAS r_u;
- BOOL pol_open = False;
-
- /* set up the SAMR open_alias response */
+ DOM_SID sid;
+
+ /* get the domain policy. */
+ if (!open_lsa_policy_hnd(&domain_pol))
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- r_u.status = 0x0;
/* get a (unique) handle. open a policy on it. */
- if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol))))
- {
- r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ if (!open_lsa_policy_hnd(alias_pol))
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+
+ /* Get the domain SID stored in the domain policy */
+ if(!get_lsa_policy_samr_sid(&domain_pol, &sid)) {
+ close_lsa_policy_hnd(alias_pol);
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* append the alias' RID to it */
+ if(!sid_append_rid(&sid, alias_rid)) {
+ close_lsa_policy_hnd(alias_pol);
+ return NT_STATUS_NO_SUCH_USER;
}
/* associate a RID with the (unique) handle. */
- if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
- {
+ if (!set_lsa_policy_samr_sid(alias_pol, &sid)) {
/* oh, whoops. don't know what error message to return, here */
- r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ close_lsa_policy_hnd(alias_pol);
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
- if (r_u.status != 0 && pol_open)
- {
- close_lsa_policy_hnd(&(r_u.pol));
- }
+ return NT_STATUS_NO_PROBLEMO;
+}
- DEBUG(5,("samr_open_alias: %d\n", __LINE__));
+/*******************************************************************
+ api_samr_open_alias
+ ********************************************************************/
+static BOOL api_samr_open_alias(pipes_struct *p)
+{
+ SAMR_Q_OPEN_ALIAS q_u;
+ SAMR_R_OPEN_ALIAS r_u;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ /* grab the samr open policy */
+ if(!samr_io_q_open_alias("", &q_u, data, 0))
+ return False;
+
+ r_u.status=_api_samr_open_alias(q_u.dom_pol, q_u.rid_alias, &r_u.pol);
/* store the response in the SMB stream */
if(!samr_io_r_open_alias("", &r_u, rdata, 0))
return False;
+
+ return True;
+}
+
+/*******************************************************************
+ set_user_info_10
+ ********************************************************************/
+static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
+{
+ struct sam_passwd *pwd = getsam21pwrid(rid);
+ struct sam_passwd new_pwd;
+
+ if (id10 == NULL) {
+ DEBUG(5, ("set_user_info_10: NULL id10\n"));
+ return False;
+ }
+
+ if (pwd == NULL)
+ return False;
+
+ copy_sam_passwd(&new_pwd, pwd);
+
+ new_pwd.acct_ctrl = id10->acb_info;
+
+ if(!mod_sam21pwd_entry(&new_pwd, True))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ set_user_info_12
+ ********************************************************************/
+static BOOL set_user_info_12(const SAM_USER_INFO_12 *id12, uint32 rid)
+{
+ struct sam_passwd *pwd = getsam21pwrid(rid);
+ struct sam_passwd new_pwd;
+ static uchar nt_hash[16];
+ static uchar lm_hash[16];
+
+ if (pwd == NULL)
+ return False;
+
+ if (id12 == NULL) {
+ DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
+ return False;
+ }
+
+ pdb_init_sam(&new_pwd);
+ copy_sam_passwd(&new_pwd, pwd);
+
+ memcpy(nt_hash, id12->nt_pwd, sizeof(nt_hash));
+ memcpy(lm_hash, id12->lm_pwd, sizeof(lm_hash));
+
+ new_pwd.smb_passwd = lm_hash;
+ new_pwd.smb_nt_passwd = nt_hash;
+
+ if(!mod_sam21pwd_entry(&new_pwd, True))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ set_user_info_21
+ ********************************************************************/
+static BOOL set_user_info_21(SAM_USER_INFO_21 * id21, uint32 rid)
+{
+ struct sam_passwd *pwd = getsam21pwrid(rid);
+ struct sam_passwd new_pwd;
+ static uchar nt_hash[16];
+ static uchar lm_hash[16];
+
+ if (id21 == NULL) {
+ DEBUG(5, ("set_user_info_21: NULL id21\n"));
+ return False;
+ }
+
+ if (pwd == NULL)
+ return False;
+
+ pdb_init_sam(&new_pwd);
+ copy_sam_passwd(&new_pwd, pwd);
+ copy_id21_to_sam_passwd(&new_pwd, id21);
+
+ if (pwd->smb_nt_passwd != NULL) {
+ memcpy(nt_hash, pwd->smb_nt_passwd, 16);
+ new_pwd.smb_nt_passwd = nt_hash;
+ } else
+ new_pwd.smb_nt_passwd = NULL;
+
+ if (pwd->smb_nt_passwd != NULL) {
+ memcpy(lm_hash, pwd->smb_passwd, 16);
+ new_pwd.smb_passwd = lm_hash;
+ } else
+ new_pwd.smb_passwd = NULL;
+
+ if(!mod_sam21pwd_entry(&new_pwd, True))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ set_user_info_23
+ ********************************************************************/
+static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
+{
+ struct sam_passwd *pwd = getsam21pwrid(rid);
+ struct sam_passwd new_pwd;
+ static uchar nt_hash[16];
+ static uchar lm_hash[16];
+ pstring buf;
+ uint32 len;
+
+ if (id23 == NULL) {
+ DEBUG(5, ("set_user_info_23: NULL id23\n"));
+ return False;
+ }
+
+ if (pwd == NULL)
+ return False;
+
+ pdb_init_sam(&new_pwd);
+ copy_sam_passwd(&new_pwd, pwd);
+ copy_id23_to_sam_passwd(&new_pwd, id23);
- DEBUG(5,("samr_open_alias: %d\n", __LINE__));
+ if (!decode_pw_buffer(id23->pass, buf, 256, &len))
+ return False;
+
+ nt_lm_owf_gen(buf, nt_hash, lm_hash);
+
+ new_pwd.smb_passwd = lm_hash;
+ new_pwd.smb_nt_passwd = nt_hash;
+
+ if(!mod_sam21pwd_entry(&new_pwd, True))
+ return False;
return True;
}
/*******************************************************************
- api_samr_open_alias
+ set_user_info_24
********************************************************************/
-static BOOL api_samr_open_alias(pipes_struct *p)
+static BOOL set_user_info_24(const SAM_USER_INFO_24 *id24, uint32 rid)
{
- SAMR_Q_OPEN_ALIAS q_u;
+ struct sam_passwd *pwd = getsam21pwrid(rid);
+ struct sam_passwd new_pwd;
+ static uchar nt_hash[16];
+ static uchar lm_hash[16];
+ uint32 len;
+ pstring buf;
+
+ if (pwd == NULL)
+ return False;
+
+ pdb_init_sam(&new_pwd);
+ copy_sam_passwd(&new_pwd, pwd);
+
+ if (!decode_pw_buffer(id24->pass, buf, 256, &len))
+ return False;
+
+ nt_lm_owf_gen(buf, nt_hash, lm_hash);
+
+ new_pwd.smb_passwd = lm_hash;
+ new_pwd.smb_nt_passwd = nt_hash;
+
+ if(!mod_sam21pwd_entry(&new_pwd, True))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ samr_reply_set_userinfo
+ ********************************************************************/
+static uint32 _samr_set_userinfo(POLICY_HND *pol, uint16 switch_value, SAM_USERINFO_CTR *ctr, uint16 vuid)
+{
+ uint32 rid = 0x0;
+ DOM_SID sid;
+ user_struct *vuser = NULL;
+
+ DEBUG(5, ("samr_reply_set_userinfo: %d\n", __LINE__));
+
+ /* search for the handle */
+ if (find_lsa_policy_by_hnd(pol) == -1)
+ return NT_STATUS_INVALID_HANDLE;
+
+ if ((vuser = get_valid_user_struct(vuid)) == NULL)
+ return NT_STATUS_INVALID_HANDLE;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_lsa_policy_samr_sid(pol, &sid))
+ return NT_STATUS_INVALID_HANDLE;
+
+ sid_split_rid(&sid, &rid);
+
+ DEBUG(5, ("samr_reply_set_userinfo: rid:0x%x, level:%d\n", rid, switch_value));
+
+ if (ctr == NULL) {
+ DEBUG(5, ("samr_reply_set_userinfo: NULL info level\n"));
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+
+ /* ok! user info levels (lots: see MSDEV help), off we go... */
+ switch (switch_value) {
+ case 0x12:
+ if (!set_user_info_12(ctr->info.id12, rid))
+ return NT_STATUS_ACCESS_DENIED;
+ break;
+
+ case 24:
+ SamOEMhash(ctr->info.id24->pass, vuser->dc.sess_key, True);
+ if (!set_user_info_24(ctr->info.id24, rid))
+ return NT_STATUS_ACCESS_DENIED;
+ break;
+
+ case 23:
+ DEBUG(5, ("samr_reply_set_userinfo: sess key:[%s]\n", credstr(vuser->dc.sess_key)));
+ SamOEMhash(ctr->info.id23->pass, vuser->dc.sess_key, 1);
+ if (!set_user_info_23(ctr->info.id23, rid))
+ return NT_STATUS_ACCESS_DENIED;
+ break;
+
+ default:
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ api_samr_set_userinfo
+ ********************************************************************/
+static BOOL api_samr_set_userinfo(pipes_struct *p)
+{
+ SAMR_Q_SET_USERINFO q_u;
+ SAMR_R_SET_USERINFO r_u;
+
prs_struct *data = &p->in_data.data;
prs_struct *rdata = &p->out_data.rdata;
- /* grab the samr open policy */
- if(!samr_io_q_open_alias("", &q_u, data, 0))
+ SAM_USERINFO_CTR ctr;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ q_u.ctr = &ctr;
+
+ if (!samr_io_q_set_userinfo("", &q_u, data, 0))
return False;
- /* construct reply. always indicate success */
- if(!samr_reply_open_alias(&q_u, rdata))
+ r_u.status = _samr_set_userinfo(&q_u.pol, q_u.switch_value, &ctr, p->vuid);
+
+ free_samr_q_set_userinfo(&q_u);
+
+ if(!samr_io_r_set_userinfo("", &r_u, rdata, 0))
return False;
return True;
}
/*******************************************************************
+ samr_reply_set_userinfo2
+ ********************************************************************/
+static uint32 _samr_set_userinfo2(POLICY_HND *pol, uint16 switch_value, SAM_USERINFO_CTR *ctr)
+{
+ DOM_SID sid;
+ uint32 rid = 0x0;
+
+ DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
+
+ /* search for the handle */
+ if (find_lsa_policy_by_hnd(pol) == -1)
+ return NT_STATUS_INVALID_HANDLE;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_lsa_policy_samr_sid(pol, &sid))
+ return NT_STATUS_INVALID_HANDLE;
+
+ sid_split_rid(&sid, &rid);
+
+ DEBUG(5, ("samr_reply_set_userinfo2: rid:0x%x\n", rid));
+
+ if (ctr == NULL) {
+ DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+
+ ctr->switch_value = switch_value;
+
+ /* ok! user info levels (lots: see MSDEV help), off we go... */
+ switch (switch_value) {
+ case 21:
+ if (!set_user_info_21(ctr->info.id21, rid))
+ return NT_STATUS_ACCESS_DENIED;
+ break;
+ case 16:
+ if (!set_user_info_10(ctr->info.id10, rid))
+ return NT_STATUS_ACCESS_DENIED;
+ break;
+ default:
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ api_samr_set_userinfo2
+ ********************************************************************/
+static BOOL api_samr_set_userinfo2(pipes_struct *p)
+{
+ SAMR_Q_SET_USERINFO2 q_u;
+ SAMR_R_SET_USERINFO2 r_u;
+ SAM_USERINFO_CTR ctr;
+
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ q_u.ctr = &ctr;
+
+ if (!samr_io_q_set_userinfo2("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _samr_set_userinfo2(&q_u.pol, q_u.switch_value, &ctr);
+
+ free_samr_q_set_userinfo2(&q_u);
+
+ if(!samr_io_r_set_userinfo2("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+
+/*******************************************************************
array of \PIPE\samr operations
********************************************************************/
static struct api_struct api_samr_cmds [] =
@@ -2221,12 +2564,12 @@ 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_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
+ { "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 },
{ "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
{ "SAMR_CREATE_USER" , SAMR_CREATE_USER , api_samr_create_user },
- { "SAMR_UNKNOWN_12" , SAMR_UNKNOWN_12 , api_samr_unknown_12 },
+ { "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 },
{ "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
@@ -2235,6 +2578,8 @@ static struct api_struct api_samr_cmds [] =
{ "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c },
{ "SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain },
{ "SAMR_ENUM_DOMAINS" , SAMR_ENUM_DOMAINS , api_samr_enum_domains },
+ { "SAMR_SET_USERINFO" , SAMR_SET_USERINFO , api_samr_set_userinfo },
+ { "SAMR_SET_USERINFO2" , SAMR_SET_USERINFO2 , api_samr_set_userinfo2 },
{ NULL , 0 , NULL }
};