summaryrefslogtreecommitdiffstats
path: root/src/tools/sssctl/sssctl_user_checks.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/sssctl/sssctl_user_checks.c')
-rw-r--r--src/tools/sssctl/sssctl_user_checks.c290
1 files changed, 290 insertions, 0 deletions
diff --git a/src/tools/sssctl/sssctl_user_checks.c b/src/tools/sssctl/sssctl_user_checks.c
new file mode 100644
index 000000000..7c7b564bd
--- /dev/null
+++ b/src/tools/sssctl/sssctl_user_checks.c
@@ -0,0 +1,290 @@
+/*
+ Authors:
+ Sumit Bose <sbose@redhat.com>
+
+ 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 (*sss_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;
+ }
+
+ sss_getpwnam_r = dlsym(dl_handle, "_nss_sss_getpwnam_r");
+ if (sss_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 = sss_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;
+}