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 +#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",