Commit | Line | Data |
---|---|---|
bcd4439c JH |
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 | * | |
5f8711c1 | 11 | * @(#)mount_umap.c 5.2 (Berkeley) %G% |
bcd4439c JH |
12 | */ |
13 | ||
14 | #include <sys/param.h> | |
15 | #include <sys/mount.h> | |
5f8711c1 JH |
16 | #include <sys/stat.h> |
17 | #include <sys/types.h> | |
18 | #include <umapfs/umap.h> | |
bcd4439c JH |
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 | ||
5f8711c1 JH |
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 | ||
bcd4439c JH |
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]; | |
bcd4439c JH |
55 | char *fs_type="umap"; |
56 | char *source, *target; | |
57 | char *mapfile, *gmapfile; | |
5f8711c1 | 58 | FILE *fp, *gfp, *fopen(); |
bcd4439c | 59 | struct stat statbuf; |
5f8711c1 | 60 | struct umap_args args; |
bcd4439c JH |
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 | ||
5f8711c1 | 83 | #ifdef MAPSECURITY |
bcd4439c JH |
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 | } | |
5f8711c1 | 107 | #endif MAPSECURITY |
bcd4439c JH |
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 | else | |
121 | printf("reading %d entries\n", nentries); | |
122 | ||
123 | for(count = 0; count<nentries;count++) { | |
124 | if ((fscanf(fp, "%d %d\n", &(mapdata[count][0]), | |
125 | &(mapdata[count][1]))) == EOF) { | |
126 | printf("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 | printf("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 | { | |
144 | printf("mount_umap: can't stat %s\n",gmapfile); | |
145 | perror("mount_umap: error status"); | |
146 | notMounted(); | |
147 | } | |
148 | ||
149 | if (statbuf.st_mode & S_IWGRP || statbuf.st_mode & S_IWOTH) | |
150 | { | |
151 | printf("mount_umap: Improper write permissions for %s, mode %x\n", | |
152 | gmapfile, statbuf.st_mode); | |
153 | } | |
154 | ||
155 | if ( statbuf.st_uid != ROOTUSER ) | |
156 | { | |
157 | printf("mount_umap: %s does not belong to root\n", mapfile); | |
158 | } | |
159 | ||
160 | /* | |
161 | * Read in gid mapping data. | |
162 | */ | |
163 | if ((gfp = fopen(gmapfile, "r")) == NULL) { | |
164 | printf("mount_umap: can't open %s\n",gmapfile); | |
165 | notMounted(); | |
166 | } | |
167 | fscanf(gfp, "%d\n", &gnentries); | |
168 | if (gnentries > GMAPFILEENTRIES) | |
169 | printf("mount_umap: gnentries exceeds maximum\n"); | |
170 | else | |
171 | printf("reading %d group entries\n", gnentries); | |
172 | ||
173 | for(count = 0; count<gnentries;count++) { | |
174 | if ((fscanf(gfp, "%d %d\n", &(gmapdata[count][0]), | |
175 | &(gmapdata[count][1]))) == EOF) { | |
176 | printf("mount_umap: %s, premature eof on group mapfile\n", | |
177 | gmapfile); | |
178 | notMounted(); | |
179 | } | |
180 | } | |
181 | ||
182 | ||
183 | /* | |
184 | * Setup mount call args. | |
185 | */ | |
5f8711c1 | 186 | args.target = source; |
bcd4439c JH |
187 | args.nentries = nentries; |
188 | args.mapdata = &(mapdata[0][0]); | |
189 | args.gnentries = gnentries; | |
190 | args.gmapdata = &(gmapdata[0][0]); | |
191 | ||
5f8711c1 JH |
192 | printf("calling mount_umap(%s,%d,<%s>)\n",target,mntflags, |
193 | args.target); | |
bcd4439c JH |
194 | if (mount(MOUNT_UMAP, argv[1], mntflags, &args)) { |
195 | (void)fprintf(stderr, "mount_umap: %s\n", strerror(errno)); | |
196 | } | |
197 | exit(0); | |
198 | } | |
199 | ||
200 | void | |
201 | usage() | |
202 | { | |
203 | (void)fprintf(stderr, | |
5f8711c1 | 204 | "usage: mount_umap [ -F fsoptions ] target_fs mount_point user_mapfile group_mapfile\n"); |
bcd4439c JH |
205 | exit(1); |
206 | } | |
207 | ||
5f8711c1 | 208 | int |
bcd4439c JH |
209 | notMounted() |
210 | { | |
211 | (void)fprintf(stderr, "file system not mounted\n"); | |
212 | } |