void auth_init(char *exports) { export_file = exports; auth_reload(); xtab_mount_write(); }
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; }
int auth_run() { if (auth_pwfile) { auth_enabled = 1; auth_reload(); } return 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; }
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; }
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; }