From df1e2693dce2da22a40ae0d0e75d2d3f35bf852f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 25 Jan 2007 00:47:27 +0000 Subject: r21009: Patch from Danilo Almeida @ Centeris (via me). Patch details: Support most options in pam_winbind.conf; support comma-separated names in require-membership-of. Details below: 1) Provides support for almost all config options in pam_winbind.conf (all except for use_first_pass, use_authtok, and unknown_ok). - That allows us to work well when invoked via call_modules from pam_unix2.conf as well as allowing use of spaces in names used w/require_membership_of. 2) Support for comma-separated list of names or SID strings in require_membership_of/require-membership-of. - Increased require_membership_of field in winbind request from fstring (256) to pstring (1024). - In PAM side, parse out multiple names or SID strings and convert all of them to SID strings. - In Winbind side, support membership check against multiple SID strings. (This used to be commit 4aca9864896b3e0890ffc9a6980d7ef1311138f7) --- source3/nsswitch/winbindd_pam.c | 74 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 9 deletions(-) (limited to 'source3/nsswitch/winbindd_pam.c') diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index b383ec663a..fcaad1fb1f 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -113,11 +113,27 @@ static NTSTATUS append_info3_as_ndr(TALLOC_CTX *mem_ctx, static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *info3, const char *group_sid) +/** + * Check whether a user belongs to a group or list of groups. + * + * @param mem_ctx talloc memory context. + * @param info3 user information, including group membership info. + * @param group_sid One or more groups , separated by commas. + * + * @return NT_STATUS_OK on success, + * NT_STATUS_LOGON_FAILURE if the user does not belong, + * or other NT_STATUS_IS_ERR(status) for other kinds of failure. + */ { - DOM_SID require_membership_of_sid; + DOM_SID *require_membership_of_sid; + size_t num_require_membership_of_sid; DOM_SID *all_sids; size_t num_all_sids = (2 + info3->num_groups2 + info3->num_other_sids); - size_t i, j = 0; + size_t i, j = 0, k; + size_t group_sid_length; + const char *search_location; + char *single_group_sid; + const char *comma; /* Parse the 'required group' SID */ @@ -125,10 +141,48 @@ static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx, /* NO sid supplied, all users may access */ return NT_STATUS_OK; } - - if (!string_to_sid(&require_membership_of_sid, group_sid)) { + + num_require_membership_of_sid = 1; + group_sid_length = strlen(group_sid); + for (i = 0; i < group_sid_length; i++) { + if (',' == group_sid[i]) { + num_require_membership_of_sid++; + } + } + + require_membership_of_sid = TALLOC_ARRAY(mem_ctx, DOM_SID, num_require_membership_of_sid); + if (!require_membership_of_sid) + return NT_STATUS_NO_MEMORY; + + i = 0; + search_location = group_sid; + + if (num_require_membership_of_sid > 1) { + + /* Allocate the maximum possible size */ + single_group_sid = TALLOC(mem_ctx, group_sid_length); + if (!single_group_sid) + return NT_STATUS_NO_MEMORY; + + while ( (comma = strstr(search_location, ",")) != NULL ) { + + strncpy(single_group_sid, search_location, comma - search_location); + single_group_sid[comma - search_location] = 0; + + if (!string_to_sid(&require_membership_of_sid[i++], single_group_sid)) { + DEBUG(0, ("check_info3_in_group: could not parse %s as a SID!", + single_group_sid)); + + return NT_STATUS_INVALID_PARAMETER; + } + + search_location = comma + 1; + } + } + + if (!string_to_sid(&require_membership_of_sid[i++], search_location)) { DEBUG(0, ("check_info3_in_group: could not parse %s as a SID!", - group_sid)); + search_location)); return NT_STATUS_INVALID_PARAMETER; } @@ -188,10 +242,12 @@ static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx, fstring sid1, sid2; DEBUG(10, ("User has SID: %s\n", sid_to_string(sid1, &all_sids[i]))); - if (sid_equal(&require_membership_of_sid, &all_sids[i])) { - DEBUG(10, ("SID %s matches %s - user permitted to authenticate!\n", - sid_to_string(sid1, &require_membership_of_sid), sid_to_string(sid2, &all_sids[i]))); - return NT_STATUS_OK; + for (k = 0; k < num_require_membership_of_sid; k++) { + if (sid_equal(&require_membership_of_sid[k], &all_sids[i])) { + DEBUG(10, ("SID %s matches %s - user permitted to authenticate!\n", + sid_to_string(sid1, &require_membership_of_sid[k]), sid_to_string(sid2, &all_sids[i]))); + return NT_STATUS_OK; + } } } -- cgit