pam_xdg: update to v0.8.0

This commit is contained in:
Steffen Nurpmeso 2021-09-01 15:58:30 +02:00
parent 6a74437922
commit 0c7b9fd7f7
6 changed files with 7 additions and 700 deletions

View File

@ -1,7 +1,5 @@
untrusted comment: verify with /etc/ports/contrib.pub
RWSagIOpLGJF35ByKJGqZDYTDYgapw8YNFcmoQfuIz4G84szVxTjO1rS11BBqoORBYTNjhd+T3T+UY/nvIWL0h6PK6YhrCZ7rwA=
SHA256 (Pkgfile) = c8ca4da1cb69de37a134d64ca3acbe68d49a5ca2f07c03f86919d9287acd39bb
RWSagIOpLGJF38vXUmHccJtpWh6lLPLXjBsQAIu9jyBjAwuy+q2IRksNUSDkG3WYjwshJpy6iLYkM4T9wwCbIkPCYR7Un9U7jA8=
SHA256 (Pkgfile) = 40650e03f6f56f26595ee0225fae4c3b77bb4721531c909e69a15b4b65246b29
SHA256 (.footprint) = 56d789b652e6167f5fb93e1e6d48243e13f598c6d9a72705a8e54a003574ba31
SHA256 (pam_xdg.c) = 3ed98ccd23cee452086722be11c605420b5b96d2a5bb6734270121f1eb18463c
SHA256 (pam_xdg.8) = 946a65f7559e5e9c343fecf565fc3ddee8227e29e2dbb1729eaa96ee6eff75f1
SHA256 (makefile) = 2466f499c3e84fd821176371fa9ff78143bf94b9ec09fd9e654b35613e4ead7d
SHA256 (pam_xdg-0.8.0.tar.gz) = 386ce8311d77e4a60792b1085c72f34484f44a93d1db1de7bed1d4fb423f8f48

View File

@ -1,13 +1,14 @@
# Description: PAM module to manage XDG Base Directories (sessions)
# Description: PAM module to manage XDG Base Directories (see manual)
# URL: https://www.sdaoden.eu/code.html#s-toolbox
# Maintainer: Steffen Nurpmeso, steffen at sdaoden dot eu
name=pam_xdg
version=20210801
version=0.8.0
release=1
source=($name.c $name.8 makefile)
source=(https://ftp.sdaoden.eu/${name}-${version}.tar.gz)
build () {
cd ${name}-${version}
make install DESTDIR=$PKG
}

View File

@ -1,18 +0,0 @@
README for pam_xdg
PAM module that handles the XDG Base Directory Specification[1]
directories, including creation of XDG_RUNTIME_DIR and injection
of according environment variables into user sessions.
For it to work it must be included in /etc/pam.d -- to make it a
vivid part of session handling the file /etc/pam.d/common-session
seems best. Include the following early:
session optional pam_xdg.so [notroot] [runtime] [track_sessions]
Use notroot argument to only handle XDG for non-root users.
Use runtime argument to only handle of XDG_RUNTIME_DIR.
Use track_sessions to remove XDG_RUNTIME_DIR once the last user
session ends (take care of CAVEATS of manual, maybe).
[1] https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html

View File

@ -1,41 +0,0 @@
#@ Makefile for pam_xdg(8).
PREFIX = /
MANPREFIX = /usr
DESTDIR =
LIBDIR = $(DESTDIR)$(PREFIX)/lib/security
MANDIR = $(DESTDIR)$(MANPREFIX)/share/man/man8
NAME = pam_xdg
CC = cc
CFLAGS = -DNDEBUG \
-O2 -W -Wall -Wextra -pedantic \
-Wno-uninitialized -Wno-unused-result -Wno-unused-value \
-fno-asynchronous-unwind-tables -fno-unwind-tables \
-fno-common \
-fstrict-aliasing -fstrict-overflow \
-fstack-protector-strong -D_FORTIFY_SOURCE=2 -fPIE
LDFLAGS = -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -Wl,--as-needed \
-Wl,--enable-new-dtags -pie -shared
INSTALL = install
RM = rm
.PHONY: all clean distclean install uninstall
all: $(NAME).so
$(NAME).so: $(NAME).c
$(CC) $(CFLAGS) $(LDFLAGS) -o $(@) $(?)
clean:
$(RM) -f $(NAME).so
distclean: clean
install: all
$(INSTALL) -D -m 0755 $(NAME).so $(LIBDIR)/$(NAME).so
$(INSTALL) -D -m 0644 $(NAME).8 $(MANDIR)/$(NAME).8
uninstall:
$(RM) -f $(LIBDIR)/$(NAME).so $(MANDIR)/$(NAME).8
# s-mk-mode

View File

@ -1,112 +0,0 @@
.\"@ pam_xdg - manage XDG Base Directories (runtime dir life time, environ).
.\"
.\" Copyright (c) 2021 Steffen Nurpmeso <steffen@sdaoden.eu>.
.\" SPDX-License-Identifier: ISC
.\"
.\" Permission to use, copy, modify, and/or distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.
.Dd August 1, 2021
.Dt PAM_XDG 8
.Os
.
.
.Sh NAME
.Nm pam_xdg.so
.Nd PAM module that manages XDG Base Directories
.
.
.Sh SYNOPSIS
.
.Nm
.Op Ar runtime
.Op Ar notroot
.Op Ar track_sessions Op Ar per_user_lock
.
.
.Sh DESCRIPTION
.
.Nm
is a PAM module that manages creation of the
.Ev XDG_RUNTIME_DIR
directory, as well as injection of environment variables denoting all
directories specified by the
.Lk https://specifications.\:freedesktop.\:org/basedir-\:\
spec/\:basedir-\:spec-\:latest.html "XDG Base Directory Specification"
into user sessions.
.
.Pp
When linked into the PAM session system the runtime directory will be
created once a user creates his or her first login session.
Unless
.Ar runtime
was given all XDG related environment variables will be created in all
user sessions with their default or computed values, otherwise only
.Ev XDG_RUNTIME_DIR .
If
.Ar notroot
was given the module will bypass itself for root account logins and
perform no actions for root.
Lastly
.Ar track_sessions
will enable session tracking: once the last session ends, the user's
.Ev XDG_RUNTIME_DIR
will be recursively removed; on high-load servers then setting
.Ar per_user_lock
will reduce lock file lock contention.
.
.Pp
In order to make use of this module, place the following in the
.Ql session
part of the control file of desire under
.Pa /etc/pam.d ,
on Linux it may be
.Pa /etc/pam.d/common-session
if that exists, on BSD's the files
.Pa /etc/pam.d/system
as well as
.Pa /etc/pam.d/login ,
.Pa /etc/pam.d/sshd
and
.Pa /etc/pam.d/su
may be desirable, adjusting paths as necessary:
.
.Bd -literal -offset indent
session optional pam_xdg.so notroot track_sessions
.Ed
.
.
.Sh "SEE ALSO"
.
.Xr pam 3 ,
.Xr pam.conf 5
.
.
.Sh AUTHORS
.
.An "Steffen Nurpmeso" Aq steffen@sdaoden.eu .
.
.
.Sh CAVEATS
.
On Unix systems any
.Dq daemonized
program or script is reparented to the program running with PID 1,
most likely leaving the PAM user session without PAM recognizing this.
Yet careless such code may hold or expect availability of resources of
the session it just left, truly performing cleanup when sessions end
seems thus unwise.
Since so many PAM modules do support session tracking and cleanup
.Nm
readded optional support for this.
.
.\" s-ts-mode

View File

@ -1,521 +0,0 @@
/*@ pam_xdg - manage XDG Base Directories (runtime dir life time, environment).
*@ See pam_xdg.8 for more.
*@ - According to XDG Base Directory Specification, v0.7.
*@ - Supports libpam (Linux) and OpenPAM.
*@ - Requires C preprocessor with __VA_ARGS__ support!
*@ - Uses "rm -rf" to drop per-user directories. XXX Unroll this? nftw?
*
* Copyright (c) 2021 Steffen Nurpmeso <steffen@sdaoden.eu>.
* SPDX-License-Identifier: ISC
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* For these a leading \1 is replaced with struct passwd::pw_dir.
* Be aware we use a stack buffer for storage */
#define a_XDG_DATA_HOME_DEF "\1/.local/share"
#define a_XDG_CONFIG_HOME_DEF "\1/.config"
#define a_XDG_DATA_DIRS_DEF "/usr/local/share:/usr/share"
#define a_XDG_CONFIG_DIRS_DEF "/etc/xdg/"
#define a_XDG_CACHE_HOME_DEF "\1/.cache"
/* We create the outer directories as necessary (stack buffer storage!) */
#define a_RUNTIME_DIR_OUTER "/run"
#define a_RUNTIME_DIR_OUTER_MODE 0755
#define a_RUNTIME_DIR_BASE "user"
#define a_RUNTIME_DIR_BASE_MODE 0755 /* 0711? */
/* Note: we manage these relative to the per-user directory!
* a_LOCK_FILE is only used without "per_user_lock" */
#define a_LOCK_FILE "../." a_XDG ".lck"
#define a_LOCK_TRIES 10
#define a_DAT_FILE "." a_XDG ".dat"
/* >8 -- 8< */
/*
#define _POSIX_C_SOURCE 200809L
#define _ATFILE_SOURCE
*/
#define _GNU_SOURCE /* Always the same mess */
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <pwd.h>
#include <stdint.h> /* xxx not, actually!?! */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <security/pam_appl.h>
#include <security/pam_modules.h>
#ifdef OPENPAM_VERSION
# include <security/openpam.h>
#else
# include <security/pam_ext.h>
#endif
#ifdef OPENPAM_VERSION
#else
# include <syslog.h>
#endif
/* Who are we? */
#define a_XDG "pam_xdg"
/* _XOPEN_PATH_MAX POSIX 2008/Cor 1-2013 */
#ifndef PATH_MAX
# define PATH_MAX 1024
#endif
/* */
#ifdef O_SEARCH
# define a_O_SEARCH O_SEARCH
#elif defined O_PATH
# define a_O_SEARCH O_PATH
#else
/* Well, hardly, but not in practice so do not #error out */
# define a_O_SEARCH 0
#endif
/* libpam / OpenPAM compat */
#ifdef OPENPAM_VERSION
# define a_LOG(HDL, LVL, ...) ((void)HDL, openpam_log(LVL, __VA_ARGS__))
# define a_LOG_ERR PAM_LOG_ERROR
# define a_LOG_NOTICE PAM_LOG_NOTICE
#else
# define a_LOG(HDL, LVL, ...) pam_syslog(HDL, LVL, __VA_ARGS__)
# define a_LOG_ERR LOG_ERR
# define a_LOG_NOTICE LOG_NOTICE
#endif
/* Just put it all in one big fun, use two exec paths */
static int a_xdg(int isopen, pam_handle_t *pamh, int flags, int argc,
const char **argv);
static int
a_xdg(int isopen, pam_handle_t *pamh, int flags, int argc, const char **argv){
enum a_flags{
a_NONE,
/* Options */
a_RUNTIME = 1u<<0,
a_NOTROOT = 1u<<1,
a_SESSIONS = 1u<<16,
a_USER_LOCK = 1u<<17,
/* Flags */
a_MPV = 1u<<29, /* Multi-Purpose-Vehicle */
a_SKIP_XDG = 1u<<30 /* We shall not act */
};
struct a_dirtree{
char const *name;
int mode;
};
static struct a_dirtree const a_dirtree[] = {
{a_RUNTIME_DIR_OUTER, a_RUNTIME_DIR_OUTER_MODE},
{a_RUNTIME_DIR_BASE, a_RUNTIME_DIR_BASE_MODE},
{NULL, 0} /* XXX -> nelem/item/countof */
};
static int f_saved;
char uidbuf[sizeof "../.18446744073709551615"],
xbuf[((sizeof("XDG_RUNTIME_DIR=") + sizeof(a_RUNTIME_DIR_OUTER) +
sizeof(a_RUNTIME_DIR_BASE) +
sizeof("../.18446744073709551615")) |
(sizeof("XDG_CONFIG_DIRS=") + PATH_MAX)
) +1];
struct a_dirtree dt_user;
struct a_dirtree const *dtp;
struct passwd *pwp;
char const *emsg;
int cwdfd, cntrlfd, datfd, f, res, uidbuflen;
char const *user;
user = "<unset>";
cwdfd = AT_FDCWD;
datfd = cntrlfd = -1;
/* Command line */
if(isopen){
f = a_NONE;
for(; argc > 0; ++argv, --argc){
if(!strcmp(argv[0], "runtime"))
f |= a_RUNTIME;
else if(!strcmp(argv[0], "rundir")){ /* XXX COMPAT */
a_LOG(pamh, a_LOG_NOTICE,
a_XDG ": \"rundir\" was a misdocumentation of \"runtime\", "
"sorry for this");
f |= a_RUNTIME;
}
else if(!strcmp(argv[0], "notroot"))
f |= a_NOTROOT;
else if(!strcmp(argv[0], "track_sessions"))
f |= a_SESSIONS;
else if(!strcmp(argv[0], "per_user_lock"))
f |= a_USER_LOCK;
else if(!(flags & PAM_SILENT)){
emsg = "command line";
errno = EINVAL;
goto jerr;
}
}
if((f & a_USER_LOCK) && !(f & a_SESSIONS))
a_LOG(pamh, a_LOG_NOTICE,
a_XDG ": \"per_user_lock\" requires \"track_sessions\"");
}else{
f = f_saved;
if(f & a_SKIP_XDG)
goto jok;
}
/* We need the user we go for */
if((res = pam_get_item(pamh, PAM_USER, (void const**)&user)
) != PAM_SUCCESS){
user = "<lookup failed>";
emsg = "cannot query PAM_USER name";
goto jepam;
}
/* No PAM failure, no PAM_USER_UNKNOWN here: we are no authentificator! */
if((pwp = getpwnam(user)) == NULL){
emsg = "host does not know about user";
errno = EINVAL;
goto jerr;
}
if((f & a_NOTROOT) && pwp->pw_uid == 0){
f |= a_SKIP_XDG;
goto jok;
}
/* Our lockfile and per-user directory name */
uidbuflen = snprintf(uidbuf, sizeof(uidbuf), "../.%lu", /* xxx error?? */
(unsigned long)pwp->pw_uid) - 3;
dt_user.name = &uidbuf[4];
dt_user.mode = 0700; /* XDG implied */
/* Handle tree, go to user runtime. On *BSD outermost may not exist! */
for(/*f &= ~a_MPV,*/ dtp = a_dirtree;;){
int e;
gid_t oegid;
mode_t oumask;
if((res = openat(cwdfd, dtp->name,
(a_O_SEARCH | O_DIRECTORY | O_NOFOLLOW))) != -1){
if(cwdfd != AT_FDCWD)
close(cwdfd); /* XXX error hdl */
cwdfd = res;
if(dtp == &dt_user)
break;
else if((++dtp)->name == NULL)
dtp = &dt_user;
f &= ~a_MPV;
continue;
}
if(!isopen)
/* XXX Entire directory tree disappeared while sessions were open!
* XXX Silently out!?! */
goto jok;
/* We try creating the directories once as necessary */
if((f & a_MPV) || errno != ENOENT){
emsg = "cannot obtain chdir(2) descriptor (within) tree "
a_RUNTIME_DIR_OUTER "/" a_RUNTIME_DIR_BASE;
goto jerr;
}
f |= a_MPV;
oumask = umask(0000);
oegid = getegid();
setegid(0);
res = mkdirat(cwdfd, dtp->name, dtp->mode);
e = (res == -1) ? errno : 0;
setegid(oegid);
umask(oumask);
if(res == -1){
if(e != EEXIST){
emsg = "cannot create directory (within) tree "
a_RUNTIME_DIR_OUTER "/" a_RUNTIME_DIR_BASE;
goto jerr;
}
}else if(cwdfd == AT_FDCWD)
a_LOG(pamh, a_LOG_NOTICE,
a_XDG ": " a_RUNTIME_DIR_OUTER " did not exist, but should be "
"(a mount point of) volatile storage!");
/* Just chown it! */
else if(dtp == &dt_user &&
fchownat(cwdfd, &uidbuf[4], pwp->pw_uid, pwp->pw_gid,
AT_SYMLINK_NOFOLLOW) == -1){
emsg = "cannot chown(2) per user XDG_RUNTIME_DIR";
goto jerr;
}
}
/* In session mode we have to manage the counter file */
if(f & a_SESSIONS){
unsigned long long int sessions;
/* Landed in the runtime base dir, obtain our lock */
if((cntrlfd = openat(cwdfd,
(f & a_USER_LOCK ? uidbuf : a_LOCK_FILE),
(O_CREAT | O_WRONLY | O_NOFOLLOW | O_NOCTTY),
(S_IRUSR | S_IWUSR))) == -1){
emsg = "cannot open control lock file";
goto jerr;
}
for(res = a_LOCK_TRIES;;){
struct flock flp;
memset(&flp, 0, sizeof flp);
flp.l_type = F_WRLCK;
flp.l_start = 0;
flp.l_whence = SEEK_SET;
flp.l_len = 0;
if(fcntl(cntrlfd, F_SETLKW, &flp) != -1)
break;
/* XXX It may happen we cannot manage the lock and thus not access
* XXX the session counter, ie this session is zombie to us.
* XXX Just like counter below, should globally disable sessions!! */
if(errno != EINTR){
emsg = "unexpected error obtaining lock on lock control file";
goto jerr;
}
if(--res == 0){
emsg = "cannot obtain lock on lock control file";
goto jerr;
}
}
sessions = 0;
if((datfd = openat(cwdfd, a_DAT_FILE, O_RDONLY)) != -1){
char *ep;
ssize_t r;
while((r = read(datfd, xbuf, sizeof(xbuf) -1)) == -1){
if(errno != EINTR)
goto jecnt;
}
close(datfd);
datfd = -1;
xbuf[(size_t)r] = '\0';
sessions = strtoull(xbuf, &ep, 10);
/* Do not log too often for "session counter error"s, as below */
if(ep == xbuf){
res = PAM_SESSION_ERR;
goto jleave;
}else if(sessions == ULLONG_MAX || ep != &xbuf[(size_t)r])
goto jecnt;
}
if(isopen)
++sessions;
else if(sessions > 0)
--sessions;
if(!isopen && sessions == 0){ /* former.. hmmm. */
/* Ridiculously simple, but everything else would be the opposite.
* Ie, E[MN]FILE failures, or whatever else */
char const cmd[] = "rm -rf " a_RUNTIME_DIR_OUTER "/"
a_RUNTIME_DIR_BASE "/";
memcpy(xbuf, cmd, sizeof(cmd) -1);
memcpy(&xbuf[sizeof(cmd) -1], &uidbuf[4], uidbuflen +1);
res = system(xbuf);
if(!WIFEXITED(res) || WEXITSTATUS(res) != 0){
emsg = "unable to rm(1) -rf per user XDG_RUNTIME_DIR";
errno = EINVAL;
goto jerr;
}
/* This is the end .. */
goto jok;
}else{
/* Write out session counter */
res = snprintf(xbuf, sizeof xbuf, "%llu", sessions); /* xxx error? */
if(((datfd = openat(cwdfd, a_DAT_FILE,
(O_CREAT | O_TRUNC | O_WRONLY | O_SYNC | O_NOFOLLOW |
O_NOCTTY),
(S_IRUSR | S_IWUSR))) == -1) ||
write(datfd, xbuf, res) != res){
jecnt:
/* Ensure read above fails, so that henceforth session teardown is
* skipped for this user */
truncate(a_DAT_FILE, 0);
emsg = "counter file error, disabled session tracking for user";
goto jerr;
}
close(datfd);
datfd = -1;
}
}
/* When opening, we want to put environment variables, too */
if(isopen){
char *cp;
/* XDG_RUNTIME_DIR */
cp = xbuf;
memcpy(cp, "XDG_RUNTIME_DIR=", sizeof("XDG_RUNTIME_DIR=") -1);
cp += sizeof("XDG_RUNTIME_DIR=") -1;
memcpy(cp, a_RUNTIME_DIR_OUTER, sizeof(a_RUNTIME_DIR_OUTER) -1);
cp += sizeof(a_RUNTIME_DIR_OUTER) -1;
*cp++ = '/';
memcpy(cp, a_RUNTIME_DIR_BASE, sizeof(a_RUNTIME_DIR_BASE) -1);
cp += sizeof(a_RUNTIME_DIR_BASE) -1;
*cp++ = '/';
memcpy(cp, &uidbuf[4], uidbuflen);
if((res = pam_putenv(pamh, xbuf)) != PAM_SUCCESS)
goto jepam;
/* And the rest unless disallowed */
if(!(f & a_RUNTIME)){
struct a_dir{
char const *name;
size_t len;
char const *defval;
};
static struct a_dir const a_dirs[] = {
{"XDG_DATA_HOME=", sizeof("XDG_DATA_HOME=") -1,
a_XDG_DATA_HOME_DEF},
{"XDG_CONFIG_HOME=", sizeof("XDG_CONFIG_HOME=") -1,
a_XDG_CONFIG_HOME_DEF},
{"XDG_DATA_DIRS=", sizeof("XDG_DATA_DIRS=") -1,
a_XDG_DATA_DIRS_DEF},
{"XDG_CONFIG_DIRS=", sizeof("XDG_CONFIG_DIRS=") -1,
a_XDG_CONFIG_DIRS_DEF},
{"XDG_CACHE_HOME=", sizeof("XDG_CACHE_HOME=") -1,
a_XDG_CACHE_HOME_DEF},
{NULL,0,NULL} /* XXX -> nelem/item/countof */
};
char const *src;
struct a_dir const *adp;
size_t i;
i = strlen(pwp->pw_dir);
for(adp = a_dirs; adp->name != NULL; ++adp){
cp = xbuf;
memcpy(cp, adp->name, adp->len);
cp += adp->len;
if(*(src = adp->defval) == '\1'){
memcpy(cp, pwp->pw_dir, i);
cp += i;
++src;
}
memcpy(cp, src, strlen(src) +1);
if((res = pam_putenv(pamh, xbuf)) != PAM_SUCCESS)
goto jepam;
}
}
}
jok:
res = PAM_SUCCESS;
jleave:
if(datfd != -1)
close(datfd);
if(cntrlfd != -1)
close(cntrlfd);
if(cwdfd != -1 && cwdfd != AT_FDCWD) /* >=0, but AT_FDCWD unspecified */
close(cwdfd);
f_saved = f;
return (res == PAM_SUCCESS) ? PAM_SUCCESS : PAM_SESSION_ERR;
jerr:
a_LOG(pamh, a_LOG_ERR, a_XDG ": user %s: %s: %s\n",
user, emsg, strerror(errno));
f |= a_SKIP_XDG;
res = PAM_SESSION_ERR;
goto jleave;
jepam:
a_LOG(pamh, a_LOG_ERR, a_XDG ": user %s: PAM failure: %s\n",
user, pam_strerror(pamh, res));
f |= a_SKIP_XDG;
goto jleave;
}
int
pam_sm_open_session(pam_handle_t *pamh, int flags,
int argc, const char **argv){
return a_xdg(1, pamh, flags, argc, argv);
}
int
pam_sm_close_session(pam_handle_t *pamh, int flags,
int argc, const char **argv){
return a_xdg(0, pamh, flags, argc, argv);
}
int
pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv){
(void)flags;
(void)argc;
(void)argv;
a_LOG(pamh, a_LOG_NOTICE, a_XDG ": pam_sm_acct_mgmt not used");
return PAM_SERVICE_ERR;
}
int
pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv){
(void)flags;
(void)argc;
(void)argv;
a_LOG(pamh, a_LOG_NOTICE, a_XDG ": pam_sm_setcred not used");
return PAM_SERVICE_ERR;
}
int
pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv){
(void)flags;
(void)argc;
(void)argv;
a_LOG(pamh, a_LOG_NOTICE, a_XDG ": pam_sm_chauthtok not used");
return PAM_SERVICE_ERR;
}
/* s-it-mode */