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 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 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 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 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 * 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