]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/misc-progs/ipcopbackup.c
git-svn-id: http://svn.ipfire.org/svn/ipfire/IPFire/source@16 ea5c0bd1-69bd-2848...
[people/teissler/ipfire-2.x.git] / src / misc-progs / ipcopbackup.c
1 /*
2 * This file is part of the IPCop Firewall.
3 *
4 * IPCop is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * IPCop is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with IPCop; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Copyright (C) 2002-06-02 Mark Wormgoor <mark@wormgoor.com>
19 *
20 * $Id: ipcopbackup.c,v 1.8.2.6 2006/01/20 13:30:42 franck78 Exp $
21 *
22 */
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31 #include <pwd.h>
32 #include <shadow.h>
33 #include <crypt.h>
34 #include <glob.h>
35 #include "setuid.h"
36
37 // want a bigger buffer to concatenate a possibly long string
38 #define COMMAND_SIZE 4000
39 //Append lines contained in 'inputfile' to 'string'
40 int catlist(char* inputfile,
41 char* string ) {
42
43 struct stat s; // input file stats
44 char buffer[STRING_SIZE]; // read buffer
45
46 if (stat(inputfile,&s) != 0) return 1;
47 if (s.st_size+strlen(string)>COMMAND_SIZE) return 1; // too big!
48 int f = open(inputfile, O_RDONLY);
49 if (!f) return 1; // cannot open file
50
51 int count;
52 while ((count = read(f, buffer, STRING_SIZE - 1))) {
53 int j;
54 for (j=0; j<count; j++) { //replace newlines with spaces
55 if (buffer[j] == '\n') buffer[j] = ' ';
56 }
57 buffer[j] = '\0';
58 strcat (string,buffer); // append to string
59 }
60 close (f);
61 return 0; //success
62 }
63
64 // make a raw backup to floppy_dev (no partitioning)
65 int savecfg_floppy(char* floppy_dev) {
66 char command[COMMAND_SIZE]; // because copy each filename here
67
68 // want special output...
69 if (close(0)) { fprintf(stderr, "Couldn't close 0\n"); exit(1); }
70 if (open("/dev/zero", O_RDONLY) != 0) {fprintf(stderr, "Couldn't reopen stdin from /dev/zero\n"); exit(1); }
71 if (close(2)) { fprintf(stderr, "Couldn't close 2\n"); exit(1); }
72 if (! dup(1)) { fprintf(stderr, "Couldnt redirect stderr to stdout\n"); exit(1); }
73
74 /* Make sure floppy device name is up to date */
75 safe_system ("/usr/sbin/updfstab");
76
77 /* Darren Critchley - check for floppy disk in disk drive before continuing */
78 snprintf (command, STRING_SIZE-1, "dd if=%s of=/dev/null bs=1k count=1 2> /dev/null", floppy_dev);
79 if (safe_system(command)) {
80 perror( "Error: No floppy in drive or bad floppy in drive" );
81 exit(1);
82 }
83
84 /* Clearing disk */
85 snprintf (command, STRING_SIZE-1, "/bin/dd if=/dev/zero of=%s bs=1k 2> /dev/null", floppy_dev);
86 safe_system (command);
87
88 /* Start tarring files to floppy */
89 snprintf (command, COMMAND_SIZE-1, "/bin/tar -X " CONFIG_ROOT"/backup/exclude.system "
90 "-X " CONFIG_ROOT"/backup/exclude.user "
91 "-C / -cvzf %s "
92 "-T " CONFIG_ROOT"/backup/include.user ",
93 floppy_dev);
94 /* add include.system file content to 'command' */
95 if (catlist(CONFIG_ROOT "/backup/include.system", command)) {
96 fprintf(stderr, "Couldn't open backup system include file\n");
97 exit (1);
98 }
99 safe_system (command);
100
101 /* Now check it */
102 snprintf (command, STRING_SIZE-1,"/bin/echo '<b>Checking</b>'; /bin/tar -tzf %s" , floppy_dev);
103 safe_system (command);
104
105 exit(0);
106 }
107
108
109 // Just verify that root password is ok
110 int checkrootpass (char* passwd) {
111
112 struct passwd *pw;
113 struct spwd *spwd;
114
115 if ((pw = getpwnam("root")) == NULL) {
116 return (0); // root unknown....!
117 }
118
119 // get shadowed password
120 spwd = getspnam("root");
121
122 //and use it in right place
123 if (spwd)
124 pw->pw_passwd = spwd->sp_pwdp;
125
126 return (strcmp ( crypt(passwd, pw->pw_passwd), //encrypt cleartext
127 pw->pw_passwd) == 0 //compare to encrypted version
128 ) ? 1 : 0; // true or false
129 }
130
131
132 int main (int argc, char *argv[]) {
133 char command[STRING_SIZE];
134
135 if (argc < 3) { // at least two args always needed, avoid some testing.
136 fprintf (stderr, "Err %s: used from cgi only !\n", argv[0]);
137 exit (1);
138 }
139
140 if (!initsetuid()){
141 fprintf (stderr, "Err %s: cannot setuid !\n", argv[0]);
142 exit (1);
143 }
144
145 // save on normal floppy for use during reinstall ONLY
146 if ( (strcmp(argv[1],"-savecfg" ) == 0) &&
147 (strcmp(argv[2],"floppy") == 0) )
148 savecfg_floppy("/dev/floppy"); // to do: mount usb floppy....
149
150 if ( (strcmp(argv[1],"-proc" ) == 0) &&
151 (strcmp(argv[2],"partitions") == 0) ) { // issue cat /proc/partitions
152
153 int fi;
154 if ( (fi = open("/proc/partitions", O_RDONLY))==-1) exit (1); // cannot open file
155 char string[STRING_SIZE];
156 int count;
157 while ((count = read(fi, string, STRING_SIZE))) {
158 write (1, string, count);
159 }
160 close (fi);
161 exit (0);
162 }
163
164 // output result of 'glob' function
165 if ( (strcmp(argv[1],"-glob" ) == 0)) {
166 glob_t g;
167 if (glob (argv[2],0,NULL,&g) == 0) {
168 char** pstr = g.gl_pathv; // base array
169 while (*pstr) { // while not NULL
170 printf ("%s\n", *pstr); // pstr is a pointer to array of char*
171 pstr++; // next pointer
172 }
173 globfree (&g);
174 }
175 exit (0);
176 }
177
178 // tell if the backup.key is present
179 if ( (strcmp(argv[1],"-key" ) == 0) &&
180 (strcmp(argv[2],"exist") == 0) ) { // check key existence
181 if ( !(file_exists(BACKUP_KEY)) ) {
182 fprintf (stderr, "Err %s: backup key "BACKUP_KEY" does not exist !\n", argv[0]);
183 exit (ERR_KEY);
184 }
185 exit (0);
186 }
187
188 // cat the backup.key, for saving it
189 if ( strcmp(argv[1],"-keycat" ) == 0) {
190 if (! checkrootpass (argv[2])) exit (1); // but only if root pw provided
191 int fi;
192 if ( (fi = open(BACKUP_KEY, O_RDONLY))==-1) exit (1); // cannot open file
193 char string[STRING_SIZE];
194 int count;
195 while ((count = read(fi, string, STRING_SIZE))) {
196 write (1, string, count);
197 }
198 close (fi);
199 exit (0);
200 }
201
202 // generate a new backup.key ONLY if inexistant
203 if ( (strcmp(argv[1],"-key" ) == 0) &&
204 (strcmp(argv[2],"new") == 0) ) {
205 if ( (file_exists(BACKUP_KEY)) ) {
206 fprintf (stderr, "Err %s: backup key "BACKUP_KEY" already exists !\n", argv[0]);
207 exit (ERR_KEY);
208 }
209 //ok we can generate it
210 if (safe_system ("/usr/sbin/ipsec ranbits 256 > " BACKUP_KEY)) {
211 fprintf (stderr, "Err %s: couldn't create key !\n", argv[0]);
212 exit (ERR_KEY);
213 }
214 chmod(BACKUP_KEY, S_IRUSR); // protect it
215 exit (0);
216 }
217
218 // import a backup.key only if non existent
219 if ( (strcmp(argv[1],"-key" ) == 0) &&
220 (strcmp(argv[2],"import") == 0) ) {
221 if ( (file_exists(BACKUP_KEY)) ) {
222 unlink (MOUNTPOINT"/key"); // clean anyway
223 fprintf (stderr, "Err %s: backup key "BACKUP_KEY" already exists !\n", argv[0]);
224 exit (ERR_KEY);
225 }
226
227 int fi, fo;
228 if ( (fi = open(MOUNTPOINT"/key", O_RDONLY))==-1) {
229 fprintf (stderr, "Err %s: no backup key "MOUNTPOINT"/key to import !\n", argv[0]);
230 exit (ERR_KEY); // cannot open file
231 }
232
233 if ( (fo = open(BACKUP_KEY, O_WRONLY | O_CREAT ))==-1) {
234 close (fi);
235 unlink (MOUNTPOINT"/key"); // clean anyway
236 fprintf (stderr, "Err %s: backup key "BACKUP_KEY" creation error !\n", argv[0]);
237 exit (ERR_KEY);
238 }
239
240 char buffer[STRING_SIZE];
241 int count;
242 while ((count = read(fi, buffer, STRING_SIZE))) {
243 write (fo, buffer, count);
244 }
245 close (fo);
246 close (fi);
247 unlink (MOUNTPOINT"/key");
248 exit (0);
249 }
250
251 // disk functions like mount umount,...
252 if ((strspn(argv[2], LETTERS_NUMBERS ) == strlen(argv[2])) &&
253 (strlen(argv[2]) >2) && (strlen(argv[2]) <6)) {
254 if (strcmp(argv[1],"-M") == 0) { // M sda1 => mount /dev/sda1 /mountpoint
255 //safe_system("/bin/sync");
256 snprintf(command, STRING_SIZE - 1,"/bin/mount -t vfat -o,uid=99,gid=99 /dev/%s "MOUNTPOINT, argv[2]);
257 safe_system(command);
258 //safe_system("/bin/sync");
259 }else
260 if (strcmp(argv[1],"-U") == 0) { // U sda1 => umount /dev/sda1
261 //safe_system("/bin/sync");
262 snprintf(command, STRING_SIZE - 1,"/bin/umount /dev/%s", argv[2]);
263 safe_system(command);
264 safe_system("/bin/sync");
265 }else
266 if (strcmp(argv[1],"-f") == 0) { // f sda1 => mke2fs /dev/sda1
267 snprintf(command, STRING_SIZE - 1,"/sbin/mke2fs -q /dev/%s", argv[2]);
268 //safe_system(command);
269 //safe_system("/bin/sync");
270 }else
271 if (strcmp(argv[1],"-F") == 0) { // F sda => fdisk /dev/sda
272 //safe_system("/bin/sync");
273 snprintf(command, STRING_SIZE - 1,"/bin/dd if=/dev/zero of=/dev/%s count=2 bs=512", argv[2]);
274 //safe_system(command);
275 snprintf(command, STRING_SIZE - 1,"/bin/echo \"n\np\n1\n1\n\nw\nq\n\"|/sbin/fdisk /dev/%s", argv[2]);
276 //safe_system(command);
277 snprintf(command, STRING_SIZE - 1,"/sbin/mke2fs -q /dev/%s1", argv[2]); // beware of %s1
278 //safe_system(command);
279 //safe_system("/bin/sync");
280 }else {
281 fprintf (stderr, "Err %s: bad command !\n", argv[0]);
282 exit (1);
283 }
284 exit (0);
285 }else {
286 fprintf (stderr, "Err %s: bad arg !\n", argv[0]);
287 exit (1);
288 }
289 return 0;
290 }