14bff34e3Sthurlow /*
24bff34e3Sthurlow * CDDL HEADER START
34bff34e3Sthurlow *
44bff34e3Sthurlow * The contents of this file are subject to the terms of the
54bff34e3Sthurlow * Common Development and Distribution License (the "License").
64bff34e3Sthurlow * You may not use this file except in compliance with the License.
74bff34e3Sthurlow *
84bff34e3Sthurlow * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94bff34e3Sthurlow * or http://www.opensolaris.org/os/licensing.
104bff34e3Sthurlow * See the License for the specific language governing permissions
114bff34e3Sthurlow * and limitations under the License.
124bff34e3Sthurlow *
134bff34e3Sthurlow * When distributing Covered Code, include this CDDL HEADER in each
144bff34e3Sthurlow * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154bff34e3Sthurlow * If applicable, add the following below this CDDL HEADER, with the
164bff34e3Sthurlow * fields enclosed by brackets "[]" replaced with your own identifying
174bff34e3Sthurlow * information: Portions Copyright [yyyy] [name of copyright owner]
184bff34e3Sthurlow *
194bff34e3Sthurlow * CDDL HEADER END
204bff34e3Sthurlow */
214bff34e3Sthurlow /*
2242d15982SGordon Ross * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
234bff34e3Sthurlow * Use is subject to license terms.
244bff34e3Sthurlow */
254bff34e3Sthurlow
266a1a5bb9SJohn Levon /*
276a1a5bb9SJohn Levon * Copyright (c) 2018, Joyent, Inc.
28*0463c800SGordon Ross * Copyright 2019 Nexenta by DDN, Inc. All rights reserved.
296a1a5bb9SJohn Levon */
306a1a5bb9SJohn Levon
314bff34e3Sthurlow /*
324bff34e3Sthurlow * smbfs umount
334bff34e3Sthurlow */
344bff34e3Sthurlow
354bff34e3Sthurlow #include <stdio.h>
364bff34e3Sthurlow #include <stdlib.h>
374bff34e3Sthurlow #include <string.h>
384bff34e3Sthurlow #include <stdarg.h>
394bff34e3Sthurlow #include <signal.h>
404bff34e3Sthurlow #include <unistd.h>
414bff34e3Sthurlow #include <kstat.h>
424bff34e3Sthurlow #include <rpc/rpc.h>
434bff34e3Sthurlow #include <sys/mnttab.h>
444bff34e3Sthurlow #include <sys/mount.h>
454bff34e3Sthurlow #include <sys/mntent.h>
464bff34e3Sthurlow #include <errno.h>
474bff34e3Sthurlow #include <locale.h>
484bff34e3Sthurlow #include <fslib.h>
4942d15982SGordon Ross #include <priv_utils.h>
504bff34e3Sthurlow
514bff34e3Sthurlow #define RET_OK 0
524bff34e3Sthurlow #define RET_ERR 32
534bff34e3Sthurlow
544bff34e3Sthurlow static void pr_err(const char *fmt, ...);
554bff34e3Sthurlow static void usage();
564bff34e3Sthurlow static int smbfs_unmount(char *, int);
574bff34e3Sthurlow static struct extmnttab *mnttab_find();
584bff34e3Sthurlow
594bff34e3Sthurlow int
main(int argc,char * argv[])604bff34e3Sthurlow main(int argc, char *argv[])
614bff34e3Sthurlow {
624bff34e3Sthurlow extern int optind;
634bff34e3Sthurlow int c;
644bff34e3Sthurlow int umnt_flag = 0;
654bff34e3Sthurlow
664bff34e3Sthurlow (void) setlocale(LC_ALL, "");
674bff34e3Sthurlow
684bff34e3Sthurlow #if !defined(TEXT_DOMAIN)
694bff34e3Sthurlow #define TEXT_DOMAIN "SYS_TEST"
704bff34e3Sthurlow #endif
714bff34e3Sthurlow (void) textdomain(TEXT_DOMAIN);
724bff34e3Sthurlow
7342d15982SGordon Ross /*
7442d15982SGordon Ross * Normal users are allowed to umount smbfs mounts they own.
75*0463c800SGordon Ross * To allow that, this program has an exec_attr that adds
76*0463c800SGordon Ross * SYS_MOUNT privilege.
77*0463c800SGordon Ross *
78*0463c800SGordon Ross * The __init_suid_priv call was designed for SUID programs,
79*0463c800SGordon Ross * but also works for privileges granted via exec_attr with
80*0463c800SGordon Ross * one difference: the added privileges are already effective
81*0463c800SGordon Ross * when the program starts, and remain effective after the call.
82*0463c800SGordon Ross * To make this work more like the SUID case we'll turn off the
83*0463c800SGordon Ross * additional privileges with a __priv_bracket() call here.
84*0463c800SGordon Ross * Later calls to __priv_bracket() make the extra privileges
85*0463c800SGordon Ross * effective only when we need them.
8642d15982SGordon Ross */
8742d15982SGordon Ross if (__init_suid_priv(0, PRIV_SYS_MOUNT, (char *)NULL) < 0) {
8842d15982SGordon Ross (void) fprintf(stderr,
8942d15982SGordon Ross gettext("Insufficient privileges, "
90*0463c800SGordon Ross "%s should have sys_mount privilege via exec_attr\n"),
91*0463c800SGordon Ross argv[0]);
9242d15982SGordon Ross exit(RET_ERR);
9342d15982SGordon Ross }
94*0463c800SGordon Ross (void) __priv_bracket(PRIV_OFF);
954bff34e3Sthurlow
964bff34e3Sthurlow /*
974bff34e3Sthurlow * Set options
984bff34e3Sthurlow */
994bff34e3Sthurlow while ((c = getopt(argc, argv, "f")) != EOF) {
1004bff34e3Sthurlow switch (c) {
1014bff34e3Sthurlow case 'f':
1024bff34e3Sthurlow umnt_flag |= MS_FORCE; /* forced unmount is desired */
1034bff34e3Sthurlow break;
1044bff34e3Sthurlow default:
1054bff34e3Sthurlow usage();
1064bff34e3Sthurlow exit(RET_ERR);
1074bff34e3Sthurlow }
1084bff34e3Sthurlow }
1094bff34e3Sthurlow if (argc - optind != 1) {
1104bff34e3Sthurlow usage();
1114bff34e3Sthurlow exit(RET_ERR);
1124bff34e3Sthurlow }
1134bff34e3Sthurlow
1144bff34e3Sthurlow return (smbfs_unmount(argv[optind], umnt_flag));
1154bff34e3Sthurlow }
1164bff34e3Sthurlow
1174bff34e3Sthurlow static void
pr_err(const char * fmt,...)1184bff34e3Sthurlow pr_err(const char *fmt, ...)
1194bff34e3Sthurlow {
1204bff34e3Sthurlow va_list ap;
1214bff34e3Sthurlow
1224bff34e3Sthurlow va_start(ap, fmt);
123*0463c800SGordon Ross (void) fprintf(stderr, "smbfs/umount: ");
1244bff34e3Sthurlow (void) vfprintf(stderr, fmt, ap);
1254bff34e3Sthurlow (void) fflush(stderr);
1264bff34e3Sthurlow va_end(ap);
1274bff34e3Sthurlow }
1284bff34e3Sthurlow
1294bff34e3Sthurlow static void
usage()1304bff34e3Sthurlow usage()
1314bff34e3Sthurlow {
1324bff34e3Sthurlow (void) fprintf(stderr,
1334bff34e3Sthurlow gettext("Usage: smbfs umount [-o opts] {//server/share | dir}\n"));
1344bff34e3Sthurlow exit(RET_ERR);
1354bff34e3Sthurlow }
1364bff34e3Sthurlow
1374bff34e3Sthurlow static int
smbfs_unmount(char * pathname,int umnt_flag)1384bff34e3Sthurlow smbfs_unmount(char *pathname, int umnt_flag)
1394bff34e3Sthurlow {
1404bff34e3Sthurlow struct extmnttab *mntp;
14142d15982SGordon Ross int rc;
1424bff34e3Sthurlow
1434bff34e3Sthurlow mntp = mnttab_find(pathname);
1444bff34e3Sthurlow if (mntp) {
1454bff34e3Sthurlow pathname = mntp->mnt_mountp;
1464bff34e3Sthurlow }
1474bff34e3Sthurlow
14842d15982SGordon Ross /* Need sys_mount privilege for the umount call. */
14942d15982SGordon Ross (void) __priv_bracket(PRIV_ON);
15042d15982SGordon Ross rc = umount2(pathname, umnt_flag);
15142d15982SGordon Ross (void) __priv_bracket(PRIV_OFF);
15242d15982SGordon Ross
15342d15982SGordon Ross if (rc < 0) {
1544bff34e3Sthurlow pr_err(gettext("%s: %s\n"), pathname, strerror(errno));
1554bff34e3Sthurlow return (RET_ERR);
1564bff34e3Sthurlow }
1574bff34e3Sthurlow
1584bff34e3Sthurlow return (RET_OK);
1594bff34e3Sthurlow }
1604bff34e3Sthurlow
1614bff34e3Sthurlow /*
1624bff34e3Sthurlow * Find the mnttab entry that corresponds to "name".
1634bff34e3Sthurlow * We're not sure what the name represents: either
1644bff34e3Sthurlow * a mountpoint name, or a special name (server:/path).
1654bff34e3Sthurlow * Return the last entry in the file that matches.
1664bff34e3Sthurlow */
1674bff34e3Sthurlow static struct extmnttab *
mnttab_find(char * dirname)168*0463c800SGordon Ross mnttab_find(char *dirname)
1694bff34e3Sthurlow {
1704bff34e3Sthurlow FILE *fp;
1714bff34e3Sthurlow struct extmnttab mnt;
1724bff34e3Sthurlow struct extmnttab *res = NULL;
1734bff34e3Sthurlow
1744bff34e3Sthurlow fp = fopen(MNTTAB, "r");
1754bff34e3Sthurlow if (fp == NULL) {
1764bff34e3Sthurlow pr_err("%s: %s\n", MNTTAB, strerror(errno));
1774bff34e3Sthurlow return (NULL);
1784bff34e3Sthurlow }
1794bff34e3Sthurlow while (getextmntent(fp, &mnt, sizeof (struct extmnttab)) == 0) {
1804bff34e3Sthurlow if (strcmp(mnt.mnt_mountp, dirname) == 0 ||
1814bff34e3Sthurlow strcmp(mnt.mnt_special, dirname) == 0) {
1824bff34e3Sthurlow if (res)
1834bff34e3Sthurlow fsfreemnttab(res);
1844bff34e3Sthurlow res = fsdupmnttab(&mnt);
1854bff34e3Sthurlow }
1864bff34e3Sthurlow }
1874bff34e3Sthurlow
1886a1a5bb9SJohn Levon (void) fclose(fp);
1894bff34e3Sthurlow return (res);
1904bff34e3Sthurlow }
191