CERT Advisory CA-95:02.binmail.vulnerabilities
============================================================================= CA-95:02 CERT Advisory January 26, 1995 Vulnerabilities in /bin/mail ----------------------------------------------------------------------------- This advisory supersedes CA-91:01a SunOS Mail Vulnerability and CA-91:13 Ultrix Mail Vulnerability. There are vulnerabilities in some versions of /bin/mail. Section III below provides vendor-specific information and an alternative to /bin/mail. As we receive additional information relating to this advisory, we will place it, along with any clarifications, in a CA-95:02.README file. CERT advisories and their associated README files are available by anonymous FTP from info.cert.org. We encourage you to check the README files regularly for updates on advisories that relate to your site. ----------------------------------------------------------------------------- I. Description Some versions of /bin/mail based on BSD 4.3 UNIX are vulnerable because of timing windows in the way /bin/mail uses publicly writable directories. II. Impact Local users (users that have an account on the system) can create or modify root-owned files on the system and can thereby gain unauthorized root access. III. Solutions Either install a patch from your vendor or replace /bin/mail with mail.local. A. Obtain the appropriate patch from your vendor and install it according to the instructions included with the patch. Below is a summary of the vendors listed in the current version of the CA-95:02.README file, and the status they have provided. More complete information, including how to obtain patches, is provided in Appendix A of this advisory and reproduced in the README file associated with this advisory. We will update the README file as we receive more information from vendors. If your vendor's name is not on this list, please contact the vendor directly. Vendor or Source Status ---------------- ------------ Apple Computer, Inc. not vulnerable Berkeley SW Design, Inc. (BSDI) not vulnerable Data General Corp. not vulnerable Digital Equipment Corp. vulnerable, patches available FreeBSD not vulnerable Harris not vulnerable IBM not vulnerable NetBSD not vulnerable NeXT, Inc. not vulnerable Pyramid not vulnerable The Santa Cruz Operation (SCO) see note in Appendix A Solbourne (Grumman) vulnerable - contact vendor Sun Microsystems, Inc. SunOS 4.x vulnerable, patches available, patch revisions coming soon Solaris 2.x not vulnerable B. Replace /bin/mail with mail.local. If you cannot obtain a vendor-supplied replacement for /bin/mail, the CERT Coordination Center recommends using mail.local as a replacement for /bin/mail. Although the current version of mail.local is not a perfect solution, it addresses the vulnerabilities currently being exploited in /bin/mail. As improvements to mail.local become available, we will note them in the README file associated with this advisory. The current version of mail.local has been tested on SunOS 4.1 and Ultrix 4.X systems. Mail.local.c for BSD 4.3 systems, along with a README file containing installation instructions, can be found on the anonymous FTP servers listed below. In addition, Appendix B of this advisory contains the the README file and Appendix C contains mail.local.c. Location Filename -------- -------- info.cert.org /pub/tools/mail.local/mail.local.c MD5 c0d64e740b42f6dc5cc54a2bc37c31b0 coast.cs.purdue.edu /pub/tools/unix/mail.local/mail.local.c MD5 c0d64e740b42f6dc5cc54a2bc37c31b0 --------------------------------------------------------------------------- The CERT Coordination Center thanks Eric Allman, Wolfgang Ley, Karl Strickland, Wietse Venema, and Neil Woods for their contributions to mail.local. --------------------------------------------------------------------------- If you believe that your system has been compromised, contact the CERT Coordination Center or your representative in Forum of Incident Response and Security Teams (FIRST). If you wish to send sensitive incident or vulnerability information to CERT staff by electronic mail, we strongly advise that the e-mail be encrypted. The CERT Coordination Center can support a shared DES key, PGP (public key available via anonymous FTP on info.cert.org), or PEM (contact CERT staff for details). Internet E-mail: cert@cert.org Telephone: +1 412-268-7090 (24-hour hotline) CERT personnel answer 8:30 a.m.-5:00 p.m. EST(GMT-5)/EDT(GMT-4), and are on call for emergencies during other hours. Fax: +1 412-268-6989 CERT Coordination Center Software Engineering Institute Carnegie Mellon University Pittsburgh, PA 15213-3890 USA Past advisories, CERT bulletins, information about FIRST representatives, and other information related to computer security are available for anonymous FTP from info.cert.org. CERT is a service mark of Carnegie Mellon University. ............................................................................... Appendix A: Vendor Information Current as of January 26, 1995 See CA-95.02.README for updated information Below is information we have received from vendors who have patches available or upcoming for the vulnerabilities described in this advisory, as well as vendors who have confirmed that their products are not vulnerable. If your vendor's name is not in one of these lists, contact the vendor directly for information on whether their version of sendmail is vulnerable and, if so, the status of patches to address the vulnerabilities. NOT VULNERABLE -------------- The following vendors have reported that their products are NOT vulnerable. Apple Computer, Inc. Berkeley SW Design, Inc. (BSDI) Data General Corp. Harris IBM NeXT, Inc. Pyramid The Santa Cruz Operation (SCO) - not vulnerable, but see note below Sun Microsystems, Inc. - Solaris 2.x (SunOS 4.x is vulnerable; see below) In addition, we have reports that the following products are NOT vulnerable. FreeBSD NetBSD VULNERABLE ---------- We have reports that the following vendors' products ARE vulnerable. Patch information is provided below. ----------------------------- Digital Equipment Corporation Vulnerable: DEC OSF/1 versions 1.2, 1.3, and 2.0 DEC ULTRIX versions 4.3, 4.3A, and 4.4 Obtain and install the appropriate patch according to the instructions included with the patch. The patch that corrects the /bin/mail problem in each case is part of a comprehensive Security Enhanced Kit that addresses other problems as well. This kit has been available since May 17, 1994. It is described in DEC security advisory #0505 and in CERT bulletin VB-94:02. 1. DEC OSF/1 Upgrade/install OSF/1 to a minimum of V2.0 and install Security Enhanced Kit CSCPAT_4061 v1.0. 2. DEC ULTRIX Upgrade/install ULTRIX to a minimum of V4.4 and install Security Enhanced Kit CSCPAT_4060 v1.0. Both kits listed above are available from Digital Equipment Corporation by contacting your normal Digital support channel or by request via DSNlink for electronic transfer. ----------------------------- The Santa Cruz Operation (SCO) SCO's version of /bin/mail is not vulnerable to the problems mentioned in this advisory. SCO's /bin/mail is not setuid-root. However, SCO's /bin/mail has other security-related issues that are fixed by SCO's Support Level Supplement (SLS) uod392a. To get this: ftp: ftp.sco.COM:/SLS/uod392a.Z (compressed disk image) ftp.sco.COM:/SLS/uod392a.ltr.Z (cover letter) ftp.sco.COM:/SLS/README ----------------------------- Solbourne Grumman System Support Corporation now performs all Solbourne software and hardware support. Please contact them for further information. ftp: ftp.nts.gssc.com phone: 1-800-447-2861 e-mail: support@nts.gssc.com ----------------------------- Sun Microsystems, Inc. Current patches are listed below, but they are being revised. SunOS Patch MD5 Checksum ------ ----- ------------ 4.1.3 100224-13.tar.Z 90a507017a1a40c4622b3f1f00ce5d2d 4.1.3UI 101436-08.tar.Z 0e64560edc61eb4b3da81a932e8b11e1 The patches can be obtained from local Sun Answer Centers and through anonymous FTP from ftp.uu.net in the /systems/sun/sun-dist directory. In Europe, the patches are available from mcsun.eu.net in the /sun/fixes directory. Appendix B: README File for mail.local.c /bin/mail is a setuid root program with several security vulnerabilities. If you cannot obtain a vendor-supplied replacement for /bin/mail, the CERT Coordination Center suggests using mail.local as a replacement for /bin/mail. In the early days of UNIX, /bin/mail was used to read and to send e-mail. Over the years, many users have switched to e-mail programs with better user interfaces and more features. On BSD 4.3 based UNIX systems using sendmail, /bin/mail is still being used as the local delivery agent. These systems could be at risk. Systems based on UNIX system III or system IV are not vulnerable. mail.local is a replacement for the /bin/mail program. It is only a delivery agent for sendmail and does not have a user interface. It is distributed as a C source file. For operating systems based on BSD 4.3, mail.local.c from a BSD 4.4 distribution will not compile. The version of mail.local.c in this directory was ported to BSD 4.3 by Eric Allman. It should compile and operate on most BSD 4.3 systems. It has been tested on SunOS 4.1.x and Ultrix 4.x systems. To install mail.local, edit the source file to set the _PATH_MAILDIR to the directory where users' spooled mail files are located. The default is "/var/spool/mail". SunOS % cc -Bstatic -O -o mail.local mail.local.c Ultrix % cc -O -o mail.local mail.local.c -Dultrix As root: # mv mail.local $INSTALL_DIR Substitute $INSTALL_DIR for the full pathname of the directory where mail.local will be installed. # chown root $INSTALL_DIR/mail.local # chmod 4711 $INSTALL_DIR/mail.local Edit the sendmail.cf file (in /etc or /usr/lib) search for Mlocal. On that line, replace /bin/mail with $INSTALL_DIR/mail.local. Restart the sendmail process. For versions of sendmail using frozen configuration files, it is important to refreeze the configuration file before restarting the sendmail process. Test the e-mail system. When you are satisfied that everything is working, disable the setuid root bit on the /bin/mail program. # chmod 0711 /bin/mail OR # chmod 0711 /usr/bin/mail **************************************************************************** * The CERT Coordination Center will not formally review, evaluate, or * * endorse the program described. The decision to use the program * * described is the responsibility of each user or organization and we * * encourage each organization to thoroughly evaluate this program * * before installation or use. * **************************************************************************** Appendix C: mail.local.c /*- * Copyright (c) 1990, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint static char copyright[] = "@(#) Copyright (c) 1990, 1993, 1994\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint static char sccsid[] = "@(#)mail.local.c 8.18 (Berkeley) 1/25/95"; #endif /* not lint */ /* * This is not intended to compile on System V derived systems * such as Solaris or HP-UX, since they use a totally different * approach to mailboxes (essentially, they have a setgid program * rather than setuid, and they rely on the ability to "give away" * files to do their work). IT IS NOT A BUG that this doesn't * compile on such architectures. */ #include <sys/param.h> #include <sys/stat.h> #include <sys/socket.h> #include <netinet/in.h> #include <errno.h> #include <fcntl.h> #include <netdb.h> #include <pwd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sysexits.h> #include <syslog.h> #include <time.h> #include <unistd.h> #include <ctype.h> #if __STDC__ #include <stdarg.h> #else #include <varargs.h> #endif #ifndef LOCK_EX # include <sys/file.h> #endif #ifdef BSD4_4 # include "pathnames.h" #endif #ifndef __P # ifdef __STDC__ # define __P(protos) protos # else # define __P(protos) () # define const # endif #endif #ifndef __dead # if defined(__GNUC__) && (__GNUC__ < 2 || __GNUC_MINOR__ < 5) && !defined(__STRICT_ANSI__) # define __dead __volatile # else # define __dead # endif #endif #ifndef BSD4_4 # define _BSD_VA_LIST_ va_list extern char *strerror __P((int)); #endif #ifndef _PATH_LOCTMP # define _PATH_LOCTMP "/tmp/local.XXXXXX" #endif #ifndef _PATH_MAILDIR # define _PATH_MAILDIR "/var/spool/mail" #endif #ifndef S_ISREG # define S_ISREG(mode) (((mode) & _S_IFMT) == S_IFREG) #endif int eval = EX_OK; /* sysexits.h error value. */ void deliver __P((int, char *)); void e_to_sys __P((int)); __dead void err __P((const char *, ...)); void notifybiff __P((char *)); int store __P((char *)); void usage __P((void)); void vwarn __P((const char *, _BSD_VA_LIST_)); void warn __P((const char *, ...)); int main(argc, argv) int argc; char *argv[]; { struct passwd *pw; int ch, fd; uid_t uid; char *from; extern char *optarg; extern int optind; /* make sure we have some open file descriptors */ for (fd = 10; fd < 30; fd++) (void) close(fd); /* use a reasonable umask */ (void) umask(0077); #ifdef LOG_MAIL openlog("mail.local", 0, LOG_MAIL); #else openlog("mail.local", 0); #endif from = NULL; while ((ch = getopt(argc, argv, "df:r:")) != EOF) switch(ch) { case 'd': /* Backward compatible. */ break; case 'f': case 'r': /* Backward compatible. */ if (from != NULL) { warn("multiple -f options"); usage(); } from = optarg; break; case '?': default: usage(); } argc -= optind; argv += optind; if (!*argv) usage(); /* * If from not specified, use the name from getlogin() if the * uid matches, otherwise, use the name from the password file * corresponding to the uid. */ uid = getuid(); if (!from && (!(from = getlogin()) || !(pw = getpwnam(from)) || pw->pw_uid != uid)) from = (pw = getpwuid(uid)) ? pw->pw_name : "???"; /* * There is no way to distinguish the error status of one delivery * from the rest of the deliveries. So, if we failed hard on one * or more deliveries, but had no failures on any of the others, we * return a hard failure. If we failed temporarily on one or more * deliveries, we return a temporary failure regardless of the other * failures. This results in the delivery being reattempted later * at the expense of repeated failures and multiple deliveries. */ for (fd = store(from); *argv; ++argv) deliver(fd, *argv); exit(eval); } int store(from) char *from; { FILE *fp; time_t tval; int fd, eline; char line[2048]; char tmpbuf[sizeof _PATH_LOCTMP + 1]; strcpy(tmpbuf, _PATH_LOCTMP); if ((fd = mkstemp(tmpbuf)) == -1 || (fp = fdopen(fd, "w+")) == NULL) { e_to_sys(errno); err("unable to open temporary file"); } (void)unlink(tmpbuf); (void)time(&tval); (void)fprintf(fp, "From %s %s", from, ctime(&tval)); line[0] = '\0'; for (eline = 1; fgets(line, sizeof(line), stdin);) { if (line[0] == '\n') eline = 1; else { if (eline && line[0] == 'F' && !memcmp(line, "From ", 5)) (void)putc('>', fp); eline = 0; } (void)fprintf(fp, "%s", line); if (ferror(fp)) { e_to_sys(errno); err("temporary file write error"); } } /* If message not newline terminated, need an extra. */ if (!strchr(line, '\n')) (void)putc('\n', fp); /* Output a newline; note, empty messages are allowed. */ (void)putc('\n', fp); if (fflush(fp) == EOF || ferror(fp)) { e_to_sys(errno); err("temporary file write error"); } return (fd); } void deliver(fd, name) int fd; char *name; { struct stat fsb, sb; struct passwd *pw; int mbfd, nr, nw, off; char *p; char biffmsg[100], buf[8*1024], path[MAXPATHLEN]; off_t curoff; /* * Disallow delivery to unknown names -- special mailboxes can be * handled in the sendmail aliases file. */ if (!(pw = getpwnam(name))) { if (eval != EX_TEMPFAIL) eval = EX_UNAVAILABLE; warn("unknown name: %s", name); return; } /* * Keep name reasonably short to avoid buffer overruns. * This isn't necessary on BSD because of the proper * definition of snprintf(), but it can cause problems * on other systems. * Also, clear out any bogus characters. */ if (strlen(name) > 40) name[40] = '\0'; for (p = name; *p != '\0'; p++) { if (!isascii(*p)) *p &= 0x7f; else if (!isprint(*p)) *p = '.'; } (void)snprintf(path, sizeof(path), "%s/%s", _PATH_MAILDIR, name); /* * If the mailbox is linked or a symlink, fail. There's an obvious * race here, that the file was replaced with a symbolic link after * the lstat returned, but before the open. We attempt to detect * this by comparing the original stat information and information * returned by an fstat of the file descriptor returned by the open. * * NB: this is a symptom of a larger problem, that the mail spooling * directory is writeable by the wrong users. If that directory is * writeable, system security is compromised for other reasons, and * it cannot be fixed here. * * If we created the mailbox, set the owner/group. If that fails, * just return. Another process may have already opened it, so we * can't unlink it. Historically, binmail set the owner/group at * each mail delivery. We no longer do this, assuming that if the * ownership or permissions were changed there was a reason. * * XXX * open(2) should support flock'ing the file. */ tryagain: lockmbox(path); if (lstat(path, &sb)) { mbfd = open(path, O_APPEND|O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR); if (mbfd == -1) { if (errno == EEXIST) goto tryagain; } else if (fchown(mbfd, pw->pw_uid, pw->pw_gid)) { e_to_sys(errno); warn("chown %u.%u: %s", pw->pw_uid, pw->pw_gid, name); unlockmbox(); return; } } else if (sb.st_nlink != 1 || !S_ISREG(sb.st_mode)) { e_to_sys(errno); warn("%s: irregular file", path); unlockmbox(); return; } else if (sb.st_uid != pw->pw_uid) { warn("%s: wrong ownership (%d)", path, sb.st_uid); unlockmbox(); return; } else { mbfd = open(path, O_APPEND|O_WRONLY, 0); if (mbfd != -1 && (fstat(mbfd, &fsb) || fsb.st_nlink != 1 || !S_ISREG(fsb.st_mode) || sb.st_dev != fsb.st_dev || sb.st_ino != fsb.st_ino || sb.st_uid != fsb.st_uid)) { warn("%s: file changed after open", path); (void)close(mbfd); unlockmbox(); return; } } if (mbfd == -1) { e_to_sys(errno); warn("%s: %s", path, strerror(errno)); unlockmbox(); return; } /* Wait until we can get a lock on the file. */ if (flock(mbfd, LOCK_EX)) { e_to_sys(errno); warn("%s: %s", path, strerror(errno)); unlockmbox(); goto err1; } /* Get the starting offset of the new message for biff. */ curoff = lseek(mbfd, (off_t)0, SEEK_END); (void)snprintf(biffmsg, sizeof(biffmsg), sizeof curoff > sizeof(long) ? "%s@%qd\n" : "%s@%ld\n", name, curoff); /* Copy the message into the file. */ if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) { e_to_sys(errno); warn("temporary file: %s", strerror(errno)); goto err1; } while ((nr = read(fd, buf, sizeof(buf))) > 0) for (off = 0; off < nr; off += nw) if ((nw = write(mbfd, buf + off, nr - off)) < 0) { e_to_sys(errno); warn("%s: %s", path, strerror(errno)); goto err2;; } if (nr < 0) { e_to_sys(errno); warn("temporary file: %s", strerror(errno)); goto err2;; } /* Flush to disk, don't wait for update. */ if (fsync(mbfd)) { e_to_sys(errno); warn("%s: %s", path, strerror(errno)); err2: (void)ftruncate(mbfd, curoff); err1: (void)close(mbfd); unlockmbox(); return; } /* Close and check -- NFS doesn't write until the close. */ if (close(mbfd)) { e_to_sys(errno); warn("%s: %s", path, strerror(errno)); unlockmbox(); return; } unlockmbox(); notifybiff(biffmsg); } /* * user.lock files are necessary for compatibility with other * systems, e.g., when the mail spool file is NFS exported. * Alas, mailbox locking is more than just a local matter. * EPA 11/94. */ char lockname[MAXPATHLEN]; int locked = 0; lockmbox(path) char *path; { int statfailed = 0; if (locked) return; sprintf(lockname, "%s.lock", path); for (;; sleep(5)) { int fd; struct stat st; time_t now; fd = open(lockname, O_WRONLY|O_EXCL|O_CREAT, 0); if (fd >= 0) { locked = 1; close(fd); return; } if (stat(lockname, &st) < 0) { if (statfailed++ > 5) return; continue; } statfailed = 0; time(&now); if (now < st.st_ctime + 300) continue; unlink(lockname); } } unlockmbox() { if (!locked) return; unlink(lockname); locked = 0; } void notifybiff(msg) char *msg; { static struct sockaddr_in addr; static int f = -1; struct hostent *hp; struct servent *sp; int len; if (!addr.sin_family) { /* Be silent if biff service not available. */ if (!(sp = getservbyname("biff", "udp"))) return; if (!(hp = gethostbyname("localhost"))) { warn("localhost: %s", strerror(errno)); return; } addr.sin_family = hp->h_addrtype; memcpy(&addr.sin_addr, hp->h_addr, hp->h_length); addr.sin_port = sp->s_port; } if (f < 0 && (f = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { warn("socket: %s", strerror(errno)); return; } len = strlen(msg) + 1; if (sendto(f, msg, len, 0, (struct sockaddr *)&addr, sizeof(addr)) != len) warn("sendto biff: %s", strerror(errno)); } void usage() { eval = EX_USAGE; err("usage: mail.local [-f from] user ..."); } #if __STDC__ void err(const char *fmt, ...) #else void err(fmt, va_alist) const char *fmt; va_dcl #endif { va_list ap; #if __STDC__ va_start(ap, fmt); #else va_start(ap); #endif vwarn(fmt, ap); va_end(ap); exit(eval); } void #if __STDC__ warn(const char *fmt, ...) #else warn(fmt, va_alist) const char *fmt; va_dcl #endif { va_list ap; #if __STDC__ va_start(ap, fmt); #else va_start(ap); #endif vwarn(fmt, ap); va_end(ap); } void vwarn(fmt, ap) const char *fmt; _BSD_VA_LIST_ ap; { /* * Log the message to stderr. * * Don't use LOG_PERROR as an openlog() flag to do this, * it's not portable enough. */ if (eval != EX_USAGE) (void)fprintf(stderr, "mail.local: "); (void)vfprintf(stderr, fmt, ap); (void)fprintf(stderr, "\n"); #ifndef ultrix /* Log the message to syslog. */ vsyslog(LOG_ERR, fmt, ap); #else { char fmtbuf[10240]; (void) sprintf(fmtbuf, fmt, ap); syslog(LOG_ERR, "%s", fmtbuf); } #endif } /* * e_to_sys -- * Guess which errno's are temporary. Gag me. */ void e_to_sys(num) int num; { /* Temporary failures override hard errors. */ if (eval == EX_TEMPFAIL) return; switch(num) { /* Hopefully temporary errors. */ #ifdef EAGAIN case EAGAIN: /* Resource temporarily unavailable */ #endif #ifdef EDQUOT case EDQUOT: /* Disc quota exceeded */ #endif #ifdef EBUSY case EBUSY: /* Device busy */ #endif #ifdef EPROCLIM case EPROCLIM: /* Too many processes */ #endif #ifdef EUSERS case EUSERS: /* Too many users */ #endif #ifdef ECONNABORTED case ECONNABORTED: /* Software caused connection abort */ #endif #ifdef ECONNREFUSED case ECONNREFUSED: /* Connection refused */ #endif #ifdef ECONNRESET case ECONNRESET: /* Connection reset by peer */ #endif #ifdef EDEADLK case EDEADLK: /* Resource deadlock avoided */ #endif #ifdef EFBIG case EFBIG: /* File too large */ #endif #ifdef EHOSTDOWN case EHOSTDOWN: /* Host is down */ #endif #ifdef EHOSTUNREACH case EHOSTUNREACH: /* No route to host */ #endif #ifdef EMFILE case EMFILE: /* Too many open files */ #endif #ifdef ENETDOWN case ENETDOWN: /* Network is down */ #endif #ifdef ENETRESET case ENETRESET: /* Network dropped connection on reset */ #endif #ifdef ENETUNREACH case ENETUNREACH: /* Network is unreachable */ #endif #ifdef ENFILE case ENFILE: /* Too many open files in system */ #endif #ifdef ENOBUFS case ENOBUFS: /* No buffer space available */ #endif #ifdef ENOMEM case ENOMEM: /* Cannot allocate memory */ #endif #ifdef ENOSPC case ENOSPC: /* No space left on device */ #endif #ifdef EROFS case EROFS: /* Read-only file system */ #endif #ifdef ESTALE case ESTALE: /* Stale NFS file handle */ #endif #ifdef ETIMEDOUT case ETIMEDOUT: /* Connection timed out */ #endif #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN && EWOULDBLOCK != EDEADLK case EWOULDBLOCK: /* Operation would block. */ #endif eval = EX_TEMPFAIL; break; default: eval = EX_UNAVAILABLE; break; } } #ifndef BSD4_4 char * strerror(eno) int eno; { extern int sys_nerr; extern char *sys_errlist[]; static char ebuf[60]; if (eno >= 0 && eno <= sys_nerr) return sys_errlist[eno]; (void) sprintf(ebuf, "Error %d", eno); return ebuf; } #if __STDC__ snprintf(char *buf, int bufsiz, const char *fmt, ...) #else snprintf(buf, bufsiz, fmt, va_alist) char *buf; int bufsiz; const char *fmt; va_dcl #endif { va_list ap; #if __STDC__ va_start(ap, fmt); #else va_start(ap); #endif vsprintf(buf, fmt, ap); va_end(ap); } #endif #ifdef ultrix /* * Copyright (c) 1987, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <stdio.h> #include <ctype.h> static int _gettemp(); mkstemp(path) char *path; { int fd; return (_gettemp(path, &fd) ? fd : -1); } /* char * mktemp(path) char *path; { return(_gettemp(path, (int *)NULL) ? path : (char *)NULL); } */ static _gettemp(path, doopen) char *path; register int *doopen; { extern int errno; register char *start, *trv; struct stat sbuf; u_int pid; pid = getpid(); for (trv = path; *trv; ++trv); /* extra X's get set to 0's */ while (*--trv == 'X') { *trv = (pid % 10) + '0'; pid /= 10; } /* * check the target directory; if you have six X's and it * doesn't exist this runs for a *very* long time. */ for (start = trv + 1;; --trv) { if (trv <= path) break; if (*trv == '/') { *trv = '\0'; if (stat(path, &sbuf)) return(0); if (!S_ISDIR(sbuf.st_mode)) { errno = ENOTDIR; return(0); } *trv = '/'; break; } } for (;;) { if (doopen) { if ((*doopen = open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) return(1); if (errno != EEXIST) return(0); } else if (stat(path, &sbuf)) return(errno == ENOENT ? 1 : 0); /* tricky little algorithm for backward compatibility */ for (trv = start;;) { if (!*trv) return(0); if (*trv == 'z') *trv++ = 'a'; else { if (isdigit(*trv)) *trv = 'a'; else ++*trv; break; } } } /*NOTREACHED*/ } #endif
participants (1)
-
cert-advisory@cert.org