nmh-workers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Nmh-workers] Re: Diffs for replacing mktemp() usage


From: Earl Hood
Subject: [Nmh-workers] Re: Diffs for replacing mktemp() usage
Date: Tue, 02 Feb 2010 23:43:04 -0600

Even though no one has convinced me that my new functions
still contain the race condition security problem,
I've updated the new functions to default to using the
user's mail directory for creating temp file if no
template is provided.

New version of m_mktemp.c is attached.  None of the
changes I have done have yet to be committed into
CVS.

/*
 * m_mktemp.c -- Construct a temporary file.
 *
 * $Id: m_mktemp.c,v 1.4 2002/07/02 22:09:14 kenh Exp $
 *
 * This code is Copyright (c) 2010, by the authors of nmh.  See the
 * COPYRIGHT file in the root directory of the nmh distribution for
 * complete copyright information.
 */

#include <errno.h>
#include <h/mh.h>


char *
m_mktemp (
    const char *pfx_in,   /* Pathname prefix for temporary file. */
    int *fd_ret,          /* (return,optional) File descriptor to temp file. */
    FILE **fp_ret         /* (return,optional) FILE pointer to temp file. */
)
{
    static char tmpfil[BUFSIZ];
    int fd = -1;
    int keep_open = 0;

    if (pfx_in == NULL) {
        snprintf(tmpfil, sizeof(tmpfil), "%s/nmhXXXXXX", m_maildir(""));
    } else {
        snprintf(tmpfil, sizeof(tmpfil), "%sXXXXXX", pfx_in);
    }

    fd = mkstemp(tmpfil);
    if (fd < 0) {
        return NULL;
    }
    if (fd_ret != NULL) {
        *fd_ret = fd;
        keep_open = 1;
    }
    if (fp_ret != NULL) {
        FILE *fp = fdopen(fd, "w+");
        if (fp == NULL) {
            int olderr = errno;
            unlink(tmpfil);
            close(fd);
            errno = olderr;
            return NULL;
        }
        *fp_ret = fp;
        keep_open = 1;
    }
    if (!keep_open) {
        close(fd);
    }
    return tmpfil;
}

/* This version allows one to specify the directory the temp file should
 * by created based on a given pathname.  Although m_mktemp() technically
 * support this, this version is when the directory is defined by
 * a separate variable from the prefix, eliminating the caller from have to do
 * string manipulation to generate the desired. pathname prefix.
 *
 * The pfx_in parameter specifies a basename prefix for the file.  If dir_in
 * is NULL, then the user's mail directory will be used for containing
 * the temporary file.
 */
char *
m_mktemp2 (
    const char *dir_in,   /* Directory to place temp file. */
    const char *pfx_in,   /* Basename prefix for temp file. */
    int *fd_ret,          /* (return,optional) File descriptor to temp file. */
    FILE **fp_ret         /* (return,optional) FILE pointer to temp file. */
)
{
    static char buffer[BUFSIZ];
    char *cp;

    if (dir_in == NULL) {
        if (pfx_in == NULL) {
            return m_mktemp(NULL, fd_ret, fp_ret);
        }
        snprintf(buffer, sizeof(buffer), "%s/%s", m_maildir(""), pfx_in);
        return m_mktemp(buffer, fd_ret, fp_ret);
    }

    if ((cp = r1bindex ((char *)dir_in, '/')) == dir_in) {
        /* No directory component */
        return m_mktemp(pfx_in, fd_ret, fp_ret);
    }
    int n = (int)(cp-dir_in-1); /* Length of dir component */
    snprintf(buffer, sizeof(buffer), "%.*s%s", n, dir_in, pfx_in);
    return m_mktemp(buffer, fd_ret, fp_ret);
}


reply via email to

[Prev in Thread] Current Thread [Next in Thread]