/* This file is part of pam-modules. Copyright (C) 2009-2012, 2014-2015, 2018 Sergey Poznyakoff 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 . */ #include "pamck.h" char *program_name; void usage() { printf("usage: %s [-hv] [-s service] [-g group] user [password]\n", program_name); } void help() { printf("usage: %s [-hv] [-s service] [-g group] user [password]\n", program_name); printf("\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT); printf("%s home page: .\n", PACKAGE_NAME, PACKAGE); } void version() { printf("%s (%s) %s\n", program_name, PACKAGE, PACKAGE_VERSION); fputs ("\ Copyright (C) 2009-2015 Sergey Poznyakoff\n\ \n\ License GPLv3+: GNU GPL version 3 or later .\n\ This is free software: you are free to change and redistribute it.\n\ There is NO WARRANTY, to the extent permitted by law.\n\ \n\ ", stdout); } void error(int code, const char *fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "%s: ", program_name); vfprintf(stderr, fmt, ap); fputc('\n', stderr); va_end(ap); if (code) exit(code); } struct grouptab { char *name; char *funcname; int (*pam_fn) (pam_handle_t *pamh, int flags); } grouptab[] = { { "auth", "pam_authenticate", pam_authenticate }, { "acct", "pam_acct_mgmt", pam_acct_mgmt }, { "open", "pam_open_session", pam_open_session }, { "close", "pam_close_session", pam_close_session }, { "pass", "pam_chauthtok", pam_chauthtok }, { NULL } }; struct grouptab * find_group(char *name) { struct grouptab *p; for (p = grouptab; p->name; p++) if (strcmp(p->name, name) == 0) return p; return NULL; } void groupprint() { struct grouptab *p; for (p = grouptab; p->name; p++) printf("%s\n", p->name); } char *service = "check"; struct grouptab *group; char *user; char *pass; static struct pam_conv conv = { pamck_conv, NULL }; void check_default(pam_handle_t *pamh) { int rc; rc = pam_authenticate(pamh, 0); if (rc) error(2, "%s failed: %s", "pam_authenticate", pam_strerror (pamh, rc)); rc = pam_acct_mgmt(pamh, 0); if (rc) error(2, "%s failed: %s", "pam_acct_mgmt", pam_strerror (pamh, rc)); printf("OK\n"); } void check_group(pam_handle_t *pamh, struct grouptab *grp) { int rc = grp->pam_fn(pamh, 0); if (rc) error(2, "%s failed: %s", grp->funcname, pam_strerror (pamh, rc)); } int main (int argc, char **argv) { int c; int rc; pam_handle_t *pamh = NULL; program_name = argv[0]; /* A bit of sugar to fake common GNU-style long options */ if (argc == 2) { if (strcmp (argv[1], "--help") == 0) { help(); exit(0); } if (strcmp (argv[1], "--usage") == 0) { usage(); exit(0); } else if (strcmp (argv[1], "--version") == 0) { version(); exit(0); } } /* Normal option processing */ while ((c = getopt (argc, argv, "hg:s:v")) != EOF) { switch (c) { case 'h': help(); exit(0); case 'g': if (strcmp(optarg, "help") == 0) { groupprint(); exit(0); } group = find_group(optarg); if (!group) error(1, "no such management group, try `%s -g help' for the list", program_name); break; case 's': service = optarg; break; case 'v': version(); exit(0); default: exit(1); } } argc -= optind; argv += optind; switch (argc) { case 2: pass = argv[1]; case 1: user = argv[0]; break; default: usage(); exit(1); } rc = pam_start(service, user, &conv, &pamh); if (rc) error(2, "pam_start failed"); if (group) check_group(pamh, group); else check_default(pamh); if (pam_end(pamh, rc) != PAM_SUCCESS) { pamh = NULL; error(2, "failed to release authenticator"); } exit (0); }