File shadow-4.8.1-lock-mechanism.patch of Package shadow.29816

Based on:
https://github.com/shadow-maint/shadow/commit/65470e5c7ddbc2885ad35fbd0218b91a75626c2f
Index: shadow-4.8.1/lib/commonio.c
===================================================================
--- shadow-4.8.1.orig/lib/commonio.c
+++ shadow-4.8.1/lib/commonio.c
@@ -54,8 +54,6 @@
 
 /* local function prototypes */
 static int lrename (const char *, const char *);
-static int check_link_count (const char *file);
-static int do_lock_file (const char *file, const char *lock, bool log);
 static /*@null@*/ /*@dependent@*/FILE *fopen_set_perms (
 	const char *name,
 	const char *mode,
@@ -117,140 +115,6 @@ int lrename (const char *old, const char
 	return res;
 }
 
-static int check_link_count (const char *file)
-{
-	struct stat sb;
-
-	if (stat (file, &sb) != 0) {
-		return 0;
-	}
-
-	if (sb.st_nlink != 2) {
-		return 0;
-	}
-
-	return 1;
-}
-
-
-static int do_lock_file (const char *file, const char *lock, bool log)
-{
-	int fd;
-	pid_t pid;
-	ssize_t len;
-	int retval;
-	char buf[32];
-
-	fd = open (file, O_CREAT | O_TRUNC | O_WRONLY, 0600);
-	if (-1 == fd) {
-		if (log) {
-			(void) fprintf (stderr,
-			                "%s: %s: %s\n",
-			                Prog, file, strerror (errno));
-		}
-		return 0;
-	}
-
-	pid = getpid ();
-	snprintf (buf, sizeof buf, "%lu", (unsigned long) pid);
-	len = (ssize_t) strlen (buf) + 1;
-	if (write (fd, buf, (size_t) len) != len) {
-		if (log) {
-			(void) fprintf (stderr,
-			                "%s: %s: %s\n",
-			                Prog, file, strerror (errno));
-		}
-		(void) close (fd);
-		unlink (file);
-		return 0;
-	}
-	close (fd);
-
-	if (link (file, lock) == 0) {
-		retval = check_link_count (file);
-		if ((0==retval) && log) {
-			(void) fprintf (stderr,
-			                "%s: %s: lock file already used\n",
-			                Prog, file);
-		}
-		unlink (file);
-		return retval;
-	}
-
-	fd = open (lock, O_RDWR);
-	if (-1 == fd) {
-		if (log) {
-			(void) fprintf (stderr,
-			                "%s: %s: %s\n",
-			                Prog, lock, strerror (errno));
-		}
-		unlink (file);
-		errno = EINVAL;
-		return 0;
-	}
-	len = read (fd, buf, sizeof (buf) - 1);
-	close (fd);
-	if (len <= 0) {
-		if (log) {
-			(void) fprintf (stderr,
-			                "%s: existing lock file %s without a PID\n",
-			                Prog, lock);
-		}
-		unlink (file);
-		errno = EINVAL;
-		return 0;
-	}
-	buf[len] = '\0';
-	if (get_pid (buf, &pid) == 0) {
-		if (log) {
-			(void) fprintf (stderr,
-			                "%s: existing lock file %s with an invalid PID '%s'\n",
-			                Prog, lock, buf);
-		}
-		unlink (file);
-		errno = EINVAL;
-		return 0;
-	}
-	if (kill (pid, 0) == 0) {
-		if (log) {
-			(void) fprintf (stderr,
-			                "%s: lock %s already used by PID %lu\n",
-			                Prog, lock, (unsigned long) pid);
-		}
-		unlink (file);
-		errno = EEXIST;
-		return 0;
-	}
-	if (unlink (lock) != 0) {
-		if (log) {
-			(void) fprintf (stderr,
-			                "%s: cannot get lock %s: %s\n",
-			                Prog, lock, strerror (errno));
-		}
-		unlink (file);
-		return 0;
-	}
-
-	retval = 0;
-	if (link (file, lock) == 0) {
-		retval = check_link_count (file);
-		if ((0==retval) && log) {
-			(void) fprintf (stderr,
-			                "%s: %s: lock file already used\n",
-			                Prog, file);
-		}
-	} else {
-		if (log) {
-			(void) fprintf (stderr,
-			                "%s: cannot get lock %s: %s\n",
-			                Prog, lock, strerror (errno));
-		}
-	}
-
-	unlink (file);
-	return retval;
-}
-
 
 static /*@null@*/ /*@dependent@*/FILE *fopen_set_perms (
 	const char *name,
@@ -374,6 +238,29 @@ bool commonio_present (const struct comm
 	return (access (db->filename, F_OK) == 0);
 }
 
+int do_fcntl_lock (const char *file, bool log, short type)
+{
+	int fd;
+	struct flock lck = {
+		.l_type = type,
+		.l_whence = SEEK_SET,
+		.l_start = 0,
+		.l_len = 0,
+	};
+
+	fd = open (file, O_WRONLY, 0600);
+	if (-1 == fd) {
+		if (log) {
+			(void) fprintf (stderr, "%s: %s: %s\n",
+					Prog, file, strerror (errno));
+		}
+		return 0;
+	}
+
+	fcntl (fd, F_OFD_SETLKW, &lck);
+	close(fd);
+	return(1);
+}
 
 int commonio_lock_nowait (struct commonio_db *db, bool log)
 {
@@ -398,8 +285,7 @@ int commonio_lock_nowait (struct commoni
 	}
 	snprintf (file, file_len, "%s.%lu",
 	          db->filename, (unsigned long) getpid ());
-	snprintf (lock, lock_file_len, "%s.lock", db->filename);
-	if (do_lock_file (file, lock, log) != 0) {
+	if (do_fcntl_lock (db->filename, log, F_WRLCK | F_RDLCK) != 0) {
 		db->locked = true;
 		lock_count++;
 		err = 1;
@@ -499,8 +385,6 @@ static void dec_lock_count (void)
 
 int commonio_unlock (struct commonio_db *db)
 {
-	char lock[1024];
-
 	if (db->isopen) {
 		db->readonly = true;
 		if (commonio_close (db) == 0) {
@@ -511,13 +395,8 @@ int commonio_unlock (struct commonio_db
 		}
 	}
 	if (db->locked) {
-		/*
-		 * Unlock in reverse order: remove the lock file,
-		 * then call ulckpwdf() (if used) on last unlock.
-		 */
 		db->locked = false;
-		snprintf (lock, sizeof lock, "%s.lock", db->filename);
-		unlink (lock);
+		do_fcntl_lock (db->filename, false, F_UNLCK);
 		dec_lock_count ();
 		return 1;
 	}
Index: shadow-4.8.1/lib/commonio.h
===================================================================
--- shadow-4.8.1.orig/lib/commonio.h
+++ shadow-4.8.1/lib/commonio.h
@@ -150,6 +150,7 @@ extern int commonio_setname (struct comm
 extern bool commonio_present (const struct commonio_db *db);
 extern int commonio_lock (struct commonio_db *);
 extern int commonio_lock_nowait (struct commonio_db *, bool log);
+extern int do_fcntl_lock (const char *file, bool log, short type);
 extern int commonio_open (struct commonio_db *, int);
 extern /*@observer@*/ /*@null@*/const void *commonio_locate (struct commonio_db *, const char *);
 extern int commonio_update (struct commonio_db *, const void *);
openSUSE Build Service is sponsored by