107-srv_samr_nt.c.diff   [plain text]


Index: samba/source/rpc_server/srv_samr_nt.c
===================================================================
--- samba/source/rpc_server/srv_samr_nt.c.orig
+++ samba/source/rpc_server/srv_samr_nt.c
@@ -33,6 +33,10 @@
 
 #include "includes.h"
 
+#ifdef HAVE_MEMBERSHIP_H
+#include <membership.h>
+#endif /* HAVE_MEMBERSHIP_H */
+
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_SRV
 
@@ -45,6 +49,10 @@
 
 #define DISP_INFO_CACHE_TIMEOUT 10
 
+#if defined(HAVE_MBR_UID_TO_UUID) && defined(HAVE_MBR_GID_TO_UUID) && defined(HAVE_MBR_CHECK_MEMBERSHIP)
+#define HAVE_MEMBERD
+#endif
+
 typedef struct disp_info {
 	DOM_SID sid; /* identify which domain this is. */
 	BOOL builtin_domain; /* Quick flag to check if this is the builtin domain. */
@@ -107,6 +115,58 @@ static struct generic_mapping ali_generi
 /*******************************************************************
 *******************************************************************/
 
+#ifdef HAVE_MEMBERD
+
+static BOOL is_member_of_group(uid_t uid, gid_t gid)
+{
+	uuid_t user_uuid;
+	uuid_t grp_uuid;
+	int result = 0;
+	char uustr[50];
+	int ismember = 0;
+
+	DEBUG(4,("is_member_of_group(uid<%d>, gid<%d>)\n", uid, gid));
+
+	uuid_clear(user_uuid);
+	if ((result = mbr_uid_to_uuid( uid, user_uuid)) != 0) {
+		DEBUG(0,("[%d]mbr_uid_to_uuid: errno(%d) - (%s)\n",
+		    result, errno, strerror(errno)));
+		return False;
+	}
+
+	uuid_clear(grp_uuid);
+	if ((result = mbr_gid_to_uuid( gid, grp_uuid)) != 0) {
+		DEBUG(0,("[%d]mbr_gid_to_uuid: errno(%d) - (%s)\n",
+		    result, errno, strerror(errno)));
+		return False;
+	}
+
+	uuid_unparse(grp_uuid, uustr);
+	DEBUG(4,("mbr_gid_to_uuid: (%s)\n", uustr));
+
+	result = mbr_check_membership(user_uuid, grp_uuid, &ismember);
+	if (result != 0) {
+		DEBUG(0,("[%d]mbr_check_membership: errno(%d) - (%s)\n",
+		    result, errno, strerror(errno)));
+		return False;
+	}
+
+	DEBUG(4,("mbr_check_membership: ismember(%d)\n",ismember));
+	return ismember ? True : False;
+}
+
+#else /* HAVE_MEMBERD */
+
+static BOOL is_member_of_group(uid_t uid, gid_t gid)
+{
+	return False;
+}
+
+#endif /* HAVE_MEMBERD */
+
+/*******************************************************************
+*******************************************************************/
+
 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
                                      struct generic_mapping *map,
 				     DOM_SID *sid, uint32 sid_access )
@@ -238,6 +298,18 @@ static NTSTATUS access_check_samr_functi
 		DEBUGADD(4,("but overwritten by euid == 0\n"));
 		
 		return NT_STATUS_OK;
+	} else {
+		struct group * admin;
+		admin = getgrnam("admin");
+
+		if (admin && is_member_of_group(geteuid(), admin->gr_gid)) {
+			DEBUG(4,("%s: ACCESS should be DENIED "
+				 "(granted: %#010x;  required: %#010x)\n",
+				debug, acc_granted, acc_required));
+			DEBUGADD(4,("but overwritten by egid == %d\n",
+				admin->gr_gid));
+			return NT_STATUS_OK;
+		}
 	}
 	
 	DEBUG(2,("%s: ACCESS DENIED (granted: %#010x;  required: %#010x)\n",