[crux-commits] ports/contrib (refs/remotes/origin/3.6): pam_xdg: new port: all-around carefree XDG Base Directories package

crux at crux.nu crux at crux.nu
Sat Apr 10 19:05:57 UTC 2021


commit 254e705c27a7ac96d70ebe275e68fbd4acc5c87e
Author: Steffen Nurpmeso <steffen at sdaoden.eu>
Date:   Sat Jan 30 23:10:12 2021 +0100

    pam_xdg: new port: all-around carefree XDG Base Directories package

diff --git a/pam_xdg/.footprint b/pam_xdg/.footprint
new file mode 100644
index 000000000..88ae0d381
--- /dev/null
+++ b/pam_xdg/.footprint
@@ -0,0 +1,8 @@
+drwxr-xr-x	root/root	lib/
+drwxr-xr-x	root/root	lib/security/
+-rwxr-xr-x	root/root	lib/security/pam_xdg.so
+drwxr-xr-x	root/root	usr/
+drwxr-xr-x	root/root	usr/share/
+drwxr-xr-x	root/root	usr/share/man/
+drwxr-xr-x	root/root	usr/share/man/man8/
+-rw-r--r--	root/root	usr/share/man/man8/pam_xdg.8.gz
diff --git a/pam_xdg/.signature b/pam_xdg/.signature
new file mode 100644
index 000000000..ee0895692
--- /dev/null
+++ b/pam_xdg/.signature
@@ -0,0 +1,7 @@
+untrusted comment: verify with /etc/ports/contrib.pub
+RWSagIOpLGJF3yVeUzlfQ7+UJq2gIuabqKJqhiWq7h2/UY5x8mlWVY7NEag9ndV9ypuodnfpLrP0QWzNjqO3eRJ1b5zTk3MRnAs=
+SHA256 (Pkgfile) = e1b2ba87fd768518b4f81f3f9fb1fcce6780b2538cded18600564532e86f6a05
+SHA256 (.footprint) = 56d789b652e6167f5fb93e1e6d48243e13f598c6d9a72705a8e54a003574ba31
+SHA256 (pam_xdg.c) = 9125ac3749b087f78844953a1a43790055a62efa0b8c25bd8766e35b061ca58c
+SHA256 (pam_xdg.8) = 0f19e9f2437c6d0cb24465798ded6d6a3b2be07c012ee611648a4e4f1a21bbf1
+SHA256 (makefile) = 2466f499c3e84fd821176371fa9ff78143bf94b9ec09fd9e654b35613e4ead7d
diff --git a/pam_xdg/Pkgfile b/pam_xdg/Pkgfile
new file mode 100644
index 000000000..71c42bd5e
--- /dev/null
+++ b/pam_xdg/Pkgfile
@@ -0,0 +1,14 @@
+# Description: PAM module to manage XDG Base Directories
+# URL:         https://www.sdaoden.eu/code.html#s-toolbox
+# Maintainer:  Steffen Nurpmeso, steffen at sdaoden dot eu
+
+name=pam_xdg
+version=20210130
+release=1
+source=($name.c $name.8 makefile)
+
+build () {
+   make install DESTDIR=$PKG
+}
+
+# s-sh-mode
diff --git a/pam_xdg/README b/pam_xdg/README
new file mode 100644
index 000000000..3221cb225
--- /dev/null
+++ b/pam_xdg/README
@@ -0,0 +1,17 @@
+README for pam_xdg
+
+This is a module for PAM that handles the XDG Base Directory
+Specification[1] directories, including lifetime management
+of XDG_RUNTIME_DIR and injection of according environment variables
+into the user session.
+
+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]
+
+Use notroot argument to only handle XDG for non-root users.
+Use runtime argument to only handle of XDG_RUNTIME_DIR.
+
+  [1] https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
diff --git a/pam_xdg/makefile b/pam_xdg/makefile
new file mode 100644
index 000000000..2f060a7e6
--- /dev/null
+++ b/pam_xdg/makefile
@@ -0,0 +1,41 @@
+#@ 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
diff --git a/pam_xdg/pam_xdg.8 b/pam_xdg/pam_xdg.8
new file mode 100644
index 000000000..013fb7ea1
--- /dev/null
+++ b/pam_xdg/pam_xdg.8
@@ -0,0 +1,85 @@
+.\"@ pam_xdg - manage XDG Base Directories (runtime dir life time, environ).
+.\"
+.\" Copyright (c) 2021 Steffen Nurpmeso <steffen at 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 January 30, 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 rundir
+.Op Ar notroot
+.
+.
+.Sh DESCRIPTION
+.
+.Nm
+is a PAM module that manages creation and deletion 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 system, the runtime directory will be created as
+.Ql /run/user/`id -u`
+once a user creates his or her first login session, and it will be
+removed recursively once the last such session ends.
+Unless
+.Ar rundir
+was given all XDG related environment variables will be created in the
+user session 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, that
+is, no actions will be performed.
+.
+.Pp
+In order to make use of this script, place the following in the control
+file of desire under
+.Pa /etc/pam.d ,
+best maybe
+.Pa /etc/pam.d/common-session
+if that exists (possibly adjusting paths):
+.
+.Bd -literal -offset indent
+session optional pam_xdg.so notroot
+.Ed
+.
+.
+.Sh "SEE ALSO"
+.
+.Xr pam.conf 5 ,
+.Xr pam.d 8 ,
+.Xr pam 8
+.
+.
+.Sh AUTHORS
+.
+.An "Steffen Nurpmeso" Aq steffen at sdaoden.eu .
+.
+.\" s-ts-mode
diff --git a/pam_xdg/pam_xdg.c b/pam_xdg/pam_xdg.c
new file mode 100644
index 000000000..a2c56cdfe
--- /dev/null
+++ b/pam_xdg/pam_xdg.c
@@ -0,0 +1,437 @@
+/*@ pam_xdg - manage XDG Base Directories (runtime dir life time, environment).
+ *@ Create /run/user/`id -u` when the first session is opened, and remove it
+ *@ again once the last is closed.
+ *@ It also creates according XDG_RUNTIME_DIR etc. environment variables in the
+ *@ user sessions, except when given the "runtime" option, in which case it
+ *@ only creates XDG_RUNTIME_DIR and not the others.
+ *@ Place for example in /etc/pam.d/common-session one of the following:
+ *@   session options pam_xdg.so [runtime] [notroot]
+ *@ Notes: - effectively needs ISO C99 as it uses strtoull(3).
+ *@        - according to XDG Base Directory Specification, v0.7.
+ *@        - Linux.
+ *
+ * Copyright (c) 2021 Steffen Nurpmeso <steffen at 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"
+
+/* */
+#define a_XDG "pam_xdg"
+
+#define a_RUNTIME_DIR_OUTER "/run"  /* This must exist already */
+#define a_RUNTIME_DIR_BASE "user" /* We create this as necessary, thus. */
+
+#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>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_ext.h>
+
+/* _XOPEN_PATH_MAX POSIX 2008/Cor 1-2013 */
+#ifndef PATH_MAX
+# define PATH_MAX 1024
+#endif
+
+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){
+   char uidbuf[sizeof "18446744073709551615"],
+         wbuf[(((sizeof("18446744073709551615") -1) * 2) | 
+            (sizeof("cd ..;rm -rf ") + sizeof("18446744073709551615")) |
+            (sizeof("XDG_RUNTIME_DIR=") + sizeof(a_RUNTIME_DIR_OUTER) +
+               sizeof(a_RUNTIME_DIR_BASE) + sizeof("18446744073709551615")) |
+            (sizeof("XDG_CONFIG_DIRS=") + PATH_MAX)
+            ) +1];
+   struct flock flp;
+   struct stat st;
+   uint64_t sessions;
+   struct passwd *pwp;
+   char const *emsg;
+   int cntrlfd, fd, cwdfd, only_runtime, notroot, res, uidbuflen;
+   char const *user;
+   (void)flags;
+
+   user = "<unset>";
+   cntrlfd = fd = cwdfd = -1;
+   only_runtime = notroot = 0;
+
+   /* Command line */
+   if(isopen){
+      for(; argc > 0; ++argv, --argc){
+         if(!strcmp(argv[0], "runtime"))
+            only_runtime = 1;
+         else if(!strcmp(argv[0], "notroot"))
+            notroot = 1;
+         else if(!(flags & PAM_SILENT)){
+            emsg = "command line";
+            errno = EINVAL;
+            goto jerr;
+         }
+      }
+   }
+
+   /* 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;
+   }
+
+   if((pwp = getpwnam(user)) == NULL){
+      emsg = "host machine does not know about user";
+      errno = EINVAL;
+      goto jerr;
+   }
+
+   if(notroot && pwp->pw_uid == 0)
+      goto jok;
+
+   /* I admit all this is overly complicated and expensive */
+   umask(0022);
+
+   if((cwdfd = open(a_RUNTIME_DIR_OUTER, (O_PATH | O_DIRECTORY | O_NOFOLLOW))
+         ) == -1){
+      emsg = "cannot obtain chdir(2) descriptor to " a_RUNTIME_DIR_OUTER;
+      goto jerr;
+   }
+
+   /* We try create the base directory once as necessary */
+   if(isopen){
+      res = 0;
+      while(fstatat(cwdfd, a_RUNTIME_DIR_BASE, &st, AT_SYMLINK_NOFOLLOW
+            ) == -1){
+         if(res++ != 0 || errno != ENOENT){
+            emsg = "base directory " a_RUNTIME_DIR_OUTER "/" a_RUNTIME_DIR_BASE
+                  " not accessible";
+            goto jerr;
+         }
+
+         if(mkdirat(cwdfd, a_RUNTIME_DIR_BASE, 0711) == -1){
+            emsg = "cannot create base directory "
+                  a_RUNTIME_DIR_OUTER "/" a_RUNTIME_DIR_BASE;
+            goto jerr;
+         }
+      }
+   }
+
+   if((res = openat(cwdfd, a_RUNTIME_DIR_BASE,
+         (O_PATH | O_DIRECTORY | O_NOFOLLOW))) == -1){
+      emsg = "cannot obtain chdir(2) descriptor to " a_RUNTIME_DIR_OUTER "/"
+            a_RUNTIME_DIR_BASE;
+      goto jerr;
+   }
+   close(cwdfd);
+   cwdfd = res;
+
+   /* Landed in the runtime base dir, obtain our lock */
+   if((cntrlfd = openat(cwdfd, 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;;){
+      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;
+
+      if(errno != EINTR){
+         emsg = "unexpected error obtaining lock on control lock file";
+         goto jerr;
+      }
+      if(--res == 0){
+         emsg = "cannot obtain lock on control lock file";
+         goto jerr;
+      }
+   }
+
+   /* Turn to user management */
+   uidbuflen = snprintf(uidbuf, sizeof(uidbuf), "%lu",
+         (unsigned long)pwp->pw_uid);
+
+   /* We create the per-user directory on isopen time as necessary */
+   for(res = 0;; ++res){
+      int nfd;
+
+      if((nfd = openat(cwdfd, uidbuf, (O_PATH | O_DIRECTORY | O_NOFOLLOW))
+            ) != -1){
+         close(cwdfd);
+         cwdfd = nfd;
+         break;
+      }else{
+         if(errno == ENOENT){
+            if(!isopen)
+               goto jok;
+            if(res != 0)
+               goto jeurd;
+         }else{
+jeurd:
+            emsg = "per user XDG_RUNTIME_DIR not accessible";
+            goto jerr;
+         }
+      }
+
+      if(mkdirat(cwdfd, uidbuf, 0700) == -1){
+         emsg = "cannot create per user XDG_RUNTIME_DIR";
+         goto jerr;
+      }
+      if(fchownat(cwdfd, uidbuf, pwp->pw_uid, pwp->pw_gid, AT_SYMLINK_NOFOLLOW
+            ) == -1){
+         emsg = "cannot chown(2) per user XDG_RUNTIME_DIR";
+         goto jerr;
+      }
+   }
+
+   /* Read session counter; be simple and assume 0 if non-existent, this should
+    * not happen in practice */
+   sessions = 0;
+   if((fd = openat(cwdfd, a_DAT_FILE, O_RDONLY)) != -1){
+      char *ep;
+      ssize_t r;
+
+      while((r = read(fd, wbuf, sizeof(wbuf) -1)) == -1){
+         if(errno != EINTR){
+            emsg = "I/O error while reading session counter";
+            goto jerr;
+         }
+      }
+
+      /* We have written this as a valid POSIX text file, then, so chop tail */
+      if(r < 1 || (size_t)r >= (sizeof(wbuf) -1) / 2){
+jecnt:
+         emsg = "session counter corrupted, ask administrator to remove "
+               a_RUNTIME_DIR_OUTER "/" a_RUNTIME_DIR_BASE "/YOUR-UID/"
+               a_DAT_FILE;
+         goto jerr;
+      }
+      for(;;){
+         char c;
+
+         c = wbuf[(size_t)r - 1];
+         if(c == '\0' || c == '\n'){
+            if(--r == 0)
+               goto jecnt;
+         }else
+            break;
+      }
+      wbuf[(size_t)r] = '\0';
+
+      sessions = strtoull(wbuf, &ep, 10);
+      if(sessions == ULLONG_MAX || ep == wbuf || *ep != '\0')
+         goto jecnt;
+
+      close(fd);
+      fd = -1;
+   }
+
+   if(isopen)
+      ++sessions;
+   /* == 0 should never happen, but just handled it easily */
+   else if(sessions == 0 || --sessions == 0){
+      /* This is ridiculously simple, but everything else would be opposite */
+      char const cmd[] = "rm -rf " a_RUNTIME_DIR_OUTER "/"
+            a_RUNTIME_DIR_BASE "/";
+
+      memcpy(wbuf, cmd, sizeof(cmd) -1);
+      memcpy(&wbuf[sizeof(cmd) -1], uidbuf, uidbuflen +1);
+      res = system(wbuf);
+      if(!WIFEXITED(res) || WEXITSTATUS(res) != 0){
+         emsg = "unable to rm(1) -rf per user XDG_RUNTIME_DIR";
+         errno = EINVAL;
+         goto jerr;
+      }
+      goto jok;
+   }
+
+   /* Write out session counter (as a valid POSIX text file) */
+   res = snprintf(wbuf, sizeof wbuf, "%llu\n", (unsigned long long)sessions);
+
+   if(((fd = openat(cwdfd, a_DAT_FILE,
+         (O_CREAT | O_TRUNC | O_WRONLY | O_SYNC | O_NOFOLLOW | O_NOCTTY),
+         (S_IRUSR | S_IWUSR))) == -1) || write(fd, wbuf, res) != res){
+      emsg = "cannot write session counter, ask administrator to remove "
+            a_RUNTIME_DIR_OUTER "/" a_RUNTIME_DIR_BASE "/YOUR-UID/"
+            a_DAT_FILE;
+      goto jerr;
+   }
+   close(fd);
+   fd = -1;
+
+   /* When opening, we want to put environment variables, too */
+   if(isopen){
+      char *cp;
+
+      /* XDG_RUNTIME_DIR */
+      cp = wbuf;
+      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, uidbuflen +1);
+
+      if((res = pam_putenv(pamh, wbuf)) != PAM_SUCCESS)
+         goto jepam;
+
+      /* And the rest */
+      if(!only_runtime){
+         struct adir{
+            char const *name;
+            size_t len;
+            char const *defval;
+         } const adirs[] = {
+            {"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 */
+         }, *adp;
+
+         char const *src;
+         size_t i;
+
+         i = strlen(pwp->pw_dir);
+
+         for(adp = adirs; adp->name != NULL; ++adp){
+            cp = wbuf;
+            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, wbuf)) != PAM_SUCCESS)
+               goto jepam;
+         }
+      }
+   }
+
+jok:
+   res = PAM_SUCCESS;
+jleave:
+   if(fd != -1)
+      close(fd);
+   if(cntrlfd != -1)
+      close(cntrlfd);
+   if(cwdfd != -1)
+      close(cwdfd);
+
+   return (res == PAM_SUCCESS) ? PAM_SUCCESS : PAM_SESSION_ERR;
+
+jerr:
+   pam_syslog(pamh, LOG_ERR, a_XDG ": user %s: %s: %s\n",
+      user, emsg, strerror(errno));
+   res = PAM_SESSION_ERR;
+   goto jleave;
+
+jepam:
+   pam_syslog(pamh, LOG_ERR, a_XDG ": user %s: PAM failure: %s\n",
+      user, pam_strerror(pamh, res));
+   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;
+   pam_syslog(pamh, LOG_NOTICE, "pam_sm_acct_mgmt not used by " a_XDG);
+   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;
+   pam_syslog(pamh, LOG_NOTICE, "pam_sm_setcred not used by " a_XDG);
+   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;
+   pam_syslog(pamh, LOG_NOTICE, "pam_sm_chauthtok not used by " a_XDG);
+   return PAM_SERVICE_ERR;
+}
+
+/* s-it-mode */


More information about the crux-commits mailing list