Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/providers/ldap/sdap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1839,7 +1839,7 @@ errno_t sdap_get_primary_name(const char *attr_name,
}
talloc_free(tmp_ctx);

DEBUG(SSSDBG_TRACE_FUNC, "Processing object %s\n", orig_name);
DEBUG_CONDITIONAL(SSSDBG_TRACE_FUNC, "Processing object %s\n", orig_name);

*_primary_name = orig_name;

Expand Down
30 changes: 26 additions & 4 deletions src/util/sss_tc_utf8.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,29 @@
#include "config.h"

#include <stdlib.h>
#include <stdbool.h>
#include <unistr.h>
#include <unicase.h>

#include <talloc.h>
#include "util/util.h"

static inline bool sss_is_ascii_lowercase(const char *s)
{
if (s == NULL) {
return true;
}

while (*s != 0) {
if (((unsigned char)*s > 0x7F) || ((*s >= 'A') && (*s <= 'Z'))) {
return false;
}
s++;
}

return true;
}

/* Expects and returns NULL-terminated string;
* result must be freed with free()
*/
Expand All @@ -41,10 +58,15 @@ char *sss_tc_utf8_str_tolower(TALLOC_CTX *mem_ctx, const char *s)
char *lower;
char *ret = NULL;

lower = sss_utf8_tolower(s);
if (lower) {
ret = talloc_strdup(mem_ctx, lower);
free(lower);
if (sss_is_ascii_lowercase(s)) {
ret = talloc_strdup(mem_ctx, s);
}
else {
lower = sss_utf8_tolower(s);
if (lower) {
ret = talloc_strdup(mem_ctx, lower);
free(lower);
}
}

return ret;
Expand Down
66 changes: 58 additions & 8 deletions src/util/usertools.c
Original file line number Diff line number Diff line change
Expand Up @@ -638,29 +638,79 @@ errno_t sss_parse_internal_fqname(TALLOC_CTX *mem_ctx,
return EOK;
}

/* This is a wrapper around `sss_tc_utf8_str_tolower()` that
* maintains run time cache.
*/
static const char *sss_get_lc_dom_name(const char *dom_name)
{
static TALLOC_CTX *cache_ctx;
static hash_table_t *lc_dom_name_cache;
hash_key_t key;
hash_value_t value;
char *lc_dom_name;
int hret;

key.type = HASH_KEY_CONST_STRING;
key.c_str = dom_name;

if (lc_dom_name_cache != NULL) {
hret = hash_lookup(lc_dom_name_cache, &key, &value);
if (hret == HASH_SUCCESS) {
return (const char *)value.ptr;
}
} else {
cache_ctx = talloc_new(NULL);
if (cache_ctx == NULL) {
return NULL;
}
hret = hash_create(0, &lc_dom_name_cache, NULL, NULL);
if (hret != HASH_SUCCESS) {
DEBUG(SSSDBG_CRIT_FAILURE,
"hash_create() failed [%s]\n", hash_error_string(hret));
lc_dom_name_cache = NULL;
talloc_zfree(cache_ctx);
return NULL;
}
}

lc_dom_name = sss_tc_utf8_str_tolower(cache_ctx, dom_name);
if (lc_dom_name == NULL) {
return NULL;
}

value.type = HASH_VALUE_PTR;
value.ptr = lc_dom_name;

hret = hash_enter(lc_dom_name_cache, &key, &value);
if (hret != HASH_SUCCESS) {
DEBUG(SSSDBG_CRIT_FAILURE,
"hash_enter() failed [%s]\n", hash_error_string(hret));
talloc_free(lc_dom_name);
return NULL;
}

return lc_dom_name;
}

/* Creates internal fqname in format shortname@domname.
* The domain portion is lowercased. */
char *sss_create_internal_fqname(TALLOC_CTX *mem_ctx,
const char *shortname,
const char *dom_name)
{
char *lc_dom_name;
char *fqname = NULL;
const char *lc_dom_name;

if (shortname == NULL || dom_name == NULL) {
/* Avoid allocating null@null */
return NULL;
}

lc_dom_name = sss_tc_utf8_str_tolower(mem_ctx, dom_name);
lc_dom_name = sss_get_lc_dom_name(dom_name);
if (lc_dom_name == NULL) {
goto done;
return NULL;
}

fqname = talloc_asprintf(mem_ctx, "%s@%s", shortname, lc_dom_name);
talloc_free(lc_dom_name);
done:
return fqname;
return talloc_asprintf(mem_ctx, "%s@%s", shortname, lc_dom_name);
}

/* Creates a list of internal fqnames in format shortname@domname.
Expand Down