1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-10 12:58:35 +03:00

Fix for the SID history problem when using a Win2k domain controller

with security=domain. Also fixed to dynamically allocate the SIDs and GIDs.
Jeremy.
This commit is contained in:
Jeremy Allison -
parent 55ed0a9b0c
commit 2b1f66eb82
6 changed files with 76 additions and 30 deletions

View File

@ -2311,6 +2311,7 @@ void init_net_user_info3(NET_USER_INFO_3 *usr,
DOM_SID *dom_sid,
char *other_sids);
void free_user_info3(NET_USER_INFO_3 *usr);
BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth);
BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth);
BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth);
@ -3160,7 +3161,7 @@ uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32
uint32 _new_spoolss_enumforms( POLICY_HND *handle, uint32 level,
NEW_BUFFER *buffer, uint32 offered,
uint32 *needed, uint32 *numofforms);
uint32 _spoolss_getform( POLICY_HND *handle, uint32 level, UNISTR2 *formname, NEW_BUFFER *buffer, uint32 offered, uint32 *needed);
uint32 _spoolss_getform( POLICY_HND *handle, uint32 level, UNISTR2 *uni_formname, NEW_BUFFER *buffer, uint32 offered, uint32 *needed);
uint32 _spoolss_enumports( UNISTR2 *name, uint32 level,
NEW_BUFFER *buffer, uint32 offered,
uint32 *needed, uint32 *returned);

View File

@ -52,7 +52,7 @@ enum SID_NAME_USE
#define LSA_LOOKUPRIDS 0xFD
#define LSA_MAX_GROUPS 96
#define LSA_MAX_SIDS 32
#define LSA_MAX_SIDS 128
/* DOM_QUERY - info class 3 and 5 LSA Query response */
typedef struct dom_query_info

View File

@ -120,7 +120,10 @@ typedef struct net_user_info_3
UNISTR2 uni_logon_dom; /* logon domain unicode string */
DOM_SID2 dom_sid; /* domain SID */
DOM_SID2 other_sids[LSA_MAX_SIDS]; /* undocumented - domain SIDs */
uint32 num_other_groups; /* other groups */
DOM_GID *other_gids; /* group info */
DOM_SID2 *other_sids; /* undocumented - domain SIDs */
} NET_USER_INFO_3;

View File

@ -608,7 +608,7 @@ BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int de
Init DOM_SID2 array from a string containing multiple sids
*************************************************************************/
static int init_dom_sid2s(char *sids_str, DOM_SID2 *sids, int max_sids)
static int init_dom_sid2s(char *sids_str, DOM_SID2 **ppsids)
{
char *ptr;
pstring s2;
@ -616,12 +616,29 @@ static int init_dom_sid2s(char *sids_str, DOM_SID2 *sids, int max_sids)
DEBUG(4,("init_dom_sid2s: %s\n", sids_str ? sids_str:""));
*ppsids = NULL;
if(sids_str) {
int number;
DOM_SID2 *sids;
/* Count the number of SIDs. */
for (count = 0, ptr = sids_str;
next_token(&ptr, s2, NULL, sizeof(s2)) && count < max_sids; count++) {
next_token(&ptr, s2, NULL, sizeof(s2)); count++)
;
/* Now allocate space for them. */
*ppsids = (DOM_SID2 *)malloc(count * sizeof(DOM_SID2));
if (*ppsids == NULL)
return 0;
sids = *ppsids;
for (number = 0, ptr = sids_str;
next_token(&ptr, s2, NULL, sizeof(s2)); number++) {
DOM_SID tmpsid;
string_to_sid(&tmpsid, s2);
init_dom_sid2(&sids[count], &tmpsid);
init_dom_sid2(&sids[number], &tmpsid);
}
}
@ -1056,7 +1073,7 @@ void init_net_user_info3(NET_USER_INFO_3 *usr,
memset((char *)usr->padding, '\0', sizeof(usr->padding));
num_other_sids = init_dom_sid2s(other_sids, usr->other_sids, LSA_MAX_SIDS);
num_other_sids = init_dom_sid2s(other_sids, &usr->other_sids);
usr->num_other_sids = num_other_sids;
usr->buffer_other_sids = (num_other_sids != 0) ? 1 : 0;
@ -1070,8 +1087,7 @@ void init_net_user_info3(NET_USER_INFO_3 *usr,
usr->num_groups2 = num_groups;
if (num_groups > 0)
{
if (num_groups > 0) {
usr->gids = (DOM_GID *)malloc(sizeof(DOM_GID) * num_groups);
if (usr->gids == NULL)
return;
@ -1086,6 +1102,15 @@ void init_net_user_info3(NET_USER_INFO_3 *usr,
/* "other" sids are set up above */
}
/*******************************************************************
Delete any memory allocated by init_user_info_3...
********************************************************************/
void free_user_info3(NET_USER_INFO_3 *usr)
{
safe_free(usr->gids);
safe_free(usr->other_sids);
}
/*******************************************************************
Reads or writes a structure.
@ -1188,9 +1213,8 @@ static BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 *usr, prs_struct *ps,
if(!prs_uint32("num_groups2 ", ps, depth, &usr->num_groups2)) /* num groups */
return False;
if (UNMARSHALLING(ps) && usr->num_groups2 > 0)
{
usr->gids = (DOM_GID *)malloc(sizeof(DOM_GID)*usr->num_groups2);
if (UNMARSHALLING(ps) && usr->num_groups2 > 0) {
usr->gids = (DOM_GID *)prs_alloc_mem(ps, sizeof(DOM_GID)*usr->num_groups2);
if (usr->gids == NULL)
return False;
}
@ -1208,11 +1232,31 @@ static BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 *usr, prs_struct *ps,
if(!smb_io_dom_sid2("", &usr->dom_sid, ps, depth)) /* domain SID */
return False;
SMB_ASSERT_ARRAY(usr->other_sids, usr->num_other_sids);
if (usr->num_other_sids) {
for (i = 0; i < usr->num_other_sids; i++) {
if(!smb_io_dom_sid2("", &usr->other_sids[i], ps, depth)) /* other domain SIDs */
if (UNMARSHALLING(ps)) {
usr->other_sids = (DOM_SID2 *)prs_alloc_mem(ps, sizeof(DOM_SID2)*usr->num_other_sids);
if (usr->other_sids == NULL)
return False;
}
if(!prs_uint32("num_other_groups", ps, depth, &usr->num_other_groups))
return False;
if (UNMARSHALLING(ps)) {
usr->other_gids = (DOM_GID *)prs_alloc_mem(ps, sizeof(DOM_GID)*usr->num_other_groups);
if (usr->other_gids == NULL)
return False;
}
for (i = 0; i < usr->num_other_groups; i++) {
if(!smb_io_gid("", &usr->other_gids[i], ps, depth)) /* other GIDs */
return False;
}
for (i = 0; i < usr->num_other_sids; i++) {
if(!smb_io_dom_sid2("", &usr->other_sids[i], ps, depth)) /* other domain SIDs */
return False;
}
}
return True;

View File

@ -665,18 +665,15 @@ static BOOL api_net_sam_logon(pipes_struct *p)
q_l.sam_id.ctr = &ctr;
if(!net_io_q_sam_logon("", &q_l, data, 0)) {
DEBUG(0,
("api_net_sam_logon: Failed to unmarshall NET_Q_SAM_LOGON.\n"));
DEBUG(0, ("api_net_sam_logon: Failed to unmarshall NET_Q_SAM_LOGON.\n"));
return False;
}
/* checks and updates credentials. creates reply credentials */
if (!deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
&(q_l.sam_id.client.cred), &srv_cred))
if (!deal_with_creds(vuser->dc.sess_key, &vuser->dc.clnt_cred, &q_l.sam_id.client.cred, &srv_cred))
status = NT_STATUS_INVALID_HANDLE;
else
memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred),
sizeof(vuser->dc.clnt_cred));
memcpy(&vuser->dc.srv_cred, &vuser->dc.clnt_cred, sizeof(vuser->dc.clnt_cred));
/* find the username */
@ -858,9 +855,13 @@ static BOOL api_net_sam_logon(pipes_struct *p)
free((char *)gids);
}
if(!net_reply_sam_logon(&q_l, rdata, &srv_cred, &usr_info, status))
if(!net_reply_sam_logon(&q_l, rdata, &srv_cred, &usr_info, status)) {
free_user_info3(&usr_info);
return False;
}
free_user_info3(&usr_info);
return True;
}

View File

@ -1487,19 +1487,12 @@ BOOL domain_client_validate( char *user, char *domain,
cli_ulogoff(&cli);
cli_shutdown(&cli);
/* unused, so delete here. */
if (info3.gids != NULL)
free (info3.gids);
if((nt_rpc_err == NT_STATUS_NO_SUCH_USER) && (user_exists != NULL))
*user_exists = False;
return False;
}
/* unused, so delete here. */
if (info3.gids != NULL)
free (info3.gids);
/*
* Here, if we really want it, we have lots of info about the user in info3.
*/
@ -1521,6 +1514,10 @@ BOOL domain_client_validate( char *user, char *domain,
}
#endif /* 0 */
/* Note - once the cli stream is shutdown the mem_ctx used
to allocate the other_sids and gids structures has been deleted - so
these pointers are no longer valid..... */
cli_nt_session_close(&cli);
cli_ulogoff(&cli);
cli_shutdown(&cli);