You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
438 lines
9.3 KiB
438 lines
9.3 KiB
diff --git a/.gitignore b/.gitignore |
|
index 6244609..d24d727 100644 |
|
--- a/.gitignore |
|
+++ b/.gitignore |
|
@@ -17,18 +17,13 @@ libnfsidmap.pc |
|
libtool |
|
.libs/ |
|
libnfsidmap.la |
|
-libnfsidmap_la-cfg.lo |
|
-libnfsidmap_la-libnfsidmap.lo |
|
-libnfsidmap_la-strlcpy.lo |
|
-nss.lo |
|
nsswitch.la |
|
static.la |
|
-static.lo |
|
umich_ldap.la |
|
-umich_ldap.lo |
|
configure.in~ |
|
m4/ |
|
*.o |
|
+*.lo |
|
cscope.* |
|
config.h |
|
config.h.in |
|
diff --git a/autogen.sh b/autogen.sh |
|
index ee89987..c17f6be 100755 |
|
--- a/autogen.sh |
|
+++ b/autogen.sh |
|
@@ -37,5 +37,6 @@ fi |
|
|
|
aclocal |
|
libtoolize --force --copy |
|
-autoupdate |
|
+autoheader |
|
+automake --add-missing --copy --gnu |
|
autoreconf -vi -Wall |
|
diff --git a/idmapd.conf.5 b/idmapd.conf.5 |
|
index 9c7f1ae..de1bfa9 100644 |
|
--- a/idmapd.conf.5 |
|
+++ b/idmapd.conf.5 |
|
@@ -31,7 +31,7 @@ |
|
.\" |
|
.TH idmapd.conf 5 "19 Nov 2008" |
|
.SH NAME |
|
-idmapd.conf |
|
+idmapd.conf \- configuration file for libnfsidmap |
|
.SH SYNOPSIS |
|
Configuration file for libnfsidmap. Used by idmapd and svcgssd to map NFSv4 name to and from ids. |
|
.SH DESCRIPTION |
|
@@ -234,7 +234,6 @@ Number of seconds before timing out an LDAP request |
|
.\" ------------------------------------------------------------------- |
|
.\" |
|
.SH EXAMPLES |
|
-." |
|
An example |
|
.I /etc/idmapd.conf |
|
file: |
|
@@ -266,7 +265,7 @@ johndoe@OTHER.DOMAIN.ORG = johnny |
|
LDAP_server = ldap.domain.org |
|
LDAP_base = dc=org,dc=domain |
|
|
|
-.fo |
|
+.fi |
|
.\" |
|
.\" ------------------------------------------------------------------- |
|
.\" Additional sections |
|
@@ -275,11 +274,11 @@ LDAP_base = dc=org,dc=domain |
|
.SH SEE ALSO |
|
.BR idmapd (8) |
|
.BR svcgssd (8) |
|
-.".SH COMPATIBILITY |
|
-.".SH STANDARDS |
|
-.".SH ACKNOWLEDGEMENTS |
|
-.".SH AUTHORS |
|
-.".SH HISTORY |
|
+.\".SH COMPATIBILITY |
|
+.\".SH STANDARDS |
|
+.\".SH ACKNOWLEDGEMENTS |
|
+.\".SH AUTHORS |
|
+.\".SH HISTORY |
|
.SH BUGS |
|
Report bugs to <nfsv4@linux-nfs.org> |
|
-.".SH CAVEATS |
|
+.\".SH CAVEATS |
|
diff --git a/libnfsidmap.c b/libnfsidmap.c |
|
index 57bb6c3..641d766 100644 |
|
--- a/libnfsidmap.c |
|
+++ b/libnfsidmap.c |
|
@@ -285,8 +285,9 @@ int nfs4_init_name_mapping(char *conffile) |
|
} |
|
buf = malloc(siz); |
|
if (buf) { |
|
+ *buf = 0; |
|
TAILQ_FOREACH(r, &local_realms->fields, link) { |
|
- sprintf(buf, "'%s' ", r->field); |
|
+ sprintf(buf+strlen(buf), "'%s' ", r->field); |
|
} |
|
IDMAP_LOG(1, ("libnfsidmap: Realms list: %s", buf)); |
|
free(buf); |
|
diff --git a/static.c b/static.c |
|
index fffd458..8be87e8 100644 |
|
--- a/static.c |
|
+++ b/static.c |
|
@@ -40,6 +40,7 @@ |
|
#include <grp.h> |
|
#include <errno.h> |
|
|
|
+#include "queue.h" |
|
#include "cfg.h" |
|
#include "nfsidmap.h" |
|
#include "nfsidmap_internal.h" |
|
@@ -57,6 +58,40 @@ struct pwbuf { |
|
char buf[1]; |
|
}; |
|
|
|
+struct grbuf { |
|
+ struct group grbuf; |
|
+ char buf[1]; |
|
+}; |
|
+ |
|
+struct uid_mapping { |
|
+ LIST_ENTRY (uid_mapping) link; |
|
+ uid_t uid; |
|
+ char * principal; |
|
+ char * localname; |
|
+}; |
|
+ |
|
+struct gid_mapping { |
|
+ LIST_ENTRY (gid_mapping) link; |
|
+ gid_t gid; |
|
+ char * principal; |
|
+ char * localgroup; |
|
+}; |
|
+ |
|
+static __inline__ u_int8_t uid_hash (uid_t uid) |
|
+{ |
|
+ return uid % 256; |
|
+} |
|
+ |
|
+static __inline__ u_int8_t gid_hash (gid_t gid) |
|
+{ |
|
+ return gid % 256; |
|
+} |
|
+ |
|
+//Hash tables of uid and guids to principals mappings. |
|
+//We reuse some queue/hash functions from cfg.c. |
|
+LIST_HEAD (uid_mappings, uid_mapping) uid_mappings[256]; |
|
+LIST_HEAD (gid_mappings, gid_mapping) gid_mappings[256]; |
|
+ |
|
static struct passwd *static_getpwnam(const char *name, const char *domain, |
|
int *err_p) |
|
{ |
|
@@ -75,12 +110,9 @@ static struct passwd *static_getpwnam(const char *name, const char *domain, |
|
localname = conf_get_str("Static", (char *)name); |
|
if (!localname) { |
|
err = ENOENT; |
|
- goto err; |
|
+ goto err_free_buf; |
|
} |
|
|
|
- IDMAP_LOG(4, ("static_getpwnam: name '%s' mapped to '%s'\n", |
|
- name, localname)); |
|
- |
|
again: |
|
err = getpwnam_r(localname, &buf->pwbuf, buf->buf, buflen, &pw); |
|
|
|
@@ -91,12 +123,15 @@ again: |
|
if (err == 0) |
|
err = ENOENT; |
|
|
|
- IDMAP_LOG(0, ("static_getpwnam: name '%s' not found\n", |
|
- localname)); |
|
+ IDMAP_LOG(0, ("static_getpwnam: localname '%s' for '%s' not found\n", |
|
+ localname, name)); |
|
|
|
goto err_free_buf; |
|
} |
|
|
|
+ IDMAP_LOG(4, ("static_getpwnam: name '%s' mapped to '%s'\n", |
|
+ name, localname)); |
|
+ |
|
*err_p = 0; |
|
return pw; |
|
|
|
@@ -107,6 +142,56 @@ err: |
|
return NULL; |
|
} |
|
|
|
+static struct group *static_getgrnam(const char *name, const char *domain, |
|
+ int *err_p) |
|
+{ |
|
+ struct group *gr; |
|
+ struct grbuf *buf; |
|
+ size_t buflen = sysconf(_SC_GETGR_R_SIZE_MAX); |
|
+ char *localgroup; |
|
+ int err; |
|
+ |
|
+ buf = malloc(sizeof(*buf) + buflen); |
|
+ if (!buf) { |
|
+ err = ENOMEM; |
|
+ goto err; |
|
+ } |
|
+ |
|
+ localgroup = conf_get_str("Static", (char *)name); |
|
+ if (!localgroup) { |
|
+ err = ENOENT; |
|
+ goto err_free_buf; |
|
+ } |
|
+ |
|
+again: |
|
+ err = getgrnam_r(localgroup, &buf->grbuf, buf->buf, buflen, &gr); |
|
+ |
|
+ if (err == EINTR) |
|
+ goto again; |
|
+ |
|
+ if (!gr) { |
|
+ if (err == 0) |
|
+ err = ENOENT; |
|
+ |
|
+ IDMAP_LOG(0, ("static_getgrnam: local group '%s' for '%s' not found\n", |
|
+ localgroup, name)); |
|
+ |
|
+ goto err_free_buf; |
|
+ } |
|
+ |
|
+ IDMAP_LOG(4, ("static_getgrnam: group '%s' mapped to '%s'\n", |
|
+ name, localgroup)); |
|
+ |
|
+ *err_p = 0; |
|
+ return gr; |
|
+ |
|
+err_free_buf: |
|
+ free(buf); |
|
+err: |
|
+ *err_p = err; |
|
+ return NULL; |
|
+} |
|
+ |
|
static int static_gss_princ_to_ids(char *secname, char *princ, |
|
uid_t *uid, uid_t *gid, |
|
extra_mapping_params **ex) |
|
@@ -151,14 +236,173 @@ static int static_gss_princ_to_grouplist(char *secname, char *princ, |
|
return -err; |
|
} |
|
|
|
+static int static_name_to_uid(char *name, uid_t *uid) |
|
+{ |
|
+ struct passwd *pw; |
|
+ int err; |
|
+ |
|
+ pw = static_getpwnam(name, NULL, &err); |
|
+ |
|
+ if (pw) { |
|
+ *uid = pw->pw_uid; |
|
+ free(pw); |
|
+ } |
|
+ |
|
+ return -err; |
|
+} |
|
+ |
|
+static int static_name_to_gid(char *name, gid_t *gid) |
|
+{ |
|
+ struct group *gr; |
|
+ int err; |
|
+ |
|
+ gr = static_getgrnam(name, NULL, &err); |
|
+ |
|
+ if (gr) { |
|
+ *gid = gr->gr_gid; |
|
+ free(gr); |
|
+ } |
|
+ |
|
+ return -err; |
|
+} |
|
+ |
|
+static int static_uid_to_name(uid_t uid, char *domain, char *name, size_t len) |
|
+{ |
|
+ struct passwd *pw; |
|
+ struct uid_mapping * um; |
|
+ |
|
+ for (um = LIST_FIRST (&uid_mappings[uid_hash (uid)]); um; |
|
+ um = LIST_NEXT (um, link)) { |
|
+ if (um->uid == uid) { |
|
+ strcpy(name, um->principal); |
|
+ return 0; |
|
+ } |
|
+ } |
|
+ |
|
+ return -ENOENT; |
|
+} |
|
+ |
|
+static int static_gid_to_name(gid_t gid, char *domain, char *name, size_t len) |
|
+{ |
|
+ struct group *gr; |
|
+ struct gid_mapping * gm; |
|
+ |
|
+ for (gm = LIST_FIRST (&gid_mappings[gid_hash (gid)]); gm; |
|
+ gm = LIST_NEXT (gm, link)) { |
|
+ if (gm->gid == gid) { |
|
+ strcpy(name, gm->principal); |
|
+ return 0; |
|
+ } |
|
+ } |
|
+ |
|
+ return -ENOENT; |
|
+} |
|
+ |
|
+/* |
|
+ * We buffer all UID's for which static mappings is defined in advance, so the |
|
+ * uid_to_name functions will be fast enough. |
|
+ */ |
|
+ |
|
+static int static_init() { |
|
+ int err; |
|
+ uid_t uid; |
|
+ struct conf_list * princ_list = NULL; |
|
+ struct conf_list_node * cln, *next; |
|
+ struct uid_mapping * unode; |
|
+ struct gid_mapping * gnode; |
|
+ struct passwd * pw = NULL; |
|
+ struct group * gr = NULL; |
|
+ unsigned int i; |
|
+ |
|
+ //init hash_table first |
|
+ for (i = 0; i < sizeof uid_mappings / sizeof uid_mappings[0]; i++) |
|
+ LIST_INIT (&uid_mappings[i]); |
|
+ |
|
+ //get all principals for which we have mappings |
|
+ princ_list = conf_get_tag_list("Static"); |
|
+ |
|
+ if (!princ_list) { |
|
+ return -ENOENT; |
|
+ } |
|
+ |
|
+ /* As we can not distinguish between mappings for users and groups, we try to |
|
+ * resolve all mappings for both cases. |
|
+ */ |
|
+ |
|
+ //resolve uid of localname account for all such principals and cache it |
|
+ for (cln = TAILQ_FIRST (&princ_list->fields); cln; cln = next) |
|
+ { |
|
+ next = TAILQ_NEXT (cln, link); |
|
+ |
|
+ pw = static_getpwnam(cln->field, NULL, &err); |
|
+ if (!pw) { |
|
+ continue; |
|
+ } |
|
+ |
|
+ unode = calloc (1, sizeof *unode); |
|
+ if (!unode) |
|
+ { |
|
+ warnx("static_init: calloc (1, %lu) failed", |
|
+ (unsigned long)sizeof *unode); |
|
+ free(pw); |
|
+ return -ENOMEM; |
|
+ } |
|
+ unode->uid = pw->pw_uid; |
|
+ unode->principal = strdup(cln->field); |
|
+ |
|
+ unode->localname = conf_get_str("Static", cln->field); |
|
+ if (!unode->localname) { |
|
+ free(pw); |
|
+ return -ENOENT; |
|
+ } |
|
+ |
|
+ free(pw); |
|
+ |
|
+ LIST_INSERT_HEAD (&uid_mappings[uid_hash(unode->uid)], unode, link); |
|
+ } |
|
+ |
|
+ //resolve gid of localgroup accounts and cache it |
|
+ for (cln = TAILQ_FIRST (&princ_list->fields); cln; cln = next) |
|
+ { |
|
+ next = TAILQ_NEXT (cln, link); |
|
+ |
|
+ gr = static_getgrnam(cln->field, NULL, &err); |
|
+ if (!pw) { |
|
+ continue; |
|
+ } |
|
+ |
|
+ gnode = calloc (1, sizeof *gnode); |
|
+ if (!gnode) |
|
+ { |
|
+ warnx("static_init: calloc (1, %lu) failed", |
|
+ (unsigned long)sizeof *gnode); |
|
+ free(pw); |
|
+ return -ENOMEM; |
|
+ } |
|
+ gnode->gid = pw->pw_uid; |
|
+ gnode->principal = strdup(cln->field); |
|
+ |
|
+ gnode->localgroup = conf_get_str("Static", cln->field); |
|
+ if (!gnode->localgroup) { |
|
+ free(pw); |
|
+ return -ENOENT; |
|
+ } |
|
+ |
|
+ free(pw); |
|
+ |
|
+ LIST_INSERT_HEAD (&gid_mappings[gid_hash(gnode->gid)], gnode, link); |
|
+ } |
|
+ return 0; |
|
+} |
|
+ |
|
|
|
struct trans_func static_trans = { |
|
.name = "static", |
|
- .init = NULL, |
|
- .name_to_uid = NULL, |
|
- .name_to_gid = NULL, |
|
- .uid_to_name = NULL, |
|
- .gid_to_name = NULL, |
|
+ .init = static_init, |
|
+ .name_to_uid = static_name_to_uid, |
|
+ .name_to_gid = static_name_to_gid, |
|
+ .uid_to_name = static_uid_to_name, |
|
+ .gid_to_name = static_gid_to_name, |
|
.princ_to_ids = static_gss_princ_to_ids, |
|
.gss_princ_to_grouplist = static_gss_princ_to_grouplist, |
|
}; |
|
diff --git a/umich_ldap.c b/umich_ldap.c |
|
index f482b0a..b527c5d 100644 |
|
--- a/umich_ldap.c |
|
+++ b/umich_ldap.c |
|
@@ -32,8 +32,6 @@ |
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
*/ |
|
|
|
-#ifdef ENABLE_LDAP |
|
- |
|
#include <sys/types.h> |
|
#include <sys/socket.h> |
|
#include <netdb.h> |
|
@@ -1302,4 +1300,3 @@ struct trans_func *libnfsidmap_plugin_init() |
|
{ |
|
return (&umichldap_trans); |
|
} |
|
-#endif
|
|
|