aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2015-05-20 12:00:52 +0200
committerAndreas Schneider <asn@samba.org>2015-05-20 14:08:00 +0200
commit27fe103bc6aa5df272b641fc1c0ec352dfe7340f (patch)
tree2376e0ad6f1e89745419da2ac1de87fe8ea6f5c2
parent09146896e278578a4c8435a163c4b6c822221188 (diff)
downloadpam_wrapper-27fe103bc6aa5df272b641fc1c0ec352dfe7340f.tar.gz
pam_wrapper-27fe103bc6aa5df272b641fc1c0ec352dfe7340f.tar.xz
pam_wrapper-27fe103bc6aa5df272b641fc1c0ec352dfe7340f.zip
pwrap: Remove config directory if we cleanup
Signed-off-by: Andreas Schneider <asn@samba.org>
-rw-r--r--src/pam_wrapper.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/pam_wrapper.c b/src/pam_wrapper.c
index bb93376..96e77f0 100644
--- a/src/pam_wrapper.c
+++ b/src/pam_wrapper.c
@@ -27,6 +27,7 @@
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <dirent.h>
#include <unistd.h>
#include <dlfcn.h>
@@ -394,13 +395,86 @@ void pwrap_constructor(void)
* DESTRUCTOR
***************************/
+static int p_rmdirs(const char *path) {
+ DIR *d;
+ struct dirent *dp;
+ struct stat sb;
+ char *fname;
+
+ if ((d = opendir(path)) != NULL) {
+ while(stat(path, &sb) == 0) {
+ /* if we can remove the directory we're done */
+ if (rmdir(path) == 0) {
+ break;
+ }
+ switch (errno) {
+ case ENOTEMPTY:
+ case EEXIST:
+ case EBADF:
+ break; /* continue */
+ default:
+ closedir(d);
+ return 0;
+ }
+
+ while ((dp = readdir(d)) != NULL) {
+ size_t len;
+ /* skip '.' and '..' */
+ if (dp->d_name[0] == '.' &&
+ (dp->d_name[1] == '\0' ||
+ (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) {
+ continue;
+ }
+
+ len = strlen(path) + strlen(dp->d_name) + 2;
+ fname = malloc(len);
+ if (fname == NULL) {
+ return -1;
+ }
+ snprintf(fname, len, "%s/%s", path, dp->d_name);
+
+ /* stat the file */
+ if (lstat(fname, &sb) != -1) {
+ if (S_ISDIR(sb.st_mode) && !S_ISLNK(sb.st_mode)) {
+ if (rmdir(fname) < 0) { /* can't be deleted */
+ if (errno == EACCES) {
+ closedir(d);
+ SAFE_FREE(fname);
+ return -1;
+ }
+ p_rmdirs(fname);
+ }
+ } else {
+ unlink(fname);
+ }
+ } /* lstat */
+ SAFE_FREE(fname);
+ } /* readdir */
+
+ rewinddir(d);
+ }
+ } else {
+ return -1;
+ }
+
+ closedir(d);
+ return 0;
+}
+
/*
* This function is called when the library is unloaded and makes sure that
* resources are freed.
*/
void pwrap_destructor(void)
{
+ const char *env;
+
if (pwrap.libpam.handle != NULL) {
dlclose(pwrap.libpam.handle);
}
+
+ env = getenv("PAM_WRAPPER_KEEP_DIR");
+ if (env == NULL || env[0] != '1') {
+ p_rmdirs(pwrap.config_dir);
+ }
}