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>
#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;
}
/* 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);
{
FILE *f;
char *tmpname;
- f = xfmkstemp(&tmpname);
+ f = xfmkstemp(&tmpname, NULL);
unlink(tmpname);
free(tmpname);
fclose(f);
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 */
{
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"));
}
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);