summaryrefslogtreecommitdiff
path: root/source3/rpc_server/srv_samr_nt.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/rpc_server/srv_samr_nt.c')
-rw-r--r--source3/rpc_server/srv_samr_nt.c122
1 files changed, 92 insertions, 30 deletions
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index 1b1e98c049..261d77ca65 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -113,36 +113,35 @@ static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd
{
DOM_SID domadmin_sid;
SEC_ACE ace[5]; /* at most 5 entries */
- SEC_ACCESS mask;
size_t i = 0;
SEC_ACL *psa = NULL;
/* basic access for Everyone */
- init_sec_access(&mask, map->generic_execute | map->generic_read );
- init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
+ map->generic_execute | map->generic_read, 0);
/* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
- init_sec_access(&mask, map->generic_all);
-
- init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
- init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
+ SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
+ init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
+ SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
/* Add Full Access for Domain Admins if we are a DC */
if ( IS_DC ) {
sid_copy( &domadmin_sid, get_global_sam_sid() );
sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
- init_sec_ace(&ace[i++], &domadmin_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[i++], &domadmin_sid,
+ SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
}
/* if we have a sid, give it some special access */
if ( sid ) {
- init_sec_access( &mask, sid_access );
- init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, sid_access, 0);
}
/* create the security descriptor */
@@ -826,6 +825,13 @@ NTSTATUS _samr_QuerySecurity(pipes_struct *p,
DEBUG(10,("_samr_QuerySecurity: querying security on SID: %s\n",
sid_string_dbg(&pol_sid)));
+ status = access_check_samr_function(acc_granted,
+ STD_RIGHT_READ_CONTROL_ACCESS,
+ "_samr_QuerySecurity");
+ if (NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
/* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
/* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
@@ -1154,6 +1160,9 @@ NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
return NT_STATUS_INVALID_HANDLE;
+ DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
+ sid_string_dbg(&info->sid)));
+
status = access_check_samr_function(info->acc_granted,
SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
"_samr_EnumDomainAliases");
@@ -1161,9 +1170,6 @@ NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
return status;
}
- DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
- sid_string_dbg(&info->sid)));
-
samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
if (!samr_array) {
return NT_STATUS_NO_MEMORY;
@@ -1430,6 +1436,13 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
return NT_STATUS_INVALID_HANDLE;
+ status = access_check_samr_function(info->acc_granted,
+ SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
+ "_samr_QueryDisplayInfo");
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
/*
* calculate how many entries we will return.
* based on
@@ -2063,6 +2076,13 @@ NTSTATUS _samr_LookupRids(pipes_struct *p,
if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
return NT_STATUS_INVALID_HANDLE;
+ status = access_check_samr_function(acc_granted,
+ SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
+ "_samr__LookupRids");
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
if (num_rids > 1000) {
DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
"to samba4 idl this is not possible\n", num_rids));
@@ -2438,7 +2458,7 @@ static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
if (munged_dial) {
blob = base64_decode_data_blob(munged_dial);
} else {
- blob = data_blob_string_const("");
+ blob = data_blob_string_const_null("");
}
status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
@@ -2547,7 +2567,7 @@ static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
if (munged_dial) {
blob = base64_decode_data_blob(munged_dial);
} else {
- blob = data_blob_string_const("");
+ blob = data_blob_string_const_null("");
}
status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
@@ -2633,6 +2653,13 @@ NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
return NT_STATUS_INVALID_HANDLE;
+ status = access_check_samr_function(info->acc_granted,
+ SA_RIGHT_DOMAIN_OPEN_ACCOUNT,
+ "_samr_QueryUserInfo");
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
domain_sid = info->sid;
sid_split_rid(&domain_sid, &rid);
@@ -2881,6 +2908,13 @@ static NTSTATUS samr_QueryDomainInfo_internal(const char *fn_name,
return NT_STATUS_INVALID_HANDLE;
}
+ status = access_check_samr_function(info->acc_granted,
+ SA_RIGHT_SAM_OPEN_DOMAIN,
+ "_samr_QueryDomainInfo_internal" );
+
+ if ( !NT_STATUS_IS_OK(status) )
+ return status;
+
switch (level) {
case 0x01:
@@ -2910,6 +2944,10 @@ static NTSTATUS samr_QueryDomainInfo_internal(const char *fn_name,
unix_to_nt_time_abs(&nt_expire, u_expire);
unix_to_nt_time_abs(&nt_min_age, u_min_age);
+ if (lp_check_password_script() && *lp_check_password_script()) {
+ password_properties |= DOMAIN_PASSWORD_COMPLEX;
+ }
+
init_samr_DomInfo1(&dom_info->info1,
(uint16)min_pass_len,
(uint16)pass_hist,
@@ -2943,18 +2981,18 @@ static NTSTATUS samr_QueryDomainInfo_internal(const char *fn_name,
if (lp_server_role() == ROLE_DOMAIN_BDC)
server_role = ROLE_DOMAIN_BDC;
- init_samr_DomInfo2(&dom_info->info2,
- nt_logout,
- lp_serverstring(),
- lp_workgroup(),
- global_myname(),
- seq_num,
- 1,
- server_role,
- 1,
- num_users,
- num_groups,
- num_aliases);
+ init_samr_DomGeneralInformation(&dom_info->general,
+ nt_logout,
+ lp_serverstring(),
+ lp_workgroup(),
+ global_myname(),
+ seq_num,
+ 1,
+ server_role,
+ 1,
+ num_users,
+ num_groups,
+ num_aliases);
break;
case 0x03:
@@ -2979,8 +3017,8 @@ static NTSTATUS samr_QueryDomainInfo_internal(const char *fn_name,
break;
case 0x04:
- init_samr_DomInfo4(&dom_info->info4,
- lp_serverstring());
+ init_samr_DomOEMInformation(&dom_info->oem,
+ lp_serverstring());
break;
case 0x05:
init_samr_DomInfo5(&dom_info->info5,
@@ -5602,16 +5640,32 @@ NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
struct samr_SetDomainInfo *r)
{
+ struct samr_info *info = NULL;
time_t u_expire, u_min_age;
time_t u_logout;
time_t u_lock_duration, u_reset_time;
+ NTSTATUS result;
DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
/* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, r->in.domain_handle, NULL))
+ if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
return NT_STATUS_INVALID_HANDLE;
+ /* We do have different access bits for info
+ * levels here, but we're really just looking for
+ * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
+ * this maps to different specific bits. So
+ * assume if we have SA_RIGHT_DOMAIN_SET_INFO_1
+ * set we are ok. */
+
+ result = access_check_samr_function(info->acc_granted,
+ SA_RIGHT_DOMAIN_SET_INFO_1,
+ "_samr_SetDomainInfo");
+
+ if (!NT_STATUS_IS_OK(result))
+ return result;
+
DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
switch (r->in.level) {
@@ -5669,6 +5723,7 @@ NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
int i;
uint32_t num_account = 0;
struct samr_displayentry *entries = NULL;
+ NTSTATUS status;
DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
@@ -5677,6 +5732,13 @@ NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
return NT_STATUS_INVALID_HANDLE;
}
+ status = access_check_samr_function(info->acc_granted,
+ SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
+ "_samr_GetDisplayEnumerationIndex");
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
if ((r->in.level < 1) || (r->in.level > 3)) {
DEBUG(0,("_samr_GetDisplayEnumerationIndex: "
"Unknown info level (%u)\n",