diff options
Diffstat (limited to 'source3/libads')
-rw-r--r-- | source3/libads/ads_status.c | 2 | ||||
-rw-r--r-- | source3/libads/authdata.c | 7 | ||||
-rw-r--r-- | source3/libads/kerberos_verify.c | 165 | ||||
-rw-r--r-- | source3/libads/krb5_setpw.c | 17 | ||||
-rw-r--r-- | source3/libads/ldap.c | 6 | ||||
-rw-r--r-- | source3/libads/ldap_utils.c | 5 | ||||
-rw-r--r-- | source3/libads/sasl.c | 18 |
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); |