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