diff options
Diffstat (limited to 'contrib/opie/libopie/lock.c')
-rw-r--r-- | contrib/opie/libopie/lock.c | 87 |
1 files changed, 78 insertions, 9 deletions
diff --git a/contrib/opie/libopie/lock.c b/contrib/opie/libopie/lock.c index d6ea56e..40999de 100644 --- a/contrib/opie/libopie/lock.c +++ b/contrib/opie/libopie/lock.c @@ -1,7 +1,7 @@ /* lock.c: The opielock() library function. -%%% portions-copyright-cmetz -Portions of this software are Copyright 1996 by Craig Metz, All Rights +%%% portions-copyright-cmetz-96 +Portions of this software are Copyright 1996-1997 by Craig Metz, All Rights Reserved. The Inner Net License Version 2 applies to these portions of the software. You should have received a copy of the license with this software. If @@ -14,6 +14,8 @@ License Agreement applies to this software. History: + Modified by cmetz for OPIE 2.31. Put locks in a separate dir. + Bug fixes. Modified by cmetz for OPIE 2.3. Do refcounts whether or not we actually lock. Fixed USER_LOCKING=0 case. Modified by cmetz for OPIE 2.22. Added reference count for locks. @@ -33,12 +35,19 @@ License Agreement applies to this software. #if HAVE_UNISTD_H #include <unistd.h> #endif /* HAVE_UNISTD_H */ +#include <sys/stat.h> +#include <syslog.h> #include <fcntl.h> #if HAVE_STDLIB_H #include <stdlib.h> #endif /* HAVE_STDLIB_H */ +#include <errno.h> #include "opie.h" +#if !HAVE_LSTAT +#define lstat(x, y) stat(x, y) +#endif /* !HAVE_LSTAT */ + int __opie_lockrefcount = 0; #if USER_LOCKING @@ -75,22 +84,70 @@ int opielock FUNCTION((principal), char *principal) #if USER_LOCKING int fh, waits = 0, rval = -1, pid, t, i; char buffer[128], buffer2[128], *c, *c2; + struct stat statbuf[2]; + + if (getuid() && geteuid()) { +#if DEBUG + syslog(LOG_DEBUG, "opielock: requires superuser priveleges"); +#endif /* DEBUG */ + return -1; + }; if (__opie_lockfilename) { __opie_lockrefcount++; return 0; } - if (!(__opie_lockfilename = (char *)malloc(sizeof(OPIE_LOCK_PREFIX) + strlen(principal)))) + if (!(__opie_lockfilename = (char *)malloc(sizeof(OPIE_LOCK_DIR) + 1 + strlen(principal)))) + return -1; + + strcpy(__opie_lockfilename, OPIE_LOCK_DIR); + + if (mkdir(__opie_lockfilename, 0700) < 0) + if (errno != EEXIST) + return -1; + + if (lstat(__opie_lockfilename, &statbuf[0]) < 0) + return -1; + + if (statbuf[0].st_uid) { +#if DEBUG + syslog(LOG_DEBUG, "opielock: %s isn't owned by the superuser.", __opie_lockfilename); +#endif /* DEBUG */ + return -1; + }; + + if (!S_ISDIR(statbuf[0].st_mode)) { +#if DEBUG + syslog(LOG_DEBUG, "opielock: %s isn't a directory.", __opie_lockfilename); +#endif /* DEBUG */ + return -1; + }; + + if ((statbuf[0].st_mode & 0777) != 00700) { +#if DEBUG + syslog(LOG_DEBUG, "opielock: permissions on %s are not correct.", __opie_lockfilename); +#endif /* DEBUG */ return -1; + }; - strcpy(__opie_lockfilename, OPIE_LOCK_PREFIX); + strcat(__opie_lockfilename, "/"); strcat(__opie_lockfilename, principal); - fh = 0; - while (!fh) + fh = -1; + while (fh < 0) { + if (!lstat(__opie_lockfilename, &statbuf[0])) + if (!S_ISREG(statbuf[0].st_mode)) + goto lockret; + if ((fh = open(__opie_lockfilename, O_WRONLY | O_CREAT | O_EXCL, 0600)) < 0) { - if ((fh = open(__opie_lockfilename, O_RDWR, 0600)) < 0) + if (lstat(__opie_lockfilename, &statbuf[1]) < 0) + goto lockret; + if (statbuf[0].st_ino != statbuf[1].st_ino) + goto lockret; + if (statbuf[0].st_mode != statbuf[1].st_mode) + goto lockret; + if ((fh = open(__opie_lockfilename, O_RDONLY, 0600)) < 0) goto lockret; if ((i = read(fh, buffer, sizeof(buffer))) <= 0) goto lockret; @@ -114,7 +171,7 @@ int opielock FUNCTION((principal), char *principal) if (!(t = atoi(c))) break; - if ((time(0) + OPIE_LOCK_TIMEOUT) < t) + if ((t + OPIE_LOCK_TIMEOUT) < time(0)) break; if (kill(pid, 0)) @@ -128,6 +185,14 @@ int opielock FUNCTION((principal), char *principal) goto lockret; }; }; + }; + + if (lstat(__opie_lockfilename, &statbuf[0]) < 0) + goto lockret; + if (fstat(fh, &statbuf[1]) < 0) + goto lockret; + if (!S_ISREG(statbuf[0].st_mode) || (statbuf[0].st_mode != statbuf[1].st_mode) || (statbuf[0].st_ino != statbuf[1].st_ino)) + goto lockret; sprintf(buffer, "%d\n%d\n", getpid(), time(0)); i = strlen(buffer) + 1; @@ -165,8 +230,12 @@ int opielock FUNCTION((principal), char *principal) atexit(opieunlockaeh); lockret: - if (fh) + if (fh >= 0) close(fh); + if (!__opie_lockrefcount) { + free (__opie_lockfilename); + __opie_lockfilename = NULL; + }; return rval; #else /* USER_LOCKING */ __opie_lockrefcount++; |