From 1bf57dbb331607f5b7e087c2056c602aa0010af5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9her=20M=C3=A1rton?= Date: Sun, 3 Oct 2010 19:45:51 +0200 Subject: [PATCH 1/2] Modifications to implement restricted user listing. If you can use restrictions only with LDAP backend. If ldap restrictions are switched on users can see users in thei primary groups and ther primary groups if they are trying to grant ACLs on windows. This is good for anybody who is serving different customers with one samba, and don't want them to see each others users. --- source3/include/passdb.h | 7 ++++ source3/include/proto.h | 5 +++ source3/param/loadparm.c | 12 ++++++++ source3/passdb/pdb_interface.c | 35 ++++++++++++++++++++++ source3/passdb/pdb_ldap.c | 59 ++++++++++++++++++++++++++++++++++++-- source3/rpc_server/srv_samr_nt.c | 17 ++++++++-- 6 files changed, 128 insertions(+), 7 deletions(-) diff --git a/source3/include/passdb.h b/source3/include/passdb.h index 9be2a69..e78bbdb 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -395,8 +395,15 @@ struct pdb_methods bool (*search_users)(struct pdb_methods *methods, struct pdb_search *search, uint32 acct_flags); + bool (*search_users_restrictable)(struct pdb_methods *methods, + struct pdb_search *search, + uint32 acct_flags, + const struct dom_sid *domain_sid); bool (*search_groups)(struct pdb_methods *methods, struct pdb_search *search); + bool (*search_groups_restricted)(struct pdb_methods *methods, + struct pdb_search *search, + const struct dom_sid *prigrp_sid); bool (*search_aliases)(struct pdb_methods *methods, struct pdb_search *search, const DOM_SID *sid); diff --git a/source3/include/proto.h b/source3/include/proto.h index 483fd84..f28f8a4 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -3998,6 +3998,7 @@ bool lp_passdb_expand_explicit(void); char *lp_ldap_suffix(void); char *lp_ldap_admin_dn(void); int lp_ldap_ssl(void); +bool lp_ldap_restrict_userlisting(void); bool lp_ldap_ssl_ads(void); int lp_ldap_deref(void); int lp_ldap_follow_referral(void); @@ -4632,7 +4633,11 @@ bool initialize_password_db(bool reload, struct event_context *event_ctx); struct pdb_search *pdb_search_init(TALLOC_CTX *mem_ctx, enum pdb_search_type type); struct pdb_search *pdb_search_users(TALLOC_CTX *mem_ctx, uint32 acct_flags); +struct pdb_search *pdb_search_users_restrictable(TALLOC_CTX *mem_ctx, uint32 acct_flags, + const struct dom_sid *domain_sid); struct pdb_search *pdb_search_groups(TALLOC_CTX *mem_ctx); +struct pdb_search *pdb_search_groups_restricted(TALLOC_CTX *mem_ctx, + const struct dom_sid *prigrp_sid); struct pdb_search *pdb_search_aliases(TALLOC_CTX *mem_ctx, const DOM_SID *sid); uint32 pdb_search_entries(struct pdb_search *search, uint32 start_idx, uint32 max_entries, diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 57ea2cd..39fe734 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -259,6 +259,7 @@ struct global { char *szLdapIdmapSuffix; char *szLdapGroupSuffix; int ldap_ssl; + bool ldap_restrict_userlisting; bool ldap_ssl_ads; int ldap_deref; int ldap_follow_referral; @@ -3687,6 +3688,15 @@ static struct parm_struct parm_table[] = { .flags = FLAG_ADVANCED, }, { + .label = "ldap restrict userlisting", + .type = P_BOOL, + .p_class = P_GLOBAL, + .ptr = &Globals.ldap_restrict_userlisting, + .special = NULL, + .enum_list = NULL, + .flags = FLAG_ADVANCED, + }, + { .label = "ldap deref", .type = P_ENUM, .p_class = P_GLOBAL, @@ -5103,6 +5113,7 @@ static void init_globals(bool first_time_only) string_set(&Globals.szLdapAdminDn, ""); Globals.ldap_ssl = LDAP_SSL_START_TLS; Globals.ldap_ssl_ads = False; + Globals.ldap_restrict_userlisting = False; Globals.ldap_deref = -1; Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF; Globals.ldap_delete_dn = False; @@ -5459,6 +5470,7 @@ FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix) FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn) FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl) FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads) +FN_GLOBAL_BOOL(lp_ldap_restrict_userlisting, &Globals.ldap_restrict_userlisting) FN_GLOBAL_INTEGER(lp_ldap_deref, &Globals.ldap_deref) FN_GLOBAL_INTEGER(lp_ldap_follow_referral, &Globals.ldap_follow_referral) FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync) diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index de46254..5a51076 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -1841,6 +1841,24 @@ struct pdb_search *pdb_search_users(TALLOC_CTX *mem_ctx, uint32 acct_flags) return result; } +struct pdb_search *pdb_search_users_restrictable(TALLOC_CTX *mem_ctx, uint32 acct_flags, + const struct dom_sid *domain_sid) +{ + struct pdb_methods *pdb = pdb_get_methods(); + struct pdb_search *result; + + result = pdb_search_init(mem_ctx, PDB_USER_SEARCH); + if (result == NULL) { + return NULL; + } + + if (!pdb->search_users_restrictable(pdb, result, acct_flags,domain_sid)) { + TALLOC_FREE(result); + return NULL; + } + return result; +} + struct pdb_search *pdb_search_groups(TALLOC_CTX *mem_ctx) { struct pdb_methods *pdb = pdb_get_methods(); @@ -1858,6 +1876,23 @@ struct pdb_search *pdb_search_groups(TALLOC_CTX *mem_ctx) return result; } +struct pdb_search *pdb_search_groups_restricted(TALLOC_CTX *mem_ctx, const struct dom_sid *prigrp_sid) +{ + struct pdb_methods *pdb = pdb_get_methods(); + struct pdb_search *result; + + result = pdb_search_init(mem_ctx, PDB_GROUP_SEARCH); + if (result == NULL) { + return NULL; + } + + if (!pdb->search_groups_restricted(pdb, result, prigrp_sid)) { + TALLOC_FREE(result); + return NULL; + } + return result; +} + struct pdb_search *pdb_search_aliases(TALLOC_CTX *mem_ctx, const DOM_SID *sid) { struct pdb_methods *pdb = pdb_get_methods(); diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index db86a48..d532523 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -4347,6 +4347,29 @@ static char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username) return result; } +static char *get_ldap_group_filter(TALLOC_CTX *mem_ctx, const char *groupsid) +{ + char *filter = NULL; + char *escaped = NULL; + char *result = NULL; + + if (asprintf(&filter, "(&%s(objectclass=%s))", + "(sambaPrimaryGroupSID=%g)", LDAP_OBJ_SAMBASAMACCOUNT) < 0) { + goto done; + } + + escaped = escape_ldap_string(talloc(),groupsid); + if (escaped == NULL) goto done; + + result = talloc_string_sub(mem_ctx, filter, "%g", groupsid); + + done: + SAFE_FREE(filter); + SAFE_FREE(escaped); + + return result; +} + const char **talloc_attrs(TALLOC_CTX *mem_ctx, ...) { int i, num = 0; @@ -4647,13 +4670,15 @@ static bool ldapuser2displayentry(struct ldap_search_state *state, } -static bool ldapsam_search_users(struct pdb_methods *methods, +static bool ldapsam_search_users_restrictable(struct pdb_methods *methods, struct pdb_search *search, - uint32 acct_flags) + uint32 acct_flags, + const struct dom_sid *prigrp_sid) { struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)methods->private_data; struct ldap_search_state *state; + fstring tmp; state = talloc(search, struct ldap_search_state); if (state == NULL) { @@ -4674,7 +4699,13 @@ static bool ldapsam_search_users(struct pdb_methods *methods, state->acct_flags = acct_flags; state->base = talloc_strdup(search, state->base); state->scope = LDAP_SCOPE_SUBTREE; - state->filter = get_ldap_filter(search, "*"); + if (prigrp_sid == NULL) + { + state->filter = get_ldap_filter(search, "*"); + }else + { + state->filter = get_ldap_group_filter(search, sid_to_fstring(tmp,prigrp_sid)); + } state->attrs = talloc_attrs(search, "uid", "sambaSid", "displayName", "description", "sambaAcctFlags", NULL); @@ -4695,6 +4726,13 @@ static bool ldapsam_search_users(struct pdb_methods *methods, return ldapsam_search_firstpage(search); } +static bool ldapsam_search_users(struct pdb_methods *methods, + struct pdb_search *search, + uint32 acct_flags) +{ + return ldapsam_search_users_restrictable(methods, search, acct_flags, NULL); +} + static bool ldapgroup2displayentry(struct ldap_search_state *state, TALLOC_CTX *mem_ctx, LDAP *ld, LDAPMessage *entry, @@ -4871,6 +4909,19 @@ static bool ldapsam_search_groups(struct pdb_methods *methods, return ldapsam_search_grouptype(methods, search, get_global_sam_sid(), SID_NAME_DOM_GRP); } +static bool ldapsam_search_groups_restricted(struct pdb_methods *methods, + struct pdb_search *search, + const struct dom_sid *prigrp_sid) +{ + if ( prigrp_sid == NULL ) + { + return ldapsam_search_grouptype(methods, search, prigrp_sid, SID_NAME_DOM_GRP); + }else{ + return ldapsam_search_grouptype(methods, search, get_global_sam_sid(), SID_NAME_DOM_GRP); + } +} + + static bool ldapsam_search_aliases(struct pdb_methods *methods, struct pdb_search *search, const DOM_SID *sid) @@ -6584,7 +6635,9 @@ NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location) (*pdb_method)->enum_aliasmem = ldapsam_enum_aliasmem; (*pdb_method)->enum_alias_memberships = ldapsam_alias_memberships; (*pdb_method)->search_users = ldapsam_search_users; + (*pdb_method)->search_users_restrictable = ldapsam_search_users_restrictable; (*pdb_method)->search_groups = ldapsam_search_groups; + (*pdb_method)->search_groups_restricted = ldapsam_search_groups_restricted; (*pdb_method)->search_aliases = ldapsam_search_aliases; if (lp_parm_bool(-1, "ldapsam", "trusted", False)) { diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index e98e4aa..0de7f4c 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -1420,6 +1420,7 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p, enum remote_arch_types ra_type = get_remote_arch(); int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K; struct samr_displayentry *entries = NULL; + struct dom_sid *prigrp_sid = NULL; DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__)); @@ -1496,8 +1497,12 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p, case 1: case 4: if (dinfo->disp_info->users == NULL) { - dinfo->disp_info->users = pdb_search_users( - dinfo->disp_info, ACB_NORMAL); + if ( lp_ldap_restrict_userlisting() ) + { + prigrp_sid = pdb_get_group_sid(p->server_info->sam_account); + } + info->disp_info->users = pdb_search_users_restrictable( + info->disp_info, ACB_NORMAL, prigrp_sid); if (dinfo->disp_info->users == NULL) { unbecome_root(); return NT_STATUS_ACCESS_DENIED; @@ -1535,8 +1540,12 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p, case 3: case 5: if (dinfo->disp_info->groups == NULL) { - dinfo->disp_info->groups = pdb_search_groups( - dinfo->disp_info); + if ( lp_ldap_restrict_userlisting() ) + { + prigrp_sid = pdb_get_group_sid(p->server_info->sam_account); + } + info->disp_info->groups = pdb_search_groups_restricted( + info->disp_info, prigrp_sid); if (dinfo->disp_info->groups == NULL) { unbecome_root(); return NT_STATUS_ACCESS_DENIED; -- 1.7.0.4 From c3599feff5e77453fc42f2986b5c62e1f0026fe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9her=20M=C3=A1rton?= Date: Sun, 3 Oct 2010 23:45:02 +0200 Subject: [PATCH 2/2] fixing a typo --- source3/rpc_server/srv_samr_nt.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 0de7f4c..140d928 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -1501,8 +1501,8 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p, { prigrp_sid = pdb_get_group_sid(p->server_info->sam_account); } - info->disp_info->users = pdb_search_users_restrictable( - info->disp_info, ACB_NORMAL, prigrp_sid); + dinfo->disp_info->users = pdb_search_users_restrictable( + dinfo->disp_info, ACB_NORMAL, prigrp_sid); if (dinfo->disp_info->users == NULL) { unbecome_root(); return NT_STATUS_ACCESS_DENIED; @@ -1544,8 +1544,8 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p, { prigrp_sid = pdb_get_group_sid(p->server_info->sam_account); } - info->disp_info->groups = pdb_search_groups_restricted( - info->disp_info, prigrp_sid); + dinfo->disp_info->groups = pdb_search_groups_restricted( + dinfo->disp_info, prigrp_sid); if (dinfo->disp_info->groups == NULL) { unbecome_root(); return NT_STATUS_ACCESS_DENIED; -- 1.7.0.4