a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher/*
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher SSSD
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher Authors:
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher Stephen Gallagher <sgallagh@redhat.com>
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher Copyright (C) 2012 Red Hat
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher This program is free software; you can redistribute it and/or modify
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher it under the terms of the GNU General Public License as published by
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher the Free Software Foundation; either version 3 of the License, or
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher (at your option) any later version.
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher This program is distributed in the hope that it will be useful,
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher but WITHOUT ANY WARRANTY; without even the implied warranty of
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher GNU General Public License for more details.
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher You should have received a copy of the GNU General Public License
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher along with this program. If not, see <http://www.gnu.org/licenses/>.
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher*/
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher#include <security/pam_modules.h>
f929e9e5a6daa71a22176b08eb7983fb4b708180Lukas Slebodnik#include <syslog.h>
f929e9e5a6daa71a22176b08eb7983fb4b708180Lukas Slebodnik
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher#include "src/util/util.h"
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher#include "src/providers/data_provider.h"
cc2d77d5218c188119fa954c856e858cbde76947Pavel Březina#include "src/providers/backend.h"
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher#include "src/providers/ad/ad_access.h"
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley#include "providers/ad/ad_gpo.h"
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek#include "src/providers/ad/ad_common.h"
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher#include "src/providers/ldap/sdap_access.h"
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek/*
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * More advanced format can be used to restrict the filter to a specific
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * domain or a specific forest. This format is KEYWORD:NAME:FILTER
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek *
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * KEYWORD can be one of DOM or FOREST
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * KEYWORD can be missing
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * NAME is a label.
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * - if KEYWORD equals DOM or missing completely, the filter is applied
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * for users from domain named NAME only
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * - if KEYWORD equals FOREST, the filter is applied on users from
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * forest named NAME only
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * examples of valid filters are:
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * apply filter on domain called dom1 only:
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * dom1:(memberOf=cn=admins,ou=groups,dc=dom1,dc=com)
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * apply filter on domain called dom2 only:
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * DOM:dom2:(memberOf=cn=admins,ou=groups,dc=dom2,dc=com)
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * apply filter on forest called EXAMPLE.COM only:
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * FOREST:EXAMPLE.COM:(memberOf=cn=admins,ou=groups,dc=example,dc=com)
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek *
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * If any of the extended formats are used, the filter MUST be enclosed
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * already.
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek */
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek/* From least specific */
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek#define AD_FILTER_GENERIC 0x01
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek#define AD_FILTER_FOREST 0x02
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek#define AD_FILTER_DOMAIN 0x04
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek#define KW_FOREST "FOREST"
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek#define KW_DOMAIN "DOM"
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek/* parse filter in the format domain_name:filter */
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozekstatic errno_t
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozekparse_sub_filter(TALLOC_CTX *mem_ctx, const char *full_filter,
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek char **filter, char **sub_name, int *flags,
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek const int flagconst)
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek{
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek char *specdelim;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek specdelim = strchr(full_filter, ':');
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek if (specdelim == NULL) return EINVAL;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek /* Make sure the filter is already enclosed in brackets */
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek if (*(specdelim+1) != '(') return EINVAL;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek *sub_name = talloc_strndup(mem_ctx, full_filter, specdelim - full_filter);
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek *filter = talloc_strdup(mem_ctx, specdelim+1);
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek if (*sub_name == NULL || *filter == NULL) return ENOMEM;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek *flags = flagconst;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek return EOK;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek}
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozekstatic inline errno_t
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozekparse_dom_filter(TALLOC_CTX *mem_ctx, const char *dom_filter,
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek char **filter, char **domname, int *flags)
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek{
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek return parse_sub_filter(mem_ctx, dom_filter, filter, domname,
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek flags, AD_FILTER_DOMAIN);
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek}
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozekstatic inline errno_t
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozekparse_forest_filter(TALLOC_CTX *mem_ctx, const char *forest_filter,
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek char **filter, char **forest_name, int *flags)
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek{
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek return parse_sub_filter(mem_ctx, forest_filter, filter, forest_name,
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek flags, AD_FILTER_FOREST);
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek}
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozekstatic errno_t
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozekparse_filter(TALLOC_CTX *mem_ctx, const char *full_filter,
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek char **filter, char **spec, int *flags)
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek{
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek char *kwdelim, *specdelim;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek if (filter == NULL || spec == NULL || flags == NULL) return EINVAL;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek kwdelim = strchr(full_filter, ':');
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek if (kwdelim != NULL) {
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek specdelim = strchr(kwdelim+1, ':');
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek if (specdelim == NULL) {
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek /* There is a single keyword. Treat it as a domain name */
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek return parse_dom_filter(mem_ctx, full_filter, filter, spec, flags);
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek } else if (strncmp(full_filter, "DOM", kwdelim-full_filter) == 0) {
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek /* The format must be DOM:domain_name:filter */
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek if (specdelim && specdelim-kwdelim <= 1) {
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek /* Check if there is some domain_name */
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek return EINVAL;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek }
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek return parse_dom_filter(mem_ctx, kwdelim + 1, filter, spec, flags);
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek } else if (strncmp(full_filter, "FOREST", kwdelim-full_filter) == 0) {
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek /* The format must be FOREST:forest_name:filter */
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek if (specdelim && specdelim-kwdelim <= 1) {
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek /* Check if there is some domain_name */
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek return EINVAL;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek }
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek return parse_forest_filter(mem_ctx, kwdelim + 1,
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek filter, spec, flags);
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek }
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek /* Malformed option */
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Keyword in filter [%s] did not match expected format\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov full_filter);
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek return EINVAL;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek }
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek /* No keyword. Easy. */
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek *filter = talloc_strdup(mem_ctx, full_filter);
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek if (*filter == NULL) return ENOMEM;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek *spec = NULL;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek *flags = AD_FILTER_GENERIC;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek return EOK;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek}
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozekstatic errno_t
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozekad_parse_access_filter(TALLOC_CTX *mem_ctx,
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek struct sss_domain_info *dom,
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek const char *filter_list,
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek char **_filter)
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek{
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek char **filters;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek int nfilters;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek errno_t ret;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek char *best_match;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek int best_flags;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek char *filter;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek char *spec;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek int flags;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek TALLOC_CTX *tmp_ctx;
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley int i = 0;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
64cb81a65e584858dd631bc5160959d350c091e3Jakub Hrozek if (_filter == NULL) return EINVAL;
64cb81a65e584858dd631bc5160959d350c091e3Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek tmp_ctx = talloc_new(mem_ctx);
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek if (tmp_ctx == NULL) {
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek ret = ENOMEM;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek goto done;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek }
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
64cb81a65e584858dd631bc5160959d350c091e3Jakub Hrozek if (filter_list == NULL) {
64cb81a65e584858dd631bc5160959d350c091e3Jakub Hrozek *_filter = NULL;
64cb81a65e584858dd631bc5160959d350c091e3Jakub Hrozek ret = EOK;
64cb81a65e584858dd631bc5160959d350c091e3Jakub Hrozek goto done;
64cb81a65e584858dd631bc5160959d350c091e3Jakub Hrozek }
64cb81a65e584858dd631bc5160959d350c091e3Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek ret = split_on_separator(tmp_ctx, filter_list, '?', true, true,
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek &filters, &nfilters);
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek if (ret != EOK) {
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Cannot parse the list of ad_access_filters\n");
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek goto done;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek }
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek best_match = NULL;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek best_flags = 0;
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley for (i=0; i < nfilters; i++) {
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek ret = parse_filter(tmp_ctx, filters[i], &filter, &spec, &flags);
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek if (ret != EOK) {
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek /* Skip the faulty filter. At worst, the user won't be
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * allowed access */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_MINOR_FAILURE, "Access filter [%s] could not be "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "parsed, skipping\n", filters[i]);
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek continue;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek }
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek if (flags & AD_FILTER_DOMAIN && strcasecmp(spec, dom->name) != 0) {
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek /* If the filter specifies a domain, it must match the
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * domain the user comes from
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek */
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek continue;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek }
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek if (flags & AD_FILTER_FOREST && strcasecmp(spec, dom->forest) != 0) {
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek /* If the filter specifies a forest, it must match the
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek * forest the user comes from
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek */
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek continue;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek }
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek if (flags > best_flags) {
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek best_flags = flags;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek best_match = filter;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek }
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek }
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek ret = EOK;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek /* Make sure the result is enclosed in brackets */
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek *_filter = sdap_get_access_filter(mem_ctx, best_match);
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozekdone:
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek talloc_free(tmp_ctx);
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek return ret;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek}
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozekstruct ad_access_state {
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek struct tevent_context *ev;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek struct ad_access_ctx *ctx;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek struct pam_data *pd;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek struct be_ctx *be_ctx;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek struct sss_domain_info *domain;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek char *filter;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek struct sdap_id_conn_ctx **clist;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek int cindex;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek};
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleystatic errno_t
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyad_sdap_access_step(struct tevent_req *req, struct sdap_id_conn_ctx *conn);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleystatic void
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyad_sdap_access_done(struct tevent_req *req);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozekstatic struct tevent_req *
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozekad_access_send(TALLOC_CTX *mem_ctx,
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek struct tevent_context *ev,
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek struct be_ctx *be_ctx,
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek struct sss_domain_info *domain,
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek struct ad_access_ctx *ctx,
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek struct pam_data *pd)
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek{
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek struct tevent_req *req;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek struct ad_access_state *state;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek errno_t ret;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek req = tevent_req_create(mem_ctx, &state, struct ad_access_state);
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek if (req == NULL) {
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek return NULL;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek }
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek state->ev = ev;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek state->ctx = ctx;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek state->pd = pd;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek state->be_ctx = be_ctx;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek state->domain = domain;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek ret = ad_parse_access_filter(state, domain, ctx->sdap_access_ctx->filter,
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek &state->filter);
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Could not determine the best filter\n");
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek ret = ERR_ACCESS_DENIED;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek goto done;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek }
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
72ae534f5aef6d2e5d3f2f51299aede5abf9687eJakub Hrozek state->clist = ad_gc_conn_list(state, ctx->ad_id_ctx, domain);
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek if (state->clist == NULL) {
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek ret = ENOMEM;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek goto done;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek }
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = ad_sdap_access_step(req, state->clist[state->cindex]);
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek if (ret != EOK) {
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek goto done;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek }
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek ret = EOK;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozekdone:
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek if (ret != EOK) {
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek tevent_req_error(req, ret);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek tevent_req_post(req, ev);
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek }
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek return req;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek}
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozekstatic errno_t
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyad_sdap_access_step(struct tevent_req *req, struct sdap_id_conn_ctx *conn)
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek{
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek struct tevent_req *subreq;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek struct ad_access_state *state;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek struct sdap_access_ctx *req_ctx;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek state = tevent_req_data(req, struct ad_access_state);
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek req_ctx = talloc(state, struct sdap_access_ctx);
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek if (req_ctx == NULL) {
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek return ENOMEM;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek }
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek req_ctx->id_ctx = state->ctx->sdap_access_ctx->id_ctx;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek req_ctx->filter = state->filter;
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek memcpy(&req_ctx->access_rule,
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek state->ctx->sdap_access_ctx->access_rule,
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek sizeof(int) * LDAP_ACCESS_LAST);
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley subreq = sdap_access_send(state, state->ev, state->be_ctx,
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek state->domain, req_ctx,
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek conn, state->pd);
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek if (req == NULL) {
1ce58f139699dd26b8888f4131c996263b6a80a5Jakub Hrozek talloc_free(req_ctx);
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek return ENOMEM;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek }
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley tevent_req_set_callback(subreq, ad_sdap_access_done, req);
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek return EOK;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek}
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozekstatic void
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyad_gpo_access_done(struct tevent_req *subreq);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleystatic void
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyad_sdap_access_done(struct tevent_req *subreq)
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek{
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek struct tevent_req *req;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek struct ad_access_state *state;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek errno_t ret;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek req = tevent_req_callback_data(subreq, struct tevent_req);
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek state = tevent_req_data(req, struct ad_access_state);
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek ret = sdap_access_recv(subreq);
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek talloc_zfree(subreq);
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if (ret != EOK) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley switch (ret) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley case ERR_ACCOUNT_EXPIRED:
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley tevent_req_error(req, ret);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley return;
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley case ERR_ACCESS_DENIED:
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* Retry on ACCESS_DENIED, too, to make sure that we don't
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * miss out any attributes not present in GC
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * FIXME - this is slow. We should retry only if GC failed
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * and LDAP succeeded after the first ACCESS_DENIED
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley break;
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley default:
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley break;
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley }
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* If possible, retry with LDAP */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley state->cindex++;
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if (state->clist[state->cindex] == NULL) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "Error retrieving access check result: %s\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley sss_strerror(ret));
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley tevent_req_error(req, ret);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley return;
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley }
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = ad_sdap_access_step(req, state->clist[state->cindex]);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if (ret != EOK) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley tevent_req_error(req, ret);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley return;
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley }
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* Another check in progress */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek return;
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley }
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley switch (state->ctx->gpo_access_control_mode) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley case GPO_ACCESS_CONTROL_DISABLED:
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* do not evaluate gpos; mark request done */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley tevent_req_done(req);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley return;
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley case GPO_ACCESS_CONTROL_PERMISSIVE:
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley case GPO_ACCESS_CONTROL_ENFORCING:
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* continue on to evaluate gpos */
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek break;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek default:
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley tevent_req_error(req, EINVAL);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley return;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek }
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley subreq = ad_gpo_access_send(state,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley state->be_ctx->ev,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley state->domain,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley state->ctx,
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley state->pd->user,
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley state->pd->service);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if (!subreq) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley tevent_req_error(req, ENOMEM);
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek return;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek }
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley tevent_req_set_callback(subreq, ad_gpo_access_done, req);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley}
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleystatic void
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyad_gpo_access_done(struct tevent_req *subreq)
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley{
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley struct tevent_req *req;
f929e9e5a6daa71a22176b08eb7983fb4b708180Lukas Slebodnik struct ad_access_state *state;
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley errno_t ret;
f929e9e5a6daa71a22176b08eb7983fb4b708180Lukas Slebodnik enum gpo_access_control_mode mode;
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley req = tevent_req_callback_data(subreq, struct tevent_req);
f929e9e5a6daa71a22176b08eb7983fb4b708180Lukas Slebodnik state = tevent_req_data(req, struct ad_access_state);
f929e9e5a6daa71a22176b08eb7983fb4b708180Lukas Slebodnik mode = state->ctx->gpo_access_control_mode;
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = ad_gpo_access_recv(subreq);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley talloc_zfree(subreq);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if (ret == EOK) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_TRACE_FUNC, "GPO-based access control successful.\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley tevent_req_done(req);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley } else {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "GPO-based access control failed.\n");
f929e9e5a6daa71a22176b08eb7983fb4b708180Lukas Slebodnik if (mode == GPO_ACCESS_CONTROL_ENFORCING) {
f929e9e5a6daa71a22176b08eb7983fb4b708180Lukas Slebodnik tevent_req_error(req, ret);
f929e9e5a6daa71a22176b08eb7983fb4b708180Lukas Slebodnik } else {
f929e9e5a6daa71a22176b08eb7983fb4b708180Lukas Slebodnik DEBUG(SSSDBG_OP_FAILURE,
f929e9e5a6daa71a22176b08eb7983fb4b708180Lukas Slebodnik "Ignoring error: [%d](%s); GPO-based access control failed, "
f929e9e5a6daa71a22176b08eb7983fb4b708180Lukas Slebodnik "but GPO is not in enforcing mode.\n",
f929e9e5a6daa71a22176b08eb7983fb4b708180Lukas Slebodnik ret, sss_strerror(ret));
f929e9e5a6daa71a22176b08eb7983fb4b708180Lukas Slebodnik sss_log_ext(SSS_LOG_WARNING, LOG_AUTHPRIV, "Warning: user would "
f929e9e5a6daa71a22176b08eb7983fb4b708180Lukas Slebodnik "have been denied GPO-based logon access if the "
f929e9e5a6daa71a22176b08eb7983fb4b708180Lukas Slebodnik "ad_gpo_access_control option were set to enforcing mode.");
f929e9e5a6daa71a22176b08eb7983fb4b708180Lukas Slebodnik tevent_req_done(req);
f929e9e5a6daa71a22176b08eb7983fb4b708180Lukas Slebodnik }
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek }
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek}
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozekstatic errno_t
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozekad_access_recv(struct tevent_req *req)
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek{
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek TEVENT_REQ_RETURN_ON_ERROR(req);
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek return EOK;
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek}
67b1fc914190e12ab014c0616b7f0a642fbe6356Jakub Hrozek
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březinastruct ad_pam_access_handler_state {
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct pam_data *pd;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina};
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březinastatic void ad_pam_access_handler_done(struct tevent_req *subreq);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březinastruct tevent_req *
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březinaad_pam_access_handler_send(TALLOC_CTX *mem_ctx,
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct ad_access_ctx *access_ctx,
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct pam_data *pd,
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct dp_req_params *params)
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher{
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct ad_pam_access_handler_state *state;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct tevent_req *subreq;
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher struct tevent_req *req;
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina req = tevent_req_create(mem_ctx, &state,
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct ad_pam_access_handler_state);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina if (req == NULL) {
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina return NULL;
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher }
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina state->pd = pd;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina subreq = ad_access_send(state, params->ev, params->be_ctx,
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina params->domain, access_ctx, pd);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina if (subreq == NULL) {
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina pd->pam_status = PAM_SYSTEM_ERR;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina goto immediately;
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher }
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina tevent_req_set_callback(subreq, ad_pam_access_handler_done, req);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina return req;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březinaimmediately:
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina /* TODO For backward compatibility we always return EOK to DP now. */
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina tevent_req_done(req);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina tevent_req_post(req, params->ev);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina return req;
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher}
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březinastatic void ad_pam_access_handler_done(struct tevent_req *subreq)
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher{
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct ad_pam_access_handler_state *state;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct tevent_req *req;
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher errno_t ret;
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina state = tevent_req_data(req, struct ad_pam_access_handler_state);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina ret = ad_access_recv(subreq);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina talloc_free(subreq);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce switch (ret) {
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce case EOK:
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina state->pd->pam_status = PAM_SUCCESS;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina break;
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce case ERR_ACCESS_DENIED:
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina state->pd->pam_status = PAM_PERM_DENIED;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina break;
ee02e59e4d966f44c7a48ad04474156fc65d7006Pavel Březina case ERR_ACCOUNT_EXPIRED:
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina state->pd->pam_status = PAM_ACCT_EXPIRED;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina break;
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce default:
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina state->pd->pam_status = PAM_SYSTEM_ERR;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina break;
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher }
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina /* TODO For backward compatibility we always return EOK to DP now. */
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina tevent_req_done(req);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina}
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březinaerrno_t
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březinaad_pam_access_handler_recv(TALLOC_CTX *mem_ctx,
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct tevent_req *req,
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct pam_data **_data)
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina{
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct ad_pam_access_handler_state *state = NULL;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina state = tevent_req_data(req, struct ad_pam_access_handler_state);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina TEVENT_REQ_RETURN_ON_ERROR(req);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina *_data = talloc_steal(mem_ctx, state->pd);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina return EOK;
a4cce2c98eedecb5d3b47da62104634cae268434Stephen Gallagher}