modified showVersion() to show current version instead of an hardcoded
[util-vserver.git] / util-vserver / src / secure-mount.c
1 // $Id$    --*- c++ -*--
2
3 // Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 //  
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; version 2 of the License.
8 //  
9 // This program 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 this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18
19   // secure-mount <chroot-base> <src> <dst>
20   //
21   // mounts <src> into the chroot <chroot-base> at destination <dst> in a way
22   // that prevents symlink attacks
23
24   // algorithm:
25   //   enter chroot
26   //     mount tmpfs-directory
27   //   leave chroot
28   //   mount --bind <src> tmpfs
29   //   enter chroot
30   //     mount --move tmpfs <dst>
31
32 #ifdef HAVE_CONFIG_H
33 #  include <config.h>
34 #endif
35
36 #define VERSION_COPYRIGHT_YEAR          "2003"
37 #define VERSION_COPYRIGHT_AUTHOR        "Enrico Scholz"
38 #include "util.h"
39
40 #include <unistd.h>
41 #include <sys/mount.h>
42 #include <linux/fs.h>
43 #include <sys/types.h>
44 #include <sys/stat.h>
45 #include <fcntl.h>
46 #include <string.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49
50
51 #define MNTPOINT        "/etc"
52
53 static void
54 showHelp(int fd, char const *cmd, int res)
55 {
56   WRITE_MSG(fd, "Usage:  ");
57   WRITE_STR(fd, cmd);
58   WRITE_MSG(fd,
59             " <chroot-base> <src> <dst>\n\n"
60             "Please report bugs to " PACKAGE_BUGREPORT "\n");
61
62   exit(res);
63 }
64
65 static void
66 showVersion()
67 {
68   WRITE_MSG(1,
69             "secure-mount " VERSION " -- secure mounting of directories in chroots\n"
70             "This program is part of " PACKAGE_STRING "\n"
71             "Copyright (C) 2003 Enrico Scholz\n"
72             VERSION_COPYRIGHT_DISCLAIMER);
73   exit(0);
74 }
75
76 int main(int argc, char *argv[])
77 {
78   int   fd = open("/", O_RDONLY);
79     // HACK: sanity checks should be done before declaration, but this does
80     // not work with C89 compilers
81   char  path[strlen(argc==1 ? "" : argv[1]) + sizeof(MNTPOINT) + 3];
82
83   if (argc>=2) {
84     if (!strcmp(argv[1], "--help"))    showHelp(1, argv[0], 0);
85     if (!strcmp(argv[1], "--version")) showVersion();
86   }
87   if (argc!=4) {
88     WRITE_MSG(2, "Bad parameter count; use --help for further information.\n");
89     exit(255);
90   }
91
92   if (chroot(argv[1]) == -1 ||
93       chdir("/")      == -1) {
94     perror("chroot()/chdir()");
95     exit(1);
96   }
97   
98   if (mount("none", MNTPOINT, "tmpfs", 0, "size=4k")==-1) {
99     perror("mount()");
100     exit(1);
101   }
102
103   if (mkdir(MNTPOINT "/x",0600) == -1) {
104     perror("mkdir()/fchdir()");
105     goto err1;
106   }
107   
108   if (fchdir(fd)      == -1 ||
109       chroot(".")     == -1) {
110     perror("chroot()");
111     goto err2;
112   }
113
114   strcpy(path, argv[1]);
115   strcat(path, MNTPOINT "/x");
116   
117   if (mount(argv[2], path, "", MS_BIND, 0)==-1) {
118     perror("mount()");
119     goto err3;
120   }
121
122   if (chroot(argv[1]) == -1) {
123     perror("chroot()");
124     goto err4;
125   }
126
127   if (chdir("/")      == -1 ||
128       mount(MNTPOINT "/x", argv[3], "", MS_MOVE, 0) == -1) {
129     perror("chdir()/mount()");
130     goto err5;
131   }
132
133   if (umount(MNTPOINT) == -1) {
134     perror("umount()");
135   }
136
137   return 0;
138
139   err5:
140   err4:
141   if (umount(path)==-1)   perror("umount(path)");
142   
143   err3:
144   if (chdir(argv[1])==-1) {
145     perror("chdir()");
146     return 1;
147   }
148
149   err2:
150   err1:
151   if (umount("mnt")==-1)  perror("umount(\"mnt\")");
152
153   return 1;
154 }