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