From 75c346e70c83f7386ecd2f10fe155c4a4dfd47de Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Sat, 7 Oct 2000 15:56:36 +0000 Subject: added samr_set_user_info and info_2. 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. (This used to be commit b655bc281fa183b1827a946ada1fcf500fb93aea) --- source3/include/proto.h | 31 +- source3/include/rpc_samr_old.h | 236 +++++++++++-- source3/libsmb/smbencrypt.c | 44 +++ source3/passdb/passdb.c | 209 ++++++++++++ source3/rpc_client/cli_samr.c | 12 +- source3/rpc_parse/parse_samr.c | 706 +++++++++++++++++++++++++++++++++++++-- source3/rpc_server/srv_lsa_hnd.c | 31 +- source3/rpc_server/srv_pipe.c | 2 +- source3/rpc_server/srv_samr.c | 687 +++++++++++++++++++++++++++---------- 9 files changed, 1697 insertions(+), 261 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index c1c1cd8e35..27fcb6a921 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -867,6 +867,8 @@ void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]); void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]); void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24); BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode); +BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd, + int new_pwrd_size, uint32 *new_pw_len); /*The following definitions come from libsmb/smberr.c */ @@ -1627,11 +1629,16 @@ struct sam_disp_info *getsamdisprid(uint32 rid); struct sam_passwd *getsam21pwent(void *vp); struct sam_passwd *getsam21pwnam(char *name); struct sam_passwd *getsam21pwrid(uint32 rid); +BOOL add_sam21pwd_entry(struct sam_passwd *pwd); +BOOL mod_sam21pwd_entry(struct sam_passwd *pwd, BOOL override); void pdb_init_smb(struct smb_passwd *user); void pdb_init_sam(struct sam_passwd *user); struct sam_disp_info *pdb_sam_to_dispinfo(struct sam_passwd *user); struct smb_passwd *pdb_sam_to_smb(struct sam_passwd *user); struct sam_passwd *pdb_smb_to_sam(struct smb_passwd *user); +void copy_id23_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_23 *from); +void copy_id21_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_21 *from); +void copy_sam_passwd(struct sam_passwd *to, const struct sam_passwd *from); char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length); uint16 pdb_decode_acct_ctrl(const char *p); time_t pdb_get_last_set_time(const char *p); @@ -2539,8 +2546,13 @@ BOOL samr_io_q_unknown_3(char *desc, SAMR_Q_UNKNOWN_3 *q_u, prs_struct *ps, int void init_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u, POLICY_HND *domain_pol, uint16 switch_value); BOOL samr_io_q_query_dom_info(char *desc, SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct *ps, int depth); +BOOL init_unk_info1(SAM_UNK_INFO_1 *u_1); void init_unk_info2(SAM_UNK_INFO_2 *u_2, char *domain, char *server); BOOL sam_io_unk_info2(char *desc, SAM_UNK_INFO_2 *u_2, prs_struct *ps, int depth); +BOOL init_unk_info3(SAM_UNK_INFO_3 * u_3); +BOOL init_unk_info6(SAM_UNK_INFO_6 * u_6); +BOOL init_unk_info7(SAM_UNK_INFO_7 *u_7); +BOOL init_unk_info12(SAM_UNK_INFO_12 * u_12); void init_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO *r_u, uint16 switch_value, SAM_UNK_CTR *ctr, uint32 status); @@ -2601,11 +2613,11 @@ BOOL samr_io_q_lookup_names(char *desc, SAMR_Q_LOOKUP_NAMES *q_u, prs_struct *p void init_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_u, uint32 num_rids, uint32 *rid, enum SID_NAME_USE *type, uint32 status); BOOL samr_io_r_lookup_names(char *desc, SAMR_R_LOOKUP_NAMES *r_u, prs_struct *ps, int depth); -BOOL samr_io_q_unknown_12(char *desc, SAMR_Q_UNKNOWN_12 *q_u, prs_struct *ps, int depth); -void init_samr_r_unknown_12(SAMR_R_UNKNOWN_12 *r_u, +BOOL samr_io_q_lookup_rids(char *desc, SAMR_Q_LOOKUP_RIDS *q_u, prs_struct *ps, int depth); +void init_samr_r_lookup_rids(SAMR_R_LOOKUP_RIDS *r_u, uint32 num_aliases, fstring *als_name, uint32 *num_als_usrs, uint32 status); -BOOL samr_io_r_unknown_12(char *desc, SAMR_R_UNKNOWN_12 *r_u, prs_struct *ps, int depth); +BOOL samr_io_r_lookup_rids(char *desc, SAMR_R_LOOKUP_RIDS *r_u, prs_struct *ps, int depth); void init_samr_q_open_user(SAMR_Q_OPEN_USER *q_u, POLICY_HND *pol, uint32 unk_0, uint32 rid); @@ -2672,9 +2684,9 @@ BOOL samr_io_q_connect_anon(char *desc, SAMR_Q_CONNECT_ANON *q_u, prs_struct *p BOOL samr_io_r_connect_anon(char *desc, SAMR_R_CONNECT_ANON *r_u, prs_struct *ps, int depth); void init_samr_q_open_alias(SAMR_Q_OPEN_ALIAS *q_u, uint32 unknown_0, uint32 rid); -BOOL samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, int depth); +BOOL samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, int depth); BOOL samr_io_r_open_alias(char *desc, SAMR_R_OPEN_ALIAS *r_u, prs_struct *ps, int depth); -void init_samr_q_unknown_12(SAMR_Q_UNKNOWN_12 *q_u, +void init_samr_q_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u, POLICY_HND *pol, uint32 rid, uint32 num_gids, uint32 *gid); void init_samr_q_unknown_21(SAMR_Q_UNKNOWN_21 *q_c, @@ -2707,6 +2719,14 @@ BOOL init_samr_r_enum_domains(SAMR_R_ENUM_DOMAINS * r_u, uint32 next_idx, fstring* domains, uint32 num_sam_entries); BOOL samr_io_r_enum_domains(char *desc, SAMR_R_ENUM_DOMAINS * r_u, prs_struct *ps, int depth); +void free_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr); +BOOL samr_io_q_set_userinfo(char *desc, SAMR_Q_SET_USERINFO *q_u, prs_struct *ps, int depth); +void free_samr_q_set_userinfo(SAMR_Q_SET_USERINFO * q_u); +BOOL samr_io_r_set_userinfo(char *desc, SAMR_R_SET_USERINFO *r_u, prs_struct *ps, int depth); +BOOL samr_io_q_set_userinfo2(char *desc, SAMR_Q_SET_USERINFO2 *q_u, prs_struct *ps, int depth); +void free_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u); +BOOL make_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 *r_u, uint32 status); +BOOL samr_io_r_set_userinfo2(char *desc, SAMR_R_SET_USERINFO2 *r_u, prs_struct *ps, int depth); #endif /*The following definitions come from rpc_parse/parse_sec.c */ @@ -3074,7 +3094,6 @@ BOOL api_ntlsa_rpc(pipes_struct *p); void init_lsa_policy_hnd(void); BOOL open_lsa_policy_hnd(POLICY_HND *hnd); int find_lsa_policy_by_hnd(POLICY_HND *hnd); -BOOL set_lsa_policy_samr_rid(POLICY_HND *hnd, uint32 rid); BOOL set_lsa_policy_samr_pol_status(POLICY_HND *hnd, uint32 pol_status); BOOL set_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid); BOOL get_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid); diff --git a/source3/include/rpc_samr_old.h b/source3/include/rpc_samr_old.h index 620f5bc628..656a9de434 100644 --- a/source3/include/rpc_samr_old.h +++ b/source3/include/rpc_samr_old.h @@ -77,32 +77,34 @@ SamrTestPrivateFunctionsUser ********************************************************************/ +#define SAMR_CONNECT_ANON 0x00 #define SAMR_CLOSE_HND 0x01 +#define SAMR_UNKNOWN_3 0x03 #define SAMR_LOOKUP_DOMAIN 0x05 #define SAMR_ENUM_DOMAINS 0x06 #define SAMR_OPEN_DOMAIN 0x07 #define SAMR_QUERY_DOMAIN_INFO 0x08 +#define SAMR_ENUM_DOM_USERS 0x0d +#define SAMR_ENUM_DOM_ALIASES 0x0f #define SAMR_LOOKUP_IDS 0x10 #define SAMR_LOOKUP_NAMES 0x11 -#define SAMR_UNKNOWN_3 0x03 -#define SAMR_QUERY_DISPINFO 0x28 +#define SAMR_LOOKUP_RIDS 0x12 +#define SAMR_OPEN_ALIAS 0x1b +#define SAMR_QUERY_ALIASINFO 0x1c +#define SAMR_UNKNOWN_21 0x21 #define SAMR_OPEN_USER 0x22 #define SAMR_QUERY_USERINFO 0x24 +#define SAMR_SET_USERINFO2 0x25 #define SAMR_QUERY_USERGROUPS 0x27 -#define SAMR_UNKNOWN_12 0x12 -#define SAMR_UNKNOWN_21 0x21 +#define SAMR_QUERY_DISPINFO 0x28 #define SAMR_UNKNOWN_2C 0x2c +#define SAMR_ENUM_DOM_GROUPS 0x30 #define SAMR_CREATE_USER 0x32 #define SAMR_UNKNOWN_34 0x34 #define SAMR_CHGPASSWD_USER 0x37 #define SAMR_UNKNOWN_38 0x38 #define SAMR_CONNECT 0x39 -#define SAMR_CONNECT_ANON 0x00 -#define SAMR_OPEN_ALIAS 0x1b -#define SAMR_QUERY_ALIASINFO 0x1c -#define SAMR_ENUM_DOM_USERS 0x0d -#define SAMR_ENUM_DOM_ALIASES 0x0f -#define SAMR_ENUM_DOM_GROUPS 0x30 +#define SAMR_SET_USERINFO 0x3A typedef struct logon_hours_info @@ -139,7 +141,7 @@ typedef struct sam_user_info_21 uint32 user_rid; /* Primary User ID */ uint32 group_rid; /* Primary Group ID */ - uint16 acb_info; /* account info (ACB_xxxx bit-mask) */ + uint32 acb_info; /* account info (ACB_xxxx bit-mask) */ /* uint8 pad[2] */ uint32 unknown_3; /* 0x00ff ffff */ @@ -351,6 +353,14 @@ typedef struct q_samr_query_domain_info } SAMR_Q_QUERY_DOMAIN_INFO; +typedef struct sam_unknown_info_1_inf +{ + uint8 padding[12]; /* 12 bytes zeros */ + uint32 unknown_1; /* 0x8000 0000 */ + uint32 unknown_2; /* 0x0000 0000 */ + +} SAM_UNK_INFO_1; + typedef struct sam_unkown_info_2_info { uint32 unknown_0; /* 0x0000 0000 */ @@ -382,13 +392,49 @@ typedef struct sam_unkown_info_2_info } SAM_UNK_INFO_2; +typedef struct sam_unknown_info_3_info +{ + uint32 unknown_0; /* 0x0000 0000 */ + uint32 unknown_1; /* 0x8000 0000 */ + +} SAM_UNK_INFO_3; + +typedef struct sam_unknown_info_6_info +{ + uint32 unknown_0; /* 0x0000 0000 */ + + uint32 ptr_0; /* pointer to unknown structure */ + uint8 padding[12]; /* 12 bytes zeros */ + +} SAM_UNK_INFO_6; + +typedef struct sam_unknown_info_7_info +{ + uint16 unknown_0; /* 0x0003 */ + +} SAM_UNK_INFO_7; + +typedef struct sam_unknown_info_12_inf +{ + uint32 unknown_0; /* 0xcf1d cc00 */ + uint32 unknown_1; /* 0xffff fffb */ + uint32 unknown_2; /* 0xcf1d cc00 */ + uint32 unknown_3; /* 0xffff fffb */ + + uint32 unknown_4; /* 0x8a88 0000 */ + +} SAM_UNK_INFO_12; typedef struct sam_unknown_ctr_info { union { + SAM_UNK_INFO_1 inf1; SAM_UNK_INFO_2 inf2; - + SAM_UNK_INFO_3 inf3; + SAM_UNK_INFO_6 inf6; + SAM_UNK_INFO_7 inf7; + SAM_UNK_INFO_12 inf12; } info; } SAM_UNK_CTR; @@ -896,12 +942,12 @@ typedef struct r_samr_lookup_names_info } SAMR_R_LOOKUP_NAMES; /**************************************************************************** -SAMR_Q_UNKNOWN_12 - do a conversion from RID groups to something. +SAMR_Q_LOOKUP_RIDS - do a conversion from RID groups to something. called to resolve domain RID groups. *****************************************************************************/ -/* SAMR_Q_UNKNOWN_12 */ -typedef struct q_samr_unknown_12_info +/* SAMR_Q_LOOKUP_RIDS */ +typedef struct q_samr_lookup_rids_info { POLICY_HND pol; /* policy handle */ @@ -912,17 +958,17 @@ typedef struct q_samr_unknown_12_info uint32 gid[MAX_LOOKUP_SIDS]; /* domain RIDs being looked up */ -} SAMR_Q_UNKNOWN_12; +} SAMR_Q_LOOKUP_RIDS; /**************************************************************************** -SAMR_R_UNKNOWN_12 - do a conversion from group RID to names +SAMR_R_LOOKUP_RIDS - do a conversion from group RID to names *****************************************************************************/ -/* SAMR_R_UNKNOWN_12 */ -typedef struct r_samr_unknown_12_info +/* SAMR_R_LOOKUP_RIDS */ +typedef struct r_samr_lookup_rids_info { - POLICY_HND pol; /* policy handle */ + POLICY_HND pol; /* policy handle */ uint32 num_aliases1; /* number of aliases being looked up */ uint32 ptr_aliases; /* pointer to aliases */ @@ -939,13 +985,13 @@ typedef struct r_samr_unknown_12_info uint32 status; -} SAMR_R_UNKNOWN_12; +} SAMR_R_LOOKUP_RIDS; /* SAMR_Q_OPEN_USER - probably an open */ typedef struct q_samr_open_user_info { - POLICY_HND domain_pol; /* policy handle */ + POLICY_HND domain_pol; /* policy handle */ uint32 unknown_0; /* 32 bit unknown - 0x02011b */ uint32 user_rid; /* user RID */ @@ -955,7 +1001,7 @@ typedef struct q_samr_open_user_info /* SAMR_R_OPEN_USER - probably an open */ typedef struct r_samr_open_user_info { - POLICY_HND user_pol; /* policy handle associated with unknown id */ + POLICY_HND user_pol; /* policy handle associated with unknown id */ uint32 status; /* return status */ } SAMR_R_OPEN_USER; @@ -964,7 +1010,7 @@ typedef struct r_samr_open_user_info /* SAMR_Q_UNKNOWN_13 - probably an open alias in domain */ typedef struct q_samr_unknown_13_info { - POLICY_HND alias_pol; /* policy handle */ + POLICY_HND alias_pol; /* policy handle */ uint16 unknown_1; /* 16 bit unknown - 0x0200 */ uint16 unknown_2; /* 16 bit unknown - 0x0000 */ @@ -975,7 +1021,7 @@ typedef struct q_samr_unknown_13_info /* SAMR_Q_UNKNOWN_21 - probably an open group in domain */ typedef struct q_samr_unknown_21_info { - POLICY_HND group_pol; /* policy handle */ + POLICY_HND group_pol; /* policy handle */ uint16 unknown_1; /* 16 bit unknown - 0x0477 */ uint16 unknown_2; /* 16 bit unknown - 0x0000 */ @@ -1011,6 +1057,7 @@ typedef struct r_samr_create_user_info /* SAMR_Q_OPEN_ALIAS - probably an open */ typedef struct q_samr_open_alias_info { + POLICY_HND dom_pol; /* policy handle */ uint32 unknown_0; /* 0x0000 0008 */ uint32 rid_alias; /* rid */ @@ -1127,5 +1174,144 @@ typedef struct r_samr_chgpasswd_user_info } SAMR_R_CHGPASSWD_USER; + +/* SAM_USER_INFO_7 */ +typedef struct sam_user_info_7 +{ + UNIHDR hdr_user_name; + UNISTR2 uni_user_name; + +} SAM_USER_INFO_7; + +/* SAM_USER_INFO_12 */ +typedef struct sam_user_info_12 +{ + uint8 lm_pwd[16]; /* lm user passwords */ + uint8 nt_pwd[16]; /* nt user passwords */ + + uint8 lm_pwd_active; + uint8 nt_pwd_active; + +} SAM_USER_INFO_12; + +/* SAM_USER_INFO_23 */ +typedef struct sam_user_info_23 +{ + /* TIMES MAY NOT IN RIGHT ORDER!!!! */ + NTTIME logon_time; /* logon time */ + NTTIME logoff_time; /* logoff time */ + NTTIME kickoff_time; /* kickoff time */ + NTTIME pass_last_set_time; /* password last set time */ + NTTIME pass_can_change_time; /* password can change time */ + NTTIME pass_must_change_time; /* password must change time */ + + UNIHDR hdr_user_name; /* NULL - user name unicode string header */ + UNIHDR hdr_full_name; /* user's full name unicode string header */ + UNIHDR hdr_home_dir; /* home directory unicode string header */ + UNIHDR hdr_dir_drive; /* home drive unicode string header */ + UNIHDR hdr_logon_script; /* logon script unicode string header */ + UNIHDR hdr_profile_path; /* profile path unicode string header */ + UNIHDR hdr_acct_desc ; /* user description */ + UNIHDR hdr_workstations; /* comma-separated workstations user can log in from */ + UNIHDR hdr_unknown_str ; /* don't know what this is, yet. */ + UNIHDR hdr_munged_dial ; /* munged path name and dial-back tel number */ + + uint8 lm_pwd[16]; /* lm user passwords */ + uint8 nt_pwd[16]; /* nt user passwords */ + + uint32 user_rid; /* Primary User ID */ + uint32 group_rid; /* Primary Group ID */ + + uint32 acb_info; /* account info (ACB_xxxx bit-mask) */ + + uint32 unknown_3; /* 0x09f8 27fa */ + + uint16 logon_divs; /* 0x0000 00a8 which is 168 which is num hrs in a week */ + /* uint8 pad[2] */ + uint32 ptr_logon_hrs; /* pointer to logon hours */ + + uint8 padding1[8]; + + uint32 unknown_5; /* 0x0001 0000 */ + + uint8 pass[516]; + + UNISTR2 uni_user_name; /* NULL - username unicode string */ + UNISTR2 uni_full_name; /* user's full name unicode string */ + UNISTR2 uni_home_dir; /* home directory unicode string */ + UNISTR2 uni_dir_drive; /* home directory drive unicode string */ + UNISTR2 uni_logon_script; /* logon script unicode string */ + UNISTR2 uni_profile_path; /* profile path unicode string */ + UNISTR2 uni_acct_desc ; /* user description unicode string */ + UNISTR2 uni_workstations; /* login from workstations unicode string */ + UNISTR2 uni_unknown_str ; /* don't know what this is, yet. */ + UNISTR2 uni_munged_dial ; /* munged path name and dial-back tel no */ + + uint32 unknown_6; /* 0x0000 04ec */ + uint32 padding4; + + LOGON_HRS logon_hrs; + +} SAM_USER_INFO_23; + +/* SAM_USER_INFO_24 */ +typedef struct sam_user_info_24 +{ + uint8 pass[516]; + uint16 unk_0; + +} SAM_USER_INFO_24; + +/* SAM_USERINFO_CTR - sam user info */ +typedef struct sam_userinfo_ctr_info +{ + uint16 switch_value; + union + { + SAM_USER_INFO_7 *id7; + SAM_USER_INFO_10 *id10; /* auth-level 0x10 */ + SAM_USER_INFO_11 *id11; /* auth-level 0x11 */ + SAM_USER_INFO_12 *id12; /* auth-level 0x12 */ + SAM_USER_INFO_21 *id21; /* auth-level 21 */ + SAM_USER_INFO_23 *id23; /* auth-level 0x17 */ + SAM_USER_INFO_24 *id24; /* auth-level 0x18 */ + void* id; /* to make typecasting easy */ + } info; + +} SAM_USERINFO_CTR; + +/* SAMR_Q_SET_USERINFO - set sam info */ +typedef struct q_samr_set_user_info +{ + POLICY_HND pol; /* policy handle associated with user */ + uint16 switch_value; + SAM_USERINFO_CTR *ctr; + +} SAMR_Q_SET_USERINFO; + +/* SAMR_R_SET_USERINFO - set sam info */ +typedef struct r_samr_set_user_info +{ + uint32 status; /* return status */ + +} SAMR_R_SET_USERINFO; + +/* SAMR_Q_SET_USERINFO2 - set sam info */ +typedef struct q_samr_set_user_info2 +{ + POLICY_HND pol; /* policy handle associated with user */ + uint16 switch_value; /* 0x0010 */ + + SAM_USERINFO_CTR *ctr; + +} SAMR_Q_SET_USERINFO2; + +/* SAMR_R_SET_USERINFO2 - set sam info */ +typedef struct r_samr_set_user_info2 +{ + uint32 status; /* return status */ + +} SAMR_R_SET_USERINFO2; + #endif /* _RPC_SAMR_H */ diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index b927e193dd..16f2493947 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -228,3 +228,47 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ return True; } +/*********************************************************** + decode a password buffer +************************************************************/ +BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd, + int new_pwrd_size, uint32 *new_pw_len) +{ + int uni_pw_len=0; + char *pw; + /* + Warning !!! : This function is called from some rpc call. + The password IN the buffer is a UNICODE string. + The password IN new_pwrd is an ASCII string + If you reuse that code somewhere else check first. + */ + + + /* + * The length of the new password is in the last 4 bytes of + * the data buffer. + */ + + *new_pw_len = IVAL(buffer, 512); + +#ifdef DEBUG_PASSWORD + dump_data(100, buffer, 516); +#endif + + if ((*new_pw_len) < 0 || (*new_pw_len) > new_pwrd_size - 1) { + DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", (*new_pw_len))); + return False; + } + + uni_pw_len = *new_pw_len; + *new_pw_len /= 2; + pw = dos_unistrn2((uint16 *)(&buffer[512 - uni_pw_len]), uni_pw_len); + memcpy(new_pwrd, pw, *new_pw_len + 1); + +#ifdef DEBUG_PASSWORD + dump_data(100, new_pwrd, (*new_pw_len)); +#endif + + return True; +} + diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index a05783ac36..8b2deb4af8 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -411,6 +411,23 @@ struct sam_passwd *getsam21pwrid(uint32 rid) return pdb_ops->getsam21pwrid(rid); } +/************************************************************************ + Routine to add a SAM entry to the smb passwd file. +*************************************************************************/ + +BOOL add_sam21pwd_entry(struct sam_passwd *pwd) +{ + return pdb_ops->add_sam21pwd_entry(pwd); +} + +/************************************************************************ + Routine to modify a SAM entry to the smb passwd file. +*************************************************************************/ + +BOOL mod_sam21pwd_entry(struct sam_passwd *pwd, BOOL override) +{ + return pdb_ops->mod_sam21pwd_entry(pwd, override); +} /********************************************************** ********************************************************** @@ -521,6 +538,198 @@ struct sam_passwd *pdb_smb_to_sam(struct smb_passwd *user) return &pw_buf; } +static void select_name(fstring *string, char **name, const UNISTR2 *from) +{ + if (from->buffer != 0) + { + unistr2_to_ascii(*string, from, sizeof(*string)); + *name = *string; + } +} + +/************************************************************* + copies a sam passwd. + **************************************************************/ +void copy_id23_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_23 *from) +{ + static fstring smb_name; + static fstring full_name; + static fstring home_dir; + static fstring dir_drive; + static fstring logon_script; + static fstring profile_path; + static fstring acct_desc; + static fstring workstations; + static fstring unknown_str; + static fstring munged_dial; + + if (from == NULL || to == NULL) return; + + to->logon_time = nt_time_to_unix(&from->logon_time); + to->logoff_time = nt_time_to_unix(&from->logoff_time); + to->kickoff_time = nt_time_to_unix(&from->kickoff_time); + to->pass_last_set_time = nt_time_to_unix(&from->pass_last_set_time); + to->pass_can_change_time = nt_time_to_unix(&from->pass_can_change_time); + to->pass_must_change_time = nt_time_to_unix(&from->pass_must_change_time); + + select_name(&smb_name , &to->smb_name , &from->uni_user_name ); + select_name(&full_name , &to->full_name , &from->uni_full_name ); + select_name(&home_dir , &to->home_dir , &from->uni_home_dir ); + select_name(&dir_drive , &to->dir_drive , &from->uni_dir_drive ); + select_name(&logon_script, &to->logon_script, &from->uni_logon_script); + select_name(&profile_path, &to->profile_path, &from->uni_profile_path); + select_name(&acct_desc , &to->acct_desc , &from->uni_acct_desc ); + select_name(&workstations, &to->workstations, &from->uni_workstations); + select_name(&unknown_str , &to->unknown_str , &from->uni_unknown_str ); + select_name(&munged_dial , &to->munged_dial , &from->uni_munged_dial ); + + to->smb_userid = (uid_t)-1; + to->smb_grpid = (gid_t)-1; + to->user_rid = from->user_rid; + to->group_rid = from->group_rid; + + to->smb_passwd = NULL; + to->smb_nt_passwd = NULL; + + to->acct_ctrl = from->acb_info; + to->unknown_3 = from->unknown_3; + + to->logon_divs = from->logon_divs; + to->hours_len = from->logon_hrs.len; + memcpy(to->hours, from->logon_hrs.hours, MAX_HOURS_LEN); + + to->unknown_5 = from->unknown_5; + to->unknown_6 = from->unknown_6; +} + +/************************************************************* + copies a sam passwd. + **************************************************************/ +void copy_id21_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_21 *from) +{ + static fstring smb_name; + static fstring full_name; + static fstring home_dir; + static fstring dir_drive; + static fstring logon_script; + static fstring profile_path; + static fstring acct_desc; + static fstring workstations; + static fstring unknown_str; + static fstring munged_dial; + + if (from == NULL || to == NULL) return; + + to->logon_time = nt_time_to_unix(&from->logon_time); + to->logoff_time = nt_time_to_unix(&from->logoff_time); + to->kickoff_time = nt_time_to_unix(&from->kickoff_time); + to->pass_last_set_time = nt_time_to_unix(&from->pass_last_set_time); + to->pass_can_change_time = nt_time_to_unix(&from->pass_can_change_time); + to->pass_must_change_time = nt_time_to_unix(&from->pass_must_change_time); + + select_name(&smb_name , &to->smb_name , &from->uni_user_name ); + select_name(&full_name , &to->full_name , &from->uni_full_name ); + select_name(&home_dir , &to->home_dir , &from->uni_home_dir ); + select_name(&dir_drive , &to->dir_drive , &from->uni_dir_drive ); + select_name(&logon_script, &to->logon_script, &from->uni_logon_script); + select_name(&profile_path, &to->profile_path, &from->uni_profile_path); + select_name(&acct_desc , &to->acct_desc , &from->uni_acct_desc ); + select_name(&workstations, &to->workstations, &from->uni_workstations); + select_name(&unknown_str , &to->unknown_str , &from->uni_unknown_str ); + select_name(&munged_dial , &to->munged_dial , &from->uni_munged_dial ); + + to->smb_userid = (uid_t)-1; + to->smb_grpid = (gid_t)-1; + to->user_rid = from->user_rid; + to->group_rid = from->group_rid; + + to->smb_passwd = NULL; + to->smb_nt_passwd = NULL; + + to->acct_ctrl = from->acb_info; + to->unknown_3 = from->unknown_3; + + to->logon_divs = from->logon_divs; + to->hours_len = from->logon_hrs.len; + memcpy(to->hours, from->logon_hrs.hours, MAX_HOURS_LEN); + + to->unknown_5 = from->unknown_5; + to->unknown_6 = from->unknown_6; +} + + +/************************************************************* + copies a sam passwd. + **************************************************************/ +void copy_sam_passwd(struct sam_passwd *to, const struct sam_passwd *from) +{ + static fstring smb_name=""; + static fstring unix_name=""; + static fstring full_name=""; + static fstring home_dir=""; + static fstring dir_drive=""; + static fstring logon_script=""; + static fstring profile_path=""; + static fstring acct_desc=""; + static fstring workstations=""; + static fstring unknown_str=""; + static fstring munged_dial=""; + + if (from == NULL || to == NULL) return; + + memcpy(to, from, sizeof(*from)); + + if (from->smb_name != NULL) { + fstrcpy(smb_name , from->smb_name); + to->smb_name = smb_name; + } + + if (from->full_name != NULL) { + fstrcpy(full_name, from->full_name); + to->full_name = full_name; + } + + if (from->home_dir != NULL) { + fstrcpy(home_dir , from->home_dir); + to->home_dir = home_dir; + } + + if (from->dir_drive != NULL) { + fstrcpy(dir_drive , from->dir_drive); + to->dir_drive = dir_drive; + } + + if (from->logon_script != NULL) { + fstrcpy(logon_script , from->logon_script); + to->logon_script = logon_script; + } + + if (from->profile_path != NULL) { + fstrcpy(profile_path , from->profile_path); + to->profile_path = profile_path; + } + + if (from->acct_desc != NULL) { + fstrcpy(acct_desc , from->acct_desc); + to->acct_desc = acct_desc; + } + + if (from->workstations != NULL) { + fstrcpy(workstations , from->workstations); + to->workstations = workstations; + } + + if (from->unknown_str != NULL) { + fstrcpy(unknown_str , from->unknown_str); + to->unknown_str = unknown_str; + } + + if (from->munged_dial != NULL) { + fstrcpy(munged_dial , from->munged_dial); + to->munged_dial = munged_dial; + } +} + /********************************************************** Encode the account control bits into a string. length = length of string to encode into (including terminating diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c index 521c42ce2c..dbc10f7682 100644 --- a/source3/rpc_client/cli_samr.c +++ b/source3/rpc_client/cli_samr.c @@ -552,8 +552,8 @@ BOOL do_samr_query_unknown_12(struct cli_state *cli, { prs_struct data; prs_struct rdata; - SAMR_Q_UNKNOWN_12 q_o; - SAMR_R_UNKNOWN_12 r_o; + SAMR_Q_LOOKUP_RIDS q_o; + SAMR_R_LOOKUP_RIDS r_o; if (pol == NULL || rid == 0 || num_gids == 0 || gids == NULL || num_aliases == NULL || als_names == NULL || num_als_users == NULL ) @@ -567,17 +567,17 @@ BOOL do_samr_query_unknown_12(struct cli_state *cli, DEBUG(4,("SAMR Query Unknown 12.\n")); /* store the parameters */ - init_samr_q_unknown_12(&q_o, pol, rid, num_gids, gids); + init_samr_q_lookup_rids(&q_o, pol, rid, num_gids, gids); /* turn parameters into data stream */ - if(!samr_io_q_unknown_12("", &q_o, &data, 0)) { + if(!samr_io_q_lookup_rids("", &q_o, &data, 0)) { prs_mem_free(&data); prs_mem_free(&rdata); return False; } /* send the data on \PIPE\ */ - if (!rpc_api_pipe_req(cli, SAMR_UNKNOWN_12, &data, &rdata)) { + if (!rpc_api_pipe_req(cli, SAMR_LOOKUP_RIDS, &data, &rdata)) { prs_mem_free(&data); prs_mem_free(&rdata); return False; @@ -585,7 +585,7 @@ BOOL do_samr_query_unknown_12(struct cli_state *cli, prs_mem_free(&data); - if(!samr_io_r_unknown_12("", &r_o, &rdata, 0)) { + if(!samr_io_r_lookup_rids("", &r_o, &rdata, 0)) { prs_mem_free(&rdata); return False; } diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index c6b219d382..0bd1c29710 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -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 diff --git a/source3/rpc_server/srv_lsa_hnd.c b/source3/rpc_server/srv_lsa_hnd.c index 5670178732..0782c8c4b2 100644 --- a/source3/rpc_server/srv_lsa_hnd.c +++ b/source3/rpc_server/srv_lsa_hnd.c @@ -32,16 +32,15 @@ extern int DEBUGLEVEL; struct reg_info { - /* for use by \PIPE\winreg */ + /* for use by \PIPE\winreg */ fstring name; /* name of registry key */ }; struct samr_info { - /* for use by the \PIPE\samr policy */ + /* for use by the \PIPE\samr policy */ DOM_SID sid; - uint32 rid; /* relative id associated with the pol_hnd */ - uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */ + uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */ }; static struct policy @@ -162,25 +161,6 @@ int find_lsa_policy_by_hnd(POLICY_HND *hnd) return p?p->pnum:-1; } -/**************************************************************************** - set samr rid -****************************************************************************/ -BOOL set_lsa_policy_samr_rid(POLICY_HND *hnd, uint32 rid) -{ - struct policy *p = find_lsa_policy(hnd); - - if (p && p->open) { - DEBUG(3,("Setting policy device rid=%x pnum=%x\n", - rid, p->pnum)); - - p->dev.samr.rid = rid; - return True; - } - - DEBUG(3,("Error setting policy rid=%x\n",rid)); - return False; -} - /**************************************************************************** set samr pol status. absolutely no idea what this is. @@ -230,8 +210,7 @@ BOOL get_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid) { struct policy *p = find_lsa_policy(hnd); - if (p != NULL && p->open) - { + if (p != NULL && p->open) { fstring sidstr; memcpy(sid, &p->dev.samr.sid, sizeof(*sid)); DEBUG(3,("Getting policy sid=%s pnum=%x\n", @@ -252,7 +231,7 @@ uint32 get_lsa_policy_samr_rid(POLICY_HND *hnd) struct policy *p = find_lsa_policy(hnd); if (p && p->open) { - uint32 rid = p->dev.samr.rid; + uint32 rid = p->dev.samr.sid.sub_auths[p->dev.samr.sid.num_auths-1]; DEBUG(3,("Getting policy device rid=%x pnum=%x\n", rid, p->pnum)); diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 44bca13c1a..01d9568477 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1195,7 +1195,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, /* do the actual command */ if(!api_rpc_cmds[fn_num].fn(p)) { - DEBUG(0,("api_rpcTNP: %s: failed.\n", rpc_name)); + DEBUG(0,("api_rpcTNP: %s: %s failed.\n", rpc_name, api_rpc_cmds[fn_num].name)); prs_mem_free(&p->out_data.rdata); return False; } diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c index 7891fc16dc..59a541abd9 100644 --- a/source3/rpc_server/srv_samr.c +++ b/source3/rpc_server/srv_samr.c @@ -1306,9 +1306,9 @@ static BOOL api_samr_unknown_38(pipes_struct *p) /******************************************************************* - samr_reply_unknown_12 + samr_reply_lookup_rids ********************************************************************/ -static BOOL samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u, +static BOOL samr_reply_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u, prs_struct *rdata) { fstring group_names[MAX_SAM_ENTRIES]; @@ -1316,9 +1316,9 @@ static BOOL samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u, uint32 status = 0; int num_gids = q_u->num_gids1; - SAMR_R_UNKNOWN_12 r_u; + SAMR_R_LOOKUP_RIDS r_u; - DEBUG(5,("samr_unknown_12: %d\n", __LINE__)); + DEBUG(5,("samr_reply_lookup_rids: %d\n", __LINE__)); /* find the policy handle. open a policy on it. */ if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1)) @@ -1332,7 +1332,7 @@ static BOOL samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u, if (num_gids > MAX_SAM_ENTRIES) { num_gids = MAX_SAM_ENTRIES; - DEBUG(5,("samr_unknown_12: truncating entries to %d\n", num_gids)); + DEBUG(5,("samr_reply_lookup_rids: truncating entries to %d\n", num_gids)); } for (i = 0; i < num_gids && status == 0; i++) @@ -1342,32 +1342,32 @@ static BOOL samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u, } } - init_samr_r_unknown_12(&r_u, num_gids, group_names, group_attrs, status); + init_samr_r_lookup_rids(&r_u, num_gids, group_names, group_attrs, status); /* store the response in the SMB stream */ - if(!samr_io_r_unknown_12("", &r_u, rdata, 0)) + if(!samr_io_r_lookup_rids("", &r_u, rdata, 0)) return False; - DEBUG(5,("samr_unknown_12: %d\n", __LINE__)); + DEBUG(5,("samr_reply_lookup_rids: %d\n", __LINE__)); return True; } /******************************************************************* - api_samr_unknown_12 + api_samr_lookup_rids ********************************************************************/ -static BOOL api_samr_unknown_12(pipes_struct *p) +static BOOL api_samr_lookup_rids(pipes_struct *p) { - SAMR_Q_UNKNOWN_12 q_u; + SAMR_Q_LOOKUP_RIDS q_u; prs_struct *data = &p->in_data.data; prs_struct *rdata = &p->out_data.rdata; /* grab the samr lookup names */ - if(!samr_io_q_unknown_12("", &q_u, data, 0)) + if(!samr_io_q_lookup_rids("", &q_u, data, 0)) return False; /* construct reply. always indicate success */ - if(!samr_reply_unknown_12(&q_u, rdata)) + if(!samr_reply_lookup_rids(&q_u, rdata)) return False; return True; @@ -1375,62 +1375,51 @@ static BOOL api_samr_unknown_12(pipes_struct *p) /******************************************************************* - samr_reply_open_user + _api_samr_open_user ********************************************************************/ -static BOOL samr_reply_open_user(SAMR_Q_OPEN_USER *q_u, prs_struct *rdata, int status) +static uint32 _api_samr_open_user(POLICY_HND domain_pol, uint32 user_rid, POLICY_HND *user_pol) { - SAMR_R_OPEN_USER r_u; struct sam_passwd *sam_pass; - BOOL pol_open = False; - - /* set up the SAMR open_user response */ - memset((char *)r_u.user_pol.data, '\0', POL_HND_SIZE); + DOM_SID sid; - r_u.status = 0x0; - - /* find the policy handle. open a policy on it. */ - if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1)) - { - r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE; - } + /* find the domain policy handle. */ + if (find_lsa_policy_by_hnd(&domain_pol) == -1) + return NT_STATUS_INVALID_HANDLE; /* get a (unique) handle. open a policy on it. */ - if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.user_pol)))) - { - r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND; - } + if (!open_lsa_policy_hnd(user_pol)) + return NT_STATUS_OBJECT_NAME_NOT_FOUND; become_root(); - sam_pass = getsam21pwrid(q_u->user_rid); + sam_pass = getsam21pwrid(user_rid); unbecome_root(); /* check that the RID exists in our domain. */ - if (r_u.status == 0x0 && sam_pass == NULL) - { - r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER; + if (sam_pass == NULL) { + close_lsa_policy_hnd(user_pol); + return NT_STATUS_NO_SUCH_USER; } - - /* associate the RID with the (unique) handle. */ - if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.user_pol), q_u->user_rid)) - { - /* oh, whoops. don't know what error message to return, here */ - r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND; + + /* Get the domain SID stored in the domain policy */ + if(!get_lsa_policy_samr_sid(&domain_pol, &sid)) { + close_lsa_policy_hnd(user_pol); + return NT_STATUS_INVALID_HANDLE; } - if (r_u.status != 0 && pol_open) - { - close_lsa_policy_hnd(&(r_u.user_pol)); + /* append the user's RID to it */ + if(!sid_append_rid(&sid, user_rid)) { + close_lsa_policy_hnd(user_pol); + return NT_STATUS_NO_SUCH_USER; } - DEBUG(5,("samr_open_user: %d\n", __LINE__)); - - /* store the response in the SMB stream */ - if(!samr_io_r_open_user("", &r_u, rdata, 0)) - return False; - - DEBUG(5,("samr_open_user: %d\n", __LINE__)); + /* associate the user's SID with the handle. */ + if (!set_lsa_policy_samr_sid(user_pol, &sid)) { + /* oh, whoops. don't know what error message to return, here */ + close_lsa_policy_hnd(user_pol); + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } - return True; + return NT_STATUS_NO_PROBLEMO; } /******************************************************************* @@ -1439,21 +1428,28 @@ static BOOL samr_reply_open_user(SAMR_Q_OPEN_USER *q_u, prs_struct *rdata, int s static BOOL api_samr_open_user(pipes_struct *p) { SAMR_Q_OPEN_USER q_u; + SAMR_R_OPEN_USER r_u; prs_struct *data = &p->in_data.data; prs_struct *rdata = &p->out_data.rdata; + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + /* grab the samr unknown 22 */ if(!samr_io_q_open_user("", &q_u, data, 0)) return False; - /* construct reply. always indicate success */ - if(!samr_reply_open_user(&q_u, rdata, 0x0)) + r_u.status = _api_samr_open_user(q_u.domain_pol, q_u.user_rid, &r_u.user_pol); + + /* store the response in the SMB stream */ + if(!samr_io_r_open_user("", &r_u, rdata, 0)) return False; + DEBUG(5,("samr_open_user: %d\n", __LINE__)); + return True; } - /************************************************************************* get_user_info_10 *************************************************************************/ @@ -1753,45 +1749,64 @@ static BOOL api_samr_query_usergroups(pipes_struct *p) /******************************************************************* - samr_reply_query_dom_info + api_samr_query_dom_info ********************************************************************/ -static BOOL samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct *rdata) +static BOOL api_samr_query_dom_info(pipes_struct *p) { + SAMR_Q_QUERY_DOMAIN_INFO q_u; SAMR_R_QUERY_DOMAIN_INFO r_u; SAM_UNK_CTR ctr; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + uint16 switch_value = 0x0; uint32 status = 0x0; + ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); ZERO_STRUCT(ctr); - r_u.ctr = &ctr; + DEBUG(5,("api_samr_query_dom_info: %d\n", __LINE__)); - DEBUG(5,("samr_reply_query_dom_info: %d\n", __LINE__)); + /* grab the samr unknown 8 command */ + if(!samr_io_q_query_dom_info("", &q_u, data, 0)) + return False; /* find the policy handle. open a policy on it. */ - if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1)) - { - r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE; - DEBUG(5,("samr_reply_query_dom_info: invalid handle\n")); + if (find_lsa_policy_by_hnd(&q_u.domain_pol) == -1) { + status = NT_STATUS_INVALID_HANDLE; + DEBUG(5,("api_samr_query_dom_info: invalid handle\n")); } - if (status == 0x0) - { - switch (q_u->switch_value) - { + if (status == 0x0) { + switch (q_u.switch_value) { + case 0x01: + switch_value = 0x1; + init_unk_info1(&ctr.info.inf1); + break; case 0x02: - { switch_value = 0x2; init_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname); - break; - } + case 0x03: + switch_value = 0x3; + init_unk_info3(&ctr.info.inf3); + break; + case 0x06: + switch_value = 0x6; + init_unk_info6(&ctr.info.inf6); + break; + case 0x07: + switch_value = 0x7; + init_unk_info7(&ctr.info.inf7); + break; + case 0x0c: + switch_value = 0xc; + init_unk_info12(&ctr.info.inf12); + break; default: - { - status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS; + status = NT_STATUS_INVALID_INFO_CLASS; break; - } } } @@ -1801,65 +1816,28 @@ static BOOL samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct if(!samr_io_r_query_dom_info("", &r_u, rdata, 0)) return False; - DEBUG(5,("samr_query_dom_info: %d\n", __LINE__)); - - return True; -} - -/******************************************************************* - api_samr_query_dom_info - ********************************************************************/ -static BOOL api_samr_query_dom_info(pipes_struct *p) -{ - SAMR_Q_QUERY_DOMAIN_INFO q_e; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - /* grab the samr unknown 8 command */ - if(!samr_io_q_query_dom_info("", &q_e, data, 0)) - return False; - - /* construct reply. */ - if(!samr_reply_query_dom_info(&q_e, rdata)) - return False; + DEBUG(5,("api_samr_query_dom_info: %d\n", __LINE__)); return True; } /******************************************************************* - api_samr_create_user + _api_samr_create_user ********************************************************************/ -static BOOL api_samr_create_user(pipes_struct *p) +static BOOL _api_samr_create_user(POLICY_HND dom_pol, UNISTR2 user_account, uint32 acb_info, uint32 access_mask, + POLICY_HND *user_pol, uint32 *unknown0, uint32 *user_rid) { struct sam_passwd *sam_pass; fstring mach_acct; pstring err_str; pstring msg_str; int local_flags=0; + DOM_SID sid; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - SAMR_Q_CREATE_USER q_u; - SAMR_R_CREATE_USER r_u; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - DEBUG(5,("api_samr_create_user: %d\n", __LINE__)); - - /* grab the samr create user */ - if (!samr_io_q_create_user("", &q_u, data, 0)) { - DEBUG(0,("api_samr_create_user: Unable to unmarshall SAMR_Q_CREATE_USER.\n")); - return False; - } - /* find the policy handle. open a policy on it. */ - if ((find_lsa_policy_by_hnd(&q_u.pol) == -1)) { - r_u.status = NT_STATUS_INVALID_HANDLE; - goto out; - } + if (find_lsa_policy_by_hnd(&dom_pol) == -1) + return NT_STATUS_INVALID_HANDLE; /* find the machine account: tell the caller if it exists. lkclXXXX i have *no* idea if this is a problem or not @@ -1867,7 +1845,7 @@ static BOOL api_samr_create_user(pipes_struct *p) reply if the account already exists... */ - fstrcpy(mach_acct, dos_unistrn2(q_u.uni_mach_acct.buffer, q_u.uni_mach_acct.uni_str_len)); + fstrcpy(mach_acct, dos_unistrn2(user_account.buffer, user_account.uni_str_len)); strlower(mach_acct); become_root(); @@ -1875,18 +1853,15 @@ static BOOL api_samr_create_user(pipes_struct *p) unbecome_root(); if (sam_pass != NULL) { /* machine account exists: say so */ - r_u.status = NT_STATUS_USER_EXISTS; - goto out; + return NT_STATUS_USER_EXISTS; } /* get a (unique) handle. open a policy on it. */ - if (!open_lsa_policy_hnd(&r_u.pol)) { - r_u.status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - goto out; - } + if (!open_lsa_policy_hnd(user_pol)) + return NT_STATUS_OBJECT_NAME_NOT_FOUND; local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD; - local_flags|= (q_u.acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0; + local_flags|= (acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0; /* * NB. VERY IMPORTANT ! This call must be done as the current pipe user, @@ -1897,10 +1872,8 @@ static BOOL api_samr_create_user(pipes_struct *p) if (!local_password_change(mach_acct, local_flags, NULL, err_str, sizeof(err_str), msg_str, sizeof(msg_str))) { DEBUG(0, ("%s\n", err_str)); - r_u.status = NT_STATUS_ACCESS_DENIED; - close_lsa_policy_hnd(&r_u.pol); - memset((char *)r_u.pol.data, '\0', POL_HND_SIZE); - goto out; + close_lsa_policy_hnd(user_pol); + return NT_STATUS_ACCESS_DENIED; } become_root(); @@ -1908,31 +1881,62 @@ static BOOL api_samr_create_user(pipes_struct *p) unbecome_root(); if (sam_pass == NULL) { /* account doesn't exist: say so */ - r_u.status = NT_STATUS_ACCESS_DENIED; - close_lsa_policy_hnd(&r_u.pol); - memset((char *)r_u.pol.data, '\0', POL_HND_SIZE); - goto out; + close_lsa_policy_hnd(user_pol); + return NT_STATUS_ACCESS_DENIED; + } + + /* Get the domain SID stored in the domain policy */ + if(!get_lsa_policy_samr_sid(&dom_pol, &sid)) { + close_lsa_policy_hnd(user_pol); + return NT_STATUS_INVALID_HANDLE; + } + + /* append the user's RID to it */ + if(!sid_append_rid(&sid, sam_pass->user_rid)) { + close_lsa_policy_hnd(user_pol); + return NT_STATUS_NO_SUCH_USER; } /* associate the RID with the (unique) handle. */ - if (!set_lsa_policy_samr_rid(&r_u.pol, sam_pass->user_rid)) { + if (!set_lsa_policy_samr_sid(user_pol, &sid)) { /* oh, whoops. don't know what error message to return, here */ - r_u.status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - close_lsa_policy_hnd(&r_u.pol); - memset((char *)r_u.pol.data, '\0', POL_HND_SIZE); - goto out; + close_lsa_policy_hnd(user_pol); + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + *unknown0=0x000703ff; + *user_rid=sam_pass->user_rid; + + return NT_STATUS_NO_PROBLEMO; +} + +/******************************************************************* + api_samr_create_user + ********************************************************************/ +static BOOL api_samr_create_user(pipes_struct *p) +{ + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + SAMR_Q_CREATE_USER q_u; + SAMR_R_CREATE_USER r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + /* grab the samr create user */ + if (!samr_io_q_create_user("", &q_u, data, 0)) { + DEBUG(0,("api_samr_create_user: Unable to unmarshall SAMR_Q_CREATE_USER.\n")); + return False; } - r_u.unknown_0=0x000703ff; - r_u.user_rid=sam_pass->user_rid; + r_u.status=_api_samr_create_user(q_u.pol, q_u.uni_mach_acct, q_u.acb_info, q_u.access_mask, + &r_u.pol, &r_u.unknown_0, &r_u.user_rid); - out: /* store the response in the SMB stream */ if(!samr_io_r_create_user("", &r_u, rdata, 0)) return False; - DEBUG(5,("api_samr_create_user: %d\n", __LINE__)); - return True; } @@ -2146,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 } }; -- cgit