* Copyright (c) 1992, 1993, 1994
* The Regents of the University of California. All rights reserved.
* This code is derived from software donated to Berkeley by
* %sccs.include.redist.c%
"@(#) Copyright (c) 1992, 1993, 1994\n\
The Regents of the University of California. All rights reserved.\n";
static char sccsid
[] = "@(#)mount_umap.c 8.3 (Berkeley) %G%";
#include <miscfs/umapfs/umap.h>
* This define controls whether any user but the superuser can own and
* write mapfiles. If other users can, system security can be gravely
* compromised. If this is not a concern, undefine SECURITY.
* This routine provides the user interface to mounting a umap layer.
* It takes 4 mandatory parameters. The mandatory arguments are the place
* where the next lower level is mounted, the place where the umap layer is to
* be mounted, the name of the user mapfile, and the name of the group
* mapfile. The routine checks the ownerships and permissions on the
* mapfiles, then opens and reads them. Then it calls mount(), which
* will, in turn, call the umap version of mount.
struct mntopt mopts
[] = {
static char not[] = "; not mounted.";
u_long gmapdata
[GMAPFILEENTRIES
][2], mapdata
[MAPFILEENTRIES
][2];
int ch
, count
, gnentries
, mntflags
, nentries
;
char *gmapfile
, *mapfile
, *source
, *target
, buf
[20];
mapfile
= gmapfile
= NULL
;
while ((ch
= getopt(argc
, argv
, "g:o:u:")) != EOF
)
getmntopts(optarg
, mopts
, &mntflags
);
if (argc
!= 2 || mapfile
== NULL
|| gmapfile
== NULL
)
/* Read in uid mapping data. */
if ((fp
= fopen(mapfile
, "r")) == NULL
)
err(1, "%s%s", mapfile
, not);
* Check that group and other don't have write permissions on
* this mapfile, and that the mapfile belongs to root.
if (fstat(fileno(fp
), &statbuf
))
err(1, "%s%s", mapfile
, not);
if (statbuf
.st_mode
& S_IWGRP
|| statbuf
.st_mode
& S_IWOTH
) {
strmode(statbuf
.st_mode
, buf
);
err(1, "%s: improper write permissions (%s)%s",
if (statbuf
.st_uid
!= ROOTUSER
)
errx(1, "%s does not belong to root%s", mapfile
, not);
if ((fscanf(fp
, "%d\n", &nentries
)) != 1)
errx(1, "%s: nentries not found%s", mapfile
, not);
if (nentries
> MAPFILEENTRIES
)
"maximum number of entries is %d%s", MAPFILEENTRIES
, not);
(void)printf("reading %d entries\n", nentries
);
for (count
= 0; count
< nentries
; ++count
) {
if ((fscanf(fp
, "%lu %lu\n",
&(mapdata
[count
][0]), &(mapdata
[count
][1]))) != 2) {
err(1, "%s%s", mapfile
, not);
errx(1, "%s: unexpected end-of-file%s",
errx(1, "%s: illegal format (line %d)%s",
mapfile
, count
+ 2, not);
/* Fix a security hole. */
if (mapdata
[count
][1] == 0)
errx(1, "mapping id 0 not permitted (line %d)%s",
/* Read in gid mapping data. */
if ((gfp
= fopen(gmapfile
, "r")) == NULL
)
err(1, "%s%s", gmapfile
, not);
* Check that group and other don't have write permissions on
* this group mapfile, and that the file belongs to root.
if (fstat(fileno(gfp
), &statbuf
))
err(1, "%s%s", gmapfile
, not);
if (statbuf
.st_mode
& S_IWGRP
|| statbuf
.st_mode
& S_IWOTH
) {
strmode(statbuf
.st_mode
, buf
);
err(1, "%s: improper write permissions (%s)%s",
if (statbuf
.st_uid
!= ROOTUSER
)
errx(1, "%s does not belong to root%s", gmapfile
, not);
if ((fscanf(fp
, "%d\n", &gnentries
)) != 1)
errx(1, "nentries not found%s", gmapfile
, not);
if (gnentries
> MAPFILEENTRIES
)
"maximum number of entries is %d%s", GMAPFILEENTRIES
, not);
(void)printf("reading %d group entries\n", gnentries
);
for (count
= 0; count
< gnentries
; ++count
)
if ((fscanf(fp
, "%lu %lu\n",
&(gmapdata
[count
][0]), &(gmapdata
[count
][1]))) != 2) {
err(1, "%s%s", gmapfile
, not);
errx(1, "%s: unexpected end-of-file%s",
errx(1, "%s: illegal format (line %d)%s",
gmapfile
, count
+ 2, not);
/* Setup mount call args. */
args
.nentries
= nentries
;
args
.gnentries
= gnentries
;
args
.gmapdata
= gmapdata
;
if (mount(MOUNT_UMAP
, argv
[1], mntflags
, &args
))
"usage: mount_umap [-o options] -u usermap -g groupmap target_fs mount_point\n");