4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * CDDL HEADER START
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * The contents of this file are subject to the terms of the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Common Development and Distribution License (the "License").
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * You may not use this file except in compliance with the License.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * or http://www.opensolaris.org/os/licensing.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * See the License for the specific language governing permissions
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * and limitations under the License.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * When distributing Covered Code, include this CDDL HEADER in each
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * If applicable, add the following below this CDDL HEADER, with the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * fields enclosed by brackets "[]" replaced with your own identifying
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * information: Portions Copyright [yyyy] [name of copyright owner]
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * CDDL HEADER END
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Use is subject to license terms.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * smbfs umount
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <stdio.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <stdlib.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <string.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <stdarg.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <signal.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <unistd.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <kstat.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <rpc/rpc.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/mnttab.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/mount.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/mntent.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <errno.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <locale.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <fslib.h>
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross#include <priv_utils.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#define RET_OK 0
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#define RET_ERR 32
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic void pr_err(const char *fmt, ...);
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic void usage();
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic int smbfs_unmount(char *, int);
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic struct extmnttab *mnttab_find();
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic char *myname;
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic char typename[64];
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint
4bff34e37def8a90f9194d81bc345c52ba20086athurlowmain(int argc, char *argv[])
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow extern int optind;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int c;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int umnt_flag = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow (void) setlocale(LC_ALL, "");
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#if !defined(TEXT_DOMAIN)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#define TEXT_DOMAIN "SYS_TEST"
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#endif
4bff34e37def8a90f9194d81bc345c52ba20086athurlow (void) textdomain(TEXT_DOMAIN);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross /*
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross * Normal users are allowed to umount smbfs mounts they own.
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross * To allow that, this program is installed setuid root, and
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross * it adds SYS_MOUNT privilege here (if needed), and then
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross * restores the user's normal privileges.
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross */
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross if (__init_suid_priv(0, PRIV_SYS_MOUNT, (char *)NULL) < 0) {
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross (void) fprintf(stderr,
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross gettext("Insufficient privileges, "
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross "%s must be set-uid root\n"), argv[0]);
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross exit(RET_ERR);
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross }
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross
4bff34e37def8a90f9194d81bc345c52ba20086athurlow myname = strrchr(argv[0], '/');
4bff34e37def8a90f9194d81bc345c52ba20086athurlow myname = myname ? myname+1 : argv[0];
4bff34e37def8a90f9194d81bc345c52ba20086athurlow (void) sprintf(typename, "smbfs %s", myname);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow argv[0] = typename;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Set options
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow while ((c = getopt(argc, argv, "f")) != EOF) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow switch (c) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow case 'f':
4bff34e37def8a90f9194d81bc345c52ba20086athurlow umnt_flag |= MS_FORCE; /* forced unmount is desired */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow break;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow default:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow usage();
4bff34e37def8a90f9194d81bc345c52ba20086athurlow exit(RET_ERR);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (argc - optind != 1) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow usage();
4bff34e37def8a90f9194d81bc345c52ba20086athurlow exit(RET_ERR);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (smbfs_unmount(argv[optind], umnt_flag));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic void
4bff34e37def8a90f9194d81bc345c52ba20086athurlowpr_err(const char *fmt, ...)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow va_list ap;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow va_start(ap, fmt);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow (void) fprintf(stderr, "%s: ", typename);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow (void) vfprintf(stderr, fmt, ap);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow (void) fflush(stderr);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow va_end(ap);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic void
4bff34e37def8a90f9194d81bc345c52ba20086athurlowusage()
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow (void) fprintf(stderr,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow gettext("Usage: smbfs umount [-o opts] {//server/share | dir}\n"));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow exit(RET_ERR);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic int
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmbfs_unmount(char *pathname, int umnt_flag)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct extmnttab *mntp;
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross int rc;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mntp = mnttab_find(pathname);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (mntp) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pathname = mntp->mnt_mountp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross /* Need sys_mount privilege for the umount call. */
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross (void) __priv_bracket(PRIV_ON);
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross rc = umount2(pathname, umnt_flag);
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross (void) __priv_bracket(PRIV_OFF);
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross
42d159821800ff240cc201c8fe07f575b9e8a62bGordon Ross if (rc < 0) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pr_err(gettext("%s: %s\n"), pathname, strerror(errno));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (RET_ERR);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (RET_OK);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Find the mnttab entry that corresponds to "name".
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * We're not sure what the name represents: either
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * a mountpoint name, or a special name (server:/path).
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Return the last entry in the file that matches.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic struct extmnttab *
4bff34e37def8a90f9194d81bc345c52ba20086athurlowmnttab_find(dirname)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow char *dirname;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow FILE *fp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct extmnttab mnt;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct extmnttab *res = NULL;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow fp = fopen(MNTTAB, "r");
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (fp == NULL) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pr_err("%s: %s\n", MNTTAB, strerror(errno));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (NULL);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow while (getextmntent(fp, &mnt, sizeof (struct extmnttab)) == 0) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (strcmp(mnt.mnt_mountp, dirname) == 0 ||
4bff34e37def8a90f9194d81bc345c52ba20086athurlow strcmp(mnt.mnt_special, dirname) == 0) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (res)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow fsfreemnttab(res);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow res = fsdupmnttab(&mnt);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow }
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow fclose(fp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (res);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}