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 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 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