xref: /original-bsd/sbin/mount_umap/mount_umap.c (revision 909c03fb)
1 /*
2  * Copyright (c) 1992 The Regents of the University of California
3  * Copyright (c) 1990, 1992 Jan-Simon Pendry
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	5.4 (Berkeley) 07/12/92
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         int mapdata[MAPFILEENTRIES][2];
54         int 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 	{
90 		printf("mount_umap: can't stat %s\n",mapfile);
91 		perror("mount_umap: error status");
92 		notMounted();
93 	}
94 
95 	if (statbuf.st_mode & S_IWGRP || statbuf.st_mode & S_IWOTH)
96 	{
97 		printf("mount_umap: Improper write permissions for %s, mode %x\n",
98 		    mapfile, statbuf.st_mode);
99 		notMounted();
100 	}
101 
102 	if ( statbuf.st_uid != ROOTUSER )
103 	{
104 		printf("mount_umap: %s does not belong to root\n", mapfile);
105 		notMounted();
106 	}
107 #endif MAPSECURITY
108 
109 	/*
110 	 * Read in uid mapping data.
111 	 */
112 
113 	if ((fp = fopen(mapfile, "r")) == NULL) {
114 		printf("mount_umap: can't open %s\n",mapfile);
115 		notMounted();
116 	}
117 	fscanf(fp, "%d\n", &nentries);
118 	if (nentries > MAPFILEENTRIES)
119 		printf("mount_umap: nentries exceeds maximum\n");
120 #if 0
121 	else
122 		printf("reading %d entries\n", nentries);
123 #endif
124 
125 	for(count = 0; count<nentries;count++) {
126 		if ((fscanf(fp, "%d %d\n", &(mapdata[count][0]),
127 		    &(mapdata[count][1]))) == EOF) {
128 			printf("mount_umap: %s, premature eof\n",mapfile);
129 			notMounted();
130 		}
131 #if 0
132 		/* fix a security hole */
133 		if (mapdata[count][1] == 0) {
134 			printf("mount_umap: Mapping to UID 0 not allowed\n");
135 			notMounted();
136 		}
137 #endif
138 	}
139 
140 	/*
141 	 * Check that group and other don't have write permissions on
142 	 * this group mapfile, and that the file belongs to root.
143 	 */
144 	if ( stat(gmapfile, &statbuf) )
145 	{
146 		printf("mount_umap: can't stat %s\n",gmapfile);
147 		perror("mount_umap: error status");
148 		notMounted();
149 	}
150 
151 	if (statbuf.st_mode & S_IWGRP || statbuf.st_mode & S_IWOTH)
152 	{
153 		printf("mount_umap: Improper write permissions for %s, mode %x\n",
154 		    gmapfile, statbuf.st_mode);
155 	}
156 
157 	if ( statbuf.st_uid != ROOTUSER )
158 	{
159 		printf("mount_umap: %s does not belong to root\n", mapfile);
160 	}
161 
162 	/*
163 	 * Read in gid mapping data.
164 	 */
165 	if ((gfp = fopen(gmapfile, "r")) == NULL) {
166 		printf("mount_umap: can't open %s\n",gmapfile);
167 		notMounted();
168 	}
169 	fscanf(gfp, "%d\n", &gnentries);
170 	if (gnentries > GMAPFILEENTRIES)
171 		printf("mount_umap: gnentries exceeds maximum\n");
172 #if 0
173 	else
174 		printf("reading %d group entries\n", gnentries);
175 #endif
176 
177 	for(count = 0; count<gnentries;count++) {
178 		if ((fscanf(gfp, "%d %d\n", &(gmapdata[count][0]),
179 		    &(gmapdata[count][1]))) == EOF) {
180 			printf("mount_umap: %s, premature eof on group mapfile\n",
181 			    gmapfile);
182 			notMounted();
183 		}
184 	}
185 
186 
187 	/*
188 	 * Setup mount call args.
189 	 */
190 	args.target = source;
191 	args.nentries = nentries;
192 	args.mapdata = &(mapdata[0][0]);
193 	args.gnentries = gnentries;
194 	args.gmapdata = &(gmapdata[0][0]);
195 
196 #if 0
197 	printf("calling mount_umap(%s,%d,<%s>)\n",target,mntflags,
198 	       args.target);
199 #endif
200 	if (mount(MOUNT_UMAP, argv[1], mntflags, &args)) {
201 		(void)fprintf(stderr, "mount_umap: %s\n", strerror(errno));
202 	}
203 	exit(0);
204 }
205 
206 void
207 usage()
208 {
209 	(void)fprintf(stderr,
210 	    "usage: mount_umap [ -F fsoptions ] target_fs mount_point user_mapfile group_mapfile\n");
211 	exit(1);
212 }
213 
214 int
215 notMounted()
216 {
217 	(void)fprintf(stderr, "file system not mounted\n");
218 }
219