diff options
author | Matthew Chapman <matty@samba.org> | 1999-02-24 01:52:30 +0000 |
---|---|---|
committer | Matthew Chapman <matty@samba.org> | 1999-02-24 01:52:30 +0000 |
commit | 05f772b431f9c77a2fb37736fc4f801d84cac365 (patch) | |
tree | 12722ff39b9a869d85beb4aa228192c2a1fe110f | |
parent | 1e71ecdcb21f24e70ee5edbbc05de0284fa588f4 (diff) | |
download | samba-05f772b431f9c77a2fb37736fc4f801d84cac365.tar.gz samba-05f772b431f9c77a2fb37736fc4f801d84cac365.tar.bz2 samba-05f772b431f9c77a2fb37736fc4f801d84cac365.zip |
Win9x user level security.
* Added SAMR_LOOKUP_DOMAIN (-> SamrLookupDomainInSamServer)
* Added real SAMR_ENUM_DOM_GROUPS (corresponding to
SamrEnumerateGroupsInDomain). The existing one is just an alias for
SamrQueryDisplayInformation (see below).
* Added three extra info levels to SAMR_QUERY_DISPINFO. Info level 3 is
what was previously SAMR_ENUM_DOM_GROUPS; info levels 4 and 5 are
simple user/group list requests used by Win9x and I suspect (haven't
checked) the "low speed connection" User Manager.
* Added another two aliases for SAMR_QUERY_DISPINFO, opcodes 0x30 and
0x33. Usually the first is with info level 3 and the second 4 but there is
some overlap so indeed these should be implemented as just aliases.
* Return ERRDOS/ERRmoredata on extra data instead of
STATUS_BUFFER_OVERFLOW for Win95's benefit. On a named pipe this results
in an SMBreadX as usual.
Still need to fix SAMR_QUERY_DOMAIN_INFO which has a hard-coded number of
users and groups - which Win95 proceeds to truncate at.
(This used to be commit 7d03e6e21908f3a759a4e65c5edd850622335e3e)
-rw-r--r-- | source3/include/proto.h | 55 | ||||
-rw-r--r-- | source3/include/rpc_samr.h | 225 | ||||
-rw-r--r-- | source3/rpc_client/cli_samr.c | 78 | ||||
-rw-r--r-- | source3/rpc_parse/parse_samr.c | 802 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr.c | 223 | ||||
-rw-r--r-- | source3/rpcclient/cmd_samr.c | 138 | ||||
-rw-r--r-- | source3/smbd/ipc.c | 4 |
7 files changed, 1096 insertions, 429 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index edc087be3f..f31d178842 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1731,6 +1731,9 @@ BOOL samr_set_groupinfo(struct cli_state *cli, uint16 fnum, BOOL samr_open_domain(struct cli_state *cli, uint16 fnum, POLICY_HND *connect_pol, uint32 flags, DOM_SID *sid, POLICY_HND *domain_pol); +BOOL samr_query_lookup_domain(struct cli_state *cli, uint16 fnum, + POLICY_HND *pol, const char *dom_name, + DOM_SID *dom_sid); BOOL samr_query_lookup_names(struct cli_state *cli, uint16 fnum, POLICY_HND *pol, uint32 flags, uint32 num_names, const char **names, @@ -2160,6 +2163,10 @@ void smb_io_rpc_auth_ntlmssp_chk(char *desc, RPC_AUTH_NTLMSSP_CHK *chk, prs_stru void make_samr_q_close_hnd(SAMR_Q_CLOSE_HND *q_c, POLICY_HND *hnd); void samr_io_q_close_hnd(char *desc, SAMR_Q_CLOSE_HND *q_u, prs_struct *ps, int depth); void samr_io_r_close_hnd(char *desc, SAMR_R_CLOSE_HND *r_u, prs_struct *ps, int depth); +void make_samr_q_lookup_domain(SAMR_Q_LOOKUP_DOMAIN *q_u, + POLICY_HND *pol, const char *dom_name); +void samr_io_q_lookup_domain(char *desc, SAMR_Q_LOOKUP_DOMAIN *q_u, prs_struct *ps, int depth); +void samr_io_r_lookup_domain(char *desc, SAMR_R_LOOKUP_DOMAIN *r_u, prs_struct *ps, int depth); void make_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN *q_u, POLICY_HND *connect_pol, uint32 flags, DOM_SID *sid); @@ -2201,17 +2208,29 @@ void make_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS *r_u, uint32 num_sam_entries, SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES], uint32 status); void samr_io_r_enum_dom_users(char *desc, SAMR_R_ENUM_DOM_USERS *r_u, prs_struct *ps, int depth); void make_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_e, POLICY_HND *pol, - uint16 switch_level, uint32 start_idx, uint32 size); + uint16 switch_level, uint32 start_idx, + uint32 max_entries); void samr_io_q_query_dispinfo(char *desc, SAMR_Q_QUERY_DISPINFO *q_e, prs_struct *ps, int depth); -void make_sam_info_2(SAM_INFO_2 *sam, uint32 acb_mask, - uint32 start_idx, uint32 num_sam_entries, - SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]); -void make_sam_info_1(SAM_INFO_1 *sam, uint32 acb_mask, - uint32 start_idx, uint32 num_sam_entries, - SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]); +void make_sam_dispinfo_1(SAM_DISPINFO_1 *sam, uint32 *num_entries, + uint32 *data_size, uint32 start_idx, + SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]); +void make_sam_dispinfo_2(SAM_DISPINFO_2 *sam, uint32 *num_entries, + uint32 *data_size, uint32 start_idx, + SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]); +void make_sam_dispinfo_3(SAM_DISPINFO_3 *sam, uint32 *num_entries, + uint32 *data_size, uint32 start_idx, + DOMAIN_GRP *grp); +void make_sam_dispinfo_4(SAM_DISPINFO_4 *sam, uint32 *num_entries, + uint32 *data_size, uint32 start_idx, + SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]); +void make_sam_dispinfo_5(SAM_DISPINFO_5 *sam, uint32 *num_entries, + uint32 *data_size, uint32 start_idx, + DOMAIN_GRP *grp); void make_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO *r_u, - uint16 switch_level, SAM_INFO_CTR *ctr, uint32 status); -void samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO *r_u, prs_struct *ps, int depth); + uint32 num_entries, uint32 data_size, + uint16 switch_level, SAM_DISPINFO_CTR *ctr, + uint32 status); +void samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO *r_u, prs_struct *ps, int depth); void make_samr_q_open_group(SAMR_Q_OPEN_GROUP *q_c, POLICY_HND *hnd, uint32 unk, uint32 rid); void samr_io_q_open_group(char *desc, SAMR_Q_OPEN_GROUP *q_u, prs_struct *ps, int depth); @@ -2266,20 +2285,18 @@ void samr_io_q_query_groupmem(char *desc, SAMR_Q_QUERY_GROUPMEM *q_u, prs_struc void make_samr_r_query_groupmem(SAMR_R_QUERY_GROUPMEM *r_u, uint32 num_entries, uint32 *rid, uint32 *attr, uint32 status); void samr_io_r_query_groupmem(char *desc, SAMR_R_QUERY_GROUPMEM *r_u, prs_struct *ps, int depth); -void make_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_e, POLICY_HND *pol, - uint16 switch_level, uint32 start_idx, uint32 size); -void samr_io_q_enum_dom_groups(char *desc, SAMR_Q_ENUM_DOM_GROUPS *q_e, prs_struct *ps, int depth); -void make_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS *r_u, - uint32 start_idx, uint32 num_sam_entries, - DOMAIN_GRP *grp, - uint32 status); -void samr_io_r_enum_dom_groups(char *desc, SAMR_R_ENUM_DOM_GROUPS *r_u, prs_struct *ps, int depth); void make_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u, POLICY_HND *hnd); void samr_io_q_query_usergroups(char *desc, SAMR_Q_QUERY_USERGROUPS *q_u, prs_struct *ps, int depth); void make_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS *r_u, uint32 num_gids, DOM_GID *gid, uint32 status); void samr_io_r_query_usergroups(char *desc, SAMR_R_QUERY_USERGROUPS *r_u, prs_struct *ps, int depth); +void make_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_e, POLICY_HND *pol, uint32 size); +void samr_io_q_enum_dom_groups(char *desc, SAMR_Q_ENUM_DOM_GROUPS *q_e, prs_struct *ps, int depth); +void make_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS *r_u, + uint32 num_sam_entries, DOMAIN_GRP *grps, + uint32 status); +void samr_io_r_enum_dom_groups(char *desc, SAMR_R_ENUM_DOM_GROUPS *r_u, prs_struct *ps, int depth); void make_samr_q_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_e, POLICY_HND *pol, uint32 size); void samr_io_q_enum_dom_aliases(char *desc, SAMR_Q_ENUM_DOM_ALIASES *q_e, prs_struct *ps, int depth); void make_samr_r_enum_dom_aliases(SAMR_R_ENUM_DOM_ALIASES *r_u, @@ -2432,7 +2449,8 @@ void samr_io_r_chgpasswd_user(char *desc, SAMR_R_CHGPASSWD_USER *r_u, prs_struct void init_sec_access(SEC_ACCESS *t, uint32 mask); BOOL sec_io_access(char *desc, SEC_ACCESS *t, prs_struct *ps, int depth); -void init_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag); +void init_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, + uint8 flag); BOOL sec_io_ace(char *desc, SEC_ACE *psa, prs_struct *ps, int depth); void free_sec_acl(SEC_ACL **ppsa); BOOL sec_io_acl(char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth); @@ -2696,6 +2714,7 @@ void cmd_reg_shutdown(struct client_info *info); void cmd_sam_ntchange_pwd(struct client_info *info); void cmd_sam_test(struct client_info *info); +void cmd_sam_lookup_domain(struct client_info *info); void cmd_sam_del_aliasmem(struct client_info *info); void cmd_sam_delete_dom_alias(struct client_info *info); void cmd_sam_add_aliasmem(struct client_info *info); diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h index d70702f8a6..ea6a1f7919 100644 --- a/source3/include/rpc_samr.h +++ b/source3/include/rpc_samr.h @@ -81,11 +81,13 @@ SamrTestPrivateFunctionsUser #define SAMR_CLOSE_HND 0x01 #define SAMR_UNKNOWN_3 0x03 +#define SAMR_LOOKUP_DOMAIN 0x05 #define SAMR_OPEN_DOMAIN 0x07 #define SAMR_QUERY_DOMAIN_INFO 0x08 #define SAMR_CREATE_DOM_GROUP 0x0a +#define SAMR_ENUM_DOM_GROUPS 0x0b #define SAMR_ENUM_DOM_USERS 0x0d #define SAMR_CREATE_DOM_ALIAS 0x0e #define SAMR_ENUM_DOM_ALIASES 0x0f @@ -117,8 +119,11 @@ SamrTestPrivateFunctionsUser #define SAMR_QUERY_DISPINFO 0x28 #define SAMR_UNKNOWN_2C 0x2c -#define SAMR_ENUM_DOM_GROUPS 0x30 +#define SAMR_QUERY_DISPINFO3 0x30 /* Alias for SAMR_QUERY_DISPINFO + with info level 3 */ #define SAMR_UNKNOWN_32 0x32 +#define SAMR_QUERY_DISPINFO4 0x33 /* Alias for SAMR_QUERY_DISPINFO + with info level 4 */ #define SAMR_UNKNOWN_34 0x34 #define SAMR_CHGPASSWD_USER 0x37 @@ -446,6 +451,28 @@ typedef struct r_samr_query_domain_info } SAMR_R_QUERY_DOMAIN_INFO; +/* SAMR_Q_LOOKUP_DOMAIN - obtain SID for a local domain */ +typedef struct q_samr_lookup_domain_info +{ + POLICY_HND connect_pol; + + UNIHDR hdr_domain; + UNISTR2 uni_domain; + +} SAMR_Q_LOOKUP_DOMAIN; + + +/* SAMR_R_LOOKUP_DOMAIN */ +typedef struct r_samr_lookup_domain_info +{ + uint32 ptr_sid; + DOM_SID2 dom_sid; + + uint32 status; + +} SAMR_R_LOOKUP_DOMAIN; + + /**************************************************************************** SAMR_Q_OPEN_DOMAIN - unknown_0 values seen associated with SIDs: @@ -481,6 +508,7 @@ typedef struct samr_entry_info } SAM_ENTRY; + /* SAMR_Q_ENUM_DOM_USERS - SAM rids and names */ typedef struct q_samr_enum_dom_users_info { @@ -516,37 +544,15 @@ typedef struct r_samr_enum_dom_users_info } SAMR_R_ENUM_DOM_USERS; -typedef struct samr_entry_info3 -{ - uint32 grp_idx; - - uint32 rid_grp; - uint32 attr; - - UNIHDR hdr_grp_name; - UNIHDR hdr_grp_desc; - -} SAM_ENTRY3; - -typedef struct samr_str_entry_info3 -{ - UNISTR2 uni_grp_name; - UNISTR2 uni_grp_desc; - -} SAM_STR3; - /* SAMR_Q_ENUM_DOM_GROUPS - SAM rids and names */ typedef struct q_samr_enum_dom_groups_info { POLICY_HND pol; /* policy handle */ - /* these are possibly an enumeration context handle... */ - uint16 switch_level; /* 0x0003 */ - uint16 unknown_0; /* 0x0000 */ - uint32 start_idx; /* presumably the start enumeration index */ - uint32 unknown_1; /* 0x0000 07d0 */ + /* this is possibly an enumeration context handle... */ + uint32 unknown_0; /* 0x0000 0000 */ - uint32 max_size; /* 0x0000 7fff */ + uint32 max_size; /* 0x0000 ffff */ } SAMR_Q_ENUM_DOM_GROUPS; @@ -554,24 +560,24 @@ typedef struct q_samr_enum_dom_groups_info /* SAMR_R_ENUM_DOM_GROUPS - SAM rids and names */ typedef struct r_samr_enum_dom_groups_info { - uint32 unknown_0; /* 0x0000 0492 or 0x0000 00be */ - uint32 unknown_1; /* 0x0000 049a or 0x0000 00be */ - uint32 switch_level; /* 0x0000 0003 */ - uint32 num_entries; uint32 ptr_entries; uint32 num_entries2; + uint32 ptr_entries2; - SAM_ENTRY3 sam[MAX_SAM_ENTRIES]; - SAM_STR3 str[MAX_SAM_ENTRIES]; + uint32 num_entries3; + + SAM_ENTRY sam[MAX_SAM_ENTRIES]; + UNISTR2 uni_grp_name[MAX_SAM_ENTRIES]; + + uint32 num_entries4; uint32 status; } SAMR_R_ENUM_DOM_GROUPS; - /* SAMR_Q_ENUM_DOM_ALIASES - SAM rids and names */ typedef struct q_samr_enum_dom_aliases_info { @@ -584,6 +590,7 @@ typedef struct q_samr_enum_dom_aliases_info } SAMR_Q_ENUM_DOM_ALIASES; + /* SAMR_R_ENUM_DOM_ALIASES - SAM rids and names */ typedef struct r_samr_enum_dom_aliases_info { @@ -605,20 +612,7 @@ typedef struct r_samr_enum_dom_aliases_info } SAMR_R_ENUM_DOM_ALIASES; - -/* SAMR_Q_QUERY_DISPINFO - SAM rids, names and descriptions */ -typedef struct q_samr_query_disp_info -{ - POLICY_HND pol; /* policy handle */ - - uint16 switch_level; /* 0x0001 and 0x0002 seen */ - uint16 unknown_0; /* 0x0000 and 0x2000 seen */ - uint32 start_idx; /* presumably the start enumeration index */ - uint32 unknown_1; /* 0x0000 07d0, 0x0000 0400 and 0x0000 0200 seen */ - - uint32 max_size; /* 0x0000 7fff, 0x0000 7ffe and 0x0000 3fff seen*/ - -} SAMR_Q_QUERY_DISPINFO; +/* -- Level 1 Display Info - User Information -- */ typedef struct samr_entry_info1 { @@ -644,15 +638,13 @@ typedef struct samr_str_entry_info1 typedef struct sam_entry_info_1 { - uint32 num_entries; - uint32 ptr_entries; - uint32 num_entries2; - SAM_ENTRY1 sam[MAX_SAM_ENTRIES]; SAM_STR1 str[MAX_SAM_ENTRIES]; +} SAM_DISPINFO_1; -} SAM_INFO_1; + +/* -- Level 2 Display Info - Trust Account Information -- */ typedef struct samr_entry_info2 { @@ -676,36 +668,135 @@ typedef struct samr_str_entry_info2 typedef struct sam_entry_info_2 { - uint32 num_entries; - uint32 ptr_entries; - uint32 num_entries2; - SAM_ENTRY2 sam[MAX_SAM_ENTRIES]; SAM_STR2 str[MAX_SAM_ENTRIES]; -} SAM_INFO_2; +} SAM_DISPINFO_2; + -typedef struct sam_info_ctr_info +/* -- Level 3 Display Info - Domain Group Information -- */ + +typedef struct samr_entry_info3 +{ + uint32 grp_idx; + + uint32 rid_grp; + uint32 attr; /* SE_GROUP_xxx, usually 7 */ + + UNIHDR hdr_grp_name; + UNIHDR hdr_grp_desc; + +} SAM_ENTRY3; + +typedef struct samr_str_entry_info3 +{ + UNISTR2 uni_grp_name; + UNISTR2 uni_grp_desc; + +} SAM_STR3; + +typedef struct sam_entry_info_3 +{ + SAM_ENTRY3 sam[MAX_SAM_ENTRIES]; + SAM_STR3 str[MAX_SAM_ENTRIES]; + +} SAM_DISPINFO_3; + + +/* -- Level 4 Display Info - User List (ASCII) -- */ + +typedef struct samr_entry_info4 +{ + uint32 user_idx; + STRHDR hdr_acct_name; + +} SAM_ENTRY4; + +typedef struct samr_str_entry_info4 +{ + STRING2 acct_name; + +} SAM_STR4; + +typedef struct sam_entry_info_4 +{ + SAM_ENTRY4 sam[MAX_SAM_ENTRIES]; + SAM_STR4 str[MAX_SAM_ENTRIES]; + +} SAM_DISPINFO_4; + + +/* -- Level 5 Display Info - Group List (ASCII) -- */ + +typedef struct samr_entry_info5 +{ + uint32 grp_idx; + STRHDR hdr_grp_name; + +} SAM_ENTRY5; + +typedef struct samr_str_entry_info5 +{ + STRING2 grp_name; + +} SAM_STR5; + +typedef struct sam_entry_info_5 +{ + SAM_ENTRY5 sam[MAX_SAM_ENTRIES]; + SAM_STR5 str[MAX_SAM_ENTRIES]; + +} SAM_DISPINFO_5; + + +typedef struct sam_dispinfo_ctr_info { union { - SAM_INFO_1 *info1; /* server info */ - SAM_INFO_2 *info2; /* user info */ + SAM_DISPINFO_1 *info1; /* users/names/descriptions */ + SAM_DISPINFO_2 *info2; /* trust accounts */ + SAM_DISPINFO_3 *info3; /* domain groups/descriptions */ + SAM_DISPINFO_4 *info4; /* user list (ASCII) - used by Win95 */ + SAM_DISPINFO_5 *info5; /* group list (ASCII) */ void *info; /* allows assignment without typecasting, */ } sam; -} SAM_INFO_CTR; +} SAM_DISPINFO_CTR; + + +/* SAMR_Q_QUERY_DISPINFO - SAM rids, names and descriptions */ +typedef struct q_samr_query_disp_info +{ + POLICY_HND domain_pol; + + uint16 switch_level; /* see SAM_DISPINFO_CTR above */ + /* align */ + + uint32 start_idx; /* start enumeration index */ + uint32 max_entries; /* maximum number of entries to return */ + uint32 max_size; /* recommended data size; if exceeded server + should return STATUS_MORE_ENTRIES */ -/* SAMR_R_QUERY_DISPINFO - SAM rids, names and descriptions */ +} SAMR_Q_QUERY_DISPINFO; + + +/* SAMR_R_QUERY_DISPINFO */ typedef struct r_samr_query_dispinfo_info { - uint32 unknown_0; /* container length? 0x0000 0492 or 0x0000 00be */ - uint32 unknown_1; /* container length? 0x0000 049a or 0x0000 00be */ - uint16 switch_level; /* 0x0001 or 0x0002 */ - /*uint8 pad[2] */ + uint32 total_size; /* total data size for all matching entries + (0 = uncalculated) */ + uint32 data_size; /* actual data size returned = size of SAM_ENTRY + structures + total length of strings */ + + uint16 switch_level; /* see SAM_DISPINFO_CTR above */ + /* align */ + + uint32 num_entries; /* number of entries returned */ + uint32 ptr_entries; + uint32 num_entries2; - SAM_INFO_CTR *ctr; + SAM_DISPINFO_CTR *ctr; uint32 status; diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c index 6791195e71..d95bd99eac 100644 --- a/source3/rpc_client/cli_samr.c +++ b/source3/rpc_client/cli_samr.c @@ -405,6 +405,7 @@ BOOL samr_chgpasswd_user(struct cli_state *cli, uint16 fnum, return valid_pwc; } + /**************************************************************************** do a SAMR unknown 0x38 command ****************************************************************************/ @@ -536,7 +537,7 @@ BOOL samr_enum_dom_groups(struct cli_state *cli, uint16 fnum, prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); /* store the parameters */ - make_samr_q_enum_dom_groups(&q_e, pol, 3, 0, size); + make_samr_q_enum_dom_groups(&q_e, pol, size); /* turn parameters into data stream */ samr_io_q_enum_dom_groups("", &q_e, &data, 0); @@ -561,13 +562,12 @@ BOOL samr_enum_dom_groups(struct cli_state *cli, uint16 fnum, { int i; int name_idx = 0; - int desc_idx = 0; *num_sam_groups = r_e.num_entries2; if (*num_sam_groups > MAX_SAM_ENTRIES) { *num_sam_groups = MAX_SAM_ENTRIES; - DEBUG(2,("samr_enum_dom_groups: sam user entries limited to %d\n", + DEBUG(2,("samr_enum_dom_groups: sam group entries limited to %d\n", *num_sam_groups)); } @@ -580,21 +580,16 @@ BOOL samr_enum_dom_groups(struct cli_state *cli, uint16 fnum, for (i = 0; i < *num_sam_groups; i++) { - (*sam)[i].rid = r_e.sam[i].rid_grp; + (*sam)[i].rid = r_e.sam[i].rid; (*sam)[i].acct_name[0] = 0; (*sam)[i].acct_desc[0] = 0; - if (r_e.sam[i].hdr_grp_name.buffer) + if (r_e.sam[i].hdr_name.buffer) { - unistr2_to_ascii((*sam)[i].acct_name, &r_e.str[name_idx].uni_grp_name, sizeof((*sam)[i].acct_name)-1); + unistr2_to_ascii((*sam)[i].acct_name, &r_e.uni_grp_name[name_idx], sizeof((*sam)[i].acct_name)-1); name_idx++; } - if (r_e.sam[i].hdr_grp_desc.buffer) - { - unistr2_to_ascii((*sam)[i].acct_desc, &r_e.str[name_idx].uni_grp_desc, sizeof((*sam)[i].acct_desc)-1); - desc_idx++; - } - DEBUG(5,("samr_enum_dom_groups: idx: %4d rid: %8x acct: %s desc: %s\n", - i, (*sam)[i].rid, (*sam)[i].acct_name, (*sam)[i].acct_desc)); + DEBUG(5,("samr_enum_dom_groups: idx: %4d rid: %8x acct: %s\n", + i, (*sam)[i].rid, (*sam)[i].acct_name)); } valid_pol = True; } @@ -1630,6 +1625,63 @@ BOOL samr_open_domain(struct cli_state *cli, uint16 fnum, } /**************************************************************************** +do a SAMR Query Lookup Domain +****************************************************************************/ +BOOL samr_query_lookup_domain(struct cli_state *cli, uint16 fnum, + POLICY_HND *pol, const char *dom_name, + DOM_SID *dom_sid) +{ + prs_struct data; + prs_struct rdata; + + SAMR_Q_LOOKUP_DOMAIN q_o; + BOOL valid_query = False; + + if (pol == NULL || dom_name == NULL || dom_sid == NULL) return False; + + /* create and send a MSRPC command with api SAMR_LOOKUP_DOMAIN */ + + prs_init(&data , 1024, 4, SAFETY_MARGIN, False); + prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); + + DEBUG(4,("SAMR Query Lookup Domain.\n")); + + /* store the parameters */ + make_samr_q_lookup_domain(&q_o, pol, dom_name); + + /* turn parameters into data stream */ + samr_io_q_lookup_domain("", &q_o, &data, 0); + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, fnum, SAMR_LOOKUP_DOMAIN, &data, &rdata)) + { + SAMR_R_LOOKUP_DOMAIN r_o; + BOOL p; + + samr_io_r_lookup_domain("", &r_o, &rdata, 0); + p = rdata.offset != 0; + + if (p && r_o.status != 0) + { + /* report error code */ + DEBUG(0,("SAMR_R_LOOKUP_DOMAIN: %s\n", get_nt_error_msg(r_o.status))); + p = False; + } + + if (p && r_o.ptr_sid != 0) + { + sid_copy(dom_sid, &r_o.dom_sid.sid); + valid_query = True; + } + } + + prs_mem_free(&data ); + prs_mem_free(&rdata ); + + return valid_query; +} + +/**************************************************************************** do a SAMR Query Lookup Names ****************************************************************************/ BOOL samr_query_lookup_names(struct cli_state *cli, uint16 fnum, diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index fb93925011..0e7c891b79 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -73,6 +73,66 @@ void samr_io_r_close_hnd(char *desc, SAMR_R_CLOSE_HND *r_u, prs_struct *ps, int prs_uint32("status", ps, depth, &(r_u->status)); } +/******************************************************************* +makes a SAMR_Q_LOOKUP_DOMAIN structure. +********************************************************************/ +void make_samr_q_lookup_domain(SAMR_Q_LOOKUP_DOMAIN *q_u, + POLICY_HND *pol, const char *dom_name) +{ + int len_name = strlen(dom_name); + + if (q_u == NULL) return; + + DEBUG(5,("make_samr_q_lookup_domain\n")); + + memcpy(&(q_u->connect_pol), pol, sizeof(*pol)); + + make_uni_hdr(&(q_u->hdr_domain), len_name, len_name, 1); + make_unistr2(&(q_u->uni_domain), dom_name, len_name); +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void samr_io_q_lookup_domain(char *desc, SAMR_Q_LOOKUP_DOMAIN *q_u, prs_struct *ps, int depth) +{ + if (q_u == NULL) return; + + prs_debug(ps, depth, desc, "samr_io_q_lookup_domain"); + depth++; + + prs_align(ps); + + smb_io_pol_hnd("connect_pol", &(q_u->connect_pol), ps, depth); + prs_align(ps); + + smb_io_unihdr("hdr_domain", &(q_u->hdr_domain), ps, depth); + smb_io_unistr2("uni_domain", &(q_u->uni_domain), + q_u->hdr_domain.buffer, ps, depth); +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void samr_io_r_lookup_domain(char *desc, SAMR_R_LOOKUP_DOMAIN *r_u, prs_struct *ps, int depth) +{ + if (r_u == NULL) return; + + prs_debug(ps, depth, desc, "samr_io_r_lookup_domain"); + depth++; + + prs_align(ps); + + prs_uint32("ptr", ps, depth, &(r_u->ptr_sid)); + + if (r_u->ptr_sid != 0) + { + smb_io_dom_sid2("sid", &(r_u->dom_sid), ps, depth); + prs_align(ps); + } + + prs_uint32("status", ps, depth, &(r_u->status)); +} /******************************************************************* reads or writes a structure. @@ -258,6 +318,7 @@ void samr_io_q_query_dom_info(char *desc, SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_st prs_align(ps); } + /******************************************************************* makes a structure. ********************************************************************/ @@ -839,6 +900,68 @@ static void sam_io_sam_entry3(char *desc, SAM_ENTRY3 *sam, prs_struct *ps, int } /******************************************************************* +makes a SAM_ENTRY4 structure. +********************************************************************/ +static void make_sam_entry4(SAM_ENTRY4 *sam, uint32 user_idx, + uint32 len_acct_name) +{ + if (sam == NULL) return; + + DEBUG(5,("make_sam_entry4\n")); + + sam->user_idx = user_idx; + make_str_hdr(&(sam->hdr_acct_name), len_acct_name, len_acct_name, + len_acct_name != 0); +} + +/******************************************************************* +reads or writes a SAM_ENTRY4 structure. +********************************************************************/ +static void sam_io_sam_entry4(char *desc, SAM_ENTRY4 *sam, prs_struct *ps, int depth) +{ + if (sam == NULL) return; + + prs_debug(ps, depth, desc, "sam_io_sam_entry4"); + depth++; + + prs_align(ps); + + prs_uint32("user_idx", ps, depth, &(sam->user_idx)); + smb_io_strhdr("strhdr", &(sam->hdr_acct_name), ps, depth); +} + +/******************************************************************* +makes a SAM_ENTRY5 structure. +********************************************************************/ +static void make_sam_entry5(SAM_ENTRY5 *sam, uint32 grp_idx, + uint32 len_grp_name) +{ + if (sam == NULL) return; + + DEBUG(5,("make_sam_entry5\n")); + + sam->grp_idx = grp_idx; + make_str_hdr(&(sam->hdr_grp_name), len_grp_name, len_grp_name, + len_grp_name != 0); +} + +/******************************************************************* +reads or writes a SAM_ENTRY5 structure. +********************************************************************/ +static void sam_io_sam_entry5(char *desc, SAM_ENTRY5 *sam, prs_struct *ps, int depth) +{ + if (sam == NULL) return; + + prs_debug(ps, depth, desc, "sam_io_sam_entry5"); + depth++; + + prs_align(ps); + + prs_uint32("grp_idx", ps, depth, &(sam->grp_idx)); + smb_io_strhdr("strhdr", &(sam->hdr_grp_name), ps, depth); +} + +/******************************************************************* makes a SAM_ENTRY structure. ********************************************************************/ static void make_sam_entry(SAM_ENTRY *sam, uint32 len_sam_name, uint32 rid) @@ -1015,20 +1138,20 @@ void samr_io_r_enum_dom_users(char *desc, SAMR_R_ENUM_DOM_USERS *r_u, prs_struc makes a SAMR_Q_QUERY_DISPINFO structure. ********************************************************************/ void make_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_e, POLICY_HND *pol, - uint16 switch_level, uint32 start_idx, uint32 size) + uint16 switch_level, uint32 start_idx, + uint32 max_entries) { if (q_e == NULL || pol == NULL) return; DEBUG(5,("make_samr_q_query_dispinfo\n")); - memcpy(&(q_e->pol), pol, sizeof(*pol)); + memcpy(&(q_e->domain_pol), pol, sizeof(*pol)); q_e->switch_level = switch_level; - q_e->unknown_0 = 0; q_e->start_idx = start_idx; - q_e->unknown_1 = 0x000007d0; - q_e->max_size = size; + q_e->max_entries = max_entries; + q_e->max_size = 0xffff; /* Not especially useful */ } /******************************************************************* @@ -1043,183 +1166,370 @@ void samr_io_q_query_dispinfo(char *desc, SAMR_Q_QUERY_DISPINFO *q_e, prs_struc prs_align(ps); - smb_io_pol_hnd("pol", &(q_e->pol), ps, depth); + smb_io_pol_hnd("domain_pol", &(q_e->domain_pol), ps, depth); prs_align(ps); prs_uint16("switch_level", ps, depth, &(q_e->switch_level)); - prs_uint16("unknown_0 ", ps, depth, &(q_e->unknown_0 )); + prs_align(ps); + prs_uint32("start_idx ", ps, depth, &(q_e->start_idx )); - prs_uint32("unknown_1 ", ps, depth, &(q_e->unknown_1 )); + prs_uint32("max_entries ", ps, depth, &(q_e->max_entries )); prs_uint32("max_size ", ps, depth, &(q_e->max_size )); - - prs_align(ps); } /******************************************************************* -makes a SAM_INFO_2 structure. +makes a SAM_DISPINFO_1 structure. ********************************************************************/ -void make_sam_info_2(SAM_INFO_2 *sam, uint32 acb_mask, - uint32 start_idx, uint32 num_sam_entries, - SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]) +void make_sam_dispinfo_1(SAM_DISPINFO_1 *sam, uint32 *num_entries, + uint32 *data_size, uint32 start_idx, + SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]) +{ + uint32 len_sam_name, len_sam_full, len_sam_desc; + uint32 max_entries, max_data_size; + uint32 dsize = 0; + int i; + + if (sam == NULL || num_entries == NULL || data_size == NULL) return; + + DEBUG(5,("make_sam_dispinfo_1\n")); + + max_entries = *num_entries; + max_data_size = *data_size; + + for (i = 0; (i < max_entries) && (dsize < max_data_size); i++) + { + len_sam_name = pass[i].uni_user_name.uni_str_len; + len_sam_full = pass[i].uni_full_name.uni_str_len; + len_sam_desc = pass[i].uni_acct_desc.uni_str_len; + + make_sam_entry1(&(sam->sam[i]), start_idx + i + 1, + len_sam_name, len_sam_full, len_sam_desc, + pass[i].user_rid, pass[i].acb_info); + + copy_unistr2(&(sam->str[i].uni_acct_name), &(pass[i].uni_user_name)); + copy_unistr2(&(sam->str[i].uni_full_name), &(pass[i].uni_full_name)); + copy_unistr2(&(sam->str[i].uni_acct_desc), &(pass[i].uni_acct_desc)); + + dsize += sizeof(SAM_ENTRY1); + dsize += len_sam_name + len_sam_full + len_sam_desc; + } + + *num_entries = i; + *data_size = dsize; +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +static void sam_io_sam_dispinfo_1(char *desc, SAM_DISPINFO_1 *sam, uint32 num_entries, prs_struct *ps, int depth) { int i; - int entries_added; if (sam == NULL) return; - DEBUG(5,("make_sam_info_2\n")); + prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_1"); + depth++; + + prs_align(ps); - if (num_sam_entries >= MAX_SAM_ENTRIES) + SMB_ASSERT_ARRAY(sam->sam, num_entries); + + for (i = 0; i < num_entries; i++) { - num_sam_entries = MAX_SAM_ENTRIES; - DEBUG(5,("limiting number of entries to %d\n", - num_sam_entries)); + prs_grow(ps); + sam_io_sam_entry1("", &(sam->sam[i]), ps, depth); } - for (i = start_idx, entries_added = 0; i < num_sam_entries; i++) + for (i = 0; i < num_entries; i++) { - if (IS_BITS_SET_ALL(pass[i].acb_info, acb_mask)) - { - make_sam_entry2(&(sam->sam[entries_added]), - start_idx + entries_added + 1, - pass[i].uni_user_name.uni_str_len, - pass[i].uni_acct_desc.uni_str_len, - pass[i].user_rid, - pass[i].acb_info); + prs_grow(ps); + sam_io_sam_str1 ("", &(sam->str[i]), + sam->sam[i].hdr_acct_name.buffer, + sam->sam[i].hdr_user_name.buffer, + sam->sam[i].hdr_user_desc.buffer, + ps, depth); + } +} - copy_unistr2(&(sam->str[entries_added].uni_srv_name), &(pass[i].uni_user_name)); - copy_unistr2(&(sam->str[entries_added].uni_srv_desc), &(pass[i].uni_acct_desc)); - entries_added++; - } +/******************************************************************* +makes a SAM_DISPINFO_2 structure. +********************************************************************/ +void make_sam_dispinfo_2(SAM_DISPINFO_2 *sam, uint32 *num_entries, + uint32 *data_size, uint32 start_idx, + SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]) +{ + uint32 len_sam_name, len_sam_desc; + uint32 max_entries, max_data_size; + uint32 dsize = 0; + int i; + + if (sam == NULL || num_entries == NULL || data_size == NULL) return; + + DEBUG(5,("make_sam_dispinfo_2\n")); + + max_entries = *num_entries; + max_data_size = *data_size; + + for (i = 0; (i < max_entries) && (dsize < max_data_size); i++) + { + len_sam_name = pass[i].uni_user_name.uni_str_len; + len_sam_desc = pass[i].uni_acct_desc.uni_str_len; - sam->num_entries = entries_added; - sam->ptr_entries = 1; - sam->num_entries2 = entries_added; + make_sam_entry2(&(sam->sam[i]), start_idx + i + 1, + len_sam_name, len_sam_desc, + pass[i].user_rid, pass[i].acb_info); + + copy_unistr2(&(sam->str[i].uni_srv_name), &(pass[i].uni_user_name)); + copy_unistr2(&(sam->str[i].uni_srv_desc), &(pass[i].uni_acct_desc)); + + dsize += sizeof(SAM_ENTRY2); + dsize += len_sam_name + len_sam_desc; } + + *num_entries = i; + *data_size = dsize; } /******************************************************************* reads or writes a structure. ********************************************************************/ -static void sam_io_sam_info_2(char *desc, SAM_INFO_2 *sam, prs_struct *ps, int depth) +static void sam_io_sam_dispinfo_2(char *desc, SAM_DISPINFO_2 *sam, uint32 num_entries, prs_struct *ps, int depth) { int i; if (sam == NULL) return; - prs_debug(ps, depth, desc, "sam_io_sam_info_2"); + prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_2"); depth++; prs_align(ps); - prs_uint32("num_entries ", ps, depth, &(sam->num_entries )); - prs_uint32("ptr_entries ", ps, depth, &(sam->ptr_entries )); - - prs_uint32("num_entries2 ", ps, depth, &(sam->num_entries2 )); + SMB_ASSERT_ARRAY(sam->sam, num_entries); - SMB_ASSERT_ARRAY(sam->sam, sam->num_entries); - - for (i = 0; i < sam->num_entries; i++) + for (i = 0; i < num_entries; i++) { prs_grow(ps); sam_io_sam_entry2("", &(sam->sam[i]), ps, depth); } - for (i = 0; i < sam->num_entries; i++) + for (i = 0; i < num_entries; i++) { prs_grow(ps); sam_io_sam_str2 ("", &(sam->str[i]), - sam->sam[i].hdr_srv_name.buffer, - sam->sam[i].hdr_srv_desc.buffer, - ps, depth); + sam->sam[i].hdr_srv_name.buffer, + sam->sam[i].hdr_srv_desc.buffer, + ps, depth); } } /******************************************************************* -makes a SAM_INFO_1 structure. +makes a SAM_DISPINFO_3 structure. ********************************************************************/ -void make_sam_info_1(SAM_INFO_1 *sam, uint32 acb_mask, - uint32 start_idx, uint32 num_sam_entries, - SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]) +void make_sam_dispinfo_3(SAM_DISPINFO_3 *sam, uint32 *num_entries, + uint32 *data_size, uint32 start_idx, + DOMAIN_GRP *grp) { + uint32 len_sam_name, len_sam_desc; + uint32 max_entries, max_data_size; + uint32 dsize = 0; int i; - int entries_added; - if (sam == NULL) return; + if (sam == NULL || num_entries == NULL || data_size == NULL) return; - DEBUG(5,("make_sam_info_1\n")); + DEBUG(5,("make_sam_dispinfo_3\n")); - if (num_sam_entries >= MAX_SAM_ENTRIES) + max_entries = *num_entries; + max_data_size = *data_size; + + for (i = 0; (i < max_entries) && (dsize < max_data_size); i++) { - num_sam_entries = MAX_SAM_ENTRIES; - DEBUG(5,("limiting number of entries to %d\n", - num_sam_entries)); + len_sam_name = strlen(grp[i].name); + len_sam_desc = strlen(grp[i].comment); + + make_sam_entry3(&(sam->sam[i]), start_idx + i + 1, + len_sam_name, len_sam_desc, + grp[i].rid); + + make_unistr2(&(sam->str[i].uni_grp_name), grp[i].name , len_sam_name); + make_unistr2(&(sam->str[i].uni_grp_desc), grp[i].comment, len_sam_desc); + + dsize += sizeof(SAM_ENTRY3); + dsize += (len_sam_name + len_sam_desc) * 2; } - for (i = start_idx, entries_added = 0; i < num_sam_entries; i++) + *num_entries = i; + *data_size = dsize; +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +static void sam_io_sam_dispinfo_3(char *desc, SAM_DISPINFO_3 *sam, int num_entries, prs_struct *ps, int depth) +{ + int i; + + if (sam == NULL) return; + + prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_3"); + depth++; + + prs_align(ps); + + SMB_ASSERT_ARRAY(sam->sam, num_entries); + + for (i = 0; i < num_entries; i++) { - if (IS_BITS_SET_ALL(pass[i].acb_info, acb_mask)) - { - make_sam_entry1(&(sam->sam[entries_added]), - start_idx + entries_added + 1, - pass[i].uni_user_name.uni_str_len, - pass[i].uni_full_name.uni_str_len, - pass[i].uni_acct_desc.uni_str_len, - pass[i].user_rid, - pass[i].acb_info); - - copy_unistr2(&(sam->str[entries_added].uni_acct_name), &(pass[i].uni_user_name)); - copy_unistr2(&(sam->str[entries_added].uni_full_name), &(pass[i].uni_full_name)); - copy_unistr2(&(sam->str[entries_added].uni_acct_desc), &(pass[i].uni_acct_desc)); - - entries_added++; - } + prs_grow(ps); + sam_io_sam_entry3("", &(sam->sam[i]), ps, depth); } - sam->num_entries = entries_added; - sam->ptr_entries = 1; - sam->num_entries2 = entries_added; + for (i = 0; i < num_entries; i++) + { + prs_grow(ps); + sam_io_sam_str3 ("", &(sam->str[i]), + sam->sam[i].hdr_grp_name.buffer, + sam->sam[i].hdr_grp_desc.buffer, + ps, depth); + } } /******************************************************************* +makes a SAM_DISPINFO_4 structure. +********************************************************************/ +void make_sam_dispinfo_4(SAM_DISPINFO_4 *sam, uint32 *num_entries, + uint32 *data_size, uint32 start_idx, + SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]) +{ + fstring sam_name; + uint32 len_sam_name; + uint32 max_entries, max_data_size; + uint32 dsize = 0; + int i; + + if (sam == NULL || num_entries == NULL || data_size == NULL) return; + + DEBUG(5,("make_sam_dispinfo_4\n")); + + max_entries = *num_entries; + max_data_size = *data_size; + + for (i = 0; (i < max_entries) && (dsize < max_data_size); i++) + { + len_sam_name = pass[i].uni_user_name.uni_str_len; + + make_sam_entry4(&(sam->sam[i]), start_idx + i + 1, + len_sam_name); + + unistr2_to_ascii(sam_name, &(pass[i].uni_user_name), sizeof(sam_name)); + make_string2(&(sam->str[i].acct_name), sam_name, len_sam_name); + + dsize += sizeof(SAM_ENTRY4); + dsize += len_sam_name; + } + + *num_entries = i; + *data_size = dsize; +} + +/******************************************************************* reads or writes a structure. ********************************************************************/ -static void sam_io_sam_info_1(char *desc, SAM_INFO_1 *sam, prs_struct *ps, int depth) +static void sam_io_sam_dispinfo_4(char *desc, SAM_DISPINFO_4 *sam, int num_entries, prs_struct *ps, int depth) { int i; if (sam == NULL) return; - prs_debug(ps, depth, desc, "sam_io_sam_info_1"); + prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_4"); depth++; prs_align(ps); - prs_uint32("num_entries ", ps, depth, &(sam->num_entries )); - prs_uint32("ptr_entries ", ps, depth, &(sam->ptr_entries )); + SMB_ASSERT_ARRAY(sam->sam, num_entries); + + for (i = 0; i < num_entries; i++) + { + prs_grow(ps); + sam_io_sam_entry4("", &(sam->sam[i]), ps, depth); + } - prs_uint32("num_entries2 ", ps, depth, &(sam->num_entries2 )); + for (i = 0; i < num_entries; i++) + { + prs_grow(ps); + smb_io_string2("acct_name", &(sam->str[i].acct_name), + sam->sam[i].hdr_acct_name.buffer, ps, depth); + } +} - SMB_ASSERT_ARRAY(sam->sam, sam->num_entries); - for (i = 0; i < sam->num_entries; i++) +/******************************************************************* +makes a SAM_DISPINFO_5 structure. +********************************************************************/ +void make_sam_dispinfo_5(SAM_DISPINFO_5 *sam, uint32 *num_entries, + uint32 *data_size, uint32 start_idx, + DOMAIN_GRP *grp) +{ + uint32 len_sam_name; + uint32 max_entries, max_data_size; + uint32 dsize = 0; + int i; + + if (sam == NULL || num_entries == NULL || data_size == NULL) return; + + DEBUG(5,("make_sam_dispinfo_5\n")); + + max_entries = *num_entries; + max_data_size = *data_size; + + for (i = 0; (i < max_entries) && (dsize < max_data_size); i++) + { + len_sam_name = strlen(grp[i].name); + + make_sam_entry5(&(sam->sam[i]), start_idx + i + 1, + len_sam_name); + + make_string2(&(sam->str[i].grp_name), grp[i].name, + len_sam_name); + + dsize += sizeof(SAM_ENTRY5); + dsize += len_sam_name; + } + + *num_entries = i; + *data_size = dsize; +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +static void sam_io_sam_dispinfo_5(char *desc, SAM_DISPINFO_5 *sam, int num_entries, prs_struct *ps, int depth) +{ + int i; + + if (sam == NULL) return; + + prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_5"); + depth++; + + prs_align(ps); + + SMB_ASSERT_ARRAY(sam->sam, num_entries); + + for (i = 0; i < num_entries; i++) { prs_grow(ps); - sam_io_sam_entry1("", &(sam->sam[i]), ps, depth); + sam_io_sam_entry5("", &(sam->sam[i]), ps, depth); } - for (i = 0; i < sam->num_entries; i++) + for (i = 0; i < num_entries; i++) { prs_grow(ps); - sam_io_sam_str1 ("", &(sam->str[i]), - sam->sam[i].hdr_acct_name.buffer, - sam->sam[i].hdr_user_name.buffer, - sam->sam[i].hdr_user_desc.buffer, - ps, depth); + smb_io_string2("grp_name", &(sam->str[i].grp_name), + sam->sam[i].hdr_grp_name.buffer, ps, depth); } } @@ -1228,25 +1538,23 @@ static void sam_io_sam_info_1(char *desc, SAM_INFO_1 *sam, prs_struct *ps, int makes a SAMR_R_QUERY_DISPINFO structure. ********************************************************************/ void make_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO *r_u, - uint16 switch_level, SAM_INFO_CTR *ctr, uint32 status) + uint32 num_entries, uint32 data_size, + uint16 switch_level, SAM_DISPINFO_CTR *ctr, + uint32 status) { if (r_u == NULL) return; DEBUG(5,("make_samr_r_query_dispinfo: level %d\n", switch_level)); - if (status == 0x0) - { - r_u->unknown_0 = 0x0000001; - r_u->unknown_1 = 0x0000001; - } - else - { - r_u->unknown_0 = 0x0; - r_u->unknown_1 = 0x0; - } + r_u->total_size = 0; /* not calculated */ + r_u->data_size = data_size; r_u->switch_level = switch_level; + r_u->num_entries = num_entries; + r_u->ptr_entries = 1; + r_u->num_entries2 = num_entries; r_u->ctr = ctr; + r_u->status = status; } @@ -1254,7 +1562,7 @@ void make_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO *r_u, /******************************************************************* reads or writes a structure. ********************************************************************/ -void samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO *r_u, prs_struct *ps, int depth) +void samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO *r_u, prs_struct *ps, int depth) { if (r_u == NULL) return; @@ -1263,22 +1571,40 @@ void samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO *r_u, prs_struc prs_align(ps); - prs_uint32("unknown_0 ", ps, depth, &(r_u->unknown_0 )); - prs_uint32("unknown_1 ", ps, depth, &(r_u->unknown_1 )); - prs_uint16("switch_level ", ps, depth, &(r_u->switch_level )); - + prs_uint32("total_size ", ps, depth, &(r_u->total_size )); + prs_uint32("data_size ", ps, depth, &(r_u->data_size )); + prs_uint16("switch_level", ps, depth, &(r_u->switch_level)); prs_align(ps); + prs_uint32("num_entries ", ps, depth, &(r_u->num_entries )); + prs_uint32("ptr_entries ", ps, depth, &(r_u->ptr_entries )); + prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2)); + switch (r_u->switch_level) { case 0x1: { - sam_io_sam_info_1("users", r_u->ctr->sam.info1, ps, depth); + sam_io_sam_dispinfo_1("users", r_u->ctr->sam.info1, r_u->num_entries, ps, depth); break; } case 0x2: { - sam_io_sam_info_2("servers", r_u->ctr->sam.info2, ps, depth); + sam_io_sam_dispinfo_2("servers", r_u->ctr->sam.info2, r_u->num_entries, ps, depth); + break; + } + case 0x3: + { + sam_io_sam_dispinfo_3("groups", r_u->ctr->sam.info3, r_u->num_entries, ps, depth); + break; + } + case 0x4: + { + sam_io_sam_dispinfo_4("user list", r_u->ctr->sam.info4,r_u->num_entries, ps, depth); + break; + } + case 0x5: + { + sam_io_sam_dispinfo_5("group list", r_u->ctr->sam.info5, r_u->num_entries, ps, depth); break; } default: @@ -1979,110 +2305,59 @@ void samr_io_r_query_groupmem(char *desc, SAMR_R_QUERY_GROUPMEM *r_u, prs_struc /******************************************************************* -makes a SAMR_Q_ENUM_DOM_GROUPS structure. +makes a SAMR_Q_QUERY_USERGROUPS structure. ********************************************************************/ -void make_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_e, POLICY_HND *pol, - uint16 switch_level, uint32 start_idx, uint32 size) +void make_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u, + POLICY_HND *hnd) { - if (q_e == NULL || pol == NULL) return; - - DEBUG(5,("make_samr_q_enum_dom_groups\n")); - - memcpy(&(q_e->pol), pol, sizeof(*pol)); + if (q_u == NULL || hnd == NULL) return; - q_e->switch_level = switch_level; + DEBUG(5,("make_samr_q_query_usergroups\n")); - q_e->unknown_0 = 0; - q_e->start_idx = start_idx; - q_e->unknown_1 = 0x000007d0; - q_e->max_size = size; + memcpy(&(q_u->pol), hnd, sizeof(q_u->pol)); } /******************************************************************* reads or writes a structure. ********************************************************************/ -void samr_io_q_enum_dom_groups(char *desc, SAMR_Q_ENUM_DOM_GROUPS *q_e, prs_struct *ps, int depth) +void samr_io_q_query_usergroups(char *desc, SAMR_Q_QUERY_USERGROUPS *q_u, prs_struct *ps, int depth) { - if (q_e == NULL) return; + if (q_u == NULL) return; - prs_debug(ps, depth, desc, "samr_io_q_enum_dom_groups"); + prs_debug(ps, depth, desc, "samr_io_q_query_usergroups"); depth++; prs_align(ps); - smb_io_pol_hnd("pol", &(q_e->pol), ps, depth); - prs_align(ps); - - prs_uint16("switch_level", ps, depth, &(q_e->switch_level)); - prs_uint16("unknown_0 ", ps, depth, &(q_e->unknown_0 )); - prs_uint32("start_idx ", ps, depth, &(q_e->start_idx )); - prs_uint32("unknown_1 ", ps, depth, &(q_e->unknown_1 )); - prs_uint32("max_size ", ps, depth, &(q_e->max_size )); - + smb_io_pol_hnd("pol", &(q_u->pol), ps, depth); prs_align(ps); } - /******************************************************************* -makes a SAMR_R_ENUM_DOM_GROUPS structure. +makes a SAMR_R_QUERY_USERGROUPS structure. ********************************************************************/ -void make_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS *r_u, - uint32 start_idx, uint32 num_sam_entries, - DOMAIN_GRP *grp, - uint32 status) +void make_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS *r_u, + uint32 num_gids, DOM_GID *gid, uint32 status) { - int i; - int entries_added; - if (r_u == NULL) return; - DEBUG(5,("make_samr_r_enum_dom_groups\n")); - - if (num_sam_entries >= MAX_SAM_ENTRIES) - { - num_sam_entries = MAX_SAM_ENTRIES; - DEBUG(5,("limiting number of entries to %d\n", - num_sam_entries)); - } + DEBUG(5,("make_samr_r_query_usergroups\n")); if (status == 0x0) { - for (i = start_idx, entries_added = 0; i < num_sam_entries; i++) - { - int acct_name_len = strlen(grp[i].name); - int acct_desc_len = strlen(grp[i].comment); - - make_sam_entry3(&(r_u->sam[entries_added]), - start_idx + entries_added + 1, - acct_name_len, - acct_desc_len, - grp[i].rid); - - make_unistr2(&(r_u->str[entries_added].uni_grp_name), grp[i].name , acct_name_len); - make_unistr2(&(r_u->str[entries_added].uni_grp_desc), grp[i].comment, acct_desc_len); - - entries_added++; - } + r_u->ptr_0 = 1; + r_u->num_entries = num_gids; + r_u->ptr_1 = (num_gids != 0) ? 1 : 0; + r_u->num_entries2 = num_gids; - if (entries_added > 0) - { - r_u->unknown_0 = 0x0000492; - r_u->unknown_1 = 0x000049a; - } - else - { - r_u->unknown_0 = 0x0; - r_u->unknown_1 = 0x0; - } - r_u->switch_level = 3; - r_u->num_entries = entries_added; - r_u->ptr_entries = 1; - r_u->num_entries2 = entries_added; + r_u->gid = gid; } else { - r_u->switch_level = 0; + r_u->ptr_0 = 0; + r_u->num_entries = 0; + r_u->ptr_1 = 0; } r_u->status = status; @@ -2091,103 +2366,123 @@ void make_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS *r_u, /******************************************************************* reads or writes a structure. ********************************************************************/ -void samr_io_r_enum_dom_groups(char *desc, SAMR_R_ENUM_DOM_GROUPS *r_u, prs_struct *ps, int depth) +void samr_io_r_query_usergroups(char *desc, SAMR_R_QUERY_USERGROUPS *r_u, prs_struct *ps, int depth) { int i; - if (r_u == NULL) return; - prs_debug(ps, depth, desc, "samr_io_r_enum_dom_groups"); + prs_debug(ps, depth, desc, "samr_io_r_query_usergroups"); depth++; prs_align(ps); - prs_uint32("unknown_0 ", ps, depth, &(r_u->unknown_0 )); - prs_uint32("unknown_1 ", ps, depth, &(r_u->unknown_1 )); - prs_uint32("switch_level ", ps, depth, &(r_u->switch_level )); + prs_uint32("ptr_0 ", ps, depth, &(r_u->ptr_0 )); - if (r_u->switch_level != 0) + if (r_u->ptr_0 != 0) { - prs_uint32("num_entries ", ps, depth, &(r_u->num_entries )); - prs_uint32("ptr_entries ", ps, depth, &(r_u->ptr_entries )); - - prs_uint32("num_entries2 ", ps, depth, &(r_u->num_entries2 )); - - SMB_ASSERT_ARRAY(r_u->sam, r_u->num_entries); + prs_uint32("num_entries ", ps, depth, &(r_u->num_entries)); + prs_uint32("ptr_1 ", ps, depth, &(r_u->ptr_1 )); - for (i = 0; i < r_u->num_entries; i++) + if (r_u->num_entries != 0) { - prs_grow(ps); - sam_io_sam_entry3("", &(r_u->sam[i]), ps, depth); - } + prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2)); - for (i = 0; i < r_u->num_entries; i++) - { - prs_grow(ps); - sam_io_sam_str3 ("", &(r_u->str[i]), - r_u->sam[i].hdr_grp_name.buffer, - r_u->sam[i].hdr_grp_desc.buffer, - ps, depth); + for (i = 0; i < r_u->num_entries2; i++) + { + prs_grow(ps); + smb_io_gid("", &(r_u->gid[i]), ps, depth); + } } } - prs_uint32("status", ps, depth, &(r_u->status)); } + /******************************************************************* -makes a SAMR_Q_QUERY_USERGROUPS structure. +makes a SAMR_Q_ENUM_DOM_GROUPS structure. ********************************************************************/ -void make_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u, - POLICY_HND *hnd) +void make_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_e, POLICY_HND *pol, uint32 size) { - if (q_u == NULL || hnd == NULL) return; + if (q_e == NULL || pol == NULL) return; - DEBUG(5,("make_samr_q_query_usergroups\n")); + DEBUG(5,("make_samr_q_enum_dom_groups\n")); - memcpy(&(q_u->pol), hnd, sizeof(q_u->pol)); + memcpy(&(q_e->pol), pol, sizeof(*pol)); + + q_e->unknown_0 = 0; + q_e->max_size = size; } /******************************************************************* reads or writes a structure. ********************************************************************/ -void samr_io_q_query_usergroups(char *desc, SAMR_Q_QUERY_USERGROUPS *q_u, prs_struct *ps, int depth) +void samr_io_q_enum_dom_groups(char *desc, SAMR_Q_ENUM_DOM_GROUPS *q_e, prs_struct *ps, int depth) { - if (q_u == NULL) return; + if (q_e == NULL) return; - prs_debug(ps, depth, desc, "samr_io_q_query_usergroups"); + prs_debug(ps, depth, desc, "samr_io_q_enum_dom_groups"); depth++; prs_align(ps); - smb_io_pol_hnd("pol", &(q_u->pol), ps, depth); + smb_io_pol_hnd("pol", &(q_e->pol), ps, depth); + prs_align(ps); + + prs_uint32("unknown_0", ps, depth, &(q_e->unknown_0)); + prs_uint32("max_size ", ps, depth, &(q_e->max_size )); + prs_align(ps); } + /******************************************************************* -makes a SAMR_R_QUERY_USERGROUPS structure. +makes a SAMR_R_ENUM_DOM_GROUPS structure. ********************************************************************/ -void make_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS *r_u, - uint32 num_gids, DOM_GID *gid, uint32 status) +void make_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS *r_u, + uint32 num_sam_entries, DOMAIN_GRP *grps, + uint32 status) { + int i; + if (r_u == NULL) return; - DEBUG(5,("make_samr_r_query_usergroups\n")); + DEBUG(5,("make_samr_r_enum_dom_groups\n")); - if (status == 0x0) + if (num_sam_entries >= MAX_SAM_ENTRIES) { - r_u->ptr_0 = 1; - r_u->num_entries = num_gids; - r_u->ptr_1 = (num_gids != 0) ? 1 : 0; - r_u->num_entries2 = num_gids; + num_sam_entries = MAX_SAM_ENTRIES; + DEBUG(5,("limiting number of entries to %d\n", + num_sam_entries)); + } - r_u->gid = gid; + r_u->num_entries = num_sam_entries; + + if (num_sam_entries > 0) + { + r_u->ptr_entries = 1; + r_u->num_entries2 = num_sam_entries; + r_u->ptr_entries2 = 1; + r_u->num_entries3 = num_sam_entries; + + SMB_ASSERT_ARRAY(r_u->sam, num_sam_entries); + + for (i = 0; i < num_sam_entries; i++) + { + int acct_name_len = strlen(grps[i].name); + + make_sam_entry(&(r_u->sam[i]), + acct_name_len, + grps[i].rid); + + make_unistr2(&(r_u->uni_grp_name[i]), grps[i].name, acct_name_len); + } + + r_u->num_entries4 = num_sam_entries; } else { - r_u->ptr_0 = 0; - r_u->num_entries = 0; - r_u->ptr_1 = 0; + r_u->ptr_entries = 0; } r_u->status = status; @@ -2196,34 +2491,43 @@ void make_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS *r_u, /******************************************************************* reads or writes a structure. ********************************************************************/ -void samr_io_r_query_usergroups(char *desc, SAMR_R_QUERY_USERGROUPS *r_u, prs_struct *ps, int depth) +void samr_io_r_enum_dom_groups(char *desc, SAMR_R_ENUM_DOM_GROUPS *r_u, prs_struct *ps, int depth) { int i; + if (r_u == NULL) return; - prs_debug(ps, depth, desc, "samr_io_r_query_usergroups"); + prs_debug(ps, depth, desc, "samr_io_r_enum_dom_groups"); depth++; prs_align(ps); - prs_uint32("ptr_0 ", ps, depth, &(r_u->ptr_0 )); - - if (r_u->ptr_0 != 0) + prs_uint32("num_entries", ps, depth, &(r_u->num_entries)); + prs_uint32("ptr_entries", ps, depth, &(r_u->ptr_entries)); + + if (r_u->num_entries != 0 && r_u->ptr_entries != 0) { - prs_uint32("num_entries ", ps, depth, &(r_u->num_entries)); - prs_uint32("ptr_1 ", ps, depth, &(r_u->ptr_1 )); + prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2)); + prs_uint32("ptr_entries2", ps, depth, &(r_u->ptr_entries2)); + prs_uint32("num_entries3", ps, depth, &(r_u->num_entries3)); - if (r_u->num_entries != 0) + SMB_ASSERT_ARRAY(r_u->sam, r_u->num_entries); + + for (i = 0; i < r_u->num_entries; i++) { - prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2)); + sam_io_sam_entry("", &(r_u->sam[i]), ps, depth); + } - for (i = 0; i < r_u->num_entries2; i++) - { - prs_grow(ps); - smb_io_gid("", &(r_u->gid[i]), ps, depth); - } + for (i = 0; i < r_u->num_entries; i++) + { + smb_io_unistr2("", &(r_u->uni_grp_name[i]), r_u->sam[i].hdr_name.buffer, ps, depth); } + + prs_align(ps); + + prs_uint32("num_entries4", ps, depth, &(r_u->num_entries4)); } + prs_uint32("status", ps, depth, &(r_u->status)); } @@ -3385,10 +3689,10 @@ void samr_io_r_lookup_names(char *desc, SAMR_R_LOOKUP_NAMES *r_u, prs_struct *p prs_uint32("num_rids1", ps, depth, &(r_u->num_rids1)); prs_uint32("ptr_rids ", ps, depth, &(r_u->ptr_rids )); + prs_uint32("num_rids2", ps, depth, &(r_u->num_rids2)); if (r_u->ptr_rids != 0 && r_u->num_rids1 != 0) { - prs_uint32("num_rids2", ps, depth, &(r_u->num_rids2)); for (i = 0; i < r_u->num_rids2; i++) { prs_grow(ps); @@ -3399,10 +3703,10 @@ void samr_io_r_lookup_names(char *desc, SAMR_R_LOOKUP_NAMES *r_u, prs_struct *p prs_uint32("num_types1", ps, depth, &(r_u->num_types1)); prs_uint32("ptr_types ", ps, depth, &(r_u->ptr_types )); + prs_uint32("num_types2", ps, depth, &(r_u->num_types2)); if (r_u->ptr_types != 0 && r_u->num_types1 != 0) { - prs_uint32("num_types2", ps, depth, &(r_u->num_types2)); for (i = 0; i < r_u->num_types2; i++) { prs_grow(ps); diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c index 449a47e4c9..4f190270dd 100644 --- a/source3/rpc_server/srv_samr.c +++ b/source3/rpc_server/srv_samr.c @@ -618,7 +618,7 @@ static void api_samr_del_aliasmem( uint16 vuid, prs_struct *data, prs_struct *rd } /******************************************************************* - samr_reply_add_groupmem + samr_reply_enum_dom_groups ********************************************************************/ static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u, prs_struct *rdata) @@ -626,7 +626,6 @@ static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS r_e; DOMAIN_GRP *grps = NULL; int num_entries = 0; - BOOL got_grps = False; DOM_SID sid; fstring sid_str; @@ -646,21 +645,19 @@ static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u, if (sid_equal(&sid, &global_sam_sid)) { BOOL ret; - got_grps = True; become_root(True); ret = enumdomgroups(&grps, &num_entries); unbecome_root(True); - if (!ret) { r_e.status = 0xC0000000 | NT_STATUS_NO_MEMORY; } } - if (r_e.status == 0 && got_grps) + if (r_e.status == 0x0) { - make_samr_r_enum_dom_groups(&r_e, q_u->start_idx, num_entries, grps, r_e.status); + make_samr_r_enum_dom_groups(&r_e, num_entries, grps, r_e.status); } /* store the response in the SMB stream */ @@ -675,12 +672,16 @@ static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u, } /******************************************************************* - api_samr_enum_dom_groups + api_samr_enum_dom_aliases ********************************************************************/ static void api_samr_enum_dom_groups( uint16 vuid, prs_struct *data, prs_struct *rdata) { SAMR_Q_ENUM_DOM_GROUPS q_e; + + /* grab the samr open */ samr_io_q_enum_dom_groups("", &q_e, data, 0); + + /* construct reply. */ samr_reply_enum_dom_groups(&q_e, rdata); } @@ -777,72 +778,154 @@ static void samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u, prs_struct *rdata) { SAMR_R_QUERY_DISPINFO r_e; - SAM_INFO_CTR ctr; - SAM_INFO_1 info1; - SAM_INFO_2 info2; + SAM_DISPINFO_CTR ctr; SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]; + DOMAIN_GRP *grps = NULL; + DOMAIN_GRP *sam_grps = NULL; + uint32 data_size = 0; + uint32 status = 0x0; + uint16 acb_mask = ACB_NORMAL; + int num_sam_entries = 0; int num_entries = 0; - int total_entries = 0; - BOOL got_pwds; - uint16 switch_level = 0x0; - - ZERO_STRUCT(r_e); - - r_e.status = 0x0; + int total_entries; DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__)); /* find the policy handle. open a policy on it. */ - if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1)) + if (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1) { - r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE; + status = 0xC0000000 | NT_STATUS_INVALID_HANDLE; DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n")); } - if (r_e.status == 0x0) + if (status == 0x0) { become_root(True); - got_pwds = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, MAX_SAM_ENTRIES, 0); - unbecome_root(True); + /* Get what we need from the password database */ switch (q_u->switch_level) { + case 0x2: + { + acb_mask = ACB_WSTRUST; + /* Fall through */ + } case 0x1: + case 0x4: + { + get_sampwd_entries(pass, q_u->start_idx, + &total_entries, &num_sam_entries, + MAX_SAM_ENTRIES, acb_mask); + break; + } + case 0x3: + case 0x5: { - - /* query disp info is for users */ - switch_level = 0x1; - make_sam_info_1(&info1, ACB_NORMAL, - q_u->start_idx, num_entries, pass); + enumdomgroups(&sam_grps, &num_sam_entries); + + if (q_u->start_idx < num_sam_entries) { + grps = sam_grps + q_u->start_idx; + num_sam_entries -= q_u->start_idx; + } else { + num_sam_entries = 0; + } + break; + } + } + + unbecome_root(True); + + num_entries = num_sam_entries; + + if (num_entries > q_u->max_entries) + { + num_entries = q_u->max_entries; + } + + if (num_entries > MAX_SAM_ENTRIES) + { + num_entries = MAX_SAM_ENTRIES; + DEBUG(5,("limiting number of entries to %d\n", + num_entries)); + } - ctr.sam.info1 = &info1; + data_size = q_u->max_size; + /* Now create reply structure */ + switch (q_u->switch_level) + { + case 0x1: + { + ctr.sam.info1 = malloc(sizeof(SAM_DISPINFO_1)); + make_sam_dispinfo_1(ctr.sam.info1, + &num_entries, &data_size, + q_u->start_idx, pass); break; } case 0x2: { - /* query disp info is for servers */ - switch_level = 0x2; - make_sam_info_2(&info2, ACB_WSTRUST, - q_u->start_idx, num_entries, pass); - - ctr.sam.info2 = &info2; - + ctr.sam.info2 = malloc(sizeof(SAM_DISPINFO_2)); + make_sam_dispinfo_2(ctr.sam.info2, + &num_entries, &data_size, + q_u->start_idx, pass); + break; + } + case 0x3: + { + ctr.sam.info3 = malloc(sizeof(SAM_DISPINFO_3)); + make_sam_dispinfo_3(ctr.sam.info3, + &num_entries, &data_size, + q_u->start_idx, grps); + break; + } + case 0x4: + { + ctr.sam.info4 = malloc(sizeof(SAM_DISPINFO_4)); + make_sam_dispinfo_4(ctr.sam.info4, + &num_entries, &data_size, + q_u->start_idx, pass); + break; + } + case 0x5: + { + ctr.sam.info5 = malloc(sizeof(SAM_DISPINFO_5)); + make_sam_dispinfo_5(ctr.sam.info5, + &num_entries, &data_size, + q_u->start_idx, grps); + break; + } + default: + { + ctr.sam.info = NULL; + status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS; break; } } } - if (r_e.status == 0 && got_pwds) + if ((status == 0) && (num_entries < num_sam_entries)) { - make_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status); + status = 0x105; /* STATUS_MORE_ENTRIES */ } + make_samr_r_query_dispinfo(&r_e, num_entries, data_size, + q_u->switch_level, &ctr, status); + /* store the response in the SMB stream */ samr_io_r_query_dispinfo("", &r_e, rdata, 0); - DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__)); + /* free malloc'd areas */ + if (sam_grps != NULL) + { + free(sam_grps); + } + if (ctr.sam.info != NULL) + { + free(ctr.sam.info); + } + + DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__)); } /******************************************************************* @@ -852,10 +935,7 @@ static void api_samr_query_dispinfo( uint16 vuid, prs_struct *data, prs_struct * { SAMR_Q_QUERY_DISPINFO q_e; - /* grab the samr open */ samr_io_q_query_dispinfo("", &q_e, data, 0); - - /* construct reply. */ samr_reply_query_dispinfo(&q_e, rdata); } @@ -2538,6 +2618,64 @@ static void api_samr_open_group( uint16 vuid, prs_struct *data, prs_struct *rdat } /******************************************************************* + samr_reply_lookup_domain + ********************************************************************/ +static void samr_reply_lookup_domain(SAMR_Q_LOOKUP_DOMAIN *q_u, + prs_struct *rdata) +{ + SAMR_R_LOOKUP_DOMAIN r_u; + fstring domain; + + DEBUG(5,("samr_lookup_domain: %d\n", __LINE__)); + + r_u.ptr_sid = 0; + r_u.status = 0x0; + + /* find the connection policy handle */ + if (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1) + { + r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE; + } + + if (r_u.status == 0x0) + { + unistr2_to_ascii(domain, &(q_u->uni_domain), sizeof(domain)); + DEBUG(5, ("Lookup Domain: %s\n", domain)); + + /* check it's one of ours */ + if (strequal(domain, global_sam_name)) + { + make_dom_sid2(&(r_u.dom_sid), &global_sam_sid); + r_u.ptr_sid = 1; + } + else if (strequal(domain, "BUILTIN")) + { + make_dom_sid2(&(r_u.dom_sid), &global_sid_S_1_5_20); + r_u.ptr_sid = 1; + } + else + { + r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_DOMAIN; + } + } + + /* store the response in the SMB stream */ + samr_io_r_lookup_domain("", &r_u, rdata, 0); + + DEBUG(5,("samr_lookup_domain: %d\n", __LINE__)); +} + +/******************************************************************* + api_samr_lookup_domain + ********************************************************************/ +static void api_samr_lookup_domain( uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SAMR_Q_LOOKUP_DOMAIN q_u; + samr_io_q_lookup_domain("", &q_u, data, 0); + samr_reply_lookup_domain(&q_u, rdata); +} + +/******************************************************************* array of \PIPE\samr operations ********************************************************************/ static struct api_struct api_samr_cmds [] = @@ -2565,6 +2703,8 @@ static struct api_struct api_samr_cmds [] = { "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_DISPINFO3" , SAMR_QUERY_DISPINFO3 , api_samr_query_dispinfo }, + { "SAMR_QUERY_DISPINFO4" , SAMR_QUERY_DISPINFO4 , api_samr_query_dispinfo }, { "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo }, { "SAMR_QUERY_GROUPINFO" , SAMR_QUERY_GROUPINFO , api_samr_query_groupinfo }, { "SAMR_0x32" , SAMR_UNKNOWN_32 , api_samr_unknown_32 }, @@ -2574,6 +2714,7 @@ static struct api_struct api_samr_cmds [] = { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias }, { "SAMR_OPEN_GROUP" , SAMR_OPEN_GROUP , api_samr_open_group }, { "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain }, + { "SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain }, { "SAMR_UNKNOWN_3" , SAMR_UNKNOWN_3 , api_samr_unknown_3 }, { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c }, { NULL , 0 , NULL } diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index 852521d850..7204411dd5 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -174,6 +174,62 @@ void cmd_sam_test(struct client_info *info) } /**************************************************************************** +Lookup domain in SAM server. +****************************************************************************/ +void cmd_sam_lookup_domain(struct client_info *info) +{ + uint16 fnum; + fstring srv_name; + fstring domain; + fstring str_sid; + DOM_SID dom_sid; + BOOL res = True; + + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, info->dest_host); + strupper(srv_name); + + if (!next_token(NULL, domain, NULL, sizeof(domain))) + { + fprintf(out_hnd, "lookupdomain: <name>\n"); + return; + } + + fprintf(out_hnd, "Lookup Domain in SAM Server\n"); + + /* open SAMR session. negotiate credentials */ + res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR, &fnum) : False; + + /* establish a connection. */ + res = res ? samr_connect(smb_cli, fnum, + srv_name, 0x00000020, + &info->dom.samr_pol_connect) : False; + + /* connect to the domain */ + res = res ? samr_query_lookup_domain(smb_cli, fnum, + &info->dom.samr_pol_connect, domain, &dom_sid) : False; + + res = res ? samr_close(smb_cli, fnum, &info->dom.samr_pol_connect) : False; + + /* close the session */ + cli_nt_session_close(smb_cli, fnum); + + if (res) + { + DEBUG(5,("cmd_sam_lookup_domain: succeeded\n")); + + sid_to_string(str_sid, &dom_sid); + fprintf(out_hnd, "%s SID: %s\n", domain, str_sid); + fprintf(out_hnd, "Lookup Domain: OK\n"); + } + else + { + DEBUG(5,("cmd_sam_lookup_domain: failed\n")); + fprintf(out_hnd, "Lookup Domain: FAILED\n"); + } +} + +/**************************************************************************** SAM delete alias member. ****************************************************************************/ void cmd_sam_del_aliasmem(struct client_info *info) @@ -359,7 +415,6 @@ void cmd_sam_delete_dom_alias(struct client_info *info) } } - /**************************************************************************** SAM add alias member. ****************************************************************************/ @@ -1444,7 +1499,7 @@ void cmd_sam_query_dominfo(struct client_info *info) /**************************************************************************** -experimental SAM aliases query. +SAM aliases query. ****************************************************************************/ void cmd_sam_enum_aliases(struct client_info *info) { @@ -1606,7 +1661,7 @@ void cmd_sam_enum_aliases(struct client_info *info) cli_nt_session_close(smb_cli, fnum); if (info->dom.sam != NULL) - { + { free(info->dom.sam); } @@ -1615,14 +1670,13 @@ void cmd_sam_enum_aliases(struct client_info *info) DEBUG(5,("cmd_sam_enum_aliases: succeeded\n")); } else - { + { DEBUG(5,("cmd_sam_enum_aliases: failed\n")); - } - } - + } +} /**************************************************************************** -experimental SAM groups query. +SAM groups query. ****************************************************************************/ void cmd_sam_enum_groups(struct client_info *info) { @@ -1633,22 +1687,20 @@ void cmd_sam_enum_groups(struct client_info *info) DOM_SID sid1; BOOL res = True; BOOL request_member_info = False; - uint32 flags = 0x304; /* absolutely no idea. */ + uint32 flags = 0x200003f3; /* absolutely no idea. */ fstring tmp; uint32 group_idx; - sid_to_string(sid, &info->dom.level3_sid); - fstrcpy(domain, info->dom.level3_dom); -#if 0 - fstrcpy(sid , "S-1-5-20"); -#endif - if (strlen(sid) == 0) + sid_copy(&sid1, &info->dom.level3_sid); + + if (sid1.num_auths == 0) { fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n"); return; - } + } - string_to_sid(&sid1, sid); + sid_to_string(sid, &sid1); + fstrcpy(domain, info->dom.level3_dom); fstrcpy(srv_name, "\\\\"); fstrcat(srv_name, info->dest_host); @@ -1670,7 +1722,7 @@ void cmd_sam_enum_groups(struct client_info *info) /* establish a connection. */ res = res ? samr_connect(smb_cli, fnum, srv_name, 0x00000020, - &info->dom.samr_pol_connect) : False; + &info->dom.samr_pol_connect) : False; /* connect to the domain */ res = res ? samr_open_domain(smb_cli, fnum, @@ -1695,39 +1747,45 @@ void cmd_sam_enum_groups(struct client_info *info) { uint32 group_rid = info->dom.sam[group_idx].rid; - fprintf(out_hnd, "Group RID: %8x Group Name: %s Description: %s\n", + fprintf(out_hnd, "Group RID: %8x Group Name: %s\n", group_rid, - info->dom.sam[group_idx].acct_name, - info->dom.sam[group_idx].acct_desc); + info->dom.sam[group_idx].acct_name); if (request_member_info) { - uint32 num_groups; - uint32 num_names; + uint32 num_mem; + uint32 rid_mem[MAX_LOOKUP_SIDS]; uint32 attr_mem[MAX_LOOKUP_SIDS]; - uint32 rid_mem [MAX_LOOKUP_SIDS]; - fstring name[MAX_LOOKUP_SIDS]; - uint32 type[MAX_LOOKUP_SIDS]; - /* send user groups query */ + /* get group members */ if (get_samr_query_groupmem(smb_cli, fnum, - &info->dom.samr_pol_open_domain, - group_rid, &num_groups, - rid_mem, attr_mem) && - samr_query_lookup_rids(smb_cli, fnum, - &info->dom.samr_pol_open_domain, 0x3e8, - num_groups, rid_mem, - &num_names, name, type)) + &info->dom.samr_pol_open_domain, + group_rid, &num_mem, rid_mem, attr_mem)) { - display_group_members(out_hnd, ACTION_HEADER , num_names, name, type); - display_group_members(out_hnd, ACTION_ENUMERATE, num_names, name, type); - display_group_members(out_hnd, ACTION_FOOTER , num_names, name, type); + BOOL res3 = True; + int num_names = 0; + fstring names[MAX_LOOKUP_SIDS]; + uint32 types[MAX_LOOKUP_SIDS]; + + res3 = samr_query_lookup_rids(smb_cli, fnum, + &info->dom.samr_pol_open_domain, 1000, + num_mem, rid_mem, &num_names, names, types); + + if (res3) + { + display_group_members(out_hnd, ACTION_HEADER , num_names, names, types); + display_group_members(out_hnd, ACTION_ENUMERATE, num_names, names, types); + display_group_members(out_hnd, ACTION_FOOTER , num_names, names, types); + } } } } - res = res ? samr_close(smb_cli, fnum, &info->dom.samr_pol_connect) : False; - res = res ? samr_close(smb_cli, fnum, &info->dom.samr_pol_open_domain) : False; + res = res ? samr_close(smb_cli, fnum, + &info->dom.samr_pol_open_domain) : False; + + res = res ? samr_close(smb_cli, fnum, + &info->dom.samr_pol_connect) : False; /* close the session */ cli_nt_session_close(smb_cli, fnum); @@ -1746,5 +1804,3 @@ void cmd_sam_enum_groups(struct client_info *info) DEBUG(5,("cmd_sam_enum_groups: failed\n")); } } - - diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index 31ae8e6fc0..c8c3b52194 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -187,9 +187,13 @@ static void send_trans_reply(char *outbuf, if (buffer_too_large) { +#if 0 /* issue a buffer size warning. on a DCE/RPC pipe, expect an SMBreadX... */ SIVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES); SIVAL(outbuf, smb_rcls, 0x80000000 | NT_STATUS_ACCESS_VIOLATION); +#endif + SCVAL(outbuf, smb_rcls, ERRDOS); + SSVAL(outbuf, smb_err, ERRmoredata); } copy_trans_params_and_data(outbuf, align, |