1
0
mirror of https://github.com/samba-team/samba.git synced 2025-08-02 00:22:11 +03:00

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 7d03e6e219)
This commit is contained in:
Matthew Chapman
1999-02-24 01:52:30 +00:00
parent 1e71ecdcb2
commit 05f772b431
7 changed files with 1165 additions and 498 deletions

View File

@ -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);

View File

@ -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_R_QUERY_DISPINFO - SAM rids, names and descriptions */
/* 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_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 */
SAM_INFO_CTR *ctr;
uint16 switch_level; /* see SAM_DISPINFO_CTR above */
/* align */
uint32 num_entries; /* number of entries returned */
uint32 ptr_entries;
uint32 num_entries2;
SAM_DISPINFO_CTR *ctr;
uint32 status;

View File

@ -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;
}
@ -1629,6 +1624,63 @@ BOOL samr_open_domain(struct cli_state *cli, uint16 fnum,
return valid_pol;
}
/****************************************************************************
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
****************************************************************************/

File diff suppressed because it is too large Load Diff

View File

@ -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);
/* 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:
{
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));
}
data_size = q_u->max_size;
/* Now create reply structure */
switch (q_u->switch_level)
{
case 0x1:
{
/* query disp info is for users */
switch_level = 0x1;
make_sam_info_1(&info1, ACB_NORMAL,
q_u->start_idx, num_entries, pass);
ctr.sam.info1 = &info1;
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);
}
@ -2537,6 +2617,64 @@ static void api_samr_open_group( uint16 vuid, prs_struct *data, prs_struct *rdat
samr_reply_open_group(&q_u, rdata);
}
/*******************************************************************
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
********************************************************************/
@ -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 }

View File

@ -173,6 +173,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.
****************************************************************************/
@ -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"));
}
}

View File

@ -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,