summaryrefslogtreecommitdiff
path: root/lib/acl_files.c
diff options
context:
space:
mode:
authorGravatar John Kohl <jtkohl@mit.edu>1989-12-13 06:17:56 +0000
committerGravatar John Kohl <jtkohl@mit.edu>1989-12-13 06:17:56 +0000
commit2e5f8418a3c206f84f778dded4c77012e3c4002b (patch)
treedb2c1576bf631c7dd35c2fa24970cac0bd5087aa /lib/acl_files.c
parent27f155d473a80fcf67a1496fac73fd3d118bf7f5 (diff)
merge in fixes from Athena sources:
Use stat() not fstat() as the acl file may have been re-created by an acl_add or acl_delete call. If this happens, we are now referencing the wrong inode. [rfrench] Fixes from tjcoppet: When an acl file does not exist, and the cache is full, the load_acl() proc does not zero the hash table pointer. This causes certain olc servers to die unexpectedly. File descriptor leak fixed in acl_load().
Diffstat (limited to 'lib/acl_files.c')
-rw-r--r--lib/acl_files.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/lib/acl_files.c b/lib/acl_files.c
index 05fe595..262ecfb 100644
--- a/lib/acl_files.c
+++ b/lib/acl_files.c
@@ -14,7 +14,7 @@
#include <zephyr/mit-copyright.h>
#ifndef lint
-static char rcsid_acl_files_c[] = "$Header$";
+static char rcsid_acl_files_c[] = "$Id$";
#endif lint
/*** Routines for manipulating access control list files ***/
@@ -389,7 +389,10 @@ char *name;
i = acl_cache_next;
acl_cache_next = (acl_cache_next + 1) % CACHED_ACLS;
close(acl_cache[i].fd);
- if(acl_cache[i].acl) destroy_hash(acl_cache[i].acl);
+ if(acl_cache[i].acl) {
+ destroy_hash(acl_cache[i].acl);
+ acl_cache[i].acl = (struct hashtbl *) 0;
+ }
}
/* Set up the acl */
@@ -399,8 +402,14 @@ char *name;
acl_cache[i].acl = (struct hashtbl *) 0;
got_it:
- /* See if the stat matches */
- if(fstat(acl_cache[i].fd, &s) < 0) return(-1);
+ /*
+ * See if the stat matches
+ *
+ * Use stat(), not fstat(), as the file may have been re-created by
+ * acl_add or acl_delete. If this happens, the old inode will have
+ * no changes in the mod-time and the following test will fail.
+ */
+ if(stat(acl_cache[i].filename, &s) < 0) return(-1);
if(acl_cache[i].acl == (struct hashtbl *) 0
|| s.st_nlink != acl_cache[i].status.st_nlink
|| s.st_mtime != acl_cache[i].status.st_mtime
@@ -416,6 +425,7 @@ char *name;
acl_canonicalize_principal(buf, canon);
add_hash(acl_cache[i].acl, canon);
}
+ fclose(f);
acl_cache[i].status = s;
}
return(i);