diff options
author | Jeremy Allison <jra@samba.org> | 2000-09-06 01:06:39 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2000-09-06 01:06:39 +0000 |
commit | a1f66a820d78244fcab960fe33999c76cc1d65c5 (patch) | |
tree | 865aebe7877f3e7844df8d109f842be0f3edd9dd | |
parent | d644d4438cfef54733118cbd09f89518ffb318ca (diff) | |
download | samba-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.h | 3 | ||||
-rw-r--r-- | source3/include/rpc_lsa.h | 2 | ||||
-rw-r--r-- | source3/include/rpc_netlogon.h | 5 | ||||
-rw-r--r-- | source3/rpc_parse/parse_net.c | 68 | ||||
-rw-r--r-- | source3/rpc_server/srv_netlog.c | 17 | ||||
-rw-r--r-- | source3/smbd/password.c | 11 |
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); |