mount_umap.c revision 1.1.1.1 1 /*
2 * Copyright (c) 1992, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software donated to Berkeley by
6 * Jan-Simon Pendry.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37 #ifndef lint
38 char copyright[] =
39 "@(#) Copyright (c) 1992, 1993, 1994\n\
40 The Regents of the University of California. All rights reserved.\n";
41 #endif /* not lint */
42
43 #ifndef lint
44 static char sccsid[] = "@(#)mount_umap.c 8.3 (Berkeley) 3/27/94";
45 #endif /* not lint */
46
47 #include <sys/param.h>
48 #include <sys/mount.h>
49 #include <sys/stat.h>
50
51 #include <miscfs/umapfs/umap.h>
52
53 #include <err.h>
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <string.h>
57 #include <unistd.h>
58
59 #include "mntopts.h"
60
61 #define ROOTUSER 0
62 /*
63 * This define controls whether any user but the superuser can own and
64 * write mapfiles. If other users can, system security can be gravely
65 * compromised. If this is not a concern, undefine SECURITY.
66 */
67 #define MAPSECURITY 1
68
69 /*
70 * This routine provides the user interface to mounting a umap layer.
71 * It takes 4 mandatory parameters. The mandatory arguments are the place
72 * where the next lower level is mounted, the place where the umap layer is to
73 * be mounted, the name of the user mapfile, and the name of the group
74 * mapfile. The routine checks the ownerships and permissions on the
75 * mapfiles, then opens and reads them. Then it calls mount(), which
76 * will, in turn, call the umap version of mount.
77 */
78
79 struct mntopt mopts[] = {
80 MOPT_STDOPTS,
81 { NULL }
82 };
83
84 void usage __P((void));
85
86 int
87 main(argc, argv)
88 int argc;
89 char *argv[];
90 {
91 static char not[] = "; not mounted.";
92 struct stat statbuf;
93 struct umap_args args;
94 FILE *fp, *gfp;
95 u_long gmapdata[GMAPFILEENTRIES][2], mapdata[MAPFILEENTRIES][2];
96 int ch, count, gnentries, mntflags, nentries;
97 char *gmapfile, *mapfile, *source, *target, buf[20];
98
99 mntflags = 0;
100 mapfile = gmapfile = NULL;
101 while ((ch = getopt(argc, argv, "g:o:u:")) != EOF)
102 switch (ch) {
103 case 'g':
104 gmapfile = optarg;
105 break;
106 case 'o':
107 getmntopts(optarg, mopts, &mntflags);
108 break;
109 case 'u':
110 mapfile = optarg;
111 break;
112 case '?':
113 default:
114 usage();
115 }
116 argc -= optind;
117 argv += optind;
118
119 if (argc != 2 || mapfile == NULL || gmapfile == NULL)
120 usage();
121
122 source = argv[0];
123 target = argv[1];
124
125 /* Read in uid mapping data. */
126 if ((fp = fopen(mapfile, "r")) == NULL)
127 err(1, "%s%s", mapfile, not);
128
129 #ifdef MAPSECURITY
130 /*
131 * Check that group and other don't have write permissions on
132 * this mapfile, and that the mapfile belongs to root.
133 */
134 if (fstat(fileno(fp), &statbuf))
135 err(1, "%s%s", mapfile, not);
136 if (statbuf.st_mode & S_IWGRP || statbuf.st_mode & S_IWOTH) {
137 strmode(statbuf.st_mode, buf);
138 err(1, "%s: improper write permissions (%s)%s",
139 mapfile, buf, not);
140 }
141 if (statbuf.st_uid != ROOTUSER)
142 errx(1, "%s does not belong to root%s", mapfile, not);
143 #endif /* MAPSECURITY */
144
145 if ((fscanf(fp, "%d\n", &nentries)) != 1)
146 errx(1, "%s: nentries not found%s", mapfile, not);
147 if (nentries > MAPFILEENTRIES)
148 errx(1,
149 "maximum number of entries is %d%s", MAPFILEENTRIES, not);
150 #if 0
151 (void)printf("reading %d entries\n", nentries);
152 #endif
153 for (count = 0; count < nentries; ++count) {
154 if ((fscanf(fp, "%lu %lu\n",
155 &(mapdata[count][0]), &(mapdata[count][1]))) != 2) {
156 if (ferror(fp))
157 err(1, "%s%s", mapfile, not);
158 if (feof(fp))
159 errx(1, "%s: unexpected end-of-file%s",
160 mapfile, not);
161 errx(1, "%s: illegal format (line %d)%s",
162 mapfile, count + 2, not);
163 }
164 #if 0
165 /* Fix a security hole. */
166 if (mapdata[count][1] == 0)
167 errx(1, "mapping id 0 not permitted (line %d)%s",
168 count + 2, not);
169 #endif
170 }
171
172 /* Read in gid mapping data. */
173 if ((gfp = fopen(gmapfile, "r")) == NULL)
174 err(1, "%s%s", gmapfile, not);
175
176 #ifdef MAPSECURITY
177 /*
178 * Check that group and other don't have write permissions on
179 * this group mapfile, and that the file belongs to root.
180 */
181 if (fstat(fileno(gfp), &statbuf))
182 err(1, "%s%s", gmapfile, not);
183 if (statbuf.st_mode & S_IWGRP || statbuf.st_mode & S_IWOTH) {
184 strmode(statbuf.st_mode, buf);
185 err(1, "%s: improper write permissions (%s)%s",
186 gmapfile, buf, not);
187 }
188 if (statbuf.st_uid != ROOTUSER)
189 errx(1, "%s does not belong to root%s", gmapfile, not);
190 #endif /* MAPSECURITY */
191
192 if ((fscanf(fp, "%d\n", &gnentries)) != 1)
193 errx(1, "nentries not found%s", gmapfile, not);
194 if (gnentries > MAPFILEENTRIES)
195 errx(1,
196 "maximum number of entries is %d%s", GMAPFILEENTRIES, not);
197 #if 0
198 (void)printf("reading %d group entries\n", gnentries);
199 #endif
200
201 for (count = 0; count < gnentries; ++count)
202 if ((fscanf(fp, "%lu %lu\n",
203 &(gmapdata[count][0]), &(gmapdata[count][1]))) != 2) {
204 if (ferror(fp))
205 err(1, "%s%s", gmapfile, not);
206 if (feof(fp))
207 errx(1, "%s: unexpected end-of-file%s",
208 gmapfile, not);
209 errx(1, "%s: illegal format (line %d)%s",
210 gmapfile, count + 2, not);
211 }
212
213
214 /* Setup mount call args. */
215 args.target = source;
216 args.nentries = nentries;
217 args.mapdata = mapdata;
218 args.gnentries = gnentries;
219 args.gmapdata = gmapdata;
220
221 if (mount(MOUNT_UMAP, argv[1], mntflags, &args))
222 err(1, NULL);
223 exit(0);
224 }
225
226 void
227 usage()
228 {
229 (void)fprintf(stderr,
230 "usage: mount_umap [-o options] -u usermap -g groupmap target_fs mount_point\n");
231 exit(1);
232 }
233