From 60cb0edb8c2a3a114f965434a2c2787e5441066b Mon Sep 17 00:00:00 2001 From: Steffen Nurpmeso Date: Mon, 1 Feb 2021 18:53:46 +0100 Subject: [PATCH] pam_xdg: now without lock, must ignore EEXIST race of mkdir(2) --- pam_xdg/.signature | 6 ++--- pam_xdg/Pkgfile | 2 +- pam_xdg/README | 9 ++++---- pam_xdg/pam_xdg.c | 56 ++++++++++++++++++++++++---------------------- 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/pam_xdg/.signature b/pam_xdg/.signature index 06ecf7a22..7145ad23b 100644 --- a/pam_xdg/.signature +++ b/pam_xdg/.signature @@ -1,7 +1,7 @@ untrusted comment: verify with /etc/ports/contrib.pub -RWSagIOpLGJF3/opxnSlpIKUNMt7/zCoADPQ4PYlOmbd2GckIrSxOZvjqNNRaw5n+mhVd/iOl35BH6C2CIKF12kK6df2J7zZ4Q8= -SHA256 (Pkgfile) = ac39f667ad9c2778b25753a6265ef2705335afb9b5cde1f70d9cb86f9ee22076 +RWSagIOpLGJF3zU5kDWhhX3qLiOO1k39Qr77RTQlPHx5nQ5AZM61Q7VwupJYofPRUC254NZx4DRiSpe7m+Xomj8CAR1bi44YKAs= +SHA256 (Pkgfile) = bb1ddb4db1eaed4c45e506b5ca6d0baed5f3e813c88b9908c27566ea93f0ed55 SHA256 (.footprint) = 56d789b652e6167f5fb93e1e6d48243e13f598c6d9a72705a8e54a003574ba31 -SHA256 (pam_xdg.c) = 81bfedeb798bc63d33f2b44874df0d796b439e93876a4a41f94d1ee26a001c38 +SHA256 (pam_xdg.c) = 23ddd5788de1d0e76381935f0b9de1f134f26039fbfe24bb4445ce5ebff4f04c SHA256 (pam_xdg.8) = 2929bcd6655d28127d386215d3d8c4fed6744b65c4866ac7e49d54cb438d9133 SHA256 (makefile) = 2466f499c3e84fd821176371fa9ff78143bf94b9ec09fd9e654b35613e4ead7d diff --git a/pam_xdg/Pkgfile b/pam_xdg/Pkgfile index b798857b7..22293114e 100644 --- a/pam_xdg/Pkgfile +++ b/pam_xdg/Pkgfile @@ -3,7 +3,7 @@ # Maintainer: Steffen Nurpmeso, steffen at sdaoden dot eu name=pam_xdg -version=20210131 +version=20210201 release=1 source=($name.c $name.8 makefile) diff --git a/pam_xdg/README b/pam_xdg/README index 3221cb225..ec7ab9421 100644 --- a/pam_xdg/README +++ b/pam_xdg/README @@ -1,15 +1,14 @@ 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. +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] + 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. diff --git a/pam_xdg/pam_xdg.c b/pam_xdg/pam_xdg.c index 1ed589727..ce326c610 100644 --- a/pam_xdg/pam_xdg.c +++ b/pam_xdg/pam_xdg.c @@ -141,12 +141,14 @@ a_xdg(int isopen, pam_handle_t *pamh, int flags, int argc, const char **argv){ goto jerr; } - if(mkdirat(cwdfd, a_RUNTIME_DIR_BASE, a_RUNTIME_DIR_BASE_MODE) == -1){ + if(mkdirat(cwdfd, a_RUNTIME_DIR_BASE, a_RUNTIME_DIR_BASE_MODE + ) == -1 && errno != EEXIST){ emsg = "cannot create base directory " a_RUNTIME_DIR_OUTER "/" a_RUNTIME_DIR_BASE; goto jerr; } } + /* Not worth doing S_ISDIR(st.st_mode), O_DIRECTORY will bail next */ } if((res = openat(cwdfd, a_RUNTIME_DIR_BASE, @@ -163,37 +165,37 @@ a_xdg(int isopen, pam_handle_t *pamh, int flags, int argc, const char **argv){ (unsigned long)pwp->pw_uid); /* We create the per-user directory on isopen time as necessary */ - /*if(isopen)*/{ - for(res = 0;; ++res){ - int nfd; + for(res = 0;; ++res){ + int nfd; - if((nfd = openat(cwdfd, uidbuf, (O_PATH | O_DIRECTORY | O_NOFOLLOW)) - ) != -1){ - close(cwdfd); - cwdfd = nfd; - break; + 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{ - if(errno == ENOENT){ - if(!isopen) - goto jok; - if(res != 0) - goto jeurd; - }else{ jeurd: - emsg = "per user XDG_RUNTIME_DIR not accessible"; - goto jerr; - } + 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; - } + if(mkdirat(cwdfd, uidbuf, 0700) == -1 && errno != EEXIST){ + emsg = "cannot create per user XDG_RUNTIME_DIR"; + goto jerr; + } + + /* Just chown it! */ + 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; } }