summaryrefslogtreecommitdiff
path: root/auth
diff options
context:
space:
mode:
authorAlexander Bokovoy <ab@samba.org>2020-11-04 14:00:58 +0200
committerAlexander Bokovoy <ab@samba.org>2020-11-04 14:59:34 +0000
commit00f4262ed0b22f6e333e5a29c5590b62c783905c (patch)
treeb37e0a17d2d84f02fbc71b5399bdd0107552b0eb /auth
parenteb0474d27bae4592b25ac6bf600da29c6a1cb9f8 (diff)
downloadsamba-00f4262ed0b22f6e333e5a29c5590b62c783905c.tar.gz
cli_credentials: add a helper to parse user or group names
cli_credentials_parse_string() parses a string specified for -U option in command line tools. It has a side-effect that '%' character is always considered to be a separator after which a password is specified. Active Directory does allow to create user or group objects with '%' in the name. It means cli_credentials_parse_string() will not be able to properly parse such name. Introduce cli_credentials_parse_name() for the cases when a password is not expected in the name and call to cli_credentials_parse_name() from cli_credentials_parse_string(). Test cli_credentials_parse_name() with its intended use in lookup_name() refactoring. Signed-off-by: Alexander Bokovoy <ab@samba.org> Reviewed-by: Andreas Schneider <asn@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'auth')
-rw-r--r--auth/credentials/credentials.c18
-rw-r--r--auth/credentials/credentials.h1
-rw-r--r--auth/credentials/tests/test_creds.c56
3 files changed, 75 insertions, 0 deletions
diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c
index a8d25278e9d..53bba78176b 100644
--- a/auth/credentials/credentials.c
+++ b/auth/credentials/credentials.c
@@ -836,6 +836,24 @@ _PUBLIC_ void cli_credentials_parse_string(struct cli_credentials *credentials,
cli_credentials_set_password(credentials, p+1, obtained);
}
+ cli_credentials_parse_name(credentials, uname, obtained);
+}
+
+/**
+ * Given a string, parse it into a domain, username and realm fields
+ *
+ * The format accepted is [domain\\]user or user[@realm]
+ *
+ * @param credentials Credentials structure on which to set the components
+ * @param data the string containing the username, prefixed or suffixed with domain or realm
+ * @param obtained This enum describes how 'specified' this credential name is.
+ */
+
+_PUBLIC_ void cli_credentials_parse_name(struct cli_credentials *credentials, const char *data, enum credentials_obtained obtained)
+{
+ char *uname, *p;
+
+ uname = talloc_strdup(credentials, data);
if ((p = strchr_m(uname,'@'))) {
/*
* We also need to set username and domain
diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h
index f468b8558dd..7c7120b9f55 100644
--- a/auth/credentials/credentials.h
+++ b/auth/credentials/credentials.h
@@ -155,6 +155,7 @@ bool cli_credentials_set_password(struct cli_credentials *cred,
enum credentials_obtained obtained);
struct cli_credentials *cli_credentials_init_anon(TALLOC_CTX *mem_ctx);
void cli_credentials_parse_string(struct cli_credentials *credentials, const char *data, enum credentials_obtained obtained);
+void cli_credentials_parse_name(struct cli_credentials *credentials, const char *data, enum credentials_obtained obtained);
struct samr_Password *cli_credentials_get_nt_hash(struct cli_credentials *cred,
TALLOC_CTX *mem_ctx);
struct samr_Password *cli_credentials_get_old_nt_hash(struct cli_credentials *cred,
diff --git a/auth/credentials/tests/test_creds.c b/auth/credentials/tests/test_creds.c
index 541ecc7b264..38550d6ecf9 100644
--- a/auth/credentials/tests/test_creds.c
+++ b/auth/credentials/tests/test_creds.c
@@ -197,6 +197,61 @@ static void torture_creds_parse_string(void **state)
assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
}
+static void _parse_name_as_lookup_name(TALLOC_CTX *mem_ctx,
+ const char *full_name,
+ const char *expected_name,
+ const char *expected_domain,
+ const char *expected_realm)
+{
+ struct cli_credentials *creds = NULL;
+
+ creds = cli_credentials_init(mem_ctx);
+ assert_non_null(creds);
+
+ cli_credentials_parse_name(creds, full_name, CRED_SPECIFIED);
+
+ if (expected_name == NULL) {
+ assert_null(cli_credentials_get_username(creds));
+ } else {
+ assert_string_equal(cli_credentials_get_username(creds), expected_name);
+ }
+
+ if (expected_domain == NULL) {
+ assert_null(cli_credentials_get_domain(creds));
+ } else {
+ assert_string_equal(cli_credentials_get_domain(creds), expected_domain);
+ }
+
+ if (expected_realm == NULL) {
+ assert_null(cli_credentials_get_realm(creds));
+ } else {
+ assert_string_equal(cli_credentials_get_realm(creds), expected_realm);
+ }
+
+ TALLOC_FREE(creds);
+
+}
+
+static void torture_creds_parse_name(void **state)
+{
+ TALLOC_CTX *mem_ctx = *state;
+
+ _parse_name_as_lookup_name(mem_ctx, "XXL\\",
+ "", "XXL", NULL);
+
+ _parse_name_as_lookup_name(mem_ctx, "XXL\\wurst",
+ "wurst", "XXL", NULL);
+
+ _parse_name_as_lookup_name(mem_ctx, "wurst@brot.realm",
+ "wurst", "", "BROT.REALM");
+
+ _parse_name_as_lookup_name(mem_ctx, "wur%t",
+ "wur%t", NULL, NULL);
+
+ _parse_name_as_lookup_name(mem_ctx, "wurst",
+ "wurst", NULL, NULL);
+}
+
int main(int argc, char *argv[])
{
int rc;
@@ -206,6 +261,7 @@ int main(int argc, char *argv[])
cmocka_unit_test(torture_creds_guess),
cmocka_unit_test(torture_creds_anon_guess),
cmocka_unit_test(torture_creds_parse_string),
+ cmocka_unit_test(torture_creds_parse_name),
};
if (argc == 2) {