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 /*
22*42d15982SGordon Ross * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
234bff34e3Sthurlow * Use is subject to license terms.
244bff34e3Sthurlow */
254bff34e3Sthurlow
264bff34e3Sthurlow /*
274bff34e3Sthurlow * smbfs umount
284bff34e3Sthurlow */
294bff34e3Sthurlow
304bff34e3Sthurlow #include <stdio.h>
314bff34e3Sthurlow #include <stdlib.h>
324bff34e3Sthurlow #include <string.h>
334bff34e3Sthurlow #include <stdarg.h>
344bff34e3Sthurlow #include <signal.h>
354bff34e3Sthurlow #include <unistd.h>
364bff34e3Sthurlow #include <kstat.h>
374bff34e3Sthurlow #include <rpc/rpc.h>
384bff34e3Sthurlow #include <sys/mnttab.h>
394bff34e3Sthurlow #include <sys/mount.h>
404bff34e3Sthurlow #include <sys/mntent.h>
414bff34e3Sthurlow #include <errno.h>
424bff34e3Sthurlow #include <locale.h>
434bff34e3Sthurlow #include <fslib.h>
44*42d15982SGordon Ross #include <priv_utils.h>
454bff34e3Sthurlow
464bff34e3Sthurlow #define RET_OK 0
474bff34e3Sthurlow #define RET_ERR 32
484bff34e3Sthurlow
494bff34e3Sthurlow static void pr_err(const char *fmt, ...);
504bff34e3Sthurlow static void usage();
514bff34e3Sthurlow static int smbfs_unmount(char *, int);
524bff34e3Sthurlow static struct extmnttab *mnttab_find();
534bff34e3Sthurlow
544bff34e3Sthurlow static char *myname;
554bff34e3Sthurlow static char typename[64];
564bff34e3Sthurlow
574bff34e3Sthurlow int
main(int argc,char * argv[])584bff34e3Sthurlow main(int argc, char *argv[])
594bff34e3Sthurlow {
604bff34e3Sthurlow extern int optind;
614bff34e3Sthurlow int c;
624bff34e3Sthurlow int umnt_flag = 0;
634bff34e3Sthurlow
644bff34e3Sthurlow (void) setlocale(LC_ALL, "");
654bff34e3Sthurlow
664bff34e3Sthurlow #if !defined(TEXT_DOMAIN)
674bff34e3Sthurlow #define TEXT_DOMAIN "SYS_TEST"
684bff34e3Sthurlow #endif
694bff34e3Sthurlow (void) textdomain(TEXT_DOMAIN);
704bff34e3Sthurlow
71*42d15982SGordon Ross /*
72*42d15982SGordon Ross * Normal users are allowed to umount smbfs mounts they own.
73*42d15982SGordon Ross * To allow that, this program is installed setuid root, and
74*42d15982SGordon Ross * it adds SYS_MOUNT privilege here (if needed), and then
75*42d15982SGordon Ross * restores the user's normal privileges.
76*42d15982SGordon Ross */
77*42d15982SGordon Ross if (__init_suid_priv(0, PRIV_SYS_MOUNT, (char *)NULL) < 0) {
78*42d15982SGordon Ross (void) fprintf(stderr,
79*42d15982SGordon Ross gettext("Insufficient privileges, "
80*42d15982SGordon Ross "%s must be set-uid root\n"), argv[0]);
81*42d15982SGordon Ross exit(RET_ERR);
82*42d15982SGordon Ross }
83*42d15982SGordon Ross
844bff34e3Sthurlow myname = strrchr(argv[0], '/');
854bff34e3Sthurlow myname = myname ? myname+1 : argv[0];
864bff34e3Sthurlow (void) sprintf(typename, "smbfs %s", myname);
874bff34e3Sthurlow argv[0] = typename;
884bff34e3Sthurlow
894bff34e3Sthurlow /*
904bff34e3Sthurlow * Set options
914bff34e3Sthurlow */
924bff34e3Sthurlow while ((c = getopt(argc, argv, "f")) != EOF) {
934bff34e3Sthurlow switch (c) {
944bff34e3Sthurlow case 'f':
954bff34e3Sthurlow umnt_flag |= MS_FORCE; /* forced unmount is desired */
964bff34e3Sthurlow break;
974bff34e3Sthurlow default:
984bff34e3Sthurlow usage();
994bff34e3Sthurlow exit(RET_ERR);
1004bff34e3Sthurlow }
1014bff34e3Sthurlow }
1024bff34e3Sthurlow if (argc - optind != 1) {
1034bff34e3Sthurlow usage();
1044bff34e3Sthurlow exit(RET_ERR);
1054bff34e3Sthurlow }
1064bff34e3Sthurlow
1074bff34e3Sthurlow return (smbfs_unmount(argv[optind], umnt_flag));
1084bff34e3Sthurlow }
1094bff34e3Sthurlow
1104bff34e3Sthurlow static void
pr_err(const char * fmt,...)1114bff34e3Sthurlow pr_err(const char *fmt, ...)
1124bff34e3Sthurlow {
1134bff34e3Sthurlow va_list ap;
1144bff34e3Sthurlow
1154bff34e3Sthurlow va_start(ap, fmt);
1164bff34e3Sthurlow (void) fprintf(stderr, "%s: ", typename);
1174bff34e3Sthurlow (void) vfprintf(stderr, fmt, ap);
1184bff34e3Sthurlow (void) fflush(stderr);
1194bff34e3Sthurlow va_end(ap);
1204bff34e3Sthurlow }
1214bff34e3Sthurlow
1224bff34e3Sthurlow static void
usage()1234bff34e3Sthurlow usage()
1244bff34e3Sthurlow {
1254bff34e3Sthurlow (void) fprintf(stderr,
1264bff34e3Sthurlow gettext("Usage: smbfs umount [-o opts] {//server/share | dir}\n"));
1274bff34e3Sthurlow exit(RET_ERR);
1284bff34e3Sthurlow }
1294bff34e3Sthurlow
1304bff34e3Sthurlow static int
smbfs_unmount(char * pathname,int umnt_flag)1314bff34e3Sthurlow smbfs_unmount(char *pathname, int umnt_flag)
1324bff34e3Sthurlow {
1334bff34e3Sthurlow struct extmnttab *mntp;
134*42d15982SGordon Ross int rc;
1354bff34e3Sthurlow
1364bff34e3Sthurlow mntp = mnttab_find(pathname);
1374bff34e3Sthurlow if (mntp) {
1384bff34e3Sthurlow pathname = mntp->mnt_mountp;
1394bff34e3Sthurlow }
1404bff34e3Sthurlow
141*42d15982SGordon Ross /* Need sys_mount privilege for the umount call. */
142*42d15982SGordon Ross (void) __priv_bracket(PRIV_ON);
143*42d15982SGordon Ross rc = umount2(pathname, umnt_flag);
144*42d15982SGordon Ross (void) __priv_bracket(PRIV_OFF);
145*42d15982SGordon Ross
146*42d15982SGordon Ross if (rc < 0) {
1474bff34e3Sthurlow pr_err(gettext("%s: %s\n"), pathname, strerror(errno));
1484bff34e3Sthurlow return (RET_ERR);
1494bff34e3Sthurlow }
1504bff34e3Sthurlow
1514bff34e3Sthurlow return (RET_OK);
1524bff34e3Sthurlow }
1534bff34e3Sthurlow
1544bff34e3Sthurlow /*
1554bff34e3Sthurlow * Find the mnttab entry that corresponds to "name".
1564bff34e3Sthurlow * We're not sure what the name represents: either
1574bff34e3Sthurlow * a mountpoint name, or a special name (server:/path).
1584bff34e3Sthurlow * Return the last entry in the file that matches.
1594bff34e3Sthurlow */
1604bff34e3Sthurlow static struct extmnttab *
mnttab_find(dirname)1614bff34e3Sthurlow mnttab_find(dirname)
1624bff34e3Sthurlow char *dirname;
1634bff34e3Sthurlow {
1644bff34e3Sthurlow FILE *fp;
1654bff34e3Sthurlow struct extmnttab mnt;
1664bff34e3Sthurlow struct extmnttab *res = NULL;
1674bff34e3Sthurlow
1684bff34e3Sthurlow fp = fopen(MNTTAB, "r");
1694bff34e3Sthurlow if (fp == NULL) {
1704bff34e3Sthurlow pr_err("%s: %s\n", MNTTAB, strerror(errno));
1714bff34e3Sthurlow return (NULL);
1724bff34e3Sthurlow }
1734bff34e3Sthurlow while (getextmntent(fp, &mnt, sizeof (struct extmnttab)) == 0) {
1744bff34e3Sthurlow if (strcmp(mnt.mnt_mountp, dirname) == 0 ||
1754bff34e3Sthurlow strcmp(mnt.mnt_special, dirname) == 0) {
1764bff34e3Sthurlow if (res)
1774bff34e3Sthurlow fsfreemnttab(res);
1784bff34e3Sthurlow res = fsdupmnttab(&mnt);
1794bff34e3Sthurlow }
1804bff34e3Sthurlow }
1814bff34e3Sthurlow
1824bff34e3Sthurlow fclose(fp);
1834bff34e3Sthurlow return (res);
1844bff34e3Sthurlow }
185