public inbox for util-linux@vger.kernel.org
 help / color / mirror / Atom feed
From: Sami Kerola <kerolasa@iki.fi>
To: util-linux@vger.kernel.org
Cc: kerolasa@iki.fi
Subject: [PATCH 11/17] setpwnam: use xmkstemp() and lckpwdf()
Date: Mon,  5 Mar 2012 20:38:48 +0100	[thread overview]
Message-ID: <1330976334-10751-12-git-send-email-kerolasa@iki.fi> (raw)
In-Reply-To: <1330976334-10751-1-git-send-email-kerolasa@iki.fi>

Get rid private locking schema and use libc instead.

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
 login-utils/Makefile.am |    3 ++-
 login-utils/setpwnam.c  |   52 ++++++++++++++++-------------------------------
 2 files changed, 20 insertions(+), 35 deletions(-)

diff --git a/login-utils/Makefile.am b/login-utils/Makefile.am
index 47274bf..7bd2ddb 100644
--- a/login-utils/Makefile.am
+++ b/login-utils/Makefile.am
@@ -42,7 +42,8 @@ chfn_chsh_common = \
 	islocal.h \
 	setpwnam.c \
 	setpwnam.h \
-	$(top_srcdir)/lib/env.c
+	$(top_srcdir)/lib/env.c \
+	$(top_srcdir)/lib/fileutils.c
 login_SOURCES = \
 	login.c \
 	logindefs.c \
diff --git a/login-utils/setpwnam.c b/login-utils/setpwnam.c
index 0e0c047..97fd822 100644
--- a/login-utils/setpwnam.c
+++ b/login-utils/setpwnam.c
@@ -47,6 +47,7 @@
 #include <fcntl.h>
 #include <paths.h>
 #include <pwd.h>
+#include <shadow.h>
 #include <signal.h>
 #include <stdbool.h>
 #include <stdio.h>
@@ -58,6 +59,7 @@
 #include <unistd.h>
 
 #include "c.h"
+#include "fileutils.h"
 #include "setpwnam.h"
 
 static void pw_init(void);
@@ -71,47 +73,26 @@ static void pw_init(void);
 int setpwnam(struct passwd *pwd)
 {
 	FILE *fp = NULL, *pwf = NULL;
-	int x, save_errno, fd, ret;
+	int save_errno;
 	int found;
-	int oldumask;
 	int namelen;
 	int buflen = 256;
 	int contlen, rc;
 	char *linebuf = NULL;
-
-	oldumask = umask(0);	/* Create with exact permissions */
+	char *tmpname = NULL;
 
 	pw_init();
 
-	/* sanity check */
-	for (x = 0; x < 3; x++) {
-		if (x > 0)
-			sleep(1);
-		fd = open(PTMPTMP_FILE, O_WRONLY | O_CREAT | O_EXCL, 0644);
-		if (fd == -1) {
-			umask(oldumask);
-			return -1;
-		}
-		ret = link(PTMPTMP_FILE, PTMP_FILE);
-		unlink(PTMPTMP_FILE);
-		if (ret == -1)
-			close(fd);
-		else
-			break;
-	}
-	umask(oldumask);
-	if (ret == -1)
+	if ((fp = xmkstemp(&tmpname)) == NULL)
 		return -1;
 
 	/* ptmp should be owned by root.root or root.wheel */
-	if (chown(PTMP_FILE, (uid_t) 0, (gid_t) 0) < 0)
-		return -1;
-
-	/* open ptmp for writing and passwd for reading */
-	fp = fdopen(fd, "w");
-	if (!fp)
+	if (fchown(fileno(fp), (uid_t) 0, (gid_t) 0) < 0)
 		goto fail;
 
+	/* acquire exclusive lock */
+	if (lckpwdf() < 0)
+		goto fail;
 	pwf = fopen(PASSWD_FILE, "r");
 	if (!pwf)
 		goto fail;
@@ -164,8 +145,6 @@ int setpwnam(struct passwd *pwd)
 	if (rc < 0)
 		goto fail;
 
-	close(fd);
-	fd = -1;
 	fclose(pwf);	/* I don't think I want to know if this failed */
 	pwf = NULL;
 
@@ -178,22 +157,27 @@ int setpwnam(struct passwd *pwd)
 	unlink(PASSWD_FILE ".OLD");
 	/* we don't care if we can't create the backup file */
 	ignore_result(link(PASSWD_FILE, PASSWD_FILE ".OLD"));
+	/* xmkstemp is too restrictive by default for passwd file */
+	if (fchmod(fileno(fp), 0644) < 0)
+		goto fail;
 	/* we DO care if we can't rename to the passwd file */
-	if (rename(PTMP_FILE, PASSWD_FILE) < 0)
+	if (rename(tmpname, PASSWD_FILE) < 0)
 		goto fail;
 	/* finally:  success */
+	ulckpwdf();
 	return 0;
 
  fail:
 	save_errno = errno;
+	ulckpwdf();
 	if (fp != NULL)
 		fclose(fp);
+	if (tmpname != NULL)
+		unlink(tmpname);
+	free(tmpname);
 	if (pwf != NULL)
 		fclose(pwf);
-	if (fd >= 0)
-		close(fd);
 	free(linebuf);
-	unlink(PTMP_FILE);
 	errno = save_errno;
 	return -1;
 }
-- 
1.7.9.2


  parent reply	other threads:[~2012-03-05 19:39 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-04 13:35 [pull] fixes to todo items etc Sami Kerola
2012-03-05 12:38 ` Karel Zak
2012-03-05 19:38   ` Sami Kerola
2012-03-05 19:38     ` [PATCH 01/17] docs: add deprecation comments Sami Kerola
2012-03-05 19:38     ` [PATCH 02/17] docs: TODO removal, login-utils error printing Sami Kerola
2012-03-05 19:38     ` [PATCH 03/17] sfdisk: use rpmatch to yes/no question Sami Kerola
2012-03-05 19:38     ` [PATCH 04/17] mesg: " Sami Kerola
2012-03-05 19:38     ` [PATCH 05/17] vipw: " Sami Kerola
2012-03-05 19:38     ` [PATCH 06/17] docs: TODO removal, rpmatch task is done Sami Kerola
2012-03-05 19:38     ` [PATCH 07/17] chfn: use pathnames.h for paths Sami Kerola
2012-03-05 19:38     ` [PATCH 08/17] chsh: " Sami Kerola
2012-03-05 19:38     ` [PATCH 09/17] lib: add fileutils function collection Sami Kerola
     [not found]       ` <"1330984305.2953.25.camel"@offbook>
     [not found]       ` <"1 330984305.2953.25.camel"@offbook>
2012-03-05 21:51       ` Davidlohr Bueso
2012-03-09  7:56         ` Sami Kerola
2012-03-09 11:48           ` Davidlohr Bueso
2012-03-09 12:20             ` Karel Zak
2012-03-10 11:49               ` Sami Kerola
2012-03-05 19:38     ` [PATCH 10/17] wall: use xmkstemp for temporary file Sami Kerola
2012-03-05 19:38     ` Sami Kerola [this message]
2012-03-05 19:38     ` [PATCH 12/17] vipw: use xmkstemp() and lckpwdf() Sami Kerola
2012-03-05 19:38     ` [PATCH 13/17] pathnames: clean up various user database paths Sami Kerola
2012-03-05 20:44       ` Sami Kerola
2012-03-05 19:38     ` [PATCH 14/17] docs: TODO removal, ldattach usage is done Sami Kerola
2012-03-05 19:38     ` [PATCH 15/17] include: add asprintf wrapper Sami Kerola
2012-03-05 19:52       ` Dave Reisner
2012-03-05 20:47         ` Sami Kerola
2012-03-05 19:38     ` [PATCH 16/17] xalloc: use xasprintf in all files Sami Kerola
2012-03-05 19:38     ` [PATCH 17/17] build-sys: fix chkdupexe regression Sami Kerola
2012-03-20  8:07 ` [pull] fixes to todo items etc Karel Zak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1330976334-10751-12-git-send-email-kerolasa@iki.fi \
    --to=kerolasa@iki.fi \
    --cc=util-linux@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox