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