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