diff options
author | Simo Sorce <simo@redhat.com> | 2013-10-18 14:45:50 -0400 |
---|---|---|
committer | Simo Sorce <simo@redhat.com> | 2013-10-18 16:29:15 -0400 |
commit | e6370d26843206bcf7e418d3c3014611fdecc489 (patch) | |
tree | 5e395e41107c1e04a39527e7f19526ed6dd432cd | |
parent | 4f648eb87e317298749e2848331bc42a5622bca9 (diff) | |
download | gss-ntlmssp-e6370d26843206bcf7e418d3c3014611fdecc489.tar.gz gss-ntlmssp-e6370d26843206bcf7e418d3c3014611fdecc489.tar.xz gss-ntlmssp-e6370d26843206bcf7e418d3c3014611fdecc489.zip |
Add special case for enterprise names
When enterprise names are used they need to be passed with the embedded
'@' signed escaped with a '\', when that is done the whole name is used
as the user name and the name is not split on the @ or \ characters.
These forms are now supported:
foo
USERNAME: foo
DOMAIN: <null>
BAR\foo
USERNAME: foo
DOMAIN: BAR
foo@BAR
USERNAME: foo
DOMAIN: BAR
foo\@bar.example.com
USERNAME: foo\@bar.example.com
DOMAIN: <null>
-rw-r--r-- | src/gss_names.c | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/src/gss_names.c b/src/gss_names.c index eb15f4e..823b8ec 100644 --- a/src/gss_names.c +++ b/src/gss_names.c @@ -77,6 +77,38 @@ done: return retmaj; } +#define MAX_NAME_LEN 1024 +static uint32_t get_enterprise_name(uint32_t *retmin, + const char *str, size_t len, + char **username) +{ + char *buf; + char *e; + + if (len > MAX_NAME_LEN) { + *retmin = EINVAL; + return GSS_S_BAD_NAME; + } + buf = alloca(len + 1); + + memcpy(buf, str, len); + buf[len] = '\0'; + + e = strstr(buf, "\\@"); + if (!e) return GSS_S_UNAVAILABLE; + + /* remove escape */ + memmove(e, e + 1, len - (e - buf)); + + *username = strdup(buf); + if (NULL == *username) { + *retmin = ENOMEM; + return GSS_S_FAILURE; + } + + return GSS_S_COMPLETE; +} + static uint32_t uid_to_name(uint32_t *retmin, uid_t uid, char **name) { struct passwd *pw; @@ -155,7 +187,17 @@ uint32_t gssntlm_import_name_by_mech(uint32_t *minor_status, } else if (gss_oid_equal(input_name_type, GSS_C_NT_USER_NAME)) { name->type = GSSNTLM_NAME_USER; + name->data.user.domain = NULL; + /* Check if enterprise name first */ + retmaj = get_enterprise_name(&retmin, + input_name_buffer->value, + input_name_buffer->length, + &name->data.user.name); + if ((retmaj == GSS_S_COMPLETE) || + (retmaj != GSS_S_UNAVAILABLE)) { + goto done; + } /* Check if in classic DOMAIN\User windows format */ retmaj = string_split(&retmin, '\\', input_name_buffer->value, @@ -177,7 +219,6 @@ uint32_t gssntlm_import_name_by_mech(uint32_t *minor_status, goto done; } /* finally, take string as simple user name */ - name->data.user.domain = NULL; name->data.user.name = strndup(input_name_buffer->value, input_name_buffer->length); if (!name->data.user.name) { |