Пример #1
0
void
auth_init(char *exports)
{

	export_file = exports;
	auth_reload();
	xtab_mount_write();
}
Пример #2
0
bool_t
mount_umntall_1_svc(struct svc_req *rqstp, void *argp, void *resp)
{
	/* Reload /etc/xtab if necessary */
	auth_reload();

	mountlist_del_all(nfs_getrpccaller_in(rqstp->rq_xprt));
	return 1;
}
Пример #3
0
int
auth_run()
{
	if (auth_pwfile) {
		auth_enabled = 1;
		auth_reload();
	}
	return 0;
}
Пример #4
0
/*
 * MNTv2 pathconf procedure
 *
 * The protocol doesn't include a status field, so Sun apparently considers
 * it good practice to let anyone snoop on your system, even if it's
 * pretty harmless data such as pathconf. We don't.
 *
 * Besides, many of the pathconf values don't make much sense on NFS volumes.
 * FIFOs and tty device files represent devices on the *client*, so there's
 * no point in getting the server's buffer sizes etc.
 */
bool_t
mount_pathconf_2_svc(struct svc_req *rqstp, dirpath *path, ppathcnf *res)
{
	struct sockaddr_in *sin = nfs_getrpccaller_in(rqstp->rq_xprt);
	struct stat	stb;
	nfs_export	*exp;
	char		rpath[MAXPATHLEN+1];
	char		*p = *path;

	memset(res, 0, sizeof(*res));

	if (*p == '\0')
		p = "/";

	/* Reload /etc/xtab if necessary */
	auth_reload();

	/* Resolve symlinks */
	if (realpath(p, rpath) != NULL) {
		rpath[sizeof (rpath) - 1] = '\0';
		p = rpath;
	}

	/* Now authenticate the intruder... */
	exp = auth_authenticate("pathconf", sin, p);
	if (!exp) {
		return 1;
	} else if (stat(p, &stb) < 0) {
		xlog(L_WARNING, "can't stat exported dir %s: %s",
				p, strerror(errno));
		return 1;
	}

	res->pc_link_max  = pathconf(p, _PC_LINK_MAX);
	res->pc_max_canon = pathconf(p, _PC_MAX_CANON);
	res->pc_max_input = pathconf(p, _PC_MAX_INPUT);
	res->pc_name_max  = pathconf(p, _PC_NAME_MAX);
	res->pc_path_max  = pathconf(p, _PC_PATH_MAX);
	res->pc_pipe_buf  = pathconf(p, _PC_PIPE_BUF);
	res->pc_vdisable  = pathconf(p, _PC_VDISABLE);

	/* Can't figure out what to do with pc_mask */
	res->pc_mask[0]   = 0;
	res->pc_mask[1]   = 0;

	return 1;
}
Пример #5
0
static exports
get_exportlist(void)
{
	static exports		elist = NULL;
	struct exportnode	*e, *ne;
	struct groupnode	*g, *ng, *c, **cp;
	nfs_export		*exp;
	int			i;
	static unsigned int	ecounter;
	unsigned int		acounter;

	acounter = auth_reload();
	if (elist && acounter == ecounter)
		return elist;

	ecounter = acounter;

	for (e = elist; e != NULL; e = ne) {
		ne = e->ex_next;
		for (g = e->ex_groups; g != NULL; g = ng) {
			ng = g->gr_next;
			xfree(g->gr_name);
			xfree(g);
		}
		xfree(e->ex_dir);
		xfree(e);
	}
	elist = NULL;

	for (i = 0; i < MCL_MAXTYPES; i++) {
		for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
			for (e = elist; e != NULL; e = e->ex_next) {
				if (!strcmp(exp->m_export.e_path, e->ex_dir))
					break;
			}
			if (!e) {
				e = (struct exportnode *) xmalloc(sizeof(*e));
				e->ex_next = elist;
				e->ex_groups = NULL;
				e->ex_dir = xstrdup(exp->m_export.e_path);
				elist = e;
			}

			/* We need to check if we should remove
			   previous ones. */
			if (i == MCL_ANONYMOUS && e->ex_groups) {
				for (g = e->ex_groups; g; g = ng) {
					ng = g->gr_next;
					xfree(g->gr_name);
					xfree(g);
				}
				e->ex_groups = NULL;
				continue;
			}

			if (i != MCL_FQDN && e->ex_groups) {
			  struct hostent 	*hp;

			  cp = &e->ex_groups;
			  while ((c = *cp) != NULL) {
			    if (client_gettype (c->gr_name) == MCL_FQDN
			        && (hp = gethostbyname(c->gr_name))) {
			      hp = hostent_dup (hp);
			      if (client_check(exp->m_client, hp)) {
				*cp = c->gr_next;
				xfree(c->gr_name);
				xfree(c);
				xfree (hp);
				continue;
			      }
			      xfree (hp);
			    }
			    cp = &(c->gr_next);
			  }
			}

			if (exp->m_export.e_hostname [0] != '\0') {
				for (g = e->ex_groups; g; g = g->gr_next)
					if (strcmp (exp->m_export.e_hostname,
						    g->gr_name) == 0)
						break;
				if (g)
					continue;
				g = (struct groupnode *) xmalloc(sizeof(*g));
				g->gr_name = xstrdup(exp->m_export.e_hostname);
				g->gr_next = e->ex_groups;
				e->ex_groups = g;
			}
		}
	}

	return elist;
}
Пример #6
0
static struct nfs_fh_len *
get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret,
		mountstat3 *error, int v3)
{
	struct sockaddr_in *sin = nfs_getrpccaller_in(rqstp->rq_xprt);
	struct stat	stb, estb;
	nfs_export	*exp;
	struct nfs_fh_len *fh;
	char		rpath[MAXPATHLEN+1];
	char		*p = *path;

	if (*p == '\0')
		p = "/";

	/* Reload /var/lib/nfs/etab if necessary */
	auth_reload();

	/* Resolve symlinks */
	if (realpath(p, rpath) != NULL) {
		rpath[sizeof (rpath) - 1] = '\0';
		p = rpath;
	}

	/* Now authenticate the intruder... */
	exp = auth_authenticate("mount", sin, p);
	if (!exp) {
		*error = NFSERR_ACCES;
		return NULL;
	}
	if (stat(p, &stb) < 0) {
		xlog(L_WARNING, "can't stat exported dir %s: %s",
				p, strerror(errno));
		if (errno == ENOENT)
			*error = NFSERR_NOENT;
		else
			*error = NFSERR_ACCES;
		return NULL;
	}
	if (!S_ISDIR(stb.st_mode) && !S_ISREG(stb.st_mode)) {
		xlog(L_WARNING, "%s is not a directory or regular file", p);
		*error = NFSERR_NOTDIR;
		return NULL;
	}
	if (stat(exp->m_export.e_path, &estb) < 0) {
		xlog(L_WARNING, "can't stat export point %s: %s",
		     p, strerror(errno));
		*error = NFSERR_NOENT;
		return NULL;
	}
	if (estb.st_dev != stb.st_dev
		   && (!new_cache
			   || !(exp->m_export.e_flags & NFSEXP_CROSSMOUNT))) {
		xlog(L_WARNING, "request to export directory %s below nearest filesystem %s",
		     p, exp->m_export.e_path);
		*error = NFSERR_ACCES;
		return NULL;
	}
	if (exp->m_export.e_mountpoint &&
		   !is_mountpoint(exp->m_export.e_mountpoint[0]?
				  exp->m_export.e_mountpoint:
				  exp->m_export.e_path)) {
		xlog(L_WARNING, "request to export an unmounted filesystem: %s",
		     p);
		*error = NFSERR_NOENT;
		return NULL;
	}

	if (new_cache) {
		/* This will be a static private nfs_export with just one
		 * address.  We feed it to kernel then extract the filehandle,
		 * 
		 */

		if (cache_export(exp, p)) {
			*error = NFSERR_ACCES;
			return NULL;
		}
		fh = cache_get_filehandle(exp, v3?64:32, p);
		if (fh == NULL) {
			*error = NFSERR_ACCES;
			return NULL;
		}
	} else {
		int did_export = 0;
	retry:
		if (exp->m_exported<1) {
			export_export(exp);
			did_export = 1;
		}
		if (!exp->m_xtabent)
			xtab_append(exp);

		if (v3)
			fh = getfh_size ((struct sockaddr *) sin, p, 64);
		if (!v3 || (fh == NULL && errno == EINVAL)) {
			/* We first try the new nfs syscall. */
			fh = getfh ((struct sockaddr *) sin, p);
			if (fh == NULL && errno == EINVAL)
				/* Let's try the old one. */
				fh = getfh_old ((struct sockaddr *) sin,
						stb.st_dev, stb.st_ino);
		}
		if (fh == NULL && !did_export) {
			exp->m_exported = 0;
			goto retry;
		}

		if (fh == NULL) {
			xlog(L_WARNING, "getfh failed: %s", strerror(errno));
			*error = NFSERR_ACCES;
			return NULL;
		}
	}
	*error = NFS_OK;
	mountlist_add(inet_ntoa(sin->sin_addr), p);
	if (expret)
		*expret = exp;
	return fh;
}