mount_umap.c revision 1.1.1.1 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.1.1 mycroft static char sccsid[] = "@(#)mount_umap.c 8.3 (Berkeley) 3/27/94";
45 1.1 mycroft #endif /* not lint */
46 1.1 mycroft
47 1.1 mycroft #include <sys/param.h>
48 1.1 mycroft #include <sys/mount.h>
49 1.1 mycroft #include <sys/stat.h>
50 1.1 mycroft
51 1.1 mycroft #include <miscfs/umapfs/umap.h>
52 1.1 mycroft
53 1.1 mycroft #include <err.h>
54 1.1 mycroft #include <stdio.h>
55 1.1 mycroft #include <stdlib.h>
56 1.1 mycroft #include <string.h>
57 1.1 mycroft #include <unistd.h>
58 1.1 mycroft
59 1.1 mycroft #include "mntopts.h"
60 1.1 mycroft
61 1.1 mycroft #define ROOTUSER 0
62 1.1 mycroft /*
63 1.1 mycroft * This define controls whether any user but the superuser can own and
64 1.1 mycroft * write mapfiles. If other users can, system security can be gravely
65 1.1 mycroft * compromised. If this is not a concern, undefine SECURITY.
66 1.1 mycroft */
67 1.1 mycroft #define MAPSECURITY 1
68 1.1 mycroft
69 1.1 mycroft /*
70 1.1 mycroft * This routine provides the user interface to mounting a umap layer.
71 1.1 mycroft * It takes 4 mandatory parameters. The mandatory arguments are the place
72 1.1 mycroft * where the next lower level is mounted, the place where the umap layer is to
73 1.1 mycroft * be mounted, the name of the user mapfile, and the name of the group
74 1.1 mycroft * mapfile. The routine checks the ownerships and permissions on the
75 1.1 mycroft * mapfiles, then opens and reads them. Then it calls mount(), which
76 1.1 mycroft * will, in turn, call the umap version of mount.
77 1.1 mycroft */
78 1.1 mycroft
79 1.1 mycroft struct mntopt mopts[] = {
80 1.1 mycroft MOPT_STDOPTS,
81 1.1 mycroft { NULL }
82 1.1 mycroft };
83 1.1 mycroft
84 1.1 mycroft void usage __P((void));
85 1.1 mycroft
86 1.1 mycroft int
87 1.1 mycroft main(argc, argv)
88 1.1 mycroft int argc;
89 1.1 mycroft char *argv[];
90 1.1 mycroft {
91 1.1 mycroft static char not[] = "; not mounted.";
92 1.1 mycroft struct stat statbuf;
93 1.1 mycroft struct umap_args args;
94 1.1 mycroft FILE *fp, *gfp;
95 1.1 mycroft u_long gmapdata[GMAPFILEENTRIES][2], mapdata[MAPFILEENTRIES][2];
96 1.1 mycroft int ch, count, gnentries, mntflags, nentries;
97 1.1 mycroft char *gmapfile, *mapfile, *source, *target, buf[20];
98 1.1 mycroft
99 1.1 mycroft mntflags = 0;
100 1.1 mycroft mapfile = gmapfile = NULL;
101 1.1 mycroft while ((ch = getopt(argc, argv, "g:o:u:")) != EOF)
102 1.1 mycroft switch (ch) {
103 1.1 mycroft case 'g':
104 1.1 mycroft gmapfile = optarg;
105 1.1 mycroft break;
106 1.1 mycroft case 'o':
107 1.1 mycroft getmntopts(optarg, mopts, &mntflags);
108 1.1 mycroft break;
109 1.1 mycroft case 'u':
110 1.1 mycroft mapfile = optarg;
111 1.1 mycroft break;
112 1.1 mycroft case '?':
113 1.1 mycroft default:
114 1.1 mycroft usage();
115 1.1 mycroft }
116 1.1 mycroft argc -= optind;
117 1.1 mycroft argv += optind;
118 1.1 mycroft
119 1.1 mycroft if (argc != 2 || mapfile == NULL || gmapfile == NULL)
120 1.1 mycroft usage();
121 1.1 mycroft
122 1.1 mycroft source = argv[0];
123 1.1 mycroft target = argv[1];
124 1.1 mycroft
125 1.1 mycroft /* Read in uid mapping data. */
126 1.1 mycroft if ((fp = fopen(mapfile, "r")) == NULL)
127 1.1 mycroft err(1, "%s%s", mapfile, not);
128 1.1 mycroft
129 1.1 mycroft #ifdef MAPSECURITY
130 1.1 mycroft /*
131 1.1 mycroft * Check that group and other don't have write permissions on
132 1.1 mycroft * this mapfile, and that the mapfile belongs to root.
133 1.1 mycroft */
134 1.1 mycroft if (fstat(fileno(fp), &statbuf))
135 1.1 mycroft err(1, "%s%s", mapfile, not);
136 1.1 mycroft if (statbuf.st_mode & S_IWGRP || statbuf.st_mode & S_IWOTH) {
137 1.1 mycroft strmode(statbuf.st_mode, buf);
138 1.1 mycroft err(1, "%s: improper write permissions (%s)%s",
139 1.1 mycroft mapfile, buf, not);
140 1.1 mycroft }
141 1.1 mycroft if (statbuf.st_uid != ROOTUSER)
142 1.1 mycroft errx(1, "%s does not belong to root%s", mapfile, not);
143 1.1 mycroft #endif /* MAPSECURITY */
144 1.1 mycroft
145 1.1 mycroft if ((fscanf(fp, "%d\n", &nentries)) != 1)
146 1.1 mycroft errx(1, "%s: nentries not found%s", mapfile, not);
147 1.1 mycroft if (nentries > MAPFILEENTRIES)
148 1.1 mycroft errx(1,
149 1.1 mycroft "maximum number of entries is %d%s", MAPFILEENTRIES, not);
150 1.1 mycroft #if 0
151 1.1 mycroft (void)printf("reading %d entries\n", nentries);
152 1.1 mycroft #endif
153 1.1 mycroft for (count = 0; count < nentries; ++count) {
154 1.1 mycroft if ((fscanf(fp, "%lu %lu\n",
155 1.1 mycroft &(mapdata[count][0]), &(mapdata[count][1]))) != 2) {
156 1.1 mycroft if (ferror(fp))
157 1.1 mycroft err(1, "%s%s", mapfile, not);
158 1.1 mycroft if (feof(fp))
159 1.1 mycroft errx(1, "%s: unexpected end-of-file%s",
160 1.1 mycroft mapfile, not);
161 1.1 mycroft errx(1, "%s: illegal format (line %d)%s",
162 1.1 mycroft mapfile, count + 2, not);
163 1.1 mycroft }
164 1.1 mycroft #if 0
165 1.1 mycroft /* Fix a security hole. */
166 1.1 mycroft if (mapdata[count][1] == 0)
167 1.1 mycroft errx(1, "mapping id 0 not permitted (line %d)%s",
168 1.1 mycroft count + 2, not);
169 1.1 mycroft #endif
170 1.1 mycroft }
171 1.1 mycroft
172 1.1 mycroft /* Read in gid mapping data. */
173 1.1 mycroft if ((gfp = fopen(gmapfile, "r")) == NULL)
174 1.1 mycroft err(1, "%s%s", gmapfile, not);
175 1.1 mycroft
176 1.1 mycroft #ifdef MAPSECURITY
177 1.1 mycroft /*
178 1.1 mycroft * Check that group and other don't have write permissions on
179 1.1 mycroft * this group mapfile, and that the file belongs to root.
180 1.1 mycroft */
181 1.1 mycroft if (fstat(fileno(gfp), &statbuf))
182 1.1 mycroft err(1, "%s%s", gmapfile, not);
183 1.1 mycroft if (statbuf.st_mode & S_IWGRP || statbuf.st_mode & S_IWOTH) {
184 1.1 mycroft strmode(statbuf.st_mode, buf);
185 1.1 mycroft err(1, "%s: improper write permissions (%s)%s",
186 1.1 mycroft gmapfile, buf, not);
187 1.1 mycroft }
188 1.1 mycroft if (statbuf.st_uid != ROOTUSER)
189 1.1 mycroft errx(1, "%s does not belong to root%s", gmapfile, not);
190 1.1 mycroft #endif /* MAPSECURITY */
191 1.1 mycroft
192 1.1.1.1 mycroft if ((fscanf(fp, "%d\n", &gnentries)) != 1)
193 1.1 mycroft errx(1, "nentries not found%s", gmapfile, not);
194 1.1 mycroft if (gnentries > MAPFILEENTRIES)
195 1.1 mycroft errx(1,
196 1.1 mycroft "maximum number of entries is %d%s", GMAPFILEENTRIES, not);
197 1.1 mycroft #if 0
198 1.1 mycroft (void)printf("reading %d group entries\n", gnentries);
199 1.1 mycroft #endif
200 1.1 mycroft
201 1.1 mycroft for (count = 0; count < gnentries; ++count)
202 1.1.1.1 mycroft if ((fscanf(fp, "%lu %lu\n",
203 1.1 mycroft &(gmapdata[count][0]), &(gmapdata[count][1]))) != 2) {
204 1.1.1.1 mycroft if (ferror(fp))
205 1.1 mycroft err(1, "%s%s", gmapfile, not);
206 1.1.1.1 mycroft if (feof(fp))
207 1.1 mycroft errx(1, "%s: unexpected end-of-file%s",
208 1.1 mycroft gmapfile, not);
209 1.1 mycroft errx(1, "%s: illegal format (line %d)%s",
210 1.1 mycroft gmapfile, count + 2, not);
211 1.1 mycroft }
212 1.1 mycroft
213 1.1 mycroft
214 1.1 mycroft /* Setup mount call args. */
215 1.1 mycroft args.target = source;
216 1.1 mycroft args.nentries = nentries;
217 1.1 mycroft args.mapdata = mapdata;
218 1.1 mycroft args.gnentries = gnentries;
219 1.1 mycroft args.gmapdata = gmapdata;
220 1.1 mycroft
221 1.1 mycroft if (mount(MOUNT_UMAP, argv[1], mntflags, &args))
222 1.1 mycroft err(1, NULL);
223 1.1 mycroft exit(0);
224 1.1 mycroft }
225 1.1 mycroft
226 1.1 mycroft void
227 1.1 mycroft usage()
228 1.1 mycroft {
229 1.1 mycroft (void)fprintf(stderr,
230 1.1 mycroft "usage: mount_umap [-o options] -u usermap -g groupmap target_fs mount_point\n");
231 1.1 mycroft exit(1);
232 1.1 mycroft }
233