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