summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/rpc_server/srv_samr_nt.c75
1 files changed, 62 insertions, 13 deletions
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index 181e1140eb..9f0ce9b05d 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -57,6 +57,34 @@ static void free_samr_info(void *ptr)
}
/*******************************************************************
+ Ensure password info is never given out. Paranioa... JRA.
+ ********************************************************************/
+
+static void samr_clear_passwd_fields( SAM_USER_INFO_21 *pass, int num_entries)
+{
+ int i;
+
+ if (!pass)
+ return;
+
+ for (i = 0; i < num_entries; i++) {
+ memset(&pass[i].lm_pwd, '\0', sizeof(pass[i].lm_pwd));
+ memset(&pass[i].nt_pwd, '\0', sizeof(pass[i].nt_pwd));
+ }
+}
+
+static void samr_clear_sam_passwd( SAM_ACCOUNT *sam_pass)
+{
+ if (!sam_pass)
+ return;
+
+ if (sam_pass->lm_pw)
+ memset(sam_pass->lm_pw, '\0', 16);
+ if (sam_pass->nt_pw)
+ memset(sam_pass->nt_pw, '\0', 16);
+}
+
+/*******************************************************************
This next function should be replaced with something that
dynamically returns the correct user info..... JRA.
********************************************************************/
@@ -660,6 +688,8 @@ uint32 _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_
if (!ret)
return NT_STATUS_ACCESS_DENIED;
+ samr_clear_passwd_fields(pass, num_entries);
+
/*
* Note from JRA. total_entries is not being used here. Currently if there is a
* large user base then it looks like NT will enumerate until get_sampwd_entries
@@ -979,6 +1009,9 @@ uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_
DEBUG(5, ("limiting number of entries to %d\n", num_entries));
}
+ /* Ensure password info is never given out here. PARANOIA... JRA */
+ samr_clear_passwd_fields(pass, num_entries);
+
data_size = q_u->max_size;
orig_num_entries = num_entries;
@@ -1308,7 +1341,7 @@ uint32 _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP
}
/*******************************************************************
- _api_samr_open_user
+ _api_samr_open_user. Safe - gives out no passwd info.
********************************************************************/
uint32 _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
@@ -1334,6 +1367,8 @@ uint32 _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_U
if (sampass == NULL)
return NT_STATUS_NO_SUCH_USER;
+ samr_clear_sam_passwd(sampass);
+
/* Get the domain SID stored in the domain policy */
if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
return NT_STATUS_INVALID_HANDLE;
@@ -1357,7 +1392,7 @@ uint32 _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_U
}
/*************************************************************************
- get_user_info_10
+ get_user_info_10. Safe. Only gives out acb bits.
*************************************************************************/
static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
@@ -1386,30 +1421,40 @@ static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
}
/*************************************************************************
- get_user_info_12
+ get_user_info_12. OK - this is the killer as it gives out password info.
+ Ensure that this is only allowed on an encrypted connection with a root
+ user. JRA.
*************************************************************************/
-static BOOL get_user_info_12(SAM_USER_INFO_12 * id12, uint32 user_rid)
+static uint32 get_user_info_12(pipes_struct *p, SAM_USER_INFO_12 * id12, uint32 user_rid)
{
SAM_ACCOUNT *smbpass;
- become_root();
+ if (!p->ntlmssp_auth_validated)
+ return NT_STATUS_ACCESS_DENIED;
+
+ if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
+ return NT_STATUS_ACCESS_DENIED;
+
+ /*
+ * Do *NOT* do become_root()/unbecome_root() here ! JRA.
+ */
+
smbpass = pdb_getsampwrid(user_rid);
- unbecome_root();
if (smbpass == NULL) {
DEBUG(4, ("User 0x%x not found\n", user_rid));
- return False;
+ return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
}
DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED)
- return False;
+ return NT_STATUS_ACCOUNT_DISABLED;
init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
- return True;
+ return NT_STATUS_NOPROBLEMO;
}
/*************************************************************************
@@ -1434,6 +1479,8 @@ static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
return False;
}
+ samr_clear_sam_passwd(sampass);
+
DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
init_sam_user_info21A(id21, sampass);
@@ -1512,8 +1559,8 @@ uint32 _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_
if (ctr->info.id12 == NULL)
return NT_STATUS_NO_MEMORY;
- if (!get_user_info_12(ctr->info.id12, rid))
- return NT_STATUS_NO_SUCH_USER;
+ if ((r_u->status = get_user_info_12(p, ctr->info.id12, rid)) != NT_STATUS_NOPROBLEMO)
+ return r_u->status;
break;
case 21:
@@ -1567,6 +1614,8 @@ uint32 _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAM
if (sam_pass == NULL)
return NT_STATUS_NO_SUCH_USER;
+ samr_clear_sam_passwd(sam_pass);
+
get_domain_user_groups(groups, pdb_get_username(sam_pass));
gids = NULL;
num_groups = make_dom_gids(p->mem_ctx, groups, &gids);
@@ -2392,8 +2441,8 @@ uint32 _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SE
uint32 _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
{
- DEBUG(0,("_samr_get_dom_pwinfo: Not yet implemented.\n"));
- return False;
+ /* Actually, returning zeros here works quite well :-). */
+ return NT_STATUS_NOPROBLEMO;
}
/*********************************************************************