From: Stefan Metzmacher Date: Thu, 23 Apr 2026 16:56:21 +0000 (+0200) Subject: CVE-2026-4408: lib/util: introduce strstr_for_invalid_account_characters() X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=9910bbfc09ba35cf4ea82ff92a9f94de9f5bc862;p=thirdparty%2Fsamba.git CVE-2026-4408: lib/util: introduce strstr_for_invalid_account_characters() This splits out the logic from samaccountname_bad_chars_check() in source4/dsdb/samdb/ldb_modules/samldb.c, this will be used in other places soon. BUG: https://bugzilla.samba.org/show_bug.cgi?id=16034 Signed-off-by: Stefan Metzmacher Reviewed-by: Douglas Bagnall --- diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h index 2327ef5b9d2..8dcf6e32254 100644 --- a/lib/util/samba_util.h +++ b/lib/util/samba_util.h @@ -294,6 +294,15 @@ _PUBLIC_ size_t ascii_len_n(const char *src, size_t n); **/ _PUBLIC_ bool set_boolean(const char *boolean_string, bool *boolean); +/** + * Returns a pointer to the first invalid character in name. + * + * Passing a NULL pointer as name is not allowed! + * + * This returns NULL for a valid account name. + **/ +_PUBLIC_ const char *strstr_for_invalid_account_characters(const char *name); + /** * Convert a size specification like 16K into an integral number of bytes. **/ diff --git a/lib/util/util_str.c b/lib/util/util_str.c index 8fbfc32e0ec..63c15c33456 100644 --- a/lib/util/util_str.c +++ b/lib/util/util_str.c @@ -218,3 +218,41 @@ _PUBLIC_ bool set_boolean(const char *boolean_string, bool *boolean) } return false; } + +_PUBLIC_ const char *strstr_for_invalid_account_characters(const char *name) +{ + /* + * Return a pointer to the first invalid character in the + * sAMAccountName, or NULL if the whole name is valid. + * + * The rules here are based on + * + * https://social.technet.microsoft.com/wiki/contents/articles/11216.active-directory-requirements-for-creating-objects.aspx + */ + size_t i; + + for (i = 0; name[i] != '\0'; i++) { + uint8_t c = name[i]; + const char *p = NULL; + + if (iscntrl(c)) { + return &name[i]; + } + + p = strchr("\"[]:;|=+*?<>/\\,", c); + if (p != NULL) { + return &name[i]; + } + } + + if (i == 0) { + return &name[i]; + } + + if (name[i - 1] == '.') { + i -= 1; + return &name[i]; + } + + return NULL; +}