summaryrefslogtreecommitdiff
path: root/source4/auth/credentials
diff options
context:
space:
mode:
Diffstat (limited to 'source4/auth/credentials')
-rw-r--r--source4/auth/credentials/credentials.c27
-rw-r--r--source4/auth/credentials/credentials.h5
-rw-r--r--source4/auth/credentials/credentials_files.c57
-rw-r--r--source4/auth/credentials/credentials_krb5.c61
4 files changed, 142 insertions, 8 deletions
diff --git a/source4/auth/credentials/credentials.c b/source4/auth/credentials/credentials.c
index f24c4e2231..9be877dd2c 100644
--- a/source4/auth/credentials/credentials.c
+++ b/source4/auth/credentials/credentials.c
@@ -46,7 +46,12 @@ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx)
cred->domain_obtained = CRED_UNINITIALISED;
cred->realm_obtained = CRED_UNINITIALISED;
cred->ccache_obtained = CRED_UNINITIALISED;
+ cred->keytab_obtained = CRED_UNINITIALISED;
cred->principal_obtained = CRED_UNINITIALISED;
+
+ cred->old_password = NULL;
+ cred->smb_krb5_context = NULL;
+
return cred;
}
@@ -210,6 +215,28 @@ BOOL cli_credentials_set_password_callback(struct cli_credentials *cred,
}
/**
+ * Obtain the 'old' password for this credentials context (used for join accounts).
+ * @param cred credentials context
+ * @retval If set, the cleartext password, otherwise NULL
+ */
+const char *cli_credentials_get_old_password(struct cli_credentials *cred)
+{
+ if (cred->machine_account_pending) {
+ cli_credentials_set_machine_account(cred);
+ }
+
+ return cred->old_password;
+}
+
+BOOL cli_credentials_set_old_password(struct cli_credentials *cred,
+ const char *val,
+ enum credentials_obtained obtained)
+{
+ cred->old_password = talloc_strdup(cred, val);
+ return True;
+}
+
+/**
* Obtain the password for this credentials context.
* @param cred credentials context
* @retval If set, the cleartext password, otherwise NULL
diff --git a/source4/auth/credentials/credentials.h b/source4/auth/credentials/credentials.h
index 324b518462..aa2a0d0ac2 100644
--- a/source4/auth/credentials/credentials.h
+++ b/source4/auth/credentials/credentials.h
@@ -48,10 +48,12 @@ struct cli_credentials {
enum credentials_obtained realm_obtained;
enum credentials_obtained ccache_obtained;
enum credentials_obtained principal_obtained;
+ enum credentials_obtained keytab_obtained;
const char *workstation;
const char *username;
const char *password;
+ const char *old_password;
const char *domain;
const char *realm;
const char *principal;
@@ -59,6 +61,7 @@ struct cli_credentials {
struct samr_Password *nt_hash;
struct ccache_container *ccache;
+ struct keytab_container *keytab;
const char *(*workstation_cb) (struct cli_credentials *);
const char *(*password_cb) (struct cli_credentials *);
@@ -74,6 +77,8 @@ struct cli_credentials {
enum netr_SchannelType secure_channel_type;
int kvno;
+ struct smb_krb5_context *smb_krb5_context;
+
/* We are flagged to get machine account details from the
* secrets.ldb when we are asked for a username or password */
diff --git a/source4/auth/credentials/credentials_files.c b/source4/auth/credentials/credentials_files.c
index 353ff61720..aa0a7f3213 100644
--- a/source4/auth/credentials/credentials_files.c
+++ b/source4/auth/credentials/credentials_files.c
@@ -164,7 +164,9 @@ BOOL cli_credentials_parse_file(struct cli_credentials *cred, const char *file,
* @param cred Credentials structure to fill in
* @retval NTSTATUS error detailing any failure
*/
-NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred)
+static NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
+ const char *base,
+ const char *filter)
{
TALLOC_CTX *mem_ctx;
@@ -184,6 +186,7 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred)
const char *machine_account;
const char *password;
+ const char *old_password;
const char *domain;
const char *realm;
enum netr_SchannelType sct;
@@ -201,10 +204,9 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred)
/* search for the secret record */
ldb_ret = gendb_search(ldb,
- mem_ctx, ldb_dn_explode(mem_ctx, SECRETS_PRIMARY_DOMAIN_DN),
+ mem_ctx, ldb_dn_explode(mem_ctx, base),
&msgs, attrs,
- SECRETS_PRIMARY_DOMAIN_FILTER,
- cli_credentials_get_domain(cred));
+ "%s", filter);
if (ldb_ret == 0) {
DEBUG(1, ("Could not find join record to domain: %s\n",
cli_credentials_get_domain(cred)));
@@ -218,6 +220,7 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred)
}
password = ldb_msg_find_string(msgs[0], "secret", NULL);
+ old_password = ldb_msg_find_string(msgs[0], "priorSecret", NULL);
machine_account = ldb_msg_find_string(msgs[0], "samAccountName", NULL);
@@ -278,6 +281,52 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred)
}
/**
+ * Fill in credentials for the machine trust account, from the secrets database.
+ *
+ * @param cred Credentials structure to fill in
+ * @retval NTSTATUS error detailing any failure
+ */
+NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred)
+{
+ char *filter = talloc_asprintf(cred, SECRETS_PRIMARY_DOMAIN_FILTER,
+ cli_credentials_get_domain(cred));
+ return cli_credentials_set_secrets(cred, SECRETS_PRIMARY_DOMAIN_DN,
+ filter);
+}
+
+/**
+ * Fill in credentials for the machine trust account, from the secrets database.
+ *
+ * @param cred Credentials structure to fill in
+ * @retval NTSTATUS error detailing any failure
+ */
+NTSTATUS cli_credentials_set_krbtgt(struct cli_credentials *cred)
+{
+ char *filter = talloc_asprintf(cred, SECRETS_KRBTGT_SEARCH,
+ cli_credentials_get_realm(cred),
+ cli_credentials_get_domain(cred));
+ return cli_credentials_set_secrets(cred, SECRETS_PRINCIPALS_DN,
+ filter);
+}
+
+/**
+ * Fill in credentials for the machine trust account, from the secrets database.
+ *
+ * @param cred Credentials structure to fill in
+ * @retval NTSTATUS error detailing any failure
+ */
+NTSTATUS cli_credentials_set_stored_principal(struct cli_credentials *cred,
+ const char *serviceprincipal)
+{
+ char *filter = talloc_asprintf(cred, SECRETS_PRINCIPAL_SEARCH,
+ cli_credentials_get_realm(cred),
+ cli_credentials_get_domain(cred),
+ serviceprincipal);
+ return cli_credentials_set_secrets(cred, SECRETS_PRINCIPALS_DN,
+ filter);
+}
+
+/**
* Ask that when required, the credentials system will be filled with
* machine trust account, from the secrets database.
*
diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c
index fb3239494e..b20d9ee750 100644
--- a/source4/auth/credentials/credentials_krb5.c
+++ b/source4/auth/credentials/credentials_krb5.c
@@ -26,6 +26,22 @@
#include "system/kerberos.h"
#include "auth/kerberos/kerberos.h"
+int cli_credentials_get_krb5_context(struct cli_credentials *cred,
+ struct smb_krb5_context **smb_krb5_context)
+{
+ int ret;
+ if (cred->smb_krb5_context) {
+ *smb_krb5_context = cred->smb_krb5_context;
+ return 0;
+ }
+
+ ret = smb_krb5_init_context(cred, &cred->smb_krb5_context);
+ if (ret) {
+ return ret;
+ }
+ *smb_krb5_context = cred->smb_krb5_context;
+ return 0;
+}
int cli_credentials_set_from_ccache(struct cli_credentials *cred,
enum credentials_obtained obtained)
@@ -95,11 +111,13 @@ int cli_credentials_set_ccache(struct cli_credentials *cred,
return ENOMEM;
}
- ret = smb_krb5_init_context(ccc, &ccc->smb_krb5_context);
+ ret = cli_credentials_get_krb5_context(cred, &ccc->smb_krb5_context);
if (ret) {
talloc_free(ccc);
return ret;
}
+ talloc_reference(ccc, ccc->smb_krb5_context);
+
if (name) {
ret = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context, name, &ccc->ccache);
if (ret) {
@@ -162,7 +180,7 @@ int cli_credentials_new_ccache(struct cli_credentials *cred)
}
ccache_name = talloc_asprintf(ccc, "MEMORY:%s",
- rand_string);
+ rand_string);
talloc_free(rand_string);
if (!ccache_name) {
@@ -170,12 +188,12 @@ int cli_credentials_new_ccache(struct cli_credentials *cred)
return ENOMEM;
}
- ret = smb_krb5_init_context(ccc, &ccc->smb_krb5_context);
+ ret = cli_credentials_get_krb5_context(cred, &ccc->smb_krb5_context);
if (ret) {
- talloc_free(ccache_name);
talloc_free(ccc);
return ret;
}
+ talloc_reference(ccc, ccc->smb_krb5_context);
ret = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context, ccache_name, &ccc->ccache);
if (ret) {
@@ -227,6 +245,41 @@ int cli_credentials_get_ccache(struct cli_credentials *cred,
return ret;
}
+int cli_credentials_get_keytab(struct cli_credentials *cred,
+ struct keytab_container **_ktc)
+{
+ krb5_error_code ret;
+ struct keytab_container *ktc;
+ struct smb_krb5_context *smb_krb5_context;
+
+ if (cred->keytab_obtained >= (MAX(cred->principal_obtained,
+ cred->username_obtained))) {
+ *_ktc = cred->keytab;
+ return 0;
+ }
+
+ if (cli_credentials_is_anonymous(cred)) {
+ return EINVAL;
+ }
+
+ ret = cli_credentials_get_krb5_context(cred, &smb_krb5_context);
+ if (ret) {
+ return ret;
+ }
+
+ ret = create_memory_keytab(cred, cred, smb_krb5_context, &ktc);
+ if (ret) {
+ return ret;
+ }
+
+ cred->keytab_obtained = (MAX(cred->principal_obtained,
+ cred->username_obtained));
+
+ cred->keytab = ktc;
+ *_ktc = cred->keytab;
+ return ret;
+}
+
/**
* Set Kerberos KVNO
*/