summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
Diffstat (limited to 'source4')
-rw-r--r--source4/auth/credentials/credentials.c27
-rw-r--r--source4/auth/credentials/credentials.h6
-rw-r--r--source4/auth/credentials/credentials_files.c92
-rw-r--r--source4/auth/credentials/credentials_krb5.c211
-rw-r--r--source4/auth/gensec/gensec_gssapi.c61
-rw-r--r--source4/heimdal/kdc/kerberos5.c25
-rw-r--r--source4/heimdal/lib/gssapi/accept_sec_context.c106
-rw-r--r--source4/heimdal/lib/gssapi/acquire_cred.c50
-rw-r--r--source4/heimdal/lib/gssapi/arcfour.c8
-rw-r--r--source4/heimdal/lib/gssapi/copy_ccache.c123
-rw-r--r--source4/heimdal/lib/gssapi/gssapi.h21
-rw-r--r--source4/heimdal/lib/gssapi/gssapi_locl.h2
-rw-r--r--source4/heimdal/lib/gssapi/init_sec_context.c2
-rw-r--r--source4/heimdal/lib/gssapi/release_cred.c2
-rw-r--r--source4/heimdal/lib/hdb/db.c6
-rw-r--r--source4/heimdal/lib/hdb/hdb-protos.h4
-rw-r--r--source4/heimdal/lib/hdb/ndbm.c2
-rw-r--r--source4/heimdal/lib/krb5/cache.c37
-rw-r--r--source4/heimdal/lib/krb5/get_for_creds.c22
-rw-r--r--source4/heimdal/lib/krb5/keytab.c36
-rw-r--r--source4/heimdal/lib/krb5/krb5-private.h17
-rw-r--r--source4/heimdal/lib/krb5/krb5-protos.h12
-rw-r--r--source4/heimdal/lib/krb5/rd_cred.c2
-rw-r--r--source4/libnet/libnet_join.c35
-rw-r--r--source4/scripting/ejs/smbcalls_creds.c12
-rw-r--r--source4/scripting/libjs/provision.js3
-rw-r--r--source4/setup/secrets.ldif4
27 files changed, 633 insertions, 295 deletions
diff --git a/source4/auth/credentials/credentials.c b/source4/auth/credentials/credentials.c
index 86a3df0077..75c6795e73 100644
--- a/source4/auth/credentials/credentials.c
+++ b/source4/auth/credentials/credentials.c
@@ -46,7 +46,8 @@ 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->gss_creds_obtained = CRED_UNINITIALISED;
+ cred->client_gss_creds_obtained = CRED_UNINITIALISED;
+ cred->server_gss_creds_obtained = CRED_UNINITIALISED;
cred->keytab_obtained = CRED_UNINITIALISED;
cred->principal_obtained = CRED_UNINITIALISED;
@@ -148,6 +149,9 @@ BOOL cli_credentials_set_principal(struct cli_credentials *cred,
return False;
}
+/* Set a callback to get the principal. This could be a popup dialog,
+ * a terminal prompt or similar. */
+
BOOL cli_credentials_set_principal_callback(struct cli_credentials *cred,
const char *(*principal_cb) (struct cli_credentials *))
{
@@ -160,6 +164,10 @@ BOOL cli_credentials_set_principal_callback(struct cli_credentials *cred,
return False;
}
+/* Some of our tools are 'anonymous by default'. This is a single
+ * function to determine if authentication has been explicitly
+ * requested */
+
BOOL cli_credentials_authentication_requested(struct cli_credentials *cred)
{
if (cred->principal_obtained >= CRED_SPECIFIED) {
@@ -190,6 +198,9 @@ const char *cli_credentials_get_password(struct cli_credentials *cred)
return cred->password;
}
+/* Set a password on the credentials context, including an indication
+ * of 'how' the password was obtained */
+
BOOL cli_credentials_set_password(struct cli_credentials *cred,
const char *val,
enum credentials_obtained obtained)
@@ -240,7 +251,11 @@ BOOL cli_credentials_set_old_password(struct cli_credentials *cred,
}
/**
- * Obtain the password for this credentials context.
+ * Obtain the password, in the form MD4(unicode(password)) for this credentials context.
+ *
+ * Sometimes we only have this much of the password, while the rest of
+ * the time this call avoids calling E_md4hash themselves.
+ *
* @param cred credentials context
* @retval If set, the cleartext password, otherwise NULL
*/
@@ -566,7 +581,13 @@ void cli_credentials_set_anonymous(struct cli_credentials *cred)
BOOL cli_credentials_is_anonymous(struct cli_credentials *cred)
{
- const char *username = cli_credentials_get_username(cred);
+ const char *username;
+
+ if (cred->machine_account_pending) {
+ cli_credentials_set_machine_account(cred);
+ }
+
+ username = cli_credentials_get_username(cred);
/* Yes, it is deliberate that we die if we have a NULL pointer
* here - anonymous is "", not NULL, which is 'never specified,
diff --git a/source4/auth/credentials/credentials.h b/source4/auth/credentials/credentials.h
index 3e84db52a5..81773aa70a 100644
--- a/source4/auth/credentials/credentials.h
+++ b/source4/auth/credentials/credentials.h
@@ -47,9 +47,10 @@ struct cli_credentials {
enum credentials_obtained domain_obtained;
enum credentials_obtained realm_obtained;
enum credentials_obtained ccache_obtained;
- enum credentials_obtained gss_creds_obtained;
+ enum credentials_obtained client_gss_creds_obtained;
enum credentials_obtained principal_obtained;
enum credentials_obtained keytab_obtained;
+ enum credentials_obtained server_gss_creds_obtained;
const char *workstation;
const char *username;
@@ -63,8 +64,9 @@ struct cli_credentials {
struct samr_Password *nt_hash;
struct ccache_container *ccache;
- struct gssapi_creds_container *gssapi_creds;
+ struct gssapi_creds_container *client_gss_creds;
struct keytab_container *keytab;
+ struct gssapi_creds_container *server_gss_creds;
const char *(*workstation_cb) (struct cli_credentials *);
const char *(*password_cb) (struct cli_credentials *);
diff --git a/source4/auth/credentials/credentials_files.c b/source4/auth/credentials/credentials_files.c
index 35bbc43b34..6b3c77c4e3 100644
--- a/source4/auth/credentials/credentials_files.c
+++ b/source4/auth/credentials/credentials_files.c
@@ -164,9 +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
*/
-static NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
- const char *base,
- const char *filter)
+NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
+ const char *base,
+ const char *filter)
{
TALLOC_CTX *mem_ctx;
@@ -183,6 +183,8 @@ static NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
"ntPwdHash",
"msDS-KeyVersionNumber",
"saltPrincipal",
+ "privateKeytab",
+ "krb5Keytab",
NULL
};
@@ -193,6 +195,7 @@ static NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
const char *realm;
enum netr_SchannelType sct;
const char *salt_principal;
+ const char *keytab;
/* ok, we are going to get it now, don't recurse back here */
cred->machine_account_pending = False;
@@ -201,6 +204,7 @@ static NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
cred->machine_account = True;
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) {
@@ -279,7 +283,22 @@ static NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
}
cli_credentials_set_kvno(cred, ldb_msg_find_int(msgs[0], "msDS-KeyVersionNumber", 0));
-
+
+ /* If there was an external keytab specified by reference in
+ * the LDB, then use this. Otherwise we will make one up
+ * (chewing CPU time) from the password */
+ keytab = ldb_msg_find_string(msgs[0], "krb5Keytab", NULL);
+ if (keytab) {
+ cli_credentials_set_keytab(cred, keytab, CRED_SPECIFIED);
+ } else {
+ keytab = ldb_msg_find_string(msgs[0], "privateKeytab", NULL);
+ if (keytab) {
+ keytab = talloc_asprintf(mem_ctx, "FILE:%s", private_path(mem_ctx, keytab));
+ if (keytab) {
+ cli_credentials_set_keytab(cred, keytab, CRED_SPECIFIED);
+ }
+ }
+ }
talloc_free(mem_ctx);
return NT_STATUS_OK;
@@ -345,3 +364,68 @@ void cli_credentials_set_machine_account_pending(struct cli_credentials *cred)
cred->machine_account_pending = True;
}
+
+NTSTATUS cli_credentials_update_all_keytabs(TALLOC_CTX *parent_ctx)
+{
+ TALLOC_CTX *mem_ctx;
+ int ldb_ret;
+ struct ldb_context *ldb;
+ struct ldb_message **msgs;
+ const char *attrs[] = { NULL };
+ struct cli_credentials *creds;
+ const char *filter;
+ NTSTATUS status;
+ int i, ret;
+
+ mem_ctx = talloc_new(parent_ctx);
+ if (!mem_ctx) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* Local secrets are stored in secrets.ldb */
+ ldb = secrets_db_connect(mem_ctx);
+ if (!ldb) {
+ DEBUG(1, ("Could not open secrets.ldb\n"));
+ talloc_free(mem_ctx);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* search for the secret record */
+ ldb_ret = gendb_search(ldb,
+ mem_ctx, NULL,
+ &msgs, attrs,
+ "objectClass=kerberosSecret");
+ if (ldb_ret == -1) {
+ DEBUG(1, ("Error looking for kerberos type secrets to push into a keytab"));
+ talloc_free(mem_ctx);
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ for (i=0; i < ldb_ret; i++) {
+ /* Make a credentials structure from it */
+ creds = cli_credentials_init(mem_ctx);
+ if (!creds) {
+ DEBUG(1, ("cli_credentials_init failed!"));
+ talloc_free(mem_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+ cli_credentials_set_conf(creds);
+ filter = talloc_asprintf(mem_ctx, "dn=%s", ldb_dn_linearize(mem_ctx, msgs[i]->dn));
+ status = cli_credentials_set_secrets(creds, NULL, filter);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("Failed to read secrets for keytab update for %s\n",
+ filter));
+ talloc_free(mem_ctx);
+ return status;
+ }
+ ret = cli_credentials_update_keytab(creds);
+ if (ret != 0) {
+ DEBUG(1, ("Failed to update keytab for %s\n",
+ filter));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ }
+ return NT_STATUS_OK;
+}
+
diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c
index a3761e8359..173739e9b8 100644
--- a/source4/auth/credentials/credentials_krb5.c
+++ b/source4/auth/credentials/credentials_krb5.c
@@ -52,6 +52,10 @@ int cli_credentials_set_from_ccache(struct cli_credentials *cred,
char *name;
char **realm;
+ if (cred->ccache_obtained > obtained) {
+ return 0;
+ }
+
ret = krb5_cc_get_principal(cred->ccache->smb_krb5_context->krb5_context,
cred->ccache->ccache, &princ);
@@ -107,7 +111,12 @@ int cli_credentials_set_ccache(struct cli_credentials *cred,
{
krb5_error_code ret;
krb5_principal princ;
- struct ccache_container *ccc = talloc(cred, struct ccache_container);
+ struct ccache_container *ccc;
+ if (cred->ccache_obtained > obtained) {
+ return 0;
+ }
+
+ ccc = talloc(cred, struct ccache_container);
if (!ccc) {
return ENOMEM;
}
@@ -265,10 +274,10 @@ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
OM_uint32 maj_stat, min_stat;
struct gssapi_creds_container *gcc;
struct ccache_container *ccache;
- if (cred->gss_creds_obtained >= (MAX(cred->ccache_obtained,
+ if (cred->client_gss_creds_obtained >= (MAX(cred->ccache_obtained,
MAX(cred->principal_obtained,
cred->username_obtained)))) {
- *_gcc = cred->gssapi_creds;
+ *_gcc = cred->client_gss_creds;
return 0;
}
ret = cli_credentials_get_ccache(cred,
@@ -283,8 +292,8 @@ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
return ENOMEM;
}
- maj_stat = gss_krb5_import_ccache(&min_stat, ccache->ccache,
- &gcc->creds);
+ maj_stat = gss_krb5_import_cred(&min_stat, ccache->ccache, NULL, NULL,
+ &gcc->creds);
if (maj_stat) {
if (min_stat) {
ret = min_stat;
@@ -293,20 +302,20 @@ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
}
}
if (ret == 0) {
- cred->gss_creds_obtained = cred->ccache_obtained;
+ cred->client_gss_creds_obtained = cred->ccache_obtained;
talloc_set_destructor(gcc, free_gssapi_creds);
- cred->gssapi_creds = gcc;
+ cred->client_gss_creds = gcc;
*_gcc = gcc;
}
return ret;
}
/**
- Set a gssapi cred_id_t into the credentails system.
+ Set a gssapi cred_id_t into the credentails system. (Client case)
This grabs the credentials both 'intact' and getting the krb5
ccache out of it. This routine can be generalised in future for
- the case where we deal with GSSAPI mechs other than krb5.
+ the case where we deal with GSSAPI mechs other than krb5.
On sucess, the caller must not free gssapi_cred, as it now belongs
to the credentials system.
@@ -319,7 +328,12 @@ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
int ret;
OM_uint32 maj_stat, min_stat;
struct ccache_container *ccc;
- struct gssapi_creds_container *gcc = talloc(cred, struct gssapi_creds_container);
+ struct gssapi_creds_container *gcc;
+ if (cred->client_gss_creds_obtained > obtained) {
+ return 0;
+ }
+
+ gcc = talloc(cred, struct gssapi_creds_container);
if (!gcc) {
return ENOMEM;
}
@@ -346,18 +360,23 @@ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
gcc->creds = gssapi_cred;
talloc_set_destructor(gcc, free_gssapi_creds);
- cred->gss_creds_obtained = obtained;
- cred->gssapi_creds = gcc;
+ cred->client_gss_creds_obtained = obtained;
+ cred->client_gss_creds = gcc;
}
return ret;
}
+/* Get the keytab (actually, a container containing the krb5_keytab)
+ * attached to this context. If this hasn't been done or set before,
+ * it will be generated from the password.
+ */
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;
+ TALLOC_CTX *mem_ctx;
if (cred->keytab_obtained >= (MAX(cred->principal_obtained,
cred->username_obtained))) {
@@ -374,16 +393,180 @@ int cli_credentials_get_keytab(struct cli_credentials *cred,
return ret;
}
- ret = create_memory_keytab(cred, cred, smb_krb5_context, &ktc);
+ mem_ctx = talloc_new(cred);
+ if (!mem_ctx) {
+ return ENOMEM;
+ }
+
+ ret = create_memory_keytab(mem_ctx, cred, smb_krb5_context, &ktc);
if (ret) {
+ talloc_free(mem_ctx);
return ret;
}
cred->keytab_obtained = (MAX(cred->principal_obtained,
cred->username_obtained));
+ talloc_steal(cred, ktc);
cred->keytab = ktc;
*_ktc = cred->keytab;
+ talloc_free(mem_ctx);
+ return ret;
+}
+
+/* Given the name of a keytab (presumably in the format
+ * FILE:/etc/krb5.keytab), open it and attach it */
+
+int cli_credentials_set_keytab(struct cli_credentials *cred,
+ const char *keytab_name,
+ enum credentials_obtained obtained)
+{
+ krb5_error_code ret;
+ struct keytab_container *ktc;
+ struct smb_krb5_context *smb_krb5_context;
+ krb5_keytab keytab;
+ TALLOC_CTX *mem_ctx;
+
+ if (cred->keytab_obtained >= obtained) {
+ return 0;
+ }
+
+ ret = cli_credentials_get_krb5_context(cred, &smb_krb5_context);
+ if (ret) {
+ return ret;
+ }
+
+ mem_ctx = talloc_new(cred);
+ if (!mem_ctx) {
+ return ENOMEM;
+ }
+
+ ret = krb5_kt_resolve(smb_krb5_context->krb5_context, keytab_name, &keytab);
+ if (ret) {
+ DEBUG(1,("failed to open krb5 keytab: %s\n",
+ smb_get_krb5_error_message(smb_krb5_context->krb5_context,
+ ret, mem_ctx)));
+ talloc_free(mem_ctx);
+ return ret;
+ }
+
+ ktc = talloc(mem_ctx, struct keytab_container);
+ if (!ktc) {
+ talloc_free(mem_ctx);
+ return ENOMEM;
+ }
+
+ ktc->smb_krb5_context = talloc_reference(ktc, smb_krb5_context);
+ ktc->keytab = keytab;
+
+ cred->keytab_obtained = obtained;
+
+ talloc_steal(cred, ktc);
+ cred->keytab = ktc;
+ talloc_free(mem_ctx);
+
+ return ret;
+}
+
+int cli_credentials_update_keytab(struct cli_credentials *cred)
+{
+ krb5_error_code ret;
+ struct keytab_container *ktc;
+ struct smb_krb5_context *smb_krb5_context;
+ TALLOC_CTX *mem_ctx;
+
+ mem_ctx = talloc_new(cred);
+ if (!mem_ctx) {
+ return ENOMEM;
+ }
+
+ ret = cli_credentials_get_krb5_context(cred, &smb_krb5_context);
+ if (ret) {
+ talloc_free(mem_ctx);
+ return ret;
+ }
+
+ ret = cli_credentials_get_keytab(cred, &ktc);
+ if (ret != 0) {
+ talloc_free(mem_ctx);
+ return ret;
+ }
+
+ ret = update_keytab(mem_ctx, cred, smb_krb5_context, ktc);
+
+ talloc_free(mem_ctx);
+ return ret;
+}
+
+/* Get server gss credentials (in gsskrb5, this means the keytab) */
+
+int cli_credentials_get_server_gss_creds(struct cli_credentials *cred,
+ struct gssapi_creds_container **_gcc)
+{
+ int ret = 0;
+ OM_uint32 maj_stat, min_stat;
+ struct gssapi_creds_container *gcc;
+ struct keytab_container *ktc;
+ struct smb_krb5_context *smb_krb5_context;
+ TALLOC_CTX *mem_ctx;
+ krb5_principal princ;
+
+ if (cred->server_gss_creds_obtained >= (MAX(cred->keytab_obtained,
+ MAX(cred->principal_obtained,
+ cred->username_obtained)))) {
+ *_gcc = cred->server_gss_creds;
+ return 0;
+ }
+
+ ret = cli_credentials_get_krb5_context(cred, &smb_krb5_context);
+ if (ret) {
+ return ret;
+ }
+
+ ret = cli_credentials_get_keytab(cred,
+ &ktc);
+ if (ret) {
+ DEBUG(1, ("Failed to get keytab for GSSAPI server: %s\n", error_message(ret)));
+ return ret;
+ }
+
+ mem_ctx = talloc_new(cred);
+ if (!mem_ctx) {
+ return ENOMEM;
+ }
+
+ ret = principal_from_credentials(mem_ctx, cred, smb_krb5_context, &princ);
+ if (ret) {
+ DEBUG(1,("cli_credentials_get_server_gss_creds: makeing krb5 principal failed (%s)\n",
+ smb_get_krb5_error_message(smb_krb5_context->krb5_context,
+ ret, mem_ctx)));
+ talloc_free(mem_ctx);
+ return ret;
+ }
+
+ gcc = talloc(cred, struct gssapi_creds_container);
+ if (!gcc) {
+ talloc_free(mem_ctx);
+ return ENOMEM;
+ }
+
+ /* This creates a GSSAPI cred_id_t with the principal and keytab set */
+ maj_stat = gss_krb5_import_cred(&min_stat, NULL, princ, ktc->keytab,
+ &gcc->creds);
+ if (maj_stat) {
+ if (min_stat) {
+ ret = min_stat;
+ } else {
+ ret = EINVAL;
+ }
+ }
+ if (ret == 0) {
+ cred->server_gss_creds_obtained = cred->keytab_obtained;
+ talloc_set_destructor(gcc, free_gssapi_creds);
+ cred->server_gss_creds = gcc;
+ *_gcc = gcc;
+ }
+ talloc_free(mem_ctx);
return ret;
}
@@ -415,3 +598,5 @@ void cli_credentials_set_salt_principal(struct cli_credentials *cred, const char
{
cred->salt_principal = talloc_strdup(cred, principal);
}
+
+
diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index b5a2dadd35..68da2567da 100644
--- a/source4/auth/gensec/gensec_gssapi.c
+++ b/source4/auth/gensec/gensec_gssapi.c
@@ -41,12 +41,9 @@ struct gensec_gssapi_state {
DATA_BLOB pac;
struct smb_krb5_context *smb_krb5_context;
- krb5_ccache ccache;
- const char *ccache_name;
- struct keytab_container *keytab;
struct gssapi_creds_container *client_cred;
+ struct gssapi_creds_container *server_cred;
- gss_cred_id_t cred;
gss_cred_id_t delegated_cred_handle;
};
@@ -81,10 +78,6 @@ static int gensec_gssapi_destory(void *ptr)
struct gensec_gssapi_state *gensec_gssapi_state = ptr;
OM_uint32 maj_stat, min_stat;
- if (gensec_gssapi_state->cred != GSS_C_NO_CREDENTIAL) {
- maj_stat = gss_release_cred(&min_stat,
- &gensec_gssapi_state->cred);
- }
if (gensec_gssapi_state->delegated_cred_handle != GSS_C_NO_CREDENTIAL) {
maj_stat = gss_release_cred(&min_stat,
&gensec_gssapi_state->delegated_cred_handle);
@@ -137,7 +130,6 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security)
gensec_gssapi_state->session_key = data_blob(NULL, 0);
gensec_gssapi_state->pac = data_blob(NULL, 0);
- gensec_gssapi_state->cred = GSS_C_NO_CREDENTIAL;
gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL;
talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destory);
@@ -167,11 +159,10 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security)
static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_security)
{
NTSTATUS nt_status;
- OM_uint32 maj_stat, min_stat;
int ret;
- const char *principal;
struct gensec_gssapi_state *gensec_gssapi_state;
struct cli_credentials *machine_account;
+ struct gssapi_creds_container *gcc;
nt_status = gensec_gssapi_start(gensec_security);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -186,53 +177,15 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi
DEBUG(3, ("No machine account credentials specified\n"));
return NT_STATUS_INVALID_PARAMETER;
} else {
- ret = cli_credentials_get_keytab(machine_account, &gensec_gssapi_state->keytab);
+ ret = cli_credentials_get_server_gss_creds(machine_account, &gcc);
if (ret) {
- DEBUG(3, ("Could not create memory keytab!\n"));
+ DEBUG(1, ("Aquiring acceptor credentials failed: %s\n",
+ error_message(ret)));
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
}
}
- principal = cli_credentials_get_principal(machine_account,
- machine_account);
-
- /* This might have been explicity set to NULL, ie use what the client calls us */
- if (principal) {
- gss_buffer_desc name_token;
-
- name_token.value = discard_const_p(uint8_t, principal);
- name_token.length = strlen(principal);
-
- maj_stat = gss_import_name (&min_stat,
- &name_token,
- GSS_C_NT_USER_NAME,
- &gensec_gssapi_state->server_name);
-
- if (maj_stat) {
- DEBUG(2, ("GSS Import name of %s failed: %s\n",
- (char *)name_token.value,
- gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat)));
- return NT_STATUS_UNSUCCESSFUL;
- }
- } else {
- gensec_gssapi_state->server_name = GSS_C_NO_NAME;
- }
-
- maj_stat = gsskrb5_acquire_cred(&min_stat,
- gensec_gssapi_state->keytab->keytab,
- gensec_gssapi_state->server_name,
- GSS_C_INDEFINITE,
- GSS_C_NULL_OID_SET,
- GSS_C_ACCEPT,
- &gensec_gssapi_state->cred,
- NULL,
- NULL);
- if (maj_stat) {
- DEBUG(1, ("Aquiring acceptor credentails failed: %s\n",
- gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat)));
- return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- }
-
+ gensec_gssapi_state->server_cred = gcc;
return NT_STATUS_OK;
}
@@ -382,7 +335,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
{
maj_stat = gss_accept_sec_context(&min_stat,
&gensec_gssapi_state->gssapi_context,
- gensec_gssapi_state->cred,
+ gensec_gssapi_state->server_cred->creds,
&input_token,
gensec_gssapi_state->input_chan_bindings,
&gensec_gssapi_state->client_name,
diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c
index 565c7478f9..6f6203a92c 100644
--- a/source4/heimdal/kdc/kerberos5.c
+++ b/source4/heimdal/kdc/kerberos5.c
@@ -33,7 +33,7 @@
#include "kdc_locl.h"
-RCSID("$Id: kerberos5.c,v 1.177 2005/06/15 11:34:53 lha Exp $");
+RCSID("$Id: kerberos5.c,v 1.198 2005/11/28 20:33:57 lha Exp $");
#define MAX_TIME ((time_t)((1U << 31) - 1))
@@ -666,8 +666,7 @@ _kdc_check_flags(krb5_context context,
starttime_str, sizeof(starttime_str), TRUE);
kdc_log(context, config, 0,
"Client not yet valid until %s -- %s",
- starttime_str,
- client_name);
+ starttime_str, client_name);
return KRB5KDC_ERR_CLIENT_NOTYET;
}
@@ -676,7 +675,8 @@ _kdc_check_flags(krb5_context context,
krb5_format_time(context, *client->valid_end,
endtime_str, sizeof(endtime_str), TRUE);
kdc_log(context, config, 0,
- "Client expired at %s -- %s", endtime_str, client_name);
+ "Client expired at %s -- %s",
+ endtime_str, client_name);
return KRB5KDC_ERR_NAME_EXP;
}
@@ -686,7 +686,8 @@ _kdc_check_flags(krb5_context context,
krb5_format_time(context, *client->pw_end,
pwend_str, sizeof(pwend_str), TRUE);
kdc_log(context, config, 0,
- "Client's key has expired at %s -- %s", pwend_str, client_name);
+ "Client's key has expired at %s -- %s",
+ pwend_str, client_name);
return KRB5KDC_ERR_KEY_EXPIRED;
}
}
@@ -717,7 +718,8 @@ _kdc_check_flags(krb5_context context,
krb5_format_time(context, *server->valid_start,
starttime_str, sizeof(starttime_str), TRUE);
kdc_log(context, config, 0,
- "Server not yet valid until %s -- %s", server_name);
+ "Server not yet valid until %s -- %s",
+ starttime_str, server_name);
return KRB5KDC_ERR_SERVICE_NOTYET;
}
@@ -1099,11 +1101,12 @@ _kdc_as_rep(krb5_context context,
pa->padata_value.data = NULL;
#endif
- /* RFC4120 requires:
- - If the client only knows about old enctypes, then send both info replies
- (we send 'info' first in the list).
- - If the client is 'modern', because it knows about 'new' enc types, then
- only send the 'info2' reply.
+ /*
+ * RFC4120 requires:
+ * - If the client only knows about old enctypes, then send
+ * both info replies (we send 'info' first in the list).
+ * - If the client is 'modern', because it knows about 'new'
+ * enctype types, then only send the 'info2' reply.
*/
/* XXX check ret */
if (only_older_enctype_p(req))
diff --git a/source4/heimdal/lib/gssapi/accept_sec_context.c b/source4/heimdal/lib/gssapi/accept_sec_context.c
index 5d43cdcb43..9ca60a6cdd 100644
--- a/source4/heimdal/lib/gssapi/accept_sec_context.c
+++ b/source4/heimdal/lib/gssapi/accept_sec_context.c
@@ -33,7 +33,7 @@
#include "gssapi_locl.h"
-RCSID("$Id: accept_sec_context.c,v 1.53 2005/05/29 15:12:41 lha Exp $");
+RCSID("$Id: accept_sec_context.c,v 1.55 2005/11/25 15:57:35 lha Exp $");
HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER;
krb5_keytab gssapi_krb5_keytab;
@@ -125,66 +125,24 @@ gsskrb5_accept_delegated_token
krb5_principal principal = (*context_handle)->source;
krb5_ccache ccache = NULL;
krb5_error_code kret;
- int32_t ac_flags, ret;
- gss_cred_id_t handle = NULL;
+ int32_t ac_flags, ret = GSS_S_COMPLETE;
- if (delegated_cred_handle == NULL) {
- /* XXX Create a new delegated_cred_handle? */
-
- ret = 0;
+ *minor_status = 0;
+ /* XXX Create a new delegated_cred_handle? */
+ if (delegated_cred_handle == NULL)
kret = krb5_cc_default (gssapi_krb5_context, &ccache);
- if (kret) {
- *flags &= ~GSS_C_DELEG_FLAG;
- goto end_fwd;
- }
- } else {
-
- *delegated_cred_handle = NULL;
-
- handle = calloc(1, sizeof(*handle));
- if (handle == NULL) {
- ret = GSS_S_FAILURE;
- *minor_status = ENOMEM;
- krb5_set_error_string(gssapi_krb5_context, "out of memory");
- gssapi_krb5_set_error_string();
- *flags &= ~GSS_C_DELEG_FLAG;
- goto end_fwd;
- }
- if ((ret = gss_duplicate_name(minor_status, principal,
- &handle->principal)) != 0) {
- *flags &= ~GSS_C_DELEG_FLAG;
- ret = 0;
- goto end_fwd;
- }
- kret = krb5_cc_gen_new (gssapi_krb5_context,
- &krb5_mcc_ops,
- &handle->ccache);
- if (kret) {
- *flags &= ~GSS_C_DELEG_FLAG;
- ret = 0;
- goto end_fwd;
- }
- ccache = handle->ccache;
-
- ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
- if (ret) {
- *flags &= ~GSS_C_DELEG_FLAG;
- goto end_fwd;
- }
- ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
- &handle->mechanisms);
- if (ret) {
- *flags &= ~GSS_C_DELEG_FLAG;
- goto end_fwd;
- }
+ else
+ kret = krb5_cc_gen_new (gssapi_krb5_context, &krb5_mcc_ops, &ccache);
+ if (kret) {
+ *flags &= ~GSS_C_DELEG_FLAG;
+ goto out;
}
kret = krb5_cc_initialize(gssapi_krb5_context, ccache, principal);
if (kret) {
*flags &= ~GSS_C_DELEG_FLAG;
- ret = 0;
- goto end_fwd;
+ goto out;
}
krb5_auth_con_removeflags(gssapi_krb5_context,
@@ -204,29 +162,29 @@ gsskrb5_accept_delegated_token
*flags &= ~GSS_C_DELEG_FLAG;
ret = GSS_S_FAILURE;
*minor_status = kret;
- goto end_fwd;
+ goto out;
}
- end_fwd:
- /* if there was some kind of failure, clean up internal structures */
- if ((*flags & GSS_C_DELEG_FLAG) == 0) {
- if (handle) {
- if (handle->principal)
- gss_release_name(minor_status, &handle->principal);
- if (handle->mechanisms)
- gss_release_oid_set(NULL, &handle->mechanisms);
- if (handle->ccache)
- krb5_cc_destroy(gssapi_krb5_context, handle->ccache);
- free(handle);
- handle = NULL;
- }
+
+ if (delegated_cred_handle) {
+ ret = gss_krb5_import_cred(minor_status,
+ ccache,
+ NULL,
+ NULL,
+ delegated_cred_handle);
+ if (ret != GSS_S_COMPLETE)
+ goto out;
+
+ (*delegated_cred_handle)->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
+ ccache = NULL;
}
- if (delegated_cred_handle == NULL) {
- if (ccache)
+
+out:
+ if (ccache) {
+ if (delegated_cred_handle == NULL)
krb5_cc_close(gssapi_krb5_context, ccache);
+ else
+ krb5_cc_destroy(gssapi_krb5_context, ccache);
}
- if (handle)
- *delegated_cred_handle = handle;
-
return ret;
}
@@ -1054,7 +1012,7 @@ spnego_accept_sec_context
if(len > data.length - taglen)
return ASN1_OVERRUN;
- ret = decode_NegTokenInit((const char *)data.data + taglen, len,
+ ret = decode_NegTokenInit((const unsigned char *)data.data + taglen, len,
&ni, &ni_len);
if (ret)
return GSS_S_DEFECTIVE_TOKEN;
@@ -1065,7 +1023,7 @@ spnego_accept_sec_context
}
for (i = 0; !found && i < ni.mechTypes->len; ++i) {
- char mechbuf[17];
+ unsigned char mechbuf[17];
size_t mech_len;
ret = der_put_oid (mechbuf + sizeof(mechbuf) - 1,
diff --git a/source4/heimdal/lib/gssapi/acquire_cred.c b/source4/heimdal/lib/gssapi/acquire_cred.c
index d67b400920..44dbef3c48 100644
--- a/source4/heimdal/lib/gssapi/acquire_cred.c
+++ b/source4/heimdal/lib/gssapi/acquire_cred.c
@@ -33,7 +33,7 @@
#include "gssapi_locl.h"
-RCSID("$Id: acquire_cred.c,v 1.24 2005/10/26 11:25:16 lha Exp $");
+RCSID("$Id: acquire_cred.c,v 1.25 2005/11/02 08:56:25 lha Exp $");
OM_uint32
_gssapi_krb5_ccache_lifetime(OM_uint32 *minor_status,
@@ -106,7 +106,6 @@ get_keytab(krb5_context context, krb5_keytab *keytab)
static OM_uint32 acquire_initiator_cred
(OM_uint32 * minor_status,
krb5_context context,
- krb5_keytab keytab,
const gss_name_t desired_name,
OM_uint32 time_req,
const gss_OID_set desired_mechs,
@@ -122,7 +121,7 @@ static OM_uint32 acquire_initiator_cred
krb5_get_init_creds_opt *opt;
krb5_ccache ccache;
krb5_error_code kret;
- krb5_boolean made_keytab = FALSE;
+ krb5_keytab keytab;
ccache = NULL;
def_princ = NULL;
@@ -214,7 +213,7 @@ end:
krb5_free_cred_contents(context, &cred);
if (def_princ != NULL)
krb5_free_principal(context, def_princ);
- if (made_keytab)
+ if (keytab != NULL)
krb5_kt_close(context, keytab);
if (ret != GSS_S_COMPLETE) {
if (ccache != NULL)
@@ -230,7 +229,6 @@ end:
static OM_uint32 acquire_acceptor_cred
(OM_uint32 * minor_status,
krb5_context context,
- krb5_keytab keytab,
OM_uint32 time_req,
const gss_OID_set desired_mechs,
gss_cred_usage_t cred_usage,
@@ -244,21 +242,14 @@ static OM_uint32 acquire_acceptor_cred
kret = 0;
ret = GSS_S_FAILURE;
- if (keytab == NULL) {
- kret = get_keytab(context, &handle->keytab);
- if (kret)
- goto end;
- handle->made_keytab = TRUE;
- } else {
- handle->keytab = keytab;
- handle->made_keytab = FALSE;
- }
+ kret = get_keytab(context, &handle->keytab);
+ if (kret)
+ goto end;
ret = GSS_S_COMPLETE;
end:
if (ret != GSS_S_COMPLETE) {
- if (handle->made_keytab)
- krb5_kt_close(context, handle->keytab);
+ krb5_kt_close(context, handle->keytab);
if (kret != 0) {
*minor_status = kret;
gssapi_krb5_set_error_string ();
@@ -267,9 +258,8 @@ end:
return (ret);
}
-OM_uint32 gsskrb5_acquire_cred
+OM_uint32 gss_acquire_cred
(OM_uint32 * minor_status,
- struct krb5_keytab_data *keytab,
const gss_name_t desired_name,
OM_uint32 time_req,
const gss_OID_set desired_mechs,
@@ -328,7 +318,6 @@ OM_uint32 gsskrb5_acquire_cred
}
if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH) {
ret = acquire_initiator_cred(minor_status, gssapi_krb5_context,
- keytab,
desired_name, time_req,
desired_mechs, cred_usage,
handle, actual_mechs, time_rec);
@@ -341,7 +330,7 @@ OM_uint32 gsskrb5_acquire_cred
}
if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) {
ret = acquire_acceptor_cred(minor_status, gssapi_krb5_context,
- keytab, time_req,
+ time_req,
desired_mechs, cred_usage,
handle, actual_mechs, time_rec);
if (ret != GSS_S_COMPLETE) {
@@ -381,24 +370,3 @@ OM_uint32 gsskrb5_acquire_cred
return (GSS_S_COMPLETE);
}
-OM_uint32 gss_acquire_cred
- (OM_uint32 * minor_status,
- const gss_name_t desired_name,
- OM_uint32 time_req,
- const gss_OID_set desired_mechs,
- gss_cred_usage_t cred_usage,
- gss_cred_id_t * output_cred_handle,
- gss_OID_set * actual_mechs,
- OM_uint32 * time_rec
- )
-{
- return gsskrb5_acquire_cred(minor_status,
- NULL,
- desired_name,
- time_req,
- desired_mechs,
- cred_usage,
- output_cred_handle,
- actual_mechs,
- time_rec);
-}
diff --git a/source4/heimdal/lib/gssapi/arcfour.c b/source4/heimdal/lib/gssapi/arcfour.c
index 52bb2ecf1b..01c6c75ecc 100644
--- a/source4/heimdal/lib/gssapi/arcfour.c
+++ b/source4/heimdal/lib/gssapi/arcfour.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003 - 2004 Kungliga Tekniska Högskolan
+ * Copyright (c) 2003 - 2005 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,7 +33,7 @@
#include "gssapi_locl.h"
-RCSID("$Id: arcfour.c,v 1.17 2005/05/06 07:13:32 lha Exp $");
+RCSID("$Id: arcfour.c,v 1.18 2005/11/01 06:55:55 lha Exp $");
/*
* Implements draft-brezak-win2k-krb-rc4-hmac-04.txt
@@ -105,7 +105,7 @@ arcfour_mic_key(krb5_context context, krb5_keyblock *key,
static krb5_error_code
arcfour_mic_cksum(krb5_keyblock *key, unsigned usage,
u_char *sgn_cksum, size_t sgn_cksum_sz,
- const char *v1, size_t l1,
+ const u_char *v1, size_t l1,
const void *v2, size_t l2,
const void *v3, size_t l3)
{
@@ -256,7 +256,7 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
p = token_buffer->value;
omret = gssapi_krb5_verify_header (&p,
token_buffer->length,
- type,
+ (u_char *)type,
GSS_KRB5_MECHANISM);
if (omret)
return omret;
diff --git a/source4/heimdal/lib/gssapi/copy_ccache.c b/source4/heimdal/lib/gssapi/copy_ccache.c
index 0f2f155870..782b701e44 100644
--- a/source4/heimdal/lib/gssapi/copy_ccache.c
+++ b/source4/heimdal/lib/gssapi/copy_ccache.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000 - 2001, 2003 Kungliga Tekniska Högskolan
+ * Copyright (c) 2000 - 2001, 2003 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,7 +33,7 @@
#include "gssapi_locl.h"
-RCSID("$Id: copy_ccache.c,v 1.9 2005/10/31 16:02:08 lha Exp $");
+RCSID("$Id: copy_ccache.c,v 1.13 2005/11/28 23:05:44 lha Exp $");
OM_uint32
gss_krb5_copy_ccache(OM_uint32 *minor_status,
@@ -63,9 +63,11 @@ gss_krb5_copy_ccache(OM_uint32 *minor_status,
OM_uint32
-gss_krb5_import_ccache(OM_uint32 *minor_status,
- krb5_ccache in,
- gss_cred_id_t *cred)
+gss_krb5_import_cred(OM_uint32 *minor_status,
+ krb5_ccache id,
+ krb5_principal keytab_principal,
+ krb5_keytab keytab,
+ gss_cred_id_t *cred)
{
krb5_error_code kret;
gss_cred_id_t handle;
@@ -83,57 +85,94 @@ gss_krb5_import_ccache(OM_uint32 *minor_status,
}
HEIMDAL_MUTEX_init(&handle->cred_id_mutex);
- handle->usage = GSS_C_INITIATE;
+ handle->usage = 0;
- kret = krb5_cc_get_principal(gssapi_krb5_context, in, &handle->principal);
- if (kret) {
- free(handle);
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
+ if (id) {
+ char *str;
- ret = _gssapi_krb5_ccache_lifetime(minor_status,
- in,
- handle->principal,
- &handle->lifetime);
- if (ret != GSS_S_COMPLETE) {
- krb5_free_principal(gssapi_krb5_context, handle->principal);
- free(handle);
- return ret;
- }
+ handle->usage |= GSS_C_INITIATE;
- ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
- if (ret == GSS_S_COMPLETE)
- ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
- &handle->mechanisms);
- if (ret != GSS_S_COMPLETE) {
- krb5_free_principal(gssapi_krb5_context, handle->principal);
- free(handle);
- *minor_status = kret;
- return GSS_S_FAILURE;
+ kret = krb5_cc_get_principal(gssapi_krb5_context, id,
+ &handle->principal);
+ if (kret) {
+ free(handle);
+ gssapi_krb5_set_error_string ();
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ if (keytab_principal) {
+ krb5_boolean match;
+
+ match = krb5_principal_compare(gssapi_krb5_context,
+ handle->principal,
+ keytab_principal);
+ if (match == FALSE) {
+ krb5_free_principal(gssapi_krb5_context, handle->principal);
+ free(handle);
+ gssapi_krb5_clear_status ();
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ }
+
+ ret = _gssapi_krb5_ccache_lifetime(minor_status,
+ id,
+ handle->principal,
+ &handle->lifetime);
+ if (ret != GSS_S_COMPLETE) {
+ krb5_free_principal(gssapi_krb5_context, handle->principal);
+ free(handle);
+ return ret;
+ }
+
+
+ kret = krb5_cc_get_full_name(gssapi_krb5_context, id, &str);
+ if (kret)
+ goto out;
+
+ kret = krb5_cc_resolve(gssapi_krb5_context, str, &handle->ccache);
+ free(str);
+ if (kret)
+ goto out;
}
- {
- const char *type, *name;
+
+ if (keytab) {
char *str;
- type = krb5_cc_get_type(gssapi_krb5_context, in);
- name = krb5_cc_get_name(gssapi_krb5_context, in);
-
- if (asprintf(&str, "%s:%s", type, name) == -1) {
- krb5_set_error_string(gssapi_krb5_context,
- "malloc - out of memory");
- kret = ENOMEM;
- goto out;
+ handle->usage |= GSS_C_ACCEPT;
+
+ if (keytab_principal && handle->principal == NULL) {
+ kret = krb5_copy_principal(gssapi_krb5_context,
+ keytab_principal,
+ &handle->principal);
+ if (kret)
+ goto out;
}
- kret = krb5_cc_resolve(gssapi_krb5_context, str, &handle->ccache);
+ kret = krb5_kt_get_full_name(gssapi_krb5_context, keytab, &str);
+ if (kret)
+ goto out;
+
+ kret = krb5_kt_resolve(gssapi_krb5_context, str, &handle->keytab);
free(str);
if (kret)
goto out;
}
+
+ if (id || keytab) {
+ ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
+ if (ret == GSS_S_COMPLETE)
+ ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
+ &handle->mechanisms);
+ if (ret != GSS_S_COMPLETE) {
+ kret = *minor_status;
+ goto out;
+ }
+ }
+
*minor_status = 0;
*cred = handle;
return GSS_S_COMPLETE;
diff --git a/source4/heimdal/lib/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi.h
index 64a31d1eee..20700dc826 100644
--- a/source4/heimdal/lib/gssapi/gssapi.h
+++ b/source4/heimdal/lib/gssapi/gssapi.h
@@ -775,18 +775,6 @@ OM_uint32 gss_unseal
* kerberos mechanism specific functions
*/
-OM_uint32 gsskrb5_acquire_cred
- (OM_uint32 * minor_status,
- struct krb5_keytab_data *keytab,
- const gss_name_t desired_name,
- OM_uint32 time_req,
- const gss_OID_set desired_mechs,
- gss_cred_usage_t cred_usage,
- gss_cred_id_t * output_cred_handle,
- gss_OID_set * actual_mechs,
- OM_uint32 * time_rec
- );
-
OM_uint32
gss_krb5_ccache_name(OM_uint32 * /*minor_status*/,
const char * /*name */,
@@ -805,10 +793,11 @@ OM_uint32 gss_krb5_copy_service_keyblock
gss_ctx_id_t context_handle,
struct EncryptionKey **out);
-OM_uint32
-gss_krb5_import_ccache(OM_uint32 */*minor*/,
- struct krb5_ccache_data * /*in*/,
- gss_cred_id_t */*out*/);
+OM_uint32 gss_krb5_import_cred(OM_uint32 *minor_status,
+ struct krb5_ccache_data * /* id */,
+ struct Principal * /* keytab_principal */,
+ struct krb5_keytab_data * /* keytab */,
+ gss_cred_id_t */* cred */);
OM_uint32 gss_krb5_get_tkt_flags
(OM_uint32 */*minor*/,
diff --git a/source4/heimdal/lib/gssapi/gssapi_locl.h b/source4/heimdal/lib/gssapi/gssapi_locl.h
index ae291d15a9..b9bea7db2e 100644
--- a/source4/heimdal/lib/gssapi/gssapi_locl.h
+++ b/source4/heimdal/lib/gssapi/gssapi_locl.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
-/* $Id: gssapi_locl.h,v 1.42 2005/10/26 11:23:48 lha Exp $ */
+/* $Id: gssapi_locl.h,v 1.43 2005/11/02 08:51:17 lha Exp $ */
#ifndef GSSAPI_LOCL_H
#define GSSAPI_LOCL_H
diff --git a/source4/heimdal/lib/gssapi/init_sec_context.c b/source4/heimdal/lib/gssapi/init_sec_context.c
index e7e8f5153e..61c020b800 100644
--- a/source4/heimdal/lib/gssapi/init_sec_context.c
+++ b/source4/heimdal/lib/gssapi/init_sec_context.c
@@ -33,7 +33,7 @@
#include "gssapi_locl.h"
-RCSID("$Id: init_sec_context.c,v 1.60 2005/10/12 07:25:18 lha Exp $");
+RCSID("$Id: init_sec_context.c,v 1.61 2005/11/02 11:52:49 lha Exp $");
/*
* copy the addresses from `input_chan_bindings' (if any) to
diff --git a/source4/heimdal/lib/gssapi/release_cred.c b/source4/heimdal/lib/gssapi/release_cred.c
index ddd80c144b..cca3dfe379 100644
--- a/source4/heimdal/lib/gssapi/release_cred.c
+++ b/source4/heimdal/lib/gssapi/release_cred.c
@@ -33,7 +33,7 @@
#include "gssapi_locl.h"
-RCSID("$Id: release_cred.c,v 1.10 2003/10/07 00:51:46 lha Exp $");
+RCSID("$Id: release_cred.c,v 1.11 2005/11/02 08:57:35 lha Exp $");
OM_uint32 gss_release_cred
(OM_uint32 * minor_status,
diff --git a/source4/heimdal/lib/hdb/db.c b/source4/heimdal/lib/hdb/db.c
index d7a4cf35ee..b9f1ab47e1 100644
--- a/source4/heimdal/lib/hdb/db.c
+++ b/source4/heimdal/lib/hdb/db.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,7 +33,7 @@
#include "hdb_locl.h"
-RCSID("$Id: db.c,v 1.32 2005/06/23 13:34:17 lha Exp $");
+RCSID("$Id: db.c,v 1.33 2005/11/28 23:30:51 lha Exp $");
#if HAVE_DB1
@@ -270,7 +270,7 @@ krb5_error_code
hdb_db_create(krb5_context context, HDB **db,
const char *filename)
{
- *db = malloc(sizeof(**db));
+ *db = calloc(1, sizeof(**db));
if (*db == NULL) {
krb5_set_error_string(context, "malloc: out of memory");
return ENOMEM;
diff --git a/source4/heimdal/lib/hdb/hdb-protos.h b/source4/heimdal/lib/hdb/hdb-protos.h
index 7557b46bff..f7e0c54b7c 100644
--- a/source4/heimdal/lib/hdb/hdb-protos.h
+++ b/source4/heimdal/lib/hdb/hdb-protos.h
@@ -120,7 +120,9 @@ hdb_free_entry (
hdb_entry */*ent*/);
void
-hdb_free_entry_ex(krb5_context context, hdb_entry_ex *ent);
+hdb_free_entry_ex (
+ krb5_context /*context*/,
+ hdb_entry_ex */*ent*/);
void
hdb_free_key (Key */*key*/);
diff --git a/source4/heimdal/lib/hdb/ndbm.c b/source4/heimdal/lib/hdb/ndbm.c
index 588ff80728..dfd5bfa8f1 100644
--- a/source4/heimdal/lib/hdb/ndbm.c
+++ b/source4/heimdal/lib/hdb/ndbm.c
@@ -339,6 +339,8 @@ hdb_ndbm_create(krb5_context context, HDB **db,
return ENOMEM;
}
+ memset(*db, '\0', sizeof(**db));
+
(*db)->hdb_db = NULL;
(*db)->hdb_name = strdup(filename);
if ((*db)->hdb_name == NULL) {
diff --git a/source4/heimdal/lib/krb5/cache.c b/source4/heimdal/lib/krb5/cache.c
index ec956409a7..25dc2cb8c0 100644
--- a/source4/heimdal/lib/krb5/cache.c
+++ b/source4/heimdal/lib/krb5/cache.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: cache.c,v 1.73 2005/10/19 17:30:40 lha Exp $");
+RCSID("$Id: cache.c,v 1.74 2005/11/01 09:36:41 lha Exp $");
/*
* Add a new ccache type with operations `ops', overwriting any
@@ -223,6 +223,41 @@ krb5_cc_get_type(krb5_context context,
}
/*
+ * Return the complete resolvable name the ccache `id' in `str´.
+ * `str` should be freed with free(3).
+ * Returns 0 or an error (and then *str is set to NULL).
+ */
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_cc_get_full_name(krb5_context context,
+ krb5_ccache id,
+ char **str)
+{
+ const char *type, *name;
+
+ *str = NULL;
+
+ type = krb5_cc_get_type(context, id);
+ if (type == NULL) {
+ krb5_set_error_string(context, "cache have no name of type");
+ return KRB5_CC_UNKNOWN_TYPE;
+ }
+
+ name = krb5_cc_get_name(context, id);
+ if (name == NULL) {
+ krb5_set_error_string(context, "cache of type %s have no name", type);
+ return KRB5_CC_BADNAME;
+ }
+
+ if (asprintf(str, "%s:%s", type, name) == -1) {
+ krb5_set_error_string(context, "malloc - out of memory");
+ *str = NULL;
+ return ENOMEM;
+ }
+ return 0;
+}
+
+/*
* Return krb5_cc_ops of a the ccache `id'.
*/
diff --git a/source4/heimdal/lib/krb5/get_for_creds.c b/source4/heimdal/lib/krb5/get_for_creds.c
index 7bc8942f66..be5c1db47d 100644
--- a/source4/heimdal/lib/krb5/get_for_creds.c
+++ b/source4/heimdal/lib/krb5/get_for_creds.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,7 +33,7 @@
#include <krb5_locl.h>
-RCSID("$Id: get_for_creds.c,v 1.45 2005/06/15 02:44:36 lha Exp $");
+RCSID("$Id: get_for_creds.c,v 1.46 2005/11/28 20:43:02 lha Exp $");
static krb5_error_code
add_addrs(krb5_context context,
@@ -385,17 +385,13 @@ krb5_get_forwarded_creds (krb5_context context,
cred.enc_part.cipher.data = buf;
cred.enc_part.cipher.length = buf_size;
} else {
- /*
- * RFC4120 claims we should use the session key, but Heimdal
- * before 0.8 used the remote subkey if it was send in the
- * auth_context.
- *
- * Lorikeet-Heimdal is interested in windows compatiblity
- * more than Heimdal compatability, so we must choose the
- * session key, and break forwarding credentials to older
- * Heimdal servers.
- */
-
+ /*
+ * Here older versions then 0.7.2 of Heimdal used the local or
+ * remote subkey. That is wrong, the session key should be
+ * used. Heimdal 0.7.2 and newer have code to try both in the
+ * receiving end.
+ */
+
ret = krb5_crypto_init(context, auth_context->keyblock, 0, &crypto);
if (ret) {
free(buf);
diff --git a/source4/heimdal/lib/krb5/keytab.c b/source4/heimdal/lib/krb5/keytab.c
index 23f6685049..43fc21c1d1 100644
--- a/source4/heimdal/lib/krb5/keytab.c
+++ b/source4/heimdal/lib/krb5/keytab.c
@@ -33,7 +33,7 @@
#include "krb5_locl.h"
-RCSID("$Id: keytab.c,v 1.62 2005/07/06 01:14:42 lha Exp $");
+RCSID("$Id: keytab.c,v 1.63 2005/11/25 21:46:40 lha Exp $");
/*
* Register a new keytab in `ops'
@@ -240,6 +240,40 @@ krb5_kt_get_name(krb5_context context,
}
/*
+ * Retrieve the full name of the keytab `keytab' and store the name in
+ * `str'. `str' needs to be freed by the caller using free(3).
+ * Returns 0 or an error. On error, *str is set to NULL.
+ */
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_kt_get_full_name(krb5_context context,
+ krb5_keytab keytab,
+ char **str)
+{
+ char type[KRB5_KT_PREFIX_MAX_LEN];
+ char name[MAXPATHLEN];
+ krb5_error_code ret;
+
+ *str = NULL;
+
+ ret = krb5_kt_get_type(context, keytab, type, sizeof(type));
+ if (ret)
+ return ret;
+
+ ret = krb5_kt_get_name(context, keytab, name, sizeof(name));
+ if (ret)
+ return ret;
+
+ if (asprintf(str, "%s:%s", type, name) == -1) {
+ krb5_set_error_string(context, "malloc - out of memory");
+ *str = NULL;
+ return ENOMEM;
+ }
+
+ return 0;
+}
+
+/*
* Finish using the keytab in `id'. All resources will be released,
* even on errors. Return 0 or an error.
*/
diff --git a/source4/heimdal/lib/krb5/krb5-private.h b/source4/heimdal/lib/krb5/krb5-private.h
index 2645c29fe7..3602c89ec6 100644
--- a/source4/heimdal/lib/krb5/krb5-private.h
+++ b/source4/heimdal/lib/krb5/krb5-private.h
@@ -77,6 +77,15 @@ _krb5_extract_ticket (
krb5_decrypt_proc /*decrypt_proc*/,
krb5_const_pointer /*decryptarg*/);
+int
+_krb5_find_type_in_ad (
+ krb5_context /*context*/,
+ int /*type*/,
+ krb5_data */*data*/,
+ krb5_boolean */*found*/,
+ krb5_keyblock */*sessionkey*/,
+ const AuthorizationData */*ad*/);
+
void
_krb5_free_krbhst_info (krb5_krbhst_info */*hi*/);
@@ -399,12 +408,4 @@ _krb5_xunlock (
krb5_context /*context*/,
int /*fd*/);
-int
-_krb5_find_type_in_ad(krb5_context context,
- int type,
- krb5_data *data,
- int *found,
- krb5_keyblock *sessionkey,
- const AuthorizationData *ad);
-
#endif /* __krb5_private_h__ */
diff --git a/source4/heimdal/lib/krb5/krb5-protos.h b/source4/heimdal/lib/krb5/krb5-protos.h
index a46f8b8f8f..33e35ca60e 100644
--- a/source4/heimdal/lib/krb5/krb5-protos.h
+++ b/source4/heimdal/lib/krb5/krb5-protos.h
@@ -607,6 +607,12 @@ krb5_cc_gen_new (
const krb5_cc_ops */*ops*/,
krb5_ccache */*id*/);
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_cc_get_full_name (
+ krb5_context /*context*/,
+ krb5_ccache /*id*/,
+ char **/*str*/);
+
const char* KRB5_LIB_FUNCTION
krb5_cc_get_name (
krb5_context /*context*/,
@@ -2186,6 +2192,12 @@ krb5_kt_get_entry (
krb5_keytab_entry */*entry*/);
krb5_error_code KRB5_LIB_FUNCTION
+krb5_kt_get_full_name (
+ krb5_context /*context*/,
+ krb5_keytab /*keytab*/,
+ char **/*str*/);
+
+krb5_error_code KRB5_LIB_FUNCTION
krb5_kt_get_name (
krb5_context /*context*/,
krb5_keytab /*keytab*/,
diff --git a/source4/heimdal/lib/krb5/rd_cred.c b/source4/heimdal/lib/krb5/rd_cred.c
index 07f142267c..d62adadf26 100644
--- a/source4/heimdal/lib/krb5/rd_cred.c
+++ b/source4/heimdal/lib/krb5/rd_cred.c
@@ -33,7 +33,7 @@
#include <krb5_locl.h>
-RCSID("$Id: rd_cred.c,v 1.25 2005/09/23 03:37:57 lha Exp $");
+RCSID("$Id: rd_cred.c,v 1.26 2005/11/02 08:36:42 lha Exp $");
static krb5_error_code
compare_addrs(krb5_context context,
diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c
index 0eb109c2cf..1530a9f6a8 100644
--- a/source4/libnet/libnet_join.c
+++ b/source4/libnet/libnet_join.c
@@ -1094,6 +1094,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
uint32_t acct_type = 0;
const char *account_name;
const char *netbios_name;
+ char *filter;
r->out.error_string = NULL;
@@ -1212,6 +1213,13 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
talloc_free(tmp_mem);
return NT_STATUS_NO_MEMORY;
}
+
+ rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "objectClass", "primaryDomain");
+ if (rtn == -1) {
+ r->out.error_string = NULL;
+ talloc_free(tmp_mem);
+ return NT_STATUS_NO_MEMORY;
+ }
}
rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "objectClass", "primaryDomain");
@@ -1341,6 +1349,33 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx,
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
+ if (r2->out.realm) {
+ struct cli_credentials *creds;
+ /* Make a credentials structure from it */
+ creds = cli_credentials_init(mem_ctx);
+ if (!creds) {
+ r->out.error_string = NULL;
+ talloc_free(tmp_mem);
+ return NT_STATUS_NO_MEMORY;
+ }
+ cli_credentials_set_conf(creds);
+ filter = talloc_asprintf(mem_ctx, "dn=%s", ldb_dn_linearize(mem_ctx, msg->dn));
+ status = cli_credentials_set_secrets(creds, NULL, filter);
+ if (!NT_STATUS_IS_OK(status)) {
+ r->out.error_string = talloc_asprintf(mem_ctx, "Failed to read secrets for keytab update for %s\n",
+ filter);
+ talloc_free(tmp_mem);
+ return status;
+ }
+ ret = cli_credentials_update_keytab(creds);
+ if (ret != 0) {
+ r->out.error_string = talloc_asprintf(mem_ctx, "Failed to update keytab for %s\n",
+ filter);
+ talloc_free(tmp_mem);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ }
+
/* move all out parameter to the callers TALLOC_CTX */
r->out.error_string = NULL;
r->out.join_password = r2->out.join_password;
diff --git a/source4/scripting/ejs/smbcalls_creds.c b/source4/scripting/ejs/smbcalls_creds.c
index cc2ccf8c47..3cd554b957 100644
--- a/source4/scripting/ejs/smbcalls_creds.c
+++ b/source4/scripting/ejs/smbcalls_creds.c
@@ -240,6 +240,16 @@ int ejs_credentials_cmdline(int eid, int argc, struct MprVar **argv)
return ejs_credentials_obj(obj, cmdline_credentials);
}
+static int ejs_credentials_update_all_keytabs(MprVarHandle eid, int argc, struct MprVar **argv)
+{
+ if (!NT_STATUS_IS_OK(cli_credentials_update_all_keytabs(mprMemCtx()))) {
+ mpr_Return(eid, mprCreateBoolVar(False));
+ } else {
+ mpr_Return(eid, mprCreateBoolVar(True));
+ }
+ return 0;
+}
+
/*
setup C functions that be called from ejs
@@ -247,4 +257,6 @@ int ejs_credentials_cmdline(int eid, int argc, struct MprVar **argv)
void smb_setup_ejs_credentials(void)
{
ejsDefineCFunction(-1, "credentials_init", ejs_credentials_init, NULL, MPR_VAR_SCRIPT_HANDLE);
+ ejsDefineCFunction(-1, "credentials_update_all_keytabs", ejs_credentials_update_all_keytabs, NULL, MPR_VAR_SCRIPT_HANDLE);
}
+
diff --git a/source4/scripting/libjs/provision.js b/source4/scripting/libjs/provision.js
index 513fb23cd9..0b6a31ae4f 100644
--- a/source4/scripting/libjs/provision.js
+++ b/source4/scripting/libjs/provision.js
@@ -302,6 +302,9 @@ function provision(subobj, message, blank, paths)
setup_file("provision.zone",
paths.dns,
subobj);
+ message("Setting up keytabs\n");
+ var keytab_ok = credentials_update_all_keytabs();
+ assert(keytab_ok);
}
/*
diff --git a/source4/setup/secrets.ldif b/source4/setup/secrets.ldif
index c573ad3b56..43c3f69c9d 100644
--- a/source4/setup/secrets.ldif
+++ b/source4/setup/secrets.ldif
@@ -26,6 +26,7 @@ cn: Primary Domains
dn: flatname=${DOMAIN},CN=Primary Domains
objectClass: top
objectClass: primaryDomain
+objectClass: kerberosSecret
flatname: ${DOMAIN}
realm: ${REALM}
secret: ${MACHINEPASS}
@@ -35,10 +36,12 @@ whenCreated: ${LDAPTIME}
whenChanged: ${LDAPTIME}
msDS-KeyVersionNumber: 1
objectSid: ${DOMAINSID}
+privateKeytab: secrets.keytab
dn: samAccountName=krbtgt,flatname=${DOMAIN},CN=Principals
objectClass: top
objectClass: secret
+objectClass: kerberosSecret
flatname: ${DOMAIN}
realm: ${REALM}
secret: ${KRBTGTPASS}
@@ -49,3 +52,4 @@ msDS-KeyVersionNumber: 1
objectSid: ${DOMAINSID}
servicePrincipalName: kadmin/changepw
saltPrincipal: krbtgt@${REALM}
+privateKeytab: secrets.keytab