summaryrefslogtreecommitdiff
path: root/source3/libads
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libads')
-rw-r--r--source3/libads/ads_status.c2
-rw-r--r--source3/libads/authdata.c7
-rw-r--r--source3/libads/kerberos_verify.c165
-rw-r--r--source3/libads/krb5_setpw.c17
-rw-r--r--source3/libads/ldap.c6
-rw-r--r--source3/libads/ldap_utils.c5
-rw-r--r--source3/libads/sasl.c18
7 files changed, 184 insertions, 36 deletions
diff --git a/source3/libads/ads_status.c b/source3/libads/ads_status.c
index 80fdb99eac..11f9d66b92 100644
--- a/source3/libads/ads_status.c
+++ b/source3/libads/ads_status.c
@@ -87,7 +87,7 @@ NTSTATUS ads_ntstatus(ADS_STATUS status)
*/
const char *ads_errstr(ADS_STATUS status)
{
- int msg_ctx;
+ uint32 msg_ctx;
static char *ret;
SAFE_FREE(ret);
diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c
index 50a9ef2718..29170af377 100644
--- a/source3/libads/authdata.c
+++ b/source3/libads/authdata.c
@@ -39,6 +39,7 @@ static DATA_BLOB unwrap_pac(DATA_BLOB *auth_data)
asn1_end_tag(&data);
asn1_end_tag(&data);
asn1_end_tag(&data);
+ asn1_free(&data);
return pac_contents;
}
@@ -422,7 +423,7 @@ static BOOL pac_io_pac_signature_data(const char *desc,
if (!prs_uint32("type", ps, depth, &data->type))
return False;
if (UNMARSHALLING(ps)) {
- data->signature = prs_alloc_mem(ps, siglen);
+ data->signature = (unsigned char *)prs_alloc_mem(ps, siglen);
if (!data->signature) {
DEBUG(3, ("No memory available\n"));
return False;
@@ -600,9 +601,11 @@ PAC_DATA *decode_pac_data(DATA_BLOB *auth_data, TALLOC_CTX *ctx)
DEBUG(5,("dump_pac_data\n"));
prs_init(&ps, pac_data_blob.length, ctx, UNMARSHALL);
- prs_copy_data_in(&ps, pac_data_blob.data, pac_data_blob.length);
+ prs_copy_data_in(&ps, (char *)pac_data_blob.data, pac_data_blob.length);
prs_set_offset(&ps, 0);
+ data_blob_free(&pac_data_blob);
+
pac_data = (PAC_DATA *) talloc_zero(ctx, sizeof(PAC_DATA));
pac_io_pac_data("pac data", pac_data, &ps, 0);
diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c
index 48b61cd1f2..4ae89aa01f 100644
--- a/source3/libads/kerberos_verify.c
+++ b/source3/libads/kerberos_verify.c
@@ -4,6 +4,8 @@
Copyright (C) Andrew Tridgell 2001
Copyright (C) Remus Koos 2001
Copyright (C) Luke Howard 2003
+ Copyright (C) Guenther Deschner 2003
+ Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003
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
@@ -24,11 +26,132 @@
#ifdef HAVE_KRB5
+static void free_keytab(krb5_context context, krb5_keytab keytab)
+{
+ int ret=0;
+
+ if (keytab)
+ ret = krb5_kt_close(context, keytab);
+ if (ret) {
+ DEBUG(3, ("krb5_kt_close failed (%s)\n",
+ error_message(ret)));
+ }
+}
+
+#ifdef HAVE_MEMORY_KEYTAB
+static krb5_error_code create_keytab(krb5_context context,
+ krb5_principal host_princ,
+ char *host_princ_s,
+ krb5_data password,
+ krb5_enctype *enctypes,
+ krb5_keytab *keytab,
+ char *keytab_name)
+{
+ krb5_keytab_entry entry;
+ krb5_kvno kvno = 1;
+ krb5_error_code ret;
+ krb5_keyblock *key;
+ int i;
+
+ DEBUG(10,("creating keytab: %s\n", keytab_name));
+ ret = krb5_kt_resolve(context, keytab_name, keytab);
+ if (ret)
+ return ret;
+
+ if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) {
+ return ENOMEM;
+ }
+
+ /* add keytab entries for all encryption types */
+ for ( i=0; enctypes[i]; i++ ) {
+
+ if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) {
+ continue;
+ }
+
+ entry.principal = host_princ;
+ entry.vno = kvno;
+ /* this will have to be detected in configure...heimdal
+ calls it keyblock, MIT calls it key, but it does not
+ matter we are creating keytabs with MIT */
+ entry.keyblock = *key;
+
+ DEBUG(10,("adding keytab-entry for (%s) with encryption type (%d)\n",
+ host_princ_s, enctypes[i]));
+ ret = krb5_kt_add_entry(context, *keytab, &entry);
+ if (ret) {
+ DEBUG(1,("adding entry to keytab failed (%s)\n",
+ error_message(ret)));
+ free_keytab(context, *keytab);
+ return ret;
+ }
+ }
+ krb5_free_keyblock(context, key);
+
+ return 0;
+}
+#endif
+
+static BOOL setup_keytab(krb5_context context,
+ krb5_principal host_princ,
+ char *host_princ_s,
+ krb5_data password,
+ krb5_enctype *enctypes,
+ krb5_keytab *keytab)
+{
+ char *keytab_name = NULL;
+ krb5_error_code ret;
+
+ /* check if we have to setup a keytab - not currently enabled
+ I've put this in so that the else block below functions
+ the same way that it will when this code is turned on */
+ if (0 /* will later be *lp_keytab() */) {
+
+ /* use a file-keytab */
+ asprintf(&keytab_name, "%s:%s",
+ ""
+ /* KRB5_KT_FILE_PREFIX, "FILE" or
+ "WRFILE" depending on HEeimdal or MIT */,
+ "" /* will later be lp_keytab() */);
+
+ DEBUG(10,("will use filebased keytab: %s\n", keytab_name));
+ ret = krb5_kt_resolve(context, keytab_name, keytab);
+ if (ret) {
+ DEBUG(3,("cannot resolve keytab name %s (%s)\n",
+ keytab_name,
+ error_message(ret)));
+ SAFE_FREE(keytab_name);
+ return False;
+ }
+
+ }
+
+#if defined(HAVE_MEMORY_KEYTAB)
+ else {
+
+ /* setup a in-memory-keytab */
+ asprintf(&keytab_name, "MEMORY:");
+
+ ret = create_keytab(context, host_princ, host_princ_s, password, enctypes,
+ keytab, keytab_name);
+ if (ret) {
+ DEBUG(3,("unable to create MEMORY: keytab (%s)\n",
+ error_message(ret)));
+ SAFE_FREE(keytab_name);
+ return False;
+ }
+ }
+#endif
+ SAFE_FREE(keytab_name);
+ return True;
+}
+
+
/*
verify an incoming ticket and parse out the principal name and
authorization_data if available
*/
-NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
+NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket,
char **principal, DATA_BLOB *auth_data,
DATA_BLOB *ap_rep,
uint8 session_key[16])
@@ -79,7 +202,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
return NT_STATUS_LOGON_FAILURE;
}
- ret = krb5_set_default_realm(context, ads->auth.realm);
+ ret = krb5_set_default_realm(context, realm);
if (ret) {
DEBUG(1,("ads_verify_ticket: krb5_set_default_realm failed (%s)\n", error_message(ret)));
sret = NT_STATUS_LOGON_FAILURE;
@@ -128,11 +251,6 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
/* CIFS doesn't use addresses in tickets. This would breat NAT. JRA */
- if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) {
- sret = NT_STATUS_NO_MEMORY;
- goto out;
- }
-
if ((ret = get_kerberos_allowed_etypes(context, &enctypes))) {
DEBUG(1,("ads_verify_ticket: krb5_get_permitted_enctypes failed (%s)\n",
error_message(ret)));
@@ -149,22 +267,40 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
goto out;
}
+ if (!setup_keytab(context, host_princ, host_princ_s, password,
+ enctypes, &keytab)) {
+ DEBUG(3,("ads_verify_ticket: unable to setup keytab\n"));
+ sret = NT_STATUS_LOGON_FAILURE;
+ goto out;
+ }
+
/* We need to setup a auth context with each possible encoding type in turn. */
for (i=0;enctypes[i];i++) {
+ if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) {
+ sret = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) {
continue;
}
krb5_auth_con_setuseruserkey(context, auth_context, key);
+ krb5_free_keyblock(context, key);
+
packet.length = ticket->length;
packet.data = (krb5_pointer)ticket->data;
if (!(ret = krb5_rd_req(context, &auth_context, &packet,
- NULL, keytab, NULL, &tkt))) {
+#ifdef HAVE_MEMORY_KEYTAB
+ host_princ,
+#else
+ NULL,
+#endif
+ keytab, NULL, &tkt))) {
DEBUG(10,("ads_verify_ticket: enc type [%u] decrypted message !\n",
(unsigned int)enctypes[i] ));
- free_kerberos_etypes(context, enctypes);
auth_ok = True;
break;
}
@@ -217,8 +353,13 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
file_save("/tmp/authdata.dat",
tkt->enc_part2->authorization_data[0]->contents,
tkt->enc_part2->authorization_data[0]->length);
+ }
#endif
+
+ /* get rid of all resources associated with the keytab */
+ if (keytab) free_keytab(context, keytab);
+
if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt),
principal))) {
DEBUG(3,("ads_verify_ticket: krb5_unparse_name failed (%s)\n",
@@ -237,8 +378,12 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
if (!NT_STATUS_IS_OK(sret))
data_blob_free(ap_rep);
- SAFE_FREE(host_princ_s);
+ krb5_free_principal(context, host_princ);
+ if (tkt != NULL)
+ krb5_free_ticket(context, tkt);
+ free_kerberos_etypes(context, enctypes);
SAFE_FREE(password_s);
+ SAFE_FREE(host_princ_s);
if (auth_context)
krb5_auth_con_free(context, auth_context);
diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c
index 80ef6cdf01..9cf15221a8 100644
--- a/source3/libads/krb5_setpw.c
+++ b/source3/libads/krb5_setpw.c
@@ -143,7 +143,7 @@ static krb5_error_code build_kpasswd_request(uint16 pversion,
else
return EINVAL;
- encoded_setpw.data = setpw.data;
+ encoded_setpw.data = (char *)setpw.data;
encoded_setpw.length = setpw.length;
ret = krb5_mk_priv(context, auth_context,
@@ -664,25 +664,22 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server,
* @return status of password change
**/
ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads,
- const char *hostname,
+ const char *machine_account,
const char *password)
{
ADS_STATUS status;
- char *host = strdup(hostname);
- char *principal;
-
- strlower_m(host);
+ char *principal = NULL;
/*
- we need to use the '$' form of the name here, as otherwise the
- server might end up setting the password for a user instead
+ we need to use the '$' form of the name here (the machine account name),
+ as otherwise the server might end up setting the password for a user
+ instead
*/
- asprintf(&principal, "%s$@%s", host, ads->config.realm);
+ asprintf(&principal, "%s@%s", machine_account, ads->config.realm);
status = ads_krb5_set_password(ads->auth.kdc_server, principal,
password, ads->auth.time_offset);
- free(host);
free(principal);
return status;
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 5a12288b16..e925750e0a 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -1045,7 +1045,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname,
ads_mod_str(ctx, &mods, "dNSHostName", hostname);
ads_mod_str(ctx, &mods, "userAccountControl", controlstr);
ads_mod_str(ctx, &mods, "operatingSystem", "Samba");
- ads_mod_str(ctx, &mods, "operatingSystemVersion", VERSION);
+ ads_mod_str(ctx, &mods, "operatingSystemVersion", SAMBA_VERSION_STRING);
ret = ads_gen_add(ads, new_dn, mods);
@@ -1777,7 +1777,7 @@ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn)
ADS_STATUS status;
void *res;
- status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
+ status = ads_do_search_retry(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
if (!ADS_ERR_OK(status)) return status;
if (ads_count_replies(ads, res) != 1) {
@@ -1900,7 +1900,7 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid)
void *res;
ADS_STATUS rc;
- rc = ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_BASE, "(objectclass=*)",
+ rc = ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_BASE, "(objectclass=*)",
attrs, &res);
if (!ADS_ERR_OK(rc)) return rc;
if (!ads_pull_sid(ads, res, "objectSid", sid)) {
diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c
index 6855600288..1fa9ebfc97 100644
--- a/source3/libads/ldap_utils.c
+++ b/source3/libads/ldap_utils.c
@@ -73,7 +73,10 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope
}
free(bp);
- DEBUG(1,("ads reopen failed after error %s\n", ads_errstr(status)));
+ if (!ADS_ERR_OK(status))
+ DEBUG(1,("ads reopen failed after error %s\n",
+ ads_errstr(status)));
+
return status;
}
diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c
index 910ff3f4dc..5122803597 100644
--- a/source3/libads/sasl.c
+++ b/source3/libads/sasl.c
@@ -60,7 +60,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads)
msg1 = gen_negTokenTarg(mechs, blob);
data_blob_free(&blob);
- cred.bv_val = msg1.data;
+ cred.bv_val = (char *)msg1.data;
cred.bv_len = msg1.length;
rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred);
@@ -106,7 +106,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads)
data_blob_free(&blob);
/* now send the auth packet and we should be done */
- cred.bv_val = auth.data;
+ cred.bv_val = (char *)auth.data;
cred.bv_len = auth.length;
rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred);
@@ -134,7 +134,7 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip
}
/* now send the auth packet and we should be done */
- cred.bv_val = blob.data;
+ cred.bv_val = (char *)blob.data;
cred.bv_len = blob.length;
rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred);
@@ -227,13 +227,13 @@ failed:
*/
static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
{
- int minor_status;
+ uint32 minor_status;
gss_name_t serv_name;
gss_buffer_desc input_name;
gss_ctx_id_t context_handle;
gss_OID mech_type = GSS_C_NULL_OID;
gss_buffer_desc output_token, input_token;
- OM_uint32 ret_flags, conf_state;
+ uint32 ret_flags, conf_state;
struct berval cred;
struct berval *scred;
int i=0;
@@ -328,7 +328,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
gss_release_name(&minor_status, &serv_name);
gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token,
- &conf_state,NULL);
+ (int *)&conf_state,NULL);
if (gss_rc) {
status = ADS_ERROR_GSS(gss_rc, minor_status);
goto failed;
@@ -353,13 +353,13 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
*p++ = max_msg_size>>16;
*p++ = max_msg_size>>8;
*p++ = max_msg_size;
- snprintf(p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path);
- p += strlen(p);
+ snprintf((char *)p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path);
+ p += strlen((const char *)p);
output_token.length = PTR_DIFF(p, output_token.value);
gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT,
- &output_token, &conf_state,
+ &output_token, (int *)&conf_state,
&input_token);
if (gss_rc) {
status = ADS_ERROR_GSS(gss_rc, minor_status);