summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/confdb/confdb.h1
-rw-r--r--src/config/SSSDConfig/__init__.py.in1
-rwxr-xr-xsrc/config/SSSDConfigTest.py4
-rw-r--r--src/config/etc/sssd.api.conf1
-rw-r--r--src/man/sssd.conf.5.xml24
-rw-r--r--src/responder/autofs/autofssrv_cmd.c3
-rw-r--r--src/responder/common/negcache.c10
-rw-r--r--src/responder/common/responder.h3
-rw-r--r--src/responder/common/responder_common.c10
-rw-r--r--src/responder/nss/nsssrv_cmd.c18
-rw-r--r--src/responder/nss/nsssrv_netgroup.c3
-rw-r--r--src/responder/nss/nsssrv_services.c5
-rw-r--r--src/responder/pam/pamsrv_cmd.c31
-rw-r--r--src/responder/ssh/sshsrv_cmd.c3
-rw-r--r--src/responder/sudo/sudosrv_query.c3
-rw-r--r--src/util/usertools.c52
16 files changed, 137 insertions, 35 deletions
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index c6611f27..39267d3b 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -66,6 +66,7 @@
#define CONFDB_MONITOR_ACTIVE_DOMAINS "domains"
#define CONFDB_MONITOR_TRY_INOTIFY "try_inotify"
#define CONFDB_MONITOR_KRB5_RCACHEDIR "krb5_rcache_dir"
+#define CONFDB_MONITOR_DEFAULT_DOMAIN "default_domain_suffix"
/* Both monitor and domains */
#define CONFDB_NAME_REGEX "re_expression"
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index b90a8e10..5d023d78 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -54,6 +54,7 @@ option_strings = {
're_expression' : _('Regex to parse username and domain'),
'full_name_format' : _('Printf-compatible format for displaying fully-qualified names'),
'krb5_rcache_dir' : _('Directory on the filesystem where SSSD should store Kerberos replay cache files.'),
+ 'default_domain_suffix' : _('Domain to add to names without a domain component.'),
# [nss]
'enum_cache_timeout' : _('Enumeration cache timeout length (seconds)'),
diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py
index b03223f4..73e1ea69 100755
--- a/src/config/SSSDConfigTest.py
+++ b/src/config/SSSDConfigTest.py
@@ -84,6 +84,9 @@ class SSSDConfigTestValid(unittest.TestCase):
self.assertTrue('full_name_format' in new_options)
self.assertEquals(new_options['full_name_format'][0], str)
+ self.assertTrue('default_domain_suffix' in new_options)
+ self.assertEquals(new_options['default_domain_suffix'][0], str)
+
del sssdconfig
def testDomains(self):
@@ -277,6 +280,7 @@ class SSSDConfigTestSSSDService(unittest.TestCase):
're_expression',
'full_name_format',
'krb5_rcache_dir',
+ 'default_domain_suffix',
'debug_level',
'debug_timestamps',
'debug_microseconds',
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
index fe5a0962..f17fbb50 100644
--- a/src/config/etc/sssd.api.conf
+++ b/src/config/etc/sssd.api.conf
@@ -22,6 +22,7 @@ sbus_timeout = int, None, false
re_expression = str, None, false
full_name_format = str, None, false
krb5_rcache_dir = str, None, false
+default_domain_suffix = str, None, false
[nss]
# Name service
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index 652a2734..6fbbd9ad 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -214,6 +214,30 @@
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>default_domain_suffix (string)</term>
+ <listitem>
+ <para>
+ This string will be used as a default domain
+ name for all names without a domain name
+ component. The main use case are environments
+ were the local domain is only managing hosts
+ but no users and all users are coming from a
+ trusted domain. The option allows those users
+ to log in just with their user name without
+ giving a domain name as well.
+ </para>
+ <para>
+ Please note that if this option is set all
+ users from the local domain have to use their
+ fully qualified name, e.g. user@domain.name,
+ to log in.
+ </para>
+ <para>
+ Default: not set
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</para>
</refsect2>
diff --git a/src/responder/autofs/autofssrv_cmd.c b/src/responder/autofs/autofssrv_cmd.c
index 4dfa94e4..3af4a846 100644
--- a/src/responder/autofs/autofssrv_cmd.c
+++ b/src/responder/autofs/autofssrv_cmd.c
@@ -374,7 +374,8 @@ setautomntent_send(TALLOC_CTX *mem_ctx,
dctx->cmd_ctx = state->cmdctx;
state->dctx = dctx;
- ret = sss_parse_name_for_domains(state, client->rctx->domains, rawname,
+ ret = sss_parse_name_for_domains(state, client->rctx->domains,
+ client->rctx->default_domain, rawname,
&domname, &state->mapname);
if (ret != EOK) {
DEBUG(SSSDBG_FATAL_FAILURE,
diff --git a/src/responder/common/negcache.c b/src/responder/common/negcache.c
index b59b1f34..5be1ea68 100644
--- a/src/responder/common/negcache.c
+++ b/src/responder/common/negcache.c
@@ -596,7 +596,9 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache,
filter_set = true;
for (i = 0; (filter_list && filter_list[i]); i++) {
- ret = sss_parse_name_for_domains(tmpctx, domain_list, filter_list[i],
+ ret = sss_parse_name_for_domains(tmpctx, domain_list,
+ rctx->default_domain,
+ filter_list[i],
&domainname, &name);
if (ret != EOK) {
DEBUG(1, ("Invalid name in filterUsers list: [%s] (%d)\n",
@@ -641,7 +643,8 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache,
else if (ret != EOK) goto done;
for (i = 0; (filter_list && filter_list[i]); i++) {
- ret = sss_parse_name_for_domains(tmpctx, domain_list, filter_list[i],
+ ret = sss_parse_name_for_domains(tmpctx, domain_list,
+ rctx->default_domain, filter_list[i],
&domainname, &name);
if (ret != EOK) {
DEBUG(1, ("Invalid name in filterUsers list: [%s] (%d)\n",
@@ -738,7 +741,8 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache,
else if (ret != EOK) goto done;
for (i = 0; (filter_list && filter_list[i]); i++) {
- ret = sss_parse_name_for_domains(tmpctx, domain_list, filter_list[i],
+ ret = sss_parse_name_for_domains(tmpctx, domain_list,
+ rctx->default_domain, filter_list[i],
&domainname, &name);
if (ret != EOK) {
DEBUG(1, ("Invalid name in filterGroups list: [%s] (%d)\n",
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
index c09262d1..5bab0d3c 100644
--- a/src/responder/common/responder.h
+++ b/src/responder/common/responder.h
@@ -101,6 +101,8 @@ struct resp_ctx {
size_t allowed_uids_count;
uid_t *allowed_uids;
+ char *default_domain;
+
void *pvt_ctx;
};
@@ -160,6 +162,7 @@ int sss_parse_name(TALLOC_CTX *memctx,
int sss_parse_name_for_domains(TALLOC_CTX *memctx,
struct sss_domain_info *domains,
+ const char *default_domain,
const char *orig, char **domain, char **name);
int sss_dp_get_domain_conn(struct resp_ctx *rctx, const char *domain,
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index 37a08d94..2f8cd84d 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -783,6 +783,16 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
return ret;
}
+ ret = confdb_get_string(rctx->cdb, rctx, CONFDB_MONITOR_CONF_ENTRY,
+ CONFDB_MONITOR_DEFAULT_DOMAIN, NULL,
+ &rctx->default_domain);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ ("Cannnot get the default domain [%d]: %s\n",
+ ret, strerror(ret)));
+ return ret;
+ }
+
ret = sss_monitor_init(rctx, rctx->ev, monitor_intf,
svc_name, svc_version, rctx,
&rctx->mon_conn);
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index 64fd7a58..370c3d29 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -806,7 +806,8 @@ static int nss_cmd_getpwnam(struct cli_ctx *cctx)
rawname = (const char *)body;
domname = NULL;
- ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, rawname,
+ ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains,
+ cctx->rctx->default_domain, rawname,
&domname, &cmdctx->name);
if (ret == EAGAIN) {
req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, domname);
@@ -878,7 +879,8 @@ static void nss_cmd_getpwnam_cb(struct tevent_req *req)
goto done;
}
- ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, rawname,
+ ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains,
+ cctx->rctx->default_domain, rawname,
&domname, &cmdctx->name);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Invalid name received [%s]\n", rawname));
@@ -2293,7 +2295,8 @@ static int nss_cmd_getgrnam(struct cli_ctx *cctx)
rawname = (const char *)body;
domname = NULL;
- ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, rawname,
+ ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains,
+ cctx->rctx->default_domain, rawname,
&domname, &cmdctx->name);
if (ret == EAGAIN) {
req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, domname);
@@ -2365,7 +2368,8 @@ static void nss_cmd_getgrnam_cb(struct tevent_req *req)
goto done;
}
- ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, rawname,
+ ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains,
+ cctx->rctx->default_domain, rawname,
&domname, &cmdctx->name);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Invalid name received [%s]\n", rawname));
@@ -3423,7 +3427,8 @@ static int nss_cmd_initgroups(struct cli_ctx *cctx)
rawname = (const char *)body;
domname = NULL;
- ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, rawname,
+ ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains,
+ cctx->rctx->default_domain, rawname,
&domname, &cmdctx->name);
if (ret == EAGAIN) {
req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, domname);
@@ -3495,7 +3500,8 @@ static void nss_cmd_initgroups_cb(struct tevent_req *req)
goto done;
}
- ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, rawname,
+ ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains,
+ cctx->rctx->default_domain, rawname,
&domname, &cmdctx->name);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Invalid name received [%s]\n", rawname));
diff --git a/src/responder/nss/nsssrv_netgroup.c b/src/responder/nss/nsssrv_netgroup.c
index 774d182b..ae993fac 100644
--- a/src/responder/nss/nsssrv_netgroup.c
+++ b/src/responder/nss/nsssrv_netgroup.c
@@ -197,7 +197,8 @@ static struct tevent_req *setnetgrent_send(TALLOC_CTX *mem_ctx,
dctx = state->dctx;
dctx->cmdctx = state->cmdctx;
- ret = sss_parse_name_for_domains(state, client->rctx->domains, rawname,
+ ret = sss_parse_name_for_domains(state, client->rctx->domains,
+ client->rctx->default_domain, rawname,
&domname, &state->netgr_shortname);
if (ret != EOK) {
DEBUG(2, ("Invalid name received [%s]\n", rawname));
diff --git a/src/responder/nss/nsssrv_services.c b/src/responder/nss/nsssrv_services.c
index 880058fa..d79323c3 100644
--- a/src/responder/nss/nsssrv_services.c
+++ b/src/responder/nss/nsssrv_services.c
@@ -780,6 +780,7 @@ done:
errno_t parse_getservbyname(TALLOC_CTX *mem_ctx,
uint8_t *body, size_t blen,
struct sss_domain_info *domains,
+ char *default_domain,
char **domain_name,
char **service_name,
char **service_protocol);
@@ -821,6 +822,7 @@ int nss_cmd_getservbyname(struct cli_ctx *cctx)
ret = parse_getservbyname(cmdctx, body, blen,
cctx->rctx->domains,
+ cctx->rctx->default_domain,
&domname,
&service_name,
&service_protocol);
@@ -871,6 +873,7 @@ done:
errno_t parse_getservbyname(TALLOC_CTX *mem_ctx,
uint8_t *body, size_t blen,
struct sss_domain_info *domains,
+ char *default_domain,
char **domain_name,
char **service_name,
char **service_protocol)
@@ -959,7 +962,7 @@ errno_t parse_getservbyname(TALLOC_CTX *mem_ctx,
}
}
- ret = sss_parse_name_for_domains(tmp_ctx, domains, rawname,
+ ret = sss_parse_name_for_domains(tmp_ctx, domains, default_domain, rawname,
&domname, &svc_name);
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE,
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index 07fa96ab..2b20544d 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -119,8 +119,9 @@ static int pd_set_primary_name(const struct ldb_message *msg,struct pam_data *pd
}
static int pam_parse_in_data_v2(struct sss_domain_info *domains,
- struct pam_data *pd,
- uint8_t *body, size_t blen)
+ const char *default_domain,
+ struct pam_data *pd,
+ uint8_t *body, size_t blen)
{
size_t c;
uint32_t type;
@@ -156,7 +157,8 @@ static int pam_parse_in_data_v2(struct sss_domain_info *domains,
ret = extract_string(&pam_user, size, body, blen, &c);
if (ret != EOK) return ret;
- ret = sss_parse_name_for_domains(pd, domains, pam_user,
+ ret = sss_parse_name_for_domains(pd, domains,
+ default_domain, pam_user,
&pd->domain, &pd->user);
if (ret != EOK) return ret;
break;
@@ -209,12 +211,13 @@ static int pam_parse_in_data_v2(struct sss_domain_info *domains,
}
static int pam_parse_in_data_v3(struct sss_domain_info *domains,
- struct pam_data *pd,
- uint8_t *body, size_t blen)
+ const char *default_domain,
+ struct pam_data *pd,
+ uint8_t *body, size_t blen)
{
int ret;
- ret = pam_parse_in_data_v2(domains, pd, body, blen);
+ ret = pam_parse_in_data_v2(domains, default_domain, pd, body, blen);
if (ret != EOK) {
DEBUG(1, ("pam_parse_in_data_v2 failed.\n"));
return ret;
@@ -229,6 +232,7 @@ static int pam_parse_in_data_v3(struct sss_domain_info *domains,
}
static int pam_parse_in_data(struct sss_domain_info *domains,
+ const char *default_domain,
struct pam_data *pd,
uint8_t *body, size_t blen)
{
@@ -244,7 +248,8 @@ static int pam_parse_in_data(struct sss_domain_info *domains,
for (start = end; end < last; end++) if (body[end] == '\0') break;
if (body[end++] != '\0') return EINVAL;
- ret = sss_parse_name_for_domains(pd, domains, (char *)&body[start], &pd->domain, &pd->user);
+ ret = sss_parse_name_for_domains(pd, domains, default_domain,
+ (char *)&body[start], &pd->domain, &pd->user);
if (ret != EOK) return ret;
for (start = end; end < last; end++) if (body[end] == '\0') break;
@@ -997,13 +1002,19 @@ errno_t pam_forwarder_parse_data(struct cli_ctx *cctx, struct pam_data *pd)
switch (cctx->cli_protocol_version->version) {
case 1:
- ret = pam_parse_in_data(cctx->rctx->domains, pd, body, blen);
+ ret = pam_parse_in_data(cctx->rctx->domains,
+ cctx->rctx->default_domain, pd,
+ body, blen);
break;
case 2:
- ret = pam_parse_in_data_v2(cctx->rctx->domains, pd, body, blen);
+ ret = pam_parse_in_data_v2(cctx->rctx->domains,
+ cctx->rctx->default_domain, pd,
+ body, blen);
break;
case 3:
- ret = pam_parse_in_data_v3(cctx->rctx->domains, pd, body, blen);
+ ret = pam_parse_in_data_v3(cctx->rctx->domains,
+ cctx->rctx->default_domain, pd,
+ body, blen);
break;
default:
DEBUG(1, ("Illegal protocol version [%d].\n",
diff --git a/src/responder/ssh/sshsrv_cmd.c b/src/responder/ssh/sshsrv_cmd.c
index 82a1f901..6c10967e 100644
--- a/src/responder/ssh/sshsrv_cmd.c
+++ b/src/responder/ssh/sshsrv_cmd.c
@@ -701,7 +701,8 @@ ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx)
}
c += name_len;
- ret = sss_parse_name_for_domains(cmd_ctx, cctx->rctx->domains, name,
+ ret = sss_parse_name_for_domains(cmd_ctx, cctx->rctx->domains,
+ cctx->rctx->default_domain,name,
&cmd_ctx->domname, &cmd_ctx->name);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Invalid name received [%s]\n", name));
diff --git a/src/responder/sudo/sudosrv_query.c b/src/responder/sudo/sudosrv_query.c
index 7ba80e2a..824f682c 100644
--- a/src/responder/sudo/sudosrv_query.c
+++ b/src/responder/sudo/sudosrv_query.c
@@ -312,7 +312,8 @@ errno_t sudosrv_parse_query(TALLOC_CTX *mem_ctx,
/* parse username */
- ret = sss_parse_name_for_domains(tmp_ctx, rctx->domains, rawname,
+ ret = sss_parse_name_for_domains(tmp_ctx, rctx->domains,
+ rctx->default_domain, rawname,
&domainname, &username);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid name received [%s]\n", rawname));
diff --git a/src/util/usertools.c b/src/util/usertools.c
index 6a5720d7..0ef39549 100644
--- a/src/util/usertools.c
+++ b/src/util/usertools.c
@@ -310,6 +310,7 @@ static struct sss_domain_info * match_any_domain_or_subdomain_name (
int sss_parse_name_for_domains(TALLOC_CTX *memctx,
struct sss_domain_info *domains,
+ const char *default_domain,
const char *orig, char **domain, char **name)
{
struct sss_domain_info *dom, *match;
@@ -319,7 +320,7 @@ int sss_parse_name_for_domains(TALLOC_CTX *memctx,
char *candidate_domain = NULL;
bool name_mismatch = false;
TALLOC_CTX *tmp_ctx;
- int code;
+ int ret;
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL)
@@ -329,8 +330,8 @@ int sss_parse_name_for_domains(TALLOC_CTX *memctx,
rdomain = NULL;
for (dom = domains; dom != NULL; dom = dom->next) {
- code = sss_parse_name(tmp_ctx, dom->names, orig, &dmatch, &nmatch);
- if (code == EOK) {
+ ret = sss_parse_name(tmp_ctx, dom->names, orig, &dmatch, &nmatch);
+ if (ret == EOK) {
/*
* If the name matched without the domain part, make note of it.
* All the other domain expressions must agree on the domain-less
@@ -363,28 +364,55 @@ int sss_parse_name_for_domains(TALLOC_CTX *memctx,
}
/* EINVAL is returned when name doesn't match */
- } else if (code != EINVAL) {
- talloc_free(tmp_ctx);
- return code;
+ } else if (ret != EINVAL) {
+ goto done;
}
}
if (rdomain == NULL && rname == NULL) {
if (candidate_name && !name_mismatch) {
- DEBUG(SSSDBG_FUNC_DATA,
- ("name '%s' matched without domain, user is %s\n", orig, nmatch));
+ DEBUG(SSSDBG_FUNC_DATA, ("name '%s' matched without domain, " \
+ "user is %s\n", orig, nmatch));
rdomain = NULL;
+ if (default_domain != NULL) {
+ rdomain = talloc_strdup(tmp_ctx, default_domain);
+ if (default_domain == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
+ ret = ENOMEM;
+ goto done;
+ }
+
+ for (dom = domains; dom != NULL; dom = dom->next) {
+ match = match_any_domain_or_subdomain_name(dom, rdomain);
+ if (match != NULL) {
+ break;
+ }
+ }
+ if (match == NULL) {
+ DEBUG(SSSDBG_FUNC_DATA, ("default domain [%s] is currently " \
+ "not know, trying to look it up.\n",
+ rdomain));
+ *domain = talloc_steal(memctx, rdomain);
+ ret = EAGAIN;
+ goto done;
+ }
+ }
+
+ DEBUG(SSSDBG_FUNC_DATA, ("using default domain [%s]\n", rdomain));
+
rname = candidate_name;
} else if (candidate_domain) {
*domain = talloc_steal(memctx, candidate_domain);
- return EAGAIN;
+ ret = EAGAIN;
+ goto done;
}
}
if (rdomain == NULL && rname == NULL) {
DEBUG(SSSDBG_TRACE_FUNC,
("name '%s' did not match any domain's expression\n", orig));
- return EINVAL;
+ ret = EINVAL;
+ goto done;
}
if (domain != NULL) {
@@ -395,9 +423,11 @@ int sss_parse_name_for_domains(TALLOC_CTX *memctx,
*name = talloc_steal(memctx, rname);
}
+ ret = EOK;
+done:
talloc_free(tmp_ctx);
- return EOK;
+ return ret;
}
char *