added samr_set_user_info and info_2.
authorJean-François Micouleau <jfm@samba.org>
Sat, 7 Oct 2000 15:56:36 +0000 (15:56 +0000)
committerJean-François Micouleau <jfm@samba.org>
Sat, 7 Oct 2000 15:56:36 +0000 (15:56 +0000)
cleanup of create_user
cleanup of rid/sid mix in samr. now we only have sid.

some prs_align() missing in parse_samr.c

a small debug change in srv_pipe.c

You still can't change a user's password in this commit.
Will be availble in the next one.

J.F.

source/include/proto.h
source/include/rpc_samr_old.h
source/libsmb/smbencrypt.c
source/passdb/passdb.c
source/rpc_client/cli_samr.c
source/rpc_parse/parse_samr.c
source/rpc_server/srv_lsa_hnd.c
source/rpc_server/srv_pipe.c
source/rpc_server/srv_samr.c

index c1c1cd8e3555bb02fc2129d6b69901cd560c39c0..27fcb6a921feafd46ed45a82599a30f2203e225c 100644 (file)
@@ -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);
index 620f5bc628752b21ef50edba4bd18b4779b01537..656a9de4340f664a300a6d4f4711461c637f8598 100644 (file)
@@ -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 */
 
index b927e193dd7485ad9c403ddb997af703f237bedd..16f24939471b95bca8ee0efdf48700f3b1691743 100644 (file)
@@ -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;
+}
+
index a05783ac36a0cba37434b18811608311c976e9d4..8b2deb4af8905bf7326678fa9389758540c2cea6 100644 (file)
@@ -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
index 521c42ce2cc6965c266fb84c7be9084cf72846f3..dbc10f7682c5ca2a5b23102d85292d1c7bdfacf3 100644 (file)
@@ -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;
        }
index c6b219d382d1046fc68cc38e1139b33163976213..0bd1c297108f2f8849a49b02b2c6b14d7957f4e4 100644 (file)
@@ -318,6 +318,46 @@ BOOL samr_io_q_query_dom_info(char *desc,  SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_st
        return True;
 }
 
+/*******************************************************************
+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;
 
@@ -413,6 +456,160 @@ BOOL sam_io_unk_info2(char *desc, SAM_UNK_INFO_2 *u_2, prs_struct *ps, int depth
        return True;
 }
 
+/*******************************************************************
+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 
index 5670178732a8cc7cbaa460b9b906be4064c3930c..0782c8c4b280313de5230251e632bf4f22f66be9 100644 (file)
@@ -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));
 
index 44bca13c1aefd2ad429f90685a4d4517a779fa33..01d956847737bec878c6652e4fe86d8872bdf50e 100644 (file)
@@ -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;
        }
index 7891fc16dc1ea6eb8e37b8ae742b0e01c8a292df..59a541abd9a806bfb9138a7468230280731473a3 100644 (file)
@@ -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,66 +2150,405 @@ 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
  ********************************************************************/
@@ -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                      }
 };