fileutils: xmkstemp() interface change

We can not let the user control where TMPDIR is for this tempfile.
This will be where we write the updated passwd file, and must be
capable of being moved atomically with rename(2).  Therefore, it
cannot be on a different device, or setpwnam() and vipw/vigr programs
will invariably fail with EXDEV.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
Dave Reisner 2012-06-02 19:31:30 +02:00 committed by Sami Kerola
parent 79f8481889
commit 3c4fed097d
5 changed files with 17 additions and 9 deletions

View File

@ -1,13 +1,13 @@
#ifndef UTIL_LINUX_FILEUTILS
#define UTIL_LINUX_FILEUTILS
extern int xmkstemp(char **tmpname);
extern int xmkstemp(char **tmpname, char *dir);
static inline FILE *xfmkstemp(char **tmpname)
static inline FILE *xfmkstemp(char **tmpname, char *dir)
{
int fd;
FILE *ret;
fd = xmkstemp(tmpname);
fd = xmkstemp(tmpname, dir);
if (fd == -1) {
return NULL;
}

View File

@ -16,14 +16,20 @@
/* Create open temporary file in safe way. Please notice that the
* file permissions are -rw------- by default. */
int xmkstemp(char **tmpname)
int xmkstemp(char **tmpname, char *dir)
{
char *localtmp;
char *tmpenv;
mode_t old_mode;
int fd;
tmpenv = getenv("TMPDIR");
/* Some use cases must be capable of being moved atomically
* with rename(2), which is the reason why dir is here. */
if (dir != NULL)
tmpenv = dir;
else
tmpenv = getenv("TMPDIR");
if (tmpenv)
xasprintf(&localtmp, "%s/%s.XXXXXX", tmpenv,
program_invocation_short_name);
@ -68,7 +74,7 @@ int main(void)
{
FILE *f;
char *tmpname;
f = xfmkstemp(&tmpname);
f = xfmkstemp(&tmpname, NULL);
unlink(tmpname);
free(tmpname);
fclose(f);

View File

@ -81,10 +81,11 @@ int setpwnam(struct passwd *pwd)
int contlen, rc;
char *linebuf = NULL;
char *tmpname = NULL;
char *atomic_dir = "/etc";
pw_init();
if ((fp = xfmkstemp(&tmpname)) == NULL)
if ((fp = xfmkstemp(&tmpname, atomic_dir)) == NULL)
return -1;
/* ptmp should be owned by root.root or root.wheel */

View File

@ -143,8 +143,9 @@ static FILE * pw_tmpfile(int lockfd)
{
FILE *fd;
char *tmpname = NULL;
char *dir = "/etc";
if ((fd = xfmkstemp(&tmpname)) == NULL) {
if ((fd = xfmkstemp(&tmpname, dir)) == NULL) {
ulckpwdf();
err(EXIT_FAILURE, _("can't open temporary file"));
}

View File

@ -190,7 +190,7 @@ makemsg(char *fname, size_t *mbufsize, int print_banner)
line_max = sysconf(_SC_LINE_MAX);
lbuf = xmalloc(line_max);
if ((fp = xfmkstemp(&tmpname)) == NULL)
if ((fp = xfmkstemp(&tmpname, NULL)) == NULL)
err(EXIT_FAILURE, _("can't open temporary file"));
unlink(tmpname);
free(tmpname);