URL: https://github.com/SSSD/sssd/pull/200
Author: sumit-bose
 Title: #200: Improve PAM test client
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/200/head:pr200
git checkout pr200
From 0c34e0ed7a0f10bfb4e4dc9fef433105a8d1676f Mon Sep 17 00:00:00 2001
From: Sumit Bose <[email protected]>
Date: Tue, 24 Jan 2017 14:50:20 +0100
Subject: [PATCH 1/7] pam_test_client: add service and environment to PAM test
 client

Related to https://pagure.io/SSSD/sssd/issue/3292
---
 src/sss_client/pam_test_client.c | 51 ++++++++++++++++++++++++++++++----------
 1 file changed, 39 insertions(+), 12 deletions(-)

diff --git a/src/sss_client/pam_test_client.c b/src/sss_client/pam_test_client.c
index 29d1fcb..edd5e0c 100644
--- a/src/sss_client/pam_test_client.c
+++ b/src/sss_client/pam_test_client.c
@@ -48,34 +48,44 @@ static struct pam_conv conv = {
 # error "Missing text based pam conversation function"
 #endif
 
+#define DEFAULT_ACTION "acct"
+#define DEFAULT_SERVICE "system-auth"
+
 int main(int argc, char *argv[]) {
 
     pam_handle_t *pamh;
     char *user;
     char *action;
+    char *service;
     int ret;
+    size_t c;
+    char **pam_env;
 
     if (argc == 1) {
-        fprintf(stderr, "missing action and user name, using default\n");
-        action = strdup("auth");
-        user = strdup("dummy");
+        fprintf(stderr, "Usage: pam_test_client USERNAME "
+                        "[auth|acct|setc|chau|open|clos] [pam_service]\n");
+        return 0;
     } else if (argc == 2) {
-        fprintf(stdout, "using first argument as action and default user name\n");
-        action = strdup(argv[1]);
-        user = strdup("dummy");
-    } else {
-        action = strdup(argv[1]);
-        user = strdup(argv[2]);
+        fprintf(stderr,"using first argument as user name and default action "
+                       "and service\n");
+    } else if (argc == 3) {
+        fprintf(stderr, "using first argument as user name, second as action "
+                        "and default service\n");
     }
 
-    if (action == NULL || user == NULL) {
+    user = strdup(argv[1]);
+    action =  argc > 2 ? strdup(argv[2]) : strdup(DEFAULT_ACTION);
+    service = argc > 3 ? strdup(argv[3]) : strdup(DEFAULT_SERVICE);
+
+    if (action == NULL || user == NULL || service == NULL) {
         fprintf(stderr, "Out of memory!\n");
         return 1;
     }
 
-    fprintf(stdout, "action: %s\nuser: %s\n", action,user);
+    fprintf(stdout, "user: %s\naction: %s\nservice: %s\n",
+                    user, action, service);
 
-    ret = pam_start("sss_test", user, &conv, &pamh);
+    ret = pam_start(service, user, &conv, &pamh);
     if (ret != PAM_SUCCESS) {
         fprintf(stderr, "pam_start failed: %s\n", pam_strerror(pamh, ret));
         return 1;
@@ -109,7 +119,24 @@ int main(int argc, char *argv[]) {
         fprintf(stderr, "unknown action\n");
     }
 
+    fprintf(stderr, "PAM Environment:\n");
+    pam_env = pam_getenvlist(pamh);
+    if (pam_env != NULL && pam_env[0] != NULL) {
+        for (c = 0; pam_env[c] != NULL; c++) {
+            fprintf(stderr," - %s\n", pam_env[c]);
+            free(pam_env[c]);
+        }
+    } else {
+        fprintf(stderr," - no env -\n");
+    }
+    free(pam_env);
+
+
     pam_end(pamh, ret);
 
+    free(user);
+    free(action);
+    free(service);
+
     return 0;
 }

From 9d1519e3ddb868ea022df219ee3bae01a4a8d7e4 Mon Sep 17 00:00:00 2001
From: Sumit Bose <[email protected]>
Date: Wed, 25 Jan 2017 16:50:00 +0100
Subject: [PATCH 2/7] pam_test_client: add SSSD getpwnam lookup

Related to https://pagure.io/SSSD/sssd/issue/3292
---
 Makefile.am                      | 10 ++++--
 src/sss_client/pam_test_client.c | 75 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index d45c0ff..7aca5b8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3461,8 +3461,14 @@ if BUILD_WITH_LIBCURL
 noinst_PROGRAMS += tcurl-test-tool
 endif
 
-pam_test_client_SOURCES = src/sss_client/pam_test_client.c
-pam_test_client_LDADD = $(PAM_LIBS) $(PAM_MISC_LIBS)
+pam_test_client_SOURCES = \
+    src/sss_client/pam_test_client.c \
+    $(NULL)
+pam_test_client_LDADD = \
+    $(PAM_LIBS) \
+    $(PAM_MISC_LIBS) \
+    $(LIBADD_DL) \
+    $(NULL)
 
 if BUILD_AUTOFS
 autofs_test_client_SOURCES = \
diff --git a/src/sss_client/pam_test_client.c b/src/sss_client/pam_test_client.c
index edd5e0c..2b2c607 100644
--- a/src/sss_client/pam_test_client.c
+++ b/src/sss_client/pam_test_client.c
@@ -25,6 +25,11 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <nss.h>
+#include <errno.h>
 
 #include <security/pam_appl.h>
 
@@ -51,6 +56,69 @@ static struct pam_conv conv = {
 #define DEFAULT_ACTION "acct"
 #define DEFAULT_SERVICE "system-auth"
 
+#define DEFAULT_BUFSIZE 4096
+
+static int sss_getpwnam_check(const char *user)
+{
+    void *dl_handle = NULL;
+    enum nss_status (*getpwnam_r)(const char *name, struct passwd *result,
+                      char *buffer, size_t buflen, int *errnop);
+    struct passwd pwd = {0};
+    enum nss_status status;
+    char *buffer = NULL;
+    size_t buflen;
+    int nss_errno;
+    int ret;
+
+    dl_handle = dlopen("libnss_sss.so.2", RTLD_NOW);
+    if (dl_handle == NULL) {
+        fprintf(stderr, "dlopen failed with [%s].\n", dlerror());
+        ret = EIO;
+        goto done;
+    }
+
+    getpwnam_r = dlsym(dl_handle, "_nss_sss_getpwnam_r");
+    if (getpwnam_r == NULL) {
+        fprintf(stderr, "dlsym failed with [%s].\n", dlerror());
+        ret = EIO;
+        goto done;
+    }
+
+    buflen = DEFAULT_BUFSIZE;
+    buffer = malloc(buflen);
+    if (buffer == NULL) {
+        fprintf(stderr, "malloc failed.\n");
+        ret = ENOMEM;
+        goto done;
+    }
+
+    status = getpwnam_r(user, &pwd, buffer, buflen, &nss_errno);
+    if (status != NSS_STATUS_SUCCESS) {
+        fprintf(stderr, "sss_getpwnam_r failed with [%d].\n", status);
+        ret = EIO;
+        goto done;
+    }
+
+    fprintf(stdout, "SSSD nss user lookup result:\n");
+    fprintf(stdout, " - user name: %s\n", pwd.pw_name);
+    fprintf(stdout, " - user id: %d\n", pwd.pw_uid);
+    fprintf(stdout, " - group id: %d\n", pwd.pw_gid);
+    fprintf(stdout, " - gecos: %s\n", pwd.pw_gecos);
+    fprintf(stdout, " - home directory: %s\n", pwd.pw_dir);
+    fprintf(stdout, " - shell: %s\n", pwd.pw_shell);
+
+    ret = 0;
+
+done:
+    if (dl_handle != NULL) {
+        dlclose(dl_handle);
+    }
+
+    free(buffer);
+
+    return ret;
+}
+
 int main(int argc, char *argv[]) {
 
     pam_handle_t *pamh;
@@ -85,6 +153,13 @@ int main(int argc, char *argv[]) {
     fprintf(stdout, "user: %s\naction: %s\nservice: %s\n",
                     user, action, service);
 
+    if (*user != '\0') {
+        ret = sss_getpwnam_check(user);
+        if (ret != 0) {
+            fprintf(stderr,"User name lookup with [%s] failed.\n", user);
+        }
+    }
+
     ret = pam_start(service, user, &conv, &pamh);
     if (ret != PAM_SUCCESS) {
         fprintf(stderr, "pam_start failed: %s\n", pam_strerror(pamh, ret));

From 489bb364b943672792ed2cad97d198a18b7ad304 Mon Sep 17 00:00:00 2001
From: Sumit Bose <[email protected]>
Date: Thu, 16 Mar 2017 11:37:41 +0100
Subject: [PATCH 3/7] sss_sifp: update method names

Related to https://pagure.io/SSSD/sssd/issue/3292
---
 src/lib/sifp/sss_sifp_common.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/lib/sifp/sss_sifp_common.c b/src/lib/sifp/sss_sifp_common.c
index bd1dc6a..8913d0b 100644
--- a/src/lib/sifp/sss_sifp_common.c
+++ b/src/lib/sifp/sss_sifp_common.c
@@ -168,7 +168,7 @@ sss_sifp_fetch_user_by_uid(sss_sifp_ctx *ctx,
     uint64_t _uid = uid;
 
     return sss_sifp_fetch_object_by_attr(ctx, IFP_PATH_USERS, IFACE_IFP_USERS,
-                                         IFACE_IFP_USERS_USER, "UserByID",
+                                         IFACE_IFP_USERS_USER, "ByID",
                                          DBUS_TYPE_UINT64, &_uid, _user);
 }
 
@@ -178,6 +178,6 @@ sss_sifp_fetch_user_by_name(sss_sifp_ctx *ctx,
                             sss_sifp_object **_user)
 {
     return sss_sifp_fetch_object_by_name(ctx, IFP_PATH_USERS, IFACE_IFP_USERS,
-                                         IFACE_IFP_USERS_USER, "UserByName",
+                                         IFACE_IFP_USERS_USER, "ByName",
                                          name, _user);
 }

From 04642cd664cbc11768333539c69dd1754634df39 Mon Sep 17 00:00:00 2001
From: Sumit Bose <[email protected]>
Date: Thu, 16 Mar 2017 11:38:20 +0100
Subject: [PATCH 4/7] pam_test_client: add InfoPipe user lookup

Related to https://pagure.io/SSSD/sssd/issue/3292
---
 Makefile.am                      |  1 +
 src/sss_client/pam_test_client.c | 71 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+)

diff --git a/Makefile.am b/Makefile.am
index 7aca5b8..1b888f1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3468,6 +3468,7 @@ pam_test_client_LDADD = \
     $(PAM_LIBS) \
     $(PAM_MISC_LIBS) \
     $(LIBADD_DL) \
+    libsss_simpleifp.la \
     $(NULL)
 
 if BUILD_AUTOFS
diff --git a/src/sss_client/pam_test_client.c b/src/sss_client/pam_test_client.c
index 2b2c607..7d210e8 100644
--- a/src/sss_client/pam_test_client.c
+++ b/src/sss_client/pam_test_client.c
@@ -30,9 +30,12 @@
 #include <pwd.h>
 #include <nss.h>
 #include <errno.h>
+#include <inttypes.h>
 
 #include <security/pam_appl.h>
 
+#include "lib/sifp/sss_sifp.h"
+
 #ifdef HAVE_SECURITY_PAM_MISC_H
 # include <security/pam_misc.h>
 #elif defined(HAVE_SECURITY_OPENPAM_H)
@@ -58,6 +61,69 @@ static struct pam_conv conv = {
 
 #define DEFAULT_BUFSIZE 4096
 
+static int get_ifp_user(const char *user)
+{
+    sss_sifp_ctx *sifp;
+    sss_sifp_error error;
+    sss_sifp_object *user_obj;
+    const char *tmp_str;
+    uint32_t tmp_uint32;
+    size_t c;
+
+    struct ifp_user_attr {
+        const char *name;
+        bool is_string;
+    } ifp_user_attr[] = {
+        {"name", true},
+        {"uidNumber", false},
+        {"gidNumber", false},
+        {"gecos", true},
+        {"homeDirectory", true},
+        {"loginShell", true},
+        {NULL, false}
+    };
+
+    error = sss_sifp_init(&sifp);
+    if (error != SSS_SIFP_OK) {
+        fprintf(stderr, "Unable to connect to the InfoPipe");
+        return EFAULT;
+    }
+
+    error = sss_sifp_fetch_user_by_name(sifp, user, &user_obj);
+    if (error != SSS_SIFP_OK) {
+        fprintf(stderr, "Unable to get user object");
+        return EIO;
+    }
+
+    fprintf(stdout, "SSSD InfoPipe user lookup result:\n");
+    for (c = 0; ifp_user_attr[c].name != NULL; c++) {
+        if (ifp_user_attr[c].is_string) {
+            error = sss_sifp_find_attr_as_string(user_obj->attrs,
+                                                 ifp_user_attr[c].name,
+                                                 &tmp_str);
+        } else {
+            error = sss_sifp_find_attr_as_uint32(user_obj->attrs,
+                                                 ifp_user_attr[c].name,
+                                                 &tmp_uint32);
+        }
+        if (error != SSS_SIFP_OK) {
+            fprintf(stderr, "Unable to get user name attr");
+            return EIO;
+        }
+
+        if (ifp_user_attr[c].is_string) {
+            fprintf(stdout, " - %s: %s\n", ifp_user_attr[c].name, tmp_str);
+        } else {
+            fprintf(stdout, " - %s: %"PRIu32"\n", ifp_user_attr[c].name,
+                                                  tmp_uint32);
+        }
+    }
+
+    sss_sifp_free_object(sifp, &user_obj);
+    sss_sifp_free(&sifp);
+    return 0;
+}
+
 static int sss_getpwnam_check(const char *user)
 {
     void *dl_handle = NULL;
@@ -158,6 +224,11 @@ int main(int argc, char *argv[]) {
         if (ret != 0) {
             fprintf(stderr,"User name lookup with [%s] failed.\n", user);
         }
+
+        ret = get_ifp_user(user);
+        if (ret != 0) {
+            fprintf(stderr,"InforPipe User lookup with [%s] failed.\n", user);
+        }
     }
 
     ret = pam_start(service, user, &conv, &pamh);

From e835bacb5050510ae966a40959879f276bce33ac Mon Sep 17 00:00:00 2001
From: Sumit Bose <[email protected]>
Date: Thu, 16 Mar 2017 10:54:04 +0100
Subject: [PATCH 5/7] pam_test_client: install as sss_pam_test_client

Related to https://pagure.io/SSSD/sssd/issue/3292
---
 Makefile.am          | 7 ++++---
 contrib/sssd.spec.in | 1 +
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 1b888f1..0a7245c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -146,6 +146,7 @@ sbin_PROGRAMS = \
     sss_override \
     sss_seed \
     sssctl \
+    sss_pam_test_client \
     $(NULL)
 
 sssdlibexec_PROGRAMS = \
@@ -3450,7 +3451,7 @@ endif # BUILD_KCM
 
 endif # HAVE_CMOCKA
 
-noinst_PROGRAMS = pam_test_client
+noinst_PROGRAMS =
 if BUILD_SUDO
 noinst_PROGRAMS += sss_sudo_cli
 endif
@@ -3461,10 +3462,10 @@ if BUILD_WITH_LIBCURL
 noinst_PROGRAMS += tcurl-test-tool
 endif
 
-pam_test_client_SOURCES = \
+sss_pam_test_client_SOURCES = \
     src/sss_client/pam_test_client.c \
     $(NULL)
-pam_test_client_LDADD = \
+sss_pam_test_client_LDADD = \
     $(PAM_LIBS) \
     $(PAM_MISC_LIBS) \
     $(LIBADD_DL) \
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
index 39a974e..44b847c 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -1080,6 +1080,7 @@ done
 %{_sbindir}/sss_debuglevel
 %{_sbindir}/sss_seed
 %{_sbindir}/sssctl
+%{_sbindir}/sss_pam_test_client
 %{_mandir}/man8/sss_groupadd.8*
 %{_mandir}/man8/sss_groupdel.8*
 %{_mandir}/man8/sss_groupmod.8*

From 6924fb95defd9e1009c45c25059d5f1543de22ab Mon Sep 17 00:00:00 2001
From: Sumit Bose <[email protected]>
Date: Thu, 30 Mar 2017 16:21:15 +0200
Subject: [PATCH 6/7] sssctl: integrate pam_test_client into sssctl

---
 Makefile.am                           |  15 +-
 contrib/sssd.spec.in                  |   1 -
 po/POTFILES.in                        |   1 -
 src/sss_client/pam_test_client.c      | 288 ---------------------------------
 src/tools/sssctl/sssctl.c             |   1 +
 src/tools/sssctl/sssctl.h             |   4 +
 src/tools/sssctl/sssctl_user_checks.c | 291 ++++++++++++++++++++++++++++++++++
 7 files changed, 300 insertions(+), 301 deletions(-)
 delete mode 100644 src/sss_client/pam_test_client.c
 create mode 100644 src/tools/sssctl/sssctl_user_checks.c

diff --git a/Makefile.am b/Makefile.am
index 0a7245c..c1d0945 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -146,7 +146,6 @@ sbin_PROGRAMS = \
     sss_override \
     sss_seed \
     sssctl \
-    sss_pam_test_client \
     $(NULL)
 
 sssdlibexec_PROGRAMS = \
@@ -1725,11 +1724,15 @@ sssctl_SOURCES = \
     src/tools/sssctl/sssctl_domains.c \
     src/tools/sssctl/sssctl_sifp.c \
     src/tools/sssctl/sssctl_config.c \
+    src/tools/sssctl/sssctl_user_checks.c \
     $(SSSD_TOOLS_OBJ) \
     $(NULL)
 sssctl_LDADD = \
     $(TOOLS_LIBS) \
     $(SSSD_INTERNAL_LTLIBS) \
+    $(PAM_LIBS) \
+    $(PAM_MISC_LIBS) \
+    $(LIBADD_DL) \
     libsss_simpleifp.la \
     $(NULL)
 sssctl_CFLAGS = \
@@ -3462,16 +3465,6 @@ if BUILD_WITH_LIBCURL
 noinst_PROGRAMS += tcurl-test-tool
 endif
 
-sss_pam_test_client_SOURCES = \
-    src/sss_client/pam_test_client.c \
-    $(NULL)
-sss_pam_test_client_LDADD = \
-    $(PAM_LIBS) \
-    $(PAM_MISC_LIBS) \
-    $(LIBADD_DL) \
-    libsss_simpleifp.la \
-    $(NULL)
-
 if BUILD_AUTOFS
 autofs_test_client_SOURCES = \
     src/sss_client/autofs/autofs_test_client.c \
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
index 44b847c..39a974e 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -1080,7 +1080,6 @@ done
 %{_sbindir}/sss_debuglevel
 %{_sbindir}/sss_seed
 %{_sbindir}/sssctl
-%{_sbindir}/sss_pam_test_client
 %{_mandir}/man8/sss_groupadd.8*
 %{_mandir}/man8/sss_groupdel.8*
 %{_mandir}/man8/sss_groupmod.8*
diff --git a/po/POTFILES.in b/po/POTFILES.in
index ee532de..f4e4e09 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -9,7 +9,6 @@ src/sss_client/common.c
 src/sss_client/nss_group.c
 src/sss_client/nss_passwd.c
 src/sss_client/pam_sss.c
-src/sss_client/pam_test_client.c
 src/sss_client/ssh/sss_ssh_authorizedkeys.c
 src/sss_client/ssh/sss_ssh_knownhostsproxy.c
 src/tools/sss_useradd.c
diff --git a/src/sss_client/pam_test_client.c b/src/sss_client/pam_test_client.c
deleted file mode 100644
index 7d210e8..0000000
--- a/src/sss_client/pam_test_client.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
-    Authors:
-        Sumit Bose <[email protected]>
-
-    Copyright (C) 2009 Red Hat
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <dlfcn.h>
-#include <sys/types.h>
-#include <pwd.h>
-#include <nss.h>
-#include <errno.h>
-#include <inttypes.h>
-
-#include <security/pam_appl.h>
-
-#include "lib/sifp/sss_sifp.h"
-
-#ifdef HAVE_SECURITY_PAM_MISC_H
-# include <security/pam_misc.h>
-#elif defined(HAVE_SECURITY_OPENPAM_H)
-# include <security/openpam.h>
-#endif
-
-#ifdef HAVE_SECURITY_PAM_MISC_H
-static struct pam_conv conv = {
-    misc_conv,
-    NULL
-};
-#elif defined(HAVE_SECURITY_OPENPAM_H)
-static struct pam_conv conv = {
-    openpam_ttyconv,
-    NULL
-};
-#else
-# error "Missing text based pam conversation function"
-#endif
-
-#define DEFAULT_ACTION "acct"
-#define DEFAULT_SERVICE "system-auth"
-
-#define DEFAULT_BUFSIZE 4096
-
-static int get_ifp_user(const char *user)
-{
-    sss_sifp_ctx *sifp;
-    sss_sifp_error error;
-    sss_sifp_object *user_obj;
-    const char *tmp_str;
-    uint32_t tmp_uint32;
-    size_t c;
-
-    struct ifp_user_attr {
-        const char *name;
-        bool is_string;
-    } ifp_user_attr[] = {
-        {"name", true},
-        {"uidNumber", false},
-        {"gidNumber", false},
-        {"gecos", true},
-        {"homeDirectory", true},
-        {"loginShell", true},
-        {NULL, false}
-    };
-
-    error = sss_sifp_init(&sifp);
-    if (error != SSS_SIFP_OK) {
-        fprintf(stderr, "Unable to connect to the InfoPipe");
-        return EFAULT;
-    }
-
-    error = sss_sifp_fetch_user_by_name(sifp, user, &user_obj);
-    if (error != SSS_SIFP_OK) {
-        fprintf(stderr, "Unable to get user object");
-        return EIO;
-    }
-
-    fprintf(stdout, "SSSD InfoPipe user lookup result:\n");
-    for (c = 0; ifp_user_attr[c].name != NULL; c++) {
-        if (ifp_user_attr[c].is_string) {
-            error = sss_sifp_find_attr_as_string(user_obj->attrs,
-                                                 ifp_user_attr[c].name,
-                                                 &tmp_str);
-        } else {
-            error = sss_sifp_find_attr_as_uint32(user_obj->attrs,
-                                                 ifp_user_attr[c].name,
-                                                 &tmp_uint32);
-        }
-        if (error != SSS_SIFP_OK) {
-            fprintf(stderr, "Unable to get user name attr");
-            return EIO;
-        }
-
-        if (ifp_user_attr[c].is_string) {
-            fprintf(stdout, " - %s: %s\n", ifp_user_attr[c].name, tmp_str);
-        } else {
-            fprintf(stdout, " - %s: %"PRIu32"\n", ifp_user_attr[c].name,
-                                                  tmp_uint32);
-        }
-    }
-
-    sss_sifp_free_object(sifp, &user_obj);
-    sss_sifp_free(&sifp);
-    return 0;
-}
-
-static int sss_getpwnam_check(const char *user)
-{
-    void *dl_handle = NULL;
-    enum nss_status (*getpwnam_r)(const char *name, struct passwd *result,
-                      char *buffer, size_t buflen, int *errnop);
-    struct passwd pwd = {0};
-    enum nss_status status;
-    char *buffer = NULL;
-    size_t buflen;
-    int nss_errno;
-    int ret;
-
-    dl_handle = dlopen("libnss_sss.so.2", RTLD_NOW);
-    if (dl_handle == NULL) {
-        fprintf(stderr, "dlopen failed with [%s].\n", dlerror());
-        ret = EIO;
-        goto done;
-    }
-
-    getpwnam_r = dlsym(dl_handle, "_nss_sss_getpwnam_r");
-    if (getpwnam_r == NULL) {
-        fprintf(stderr, "dlsym failed with [%s].\n", dlerror());
-        ret = EIO;
-        goto done;
-    }
-
-    buflen = DEFAULT_BUFSIZE;
-    buffer = malloc(buflen);
-    if (buffer == NULL) {
-        fprintf(stderr, "malloc failed.\n");
-        ret = ENOMEM;
-        goto done;
-    }
-
-    status = getpwnam_r(user, &pwd, buffer, buflen, &nss_errno);
-    if (status != NSS_STATUS_SUCCESS) {
-        fprintf(stderr, "sss_getpwnam_r failed with [%d].\n", status);
-        ret = EIO;
-        goto done;
-    }
-
-    fprintf(stdout, "SSSD nss user lookup result:\n");
-    fprintf(stdout, " - user name: %s\n", pwd.pw_name);
-    fprintf(stdout, " - user id: %d\n", pwd.pw_uid);
-    fprintf(stdout, " - group id: %d\n", pwd.pw_gid);
-    fprintf(stdout, " - gecos: %s\n", pwd.pw_gecos);
-    fprintf(stdout, " - home directory: %s\n", pwd.pw_dir);
-    fprintf(stdout, " - shell: %s\n", pwd.pw_shell);
-
-    ret = 0;
-
-done:
-    if (dl_handle != NULL) {
-        dlclose(dl_handle);
-    }
-
-    free(buffer);
-
-    return ret;
-}
-
-int main(int argc, char *argv[]) {
-
-    pam_handle_t *pamh;
-    char *user;
-    char *action;
-    char *service;
-    int ret;
-    size_t c;
-    char **pam_env;
-
-    if (argc == 1) {
-        fprintf(stderr, "Usage: pam_test_client USERNAME "
-                        "[auth|acct|setc|chau|open|clos] [pam_service]\n");
-        return 0;
-    } else if (argc == 2) {
-        fprintf(stderr,"using first argument as user name and default action "
-                       "and service\n");
-    } else if (argc == 3) {
-        fprintf(stderr, "using first argument as user name, second as action "
-                        "and default service\n");
-    }
-
-    user = strdup(argv[1]);
-    action =  argc > 2 ? strdup(argv[2]) : strdup(DEFAULT_ACTION);
-    service = argc > 3 ? strdup(argv[3]) : strdup(DEFAULT_SERVICE);
-
-    if (action == NULL || user == NULL || service == NULL) {
-        fprintf(stderr, "Out of memory!\n");
-        return 1;
-    }
-
-    fprintf(stdout, "user: %s\naction: %s\nservice: %s\n",
-                    user, action, service);
-
-    if (*user != '\0') {
-        ret = sss_getpwnam_check(user);
-        if (ret != 0) {
-            fprintf(stderr,"User name lookup with [%s] failed.\n", user);
-        }
-
-        ret = get_ifp_user(user);
-        if (ret != 0) {
-            fprintf(stderr,"InforPipe User lookup with [%s] failed.\n", user);
-        }
-    }
-
-    ret = pam_start(service, user, &conv, &pamh);
-    if (ret != PAM_SUCCESS) {
-        fprintf(stderr, "pam_start failed: %s\n", pam_strerror(pamh, ret));
-        return 1;
-    }
-
-    if ( strncmp(action, "auth", 4)== 0 ) {
-        fprintf(stdout, "testing pam_authenticate\n");
-        ret = pam_authenticate(pamh, 0);
-        fprintf(stderr, "pam_authenticate: %s\n", pam_strerror(pamh, ret));
-    } else if ( strncmp(action, "chau", 4)== 0 ) {
-        fprintf(stdout, "testing pam_chauthtok\n");
-        ret = pam_chauthtok(pamh, 0);
-        fprintf(stderr, "pam_chauthtok: %s\n", pam_strerror(pamh, ret));
-    } else if ( strncmp(action, "acct", 4)== 0 ) {
-        fprintf(stdout, "testing pam_acct_mgmt\n");
-        ret = pam_acct_mgmt(pamh, 0);
-        fprintf(stderr, "pam_acct_mgmt: %s\n", pam_strerror(pamh, ret));
-    } else if ( strncmp(action, "setc", 4)== 0 ) {
-        fprintf(stdout, "testing pam_setcred\n");
-        ret = pam_setcred(pamh, 0);
-        fprintf(stderr, "pam_setcred: %d[%s]\n", ret, pam_strerror(pamh, ret));
-    } else if ( strncmp(action, "open", 4)== 0 ) {
-        fprintf(stdout, "testing pam_open_session\n");
-        ret = pam_open_session(pamh, 0);
-        fprintf(stderr, "pam_open_session: %s\n", pam_strerror(pamh, ret));
-    } else if ( strncmp(action, "clos", 4)== 0 ) {
-        fprintf(stdout, "testing pam_close_session\n");
-        ret = pam_close_session(pamh, 0);
-        fprintf(stderr, "pam_close_session: %s\n", pam_strerror(pamh, ret));
-    } else {
-        fprintf(stderr, "unknown action\n");
-    }
-
-    fprintf(stderr, "PAM Environment:\n");
-    pam_env = pam_getenvlist(pamh);
-    if (pam_env != NULL && pam_env[0] != NULL) {
-        for (c = 0; pam_env[c] != NULL; c++) {
-            fprintf(stderr," - %s\n", pam_env[c]);
-            free(pam_env[c]);
-        }
-    } else {
-        fprintf(stderr," - no env -\n");
-    }
-    free(pam_env);
-
-
-    pam_end(pamh, ret);
-
-    free(user);
-    free(action);
-    free(service);
-
-    return 0;
-}
diff --git a/src/tools/sssctl/sssctl.c b/src/tools/sssctl/sssctl.c
index e1cf463..509d2e1 100644
--- a/src/tools/sssctl/sssctl.c
+++ b/src/tools/sssctl/sssctl.c
@@ -263,6 +263,7 @@ int main(int argc, const char **argv)
         SSS_TOOL_DELIMITER("SSSD Status:"),
         SSS_TOOL_COMMAND("domain-list", "List available domains", 0, sssctl_domain_list),
         SSS_TOOL_COMMAND("domain-status", "Print information about domain", 0, sssctl_domain_status),
+        SSS_TOOL_COMMAND("user-checks", "Print information about a user and check authentication", 0, sssctl_user_checks),
         SSS_TOOL_DELIMITER("Information about cached content:"),
         SSS_TOOL_COMMAND("user-show", "Information about cached user", 0, sssctl_user_show),
         SSS_TOOL_COMMAND("group-show", "Information about cached group", 0, sssctl_group_show),
diff --git a/src/tools/sssctl/sssctl.h b/src/tools/sssctl/sssctl.h
index 5270a9e..22626e2 100644
--- a/src/tools/sssctl/sssctl.h
+++ b/src/tools/sssctl/sssctl.h
@@ -121,4 +121,8 @@ errno_t sssctl_netgroup_show(struct sss_cmdline *cmdline,
 errno_t sssctl_config_check(struct sss_cmdline *cmdline,
                             struct sss_tool_ctx *tool_ctx,
                             void *pvt);
+
+errno_t sssctl_user_checks(struct sss_cmdline *cmdline,
+                           struct sss_tool_ctx *tool_ctx,
+                           void *pvt);
 #endif /* _SSSCTL_H_ */
diff --git a/src/tools/sssctl/sssctl_user_checks.c b/src/tools/sssctl/sssctl_user_checks.c
new file mode 100644
index 0000000..3430ba7
--- /dev/null
+++ b/src/tools/sssctl/sssctl_user_checks.c
@@ -0,0 +1,291 @@
+/*
+    Authors:
+        Sumit Bose <[email protected]>
+
+    Copyright (C) 2009 Red Hat
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <nss.h>
+#include <errno.h>
+#include <inttypes.h>
+
+#include <security/pam_appl.h>
+
+#include "lib/sifp/sss_sifp.h"
+#include "util/util.h"
+#include "tools/common/sss_tools.h"
+#include "tools/sssctl/sssctl.h"
+
+#ifdef HAVE_SECURITY_PAM_MISC_H
+# include <security/pam_misc.h>
+#elif defined(HAVE_SECURITY_OPENPAM_H)
+# include <security/openpam.h>
+#endif
+
+#ifdef HAVE_SECURITY_PAM_MISC_H
+static struct pam_conv conv = {
+    misc_conv,
+    NULL
+};
+#elif defined(HAVE_SECURITY_OPENPAM_H)
+static struct pam_conv conv = {
+    openpam_ttyconv,
+    NULL
+};
+#else
+# error "Missing text based pam conversation function"
+#endif
+
+#define DEFAULT_ACTION "acct"
+#define DEFAULT_SERVICE "system-auth"
+
+#define DEFAULT_BUFSIZE 4096
+
+static int get_ifp_user(const char *user)
+{
+    sss_sifp_ctx *sifp;
+    sss_sifp_error error;
+    sss_sifp_object *user_obj;
+    const char *tmp_str;
+    uint32_t tmp_uint32;
+    size_t c;
+
+    struct ifp_user_attr {
+        const char *name;
+        bool is_string;
+    } ifp_user_attr[] = {
+        {"name", true},
+        {"uidNumber", false},
+        {"gidNumber", false},
+        {"gecos", true},
+        {"homeDirectory", true},
+        {"loginShell", true},
+        {NULL, false}
+    };
+
+    error = sss_sifp_init(&sifp);
+    if (error != SSS_SIFP_OK) {
+        fprintf(stderr, _("Unable to connect to the InfoPipe"));
+        return EFAULT;
+    }
+
+    error = sss_sifp_fetch_user_by_name(sifp, user, &user_obj);
+    if (error != SSS_SIFP_OK) {
+        fprintf(stderr, _("Unable to get user object"));
+        return EIO;
+    }
+
+    fprintf(stdout, _("SSSD InfoPipe user lookup result:\n"));
+    for (c = 0; ifp_user_attr[c].name != NULL; c++) {
+        if (ifp_user_attr[c].is_string) {
+            error = sss_sifp_find_attr_as_string(user_obj->attrs,
+                                                 ifp_user_attr[c].name,
+                                                 &tmp_str);
+        } else {
+            error = sss_sifp_find_attr_as_uint32(user_obj->attrs,
+                                                 ifp_user_attr[c].name,
+                                                 &tmp_uint32);
+        }
+        if (error != SSS_SIFP_OK) {
+            fprintf(stderr, _("Unable to get user name attr"));
+            return EIO;
+        }
+
+        if (ifp_user_attr[c].is_string) {
+            fprintf(stdout, " - %s: %s\n", ifp_user_attr[c].name, tmp_str);
+        } else {
+            fprintf(stdout, " - %s: %"PRIu32"\n", ifp_user_attr[c].name,
+                                                  tmp_uint32);
+        }
+    }
+    fprintf(stdout, "\n");
+
+    sss_sifp_free_object(sifp, &user_obj);
+    sss_sifp_free(&sifp);
+    return 0;
+}
+
+static int sss_getpwnam_check(const char *user)
+{
+    void *dl_handle = NULL;
+    enum nss_status (*getpwnam_r)(const char *name, struct passwd *result,
+                      char *buffer, size_t buflen, int *errnop);
+    struct passwd pwd = {0};
+    enum nss_status status;
+    char *buffer = NULL;
+    size_t buflen;
+    int nss_errno;
+    int ret;
+
+    dl_handle = dlopen("libnss_sss.so.2", RTLD_NOW);
+    if (dl_handle == NULL) {
+        fprintf(stderr, _("dlopen failed with [%s].\n"), dlerror());
+        ret = EIO;
+        goto done;
+    }
+
+    getpwnam_r = dlsym(dl_handle, "_nss_sss_getpwnam_r");
+    if (getpwnam_r == NULL) {
+        fprintf(stderr, _("dlsym failed with [%s].\n"), dlerror());
+        ret = EIO;
+        goto done;
+    }
+
+    buflen = DEFAULT_BUFSIZE;
+    buffer = malloc(buflen);
+    if (buffer == NULL) {
+        fprintf(stderr, _("malloc failed.\n"));
+        ret = ENOMEM;
+        goto done;
+    }
+
+    status = getpwnam_r(user, &pwd, buffer, buflen, &nss_errno);
+    if (status != NSS_STATUS_SUCCESS) {
+        fprintf(stderr, _("sss_getpwnam_r failed with [%d].\n"), status);
+        ret = EIO;
+        goto done;
+    }
+
+    fprintf(stdout, _("SSSD nss user lookup result:\n"));
+    fprintf(stdout, _(" - user name: %s\n"), pwd.pw_name);
+    fprintf(stdout, _(" - user id: %d\n"), pwd.pw_uid);
+    fprintf(stdout, _(" - group id: %d\n"), pwd.pw_gid);
+    fprintf(stdout, _(" - gecos: %s\n"), pwd.pw_gecos);
+    fprintf(stdout, _(" - home directory: %s\n"), pwd.pw_dir);
+    fprintf(stdout, _(" - shell: %s\n\n"), pwd.pw_shell);
+
+    ret = 0;
+
+done:
+    if (dl_handle != NULL) {
+        dlclose(dl_handle);
+    }
+
+    free(buffer);
+
+    return ret;
+}
+
+errno_t sssctl_user_checks(struct sss_cmdline *cmdline,
+                           struct sss_tool_ctx *tool_ctx,
+                           void *pvt)
+{
+
+    pam_handle_t *pamh;
+    const char *user = NULL;
+    const char *action = DEFAULT_ACTION;
+    const char *service = DEFAULT_SERVICE;
+    int ret;
+    size_t c;
+    char **pam_env;
+
+    /* Parse command line. */
+    struct poptOption options[] = {
+        {"action", 'a', POPT_ARG_STRING , &action, 0,
+            _("PAM action [auth|acct|setc|chau|open|clos], default: "
+                DEFAULT_ACTION),
+            NULL },
+        {"service", 's', POPT_ARG_STRING , &service, 0,
+            _("PAM service, default: " DEFAULT_SERVICE), NULL },
+        POPT_TABLEEND
+    };
+
+    ret = sss_tool_popt_ex(cmdline, options, SSS_TOOL_OPT_OPTIONAL,
+                           NULL, NULL, "USERNAME", _("Specify user name."),
+                           &user, NULL);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse command arguments\n");
+        return ret;
+    }
+
+    fprintf(stdout, _("user: %s\naction: %s\nservice: %s\n\n"),
+                    user, action, service);
+
+    if (*user != '\0') {
+        ret = sss_getpwnam_check(user);
+        if (ret != 0) {
+            fprintf(stderr, _("User name lookup with [%s] failed.\n"), user);
+        }
+
+        ret = get_ifp_user(user);
+        if (ret != 0) {
+            fprintf(stderr, _("InforPipe User lookup with [%s] failed.\n"),
+                            user);
+        }
+    }
+
+    ret = pam_start(service, user, &conv, &pamh);
+    if (ret != PAM_SUCCESS) {
+        fprintf(stderr, _("pam_start failed: %s\n"), pam_strerror(pamh, ret));
+        return 1;
+    }
+
+    if ( strncmp(action, "auth", 4)== 0 ) {
+        fprintf(stdout, _("testing pam_authenticate\n\n"));
+        ret = pam_authenticate(pamh, 0);
+        fprintf(stderr, _("pam_authenticate: %s\n\n"), pam_strerror(pamh, ret));
+    } else if ( strncmp(action, "chau", 4)== 0 ) {
+        fprintf(stdout, _("testing pam_chauthtok\n\n"));
+        ret = pam_chauthtok(pamh, 0);
+        fprintf(stderr, _("pam_chauthtok: %s\n\n"), pam_strerror(pamh, ret));
+    } else if ( strncmp(action, "acct", 4)== 0 ) {
+        fprintf(stdout, _("testing pam_acct_mgmt\n\n"));
+        ret = pam_acct_mgmt(pamh, 0);
+        fprintf(stderr, _("pam_acct_mgmt: %s\n\n"), pam_strerror(pamh, ret));
+    } else if ( strncmp(action, "setc", 4)== 0 ) {
+        fprintf(stdout, _("testing pam_setcred\n\n"));
+        ret = pam_setcred(pamh, 0);
+        fprintf(stderr, _("pam_setcred: [%s]\n\n"), pam_strerror(pamh, ret));
+    } else if ( strncmp(action, "open", 4)== 0 ) {
+        fprintf(stdout, _("testing pam_open_session\n\n"));
+        ret = pam_open_session(pamh, 0);
+        fprintf(stderr, _("pam_open_session: %s\n\n"), pam_strerror(pamh, ret));
+    } else if ( strncmp(action, "clos", 4)== 0 ) {
+        fprintf(stdout, _("testing pam_close_session\n\n"));
+        ret = pam_close_session(pamh, 0);
+        fprintf(stderr, _("pam_close_session: %s\n\n"),
+                        pam_strerror(pamh, ret));
+    } else {
+        fprintf(stderr, _("unknown action\n"));
+    }
+
+    fprintf(stderr, _("PAM Environment:\n"));
+    pam_env = pam_getenvlist(pamh);
+    if (pam_env != NULL && pam_env[0] != NULL) {
+        for (c = 0; pam_env[c] != NULL; c++) {
+            fprintf(stderr," - %s\n", pam_env[c]);
+            free(pam_env[c]);
+        }
+    } else {
+        fprintf(stderr, _(" - no env -\n"));
+    }
+    free(pam_env);
+
+
+    pam_end(pamh, ret);
+
+    return 0;
+}

From bca3b2cce92c4ca2f406bbd240fef1d5034e8e70 Mon Sep 17 00:00:00 2001
From: Sumit Bose <[email protected]>
Date: Fri, 7 Apr 2017 14:24:10 +0200
Subject: [PATCH 7/7] i18n: adding sssctl files

---
 po/POTFILES.in | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/po/POTFILES.in b/po/POTFILES.in
index f4e4e09..33e7ed7 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -23,4 +23,12 @@ src/tools/sss_cache.c
 src/tools/sss_debuglevel.c
 src/tools/tools_util.c
 src/tools/tools_util.h
+src/tools/sssctl/sssctl.c
+src/tools/sssctl/sssctl_cache.c
+src/tools/sssctl/sssctl_config.c
+src/tools/sssctl/sssctl_data.c
+src/tools/sssctl/sssctl_domains.c
+src/tools/sssctl/sssctl_logs.c
+src/tools/sssctl/sssctl_sifp.c
+src/tools/sssctl/sssctl_user_checks.c
 src/util/util.h
_______________________________________________
sssd-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to