-/*\r
- * This file is part of the IPCop Firewall.\r
- *\r
- * IPCop is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * IPCop is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with IPCop; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
- *\r
- * Copyright (C) 2002-06-02 Mark Wormgoor <mark@wormgoor.com>\r
- *\r
- * $Id: ipcopbackup.c,v 1.8.2.6 2006/01/20 13:30:42 franck78 Exp $\r
- *\r
- */\r
-\r
-#include <stdio.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-#include <unistd.h>\r
-#include <sys/types.h>\r
-#include <sys/stat.h>\r
-#include <fcntl.h>\r
-#include <pwd.h>\r
-#include <shadow.h>\r
-#include <crypt.h>\r
-#include <glob.h>\r
-#include "setuid.h"\r
-\r
-// want a bigger buffer to concatenate a possibly long string\r
-#define COMMAND_SIZE 4000\r
-//Append lines contained in 'inputfile' to 'string'\r
-int catlist(char* inputfile,\r
- char* string ) {\r
-\r
- struct stat s; // input file stats\r
- char buffer[STRING_SIZE]; // read buffer\r
-\r
- if (stat(inputfile,&s) != 0) return 1;\r
- if (s.st_size+strlen(string)>COMMAND_SIZE) return 1; // too big!\r
- int f = open(inputfile, O_RDONLY);\r
- if (!f) return 1; // cannot open file\r
-\r
- int count;\r
- while ((count = read(f, buffer, STRING_SIZE - 1))) {\r
- int j;\r
- for (j=0; j<count; j++) { //replace newlines with spaces\r
- if (buffer[j] == '\n') buffer[j] = ' '; \r
- }\r
- buffer[j] = '\0';\r
- strcat (string,buffer); // append to string\r
- }\r
- close (f);\r
- return 0; //success\r
-}\r
-\r
-// make a raw backup to floppy_dev (no partitioning)\r
-int savecfg_floppy(char* floppy_dev) {\r
- char command[COMMAND_SIZE]; // because copy each filename here\r
-\r
- // want special output...\r
- if (close(0)) { fprintf(stderr, "Couldn't close 0\n"); exit(1); }\r
- if (open("/dev/zero", O_RDONLY) != 0) {fprintf(stderr, "Couldn't reopen stdin from /dev/zero\n"); exit(1); }\r
- if (close(2)) { fprintf(stderr, "Couldn't close 2\n"); exit(1); }\r
- if (! dup(1)) { fprintf(stderr, "Couldnt redirect stderr to stdout\n"); exit(1); }\r
-\r
- /* Make sure floppy device name is up to date */\r
- safe_system ("/usr/sbin/updfstab");\r
-\r
- /* Darren Critchley - check for floppy disk in disk drive before continuing */\r
- snprintf (command, STRING_SIZE-1, "dd if=%s of=/dev/null bs=1k count=1 2> /dev/null", floppy_dev);\r
- if (safe_system(command)) {\r
- perror( "Error: No floppy in drive or bad floppy in drive" );\r
- exit(1);\r
- }\r
-\r
- /* Clearing disk */\r
- snprintf (command, STRING_SIZE-1, "/bin/dd if=/dev/zero of=%s bs=1k 2> /dev/null", floppy_dev);\r
- safe_system (command);\r
-\r
- /* Start tarring files to floppy */\r
- snprintf (command, COMMAND_SIZE-1, "/bin/tar -X " CONFIG_ROOT"/backup/exclude.system "\r
- "-X " CONFIG_ROOT"/backup/exclude.user "\r
- "-C / -cvzf %s "\r
- "-T " CONFIG_ROOT"/backup/include.user ",\r
- floppy_dev);\r
- /* add include.system file content to 'command' */\r
- if (catlist(CONFIG_ROOT "/backup/include.system", command)) {\r
- fprintf(stderr, "Couldn't open backup system include file\n");\r
- exit (1);\r
- }\r
- safe_system (command);\r
-\r
- /* Now check it */\r
- snprintf (command, STRING_SIZE-1,"/bin/echo '<b>Checking</b>'; /bin/tar -tzf %s" , floppy_dev);\r
- safe_system (command);\r
-\r
- exit(0);\r
-}\r
-\r
-\r
-// Just verify that root password is ok\r
-int checkrootpass (char* passwd) {\r
-\r
- struct passwd *pw;\r
- struct spwd *spwd;\r
-\r
- if ((pw = getpwnam("root")) == NULL) {\r
- return (0); // root unknown....!\r
- }\r
-\r
- // get shadowed password \r
- spwd = getspnam("root");\r
-\r
- //and use it in right place\r
- if (spwd)\r
- pw->pw_passwd = spwd->sp_pwdp;\r
-\r
- return (strcmp ( crypt(passwd, pw->pw_passwd), //encrypt cleartext\r
- pw->pw_passwd) == 0 //compare to encrypted version\r
- ) ? 1 : 0; // true or false\r
-}\r
-\r
-\r
-int main (int argc, char *argv[]) {\r
- char command[STRING_SIZE];\r
-\r
- if (argc < 3) { // at least two args always needed, avoid some testing.\r
- fprintf (stderr, "Err %s: used from cgi only !\n", argv[0]);\r
- exit (1);\r
- }\r
-\r
- if (!initsetuid()){\r
- fprintf (stderr, "Err %s: cannot setuid !\n", argv[0]);\r
- exit (1);\r
- }\r
-\r
- // save on normal floppy for use during reinstall ONLY\r
- if ( (strcmp(argv[1],"-savecfg" ) == 0) &&\r
- (strcmp(argv[2],"floppy") == 0) ) \r
- savecfg_floppy("/dev/floppy"); // to do: mount usb floppy....\r
-\r
- if ( (strcmp(argv[1],"-proc" ) == 0) &&\r
- (strcmp(argv[2],"partitions") == 0) ) { // issue cat /proc/partitions\r
-\r
- int fi;\r
- if ( (fi = open("/proc/partitions", O_RDONLY))==-1) exit (1); // cannot open file\r
- char string[STRING_SIZE];\r
- int count;\r
- while ((count = read(fi, string, STRING_SIZE))) {\r
- write (1, string, count);\r
- }\r
- close (fi);\r
- exit (0);\r
- }\r
-\r
- // output result of 'glob' function\r
- if ( (strcmp(argv[1],"-glob" ) == 0)) {\r
- glob_t g;\r
- if (glob (argv[2],0,NULL,&g) == 0) {\r
- char** pstr = g.gl_pathv; // base array\r
- while (*pstr) { // while not NULL\r
- printf ("%s\n", *pstr); // pstr is a pointer to array of char*\r
- pstr++; // next pointer\r
- }\r
- globfree (&g);\r
- }\r
- exit (0);\r
- }\r
-\r
- // tell if the backup.key is present\r
- if ( (strcmp(argv[1],"-key" ) == 0) &&\r
- (strcmp(argv[2],"exist") == 0) ) { // check key existence\r
- if ( !(file_exists(BACKUP_KEY)) ) {\r
- fprintf (stderr, "Err %s: backup key "BACKUP_KEY" does not exist !\n", argv[0]);\r
- exit (ERR_KEY);\r
- }\r
- exit (0);\r
- }\r
-\r
- // cat the backup.key, for saving it\r
- if ( strcmp(argv[1],"-keycat" ) == 0) {\r
- if (! checkrootpass (argv[2])) exit (1); // but only if root pw provided\r
- int fi;\r
- if ( (fi = open(BACKUP_KEY, O_RDONLY))==-1) exit (1); // cannot open file\r
- char string[STRING_SIZE];\r
- int count;\r
- while ((count = read(fi, string, STRING_SIZE))) {\r
- write (1, string, count);\r
- }\r
- close (fi);\r
- exit (0);\r
- }\r
- \r
- // generate a new backup.key ONLY if inexistant\r
- if ( (strcmp(argv[1],"-key" ) == 0) &&\r
- (strcmp(argv[2],"new") == 0) ) { \r
- if ( (file_exists(BACKUP_KEY)) ) {\r
- fprintf (stderr, "Err %s: backup key "BACKUP_KEY" already exists !\n", argv[0]);\r
- exit (ERR_KEY);\r
- }\r
- //ok we can generate it\r
- if (safe_system ("/usr/sbin/ipsec ranbits 256 > " BACKUP_KEY)) {\r
- fprintf (stderr, "Err %s: couldn't create key !\n", argv[0]);\r
- exit (ERR_KEY);\r
- }\r
- chmod(BACKUP_KEY, S_IRUSR); // protect it\r
- exit (0);\r
- }\r
- \r
- // import a backup.key only if non existent\r
- if ( (strcmp(argv[1],"-key" ) == 0) &&\r
- (strcmp(argv[2],"import") == 0) ) {\r
- if ( (file_exists(BACKUP_KEY)) ) {\r
- unlink (MOUNTPOINT"/key"); // clean anyway\r
- fprintf (stderr, "Err %s: backup key "BACKUP_KEY" already exists !\n", argv[0]);\r
- exit (ERR_KEY);\r
- }\r
-\r
- int fi, fo;\r
- if ( (fi = open(MOUNTPOINT"/key", O_RDONLY))==-1) {\r
- fprintf (stderr, "Err %s: no backup key "MOUNTPOINT"/key to import !\n", argv[0]);\r
- exit (ERR_KEY); // cannot open file\r
- } \r
-\r
- if ( (fo = open(BACKUP_KEY, O_WRONLY | O_CREAT ))==-1) {\r
- close (fi);\r
- unlink (MOUNTPOINT"/key"); // clean anyway\r
- fprintf (stderr, "Err %s: backup key "BACKUP_KEY" creation error !\n", argv[0]);\r
- exit (ERR_KEY);\r
- }\r
-\r
- char buffer[STRING_SIZE];\r
- int count;\r
- while ((count = read(fi, buffer, STRING_SIZE))) {\r
- write (fo, buffer, count);\r
- }\r
- close (fo);\r
- close (fi);\r
- unlink (MOUNTPOINT"/key");\r
- exit (0);\r
- }\r
-\r
- // disk functions like mount umount,...\r
- if ((strspn(argv[2], LETTERS_NUMBERS ) == strlen(argv[2])) &&\r
- (strlen(argv[2]) >2) && (strlen(argv[2]) <6)) {\r
- if (strcmp(argv[1],"-M") == 0) { // M sda1 => mount /dev/sda1 /mountpoint\r
- //safe_system("/bin/sync");\r
- snprintf(command, STRING_SIZE - 1,"/bin/mount -t vfat -o,uid=99,gid=99 /dev/%s "MOUNTPOINT, argv[2]);\r
- safe_system(command);\r
- //safe_system("/bin/sync");\r
- }else\r
- if (strcmp(argv[1],"-U") == 0) { // U sda1 => umount /dev/sda1\r
- //safe_system("/bin/sync");\r
- snprintf(command, STRING_SIZE - 1,"/bin/umount /dev/%s", argv[2]);\r
- safe_system(command);\r
- safe_system("/bin/sync");\r
- }else\r
- if (strcmp(argv[1],"-f") == 0) { // f sda1 => mke2fs /dev/sda1\r
- snprintf(command, STRING_SIZE - 1,"/sbin/mke2fs -q /dev/%s", argv[2]);\r
- //safe_system(command);\r
- //safe_system("/bin/sync");\r
- }else\r
- if (strcmp(argv[1],"-F") == 0) { // F sda => fdisk /dev/sda\r
- //safe_system("/bin/sync");\r
- snprintf(command, STRING_SIZE - 1,"/bin/dd if=/dev/zero of=/dev/%s count=2 bs=512", argv[2]);\r
- //safe_system(command);\r
- snprintf(command, STRING_SIZE - 1,"/bin/echo \"n\np\n1\n1\n\nw\nq\n\"|/sbin/fdisk /dev/%s", argv[2]);\r
- //safe_system(command);\r
- snprintf(command, STRING_SIZE - 1,"/sbin/mke2fs -q /dev/%s1", argv[2]); // beware of %s1\r
- //safe_system(command);\r
- //safe_system("/bin/sync");\r
- }else {\r
- fprintf (stderr, "Err %s: bad command !\n", argv[0]);\r
- exit (1);\r
- }\r
- exit (0);\r
- }else {\r
- fprintf (stderr, "Err %s: bad arg !\n", argv[0]);\r
- exit (1);\r
- }\r
- return 0;\r
-}\r