Remove the requirement for ldap call made as root. Add in security
authorJeremy Allison <jra@samba.org>
Mon, 20 Oct 2008 23:51:37 +0000 (16:51 -0700)
committerJeremy Allison <jra@samba.org>
Mon, 20 Oct 2008 23:51:37 +0000 (16:51 -0700)
checks for all SAMR calls.
Jeremy.

source3/lib/smbldap.c
source3/rpc_server/srv_samr_nt.c

index f5e152bb959f0ce9b5421a01069a7ed968c3be28..f2161dc946f4f15247782248494f9051442a9166 100644 (file)
@@ -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))) {
 
index e527631cc116bf31002e69fe3b451973c25177b2..261d77ca65dfda6e64bdeb82598619017de21817 100644 (file)
@@ -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",