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:
parent
79f8481889
commit
3c4fed097d
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue