[SSSD] [PATCH] Add simple access provider

Sumit Bose sbose at redhat.com
Thu Feb 25 17:31:41 UTC 2010


Hi,

this is the second try to fix #392. This patch adds a new provider
called simple wuth na access target which can allow/deny access based on
a list of user names.

bye,
Sumit
-------------- next part --------------
From 522c8295026705aad037956551574db325475097 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Thu, 25 Feb 2010 17:30:47 +0100
Subject: [PATCH] Add simple access provider

---
 contrib/sssd.spec.in                       |    2 +
 src/Makefile.am                            |   32 +++++-
 src/config/SSSDConfig.py                   |    4 +
 src/config/etc/sssd.api.d/sssd-simple.conf |    5 +
 src/man/sssd-simple.5.xml                  |  116 ++++++++++++++++++++
 src/man/sssd.conf.5.xml                    |    7 ++
 src/providers/simple_access.c              |  159 ++++++++++++++++++++++++++++
 src/providers/simple_access.h              |   31 ++++++
 src/tests/simple_access-tests.c            |  150 ++++++++++++++++++++++++++
 9 files changed, 502 insertions(+), 4 deletions(-)
 create mode 100644 src/config/etc/sssd.api.d/sssd-simple.conf
 create mode 100644 src/man/sssd-simple.5.xml
 create mode 100644 src/providers/simple_access.c
 create mode 100644 src/providers/simple_access.h
 create mode 100644 src/tests/simple_access-tests.c

diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
index db1c0bc..65e8868 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -241,6 +241,7 @@ rm -f \
     $RPM_BUILD_ROOT/%{_libdir}/sssd/libsss_proxy.la \
     $RPM_BUILD_ROOT/%{_libdir}/sssd/libsss_krb5.la \
     $RPM_BUILD_ROOT/%{_libdir}/sssd/libsss_ipa.la \
+    $RPM_BUILD_ROOT/%{_libdir}/sssd/libsss_simple.la \
     $RPM_BUILD_ROOT/%{_libdir}/krb5/plugins/libkrb5/sssd_krb5_locator_plugin.la \
     $RPM_BUILD_ROOT/%{python_sitearch}/pysss.la
 
@@ -288,6 +289,7 @@ rm -rf $RPM_BUILD_ROOT
 %{_mandir}/man5/sssd-ipa.5*
 %{_mandir}/man5/sssd-krb5.5*
 %{_mandir}/man5/sssd-ldap.5*
+%{_mandir}/man5/sssd-simple.5*
 %{_mandir}/man8/sssd.8*
 %{_mandir}/man8/sss_groupadd.8*
 %{_mandir}/man8/sss_groupdel.8*
diff --git a/src/Makefile.am b/src/Makefile.am
index fa62702..241daad 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -75,7 +75,8 @@ if HAVE_CHECK
         fail_over-tests \
         find_uid-tests \
         auth-tests \
-        ipa_ldap_opt-tests
+        ipa_ldap_opt-tests \
+        simple_access-tests
 endif
 
 check_PROGRAMS = \
@@ -90,7 +91,8 @@ sssdlib_LTLIBRARIES = \
     libsss_ldap.la \
     libsss_krb5.la \
     libsss_proxy.la \
-    libsss_ipa.la
+    libsss_ipa.la \
+    libsss_simple.la
 
 ldblib_LTLIBRARIES = \
     memberof.la
@@ -324,6 +326,7 @@ dist_noinst_HEADERS = \
     providers/fail_over.h \
     providers/providers.h \
     providers/child_common.h \
+    providers/simple_access.h \
     providers/krb5/krb5_auth.h \
     providers/krb5/krb5_common.h \
     providers/krb5/krb5_utils.h \
@@ -616,6 +619,17 @@ ipa_ldap_opt_tests_CFLAGS = \
 ipa_ldap_opt_tests_LDADD = \
     $(CHECK_LIBS)
 
+simple_access_tests_SOURCES = \
+    tests/simple_access-tests.c \
+    providers/simple_access.c \
+    $(SSSD_UTIL_OBJ)
+simple_access_tests_CFLAGS = \
+    $(AM_CFLAGS) \
+    $(CHECK_CFLAGS)
+simple_access_tests_LDADD = \
+    $(SSSD_LIBS) \
+    $(CHECK_LIBS)
+
 endif
 
 stress_tests_SOURCES = \
@@ -701,6 +715,16 @@ libsss_proxy_la_LDFLAGS = \
     -version-info 1:0:0 \
     -module
 
+libsss_simple_la_SOURCES = \
+    providers/simple_access.c
+libsss_simple_la_CFLAGS = \
+    $(AM_CFLAGS)
+libsss_simple_la_LIBADD = \
+    $(PAM_LIBS)
+libsss_simple_la_LDFLAGS = \
+    -version-info 1:0:0 \
+    -module
+
 libsss_krb5_la_SOURCES = \
     util/find_uid.c \
     providers/child_common.c \
@@ -840,8 +864,8 @@ XSLTPROC_FLAGS = --catalogs --xinclude --nonet
 dist_man_MANS = man/sss_useradd.8 man/sss_userdel.8 man/sss_usermod.8 \
 		man/sss_groupadd.8 man/sss_groupdel.8 man/sss_groupmod.8 \
 		man/sssd.8 man/sssd.conf.5 man/sssd-ldap.5 man/sssd-krb5.5 \
-		man/sssd-ipa.5 man/sssd_krb5_locator_plugin.8 \
-		man/sss_groupshow.8 man/pam_sss.8
+		man/sssd-ipa.5 man/sssd-simple.5 \
+		man/sssd_krb5_locator_plugin.8 man/sss_groupshow.8 man/pam_sss.8
 
 SUFFIXES = .1.xml .1 .3.xml .3 .5.xml .5 .8.xml .8
 .1.xml.1:
diff --git a/src/config/SSSDConfig.py b/src/config/SSSDConfig.py
index 2697c71..c9e08ca 100644
--- a/src/config/SSSDConfig.py
+++ b/src/config/SSSDConfig.py
@@ -144,6 +144,10 @@ option_strings = {
     # [provider/ldap/auth]
     'ldap_pwd_policy' : _('Policy to evaluate the password expiration'),
 
+    # [provider/simple/access]
+    'simple_allow_users' : _('Comma separated list of allowed users'),
+    'simple_deny_users' : _('Comma separated list of prohibited users'),
+
     # [provider/local/id]
     'default_shell' : _('Default shell, /bin/bash'),
     'base_directory' : _('Base for home directories'),
diff --git a/src/config/etc/sssd.api.d/sssd-simple.conf b/src/config/etc/sssd.api.d/sssd-simple.conf
new file mode 100644
index 0000000..13fbeb9
--- /dev/null
+++ b/src/config/etc/sssd.api.d/sssd-simple.conf
@@ -0,0 +1,5 @@
+[provider/simple]
+
+[provider/simple/access]
+simple_allow_users = str, None, false
+simple_deny_users = str, None, false
diff --git a/src/man/sssd-simple.5.xml b/src/man/sssd-simple.5.xml
new file mode 100644
index 0000000..78de831
--- /dev/null
+++ b/src/man/sssd-simple.5.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE reference PUBLIC "-//OASIS//DTD DocBook V4.4//EN"
+"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
+<reference>
+<title>SSSD Manual pages</title>
+<refentry>
+    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="include/upstream.xml" />
+
+    <refmeta>
+        <refentrytitle>sssd-simple</refentrytitle>
+        <manvolnum>5</manvolnum>
+        <refmiscinfo class="manual">File Formats and Conventions</refmiscinfo>
+    </refmeta>
+
+    <refnamediv id='name'>
+        <refname>sssd-simple</refname>
+        <refpurpose>the configuration file for SSSD</refpurpose>
+    </refnamediv>
+
+    <refsect1 id='description'>
+        <title>DESCRIPTION</title>
+        <para>
+            This manual page describes the configuration of the simple access
+            provider for
+            <citerefentry>
+                <refentrytitle>sssd</refentrytitle>
+                <manvolnum>8</manvolnum>
+            </citerefentry>.
+            For a detailed syntax reference, refer to the <quote>FILE FORMAT</quote> section of the
+            <citerefentry>
+                <refentrytitle>sssd.conf</refentrytitle>
+                <manvolnum>5</manvolnum>
+            </citerefentry> manual page.
+        </para>
+        <para>
+            The simple access provider grants or denies access based on an
+            access or deny list of user names. Here to followig rules apply:
+            <itemizedlist>
+                <listitem>
+                    <para>if both lists are empty access is granted</para>
+                </listitem>
+                <listitem>
+                    <para>if the access list is set only users from this list
+                        are allowed, the deny list is ignored if the access list
+                        is set</para>
+                </listitem>
+                <listitem>
+                    <para>if access list is empty and the deny list is set, only
+                        the users from the deny list are rejected</para>
+                </listitem>
+            </itemizedlist>
+        </para>
+    </refsect1>
+
+    <refsect1 id='file-format'>
+        <title>CONFIGURATION OPTIONS</title>
+        <para>Refer to the section <quote>DOMAIN SECTIONS</quote> of the
+            <citerefentry>
+                <refentrytitle>sssd.conf</refentrytitle>
+                <manvolnum>5</manvolnum>
+            </citerefentry> manual page for details on the configuration of an SSSD domain.
+            <variablelist>
+                <varlistentry>
+                    <term>simple_allow_users (string)</term>
+                    <listitem>
+                        <para>
+                            Comma separated list of users who are allowed to log in.
+                        </para>
+                    </listitem>
+                </varlistentry>
+
+                <varlistentry>
+                    <term>simple_deny_users (string)</term>
+                    <listitem>
+                        <para>
+                            Comma separated list of users who are rejected if
+                            simple_allow_users is not set.
+                        </para>
+                    </listitem>
+                </varlistentry>
+
+
+            </variablelist>
+        </para>
+    </refsect1>
+
+    <refsect1 id='example'>
+        <title>EXAMPLE</title>
+        <para>
+            The following example assumes that SSSD is correctly
+            configured and example.com is one of the domains in the
+            <replaceable>[sssd]</replaceable> section. This examples shows only
+            the simple access provider-specific options.
+        </para>
+        <para>
+<programlisting>
+    [domain/example.com]
+    access_provider = simple
+    simple_allow_users = user1, user2
+</programlisting>
+        </para>
+    </refsect1>
+
+    <refsect1 id='see_also'>
+        <title>SEE ALSO</title>
+        <para>
+            <citerefentry>
+                <refentrytitle>sssd.conf</refentrytitle><manvolnum>5</manvolnum>
+            </citerefentry>,
+            <citerefentry>
+                <refentrytitle>sssd</refentrytitle><manvolnum>8</manvolnum>
+            </citerefentry>
+        </para>
+    </refsect1>
+</refentry>
+</reference>
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index a3ec028..cf1e3a7 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -563,6 +563,13 @@
                             <quote>deny</quote> always deny access.
                         </para>
                         <para>
+                            <quote>simple</quote> access control based on access
+                            or deny lists. See <citerefentry>
+                            <refentrytitle>sssd-simple</refentrytitle>
+                            <manvolnum>5</manvolnum></citerefentry> for more
+                            information on configuring the simple access module.
+                        </para>
+                        <para>
                             Default: <quote>permit</quote>
                         </para>
                     </listitem>
diff --git a/src/providers/simple_access.c b/src/providers/simple_access.c
new file mode 100644
index 0000000..f54884f
--- /dev/null
+++ b/src/providers/simple_access.c
@@ -0,0 +1,159 @@
+/*
+   SSSD
+
+   Simple access control
+
+   Copyright (C) Sumit Bose <sbose at redhat.com> 2010
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <errno.h>
+
+#include <security/pam_modules.h>
+
+#include "util/util.h"
+#include "providers/dp_backend.h"
+#include "db/sysdb.h"
+
+#define CONFDB_SIMPLE_ALLOW_USERS "simple_allow_users"
+#define CONFDB_SIMPLE_DENY_USERS "simple_deny_users"
+
+struct simple_ctx {
+    char **allow_users;
+    char **deny_users;
+};
+
+errno_t simple_access_check(const char *username, char **allow_users,
+                            char **deny_users, bool *access_granted)
+{
+    int i;
+
+    *access_granted = false;
+    if (allow_users != NULL) {
+        for(i = 0; allow_users[i] != NULL; i++) {
+            if (strcmp(username, allow_users[i]) == 0) {
+                DEBUG(9, ("User [%s] found in allow list, access granted.\n",
+                      username));
+                *access_granted = true;
+                return EOK;
+            }
+        }
+    } else {
+        *access_granted = true;
+        if (deny_users != NULL) {
+            for(i = 0; deny_users[i] != NULL; i++) {
+                if (strcmp(username, deny_users[i]) == 0) {
+                    DEBUG(9, ("User [%s] found in deny list, access denied.\n",
+                          username));
+                    *access_granted = false;
+                    return EOK;
+                }
+            }
+        }
+    }
+
+    return EOK;
+}
+
+void simple_access_handler(struct be_req *be_req)
+{
+    int ret;
+    bool access_granted = false;
+    struct pam_data *pd;
+    struct simple_ctx *ctx;
+
+    pd = talloc_get_type(be_req->req_data, struct pam_data);
+
+    pd->pam_status = PAM_SYSTEM_ERR;
+
+    if (pd->cmd != SSS_PAM_ACCT_MGMT) {
+        DEBUG(4, ("simple access does not handles pam task %d.\n", pd->cmd));
+        pd->pam_status = PAM_MODULE_UNKNOWN;
+        goto done;
+    }
+
+    ctx = talloc_get_type(be_req->be_ctx->bet_info[BET_ACCESS].pvt_bet_data,
+                          struct simple_ctx);
+
+    ret = simple_access_check(pd->user, ctx->allow_users, ctx->deny_users,
+                              &access_granted);
+    if (ret != EOK) {
+        pd->pam_status = PAM_SYSTEM_ERR;
+        goto done;
+    }
+
+    if (access_granted) {
+        pd->pam_status = PAM_SUCCESS;
+    } else {
+        pd->pam_status = PAM_PERM_DENIED;
+    }
+
+done:
+    be_req->fn(be_req, DP_ERR_OK, pd->pam_status, NULL);
+}
+
+struct bet_ops simple_access_ops = {
+    .handler = simple_access_handler,
+    .finalize = NULL
+};
+
+int sssm_simple_access_init(struct be_ctx *bectx, struct bet_ops **ops,
+                            void **pvt_data)
+{
+    int ret;
+    struct simple_ctx *ctx;
+
+    ctx = talloc_zero(bectx, struct simple_ctx);
+    if (ctx == NULL) {
+        DEBUG(1, ("talloc_zero failed.\n"));
+        return ENOMEM;
+    }
+
+    ret = confdb_get_string_as_list(bectx->cdb, ctx, bectx->conf_path,
+                                    CONFDB_SIMPLE_ALLOW_USERS,
+                                    &ctx->allow_users);
+    if (ret != EOK) {
+        if (ret == ENOENT) {
+            DEBUG(9, ("Allow user list is empty.\n"));
+            ctx->allow_users = NULL;
+        } else {
+            DEBUG(1, ("confdb_get_string_as_list failed.\n"));
+            goto failed;
+        }
+    }
+
+    ret = confdb_get_string_as_list(bectx->cdb, ctx, bectx->conf_path,
+                                    CONFDB_SIMPLE_DENY_USERS,
+                                    &ctx->deny_users);
+    if (ret != EOK) {
+        if (ret == ENOENT) {
+            DEBUG(9, ("Deny user list is empty.\n"));
+            ctx->deny_users = NULL;
+        } else {
+            DEBUG(1, ("confdb_get_string_as_list failed.\n"));
+            goto failed;
+        }
+    }
+
+
+    *ops = &simple_access_ops;
+    *pvt_data = ctx;
+
+    return EOK;
+
+failed:
+    talloc_free(ctx);
+    return ret;
+}
diff --git a/src/providers/simple_access.h b/src/providers/simple_access.h
new file mode 100644
index 0000000..4d6fa2a
--- /dev/null
+++ b/src/providers/simple_access.h
@@ -0,0 +1,31 @@
+/*
+   SSSD
+
+   Simple access control
+
+   Copyright (C) Sumit Bose <sbose at redhat.com> 2010
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __SIMPLE_ACCESS_H__
+#define __SIMPLE_ACCESS_H__
+
+#include <stdlib.h>
+
+#include "util/util.h"
+
+errno_t simple_access_check(const char *username, char **allow_users,
+                            char **deny_users, bool *access_granted);
+#endif /* __SIMPLE_ACCESS_H__ */
diff --git a/src/tests/simple_access-tests.c b/src/tests/simple_access-tests.c
new file mode 100644
index 0000000..09a4a2f
--- /dev/null
+++ b/src/tests/simple_access-tests.c
@@ -0,0 +1,150 @@
+/*
+    SSSD
+
+    Simple access module -- Tests
+
+    Authors:
+        Sumit Bose <sbose at redhat.com>
+
+    Copyright (C) 2010 Red Hat
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <popt.h>
+#include <check.h>
+
+#include "providers/simple_access.h"
+
+const char *ulist_1[] = {"u1", "u2", NULL};
+
+START_TEST(test_both_empty)
+{
+    int ret;
+    char **allow = NULL;
+    char **deny = NULL;
+    bool access_granted = false;
+
+    ret = simple_access_check("u1", allow, deny, &access_granted);
+    fail_unless(ret == EOK, "access_simple_check failed.");
+    fail_unless(access_granted == true, "Access denied "
+                                        "while both lists are empty.");
+}
+END_TEST
+
+START_TEST(test_allow_empty)
+{
+    int ret;
+    char **allow = NULL;
+    char **deny = discard_const(ulist_1);
+    bool access_granted = true;
+
+    ret = simple_access_check("u1", allow, deny, &access_granted);
+    fail_unless(ret == EOK, "access_simple_check failed.");
+    fail_unless(access_granted == false, "Access granted "
+                                         "while user is in deny list.");
+
+    ret = simple_access_check("u3", allow, deny, &access_granted);
+    fail_unless(ret == EOK, "access_simple_check failed.");
+    fail_unless(access_granted == true, "Access denied "
+                                         "while user is not in deny list.");
+}
+END_TEST
+
+START_TEST(test_deny_empty)
+{
+    int ret;
+    char **allow = discard_const(ulist_1);
+    char **deny = NULL;
+    bool access_granted = false;
+
+    ret = simple_access_check("u1", allow, deny, &access_granted);
+    fail_unless(ret == EOK, "access_simple_check failed.");
+    fail_unless(access_granted == true, "Access denied "
+                                        "while user is in allow list.");
+
+    ret = simple_access_check("u3", allow, deny, &access_granted);
+    fail_unless(ret == EOK, "access_simple_check failed.");
+    fail_unless(access_granted == false, "Access granted "
+                                        "while user is not in allow list.");
+}
+END_TEST
+
+START_TEST(test_both_set)
+{
+    int ret;
+    char **allow = discard_const(ulist_1);
+    char **deny = discard_const(ulist_1);
+    bool access_granted = false;
+
+    ret = simple_access_check("u1", allow, deny, &access_granted);
+    fail_unless(ret == EOK, "access_simple_check failed.");
+    fail_unless(access_granted == true, "Access denied "
+                                        "while user is in allow list.");
+
+    ret = simple_access_check("u3", allow, deny, &access_granted);
+    fail_unless(ret == EOK, "access_simple_check failed.");
+    fail_unless(access_granted == false, "Access granted "
+                                        "while user is not in allow list.");
+}
+END_TEST
+
+Suite *access_simple_suite (void)
+{
+    Suite *s = suite_create ("access_simple");
+
+    TCase *tc_allow_deny = tcase_create ("allow/deny");
+    tcase_add_test (tc_allow_deny, test_both_empty);
+    tcase_add_test (tc_allow_deny, test_allow_empty);
+    tcase_add_test (tc_allow_deny, test_deny_empty);
+    tcase_add_test (tc_allow_deny, test_both_set);
+    suite_add_tcase (s, tc_allow_deny);
+
+    return s;
+}
+
+int main(int argc, const char *argv[])
+{
+    int opt;
+    poptContext pc;
+    int number_failed;
+
+    struct poptOption long_options[] = {
+        POPT_AUTOHELP
+        SSSD_MAIN_OPTS
+        { NULL }
+    };
+
+    pc = poptGetContext(argv[0], argc, argv, long_options, 0);
+    while((opt = poptGetNextOpt(pc)) != -1) {
+        switch(opt) {
+        default:
+            fprintf(stderr, "\nInvalid option %s: %s\n\n",
+                    poptBadOption(pc, 0), poptStrerror(opt));
+            poptPrintUsage(pc, stderr, 0);
+            return 1;
+        }
+    }
+    poptFreeContext(pc);
+
+
+    Suite *s = access_simple_suite ();
+    SRunner *sr = srunner_create (s);
+    srunner_run_all(sr, CK_ENV);
+    number_failed = srunner_ntests_failed (sr);
+    srunner_free (sr);
+    return (number_failed==0 ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
-- 
1.6.6



More information about the sssd-devel mailing list