summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2000-09-06 01:06:39 +0000
committerJeremy Allison <jra@samba.org>2000-09-06 01:06:39 +0000
commita1f66a820d78244fcab960fe33999c76cc1d65c5 (patch)
tree865aebe7877f3e7844df8d109f842be0f3edd9dd
parentd644d4438cfef54733118cbd09f89518ffb318ca (diff)
downloadsamba-a1f66a820d78244fcab960fe33999c76cc1d65c5.tar.gz
samba-a1f66a820d78244fcab960fe33999c76cc1d65c5.tar.bz2
samba-a1f66a820d78244fcab960fe33999c76cc1d65c5.zip
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 used to be commit 2b1f66eb82f05fe0b85ac5b4916e32847b8de675)
-rw-r--r--source3/include/proto.h3
-rw-r--r--source3/include/rpc_lsa.h2
-rw-r--r--source3/include/rpc_netlogon.h5
-rw-r--r--source3/rpc_parse/parse_net.c68
-rw-r--r--source3/rpc_server/srv_netlog.c17
-rw-r--r--source3/smbd/password.c11
6 files changed, 76 insertions, 30 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 393c417f60..3a43907b4b 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -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);
diff --git a/source3/include/rpc_lsa.h b/source3/include/rpc_lsa.h
index c7fe77021b..7ba9cea0a2 100644
--- a/source3/include/rpc_lsa.h
+++ b/source3/include/rpc_lsa.h
@@ -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
diff --git a/source3/include/rpc_netlogon.h b/source3/include/rpc_netlogon.h
index 9f6757ca63..0404afd9e5 100644
--- a/source3/include/rpc_netlogon.h
+++ b/source3/include/rpc_netlogon.h
@@ -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;
diff --git a/source3/rpc_parse/parse_net.c b/source3/rpc_parse/parse_net.c
index 06430e75e6..6aa7f5e518 100644
--- a/source3/rpc_parse/parse_net.c
+++ b/source3/rpc_parse/parse_net.c
@@ -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;
diff --git a/source3/rpc_server/srv_netlog.c b/source3/rpc_server/srv_netlog.c
index f634b8e15f..9f5d84ee1f 100644
--- a/source3/rpc_server/srv_netlog.c
+++ b/source3/rpc_server/srv_netlog.c
@@ -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;
}
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index 9e59815e52..6d3a2d1a31 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -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);