Subject: bin/2544: restore doesn't use unique temporary files
To: None <gnats-bugs@NetBSD.ORG>
From: Luke Mewburn <lukem@supp.cpr.itg.telecom.com.au>
List: netbsd-bugs
Date: 06/13/1996 15:22:37
>Number:         2544
>Category:       bin
>Synopsis:       restore doesn't use unique temporary files
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   lm
>Arrival-Date:   Thu Jun 13 01:35:04 1996
>Last-Modified:
>Originator:     Luke Mewburn
>Organization:
Telstra
>Release:        1.2_ALPHA
>Environment:
System: NetBSD shelob 1.2_ALPHA NetBSD 1.2_ALPHA (SHELOB) #7: Wed Jun 5 11:03:42 EST 1996 root@shelob:/z/src/sys/arch/i386/compile/SHELOB i386

>Description:
	restore(8) creates temporary files which contain details about
	permissions to restore to directories when finished.
	These temporary names are based upon the "dump date" of the backup.
	So, if you have multiple tape drives that you're restoring from
	that had backups started at the same time (rather easy to do
	with automatic backup systems), or you have a dump archive in
	a file and you're extracting in one sessions and "tvf"-ing in
	another, then you lose.

	I'm sure that this bug has been present since 4.2BSD days, and
	has even migrated to Solaris 2 (ufsrestore) amongst others.

>How-To-Repeat:
	simple:
		% touch foo.dump
		% dump 0f foo.dump /
		% restore ivf foo.dump
		restore> (hit ^Z)
		% restore tvf foo.dump
		% fg   (to get first restore back)
		then after extracting stuff, notice the warning about
		the missing rstdir/rstmode files, and how your
		directories have the wrong permissions.

>Fix:
	apply this rather simple patch:

diff -c /ftp/pub/NetBSD/NetBSD-current/src/sbin/restore/dirs.c ./dirs.c
*** /ftp/pub/NetBSD/NetBSD-current/src/sbin/restore/dirs.c	Sat Oct 14 11:13:00 1995
--- ./dirs.c	Thu Jun 13 15:14:17 1996
***************
*** 111,119 ****
  static long	seekpt;
  static FILE	*df, *mf;
  static RST_DIR	*dirp;
! static char	dirfile[32] = "#";	/* No file */
! static char	modefile[32] = "#";	/* No file */
! static char	dot[2] = ".";		/* So it can be modified */
  
  /*
   * Format of old style directories.
--- 111,119 ----
  static long	seekpt;
  static FILE	*df, *mf;
  static RST_DIR	*dirp;
! static char	dirfile[MAXPATHLEN] = "#";	/* No file */
! static char	modefile[MAXPATHLEN] = "#";	/* No file */
! static char	dot[2] = ".";			/* So it can be modified */
  
  /*
   * Format of old style directories.
***************
*** 151,157 ****
  	struct direct nulldir;
  
  	vprintf(stdout, "Extract directories from tape\n");
! 	(void) sprintf(dirfile, "%s/rstdir%d", _PATH_TMP, dumpdate);
  	df = fopen(dirfile, "w");
  	if (df == NULL) {
  		fprintf(stderr,
--- 151,163 ----
  	struct direct nulldir;
  
  	vprintf(stdout, "Extract directories from tape\n");
! 	(void) sprintf(dirfile, "%s/rstdir%d-XXXXXX", _PATH_TMP, dumpdate);
! 	if (mktemp(dirfile) == NULL) {
! 		fprintf(stderr,
! 		    "restore: %s - cannot generate directory temporary\n",
! 		    dirfile);
! 		exit(1);
! 	}
  	df = fopen(dirfile, "w");
  	if (df == NULL) {
  		fprintf(stderr,
***************
*** 161,167 ****
  		exit(1);
  	}
  	if (genmode != 0) {
! 		(void) sprintf(modefile, "%s/rstmode%d", _PATH_TMP, dumpdate);
  		mf = fopen(modefile, "w");
  		if (mf == NULL) {
  			fprintf(stderr,
--- 167,180 ----
  		exit(1);
  	}
  	if (genmode != 0) {
! 		(void) sprintf(modefile, "%s/rstmode%d-XXXXXX", _PATH_TMP,
! 			       dumpdate);
! 		if (mktemp(modefile) == NULL) {
! 			fprintf(stderr,
! 			    "restore: %s - cannot generate modefile\n",
! 			    modefile);
! 			exit(1);
! 		}
  		mf = fopen(modefile, "w");
  		if (mf == NULL) {
  			fprintf(stderr,
Only in .: obj.i386
>Audit-Trail:
>Unformatted: