summaryrefslogtreecommitdiffstats
path: root/contrib/opie/libopie/lock.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/opie/libopie/lock.c')
-rw-r--r--contrib/opie/libopie/lock.c87
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++;
OpenPOWER on IntegriCloud