Converted from null layer to umap layer
[unix-history] / usr / src / sbin / mount_umap / mount_umap.c
CommitLineData
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
26void 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
46int
47main(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
200void
201usage()
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 208int
bcd4439c
JH
209notMounted()
210{
211 (void)fprintf(stderr, "file system not mounted\n");
212}