summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2008-10-20 16:51:37 -0700
committerJeremy Allison <jra@samba.org>2008-10-20 16:51:37 -0700
commitf0b1a1bc9b74372e2af2a48ce9b06802b2198eb4 (patch)
treeb7b20faa5b6c1cbe0f67600d36862b6ea782d742
parent29c9b88e2bb5d3f585e7aa591870e8b39a0d23c9 (diff)
downloadsamba-f0b1a1bc9b74372e2af2a48ce9b06802b2198eb4.tar.gz
samba-f0b1a1bc9b74372e2af2a48ce9b06802b2198eb4.tar.bz2
samba-f0b1a1bc9b74372e2af2a48ce9b06802b2198eb4.zip
Remove the requirement for ldap call made as root. Add in security
checks for all SAMR calls. Jeremy.
-rw-r--r--source3/lib/smbldap.c7
-rw-r--r--source3/rpc_server/srv_samr_nt.c67
2 files changed, 63 insertions, 11 deletions
diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c
index f5e152bb95..f2161dc946 100644
--- a/source3/lib/smbldap.c
+++ b/source3/lib/smbldap.c
@@ -1025,13 +1025,6 @@ static int smbldap_open(struct smbldap_state *ldap_state)
int rc, opt_rc;
bool reopen = False;
SMB_ASSERT(ldap_state);
-
-#ifndef NO_LDAP_SECURITY
- if (geteuid() != 0) {
- DEBUG(0, ("smbldap_open: cannot access LDAP when not root\n"));
- return LDAP_INSUFFICIENT_ACCESS;
- }
-#endif
if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + SMBLDAP_DONT_PING_TIME) < time(NULL))) {
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index e527631cc1..261d77ca65 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -825,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 */
@@ -1153,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");
@@ -1160,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;
@@ -1429,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
@@ -2062,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));
@@ -2632,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);
@@ -2880,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:
@@ -5605,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) {
@@ -5672,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__));
@@ -5680,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",