1305100Scy/* 2305100Scy * Copyright (c) 1997-2014 Erez Zadok 3305100Scy * Copyright (c) 1990 Jan-Simon Pendry 4305100Scy * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 5305100Scy * Copyright (c) 1990 The Regents of the University of California. 6305100Scy * All rights reserved. 7305100Scy * 8305100Scy * This code is derived from software contributed to Berkeley by 9305100Scy * Jan-Simon Pendry at Imperial College, London. 10305100Scy * 11305100Scy * Redistribution and use in source and binary forms, with or without 12305100Scy * modification, are permitted provided that the following conditions 13305100Scy * are met: 14305100Scy * 1. Redistributions of source code must retain the above copyright 15305100Scy * notice, this list of conditions and the following disclaimer. 16305100Scy * 2. Redistributions in binary form must reproduce the above copyright 17305100Scy * notice, this list of conditions and the following disclaimer in the 18305100Scy * documentation and/or other materials provided with the distribution. 19305100Scy * 3. Neither the name of the University nor the names of its contributors 20305100Scy * may be used to endorse or promote products derived from this software 21305100Scy * without specific prior written permission. 22305100Scy * 23305100Scy * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24305100Scy * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25305100Scy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26305100Scy * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27305100Scy * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28305100Scy * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29305100Scy * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30305100Scy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31305100Scy * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32305100Scy * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33305100Scy * SUCH DAMAGE. 34305100Scy * 35305100Scy * 36305100Scy * File: am-utils/amd/ops_udf.c 37305100Scy * 38305100Scy */ 39305100Scy 40305100Scy/* 41305100Scy * UDF file system 42305100Scy */ 43305100Scy 44305100Scy#ifdef HAVE_CONFIG_H 45305100Scy# include <config.h> 46305100Scy#endif /* HAVE_CONFIG_H */ 47305100Scy#include <am_defs.h> 48305100Scy#include <amd.h> 49305100Scy 50305100Scy/* forward definitions */ 51305100Scystatic char *udf_match(am_opts *fo); 52305100Scystatic int udf_mount(am_node *am, mntfs *mf); 53305100Scystatic int udf_umount(am_node *am, mntfs *mf); 54305100Scy 55305100Scy/* 56305100Scy * Ops structure 57305100Scy */ 58305100Scyam_ops udf_ops = 59305100Scy{ 60305100Scy "udf", 61305100Scy udf_match, 62305100Scy 0, /* udf_init */ 63305100Scy udf_mount, 64305100Scy udf_umount, 65305100Scy amfs_error_lookup_child, 66305100Scy amfs_error_mount_child, 67305100Scy amfs_error_readdir, 68305100Scy 0, /* udf_readlink */ 69305100Scy 0, /* udf_mounted */ 70305100Scy 0, /* udf_umounted */ 71305100Scy amfs_generic_find_srvr, 72305100Scy 0, /* udf_get_wchan */ 73305100Scy FS_MKMNT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */ 74305100Scy#ifdef HAVE_FS_AUTOFS 75305100Scy AUTOFS_UDF_FS_FLAGS, 76305100Scy#endif /* HAVE_FS_AUTOFS */ 77305100Scy}; 78305100Scy 79305100Scy#if defined(HAVE_UDF_ARGS_T_NOBODY_GID) || defined(HAVE_UDF_ARGS_T_NOBODY_UID) 80305100Scystatic int 81305100Scya_num(const char *s, const char *id_type) 82305100Scy{ 83305100Scy int id; 84305100Scy char *ep; 85305100Scy 86305100Scy id = strtol(s, &ep, 0); 87305100Scy if (*ep || s == ep || id < 0) { 88305100Scy plog(XLOG_ERROR, "mount_udf: unknown %s: %s", id_type, s); 89305100Scy return 0; 90305100Scy } 91305100Scy return id; 92305100Scy} 93305100Scy#endif /* defined(HAVE_UDF_ARGS_T_NOBODY_GID) || defined(HAVE_UDF_ARGS_T_NOBODY_UID) */ 94305100Scy 95305100Scy#if defined(HAVE_UDF_ARGS_T_NOBODY_GID) 96305100Scystatic gid_t 97305100Scya_gid(const char *s, const char *id_type) 98305100Scy{ 99305100Scy struct group *gr; 100305100Scy 101305100Scy if ((gr = getgrnam(s)) != NULL) 102305100Scy return gr->gr_gid; 103305100Scy return a_num(s, id_type); 104305100Scy} 105305100Scy#endif /* defined(HAVE_UDF_ARGS_T_NOBODY_GID) */ 106305100Scy 107305100Scy#if defined(HAVE_UDF_ARGS_T_NOBODY_UID) 108305100Scystatic uid_t 109305100Scya_uid(const char *s, const char *id_type) 110305100Scy{ 111305100Scy struct passwd *pw; 112305100Scy 113305100Scy if ((pw = getpwnam(s)) != NULL) 114305100Scy return pw->pw_uid; 115305100Scy return a_num(s, id_type); 116305100Scy} 117305100Scy#endif /* defined(HAVE_UDF_ARGS_T_NOBODY_UID) */ 118305100Scy 119305100Scy/* 120305100Scy * UDF needs remote filesystem. 121305100Scy */ 122305100Scystatic char * 123305100Scyudf_match(am_opts *fo) 124305100Scy{ 125305100Scy 126305100Scy if (!fo->opt_dev) { 127305100Scy plog(XLOG_USER, "udf: no source device specified"); 128305100Scy return 0; 129305100Scy } 130305100Scy dlog("UDF: mounting device \"%s\" on \"%s\"", fo->opt_dev, fo->opt_fs); 131305100Scy 132305100Scy /* 133305100Scy * Determine magic cookie to put in mtab 134305100Scy */ 135305100Scy return xstrdup(fo->opt_dev); 136305100Scy} 137305100Scy 138305100Scystatic int 139305100Scymount_udf(char *mntdir, char *fs_name, char *opts, int on_autofs) 140305100Scy{ 141305100Scy udf_args_t udf_args; 142305100Scy mntent_t mnt; 143305100Scy int flags; 144305100Scy char *str; 145305100Scy#if defined(HAVE_UDF_ARGS_T_NOBODY_UID) || defined(HAVE_UDF_ARGS_T_ANON_UID) 146305100Scy uid_t uid_nobody; 147305100Scy gid_t gid_nobody; 148305100Scy#endif /* defined(HAVE_UDF_ARGS_T_NOBODY_UID) || defined(HAVE_UDF_ARGS_T_ANON_UID) */ 149305100Scy /* 150305100Scy * Figure out the name of the file system type. 151305100Scy */ 152305100Scy MTYPE_TYPE type = MOUNT_TYPE_UDF; 153305100Scy 154305100Scy#if defined(HAVE_UDF_ARGS_T_NOBODY_UID) || defined(HAVE_UDF_ARGS_T_ANON_UID) 155305100Scy uid_nobody = a_uid("nobody", "user"); 156305100Scy if (uid_nobody == 0) { 157305100Scy plog(XLOG_ERROR, "mount_udf: invalid uid for nobody"); 158305100Scy return EPERM; 159305100Scy } 160305100Scy#endif /* defined(HAVE_UDF_ARGS_T_NOBODY_UID) || defined(HAVE_UDF_ARGS_T_ANON_UID) */ 161305100Scy 162305100Scy#if defined(HAVE_UDF_ARGS_T_NOBODY_GID) || defined(HAVE_UDF_ARGS_T_ANON_GID) 163305100Scy gid_nobody = a_gid("nobody", "group"); 164305100Scy if (gid_nobody == 0) { 165305100Scy plog(XLOG_ERROR, "mount_udf: invalid gid for nobody"); 166305100Scy return EPERM; 167305100Scy } 168305100Scy#endif /* defined(HAVE_UDF_ARGS_T_NOBODY_GID) || defined(HAVE_UDF_ARGS_T_ANON_GID) */ 169305100Scy 170305100Scy str = NULL; 171305100Scy memset((voidp) &udf_args, 0, sizeof(udf_args)); /* Paranoid */ 172305100Scy 173305100Scy /* 174305100Scy * Fill in the mount structure 175305100Scy */ 176305100Scy memset((voidp)&mnt, 0, sizeof(mnt)); 177305100Scy mnt.mnt_dir = mntdir; 178305100Scy mnt.mnt_fsname = fs_name; 179305100Scy mnt.mnt_type = MNTTAB_TYPE_UDF; 180305100Scy mnt.mnt_opts = opts; 181305100Scy 182305100Scy flags = compute_mount_flags(&mnt); 183305100Scy 184305100Scy#ifdef HAVE_UDF_ARGS_T_UDFMFLAGS 185305100Scy# if defined(MNT2_UDF_OPT_CLOSESESSION) && defined(MNTTAB_OPT_CLOSESESSION) 186305100Scy if (amu_hasmntopt(&mnt, MNTTAB_OPT_CLOSESESSION)) 187305100Scy udf_args.udfmflags |= MNT2_UDF_OPT_CLOSESESSION; 188305100Scy# endif /* defined(MNT2_UDF_OPT_CLOSESESSION) && defined(MNTTAB_OPT_CLOSESESSION) */ 189305100Scy#endif /* HAVE_UDF_ARGS_T_UDFMFLAGS */ 190305100Scy 191305100Scy#ifdef HAVE_UDF_ARGS_T_NOBODY_UID 192305100Scy udf_args.nobody_uid = uid_nobody; 193305100Scy#endif /* HAVE_UDF_ARGS_T_NOBODY_UID */ 194305100Scy 195305100Scy#ifdef HAVE_UDF_ARGS_T_NOBODY_GID 196305100Scy udf_args.nobody_gid = gid_nobody; 197305100Scy#endif /* HAVE_UDF_ARGS_T_NOBODY_GID */ 198305100Scy 199305100Scy#ifdef HAVE_UDF_ARGS_T_ANON_UID 200305100Scy udf_args.anon_uid = uid_nobody; /* default to nobody */ 201305100Scy if ((str = hasmntstr(&mnt, MNTTAB_OPT_USER)) != NULL) { 202305100Scy udf_args.anon_uid = a_uid(str, MNTTAB_OPT_USER); 203305100Scy XFREE(str); 204305100Scy } 205305100Scy#endif /* HAVE_UDF_ARGS_T_ANON_UID */ 206305100Scy 207305100Scy#ifdef HAVE_UDF_ARGS_T_ANON_GID 208305100Scy udf_args.anon_gid = gid_nobody; /* default to nobody */ 209305100Scy if ((str = hasmntstr(&mnt, MNTTAB_OPT_GROUP)) != NULL) { 210305100Scy udf_args.anon_gid = a_gid(str, MNTTAB_OPT_GROUP); 211305100Scy XFREE(str); 212305100Scy } 213305100Scy#endif /* HAVE_UDF_ARGS_T_ANON_GID */ 214305100Scy 215305100Scy#ifdef HAVE_UDF_ARGS_T_GMTOFF 216305100Scy udf_args.gmtoff = 0; 217305100Scy if ((str = hasmntstr(&mnt, MNTTAB_OPT_GMTOFF)) != NULL) { 218305100Scy udf_args.gmtoff = a_num(str, MNTTAB_OPT_GMTOFF); 219305100Scy XFREE(str); 220305100Scy } 221305100Scy#endif /* HAVE_UDF_ARGS_T_GMTOFF */ 222305100Scy 223305100Scy#ifdef HAVE_UDF_ARGS_T_SESSIONNR 224305100Scy udf_args.sessionnr = 0; 225305100Scy if ((str = hasmntstr(&mnt, MNTTAB_OPT_SESSIONNR)) != NULL) { 226305100Scy udf_args.sessionnr = a_num(str, MNTTAB_OPT_SESSIONNR); 227305100Scy XFREE(str); 228305100Scy } 229305100Scy#endif /* HAVE_UDF_ARGS_T_SESSIONNR */ 230305100Scy 231305100Scy#ifdef HAVE_UDF_ARGS_T_VERSION 232305100Scy# ifdef UDFMNT_VERSION 233305100Scy udf_args.version = UDFMNT_VERSION; 234305100Scy# endif /* UDFMNT_VERSION */ 235305100Scy#endif /* HAVE_UDF_ARGS_T_VERSION */ 236305100Scy 237308493Scy#ifdef HAVE_UDF_ARGS_T_FSPEC 238305100Scy udf_args.fspec = fs_name; 239305100Scy#endif /* HAVE_UFS_ARGS_T_FSPEC */ 240305100Scy 241305100Scy /* 242305100Scy * Call generic mount routine 243305100Scy */ 244305100Scy return mount_fs(&mnt, flags, (caddr_t)&udf_args, 0, type, 0, NULL, 245305100Scy mnttab_file_name, on_autofs); 246305100Scy} 247305100Scy 248305100Scystatic int 249305100Scyudf_mount(am_node *am, mntfs *mf) 250305100Scy{ 251305100Scy int on_autofs; 252305100Scy int error; 253305100Scy 254305100Scy on_autofs = mf->mf_flags & MFF_ON_AUTOFS; 255305100Scy error = mount_udf(mf->mf_mount, mf->mf_info, mf->mf_mopts, on_autofs); 256305100Scy if (error) { 257305100Scy errno = error; 258305100Scy plog(XLOG_ERROR, "mount_udf: %m"); 259305100Scy return error; 260305100Scy } 261305100Scy return 0; 262305100Scy} 263305100Scy 264305100Scy 265305100Scystatic int 266305100Scyudf_umount(am_node *am, mntfs *mf) 267305100Scy{ 268305100Scy int unmount_flags; 269305100Scy 270305100Scy unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0; 271305100Scy return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags); 272305100Scy} 273