summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/nss/nsssrv.c13
-rw-r--r--server/nss/nsssrv.h1
-rw-r--r--server/nss/nsssrv_cmd.c59
3 files changed, 72 insertions, 1 deletions
diff --git a/server/nss/nsssrv.c b/server/nss/nsssrv.c
index 0c7bf060..93a897a2 100644
--- a/server/nss/nsssrv.c
+++ b/server/nss/nsssrv.c
@@ -359,9 +359,12 @@ failed:
return EIO;
}
+/* domain names are case insensitive for now
+ * NOTE: this function is not utf-8 safe,
+ * only ASCII names for now */
static int _domain_comparator(void *key1, void *key2)
{
- return strcmp((char *)key1, (char *)key2);
+ return strcasecmp((char *)key1, (char *)key2);
}
static int nss_init_domains(struct nss_ctx *nctx)
@@ -397,6 +400,14 @@ static int nss_init_domains(struct nss_ctx *nctx)
goto done;
}
+ ret = confdb_get_string(nctx->cdb, nctx,
+ "config/domains", "default",
+ NULL, &nctx->default_domain);
+ if (ret != EOK) {
+ retval = ret;
+ goto done;
+ }
+
retval = EOK;
done:
diff --git a/server/nss/nsssrv.h b/server/nss/nsssrv.h
index ce1f7b23..795b8fa7 100644
--- a/server/nss/nsssrv.h
+++ b/server/nss/nsssrv.h
@@ -54,6 +54,7 @@ struct nss_ctx {
struct service_sbus_ctx *ss_ctx;
struct service_sbus_ctx *dp_ctx;
struct btreemap *domain_map;
+ char *default_domain;
int cache_timeout;
};
diff --git a/server/nss/nsssrv_cmd.c b/server/nss/nsssrv_cmd.c
index 95a52ea2..c2ad986c 100644
--- a/server/nss/nsssrv_cmd.c
+++ b/server/nss/nsssrv_cmd.c
@@ -80,6 +80,50 @@ static int nss_cmd_send_error(struct nss_cmd_ctx *nctx, int err)
return; \
} while(0)
+static int nss_check_domain(struct ldb_dn *dn,
+ struct btreemap *domain_map,
+ const char *def_domain, const char *domain)
+{
+ /* FIXME: it would be better to use ldb_dn_compare() */
+ const char *lineardn;
+ const char *basedn;
+ const char *key;
+ int blen, llen;
+
+ lineardn = ldb_dn_get_linearized(dn);
+ if (!lineardn || !*lineardn) {
+ DEBUG(4, ("Invalid DN (empty)\n"));
+ return EINVAL;
+ }
+ llen = strlen(lineardn);
+
+ /* if domain is NULL check if it is the default domain or LOCAL */
+ if (domain) {
+ key = domain;
+ } else if (def_domain) {
+ key = def_domain;
+ } else {
+ key = "LOCAL";
+ }
+
+ basedn = btreemap_get_value(domain_map, (void *)key);
+ if (!basedn) {
+ DEBUG(4, ("Domain (%s) not found in map!\n", domain));
+ return EINVAL;
+ }
+
+ blen = strlen(basedn);
+ if (blen < llen) {
+ if (strcasecmp(basedn, &lineardn[llen-blen]) == 0)
+ return EOK;
+ }
+
+ DEBUG(4, ("DN %s, does not match domain %s (or %s (or LOCAL))\n",
+ ldb_dn_get_linearized(dn), domain, def_domain));
+
+ return EINVAL;
+}
+
static int nss_cmd_get_version(struct cli_ctx *cctx)
{
struct nss_cmd_ctx *nctx;
@@ -240,6 +284,8 @@ static void nss_cmd_getpw_callback(void *ptr, int status,
if (res->count != 1) {
if (res->count > 1) {
+ /* FIXME: when multiple domains are configured this is possible.
+ * Add logic to select which result to return */
DEBUG(1, ("getpwnam call returned more than one result !?!\n"));
}
if (res->count == 0) {
@@ -283,6 +329,19 @@ static void nss_cmd_getpw_callback(void *ptr, int status,
}
}
+ if (nctx->name) {
+ /* before returning results check if they match their domain */
+ /* FIXME: pass the current default domain in here */
+ ret = nss_check_domain(res->msgs[0]->dn, cctx->nctx->domain_map,
+ cctx->nctx->default_domain, nctx->domain);
+ if (ret != EOK) {
+ ret = nss_cmd_send_error(nctx, ret);
+ }
+ if (ret != EOK) {
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+ }
+
/* create response packet */
ret = nss_packet_new(cctx->creq, 0,
nss_packet_get_cmd(cctx->creq->in),