#include "nfslib.h"
#include "exportfs.h"
#include "mountd.h"
-#include "xmalloc.h"
#include "fsloc.h"
#include "pseudoflavors.h"
*/
char *cp;
char class[20];
- char ipaddr[INET6_ADDRSTRLEN];
+ char ipaddr[INET6_ADDRSTRLEN + 1];
char *client = NULL;
struct addrinfo *tmp = NULL;
if (readline(fileno(f), &lbuf, &lbuflen) != 1)
strcmp(class, "nfsd") != 0)
return;
- if (qword_get(&cp, ipaddr, sizeof(ipaddr)) <= 0)
+ if (qword_get(&cp, ipaddr, sizeof(ipaddr) - 1) <= 0)
return;
tmp = host_pton(ipaddr);
struct addrinfo *ai = NULL;
ai = client_resolve(tmp->ai_addr);
- if (ai == NULL)
- goto out;
- client = client_compose(ai);
- freeaddrinfo(ai);
- if (!client)
- goto out;
+ if (ai) {
+ client = client_compose(ai);
+ freeaddrinfo(ai);
+ }
}
qword_print(f, "nfsd");
qword_print(f, ipaddr);
- qword_printuint(f, time(0) + DEFAULT_TTL);
- if (use_ipaddr)
+ qword_printtimefrom(f, DEFAULT_TTL);
+ if (use_ipaddr) {
+ memmove(ipaddr + 1, ipaddr, strlen(ipaddr) + 1);
+ ipaddr[0] = '$';
qword_print(f, ipaddr);
- else if (client)
+ } else if (client)
qword_print(f, *client?client:"DEFAULT");
qword_eol(f);
xlog(D_CALL, "auth_unix_ip: client %p '%s'", client, client?client: "DEFAULT");
free(client);
-out:
freeaddrinfo(tmp);
}
}
}
qword_printuint(f, uid);
- qword_printuint(f, time(0) + DEFAULT_TTL);
+ qword_printtimefrom(f, DEFAULT_TTL);
if (rv >= 0) {
qword_printuint(f, ngroups);
for (i=0; i<ngroups; i++)
#define get_uuid_blkdev(path) (NULL)
#endif
-static int get_uuid(const char *val, int uuidlen, char *u)
+static int get_uuid(const char *val, size_t uuidlen, char *u)
{
/* extract hex digits from uuidstr and compose a uuid
* of the given length (max 16), xoring bytes to make
* a smaller uuid.
*/
- int i = 0;
+ size_t i = 0;
memset(u, 0, uuidlen);
for ( ; *val ; val++) {
- char c = *val;
+ int c = *val;
if (!isxdigit(c))
continue;
if (isalpha(c)) {
c = c - '0' + 0;
if ((i&1) == 0)
c <<= 4;
- u[i/2] ^= c;
+ u[i/2] ^= (char)c;
i++;
if (i == uuidlen*2)
i = 0;
return 1;
}
-static int uuid_by_path(char *path, int type, int uuidlen, char *uuid)
+static int uuid_by_path(char *path, int type, size_t uuidlen, char *uuid)
{
/* get a uuid for the filesystem found at 'path'.
* There are several possible ways of generating the
{
FILE *f;
struct mntent *me;
- int l = strlen(p);
+ size_t l = strlen(p);
if (*v == NULL) {
f = setmntent("/etc/mtab", "r");
*v = f;
return me->mnt_dir;
}
+static int is_subdirectory(char *child, char *parent)
+{
+ size_t l = strlen(parent);
+
+ if (strcmp(parent, "/") == 0)
+ return 1;
+
+ return strcmp(child, parent) == 0
+ || (strncmp(child, parent, l) == 0 && child[l] == '/');
+}
+
+static int path_matches(nfs_export *exp, char *path)
+{
+ if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT)
+ return is_subdirectory(path, exp->m_export.e_path);
+ return strcmp(path, exp->m_export.e_path) == 0;
+}
+
+static int
+export_matches(nfs_export *exp, char *dom, char *path, struct addrinfo *ai)
+{
+ return path_matches(exp, path) && client_matches(exp, dom, ai);
+}
+
/* True iff e1 is a child of e2 and e2 has crossmnt set: */
static bool subexport(struct exportent *e1, struct exportent *e2)
{
char *p1 = e1->e_path, *p2 = e2->e_path;
- int l2 = strlen(p2);
+ size_t l2 = strlen(p2);
return e2->e_flags & NFSEXP_CROSSMOUNT
- && strncmp(p1, p2, l2) == 0
- && p1[l2] == '/';
+ && strncmp(p1, p2, l2) == 0
+ && p1[l2] == '/';
}
struct parsed_fsid {
unsigned int minor;
unsigned int major;
unsigned int fsidnum;
- int uuidlen;
+ size_t uuidlen;
char *fhuuid;
};
-int parse_fsid(int fsidtype, int fsidlen, char *fsid, struct parsed_fsid *parsed)
+static int parse_fsid(int fsidtype, int fsidlen, char *fsid,
+ struct parsed_fsid *parsed)
{
unsigned int dev;
unsigned long long inode64;
+ memset(parsed, 0, sizeof(*parsed));
parsed->fsidtype = fsidtype;
switch(fsidtype) {
case FSID_DEV: /* 4 bytes: 2 major, 2 minor, 4 inode */
return false;
}
-struct addrinfo *lookup_client_addr(char *dom)
+static struct addrinfo *lookup_client_addr(char *dom)
{
struct addrinfo *ret;
struct addrinfo *tmp;
/* There was no sec= option */
return;
}
+ fix_pseudoflavor_flags(ep);
qword_print(f, "secinfo");
qword_printint(f, p - ep->e_secinfo);
for (p = ep->e_secinfo; p->flav; p++) {
int different_fs = strcmp(path, exp->e_path) != 0;
int flag_mask = different_fs ? ~NFSEXP_FSID : ~0;
- qword_printuint(f, time(0) + exp->e_ttl);
+ qword_printtimefrom(f, exp->e_ttl);
qword_printint(f, exp->e_flags & flag_mask);
qword_printint(f, exp->e_anonuid);
qword_printint(f, exp->e_anongid);
qword_printhex(f, u, 16);
}
} else
- qword_printuint(f, time(0) + DEFAULT_TTL);
+ qword_printtimefrom(f, DEFAULT_TTL);
return qword_eol(f);
}
-static int is_subdirectory(char *child, char *parent)
-{
- int l = strlen(parent);
-
- return strcmp(child, parent) == 0
- || (strncmp(child, parent, l) == 0 && child[l] == '/');
-}
-
-static int path_matches(nfs_export *exp, char *path)
-{
- if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT)
- return is_subdirectory(path, exp->m_export.e_path);
- return strcmp(path, exp->m_export.e_path) == 0;
-}
-
-static int
-export_matches(nfs_export *exp, char *dom, char *path, struct addrinfo *ai)
-{
- return path_matches(exp, path) && client_matches(exp, dom, ai);
-}
-
static nfs_export *
lookup_export(char *dom, char *path, struct addrinfo *ai)
{
#ifdef HAVE_NFS_PLUGIN_H
#include <dlfcn.h>
+#include <link.h>
#include <nfs-plugin.h>
/*
/*
* Duplicate the junction's parent's export options and graft in
* the fslocdata we constructed from the locations list.
- *
- * Returned exportent points to static memory.
*/
static struct exportent *create_junction_exportent(struct exportent *parent,
const char *junction, const char *fslocdata, int ttl)
{
- static struct exportent ee;
+ static struct exportent *eep;
- dupexportent(&ee, parent);
- strcpy(ee.e_path, junction);
- ee.e_hostname = strdup(parent->e_hostname);
- if (ee.e_hostname == NULL)
- goto out_nomem;
- free(ee.e_uuid);
- ee.e_uuid = NULL;
- ee.e_ttl = (unsigned int)ttl;
-
- free(ee.e_fslocdata);
- ee.e_fslocmethod = FSLOC_REFER;
- ee.e_fslocdata = strdup(fslocdata);
- if (ee.e_fslocdata == NULL)
+ eep = (struct exportent *)malloc(sizeof(*eep));
+ if (eep == NULL)
goto out_nomem;
- return ⅇ
+ dupexportent(eep, parent);
+ strcpy(eep->e_path, junction);
+ eep->e_hostname = strdup(parent->e_hostname);
+ if (eep->e_hostname == NULL) {
+ free(eep);
+ goto out_nomem;
+ }
+ free(eep->e_uuid);
+ eep->e_uuid = NULL;
+ eep->e_ttl = (unsigned int)ttl;
+
+ free(eep->e_fslocdata);
+ eep->e_fslocdata = strdup(fslocdata);
+ if (eep->e_fslocdata == NULL) {
+ free(eep->e_hostname);
+ free(eep);
+ goto out_nomem;
+ }
+ eep->e_fslocmethod = FSLOC_REFER;
+ return eep;
out_nomem:
xlog(L_ERROR, "%s: No memory", __func__);
/*
* Walk through the set of FS locations and build an exportent.
* Returns pointer to an exportent if "junction" refers to a junction.
- *
- * Returned exportent points to static memory.
*/
static struct exportent *locations_to_export(struct jp_ops *ops,
nfs_fsloc_set_t locations, const char *junction,
* Retrieve locations information in "junction" and dump it to the
* kernel. Returns pointer to an exportent if "junction" refers
* to a junction.
- *
- * Returned exportent points to static memory.
*/
static struct exportent *invoke_junction_ops(void *handle, char *dom,
const char *junction, struct addrinfo *ai)
* Load the junction plug-in, then try to resolve "pathname".
* Returns pointer to an initialized exportent if "junction"
* refers to a junction, or NULL if not.
- *
- * Returned exportent points to static memory.
*/
static struct exportent *lookup_junction(char *dom, const char *pathname,
struct addrinfo *ai)
{
struct exportent *exp;
+ struct link_map *map;
void *handle;
handle = dlopen("libnfsjunct.so", RTLD_NOW);
xlog(D_GENERAL, "%s: dlopen: %s", __func__, dlerror());
return NULL;
}
+
+ if (dlinfo(handle, RTLD_DI_LINKMAP, &map) == 0)
+ xlog(D_GENERAL, "%s: loaded plug-in %s",
+ __func__, map->l_name);
+
(void)dlerror(); /* Clear any error */
exp = invoke_junction_ops(handle, dom, pathname, ai);
(void)dlclose(handle);
return exp;
}
+
+static void lookup_nonexport(FILE *f, char *dom, char *path,
+ struct addrinfo *ai)
+{
+ struct exportent *eep;
+
+ eep = lookup_junction(dom, path, ai);
+ dump_to_cache(f, dom, path, eep);
+ if (eep == NULL)
+ return;
+ exportent_release(eep);
+ free(eep);
+}
#else /* !HAVE_NFS_PLUGIN_H */
-static inline struct exportent *lookup_junction(char *UNUSED(dom),
- const char *UNUSED(pathname), struct addrinfo *UNUSED(ai))
+static void lookup_nonexport(FILE *f, char *dom, char *path,
+ struct addrinfo *UNUSED(ai))
{
- return NULL;
+ dump_to_cache(f, dom, path, NULL);
}
#endif /* !HAVE_NFS_PLUGIN_H */
" or fsid= required", path);
dump_to_cache(f, dom, path, NULL);
}
- } else {
- dump_to_cache(f, dom, path, lookup_junction(dom, path, ai));
- }
+ } else
+ lookup_nonexport(f, dom, path, ai);
+
out:
xlog(D_CALL, "nfsd_export: found %p path %s", found, path ? path : NULL);
if (dom) free(dom);
qword_print(f, "nfsd");
qword_print(f,
host_ntop(get_addrlist(exp->m_client, 0), buf, sizeof(buf)));
- qword_printuint(f, time(0) + exp->m_export.e_ttl);
+ qword_printtimefrom(f, exp->m_export.e_ttl);
qword_print(f, exp->m_client->m_hostname);
err = qword_eol(f);