Implement pamck utility.

* pamck/pamck.c, pamck/pamck.h, pamck/conv.c, pamck/Makefile.am: New files.
* doc/pam-modules.texi: Document pamck.
* doc/fdl.texi: Move sectioning command to pam-modules.texi.
* NEWS: Update.



git-svn-id: file:///svnroot/pam-modules/trunk@102 56984be4-0537-0410-a56c-fcb268c96130
This commit is contained in:
Sergey Poznyakoff 2009-02-25 12:58:11 +00:00
parent e996bc37b3
commit 91361e6976
9 changed files with 525 additions and 20 deletions

View file

@ -14,4 +14,4 @@
# with this program. If not, see <http://www.gnu.org/licenses/>.
AUTOMAKE_OPTIONS = gnits 1.8
SUBDIRS = doc lib pam_fshadow pam_regex pam_log pam_sql
SUBDIRS = doc lib pam_fshadow pam_regex pam_log pam_sql pamck

14
NEWS
View file

@ -1,9 +1,21 @@
pam-modules -- history of user-visible changes. 2009-02-17
pam-modules -- history of user-visible changes. 2009-02-25
Copyright (C) 2001,2004,2005,2007,2008,2009 Sergey Poznyakoff
See the end of file for copying conditions.
Please send radius bug reports to <bug-pam-modules@gnu.org.ua>
Version 1.6 (SVN)
* pamck
Pamck is a command line utility for checking PAM authentication and
other management groups. E.g.:
pamck -s login smith
attempts to authenticate user `smith' using PAM service name `login'.
Version 1.5, 2009-02-17

View file

@ -16,7 +16,7 @@
AC_PREREQ(2.53)
AC_INIT(pam-modules, 1.5, bug-pam-modules@gnu.org.ua)
AC_INIT(pam-modules, 1.6, bug-pam-modules@gnu.org.ua)
AC_CONFIG_SRCDIR(pam_fshadow/pam_fshadow.c)
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE(no-exeext)
@ -54,7 +54,7 @@ AC_HEADER_STDC
AC_CHECK_HEADERS(security/pam_appl.h security/pam_modules.h,
:,
AC_MSG_ERROR([Required PAM header files not found]))
AC_CHECK_HEADERS(fcntl.h syslog.h unistd.h crypt.h security/_pam_aconf.h)
AC_CHECK_HEADERS(fcntl.h syslog.h unistd.h crypt.h security/_pam_aconf.h termios.h)
AC_CHECK_HEADER(shadow.h,
[],
[build_fshadow=no])
@ -63,7 +63,7 @@ dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
dnl Checks for library functions.
AC_CHECK_FUNCS(strerror)
AC_CHECK_FUNCS(strerror tcgetattr)
AC_CHECK_FUNC(fgetspent,
[],
[build_fshadow=no])
@ -205,4 +205,5 @@ AC_OUTPUT(Makefile
pam_fshadow/Makefile
pam_regex/Makefile
pam_log/Makefile
pam_sql/Makefile)
pam_sql/Makefile
pamck/Makefile)

View file

@ -1,5 +1,4 @@
@setfilename fdl.info
@appendix GNU Free Documentation License
@cindex FDL, GNU Free Documentation License
@center Version 1.2, November 2002

View file

@ -31,6 +31,7 @@
session management.
* pam_log: (pam-modules)log. Format and log arbitrary
messages to syslog.
* pamck: (pam-modules)pamck. Verify PAM Access.
@end direntry
@end ifinfo
@ -39,7 +40,7 @@ Published by the Free Software Foundation,
51 Franklin Street, Fifth Floor
Boston, MA 02110-1301, USA
Copyright @copyright{} 2005, 2007, 2008 Sergey Poznyakoff
Copyright @copyright{} 2005, 2007, 2008, 2009 Sergey Poznyakoff
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2 or
@ -67,16 +68,17 @@ Software Foundation raise funds for GNU development.''
@page
@contents
@node Top, Intro, (dir), (dir)
@ifnottex
@node Top
@top PAM modules
@ifinfo
@chapter PAM-modules
This edition of the @cite{PAM-modules Manual}, last updated @value{UPDATED},
documents PAM-modules Version @value{VERSION}.
@end ifinfo
@end ifnottex
@menu
* Intro:: Introduction to PAM-modules
* pamck:: Verify PAM Authentication
Individual modules
@ -86,6 +88,7 @@ Individual modules
expression.
* log:: Log arbitrary messages to syslog.
* sql:: Modules for SQL authentication and session management.
* Reporting Bugs:: How to Report a Bug.
Appendices
@ -120,7 +123,7 @@ SQL Authentication and Session Management.
@end detailmenu
@end menu
@node Intro, fshadow, Top, Top
@node Intro
@chapter Introduction to PAM-modules
PAM-modules is a collection of various pluggable authentication
@ -225,7 +228,85 @@ username: }.
Item expansion is used by @command{pam_log}, @command{pam_mysql}
and @command{pam_pgsql}.
@node fshadow, regex, Intro, Top
@node pamck
@chapter Verify PAM Access
@prindex pamck
The @command{pamck} utility checks if a user can be authenticated using
@acronym{PAM}. The user name is specified in the command line, so the
simplest invocation is:
@smallexample
$ pamck user
@end smallexample
When used this way, @command{pamck} first authenticates @samp{user},
by calling @code{pam_authenticate}, and then performs account
management (@code{pam_acct_mgmt}). If both functions return success,
the utility prints @samp{OK} on the standard output and exits with
zero code. In case of failure, it displays diagnostics on standard
error and exits with error code 2.
It exits with code 1 in case of usage error (e.g. wrong command line
option).
If password is required, the utility asks about it, and waits for the
user input. When reading user input, terminal echo is turned off to
prevent password compromising.
Alternatively, the password may be given on the command line, as the
second argument:
@smallexample
$ pamck user pass
@end smallexample
By default, @command{pamck} uses @acronym{PAM} service @samp{check}.
Another service name may be supplied using the @option{-s} command
line option:
@smallexample
$ pamck -s login user
@end smallexample
The @option{-g} command line option allows to select the @acronym{PAM}
management group to check. It takes the name of the group as an
argument. Allowed group names are:
@table @asis
@item auth
Authentication group. Call @code{pam_authenticate}.
@item acct
Account management. Call @code{pam_acct_mgmt}.
@item open
Session management. Call @code{pam_open_session}.
@item close
Session management. Call @code{pam_close_session}.
@item pass
Password management. Call @code{pam_chauthtok}.
@end table
The following table summarizes available command line options:
@table @option
@item -s @var{service}
Select service name to use.
@item -g @var{group}
Select @acronym{PAM} management group to check.
@item -h
Print short help summary and exit.
@item -v
Print program version and copyright information and exit.
@end table
@node fshadow
@chapter Authentication against an alternative shadow file.
@set MODULE pam_fshadow
@prindex pam_fshadow
@ -429,7 +510,7 @@ authentication tokens.
@end table
@node regex, log, fshadow, Top
@node regex
@chapter Authentication using regular expressions.
@set MODULE pam_regex
@ -622,7 +703,7 @@ return @code{PAM_AUTH_ERR}. Default is @samp{allow}.
@end table
@node log, sql, regex, Top
@node log
@chapter Log arbitrary messages to syslog.
@set MODULE pam_log
@ -695,7 +776,7 @@ cvs session required pam_permit.so
@end group
@end smallexample
@node sql, Reporting Bugs, log, Top
@node sql
@chapter SQL Authentication and Session Management.
@set MODULE pam_sql
@prindex pam_pgsql
@ -1050,7 +1131,7 @@ The @var{query} is subject to item expansion (@pxref{item expansion}).
@xref{sql setenv}, for a detailed description.
@end table
@node Reporting Bugs, Copying This Manual, sql, Top
@node Reporting Bugs
@chapter How to Report a Bug
Email bug reports to @email{bug-pam-modules@@gnu.org.ua}.
@ -1065,10 +1146,11 @@ The information needed is:
@item Conditions under which the bug appears.
@end itemize
@node Copying This Manual, Concept Index, Reporting Bugs, Top
@node Copying This Manual
@appendix GNU Free Documentation License
@include fdl.texi
@node Concept Index, , Copying This Manual, Top
@node Concept Index,
@comment node-name, next, previous, up
@unnumbered Concept Index

18
pamck/Makefile.am Normal file
View file

@ -0,0 +1,18 @@
# Copyright (C) 2009 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, 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/>.
bin_PROGRAMS = pamck
LDADD = -lpam
pamck_SOURCES=pamck.c pamck.h conv.c

165
pamck/conv.c Normal file
View file

@ -0,0 +1,165 @@
/* This file is part of pam-modules.
Copyright (C) 2009 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 <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "pamck.h"
#if HAVE_TERMIOS_H
# include <termios.h>
#endif
#ifndef TCSASOFT
# define TCSASOFT 0
#endif
#define DELTA 1
static char *
readline (FILE *in)
{
char *buf;
size_t bufsize = 1;
size_t len = 0;
int c;
buf = malloc(bufsize);
if (!buf)
return buf;
while ((c = fgetc(in)) != EOF) {
if (len + 1 == bufsize) {
char *p = realloc(buf, bufsize + DELTA);
if (!p) {
free(buf);
return NULL;
}
bufsize += DELTA;
buf = p;
}
if (c == '\n') {
buf[len++] = 0;
break;
} else
buf[len++] = c;
}
return buf;
}
static char *
read_string(const char *prompt, int echo)
{
FILE *tty, *in, *out;
struct termios s, t;
int tty_changed = 0;
char *str;
tty = fopen ("/dev/tty", "w+");
if (tty == NULL) {
in = stdin;
out = stderr;
} else
out = in = tty;
#if HAVE_TCGETATTR
if (!echo) {
if (tcgetattr(fileno(in), &t) == 0) {
/* Save the old one. */
s = t;
/* Tricky, tricky. */
t.c_lflag &= ~(ECHO | ISIG);
tty_changed = tcsetattr(fileno(in),
TCSAFLUSH | TCSASOFT,
&t) == 0;
}
}
#endif
fputs(prompt, out);
fflush(out);
str = readline(in);
fputc('\n', out);
fseek(out, 0, SEEK_CUR);
#if HAVE_TCGETATTR
if (tty_changed)
tcsetattr(fileno(in), TCSAFLUSH | TCSASOFT, &s);
#endif
if (tty != NULL)
fclose(tty);
return str;
}
int
pamck_conv(int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *closure)
{
int i;
struct pam_response *reply;
if (num_msg <= 0)
return PAM_CONV_ERR;
reply = calloc(num_msg, sizeof(struct pam_response));
if (!reply)
return PAM_CONV_ERR;
for (i = 0; i < num_msg; i++) {
char *str;
switch (msg[i]->msg_style) {
case PAM_PROMPT_ECHO_OFF:
str = read_string(msg[i]->msg, 0);
break;
case PAM_PROMPT_ECHO_ON:
if (pass)
str = strdup(pass);
else
str = pass = read_string(msg[i]->msg, 1);
break;
case PAM_ERROR_MSG:
if (fprintf(stderr,"%s\n",msg[i]->msg) < 0)
break;
continue;
case PAM_TEXT_INFO:
if (fprintf(stdout,"%s\n",msg[i]->msg) < 0)
break;
continue;
default:
error(0, "erroneous conversation (%d)",
msg[i]->msg_style);
}
if (str) {
reply[i].resp_retcode = 0;
reply[i].resp = str;
} else {
free(reply);
return PAM_CONV_ERR;
}
}
*resp = reply;
return PAM_SUCCESS;
}

211
pamck/pamck.c Normal file
View file

@ -0,0 +1,211 @@
/* This file is part of pam-modules.
Copyright (C) 2009 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 <http://www.gnu.org/licenses/>. */
#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: <http://www.gnu.org.ua/software/%s/>.\n",
PACKAGE_NAME, PACKAGE);
}
void
version()
{
printf("%s (%s) %s\n", program_name, PACKAGE, PACKAGE_VERSION);
fputs ("\
Copyright (C) 2009 Sergey Poznyakoff\n\
\n\
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\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 (!service)
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;
if (!argc || argc > 3) {
usage();
exit(1);
}
user = argv[0];
pass = argv[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);
}

17
pamck/pamck.h Normal file
View file

@ -0,0 +1,17 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <security/pam_appl.h>
extern char *user;
extern char *pass;
void error(int code, const char *fmt, ...);
int pamck_conv(int, const struct pam_message **,
struct pam_response **, void *);