/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <syslog.h>
#include <errno.h>
#include <pwd.h>
#include <netdb.h>
#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
#include <thread.h>
#include <limits.h>
#include <assert.h>
#include <fcntl.h>
#include <strings.h>
#include "automount.h"
#include "replica.h"
static int unmount_mntpnt(struct mnttab *);
static int call_fork_exec(char *, char *, char **, int);
static void remove_browse_options(char *);
static int inherit_options(char *, char **);
int
char *mapname,
char *key,
char *subdir,
char *mapopts,
char *path,
action_list **alpp,
int flags)
{
int err = 0;
int mount_ok = 0;
iswildcard = FALSE;
/* initialize the stack of open files for this thread */
if (err == 0) {
}
if (trace) {
trace_prt(0, "\t\t-%s\n",
trace_prt(0, "\t\t%s:%s\tpenalty=%d\n",
mfs->mfs_penalty);
}
}
/*
* Each mapent in the list describes a mount to be done.
* Normally there's just a single entry, though in the
* case of /net mounts there may be many entries, that
* must be mounted as a hierarchy. For each mount the
* automountd must make sure the required mountpoint
* exists and invoke the appropriate mount command for
* the fstype.
*/
private = "";
return (ENAMETOOLONG);
}
/*
* remove trailing /'s from mountpoint to avoid problems
* stating a directory with two or more trailing slashes.
* This will let us mount directories from machines
* which export with two or more slashes (apollo for instance).
*/
len -= 1;
if (isrestricted &&
return (EAGAIN);
}
if (flags == DOMOUNT_KERNEL) {
sizeof (action_list));
"malloc of alp failed");
continue;
}
} else
err =
&alp);
/*
* We must retry if we don't have access to the
* root file system and there are other
* following mapents. The reason we can't
* continue because the rest of the mapent list
* depends on whether mount_access is TRUE or FALSE.
*/
/*
* don't expect mount_access to be
* FALSE here, but we do a check
* anyway.
*/
if (mount_access == TRUE) {
err = 0;
if (alp) {
}
goto retry;
}
}
if (alp) {
else {
}
}
if (isdirect) {
} else {
}
return (ENAMETOOLONG);
}
continue;
}
/*
* get the next subidr, but only if its a modified
* or faked autofs mount
*/
me->map_mntpnt);
} else {
next_subdir[0] = '\0';
len = 0;
}
if (trace > 2)
root, next_subdir);
if (len < sizeof (next_subdir)) {
} else {
err = ENAMETOOLONG;
}
if (err == 0) {
/*
* append to action list
*/
mount_ok++;
else {
}
} else {
mount_ok = 0;
}
} else {
}
}
if (mapents)
/*
* If an error occurred,
* the filesystem doesn't exist, or could not be
* mounted. Return EACCES to autofs indicating that
* the mountpoint can not be accessed if this is not
* a wildcard access. If it is a wildcard access we
* return ENOENT since the lookup that triggered
* this mount request will fail and the entry will not
* be available.
*/
if (mount_ok) {
/*
* No error occurred, return 0 to indicate success.
*/
err = 0;
} else {
/*
* The filesystem does not exist or could not be mounted.
* Return ENOENT if the lookup was triggered by a wildcard
* access. Wildcard entries only exist if they can be
* mounted. They can not be listed otherwise (through
* a readdir(2)).
* Return EACCES if the lookup was not triggered by a
* wildcard access. Map entries that are explicitly defined
* in maps are visible via readdir(2), therefore we return
* EACCES to indicate that the entry exists, but the directory
* can not be opened. This is the same behavior of a Unix
* directory that exists, but has its execute bit turned off.
* The directory is there, but the user does not have access
* to it.
*/
if (iswildcard)
else
}
return (err);
}
int
int overlay;
{
struct mnttab m;
int i, res;
if (trace > 1) {
}
return (ENOENT);
}
i = 2;
if (overlay)
newargv[i++] = "-O";
/*
* Use "quiet" option to suppress warnings about unsupported
* mount options.
*/
newargv[i++] = "-q";
m.mnt_mntopts = opts;
newargv[i++] = "-r";
newargv[i++] = "-o";
}
newargv[i++] = "--";
} else {
}
}
return (res);
}
void
{
int stat_loc;
int fd = 0;
int res;
int child_pid;
int i;
}
case -1:
break;
case 0:
/*
* Child
*/
(void) setsid();
O_WRONLY);
if (fd != -1) {
}
}
}
default:
/*
* Parent
*/
if (trace > 1) {
trace_prt(1,
" fork_exec: returns exit status %d\n",
}
} else if (WIFSIGNALED(stat_loc)) {
if (trace > 1)
trace_prt(1,
" fork_exec: returns signal status %d\n",
res = 1;
} else {
if (trace > 1)
trace_prt(1,
" fork_exec: returns unknown status\n");
res = 1;
}
}
}
int
{
struct mnttab m;
int res = 0;
/*
* Special case for NFS mounts.
* Don't want to attempt unmounts from
* a dead server. If any member of a
* hierarchy belongs to a dead server
* give up (try later).
*/
int i, n;
int nfs_port;
int got_port;
/*
* See if a port number was specified. If one was
* specified that is too large to fit in 16 bits, truncate
* the high-order bits (for historical compatibility). Use
* zero to indicate "no port specified".
*/
if (!got_port)
nfs_port = 0;
if (hasmntopt(&m, MNTOPT_PUBLIC))
if (n >= 0)
res = 1;
goto done;
}
for (i = 0; i < n; i++) {
res = 1;
free_replica(list, n);
goto done;
}
}
free_replica(list, n);
}
res = unmount_mntpnt(&m);
}
static int
{
int res;
} else {
/*
* filesystem specific unmount command not found
*/
}
}
if (trace > 1)
return (res);
}
/*
* Remove the autofs specific options 'browse', 'nobrowse' and
* 'restrict' from 'opts'.
*/
static void
{
char *p, *pb;
char *placeholder;
new[0] = '\0';
if (strcmp(p, MNTOPT_NOBROWSE) != 0 &&
strcmp(p, MNTOPT_BROWSE) != 0 &&
strcmp(p, MNTOPT_RESTRICT) != 0) {
if (new[0] != '\0')
}
}
}
static const char *restropts[] = {
};
static int
{
int i;
char *new;
for (i = 0; i < NROPTS; i++)
/* "," for each new option plus the trailing NUL */
if (new == 0)
return (-1);
for (i = 0; i < NROPTS; i++) {
if (*new != '\0')
}
}
free(*mapentopts);
*mapentopts = new;
return (0);
}
{
}
static int
char *fstype;
char *cmd;
char **newargv;
int console;
{
int ret;
int sz;
int status;
int i;
/* build the full path name of the fstype dependent command */
return (ret);
}
for (i = 2; newargv[i]; i++) {
}
if (trace > 1) {
trace_prt(0, "\n");
}
if (trace > 1) {
}
return (status);
}