diff options
-rw-r--r-- | source4/include/credentials.h | 10 | ||||
-rw-r--r-- | source4/lib/cmdline/popt_common.c | 8 | ||||
-rw-r--r-- | source4/lib/credentials.c | 107 |
3 files changed, 100 insertions, 25 deletions
diff --git a/source4/include/credentials.h b/source4/include/credentials.h index 7b223dad5a..d7bf8997eb 100644 --- a/source4/include/credentials.h +++ b/source4/include/credentials.h @@ -4,6 +4,7 @@ Client credentials structure Copyright (C) Jelmer Vernooij 2004-2005 + Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -49,5 +50,14 @@ struct cli_credentials { const char *(*domain_cb) (struct cli_credentials *); const char *(*realm_cb) (struct cli_credentials *); + /* Private handle for the callback routines to use */ void *priv_data; + + struct creds_CredentialState *netlogon_creds; + + /* We are flagged to get machine account details from the + * secrets.ldb when we are asked for a username or password */ + + BOOL machine_account_pending; }; + diff --git a/source4/lib/cmdline/popt_common.c b/source4/lib/cmdline/popt_common.c index 50e07d95e9..68f491a188 100644 --- a/source4/lib/cmdline/popt_common.c +++ b/source4/lib/cmdline/popt_common.c @@ -212,10 +212,10 @@ static void popt_common_credentials_callback(poptContext con, break; case 'P': - { - cli_credentials_set_machine_account(cmdline_credentials); - } - /* machine accounts only work with kerberos */ + /* Later, after this is all over, get the machine account details from the secrets.ldb */ + cli_credentials_set_machine_account_pending(cmdline_credentials); + + /* machine accounts only work with kerberos (fall though)*/ case 'k': #ifndef HAVE_KRB5 diff --git a/source4/lib/credentials.c b/source4/lib/credentials.c index e98e261b05..da0bc4236f 100644 --- a/source4/lib/credentials.c +++ b/source4/lib/credentials.c @@ -34,15 +34,15 @@ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx) return cred; } - cli_credentials_set_domain(cred, lp_workgroup(), CRED_GUESSED); - cli_credentials_set_workstation(cred, lp_netbios_name(), CRED_GUESSED); - cli_credentials_set_realm(cred, lp_realm(), CRED_GUESSED); - return cred; } const char *cli_credentials_get_username(struct cli_credentials *cred) { + if (cred->machine_account_pending) { + cli_credentials_set_machine_account(cred); + } + if (cred->username_obtained == CRED_CALLBACK) { cred->username = cred->username_cb(cred); cred->username_obtained = CRED_SPECIFIED; @@ -64,6 +64,10 @@ BOOL cli_credentials_set_username(struct cli_credentials *cred, const char *val, const char *cli_credentials_get_password(struct cli_credentials *cred) { + if (cred->machine_account_pending) { + cli_credentials_set_machine_account(cred); + } + if (cred->password_obtained == CRED_CALLBACK) { cred->password = cred->password_cb(cred); cred->password_obtained = CRED_SPECIFIED; @@ -85,6 +89,10 @@ BOOL cli_credentials_set_password(struct cli_credentials *cred, const char *val, const char *cli_credentials_get_domain(struct cli_credentials *cred) { + if (cred->machine_account_pending) { + cli_credentials_set_machine_account(cred); + } + if (cred->domain_obtained == CRED_CALLBACK) { cred->domain = cred->domain_cb(cred); cred->domain_obtained = CRED_SPECIFIED; @@ -107,8 +115,8 @@ BOOL cli_credentials_set_domain(struct cli_credentials *cred, const char *val, e const char *cli_credentials_get_realm(struct cli_credentials *cred) { - if (cred == NULL) { - return NULL; + if (cred->machine_account_pending) { + cli_credentials_set_machine_account(cred); } if (cred->realm_obtained == CRED_CALLBACK) { @@ -119,6 +127,14 @@ const char *cli_credentials_get_realm(struct cli_credentials *cred) return cred->realm; } +char *cli_credentials_get_principal(struct cli_credentials *cred, + TALLOC_CTX *mem_ctx) +{ + return talloc_asprintf(mem_ctx, "%s@%s", + cli_credentials_get_username(cred), + cli_credentials_get_realm(cred)); +} + BOOL cli_credentials_set_realm(struct cli_credentials *cred, const char *val, enum credentials_obtained obtained) { if (obtained >= cred->realm_obtained) { @@ -132,10 +148,6 @@ BOOL cli_credentials_set_realm(struct cli_credentials *cred, const char *val, en const char *cli_credentials_get_workstation(struct cli_credentials *cred) { - if (cred == NULL) { - return NULL; - } - if (cred->workstation_obtained == CRED_CALLBACK) { cred->workstation = cred->workstation_cb(cred); cred->workstation_obtained = CRED_SPECIFIED; @@ -287,10 +299,20 @@ void cli_credentials_parse_string(struct cli_credentials *credentials, const cha cli_credentials_set_username(credentials, uname, obtained); } +/* Initialise defaults from the lp_*() functions */ +void cli_credentials_set_conf(struct cli_credentials *cred) +{ + cli_credentials_set_domain(cred, lp_workgroup(), CRED_GUESSED); + cli_credentials_set_workstation(cred, lp_netbios_name(), CRED_GUESSED); + cli_credentials_set_realm(cred, lp_realm(), CRED_GUESSED); +} + void cli_credentials_guess(struct cli_credentials *cred) { char *p; + cli_credentials_set_conf(cred); + if (getenv("LOGNAME")) { cli_credentials_set_username(cred, getenv("LOGNAME"), CRED_GUESSED); } @@ -319,9 +341,9 @@ void cli_credentials_guess(struct cli_credentials *cred) } } -NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *creds) +NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred) { - TALLOC_CTX *mem_ctx = talloc_named(creds, 0, "cli_credentials fetch machine password"); + TALLOC_CTX *mem_ctx; struct ldb_context *ldb; int ldb_ret; @@ -330,15 +352,24 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *creds) const char *attrs[] = { "secret", "samAccountName", + "flatname", + "realm", NULL }; const char *machine_account; const char *password; + const char *domain; + const char *realm; + /* ok, we are going to get it now, don't recurse back here */ + cred->machine_account_pending = False; + + mem_ctx = talloc_named(cred, 0, "cli_credentials fetch machine password"); /* Local secrets are stored in secrets.ldb */ ldb = secrets_db_connect(mem_ctx); if (!ldb) { + DEBUG(1, ("Could not open secrets.ldb\n")); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } @@ -346,13 +377,15 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *creds) ldb_ret = gendb_search(ldb, mem_ctx, base_dn, &msgs, attrs, SECRETS_PRIMARY_DOMAIN_FILTER, - cli_credentials_get_domain(creds)); + cli_credentials_get_domain(cred)); if (ldb_ret == 0) { DEBUG(1, ("Could not find join record to domain: %s\n", - lp_workgroup())); + cli_credentials_get_domain(cred))); talloc_free(mem_ctx); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } else if (ldb_ret != 1) { + DEBUG(1, ("Found more than one (%d) join records to domain: %s\n", + ldb_ret, cli_credentials_get_domain(cred))); talloc_free(mem_ctx); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } @@ -360,7 +393,7 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *creds) password = ldb_msg_find_string(msgs[0], "secret", NULL); if (!password) { DEBUG(1, ("Could not find 'secret' in join record to domain: %s\n", - cli_credentials_get_domain(creds))); + cli_credentials_get_domain(cred))); talloc_free(mem_ctx); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } @@ -368,18 +401,47 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *creds) machine_account = ldb_msg_find_string(msgs[0], "samAccountName", NULL); if (!machine_account) { DEBUG(1, ("Could not find 'samAccountName' in join record to domain: %s\n", - cli_credentials_get_domain(creds))); + cli_credentials_get_domain(cred))); talloc_free(mem_ctx); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } - cli_credentials_set_username(creds, machine_account, CRED_SPECIFIED); - cli_credentials_set_password(creds, password, CRED_SPECIFIED); + domain = ldb_msg_find_string(msgs[0], "flatname", NULL); + if (domain) { + cli_credentials_set_domain(cred, domain, CRED_SPECIFIED); + } + + realm = ldb_msg_find_string(msgs[0], "realm", NULL); + if (realm) { + cli_credentials_set_realm(cred, realm, CRED_SPECIFIED); + } + + cli_credentials_set_username(cred, machine_account, CRED_SPECIFIED); + cli_credentials_set_password(cred, password, CRED_SPECIFIED); talloc_free(mem_ctx); return NT_STATUS_OK; } +void cli_credentials_set_machine_account_pending(struct cli_credentials *cred) +{ + cred->machine_account_pending = True; +} +/* Attach NETLOGON credentials for use with SCHANNEL */ + +void cli_credentials_set_netlogon_creds(struct cli_credentials *cred, + struct creds_CredentialState *netlogon_creds) +{ + cred->netlogon_creds = talloc_reference(cred, netlogon_creds); +} + +/* Return attached NETLOGON credentials */ + +struct creds_CredentialState *cli_credentials_get_netlogon_creds(struct cli_credentials *cred) +{ + return cred->netlogon_creds; +} + /* Fill in a credentails structure as anonymous */ void cli_credentials_set_anonymous(struct cli_credentials *cred) { @@ -388,11 +450,14 @@ void cli_credentials_set_anonymous(struct cli_credentials *cred) cli_credentials_set_password(cred, NULL, CRED_SPECIFIED); } -BOOL cli_credentials_is_anonymous(struct cli_credentials *credentials) +BOOL cli_credentials_is_anonymous(struct cli_credentials *cred) { - const char *username = cli_credentials_get_username(credentials); + const char *username = cli_credentials_get_username(cred); - if (!username || !username[0]) + /* Yes, it is deliberate that we die if we have a NULL pointer + * here - anymous is "", not NULL, which is 'never specified, + * never guessed', ie programmer bug */ + if (!username[0]) return True; return False; |