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 26*6a1a5bb9SJohn Levon /* 27*6a1a5bb9SJohn Levon * Copyright (c) 2018, Joyent, Inc. 28*6a1a5bb9SJohn Levon */ 29*6a1a5bb9SJohn Levon 304bff34e3Sthurlow /* 314bff34e3Sthurlow * smbfs umount 324bff34e3Sthurlow */ 334bff34e3Sthurlow 344bff34e3Sthurlow #include <stdio.h> 354bff34e3Sthurlow #include <stdlib.h> 364bff34e3Sthurlow #include <string.h> 374bff34e3Sthurlow #include <stdarg.h> 384bff34e3Sthurlow #include <signal.h> 394bff34e3Sthurlow #include <unistd.h> 404bff34e3Sthurlow #include <kstat.h> 414bff34e3Sthurlow #include <rpc/rpc.h> 424bff34e3Sthurlow #include <sys/mnttab.h> 434bff34e3Sthurlow #include <sys/mount.h> 444bff34e3Sthurlow #include <sys/mntent.h> 454bff34e3Sthurlow #include <errno.h> 464bff34e3Sthurlow #include <locale.h> 474bff34e3Sthurlow #include <fslib.h> 4842d15982SGordon Ross #include <priv_utils.h> 494bff34e3Sthurlow 504bff34e3Sthurlow #define RET_OK 0 514bff34e3Sthurlow #define RET_ERR 32 524bff34e3Sthurlow 534bff34e3Sthurlow static void pr_err(const char *fmt, ...); 544bff34e3Sthurlow static void usage(); 554bff34e3Sthurlow static int smbfs_unmount(char *, int); 564bff34e3Sthurlow static struct extmnttab *mnttab_find(); 574bff34e3Sthurlow 584bff34e3Sthurlow static char *myname; 594bff34e3Sthurlow static char typename[64]; 604bff34e3Sthurlow 614bff34e3Sthurlow int 624bff34e3Sthurlow main(int argc, char *argv[]) 634bff34e3Sthurlow { 644bff34e3Sthurlow extern int optind; 654bff34e3Sthurlow int c; 664bff34e3Sthurlow int umnt_flag = 0; 674bff34e3Sthurlow 684bff34e3Sthurlow (void) setlocale(LC_ALL, ""); 694bff34e3Sthurlow 704bff34e3Sthurlow #if !defined(TEXT_DOMAIN) 714bff34e3Sthurlow #define TEXT_DOMAIN "SYS_TEST" 724bff34e3Sthurlow #endif 734bff34e3Sthurlow (void) textdomain(TEXT_DOMAIN); 744bff34e3Sthurlow 7542d15982SGordon Ross /* 7642d15982SGordon Ross * Normal users are allowed to umount smbfs mounts they own. 7742d15982SGordon Ross * To allow that, this program is installed setuid root, and 7842d15982SGordon Ross * it adds SYS_MOUNT privilege here (if needed), and then 7942d15982SGordon Ross * restores the user's normal privileges. 8042d15982SGordon Ross */ 8142d15982SGordon Ross if (__init_suid_priv(0, PRIV_SYS_MOUNT, (char *)NULL) < 0) { 8242d15982SGordon Ross (void) fprintf(stderr, 8342d15982SGordon Ross gettext("Insufficient privileges, " 8442d15982SGordon Ross "%s must be set-uid root\n"), argv[0]); 8542d15982SGordon Ross exit(RET_ERR); 8642d15982SGordon Ross } 8742d15982SGordon Ross 884bff34e3Sthurlow myname = strrchr(argv[0], '/'); 894bff34e3Sthurlow myname = myname ? myname+1 : argv[0]; 904bff34e3Sthurlow (void) sprintf(typename, "smbfs %s", myname); 914bff34e3Sthurlow argv[0] = typename; 924bff34e3Sthurlow 934bff34e3Sthurlow /* 944bff34e3Sthurlow * Set options 954bff34e3Sthurlow */ 964bff34e3Sthurlow while ((c = getopt(argc, argv, "f")) != EOF) { 974bff34e3Sthurlow switch (c) { 984bff34e3Sthurlow case 'f': 994bff34e3Sthurlow umnt_flag |= MS_FORCE; /* forced unmount is desired */ 1004bff34e3Sthurlow break; 1014bff34e3Sthurlow default: 1024bff34e3Sthurlow usage(); 1034bff34e3Sthurlow exit(RET_ERR); 1044bff34e3Sthurlow } 1054bff34e3Sthurlow } 1064bff34e3Sthurlow if (argc - optind != 1) { 1074bff34e3Sthurlow usage(); 1084bff34e3Sthurlow exit(RET_ERR); 1094bff34e3Sthurlow } 1104bff34e3Sthurlow 1114bff34e3Sthurlow return (smbfs_unmount(argv[optind], umnt_flag)); 1124bff34e3Sthurlow } 1134bff34e3Sthurlow 1144bff34e3Sthurlow static void 1154bff34e3Sthurlow pr_err(const char *fmt, ...) 1164bff34e3Sthurlow { 1174bff34e3Sthurlow va_list ap; 1184bff34e3Sthurlow 1194bff34e3Sthurlow va_start(ap, fmt); 1204bff34e3Sthurlow (void) fprintf(stderr, "%s: ", typename); 1214bff34e3Sthurlow (void) vfprintf(stderr, fmt, ap); 1224bff34e3Sthurlow (void) fflush(stderr); 1234bff34e3Sthurlow va_end(ap); 1244bff34e3Sthurlow } 1254bff34e3Sthurlow 1264bff34e3Sthurlow static void 1274bff34e3Sthurlow usage() 1284bff34e3Sthurlow { 1294bff34e3Sthurlow (void) fprintf(stderr, 1304bff34e3Sthurlow gettext("Usage: smbfs umount [-o opts] {//server/share | dir}\n")); 1314bff34e3Sthurlow exit(RET_ERR); 1324bff34e3Sthurlow } 1334bff34e3Sthurlow 1344bff34e3Sthurlow static int 1354bff34e3Sthurlow smbfs_unmount(char *pathname, int umnt_flag) 1364bff34e3Sthurlow { 1374bff34e3Sthurlow struct extmnttab *mntp; 13842d15982SGordon Ross int rc; 1394bff34e3Sthurlow 1404bff34e3Sthurlow mntp = mnttab_find(pathname); 1414bff34e3Sthurlow if (mntp) { 1424bff34e3Sthurlow pathname = mntp->mnt_mountp; 1434bff34e3Sthurlow } 1444bff34e3Sthurlow 14542d15982SGordon Ross /* Need sys_mount privilege for the umount call. */ 14642d15982SGordon Ross (void) __priv_bracket(PRIV_ON); 14742d15982SGordon Ross rc = umount2(pathname, umnt_flag); 14842d15982SGordon Ross (void) __priv_bracket(PRIV_OFF); 14942d15982SGordon Ross 15042d15982SGordon Ross if (rc < 0) { 1514bff34e3Sthurlow pr_err(gettext("%s: %s\n"), pathname, strerror(errno)); 1524bff34e3Sthurlow return (RET_ERR); 1534bff34e3Sthurlow } 1544bff34e3Sthurlow 1554bff34e3Sthurlow return (RET_OK); 1564bff34e3Sthurlow } 1574bff34e3Sthurlow 1584bff34e3Sthurlow /* 1594bff34e3Sthurlow * Find the mnttab entry that corresponds to "name". 1604bff34e3Sthurlow * We're not sure what the name represents: either 1614bff34e3Sthurlow * a mountpoint name, or a special name (server:/path). 1624bff34e3Sthurlow * Return the last entry in the file that matches. 1634bff34e3Sthurlow */ 1644bff34e3Sthurlow static struct extmnttab * 1654bff34e3Sthurlow mnttab_find(dirname) 1664bff34e3Sthurlow char *dirname; 1674bff34e3Sthurlow { 1684bff34e3Sthurlow FILE *fp; 1694bff34e3Sthurlow struct extmnttab mnt; 1704bff34e3Sthurlow struct extmnttab *res = NULL; 1714bff34e3Sthurlow 1724bff34e3Sthurlow fp = fopen(MNTTAB, "r"); 1734bff34e3Sthurlow if (fp == NULL) { 1744bff34e3Sthurlow pr_err("%s: %s\n", MNTTAB, strerror(errno)); 1754bff34e3Sthurlow return (NULL); 1764bff34e3Sthurlow } 1774bff34e3Sthurlow while (getextmntent(fp, &mnt, sizeof (struct extmnttab)) == 0) { 1784bff34e3Sthurlow if (strcmp(mnt.mnt_mountp, dirname) == 0 || 1794bff34e3Sthurlow strcmp(mnt.mnt_special, dirname) == 0) { 1804bff34e3Sthurlow if (res) 1814bff34e3Sthurlow fsfreemnttab(res); 1824bff34e3Sthurlow res = fsdupmnttab(&mnt); 1834bff34e3Sthurlow } 1844bff34e3Sthurlow } 1854bff34e3Sthurlow 186*6a1a5bb9SJohn Levon (void) fclose(fp); 1874bff34e3Sthurlow return (res); 1884bff34e3Sthurlow } 189