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:
parent
55ed0a9b0c
commit
2b1f66eb82
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user