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