* NEWS, lib/commonio.h, lib/commonio.c: Additional messages to
indicate why locking failed. * NEWS, lib/commonio.c: Fix the sort algorithm in case of NIS. NIS entries were dropped. * lib/commonio.c: NIS entries can start by '+' or '-'.
This commit is contained in:
parent
a7fee9db00
commit
39cecdab06
@ -1,3 +1,11 @@
|
|||||||
|
2011-07-14 Nicolas François <nicolas.francois@centraliens.net>
|
||||||
|
|
||||||
|
* NEWS, lib/commonio.h, lib/commonio.c: Additional messages to
|
||||||
|
indicate why locking failed.
|
||||||
|
* NEWS, lib/commonio.c: Fix the sort algorithm in case of NIS. NIS
|
||||||
|
entries were dropped.
|
||||||
|
* lib/commonio.c: NIS entries can start by '+' or '-'.
|
||||||
|
|
||||||
2011-07-14 Nicolas François <nicolas.francois@centraliens.net>
|
2011-07-14 Nicolas François <nicolas.francois@centraliens.net>
|
||||||
|
|
||||||
* NEWS, src/groupmod.c: When the gshadow file exists but there are
|
* NEWS, src/groupmod.c: When the gshadow file exists but there are
|
||||||
|
5
NEWS
5
NEWS
@ -14,6 +14,7 @@ shadow-4.1.4.3 -> shadow-4.1.5 UNRELEASED
|
|||||||
* Added support for ACLs and Extended Attributes in useradd and usermod.
|
* Added support for ACLs and Extended Attributes in useradd and usermod.
|
||||||
Support shall be enabled with the new --with-acl or --with-attr
|
Support shall be enabled with the new --with-acl or --with-attr
|
||||||
configure options.
|
configure options.
|
||||||
|
* Added diagnosis for lock failures.
|
||||||
|
|
||||||
-chpasswd
|
-chpasswd
|
||||||
* PAM enabled versions: restore the -e option to allow restoring
|
* PAM enabled versions: restore the -e option to allow restoring
|
||||||
@ -28,6 +29,8 @@ shadow-4.1.4.3 -> shadow-4.1.5 UNRELEASED
|
|||||||
* When the gshadow file exists but there are no gshadow entries, an entry
|
* When the gshadow file exists but there are no gshadow entries, an entry
|
||||||
is created if the password is changed and group requires a
|
is created if the password is changed and group requires a
|
||||||
shadow entry.
|
shadow entry.
|
||||||
|
- grpck
|
||||||
|
* NIS entries were dropped by -s (sort).
|
||||||
-login
|
-login
|
||||||
* Fixed limits support (non PAM enabled versions only)
|
* Fixed limits support (non PAM enabled versions only)
|
||||||
* Added support for infinite limits and group based limits (non PAM
|
* Added support for infinite limits and group based limits (non PAM
|
||||||
@ -54,6 +57,8 @@ shadow-4.1.4.3 -> shadow-4.1.5 UNRELEASED
|
|||||||
* Added support for PAM modules which change PAM_USER.
|
* Added support for PAM modules which change PAM_USER.
|
||||||
- newgrp, sg, groupmems
|
- newgrp, sg, groupmems
|
||||||
* Fix parsing of gshadow entries.
|
* Fix parsing of gshadow entries.
|
||||||
|
- pwpck
|
||||||
|
* NIS entries were dropped by -s (sort).
|
||||||
- useradd
|
- useradd
|
||||||
* If the skeleton directory contained hardlinked files, copies of the
|
* If the skeleton directory contained hardlinked files, copies of the
|
||||||
hardlink were removed from the skeleton directory.
|
hardlink were removed from the skeleton directory.
|
||||||
|
@ -57,7 +57,7 @@
|
|||||||
/* local function prototypes */
|
/* local function prototypes */
|
||||||
static int lrename (const char *, const char *);
|
static int lrename (const char *, const char *);
|
||||||
static int check_link_count (const char *file);
|
static int check_link_count (const char *file);
|
||||||
static int do_lock_file (const char *file, const char *lock);
|
static int do_lock_file (const char *file, const char *lock, bool log);
|
||||||
static /*@null@*/ /*@dependent@*/FILE *fopen_set_perms (
|
static /*@null@*/ /*@dependent@*/FILE *fopen_set_perms (
|
||||||
const char *name,
|
const char *name,
|
||||||
const char *mode,
|
const char *mode,
|
||||||
@ -135,7 +135,7 @@ static int check_link_count (const char *file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int do_lock_file (const char *file, const char *lock)
|
static int do_lock_file (const char *file, const char *lock, bool log)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
@ -145,6 +145,11 @@ static int do_lock_file (const char *file, const char *lock)
|
|||||||
|
|
||||||
fd = open (file, O_CREAT | O_EXCL | O_WRONLY, 0600);
|
fd = open (file, O_CREAT | O_EXCL | O_WRONLY, 0600);
|
||||||
if (-1 == fd) {
|
if (-1 == fd) {
|
||||||
|
if (log) {
|
||||||
|
(void) fprintf (stderr,
|
||||||
|
"%s: %s: %s\n",
|
||||||
|
Prog, file, strerror (errno));
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,6 +157,11 @@ static int do_lock_file (const char *file, const char *lock)
|
|||||||
snprintf (buf, sizeof buf, "%lu", (unsigned long) pid);
|
snprintf (buf, sizeof buf, "%lu", (unsigned long) pid);
|
||||||
len = (ssize_t) strlen (buf) + 1;
|
len = (ssize_t) strlen (buf) + 1;
|
||||||
if (write (fd, buf, (size_t) len) != len) {
|
if (write (fd, buf, (size_t) len) != len) {
|
||||||
|
if (log) {
|
||||||
|
(void) fprintf (stderr,
|
||||||
|
"%s: %s: %s\n",
|
||||||
|
Prog, file, strerror (errno));
|
||||||
|
}
|
||||||
(void) close (fd);
|
(void) close (fd);
|
||||||
unlink (file);
|
unlink (file);
|
||||||
return 0;
|
return 0;
|
||||||
@ -160,12 +170,22 @@ static int do_lock_file (const char *file, const char *lock)
|
|||||||
|
|
||||||
if (link (file, lock) == 0) {
|
if (link (file, lock) == 0) {
|
||||||
retval = check_link_count (file);
|
retval = check_link_count (file);
|
||||||
|
if ((0==retval) && log) {
|
||||||
|
(void) fprintf (stderr,
|
||||||
|
"%s: %s: lock file already used\n",
|
||||||
|
Prog, file);
|
||||||
|
}
|
||||||
unlink (file);
|
unlink (file);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = open (lock, O_RDWR);
|
fd = open (lock, O_RDWR);
|
||||||
if (-1 == fd) {
|
if (-1 == fd) {
|
||||||
|
if (log) {
|
||||||
|
(void) fprintf (stderr,
|
||||||
|
"%s: %s: %s\n",
|
||||||
|
Prog, lock, strerror (errno));
|
||||||
|
}
|
||||||
unlink (file);
|
unlink (file);
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return 0;
|
return 0;
|
||||||
@ -173,29 +193,60 @@ static int do_lock_file (const char *file, const char *lock)
|
|||||||
len = read (fd, buf, sizeof (buf) - 1);
|
len = read (fd, buf, sizeof (buf) - 1);
|
||||||
close (fd);
|
close (fd);
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
|
if (log) {
|
||||||
|
(void) fprintf (stderr,
|
||||||
|
"%s: existing lock file %s without a PID\n",
|
||||||
|
Prog, lock);
|
||||||
|
}
|
||||||
unlink (file);
|
unlink (file);
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
if (get_pid (buf, &pid) == 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);
|
unlink (file);
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (kill (pid, 0) == 0) {
|
if (kill (pid, 0) == 0) {
|
||||||
|
if (log) {
|
||||||
|
(void) fprintf (stderr,
|
||||||
|
"%s: lock %s already used by PID %d\n",
|
||||||
|
Prog, lock, pid);
|
||||||
|
}
|
||||||
unlink (file);
|
unlink (file);
|
||||||
errno = EEXIST;
|
errno = EEXIST;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (unlink (lock) != 0) {
|
if (unlink (lock) != 0) {
|
||||||
|
if (log) {
|
||||||
|
(void) fprintf (stderr,
|
||||||
|
"%s: cannot get lock %s: %s\n",
|
||||||
|
Prog, lock, strerror (errno));
|
||||||
|
}
|
||||||
unlink (file);
|
unlink (file);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
if ((link (file, lock) == 0) && (check_link_count (file) != 0)) {
|
if (link (file, lock) == 0) {
|
||||||
retval = 1;
|
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);
|
unlink (file);
|
||||||
@ -328,7 +379,7 @@ bool commonio_present (const struct commonio_db *db)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int commonio_lock_nowait (struct commonio_db *db)
|
int commonio_lock_nowait (struct commonio_db *db, bool log)
|
||||||
{
|
{
|
||||||
char file[1024];
|
char file[1024];
|
||||||
char lock[1024];
|
char lock[1024];
|
||||||
@ -340,7 +391,7 @@ int commonio_lock_nowait (struct commonio_db *db)
|
|||||||
snprintf (file, sizeof file, "%s.%lu",
|
snprintf (file, sizeof file, "%s.%lu",
|
||||||
db->filename, (unsigned long) getpid ());
|
db->filename, (unsigned long) getpid ());
|
||||||
snprintf (lock, sizeof lock, "%s.lock", db->filename);
|
snprintf (lock, sizeof lock, "%s.lock", db->filename);
|
||||||
if (do_lock_file (file, lock) != 0) {
|
if (do_lock_file (file, lock, log) != 0) {
|
||||||
db->locked = true;
|
db->locked = true;
|
||||||
lock_count++;
|
lock_count++;
|
||||||
return 1;
|
return 1;
|
||||||
@ -364,11 +415,16 @@ int commonio_lock (struct commonio_db *db)
|
|||||||
*/
|
*/
|
||||||
if (0 == lock_count) {
|
if (0 == lock_count) {
|
||||||
if (lckpwdf () == -1) {
|
if (lckpwdf () == -1) {
|
||||||
|
if (geteuid () != 0) {
|
||||||
|
(void) fprintf (stderr,
|
||||||
|
"%s: Permission denied.\n",
|
||||||
|
Prog);
|
||||||
|
}
|
||||||
return 0; /* failure */
|
return 0; /* failure */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commonio_lock_nowait (db) != 0) {
|
if (commonio_lock_nowait (db, true) != 0) {
|
||||||
return 1; /* success */
|
return 1; /* success */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,11 +447,13 @@ int commonio_lock (struct commonio_db *db)
|
|||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
sleep (LOCK_SLEEP); /* delay between retries */
|
sleep (LOCK_SLEEP); /* delay between retries */
|
||||||
}
|
}
|
||||||
if (commonio_lock_nowait (db) != 0) {
|
if (commonio_lock_nowait (db, i==LOCK_TRIES-1) != 0) {
|
||||||
return 1; /* success */
|
return 1; /* success */
|
||||||
}
|
}
|
||||||
/* no unnecessary retries on "permission denied" errors */
|
/* no unnecessary retries on "permission denied" errors */
|
||||||
if (geteuid () != 0) {
|
if (geteuid () != 0) {
|
||||||
|
(void) fprintf (stderr, "%s: Permission denied.\n",
|
||||||
|
Prog);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -714,7 +772,8 @@ commonio_sort (struct commonio_db *db, int (*cmp) (const void *, const void *))
|
|||||||
(NULL != ptr)
|
(NULL != ptr)
|
||||||
#if KEEP_NIS_AT_END
|
#if KEEP_NIS_AT_END
|
||||||
&& (NULL != ptr->line)
|
&& (NULL != ptr->line)
|
||||||
&& ('+' != ptr->line[0])
|
&& ( ('+' != ptr->line[0])
|
||||||
|
|| ('-' != ptr->line[0]))
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
ptr = ptr->next) {
|
ptr = ptr->next) {
|
||||||
@ -763,7 +822,11 @@ commonio_sort (struct commonio_db *db, int (*cmp) (const void *, const void *))
|
|||||||
db->head->prev = NULL;
|
db->head->prev = NULL;
|
||||||
db->head->next = entries[1];
|
db->head->next = entries[1];
|
||||||
entries[n]->prev = entries[n - 1];
|
entries[n]->prev = entries[n - 1];
|
||||||
|
#if KEEP_NIS_AT_END
|
||||||
|
entries[n]->next = nis;
|
||||||
|
#else
|
||||||
entries[n]->next = NULL;
|
entries[n]->next = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Now other elements have prev and next entries */
|
/* Now other elements have prev and next entries */
|
||||||
for (i = 1; i < n; i++) {
|
for (i = 1; i < n; i++) {
|
||||||
|
@ -141,7 +141,7 @@ struct commonio_db {
|
|||||||
extern int commonio_setname (struct commonio_db *, const char *);
|
extern int commonio_setname (struct commonio_db *, const char *);
|
||||||
extern bool commonio_present (const struct commonio_db *db);
|
extern bool commonio_present (const struct commonio_db *db);
|
||||||
extern int commonio_lock (struct commonio_db *);
|
extern int commonio_lock (struct commonio_db *);
|
||||||
extern int commonio_lock_nowait (struct commonio_db *);
|
extern int commonio_lock_nowait (struct commonio_db *, bool log);
|
||||||
extern int commonio_open (struct commonio_db *, int);
|
extern int commonio_open (struct commonio_db *, int);
|
||||||
extern /*@observer@*/ /*@null@*/const void *commonio_locate (struct commonio_db *, const char *);
|
extern /*@observer@*/ /*@null@*/const void *commonio_locate (struct commonio_db *, const char *);
|
||||||
extern int commonio_update (struct commonio_db *, const void *);
|
extern int commonio_update (struct commonio_db *, const void *);
|
||||||
|
Loading…
Reference in New Issue
Block a user