From ad2974cd05b4d08c8b92f505bf95aa8e8533235f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 24 Nov 2001 14:16:41 +0000 Subject: added "net join" command this completes the first stage of the smbd ADS support (This used to be commit 058a5aee901e6609969ef7e1d482a720a84a4a12) --- source3/libads/kerberos.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 source3/libads/kerberos.c (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c new file mode 100644 index 0000000000..e4e946f0ce --- /dev/null +++ b/source3/libads/kerberos.c @@ -0,0 +1,149 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + kerberos utility library + Copyright (C) Andrew Tridgell 2001 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#ifdef HAVE_KRB5 + +/* + verify an incoming ticket and parse out the principal name and + authorization_data if available +*/ +NTSTATUS ads_verify_ticket(const DATA_BLOB *ticket, + char **principal, DATA_BLOB *auth_data) +{ + krb5_context context; + krb5_auth_context auth_context = NULL; + krb5_keytab keytab = NULL; + krb5_data packet; + krb5_ticket *tkt = NULL; + krb5_data salt; + krb5_encrypt_block eblock; + int ret; + krb5_keyblock * key; + krb5_principal host_princ; + char *host_princ_s; + extern pstring global_myname; + fstring myname; + char *password_s; + krb5_data password; + + if (!secrets_init()) { + DEBUG(1,("secrets_init failed\n")); + return NT_STATUS_LOGON_FAILURE; + } + + password_s = secrets_fetch_machine_password(); + if (!password_s) { + DEBUG(1,("failed to fetch machine password\n")); + return NT_STATUS_LOGON_FAILURE; + } + + password.data = password_s; + password.length = strlen(password_s); + + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + ret = krb5_set_default_realm(context, lp_realm()); + if (ret) { + DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + /* this whole process is far more complex than I would + like. We have to go through all this to allow us to store + the secret internally, instead of using /etc/krb5.keytab */ + ret = krb5_auth_con_init(context, &auth_context); + if (ret) { + DEBUG(1,("krb5_auth_con_init failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + fstrcpy(myname, global_myname); + strlower(myname); + asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm()); + ret = krb5_parse_name(context, host_princ_s, &host_princ); + if (ret) { + DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", host_princ_s, error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + ret = krb5_principal2salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { + return NT_STATUS_NO_MEMORY; + } + + krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); + + ret = krb5_string_to_key(context, &eblock, key, &password, &salt); + if (ret) { + DEBUG(1,("krb5_string_to_key failed (%s)\n", error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + krb5_auth_con_setuseruserkey(context, auth_context, key); + + packet.length = ticket->length; + packet.data = (krb5_pointer)ticket->data; + +#if 0 + file_save("/tmp/ticket.dat", ticket->data, ticket->length); +#endif + + if ((ret = krb5_rd_req(context, &auth_context, &packet, + NULL, keytab, NULL, &tkt))) { + DEBUG(3,("krb5_rd_req with auth failed (%s)\n", + error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + if (tkt->enc_part2) { + *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, + tkt->enc_part2->authorization_data[0]->length); + } + +#if 0 + if (tkt->enc_part2) { + file_save("/tmp/authdata.dat", + tkt->enc_part2->authorization_data[0]->contents, + tkt->enc_part2->authorization_data[0]->length); + } +#endif + + if ((ret = krb5_unparse_name(context, tkt->enc_part2->client, principal))) { + DEBUG(3,("krb5_unparse_name failed (%s)\n", + error_message(ret))); + return NT_STATUS_LOGON_FAILURE; + } + + return NT_STATUS_OK; +} + +#endif -- cgit From fe64484824d8169bf66822ebf7f6a9180a238e6e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 29 Nov 2001 06:21:56 +0000 Subject: Make better use of the ads_init() function to get the kerberos relam etc. This allows us to use automagically obtained values in future, and the value from krb5.conf now. Also fix mem leaks etc. Andrew Bartlett (This used to be commit 8f9ce717819235d98a1463f20ac659cb4b4ebbd2) --- source3/libads/kerberos.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index e4e946f0ce..a3aa8b1661 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -27,7 +27,7 @@ verify an incoming ticket and parse out the principal name and authorization_data if available */ -NTSTATUS ads_verify_ticket(const DATA_BLOB *ticket, +NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket, char **principal, DATA_BLOB *auth_data) { krb5_context context; @@ -66,9 +66,10 @@ NTSTATUS ads_verify_ticket(const DATA_BLOB *ticket, return NT_STATUS_LOGON_FAILURE; } - ret = krb5_set_default_realm(context, lp_realm()); + ret = krb5_set_default_realm(context, ads->realm); if (ret) { DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); + ads_destroy(&ads); return NT_STATUS_LOGON_FAILURE; } -- cgit From 9421ad4a7a900b219f87754bc20fa14f2f22fd35 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Dec 2001 09:46:53 +0000 Subject: added a REALLY gross hack into kerberos_kinit_password so that winbindd can do a kinit this will be removed once we have code that gets a tgt and puts it in a place where cyrus-sasl can see it (This used to be commit 7d94f1b7365215a020d3678d03d820a7d086174f) --- source3/libads/kerberos.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index a3aa8b1661..1b0de382bd 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -23,6 +23,27 @@ #ifdef HAVE_KRB5 + +/* VERY nasty hack until we have proper kerberos code for this */ +void kerberos_kinit_password(ADS_STRUCT *ads) +{ + char *s; + FILE *f; + extern pstring global_myname; + fstring myname; + fstrcpy(myname, global_myname); + strlower(myname); + asprintf(&s, "kinit 'HOST/%s@%s'", global_myname, ads->realm); + DEBUG(0,("HACK!! Running %s\n", s)); + f = popen(s, "w"); + if (f) { + fprintf(f,"%s\n", ads->password); + fflush(f); + fclose(f); + } + free(s); +} + /* verify an incoming ticket and parse out the principal name and authorization_data if available -- cgit From d412f66cd82d8b14c8bd8d97f0235296bc8b2d23 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Dec 2001 05:41:53 +0000 Subject: added a propoer kerberos_kinit_password call contribution from remus@snapserver.com thanks! (This used to be commit 3ace8f1fcc27492d26f5ad0c3cdfc63235ca0609) --- source3/libads/kerberos.c | 76 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 11 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 1b0de382bd..c494016f98 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -23,25 +23,79 @@ #ifdef HAVE_KRB5 +/* + simulate a kinit, putting the tgt in the default cache location + remus@snapserver.com +*/ +int kerberos_kinit_password(const char *principal, const char *password) +{ + krb5_context ctx; + krb5_error_code code = 0; + krb5_ccache cc; + krb5_principal me; + krb5_creds my_creds; + + if ((code = krb5_init_context(&ctx))) + return code; + + if ((code = krb5_cc_default(ctx, &cc))) { + krb5_free_context(ctx); + return code; + } + + if ((code = krb5_parse_name(ctx, principal, &me))) { + krb5_free_context(ctx); + return code; + } + + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, password, NULL, + NULL, 0, NULL, NULL))) { + krb5_free_principal(ctx, me); + krb5_free_context(ctx); + return code; + } + + if ((code = krb5_cc_initialize(ctx, cc, me))) { + krb5_free_cred_contents(ctx, &my_creds); + krb5_free_principal(ctx, me); + krb5_free_context(ctx); + return code; + } + + if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) { + krb5_cc_close(ctx, cc); + krb5_free_cred_contents(ctx, &my_creds); + krb5_free_principal(ctx, me); + krb5_free_context(ctx); + return code; + } + + krb5_cc_close(ctx, cc); + krb5_free_cred_contents(ctx, &my_creds); + krb5_free_principal(ctx, me); + krb5_free_context(ctx); + + return 0; +} + -/* VERY nasty hack until we have proper kerberos code for this */ -void kerberos_kinit_password(ADS_STRUCT *ads) + +/* run kinit to setup our ccache */ +int ads_kinit_password(ADS_STRUCT *ads) { char *s; - FILE *f; + int ret; extern pstring global_myname; fstring myname; fstrcpy(myname, global_myname); strlower(myname); - asprintf(&s, "kinit 'HOST/%s@%s'", global_myname, ads->realm); - DEBUG(0,("HACK!! Running %s\n", s)); - f = popen(s, "w"); - if (f) { - fprintf(f,"%s\n", ads->password); - fflush(f); - fclose(f); - } + asprintf(&s, "HOST/%s@%s", global_myname, ads->realm); + ret = kerberos_kinit_password(s, ads->password); free(s); + if (ret) { + DEBUG(1,("kerberos_kinit_password failed: %s\n", error_message(ret))); + } + return ret; } /* -- cgit From 44384354d822e8df2495a68c358201a7833b20bb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Dec 2001 07:33:35 +0000 Subject: put the winbindd krb5 credentials cache in the lock directory this prevents it clobbering the users cache (This used to be commit 3de552f365373de85298dbe911143e036805f9ea) --- source3/libads/kerberos.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index c494016f98..19e8ffdc00 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -87,6 +87,10 @@ int ads_kinit_password(ADS_STRUCT *ads) int ret; extern pstring global_myname; fstring myname; + + /* we don't want this to affect the users ccache */ + setenv("KRB5CCNAME", lock_path("winbindd_ccache"), 1); + fstrcpy(myname, global_myname); strlower(myname); asprintf(&s, "HOST/%s@%s", global_myname, ads->realm); -- cgit From 5d378a280f74405fccbadbfb28e1066613c76fd8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 8 Dec 2001 11:18:56 +0000 Subject: added internal sasl/gssapi code. This means we are no longer dependent on cyrus-sasl which makes the code much less fragile. Also added code to auto-determine the server name or realm (This used to be commit 435fdf276a79c2a517adcd7726933aeef3fa924b) --- source3/libads/kerberos.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 19e8ffdc00..521fe0d5eb 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -85,19 +85,29 @@ int ads_kinit_password(ADS_STRUCT *ads) { char *s; int ret; - extern pstring global_myname; - fstring myname; + char *ccache; + + ccache = lock_path("winbindd_ccache"); /* we don't want this to affect the users ccache */ - setenv("KRB5CCNAME", lock_path("winbindd_ccache"), 1); + setenv("KRB5CCNAME", ccache, 1); - fstrcpy(myname, global_myname); - strlower(myname); - asprintf(&s, "HOST/%s@%s", global_myname, ads->realm); + unlink(ccache); + + if (!ads->user_name) { + /* by default use the machine account */ + extern pstring global_myname; + fstring myname; + fstrcpy(myname, global_myname); + strlower(myname); + asprintf(&ads->user_name, "HOST/%s", global_myname); + } + asprintf(&s, "%s@%s", ads->user_name, ads->realm); ret = kerberos_kinit_password(s, ads->password); free(s); if (ret) { - DEBUG(1,("kerberos_kinit_password failed: %s\n", error_message(ret))); + DEBUG(1,("kerberos_kinit_password %s failed: %s\n", + s, error_message(ret))); } return ret; } -- cgit From bc26ea1e5c712aeef3091c0d3442b7dc430da74c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 9 Dec 2001 00:45:51 +0000 Subject: fixed used of string after free (This used to be commit f7ead035ebe55e94cdd5807b173bd4612866b06f) --- source3/libads/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 521fe0d5eb..64eca2c8c4 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -104,11 +104,11 @@ int ads_kinit_password(ADS_STRUCT *ads) } asprintf(&s, "%s@%s", ads->user_name, ads->realm); ret = kerberos_kinit_password(s, ads->password); - free(s); if (ret) { DEBUG(1,("kerberos_kinit_password %s failed: %s\n", s, error_message(ret))); } + free(s); return ret; } -- cgit From 3d27d7b9f79d530d7652106332a21e3595b7c812 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Dec 2001 22:10:31 +0000 Subject: moved ccache location change into winbindd code (This used to be commit be254eb13c4bf316823ed43db3ef9407f45ca23b) --- source3/libads/kerberos.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 64eca2c8c4..8fcc32b363 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -85,14 +85,6 @@ int ads_kinit_password(ADS_STRUCT *ads) { char *s; int ret; - char *ccache; - - ccache = lock_path("winbindd_ccache"); - - /* we don't want this to affect the users ccache */ - setenv("KRB5CCNAME", ccache, 1); - - unlink(ccache); if (!ads->user_name) { /* by default use the machine account */ -- cgit From 66d964c9fca128d2e77e0cb1b704b25ab55b45ce Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 11 Dec 2001 05:15:52 +0000 Subject: allow overriding the local time in kerberos_kinit_password() (This used to be commit cb9dbcef7cba9eb42f7b30b81c35142dc945d84f) --- source3/libads/kerberos.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 8fcc32b363..5d7b08a348 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -27,7 +27,8 @@ simulate a kinit, putting the tgt in the default cache location remus@snapserver.com */ -int kerberos_kinit_password(const char *principal, const char *password) +int kerberos_kinit_password(const char *principal, const char *password, + time_t real_time) { krb5_context ctx; krb5_error_code code = 0; @@ -38,6 +39,10 @@ int kerberos_kinit_password(const char *principal, const char *password) if ((code = krb5_init_context(&ctx))) return code; + if (real_time) { + krb5_set_real_time(ctx, real_time, 0); + } + if ((code = krb5_cc_default(ctx, &cc))) { krb5_free_context(ctx); return code; @@ -95,7 +100,8 @@ int ads_kinit_password(ADS_STRUCT *ads) asprintf(&ads->user_name, "HOST/%s", global_myname); } asprintf(&s, "%s@%s", ads->user_name, ads->realm); - ret = kerberos_kinit_password(s, ads->password); + ret = kerberos_kinit_password(s, ads->password, 0); + if (ret) { DEBUG(1,("kerberos_kinit_password %s failed: %s\n", s, error_message(ret))); -- cgit From d58b1b5981652e5ef37eb8d07ae3ff7797b112c5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 13 Dec 2001 11:30:13 +0000 Subject: better error handling (This used to be commit ed6279481bfcb21212e9c22009969c19ea4f1646) --- source3/libads/kerberos.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 5d7b08a348..8378442885 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -35,7 +35,12 @@ int kerberos_kinit_password(const char *principal, const char *password, krb5_ccache cc; krb5_principal me; krb5_creds my_creds; - + + if (! *password) { + /* kerberos dies on an empty password! */ + return KRB5_PARSE_MALFORMED; + } + if ((code = krb5_init_context(&ctx))) return code; @@ -103,7 +108,7 @@ int ads_kinit_password(ADS_STRUCT *ads) ret = kerberos_kinit_password(s, ads->password, 0); if (ret) { - DEBUG(1,("kerberos_kinit_password %s failed: %s\n", + DEBUG(0,("kerberos_kinit_password %s failed: %s\n", s, error_message(ret))); } free(s); -- cgit From 6c7e9dfb293f1243d9d8d8a2ac50ef12d738198e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 20 Dec 2001 03:54:52 +0000 Subject: net ads password and net ads chostpass commands from Remus Koos (This used to be commit 412e79c448bf02e3097b5c14a36fe0172d8d2895) --- source3/libads/kerberos.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 8378442885..aba22e023b 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -3,6 +3,8 @@ Version 3.0 kerberos utility library Copyright (C) Andrew Tridgell 2001 + Copyright (C) Remus Koos 2001 + 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 @@ -27,8 +29,7 @@ simulate a kinit, putting the tgt in the default cache location remus@snapserver.com */ -int kerberos_kinit_password(const char *principal, const char *password, - time_t real_time) +int kerberos_kinit_password(const char *principal, const char *password) { krb5_context ctx; krb5_error_code code = 0; @@ -44,10 +45,6 @@ int kerberos_kinit_password(const char *principal, const char *password, if ((code = krb5_init_context(&ctx))) return code; - if (real_time) { - krb5_set_real_time(ctx, real_time, 0); - } - if ((code = krb5_cc_default(ctx, &cc))) { krb5_free_context(ctx); return code; @@ -58,7 +55,7 @@ int kerberos_kinit_password(const char *principal, const char *password, return code; } - if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, password, NULL, + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, (char*)password, NULL, NULL, 0, NULL, NULL))) { krb5_free_principal(ctx, me); krb5_free_context(ctx); @@ -105,7 +102,7 @@ int ads_kinit_password(ADS_STRUCT *ads) asprintf(&ads->user_name, "HOST/%s", global_myname); } asprintf(&s, "%s@%s", ads->user_name, ads->realm); - ret = kerberos_kinit_password(s, ads->password, 0); + ret = kerberos_kinit_password(s, ads->password); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/libads/kerberos.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index aba22e023b..194a71275e 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. kerberos utility library Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/libads/kerberos.c | 155 ++++++++-------------------------------------- 1 file changed, 25 insertions(+), 130 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 194a71275e..1ba5d978e8 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -24,6 +24,28 @@ #ifdef HAVE_KRB5 +/* + we use a prompter to avoid a crash bug in the kerberos libs when + dealing with empty passwords + this prompter is just a string copy ... +*/ +static krb5_error_code +kerb_prompter(krb5_context ctx, void *data, + const char *name, + const char *banner, + int num_prompts, + krb5_prompt prompts[]) +{ + if (num_prompts == 0) return 0; + + memset(prompts[0].reply->data, 0, prompts[0].reply->length); + if (prompts[0].reply->length > 0) { + strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); + prompts[0].reply->length = strlen(prompts[0].reply->data); + } + return 0; +} + /* simulate a kinit, putting the tgt in the default cache location remus@snapserver.com @@ -36,11 +58,6 @@ int kerberos_kinit_password(const char *principal, const char *password) krb5_principal me; krb5_creds my_creds; - if (! *password) { - /* kerberos dies on an empty password! */ - return KRB5_PARSE_MALFORMED; - } - if ((code = krb5_init_context(&ctx))) return code; @@ -54,8 +71,9 @@ int kerberos_kinit_password(const char *principal, const char *password) return code; } - if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, (char*)password, NULL, - NULL, 0, NULL, NULL))) { + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, NULL, + kerb_prompter, + password, 0, NULL, NULL))) { krb5_free_principal(ctx, me); krb5_free_context(ctx); return code; @@ -111,128 +129,5 @@ int ads_kinit_password(ADS_STRUCT *ads) return ret; } -/* - 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, - char **principal, DATA_BLOB *auth_data) -{ - krb5_context context; - krb5_auth_context auth_context = NULL; - krb5_keytab keytab = NULL; - krb5_data packet; - krb5_ticket *tkt = NULL; - krb5_data salt; - krb5_encrypt_block eblock; - int ret; - krb5_keyblock * key; - krb5_principal host_princ; - char *host_princ_s; - extern pstring global_myname; - fstring myname; - char *password_s; - krb5_data password; - - if (!secrets_init()) { - DEBUG(1,("secrets_init failed\n")); - return NT_STATUS_LOGON_FAILURE; - } - - password_s = secrets_fetch_machine_password(); - if (!password_s) { - DEBUG(1,("failed to fetch machine password\n")); - return NT_STATUS_LOGON_FAILURE; - } - - password.data = password_s; - password.length = strlen(password_s); - - ret = krb5_init_context(&context); - if (ret) { - DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - ret = krb5_set_default_realm(context, ads->realm); - if (ret) { - DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret))); - ads_destroy(&ads); - return NT_STATUS_LOGON_FAILURE; - } - - /* this whole process is far more complex than I would - like. We have to go through all this to allow us to store - the secret internally, instead of using /etc/krb5.keytab */ - ret = krb5_auth_con_init(context, &auth_context); - if (ret) { - DEBUG(1,("krb5_auth_con_init failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - fstrcpy(myname, global_myname); - strlower(myname); - asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm()); - ret = krb5_parse_name(context, host_princ_s, &host_princ); - if (ret) { - DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", host_princ_s, error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - ret = krb5_principal2salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) { - return NT_STATUS_NO_MEMORY; - } - - krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); - - ret = krb5_string_to_key(context, &eblock, key, &password, &salt); - if (ret) { - DEBUG(1,("krb5_string_to_key failed (%s)\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - krb5_auth_con_setuseruserkey(context, auth_context, key); - - packet.length = ticket->length; - packet.data = (krb5_pointer)ticket->data; - -#if 0 - file_save("/tmp/ticket.dat", ticket->data, ticket->length); -#endif - - if ((ret = krb5_rd_req(context, &auth_context, &packet, - NULL, keytab, NULL, &tkt))) { - DEBUG(3,("krb5_rd_req with auth failed (%s)\n", - error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - if (tkt->enc_part2) { - *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, - tkt->enc_part2->authorization_data[0]->length); - } - -#if 0 - if (tkt->enc_part2) { - file_save("/tmp/authdata.dat", - tkt->enc_part2->authorization_data[0]->contents, - tkt->enc_part2->authorization_data[0]->length); - } -#endif - - if ((ret = krb5_unparse_name(context, tkt->enc_part2->client, principal))) { - DEBUG(3,("krb5_unparse_name failed (%s)\n", - error_message(ret))); - return NT_STATUS_LOGON_FAILURE; - } - - return NT_STATUS_OK; -} #endif -- cgit From b2edf254eda92f775e7d3d9b6793b4d77f9000b6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 17 Aug 2002 17:00:51 +0000 Subject: sync 3.0 branch with head (This used to be commit 3928578b52cfc949be5e0ef444fce1558d75f290) --- source3/libads/kerberos.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 1ba5d978e8..9a486237c9 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -110,16 +110,8 @@ int ads_kinit_password(ADS_STRUCT *ads) char *s; int ret; - if (!ads->user_name) { - /* by default use the machine account */ - extern pstring global_myname; - fstring myname; - fstrcpy(myname, global_myname); - strlower(myname); - asprintf(&ads->user_name, "HOST/%s", global_myname); - } - asprintf(&s, "%s@%s", ads->user_name, ads->realm); - ret = kerberos_kinit_password(s, ads->password); + asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm); + ret = kerberos_kinit_password(s, ads->auth.password); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", -- cgit From a834a73e341059be154426390304a42e4a011f72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/libads/kerberos.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 9a486237c9..a80837cf4d 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -50,7 +50,7 @@ kerb_prompter(krb5_context ctx, void *data, simulate a kinit, putting the tgt in the default cache location remus@snapserver.com */ -int kerberos_kinit_password(const char *principal, const char *password) +int kerberos_kinit_password(const char *principal, const char *password, int time_offset) { krb5_context ctx; krb5_error_code code = 0; @@ -60,6 +60,10 @@ int kerberos_kinit_password(const char *principal, const char *password) if ((code = krb5_init_context(&ctx))) return code; + + if (time_offset != 0) { + krb5_set_real_time(ctx, time(NULL) + time_offset, 0); + } if ((code = krb5_cc_default(ctx, &cc))) { krb5_free_context(ctx); @@ -111,7 +115,7 @@ int ads_kinit_password(ADS_STRUCT *ads) int ret; asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm); - ret = kerberos_kinit_password(s, ads->auth.password); + ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", -- cgit From ad8a22e570c8970247dc76defc9be2b768bd102d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 1 Oct 2002 13:10:57 +0000 Subject: Updates from Samba HEAD: - Fix segfaults in the 'net ads' commands when no password is provided - Readd --with-ldapsam for 2.2 compatability. This conditionally compiles the old options, but the actual code is available on all ldap systems. - Fix shadow passwords (as per work with vl) - Fix sending plaintext passwords to unicode servers (again vl) - Add a bit of const to secrets.c functions - Fix some spelling and grammer by vance. - Document the -r option in smbgroupedit. There are more changes in HEAD, I'm only merging the changes I've been involved with. Andrew Bartlett (This used to be commit 83973c389355a5cc9ca74af467dfd8b5dabd2c8f) --- source3/libads/kerberos.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index a80837cf4d..b586d84226 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -114,7 +114,14 @@ int ads_kinit_password(ADS_STRUCT *ads) char *s; int ret; - asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm); + if (asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm) == -1) { + return KRB5_CC_NOMEM; + } + + if (!ads->auth.password) { + return KRB5_LIBOS_CANTREADPWD; + } + ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset); if (ret) { -- cgit From 515e6a268e97a5d512535fd95138fa64ab46280e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Oct 2002 01:05:30 +0000 Subject: Merge tridge's blank password fix from HEAD. Jeremy. (This used to be commit eadfd312ba92a780f655cf117c44b30457f007e8) --- source3/libads/kerberos.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index b586d84226..bef2febaef 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -40,8 +40,12 @@ kerb_prompter(krb5_context ctx, void *data, memset(prompts[0].reply->data, 0, prompts[0].reply->length); if (prompts[0].reply->length > 0) { - strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); - prompts[0].reply->length = strlen(prompts[0].reply->data); + if (data) { + strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); + prompts[0].reply->length = strlen(prompts[0].reply->data); + } else { + prompts[0].reply->length = 0; + } } return 0; } -- cgit From 9a8e30d04b1cfc53e8c8949a56d4f1cf5aa26501 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 24 Mar 2004 17:32:55 +0000 Subject: Fix bugzilla # 1208 Winbind tickets expired. We now check the expiration time, and acquire new tickets. We couln't rely on renewing them, because if we didn't get a request before they expired, we wouldn't have renewed them. Also, there is a one-week limit in MS on renewal life, so new tickets would have been needed after a week anyway. Default is 10 hours, so we should only be acquiring them that often, unless the configuration on the DC is changed (and the minimum is 1 hour). (This used to be commit c2436c433afaab4006554a86307f76b6689d6929) --- source3/libads/kerberos.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index bef2febaef..70f6f3386c 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -54,7 +54,7 @@ kerb_prompter(krb5_context ctx, void *data, simulate a kinit, putting the tgt in the default cache location remus@snapserver.com */ -int kerberos_kinit_password(const char *principal, const char *password, int time_offset) +int kerberos_kinit_password(const char *principal, const char *password, int time_offset, time_t *expire_time) { krb5_context ctx; krb5_error_code code = 0; @@ -102,6 +102,9 @@ int kerberos_kinit_password(const char *principal, const char *password, int tim return code; } + if (expire_time) + *expire_time = (time_t) my_creds.times.endtime; + krb5_cc_close(ctx, cc); krb5_free_cred_contents(ctx, &my_creds); krb5_free_principal(ctx, me); @@ -126,7 +129,7 @@ int ads_kinit_password(ADS_STRUCT *ads) return KRB5_LIBOS_CANTREADPWD; } - ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset); + ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset, &ads->auth.expire); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", @@ -136,5 +139,37 @@ int ads_kinit_password(ADS_STRUCT *ads) return ret; } +int ads_kdestroy(const char *cc_name) +{ + krb5_error_code code; + krb5_context ctx; + krb5_ccache cc; + + if ((code = krb5_init_context (&ctx))) { + DEBUG(3, ("ads_kdestroy: kdb5_init_context rc=%d\n", code)); + return code; + } + + if (!cc_name) { + if ((code = krb5_cc_default(ctx, &cc))) { + krb5_free_context(ctx); + return code; + } + } else { + if ((code = krb5_cc_resolve(ctx, cc_name, &cc))) { + DEBUG(3, ("ads_kdestroy: krb5_cc_resolve rc=%d\n", + code)); + krb5_free_context(ctx); + return code; + } + } + + if ((code = krb5_cc_destroy (ctx, cc))) { + DEBUG(3, ("ads_kdestroy: krb5_cc_destroy rc=%d\n", code)); + } + + krb5_free_context (ctx); + return code; +} #endif -- cgit From 63378d6f0efa4612da1aecb5dee14992ac069d0f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 7 May 2004 02:48:03 +0000 Subject: r541: fixing segfault in winbindd caused -r527 -- looks like a bug in heimdal; also initialize some pointers (This used to be commit be74e88d9a4b74fcaf25b0816e3fa8a487c91ab5) --- source3/libads/kerberos.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 70f6f3386c..e8bf4b0846 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -56,9 +56,9 @@ kerb_prompter(krb5_context ctx, void *data, */ int kerberos_kinit_password(const char *principal, const char *password, int time_offset, time_t *expire_time) { - krb5_context ctx; + krb5_context ctx = NULL; krb5_error_code code = 0; - krb5_ccache cc; + krb5_ccache cc = NULL; krb5_principal me; krb5_creds my_creds; @@ -142,8 +142,8 @@ int ads_kinit_password(ADS_STRUCT *ads) int ads_kdestroy(const char *cc_name) { krb5_error_code code; - krb5_context ctx; - krb5_ccache cc; + krb5_context ctx = NULL; + krb5_ccache cc = NULL; if ((code = krb5_init_context (&ctx))) { DEBUG(3, ("ads_kdestroy: kdb5_init_context rc=%d\n", code)); -- cgit From 41416f3876da5a43077ff991817e73c44dd6ae70 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jun 2004 20:37:54 +0000 Subject: r1245: I think the parameter for "password" and "data" was reversed. CHECK THIS ! Jeremy. (This used to be commit d4abeefe3e307ff226fba481ca2c743cde153e4b) --- source3/libads/kerberos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index e8bf4b0846..97b895a241 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -79,9 +79,9 @@ int kerberos_kinit_password(const char *principal, const char *password, int tim return code; } - if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, NULL, + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, password, kerb_prompter, - password, 0, NULL, NULL))) { + NULL, 0, NULL, NULL))) { krb5_free_principal(ctx, me); krb5_free_context(ctx); return code; -- cgit From f1fd211e80732f66ca94604d8132d9f31dc5b717 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Aug 2004 20:18:28 +0000 Subject: r1967: Fix a couple of krb5-DEBUG-messages. Guenther (This used to be commit 86a61c86a49a7e4d67e61201458c9b0229fb0825) --- source3/libads/kerberos.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 97b895a241..327a76826e 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -146,7 +146,8 @@ int ads_kdestroy(const char *cc_name) krb5_ccache cc = NULL; if ((code = krb5_init_context (&ctx))) { - DEBUG(3, ("ads_kdestroy: kdb5_init_context rc=%d\n", code)); + DEBUG(3, ("ads_kdestroy: kdb5_init_context failed: %s\n", + error_message(code))); return code; } @@ -157,15 +158,16 @@ int ads_kdestroy(const char *cc_name) } } else { if ((code = krb5_cc_resolve(ctx, cc_name, &cc))) { - DEBUG(3, ("ads_kdestroy: krb5_cc_resolve rc=%d\n", - code)); + DEBUG(3, ("ads_kdestroy: krb5_cc_resolve failed: %s\n", + error_message(code))); krb5_free_context(ctx); return code; } } if ((code = krb5_cc_destroy (ctx, cc))) { - DEBUG(3, ("ads_kdestroy: krb5_cc_destroy rc=%d\n", code)); + DEBUG(3, ("ads_kdestroy: krb5_cc_destroy failed: %s\n", + error_message(code))); } krb5_free_context (ctx); -- cgit From 0772ddbae1be394c538f1d3529ea84434eadcf97 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 29 Oct 2004 22:38:10 +0000 Subject: r3377: Merge in first part of modified patch from Nalin Dahyabhai for bug #1717.The rest of the code needed to call this patch has not yet been checked in (that's my next task). This has not yet been tested - I'll do this once the rest of the patch is integrated. Jeremy. (This used to be commit 7565019286cf44f43c8066c005b1cd5c1556435f) --- source3/libads/kerberos.c | 555 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 548 insertions(+), 7 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 327a76826e..9eb4d9da46 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -3,8 +3,9 @@ kerberos utility library Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 - - + Copyright (C) Nalin Dahyabhai 2004. + Copyright (C) Jeremy Allison 2004. + 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 the Free Software Foundation; either version 2 of the License, or @@ -24,6 +25,8 @@ #ifdef HAVE_KRB5 +#define LIBADS_CCACHE_NAME "MEMORY:libads" + /* we use a prompter to avoid a crash bug in the kerberos libs when dealing with empty passwords @@ -38,7 +41,7 @@ kerb_prompter(krb5_context ctx, void *data, { if (num_prompts == 0) return 0; - memset(prompts[0].reply->data, 0, prompts[0].reply->length); + memset(prompts[0].reply->data, '\0', prompts[0].reply->length); if (prompts[0].reply->length > 0) { if (data) { strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); @@ -51,10 +54,15 @@ kerb_prompter(krb5_context ctx, void *data, } /* - simulate a kinit, putting the tgt in the default cache location + simulate a kinit, putting the tgt in the given cache location. If cache_name == NULL + place in default cache location. remus@snapserver.com */ -int kerberos_kinit_password(const char *principal, const char *password, int time_offset, time_t *expire_time) +int kerberos_kinit_password(const char *principal, + const char *password, + int time_offset, + time_t *expire_time, + const char *cache_name) { krb5_context ctx = NULL; krb5_error_code code = 0; @@ -69,7 +77,8 @@ int kerberos_kinit_password(const char *principal, const char *password, int tim krb5_set_real_time(ctx, time(NULL) + time_offset, 0); } - if ((code = krb5_cc_default(ctx, &cc))) { + if ((code = krb5_cc_resolve(ctx, cache_name ? + cache_name : krb5_cc_default_name(ctx), &cc))) { krb5_free_context(ctx); return code; } @@ -129,7 +138,8 @@ int ads_kinit_password(ADS_STRUCT *ads) return KRB5_LIBOS_CANTREADPWD; } - ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset, &ads->auth.expire); + ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset, + &ads->auth.expire, NULL); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", @@ -174,4 +184,535 @@ int ads_kdestroy(const char *cc_name) return code; } +/************************************************************************ + Routine to fetch the salting principal for a service. Active + Directory may use a non-obvious principal name to generate the salt + when it determines the key to use for encrypting tickets for a service, + and hopefully we detected that when we joined the domain. + ************************************************************************/ + +static char *kerberos_secrets_fetch_salting_principal(const char *service, int enctype) +{ + char *key = NULL; + char *ret = NULL; + + asprintf(&key, "%s/%s/enctype=%d", SECRETS_SALTING_PRINCIPAL, service, enctype); + if (!key) { + return NULL; + } + ret = (char *)secrets_fetch(key, NULL); + SAFE_FREE(key); + return ret; +} + +/************************************************************************ + Routine to get the salting principal for this service. Active + Directory may use a non-obvious principal name to generate the salt + when it determines the key to use for encrypting tickets for a service, + and hopefully we detected that when we joined the domain. + Caller must free if return is not null. + ************************************************************************/ + +krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, + krb5_principal host_princ, + int enctype) +{ + char *unparsed_name = NULL, *salt_princ_s = NULL; + krb5_principal ret_princ = NULL; + + if (krb5_unparse_name(context, host_princ, &unparsed_name) != 0) { + return (krb5_principal)NULL; + } + + if ((salt_princ_s = kerberos_secrets_fetch_salting_principal(unparsed_name, enctype)) == NULL) { + krb5_free_unparsed_name(context, unparsed_name); + return (krb5_principal)NULL; + } + + if (krb5_parse_name(context, salt_princ_s, &ret_princ) != 0) { + krb5_free_unparsed_name(context, unparsed_name); + SAFE_FREE(salt_princ_s); + return (krb5_principal)NULL; + } + krb5_free_unparsed_name(context, unparsed_name); + SAFE_FREE(salt_princ_s); + return ret_princ; +} + +/************************************************************************ + Routine to set the salting principal for this service. Active + Directory may use a non-obvious principal name to generate the salt + when it determines the key to use for encrypting tickets for a service, + and hopefully we detected that when we joined the domain. + Setting principal to NULL deletes this entry. + ************************************************************************/ + +BOOL kerberos_secrets_store_salting_principal(const char *service, + int enctype, + const char *principal) +{ + char *key = NULL; + BOOL ret = False; + krb5_context context = NULL; + krb5_principal princ = NULL; + char *princ_s = NULL; + char *unparsed_name = NULL; + + krb5_init_context(&context); + if (!context) { + return False; + } + if (strchr_m(service, '@')) { + asprintf(&princ_s, "%s", service); + } else { + asprintf(&princ_s, "%s@%s", service, lp_realm()); + } + + if (krb5_parse_name(context, princ_s, &princ) != 0) { + goto out; + + } + if (krb5_unparse_name(context, princ, &unparsed_name) != 0) { + goto out; + } + + asprintf(&key, "%s/%s/enctype=%d", SECRETS_SALTING_PRINCIPAL, unparsed_name, enctype); + if (!key) { + goto out; + } + + if ((principal != NULL) && (strlen(principal) > 0)) { + ret = secrets_store(key, principal, strlen(principal) + 1); + } else { + ret = secrets_delete(key); + } + + out: + + SAFE_FREE(key); + SAFE_FREE(princ_s); + + if (unparsed_name) { + krb5_free_unparsed_name(context, unparsed_name); + } + if (context) { + krb5_free_context(context); + } + + return ret; +} + +/************************************************************************ + Routine to get initial credentials as a service ticket for the local machine. + Returns a buffer initialized with krb5_mk_req_extended. + ************************************************************************/ + +static krb5_error_code get_service_ticket(krb5_context ctx, + krb5_ccache ccache, + const char *service_principal, + int enctype, + krb5_data *p_outbuf) +{ + krb5_creds creds, *new_creds = NULL; + char *service_s = NULL; + char *machine_account = NULL, *password = NULL; + krb5_data in_data; + krb5_auth_context auth_context = NULL; + krb5_error_code err = 0; + + asprintf(&machine_account, "%s$@%s", global_myname(), lp_realm()); + if (machine_account == NULL) { + goto out; + } + password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); + if (password == NULL) { + goto out; + } + if ((err = kerberos_kinit_password(machine_account, password, 0, NULL, LIBADS_CCACHE_NAME)) != 0) { + DEBUG(0,("get_service_ticket: kerberos_kinit_password %s@%s failed: %s\n", + machine_account, + lp_realm(), + error_message(err))); + goto out; + } + + /* Ok - the above call has gotten a TGT. Now we need to get a service + ticket to ourselves. */ + + /* Set up the enctype and client and server principal fields for krb5_get_credentials. */ + memset(&creds, '\0', sizeof(creds)); + kerberos_set_creds_enctype(&creds, enctype); + + if ((err = krb5_cc_get_principal(ctx, ccache, &creds.client))) { + DEBUG(3, ("get_service_ticket: krb5_cc_get_principal failed: %s\n", + error_message(err))); + goto out; + } + + if (strchr_m(service_principal, '@')) { + asprintf(&service_s, "%s", service_principal); + } else { + asprintf(&service_s, "%s@%s", service_principal, lp_realm()); + } + + if ((err = krb5_parse_name(ctx, service_s, &creds.server))) { + DEBUG(0,("get_service_ticket: krb5_parse_name %s failed: %s\n", + service_s, error_message(err))); + goto out; + } + + if ((err = krb5_get_credentials(ctx, 0, ccache, &creds, &new_creds))) { + DEBUG(5,("get_service_ticket: krb5_get_credentials for %s failed: %s\n", + service_s, error_message(err))); + goto out; + } + + memset(&in_data, '\0', sizeof(in_data)); + if ((err = krb5_mk_req_extended(ctx, &auth_context, 0, &in_data, + new_creds, p_outbuf)) != 0) { + DEBUG(0,("get_service_ticket: krb5_mk_req_extended failed: %s\n", + error_message(err))); + goto out; + } + + out: + + if (auth_context) { + krb5_auth_con_free(ctx, auth_context); + } + if (new_creds) { + krb5_free_creds(ctx, new_creds); + } + if (creds.server) { + krb5_free_principal(ctx, creds.server); + } + if (creds.client) { + krb5_free_principal(ctx, creds.client); + } + + SAFE_FREE(service_s); + SAFE_FREE(password); + SAFE_FREE(machine_account); + return err; +} + +/************************************************************************ + Check if the machine password can be used in conjunction with the salting_principal + to generate a key which will successfully decrypt the AP_REQ already + gotten as a message to the local machine. + ************************************************************************/ + +static BOOL verify_service_password(krb5_context ctx, + int enctype, + const char *salting_principal, + krb5_data *in_data) +{ + BOOL ret = False; + krb5_principal salting_kprinc = NULL; + krb5_ticket *ticket = NULL; + krb5_keyblock key; + krb5_data passdata; + char *salting_s = NULL; + char *machine_account = NULL, *password = NULL; + krb5_auth_context auth_context = NULL; + krb5_error_code err; + + memset(&passdata, '\0', sizeof(passdata)); + memset(&key, '\0', sizeof(key)); + + asprintf(&machine_account, "%s$@%s", global_myname(), lp_realm()); + if (machine_account == NULL) { + goto out; + } + password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); + if (password == NULL) { + goto out; + } + + if (strchr_m(salting_principal, '@')) { + asprintf(&salting_s, "%s", salting_principal); + } else { + asprintf(&salting_s, "%s@%s", salting_principal, lp_realm()); + } + + if ((err = krb5_parse_name(ctx, salting_s, &salting_kprinc))) { + DEBUG(0,("verify_service_password: krb5_parse_name %s failed: %s\n", + salting_s, error_message(err))); + goto out; + } + + passdata.length = strlen(password); + passdata.data = (char*)password; + if ((err = create_kerberos_key_from_string_direct(ctx, salting_kprinc, &passdata, &key, enctype))) { + DEBUG(0,("verify_service_password: create_kerberos_key_from_string %d failed: %s\n", + enctype, error_message(err))); + goto out; + } + + if ((err = krb5_auth_con_init(ctx, &auth_context)) != 0) { + DEBUG(0,("verify_service_password: krb5_auth_con_init failed %s\n", error_message(err))); + goto out; + } + + if ((err = krb5_auth_con_setuseruserkey(ctx, auth_context, &key)) != 0) { + DEBUG(0,("verify_service_password: krb5_auth_con_setuseruserkey failed %s\n", error_message(err))); + goto out; + } + + if (!(err = krb5_rd_req(ctx, &auth_context, in_data, NULL, NULL, NULL, &ticket))) { + DEBUG(10,("verify_service_password: decrypted message with enctype %u salt %s!\n", + (unsigned int)enctype, salting_s)); + ret = True; + } + + out: + + memset(&passdata, 0, sizeof(passdata)); + krb5_free_keyblock_contents(ctx, &key); + if (ticket != NULL) { + krb5_free_ticket(ctx, ticket); + } + if (salting_kprinc) { + krb5_free_principal(ctx, salting_kprinc); + } + SAFE_FREE(salting_s); + SAFE_FREE(password); + SAFE_FREE(machine_account); + return ret; +} + +/************************************************************************ + * + * From the current draft of kerberos-clarifications: + * + * It is not possible to reliably generate a user's key given a pass + * phrase without contacting the KDC, since it will not be known + * whether alternate salt or parameter values are required. + * + * And because our server has a password, we have this exact problem. We + * make multiple guesses as to which principal name provides the salt which + * the KDC is using. + * + ************************************************************************/ + +static void kerberos_derive_salting_principal_for_enctype(const char *service_principal, + krb5_context ctx, + krb5_ccache ccache, + krb5_enctype enctype, + krb5_enctype *enctypes) +{ + char *salting_principals[3] = {NULL, NULL, NULL}, *second_principal = NULL; + krb5_error_code err = 0; + krb5_data outbuf; + int i, j; + + memset(&outbuf, '\0', sizeof(outbuf)); + + /* Check that the service_principal is useful. */ + if ((service_principal == NULL) || (strlen(service_principal) == 0)) { + return; + } + + /* Generate our first guess -- the principal as-given. */ + asprintf(&salting_principals[0], "%s", service_principal); + if ((salting_principals[0] == NULL) || (strlen(salting_principals[0]) == 0)) { + return; + } + + /* Generate our second guess -- the computer's principal, as Win2k3. */ + asprintf(&second_principal, "host/%s.%s", global_myname(), lp_realm()); + if (second_principal != NULL) { + strlower_m(second_principal); + asprintf(&salting_principals[1], "%s@%s", second_principal, lp_realm()); + SAFE_FREE(second_principal); + } + if ((salting_principals[1] == NULL) || (strlen(salting_principals[1]) == 0)) { + goto out; + } + + /* Generate our third guess -- the computer's principal, as Win2k. */ + asprintf(&second_principal, "HOST/%s", global_myname()); + if (second_principal != NULL) { + strlower_m(second_principal + 5); + asprintf(&salting_principals[2], "%s@%s", + second_principal, lp_realm()); + SAFE_FREE(second_principal); + } + if ((salting_principals[2] == NULL) || (strlen(salting_principals[2]) == 0)) { + goto out; + } + + /* Get a service ticket for ourselves into our memory ccache. */ + /* This will commonly fail if there is no principal by that name (and we're trying + many names). So don't print a debug 0 error. */ + + if ((err = get_service_ticket(ctx, ccache, service_principal, enctype, &outbuf)) != 0) { + DEBUG(3, ("verify_service_password: get_service_ticket failed: %s\n", + error_message(err))); + goto out; + } + + /* At this point we have a message to ourselves, salted only the KDC knows how. We + have to work out what that salting is. */ + + /* Try and find the correct salting principal. */ + for (i = 0; i < sizeof(salting_principals) / sizeof(salting_principals[i]); i++) { + if (verify_service_password(ctx, enctype, salting_principals[i], &outbuf)) { + break; + } + } + + /* If we failed to get a match, return. */ + if (i >= sizeof(salting_principals) / sizeof(salting_principals[i])) { + goto out; + } + + /* If we succeeded, store the principal for use for all enctypes which + * share the same cipher and string-to-key function. Doing this here + * allows servers which just pass a keytab to krb5_rd_req() to work + * correctly. */ + for (j = 0; enctypes[j] != 0; j++) { + if (enctype != enctypes[j]) { + /* If this enctype isn't compatible with the one which + * we used, skip it. */ + + if (!kerberos_compatible_enctypes(ctx, enctypes[j], enctype)) + continue; + } + /* If the principal which gives us the proper salt is the one + * which we would normally guess, don't bother noting anything + * in the secrets tdb. */ + if (strcmp(service_principal, salting_principals[i]) != 0) { + kerberos_secrets_store_salting_principal(service_principal, + enctypes[j], + salting_principals[i]); + } + } + + out : + + kerberos_free_data_contents(ctx, &outbuf); + SAFE_FREE(salting_principals[0]); + SAFE_FREE(salting_principals[1]); + SAFE_FREE(salting_principals[2]); + SAFE_FREE(second_principal); +} + +/************************************************************************ + Go through all the possible enctypes for this principal. + ************************************************************************/ + +void kerberos_derive_salting_principal(krb5_context context, + krb5_ccache ccache, + krb5_enctype *enctypes, + char *service_principal) +{ + int i; + + /* Try for each enctype separately, because the rules are + * different for different enctypes. */ + for (i = 0; enctypes[i] != 0; i++) { + /* Delete secrets entry first. */ + kerberos_secrets_store_salting_principal(service_principal, 0, NULL); +#ifdef ENCTYPE_ARCFOUR_HMAC + if (enctypes[i] == ENCTYPE_ARCFOUR_HMAC) { + /* Of course this'll always work, so just save + * ourselves the effort. */ + continue; + } +#endif + /* Try to figure out what's going on with this + * principal. */ + kerberos_derive_salting_principal_for_enctype(service_principal, + context, + ccache, + enctypes[i], + enctypes); + } +} + +/************************************************************************ + Core function to try and determine what salt is being used for any keytab + keys. + ************************************************************************/ + +BOOL kerberos_derive_cifs_salting_principals(void) +{ + fstring my_fqdn; + char *service = NULL; + krb5_context context = NULL; + krb5_enctype *enctypes = NULL; + krb5_ccache ccache = NULL; + krb5_error_code ret = 0; + BOOL retval = False; + + initialize_krb5_error_table(); + if ((ret = krb5_init_context(&context)) != 0) { + DEBUG(1,("kerberos_derive_cifs_salting_principals: krb5_init_context failed. %s\n", + error_message(ret))); + return False; + } + if ((ret = get_kerberos_allowed_etypes(context, &enctypes)) != 0) { + DEBUG(1,("kerberos_derive_cifs_salting_principals: get_kerberos_allowed_etypes failed. %s\n", + error_message(ret))); + goto out; + } + + if ((ret = krb5_cc_resolve(context, LIBADS_CCACHE_NAME, &ccache)) != 0) { + DEBUG(3, ("get_service_ticket: krb5_cc_resolve for %s failed: %s\n", + LIBADS_CCACHE_NAME, error_message(ret))); + goto out; + } + + if (asprintf(&service, "%s$", global_myname()) != -1) { + strlower_m(service); + kerberos_derive_salting_principal(context, ccache, enctypes, service); + SAFE_FREE(service); + } + if (asprintf(&service, "cifs/%s", global_myname()) != -1) { + strlower_m(service); + kerberos_derive_salting_principal(context, ccache, enctypes, service); + SAFE_FREE(service); + } + if (asprintf(&service, "host/%s", global_myname()) != -1) { + strlower_m(service); + kerberos_derive_salting_principal(context, ccache, enctypes, service); + SAFE_FREE(service); + } + if (asprintf(&service, "cifs/%s.%s", global_myname(), lp_realm()) != -1) { + strlower_m(service); + kerberos_derive_salting_principal(context, ccache, enctypes, service); + SAFE_FREE(service); + } + if (asprintf(&service, "host/%s.%s", global_myname(), lp_realm()) != -1) { + strlower_m(service); + kerberos_derive_salting_principal(context, ccache, enctypes, service); + SAFE_FREE(service); + } + name_to_fqdn(my_fqdn, global_myname()); + if (asprintf(&service, "cifs/%s", my_fqdn) != -1) { + strlower_m(service); + kerberos_derive_salting_principal(context, ccache, enctypes, service); + SAFE_FREE(service); + } + if (asprintf(&service, "host/%s", my_fqdn) != -1) { + strlower_m(service); + kerberos_derive_salting_principal(context, ccache, enctypes, service); + SAFE_FREE(service); + } + + retval = True; + + out: + if (enctypes) { + free_kerberos_etypes(context, enctypes); + } + if (ccache) { + krb5_cc_destroy(context, ccache); + } + if (context) { + krb5_free_context(context); + } + return retval; +} #endif -- cgit From cf47845b1c2e83d49f32bdfc455cd9114a234df8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 30 Oct 2004 00:34:58 +0000 Subject: r3379: More merging of kerberos keytab and salting fixes from Nalin Dahyabhai (bugid #1717). Jeremy. (This used to be commit 30b8807cf6d5c3c5b9947a7e841d69f0b22eb019) --- source3/libads/kerberos.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 9eb4d9da46..dc1edb3cde 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -608,6 +608,17 @@ void kerberos_derive_salting_principal(krb5_context context, char *service_principal) { int i; + BOOL free_ccache = False; + + if (ccache == NULL) { + krb5_error_code ret; + if ((ret = krb5_cc_resolve(context, LIBADS_CCACHE_NAME, &ccache)) != 0) { + DEBUG(0, ("kerberos_derive_salting_principal: krb5_cc_resolve for %s failed: %s\n", + LIBADS_CCACHE_NAME, error_message(ret))); + return; + } + free_ccache = True; + } /* Try for each enctype separately, because the rules are * different for different enctypes. */ @@ -629,6 +640,10 @@ void kerberos_derive_salting_principal(krb5_context context, enctypes[i], enctypes); } + + if (free_ccache && ccache) { + krb5_cc_close(context, ccache); + } } /************************************************************************ -- cgit From 3688bb079e8d817dcfc3b9e5eb9d07e7b95a806f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 1 Nov 2004 19:35:55 +0000 Subject: r3439: Finally fix build for platforms without kerberos. Guenther (This used to be commit 05619cfdbf814e5c79e65934b82424eca00c76c4) --- source3/libads/kerberos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index dc1edb3cde..6004bc8098 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -247,7 +247,7 @@ krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, Setting principal to NULL deletes this entry. ************************************************************************/ -BOOL kerberos_secrets_store_salting_principal(const char *service, + BOOL kerberos_secrets_store_salting_principal(const char *service, int enctype, const char *principal) { @@ -602,7 +602,7 @@ static void kerberos_derive_salting_principal_for_enctype(const char *service_pr Go through all the possible enctypes for this principal. ************************************************************************/ -void kerberos_derive_salting_principal(krb5_context context, + void kerberos_derive_salting_principal(krb5_context context, krb5_ccache ccache, krb5_enctype *enctypes, char *service_principal) -- cgit From 917a53cc5875a7ea0384b906dd262b619eb2178e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 2 Nov 2004 21:28:14 +0000 Subject: r3492: Fixes from testing kerberos salted principal fix. Jeremy. (This used to be commit b356a8fdc5a1ac45f2f7f56a0836e794bdecddc6) --- source3/libads/kerberos.c | 74 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 23 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 6004bc8098..32f5951c9f 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -362,8 +362,8 @@ static krb5_error_code get_service_ticket(krb5_context ctx, } if ((err = krb5_get_credentials(ctx, 0, ccache, &creds, &new_creds))) { - DEBUG(5,("get_service_ticket: krb5_get_credentials for %s failed: %s\n", - service_s, error_message(err))); + DEBUG(5,("get_service_ticket: krb5_get_credentials for %s enctype %d failed: %s\n", + service_s, enctype, error_message(err))); goto out; } @@ -602,23 +602,12 @@ static void kerberos_derive_salting_principal_for_enctype(const char *service_pr Go through all the possible enctypes for this principal. ************************************************************************/ - void kerberos_derive_salting_principal(krb5_context context, +static void kerberos_derive_salting_principal_direct(krb5_context context, krb5_ccache ccache, krb5_enctype *enctypes, char *service_principal) { int i; - BOOL free_ccache = False; - - if (ccache == NULL) { - krb5_error_code ret; - if ((ret = krb5_cc_resolve(context, LIBADS_CCACHE_NAME, &ccache)) != 0) { - DEBUG(0, ("kerberos_derive_salting_principal: krb5_cc_resolve for %s failed: %s\n", - LIBADS_CCACHE_NAME, error_message(ret))); - return; - } - free_ccache = True; - } /* Try for each enctype separately, because the rules are * different for different enctypes. */ @@ -640,9 +629,48 @@ static void kerberos_derive_salting_principal_for_enctype(const char *service_pr enctypes[i], enctypes); } +} - if (free_ccache && ccache) { - krb5_cc_close(context, ccache); +/************************************************************************ + Wrapper function for the above. + ************************************************************************/ + +void kerberos_derive_salting_principal(char *service_principal) +{ + krb5_context context = NULL; + krb5_enctype *enctypes = NULL; + krb5_ccache ccache = NULL; + krb5_error_code ret = 0; + + initialize_krb5_error_table(); + if ((ret = krb5_init_context(&context)) != 0) { + DEBUG(1,("kerberos_derive_cifs_salting_principals: krb5_init_context failed. %s\n", + error_message(ret))); + return; + } + if ((ret = get_kerberos_allowed_etypes(context, &enctypes)) != 0) { + DEBUG(1,("kerberos_derive_cifs_salting_principals: get_kerberos_allowed_etypes failed. %s\n", + error_message(ret))); + goto out; + } + + if ((ret = krb5_cc_resolve(context, LIBADS_CCACHE_NAME, &ccache)) != 0) { + DEBUG(3, ("get_service_ticket: krb5_cc_resolve for %s failed: %s\n", + LIBADS_CCACHE_NAME, error_message(ret))); + goto out; + } + + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service_principal); + + out: + if (enctypes) { + free_kerberos_etypes(context, enctypes); + } + if (ccache) { + krb5_cc_destroy(context, ccache); + } + if (context) { + krb5_free_context(context); } } @@ -681,38 +709,38 @@ BOOL kerberos_derive_cifs_salting_principals(void) if (asprintf(&service, "%s$", global_myname()) != -1) { strlower_m(service); - kerberos_derive_salting_principal(context, ccache, enctypes, service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); SAFE_FREE(service); } if (asprintf(&service, "cifs/%s", global_myname()) != -1) { strlower_m(service); - kerberos_derive_salting_principal(context, ccache, enctypes, service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); SAFE_FREE(service); } if (asprintf(&service, "host/%s", global_myname()) != -1) { strlower_m(service); - kerberos_derive_salting_principal(context, ccache, enctypes, service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); SAFE_FREE(service); } if (asprintf(&service, "cifs/%s.%s", global_myname(), lp_realm()) != -1) { strlower_m(service); - kerberos_derive_salting_principal(context, ccache, enctypes, service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); SAFE_FREE(service); } if (asprintf(&service, "host/%s.%s", global_myname(), lp_realm()) != -1) { strlower_m(service); - kerberos_derive_salting_principal(context, ccache, enctypes, service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); SAFE_FREE(service); } name_to_fqdn(my_fqdn, global_myname()); if (asprintf(&service, "cifs/%s", my_fqdn) != -1) { strlower_m(service); - kerberos_derive_salting_principal(context, ccache, enctypes, service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); SAFE_FREE(service); } if (asprintf(&service, "host/%s", my_fqdn) != -1) { strlower_m(service); - kerberos_derive_salting_principal(context, ccache, enctypes, service); + kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); SAFE_FREE(service); } -- cgit From c0e31dd4f53226386a3017c0a4f8401fab102851 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 3 Nov 2004 00:29:09 +0000 Subject: r3495: Fix the build (recent kerberos-changes). Guenther (This used to be commit c7eab285d967345510a15e83bce508edb8e06e99) --- source3/libads/kerberos.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 32f5951c9f..a38f3c35b1 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -635,7 +635,7 @@ static void kerberos_derive_salting_principal_direct(krb5_context context, Wrapper function for the above. ************************************************************************/ -void kerberos_derive_salting_principal(char *service_principal) +BOOL kerberos_derive_salting_principal(char *service_principal) { krb5_context context = NULL; krb5_enctype *enctypes = NULL; @@ -646,7 +646,7 @@ void kerberos_derive_salting_principal(char *service_principal) if ((ret = krb5_init_context(&context)) != 0) { DEBUG(1,("kerberos_derive_cifs_salting_principals: krb5_init_context failed. %s\n", error_message(ret))); - return; + return False; } if ((ret = get_kerberos_allowed_etypes(context, &enctypes)) != 0) { DEBUG(1,("kerberos_derive_cifs_salting_principals: get_kerberos_allowed_etypes failed. %s\n", @@ -672,6 +672,8 @@ void kerberos_derive_salting_principal(char *service_principal) if (context) { krb5_free_context(context); } + + return ret ? False : True; } /************************************************************************ -- cgit From 44bac2bf7b8537a7cd414a883b5c89042c6ad179 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 22 Dec 2004 22:07:04 +0000 Subject: r4334: Fix for bugid #2186 - from Buck Huppmann to prevent uninitialized creds being freed. Jeremy. (This used to be commit c3f9c81a8fcb26f7110f75b3096d5d1eb30aac13) --- source3/libads/kerberos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index a38f3c35b1..b08e28e0ba 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -320,6 +320,8 @@ static krb5_error_code get_service_ticket(krb5_context ctx, krb5_auth_context auth_context = NULL; krb5_error_code err = 0; + ZERO_STRUCT(creds); + asprintf(&machine_account, "%s$@%s", global_myname(), lp_realm()); if (machine_account == NULL) { goto out; @@ -340,7 +342,6 @@ static krb5_error_code get_service_ticket(krb5_context ctx, ticket to ourselves. */ /* Set up the enctype and client and server principal fields for krb5_get_credentials. */ - memset(&creds, '\0', sizeof(creds)); kerberos_set_creds_enctype(&creds, enctype); if ((err = krb5_cc_get_principal(ctx, ccache, &creds.client))) { -- cgit From c3ba8b9a53617c75ffbcfa8ef32044cb1691d693 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 14 Jan 2005 19:26:13 +0000 Subject: r4736: small set of merges from rtunk to minimize the diffs (This used to be commit 4b351f2fcc365a7b7f8c22b5139c299aa54c9458) --- source3/libads/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index b08e28e0ba..4c9997e080 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -3,7 +3,7 @@ kerberos utility library Copyright (C) Andrew Tridgell 2001 Copyright (C) Remus Koos 2001 - Copyright (C) Nalin Dahyabhai 2004. + Copyright (C) Nalin Dahyabhai 2004. Copyright (C) Jeremy Allison 2004. This program is free software; you can redistribute it and/or modify -- cgit From 934d41d23956c663406ff9d68e5a8ba9d81b5096 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 30 Mar 2005 04:40:24 +0000 Subject: r6127: Eliminated all compiler warnings pertaining to mismatched "qualifiers". The whole of samba comiles warning-free with the default compiler flags. Temporarily defined -Wall to locate other potential problems. Found an unused static function (#ifdefed out rather than deleted, in case it's needed for something in progress). There are also a number of uses of undeclared functions, mostly krb5_*. Files with these problems need to have appropriate header files included, but they are not fixed in this update. oplock_linux.c.c has undefined functions capget() and capset(), which need to have "#undef _POSIX_SOURCE" specified before including , but that could potentially have other side effects, so that remains uncorrected as well. The flag -Wall should be added permanently to CFLAGS, and all warnings then generated should be eliminated. (This used to be commit 5b19ede88ed80318e392f8017f4573fbb2ecbe0f) --- source3/libads/kerberos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 4c9997e080..43ccb18b5a 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -88,7 +88,8 @@ int kerberos_kinit_password(const char *principal, return code; } - if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, password, + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, + (char *) password, kerb_prompter, NULL, 0, NULL, NULL))) { krb5_free_principal(ctx, me); -- cgit From 9840db418bad5a39edc4a32a1786f5e2d2c9dff8 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 31 Mar 2005 05:06:04 +0000 Subject: r6149: Fixes bugs #2498 and 2484. 1. using smbc_getxattr() et al, one may now request all access control entities in the ACL without getting all other NT attributes. 2. added the ability to exclude specified attributes from the result set provided by smbc_getxattr() et al, when requesting all attributes, all NT attributes, or all DOS attributes. 3. eliminated all compiler warnings, including when --enable-developer compiler flags are in use. removed -Wcast-qual flag from list, as that is specifically to force warnings in the case of casting away qualifiers. Note: In the process of eliminating compiler warnings, a few nasties were discovered. In the file libads/sasl.c, PRIVATE kerberos interfaces are being used; and in libsmb/clikrb5.c, both PRIAVE and DEPRECATED kerberos interfaces are being used. Someone who knows kerberos should look at these and determine if there is an alternate method of accomplishing the task. (This used to be commit 994694f7f26da5099f071e1381271a70407f33bb) --- source3/libads/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 43ccb18b5a..18820d9e31 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -89,7 +89,7 @@ int kerberos_kinit_password(const char *principal, } if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, - (char *) password, + CONST_DISCARD(char *, password), kerb_prompter, NULL, 0, NULL, NULL))) { krb5_free_principal(ctx, me); -- cgit From 1c4bbe06549d86614318718a45b9bc48e3bfc81f Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Mon, 2 May 2005 17:49:43 +0000 Subject: r6586: get rid of a few more compiler warnings (This used to be commit 173375f8d88bf8e8db8d60e5d5f0e5dcc28767d9) --- source3/libads/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 18820d9e31..902feb2eee 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -248,7 +248,7 @@ krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, Setting principal to NULL deletes this entry. ************************************************************************/ - BOOL kerberos_secrets_store_salting_principal(const char *service, +BOOL kerberos_secrets_store_salting_principal(const char *service, int enctype, const char *principal) { -- cgit From fed660877c16562265327c6093ea645cf4176b5c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 8 Jun 2005 22:10:34 +0000 Subject: r7415: * big change -- volker's new async winbindd from trunk (This used to be commit a0ac9a8ffd4af31a0ebc423b4acbb2f043d865b8) --- source3/libads/kerberos.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 902feb2eee..c25f9e4bde 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -88,8 +88,7 @@ int kerberos_kinit_password(const char *principal, return code; } - if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, - CONST_DISCARD(char *, password), + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, password, kerb_prompter, NULL, 0, NULL, NULL))) { krb5_free_principal(ctx, me); -- cgit From 8d7c88667190fe286971ac4fffb64ee5bd9eeeb0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Oct 2005 03:24:00 +0000 Subject: r11137: Compile with only 2 warnings (I'm still working on that code) on a gcc4 x86_64 box. Jeremy. (This used to be commit d720867a788c735e56d53d63265255830ec21208) --- source3/libads/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index c25f9e4bde..004079529f 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -88,7 +88,7 @@ int kerberos_kinit_password(const char *principal, return code; } - if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, password, + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), kerb_prompter, NULL, 0, NULL, NULL))) { krb5_free_principal(ctx, me); -- cgit From f99b429446595944991bd2b3e9f4e6a9dd2c13cb Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 7 Nov 2005 14:16:50 +0000 Subject: r11551: Add a few more initialize_krb5_error_table (This used to be commit d92c83aa42fe64a0e996094d1a983f0279c7c707) --- source3/libads/kerberos.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 004079529f..7f855add06 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -70,6 +70,7 @@ int kerberos_kinit_password(const char *principal, krb5_principal me; krb5_creds my_creds; + initialize_krb5_error_table(); if ((code = krb5_init_context(&ctx))) return code; @@ -155,6 +156,7 @@ int ads_kdestroy(const char *cc_name) krb5_context ctx = NULL; krb5_ccache cc = NULL; + initialize_krb5_error_table(); if ((code = krb5_init_context (&ctx))) { DEBUG(3, ("ads_kdestroy: kdb5_init_context failed: %s\n", error_message(code))); -- cgit From 438d0ad451678c42614ab800bceaf490e09c120a Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 10 Nov 2005 19:50:09 +0000 Subject: r11651: After talking to Jeremy, commit my winbindd "Do the Right Thing" patch. Still needs some more testing ni domains with multiple DCs. Coming next.... (This used to be commit aaed605206a8549cec575dab31e56bf6d32f26a6) --- source3/libads/kerberos.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 7f855add06..d5b4b11fa2 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -130,8 +130,25 @@ int ads_kinit_password(ADS_STRUCT *ads) { char *s; int ret; + const char *account_name; + fstring acct_name; - if (asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm) == -1) { + if ( IS_DC ) { + /* this will end up getting a ticket for DOMAIN@RUSTED.REA.LM */ + account_name = lp_workgroup(); + } else { + /* always use the sAMAccountName for security = domain */ + /* global_myname()$@REA.LM */ + if ( lp_security() == SEC_DOMAIN ) { + fstr_sprintf( acct_name, "%s$", global_myname() ); + account_name = acct_name; + } + else + /* This looks like host/global_myname()@REA.LM */ + account_name = ads->auth.user_name; + } + + if (asprintf(&s, "%s@%s", account_name, ads->auth.realm) == -1) { return KRB5_CC_NOMEM; } -- cgit From 0af1500fc0bafe61019f1b2ab1d9e1d369221240 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 3 Feb 2006 22:19:41 +0000 Subject: r13316: Let the carnage begin.... Sync with trunk as off r13315 (This used to be commit 17e63ac4ed8325c0d44fe62b2442449f3298559f) --- source3/libads/kerberos.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index d5b4b11fa2..67f8433775 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -62,13 +62,17 @@ int kerberos_kinit_password(const char *principal, const char *password, int time_offset, time_t *expire_time, - const char *cache_name) + time_t *renew_till_time, + const char *cache_name, + BOOL request_pac, + time_t renewable_time) { krb5_context ctx = NULL; krb5_error_code code = 0; krb5_ccache cc = NULL; krb5_principal me; krb5_creds my_creds; + krb5_get_init_creds_opt opt; initialize_krb5_error_table(); if ((code = krb5_init_context(&ctx))) @@ -77,9 +81,11 @@ int kerberos_kinit_password(const char *principal, if (time_offset != 0) { krb5_set_real_time(ctx, time(NULL) + time_offset, 0); } - - if ((code = krb5_cc_resolve(ctx, cache_name ? - cache_name : krb5_cc_default_name(ctx), &cc))) { + + DEBUG(10,("kerberos_kinit_password: using %s as ccache\n", + cache_name ? cache_name: krb5_cc_default_name(ctx))); + + if ((code = krb5_cc_resolve(ctx, cache_name ? cache_name : krb5_cc_default_name(ctx), &cc))) { krb5_free_context(ctx); return code; } @@ -88,10 +94,20 @@ int kerberos_kinit_password(const char *principal, krb5_free_context(ctx); return code; } + + krb5_get_init_creds_opt_init(&opt); + krb5_get_init_creds_opt_set_renew_life(&opt, renewable_time); + krb5_get_init_creds_opt_set_forwardable(&opt, 1); + if (request_pac) { +#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST + krb5_get_init_creds_opt_set_pac_request(ctx, &opt, True); +#endif + } + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), kerb_prompter, - NULL, 0, NULL, NULL))) { + NULL, 0, NULL, &opt))) { krb5_free_principal(ctx, me); krb5_free_context(ctx); return code; @@ -111,9 +127,14 @@ int kerberos_kinit_password(const char *principal, krb5_free_context(ctx); return code; } - - if (expire_time) + + if (expire_time) { *expire_time = (time_t) my_creds.times.endtime; + } + + if (renew_till_time) { + *renew_till_time = (time_t) my_creds.times.renew_till; + } krb5_cc_close(ctx, cc); krb5_free_cred_contents(ctx, &my_creds); @@ -157,7 +178,7 @@ int ads_kinit_password(ADS_STRUCT *ads) } ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset, - &ads->auth.expire, NULL); + &ads->auth.expire, NULL, NULL, False, ads->auth.renewable); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", @@ -349,7 +370,8 @@ static krb5_error_code get_service_ticket(krb5_context ctx, if (password == NULL) { goto out; } - if ((err = kerberos_kinit_password(machine_account, password, 0, NULL, LIBADS_CCACHE_NAME)) != 0) { + if ((err = kerberos_kinit_password(machine_account, password, 0, NULL, NULL, + LIBADS_CCACHE_NAME, False, 0)) != 0) { DEBUG(0,("get_service_ticket: kerberos_kinit_password %s@%s failed: %s\n", machine_account, lp_realm(), -- cgit From 9fb55b5cb8e916505d3b823c6761c2eff8a5f6ed Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Mar 2006 09:25:26 +0000 Subject: r14503: Fix principal in debug statement. Guenther (This used to be commit 7b1fcb75dadd5ff232d60f93206867cf13322f2e) --- source3/libads/kerberos.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 67f8433775..c82310dd08 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -372,9 +372,8 @@ static krb5_error_code get_service_ticket(krb5_context ctx, } if ((err = kerberos_kinit_password(machine_account, password, 0, NULL, NULL, LIBADS_CCACHE_NAME, False, 0)) != 0) { - DEBUG(0,("get_service_ticket: kerberos_kinit_password %s@%s failed: %s\n", + DEBUG(0,("get_service_ticket: kerberos_kinit_password %s failed: %s\n", machine_account, - lp_realm(), error_message(err))); goto out; } -- cgit From 0342db7e87f4c98da4051e9fc7a8abf1e36218d0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 17 Mar 2006 13:57:00 +0000 Subject: r14512: Guenther, This code breaks winbind with MIT krb1.3. I'm disabling it for now until we have en effective means of dealing with the ticket request flags for users and computers. (This used to be commit 635f0c9c01c2e389ca916e9004e9ea064bf69cbb) --- source3/libads/kerberos.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index c82310dd08..17e350d754 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -72,7 +72,9 @@ int kerberos_kinit_password(const char *principal, krb5_ccache cc = NULL; krb5_principal me; krb5_creds my_creds; +#if 0 krb5_get_init_creds_opt opt; +#endif initialize_krb5_error_table(); if ((code = krb5_init_context(&ctx))) @@ -95,9 +97,12 @@ int kerberos_kinit_password(const char *principal, return code; } +#if 0 /* This code causes problems with MIT krb5 1.3 when asking for a + TGT for the machine account */ krb5_get_init_creds_opt_init(&opt); krb5_get_init_creds_opt_set_renew_life(&opt, renewable_time); krb5_get_init_creds_opt_set_forwardable(&opt, 1); +#endif if (request_pac) { #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST @@ -105,9 +110,14 @@ int kerberos_kinit_password(const char *principal, #endif } +#if 0 if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), - kerb_prompter, - NULL, 0, NULL, &opt))) { + kerb_prompter, NULL, 0, NULL, &opt))) +#else + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), + kerb_prompter, NULL, 0, NULL, NULL))) +#endif + { krb5_free_principal(ctx, me); krb5_free_context(ctx); return code; -- cgit From 485a286a65d3b37f424f5701179f73c99eb9b5b9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 20 Mar 2006 19:05:44 +0000 Subject: r14585: Tighten argument list of kerberos_kinit_password again, kerberos_kinit_password_ext provides access to more options. Guenther (This used to be commit afc519530f94b420b305fc28f83c16db671d0d7f) --- source3/libads/kerberos.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 17e350d754..029e42c0c2 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -58,7 +58,7 @@ kerb_prompter(krb5_context ctx, void *data, place in default cache location. remus@snapserver.com */ -int kerberos_kinit_password(const char *principal, +int kerberos_kinit_password_ext(const char *principal, const char *password, int time_offset, time_t *expire_time, @@ -187,7 +187,7 @@ int ads_kinit_password(ADS_STRUCT *ads) return KRB5_LIBOS_CANTREADPWD; } - ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset, + ret = kerberos_kinit_password_ext(s, ads->auth.password, ads->auth.time_offset, &ads->auth.expire, NULL, NULL, False, ads->auth.renewable); if (ret) { @@ -380,8 +380,8 @@ static krb5_error_code get_service_ticket(krb5_context ctx, if (password == NULL) { goto out; } - if ((err = kerberos_kinit_password(machine_account, password, 0, NULL, NULL, - LIBADS_CCACHE_NAME, False, 0)) != 0) { + if ((err = kerberos_kinit_password(machine_account, password, + 0, LIBADS_CCACHE_NAME)) != 0) { DEBUG(0,("get_service_ticket: kerberos_kinit_password %s failed: %s\n", machine_account, error_message(err))); @@ -811,4 +811,20 @@ BOOL kerberos_derive_cifs_salting_principals(void) } return retval; } + +int kerberos_kinit_password(const char *principal, + const char *password, + int time_offset, + const char *cache_name) +{ + return kerberos_kinit_password_ext(principal, + password, + time_offset, + 0, + 0, + cache_name, + False, + 0); +} + #endif -- cgit From e4dc7454346da21d5bc7df7028057d47d7d4d0a5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 21 Mar 2006 11:14:29 +0000 Subject: r14611: Fix init_creds_opts issue jerry discovered when using MIT krb5 1.3: We were using a far too short renewable_time in the request; newer MIT releases take care interally that the renewable time is never shorter then the default ticket lifetime. Guenther (This used to be commit bde4a4018e26bc9aab4b928ec9811c05b21574f3) --- source3/libads/kerberos.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 029e42c0c2..e5211813d3 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -72,9 +72,7 @@ int kerberos_kinit_password_ext(const char *principal, krb5_ccache cc = NULL; krb5_principal me; krb5_creds my_creds; -#if 0 krb5_get_init_creds_opt opt; -#endif initialize_krb5_error_table(); if ((code = krb5_init_context(&ctx))) @@ -97,12 +95,9 @@ int kerberos_kinit_password_ext(const char *principal, return code; } -#if 0 /* This code causes problems with MIT krb5 1.3 when asking for a - TGT for the machine account */ krb5_get_init_creds_opt_init(&opt); krb5_get_init_creds_opt_set_renew_life(&opt, renewable_time); krb5_get_init_creds_opt_set_forwardable(&opt, 1); -#endif if (request_pac) { #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST @@ -110,13 +105,8 @@ int kerberos_kinit_password_ext(const char *principal, #endif } -#if 0 if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), kerb_prompter, NULL, 0, NULL, &opt))) -#else - if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), - kerb_prompter, NULL, 0, NULL, NULL))) -#endif { krb5_free_principal(ctx, me); krb5_free_context(ctx); -- cgit From b68b05854ff5a7e75953462eba74f97753428ef1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 24 Apr 2006 15:57:54 +0000 Subject: r15210: Add wrapper functions smb_krb5_parse_name, smb_krb5_unparse_name, smb_krb5_parse_name_norealm_conv that pull/push from unix charset to utf8 (which krb5 uses on the wire). This should fix issues when the unix charset is not compatible with or set to utf8. Jeremy. (This used to be commit 37ab42afbc9a79cf5b04ce6a1bf4060e9c961199) --- source3/libads/kerberos.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index e5211813d3..960709a5f0 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -90,7 +90,7 @@ int kerberos_kinit_password_ext(const char *principal, return code; } - if ((code = krb5_parse_name(ctx, principal, &me))) { + if ((code = smb_krb5_parse_name(ctx, principal, &me))) { krb5_free_context(ctx); return code; } @@ -260,21 +260,21 @@ krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, char *unparsed_name = NULL, *salt_princ_s = NULL; krb5_principal ret_princ = NULL; - if (krb5_unparse_name(context, host_princ, &unparsed_name) != 0) { + if (smb_krb5_unparse_name(context, host_princ, &unparsed_name) != 0) { return (krb5_principal)NULL; } if ((salt_princ_s = kerberos_secrets_fetch_salting_principal(unparsed_name, enctype)) == NULL) { - krb5_free_unparsed_name(context, unparsed_name); + SAFE_FREE(unparsed_name); return (krb5_principal)NULL; } - if (krb5_parse_name(context, salt_princ_s, &ret_princ) != 0) { - krb5_free_unparsed_name(context, unparsed_name); + if (smb_krb5_parse_name(context, salt_princ_s, &ret_princ) != 0) { + SAFE_FREE(unparsed_name); SAFE_FREE(salt_princ_s); return (krb5_principal)NULL; } - krb5_free_unparsed_name(context, unparsed_name); + SAFE_FREE(unparsed_name); SAFE_FREE(salt_princ_s); return ret_princ; } @@ -308,11 +308,11 @@ BOOL kerberos_secrets_store_salting_principal(const char *service, asprintf(&princ_s, "%s@%s", service, lp_realm()); } - if (krb5_parse_name(context, princ_s, &princ) != 0) { + if (smb_krb5_parse_name(context, princ_s, &princ) != 0) { goto out; } - if (krb5_unparse_name(context, princ, &unparsed_name) != 0) { + if (smb_krb5_unparse_name(context, princ, &unparsed_name) != 0) { goto out; } @@ -331,10 +331,8 @@ BOOL kerberos_secrets_store_salting_principal(const char *service, SAFE_FREE(key); SAFE_FREE(princ_s); + SAFE_FREE(unparsed_name); - if (unparsed_name) { - krb5_free_unparsed_name(context, unparsed_name); - } if (context) { krb5_free_context(context); } @@ -396,8 +394,8 @@ static krb5_error_code get_service_ticket(krb5_context ctx, asprintf(&service_s, "%s@%s", service_principal, lp_realm()); } - if ((err = krb5_parse_name(ctx, service_s, &creds.server))) { - DEBUG(0,("get_service_ticket: krb5_parse_name %s failed: %s\n", + if ((err = smb_krb5_parse_name(ctx, service_s, &creds.server))) { + DEBUG(0,("get_service_ticket: smb_krb5_parse_name %s failed: %s\n", service_s, error_message(err))); goto out; } @@ -476,8 +474,8 @@ static BOOL verify_service_password(krb5_context ctx, asprintf(&salting_s, "%s@%s", salting_principal, lp_realm()); } - if ((err = krb5_parse_name(ctx, salting_s, &salting_kprinc))) { - DEBUG(0,("verify_service_password: krb5_parse_name %s failed: %s\n", + if ((err = smb_krb5_parse_name(ctx, salting_s, &salting_kprinc))) { + DEBUG(0,("verify_service_password: smb_krb5_parse_name %s failed: %s\n", salting_s, error_message(err))); goto out; } -- cgit From 351e749246a278b60a7e18c1eeafdc8ec70efea2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 25 Apr 2006 12:24:25 +0000 Subject: r15240: Correctly disallow unauthorized access when logging on with the kerberized pam_winbind and workstation restrictions are in effect. The krb5 AS-REQ needs to add the host netbios-name in the address-list. We don't get the clear NT_STATUS_INVALID_WORKSTATION code back yet from the edata of the KRB_ERROR but the login at least fails when the local machine is not in the workstation list on the DC. Guenther (This used to be commit 8b2ba11508e2730aba074d7c095291fac2a62176) --- source3/libads/kerberos.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 960709a5f0..2dfdc31dd5 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -65,6 +65,7 @@ int kerberos_kinit_password_ext(const char *principal, time_t *renew_till_time, const char *cache_name, BOOL request_pac, + BOOL add_netbios_addr, time_t renewable_time) { krb5_context ctx = NULL; @@ -73,6 +74,7 @@ int kerberos_kinit_password_ext(const char *principal, krb5_principal me; krb5_creds my_creds; krb5_get_init_creds_opt opt; + smb_krb5_addresses *addr = NULL; initialize_krb5_error_table(); if ((code = krb5_init_context(&ctx))) @@ -101,19 +103,36 @@ int kerberos_kinit_password_ext(const char *principal, if (request_pac) { #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST - krb5_get_init_creds_opt_set_pac_request(ctx, &opt, True); + code = krb5_get_init_creds_opt_set_pac_request(ctx, &opt, True); + if (code) { + krb5_free_principal(ctx, me); + krb5_free_context(ctx); + return code; + } #endif } + if (add_netbios_addr) { + code = smb_krb5_gen_netbios_krb5_address(&addr); + if (code) { + krb5_free_principal(ctx, me); + krb5_free_context(ctx); + return code; + } + krb5_get_init_creds_opt_set_address_list(&opt, addr->addrs); + } + if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), kerb_prompter, NULL, 0, NULL, &opt))) { + smb_krb5_free_addresses(ctx, addr); krb5_free_principal(ctx, me); krb5_free_context(ctx); return code; } if ((code = krb5_cc_initialize(ctx, cc, me))) { + smb_krb5_free_addresses(ctx, addr); krb5_free_cred_contents(ctx, &my_creds); krb5_free_principal(ctx, me); krb5_free_context(ctx); @@ -122,6 +141,7 @@ int kerberos_kinit_password_ext(const char *principal, if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) { krb5_cc_close(ctx, cc); + smb_krb5_free_addresses(ctx, addr); krb5_free_cred_contents(ctx, &my_creds); krb5_free_principal(ctx, me); krb5_free_context(ctx); @@ -137,6 +157,7 @@ int kerberos_kinit_password_ext(const char *principal, } krb5_cc_close(ctx, cc); + smb_krb5_free_addresses(ctx, addr); krb5_free_cred_contents(ctx, &my_creds); krb5_free_principal(ctx, me); krb5_free_context(ctx); @@ -178,7 +199,7 @@ int ads_kinit_password(ADS_STRUCT *ads) } ret = kerberos_kinit_password_ext(s, ads->auth.password, ads->auth.time_offset, - &ads->auth.expire, NULL, NULL, False, ads->auth.renewable); + &ads->auth.expire, NULL, NULL, False, False, ads->auth.renewable); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", @@ -812,6 +833,7 @@ int kerberos_kinit_password(const char *principal, 0, cache_name, False, + False, 0); } -- cgit From d4ad11ccd8dd6780e048849784b33fd55d5a04b6 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 15 Jun 2006 21:59:25 +0000 Subject: r16272: Fix memleak. Guenther (This used to be commit afdb1189029e01a132f16fea48624126ec65cd77) --- source3/libads/kerberos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 2dfdc31dd5..90650e1dce 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -195,6 +195,7 @@ int ads_kinit_password(ADS_STRUCT *ads) } if (!ads->auth.password) { + SAFE_FREE(s); return KRB5_LIBOS_CANTREADPWD; } @@ -205,7 +206,7 @@ int ads_kinit_password(ADS_STRUCT *ads) DEBUG(0,("kerberos_kinit_password %s failed: %s\n", s, error_message(ret))); } - free(s); + SAFE_FREE(s); return ret; } -- cgit From 060b155cd2f77e37086f97461f93e9ef1ff8dce2 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 11 Jul 2006 18:45:22 +0000 Subject: r16952: New derive DES salt code and Krb5 keytab generation Major points of interest: * Figure the DES salt based on the domain functional level and UPN (if present and applicable) * Only deal with the DES-CBC-MD5, DES-CBC-CRC, and RC4-HMAC keys * Remove all the case permutations in the keytab entry generation (to be partially re-added only if necessary). * Generate keytab entries based on the existing SPN values in AD The resulting keytab looks like: ktutil: list -e slot KVNO Principal ---- ---- --------------------------------------------------------------------- 1 6 host/suse10.plainjoe.org@COLOR.PLAINJOE.ORG (DES cbc mode with CRC-32) 2 6 host/suse10.plainjoe.org@COLOR.PLAINJOE.ORG (DES cbc mode with RSA-MD5) 3 6 host/suse10.plainjoe.org@COLOR.PLAINJOE.ORG (ArcFour with HMAC/md5) 4 6 host/suse10@COLOR.PLAINJOE.ORG (DES cbc mode with CRC-32) 5 6 host/suse10@COLOR.PLAINJOE.ORG (DES cbc mode with RSA-MD5) 6 6 host/suse10@COLOR.PLAINJOE.ORG (ArcFour with HMAC/md5) 7 6 suse10$@COLOR.PLAINJOE.ORG (DES cbc mode with CRC-32) 8 6 suse10$@COLOR.PLAINJOE.ORG (DES cbc mode with RSA-MD5) 9 6 suse10$@COLOR.PLAINJOE.ORG (ArcFour with HMAC/md5) The list entries are the two basic SPN values (host/NetBIOSName & host/dNSHostName) and the sAMAccountName value. The UPN will be added as well if the machine has one. This fixes 'kinit -k'. Tested keytab using mod_auth_krb and MIT's telnet. ads_verify_ticket() continues to work with RC4-HMAC and DES keys. (This used to be commit 6261dd3c67d10db6cfa2e77a8d304d3dce4050a4) --- source3/libads/kerberos.c | 571 ++++++++-------------------------------------- 1 file changed, 100 insertions(+), 471 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 90650e1dce..a25daf5399 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -5,6 +5,7 @@ Copyright (C) Remus Koos 2001 Copyright (C) Nalin Dahyabhai 2004. Copyright (C) Jeremy Allison 2004. + Copyright (C) Gerald Carter 2006. 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 @@ -268,11 +269,89 @@ static char *kerberos_secrets_fetch_salting_principal(const char *service, int e } /************************************************************************ - Routine to get the salting principal for this service. Active - Directory may use a non-obvious principal name to generate the salt - when it determines the key to use for encrypting tickets for a service, - and hopefully we detected that when we joined the domain. - Caller must free if return is not null. + Return the standard DES salt key +************************************************************************/ + +char* kerberos_standard_des_salt( void ) +{ + fstring salt; + + fstr_sprintf( salt, "host/%s.%s@", global_myname(), lp_realm() ); + strlower_m( salt ); + fstrcat( salt, lp_realm() ); + + return SMB_STRDUP( salt ); +} + +/************************************************************************ +************************************************************************/ + +static char* des_salt_key( void ) +{ + char *key; + + asprintf(&key, "%s/DES/%s", SECRETS_SALTING_PRINCIPAL, lp_realm()); + + return key; +} + +/************************************************************************ +************************************************************************/ + +BOOL kerberos_secrets_store_des_salt( const char* salt ) +{ + char* key; + BOOL ret; + + if ( (key = des_salt_key()) == NULL ) { + DEBUG(0,("kerberos_secrets_store_des_salt: failed to generate key!\n")); + return False; + } + + if ( !salt ) { + DEBUG(8,("kerberos_secrets_store_des_salt: deleting salt\n")); + secrets_delete( key ); + } + + DEBUG(3,("kerberos_secrets_store_des_salt: Storing salt \"%s\"\n", salt)); + + ret = secrets_store( key, salt, strlen(salt)+1 ); + + SAFE_FREE( key ); + + return ret; +} + +/************************************************************************ +************************************************************************/ + +char* kerberos_secrets_fetch_des_salt( void ) +{ + char *salt, *key; + + if ( (key = des_salt_key()) == NULL ) { + DEBUG(0,("kerberos_secrets_fetch_des_salt: failed to generate key!\n")); + return False; + } + + if ( !salt ) { + DEBUG(8,("kerberos_secrets_fetch_des_salt: NULL salt!\n")); + secrets_delete( key ); + } + + salt = (char*)secrets_fetch( key, NULL ); + + SAFE_FREE( key ); + + return salt; +} + + +/************************************************************************ + Routine to get the salting principal for this service. This is + maintained for backwards compatibilty with releases prior to 3.0.24. + Since we store the salting principal string only at join, we may have + to look for the older tdb keys. Caller must free if return is not null. ************************************************************************/ krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, @@ -281,23 +360,29 @@ krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, { char *unparsed_name = NULL, *salt_princ_s = NULL; krb5_principal ret_princ = NULL; + + /* lookup new key first */ - if (smb_krb5_unparse_name(context, host_princ, &unparsed_name) != 0) { - return (krb5_principal)NULL; - } + if ( (salt_princ_s = kerberos_secrets_fetch_des_salt()) == NULL ) { + + /* look under the old key. If this fails, just use the standard key */ - if ((salt_princ_s = kerberos_secrets_fetch_salting_principal(unparsed_name, enctype)) == NULL) { - SAFE_FREE(unparsed_name); - return (krb5_principal)NULL; + if (smb_krb5_unparse_name(context, host_princ, &unparsed_name) != 0) { + return (krb5_principal)NULL; + } + if ((salt_princ_s = kerberos_secrets_fetch_salting_principal(unparsed_name, enctype)) == NULL) { + /* fall back to host/machine.realm@REALM */ + salt_princ_s = kerberos_standard_des_salt(); + } } if (smb_krb5_parse_name(context, salt_princ_s, &ret_princ) != 0) { - SAFE_FREE(unparsed_name); - SAFE_FREE(salt_princ_s); - return (krb5_principal)NULL; + ret_princ = NULL; } + SAFE_FREE(unparsed_name); SAFE_FREE(salt_princ_s); + return ret_princ; } @@ -362,465 +447,9 @@ BOOL kerberos_secrets_store_salting_principal(const char *service, return ret; } -/************************************************************************ - Routine to get initial credentials as a service ticket for the local machine. - Returns a buffer initialized with krb5_mk_req_extended. - ************************************************************************/ - -static krb5_error_code get_service_ticket(krb5_context ctx, - krb5_ccache ccache, - const char *service_principal, - int enctype, - krb5_data *p_outbuf) -{ - krb5_creds creds, *new_creds = NULL; - char *service_s = NULL; - char *machine_account = NULL, *password = NULL; - krb5_data in_data; - krb5_auth_context auth_context = NULL; - krb5_error_code err = 0; - - ZERO_STRUCT(creds); - - asprintf(&machine_account, "%s$@%s", global_myname(), lp_realm()); - if (machine_account == NULL) { - goto out; - } - password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); - if (password == NULL) { - goto out; - } - if ((err = kerberos_kinit_password(machine_account, password, - 0, LIBADS_CCACHE_NAME)) != 0) { - DEBUG(0,("get_service_ticket: kerberos_kinit_password %s failed: %s\n", - machine_account, - error_message(err))); - goto out; - } - - /* Ok - the above call has gotten a TGT. Now we need to get a service - ticket to ourselves. */ - - /* Set up the enctype and client and server principal fields for krb5_get_credentials. */ - kerberos_set_creds_enctype(&creds, enctype); - - if ((err = krb5_cc_get_principal(ctx, ccache, &creds.client))) { - DEBUG(3, ("get_service_ticket: krb5_cc_get_principal failed: %s\n", - error_message(err))); - goto out; - } - - if (strchr_m(service_principal, '@')) { - asprintf(&service_s, "%s", service_principal); - } else { - asprintf(&service_s, "%s@%s", service_principal, lp_realm()); - } - - if ((err = smb_krb5_parse_name(ctx, service_s, &creds.server))) { - DEBUG(0,("get_service_ticket: smb_krb5_parse_name %s failed: %s\n", - service_s, error_message(err))); - goto out; - } - - if ((err = krb5_get_credentials(ctx, 0, ccache, &creds, &new_creds))) { - DEBUG(5,("get_service_ticket: krb5_get_credentials for %s enctype %d failed: %s\n", - service_s, enctype, error_message(err))); - goto out; - } - - memset(&in_data, '\0', sizeof(in_data)); - if ((err = krb5_mk_req_extended(ctx, &auth_context, 0, &in_data, - new_creds, p_outbuf)) != 0) { - DEBUG(0,("get_service_ticket: krb5_mk_req_extended failed: %s\n", - error_message(err))); - goto out; - } - - out: - - if (auth_context) { - krb5_auth_con_free(ctx, auth_context); - } - if (new_creds) { - krb5_free_creds(ctx, new_creds); - } - if (creds.server) { - krb5_free_principal(ctx, creds.server); - } - if (creds.client) { - krb5_free_principal(ctx, creds.client); - } - - SAFE_FREE(service_s); - SAFE_FREE(password); - SAFE_FREE(machine_account); - return err; -} - -/************************************************************************ - Check if the machine password can be used in conjunction with the salting_principal - to generate a key which will successfully decrypt the AP_REQ already - gotten as a message to the local machine. - ************************************************************************/ - -static BOOL verify_service_password(krb5_context ctx, - int enctype, - const char *salting_principal, - krb5_data *in_data) -{ - BOOL ret = False; - krb5_principal salting_kprinc = NULL; - krb5_ticket *ticket = NULL; - krb5_keyblock key; - krb5_data passdata; - char *salting_s = NULL; - char *machine_account = NULL, *password = NULL; - krb5_auth_context auth_context = NULL; - krb5_error_code err; - - memset(&passdata, '\0', sizeof(passdata)); - memset(&key, '\0', sizeof(key)); - - asprintf(&machine_account, "%s$@%s", global_myname(), lp_realm()); - if (machine_account == NULL) { - goto out; - } - password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); - if (password == NULL) { - goto out; - } - - if (strchr_m(salting_principal, '@')) { - asprintf(&salting_s, "%s", salting_principal); - } else { - asprintf(&salting_s, "%s@%s", salting_principal, lp_realm()); - } - - if ((err = smb_krb5_parse_name(ctx, salting_s, &salting_kprinc))) { - DEBUG(0,("verify_service_password: smb_krb5_parse_name %s failed: %s\n", - salting_s, error_message(err))); - goto out; - } - - passdata.length = strlen(password); - passdata.data = (char*)password; - if ((err = create_kerberos_key_from_string_direct(ctx, salting_kprinc, &passdata, &key, enctype))) { - DEBUG(0,("verify_service_password: create_kerberos_key_from_string %d failed: %s\n", - enctype, error_message(err))); - goto out; - } - - if ((err = krb5_auth_con_init(ctx, &auth_context)) != 0) { - DEBUG(0,("verify_service_password: krb5_auth_con_init failed %s\n", error_message(err))); - goto out; - } - - if ((err = krb5_auth_con_setuseruserkey(ctx, auth_context, &key)) != 0) { - DEBUG(0,("verify_service_password: krb5_auth_con_setuseruserkey failed %s\n", error_message(err))); - goto out; - } - - if (!(err = krb5_rd_req(ctx, &auth_context, in_data, NULL, NULL, NULL, &ticket))) { - DEBUG(10,("verify_service_password: decrypted message with enctype %u salt %s!\n", - (unsigned int)enctype, salting_s)); - ret = True; - } - - out: - - memset(&passdata, 0, sizeof(passdata)); - krb5_free_keyblock_contents(ctx, &key); - if (ticket != NULL) { - krb5_free_ticket(ctx, ticket); - } - if (salting_kprinc) { - krb5_free_principal(ctx, salting_kprinc); - } - SAFE_FREE(salting_s); - SAFE_FREE(password); - SAFE_FREE(machine_account); - return ret; -} - -/************************************************************************ - * - * From the current draft of kerberos-clarifications: - * - * It is not possible to reliably generate a user's key given a pass - * phrase without contacting the KDC, since it will not be known - * whether alternate salt or parameter values are required. - * - * And because our server has a password, we have this exact problem. We - * make multiple guesses as to which principal name provides the salt which - * the KDC is using. - * - ************************************************************************/ - -static void kerberos_derive_salting_principal_for_enctype(const char *service_principal, - krb5_context ctx, - krb5_ccache ccache, - krb5_enctype enctype, - krb5_enctype *enctypes) -{ - char *salting_principals[3] = {NULL, NULL, NULL}, *second_principal = NULL; - krb5_error_code err = 0; - krb5_data outbuf; - int i, j; - - memset(&outbuf, '\0', sizeof(outbuf)); - - /* Check that the service_principal is useful. */ - if ((service_principal == NULL) || (strlen(service_principal) == 0)) { - return; - } - - /* Generate our first guess -- the principal as-given. */ - asprintf(&salting_principals[0], "%s", service_principal); - if ((salting_principals[0] == NULL) || (strlen(salting_principals[0]) == 0)) { - return; - } - - /* Generate our second guess -- the computer's principal, as Win2k3. */ - asprintf(&second_principal, "host/%s.%s", global_myname(), lp_realm()); - if (second_principal != NULL) { - strlower_m(second_principal); - asprintf(&salting_principals[1], "%s@%s", second_principal, lp_realm()); - SAFE_FREE(second_principal); - } - if ((salting_principals[1] == NULL) || (strlen(salting_principals[1]) == 0)) { - goto out; - } - - /* Generate our third guess -- the computer's principal, as Win2k. */ - asprintf(&second_principal, "HOST/%s", global_myname()); - if (second_principal != NULL) { - strlower_m(second_principal + 5); - asprintf(&salting_principals[2], "%s@%s", - second_principal, lp_realm()); - SAFE_FREE(second_principal); - } - if ((salting_principals[2] == NULL) || (strlen(salting_principals[2]) == 0)) { - goto out; - } - - /* Get a service ticket for ourselves into our memory ccache. */ - /* This will commonly fail if there is no principal by that name (and we're trying - many names). So don't print a debug 0 error. */ - - if ((err = get_service_ticket(ctx, ccache, service_principal, enctype, &outbuf)) != 0) { - DEBUG(3, ("verify_service_password: get_service_ticket failed: %s\n", - error_message(err))); - goto out; - } - - /* At this point we have a message to ourselves, salted only the KDC knows how. We - have to work out what that salting is. */ - - /* Try and find the correct salting principal. */ - for (i = 0; i < sizeof(salting_principals) / sizeof(salting_principals[i]); i++) { - if (verify_service_password(ctx, enctype, salting_principals[i], &outbuf)) { - break; - } - } - - /* If we failed to get a match, return. */ - if (i >= sizeof(salting_principals) / sizeof(salting_principals[i])) { - goto out; - } - - /* If we succeeded, store the principal for use for all enctypes which - * share the same cipher and string-to-key function. Doing this here - * allows servers which just pass a keytab to krb5_rd_req() to work - * correctly. */ - for (j = 0; enctypes[j] != 0; j++) { - if (enctype != enctypes[j]) { - /* If this enctype isn't compatible with the one which - * we used, skip it. */ - - if (!kerberos_compatible_enctypes(ctx, enctypes[j], enctype)) - continue; - } - /* If the principal which gives us the proper salt is the one - * which we would normally guess, don't bother noting anything - * in the secrets tdb. */ - if (strcmp(service_principal, salting_principals[i]) != 0) { - kerberos_secrets_store_salting_principal(service_principal, - enctypes[j], - salting_principals[i]); - } - } - - out : - - kerberos_free_data_contents(ctx, &outbuf); - SAFE_FREE(salting_principals[0]); - SAFE_FREE(salting_principals[1]); - SAFE_FREE(salting_principals[2]); - SAFE_FREE(second_principal); -} - -/************************************************************************ - Go through all the possible enctypes for this principal. - ************************************************************************/ - -static void kerberos_derive_salting_principal_direct(krb5_context context, - krb5_ccache ccache, - krb5_enctype *enctypes, - char *service_principal) -{ - int i; - - /* Try for each enctype separately, because the rules are - * different for different enctypes. */ - for (i = 0; enctypes[i] != 0; i++) { - /* Delete secrets entry first. */ - kerberos_secrets_store_salting_principal(service_principal, 0, NULL); -#ifdef ENCTYPE_ARCFOUR_HMAC - if (enctypes[i] == ENCTYPE_ARCFOUR_HMAC) { - /* Of course this'll always work, so just save - * ourselves the effort. */ - continue; - } -#endif - /* Try to figure out what's going on with this - * principal. */ - kerberos_derive_salting_principal_for_enctype(service_principal, - context, - ccache, - enctypes[i], - enctypes); - } -} - -/************************************************************************ - Wrapper function for the above. - ************************************************************************/ - -BOOL kerberos_derive_salting_principal(char *service_principal) -{ - krb5_context context = NULL; - krb5_enctype *enctypes = NULL; - krb5_ccache ccache = NULL; - krb5_error_code ret = 0; - - initialize_krb5_error_table(); - if ((ret = krb5_init_context(&context)) != 0) { - DEBUG(1,("kerberos_derive_cifs_salting_principals: krb5_init_context failed. %s\n", - error_message(ret))); - return False; - } - if ((ret = get_kerberos_allowed_etypes(context, &enctypes)) != 0) { - DEBUG(1,("kerberos_derive_cifs_salting_principals: get_kerberos_allowed_etypes failed. %s\n", - error_message(ret))); - goto out; - } - - if ((ret = krb5_cc_resolve(context, LIBADS_CCACHE_NAME, &ccache)) != 0) { - DEBUG(3, ("get_service_ticket: krb5_cc_resolve for %s failed: %s\n", - LIBADS_CCACHE_NAME, error_message(ret))); - goto out; - } - - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service_principal); - - out: - if (enctypes) { - free_kerberos_etypes(context, enctypes); - } - if (ccache) { - krb5_cc_destroy(context, ccache); - } - if (context) { - krb5_free_context(context); - } - - return ret ? False : True; -} /************************************************************************ - Core function to try and determine what salt is being used for any keytab - keys. - ************************************************************************/ - -BOOL kerberos_derive_cifs_salting_principals(void) -{ - fstring my_fqdn; - char *service = NULL; - krb5_context context = NULL; - krb5_enctype *enctypes = NULL; - krb5_ccache ccache = NULL; - krb5_error_code ret = 0; - BOOL retval = False; - - initialize_krb5_error_table(); - if ((ret = krb5_init_context(&context)) != 0) { - DEBUG(1,("kerberos_derive_cifs_salting_principals: krb5_init_context failed. %s\n", - error_message(ret))); - return False; - } - if ((ret = get_kerberos_allowed_etypes(context, &enctypes)) != 0) { - DEBUG(1,("kerberos_derive_cifs_salting_principals: get_kerberos_allowed_etypes failed. %s\n", - error_message(ret))); - goto out; - } - - if ((ret = krb5_cc_resolve(context, LIBADS_CCACHE_NAME, &ccache)) != 0) { - DEBUG(3, ("get_service_ticket: krb5_cc_resolve for %s failed: %s\n", - LIBADS_CCACHE_NAME, error_message(ret))); - goto out; - } - - if (asprintf(&service, "%s$", global_myname()) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - if (asprintf(&service, "cifs/%s", global_myname()) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - if (asprintf(&service, "host/%s", global_myname()) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - if (asprintf(&service, "cifs/%s.%s", global_myname(), lp_realm()) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - if (asprintf(&service, "host/%s.%s", global_myname(), lp_realm()) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - name_to_fqdn(my_fqdn, global_myname()); - if (asprintf(&service, "cifs/%s", my_fqdn) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - if (asprintf(&service, "host/%s", my_fqdn) != -1) { - strlower_m(service); - kerberos_derive_salting_principal_direct(context, ccache, enctypes, service); - SAFE_FREE(service); - } - - retval = True; - - out: - if (enctypes) { - free_kerberos_etypes(context, enctypes); - } - if (ccache) { - krb5_cc_destroy(context, ccache); - } - if (context) { - krb5_free_context(context); - } - return retval; -} +************************************************************************/ int kerberos_kinit_password(const char *principal, const char *password, -- cgit From 361fef49c50263313d61cdaad5a4fbe2c5ddb78d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 11 Jul 2006 20:50:50 +0000 Subject: r16955: Fix an uninitialized var -- Jerry, please check. (This used to be commit bf701f51294dacd0d4077b5304772c40119460eb) --- source3/libads/kerberos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index a25daf5399..d1b1f7240c 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -334,13 +334,13 @@ char* kerberos_secrets_fetch_des_salt( void ) return False; } + salt = (char*)secrets_fetch( key, NULL ); + if ( !salt ) { DEBUG(8,("kerberos_secrets_fetch_des_salt: NULL salt!\n")); secrets_delete( key ); } - salt = (char*)secrets_fetch( key, NULL ); - SAFE_FREE( key ); return salt; -- cgit From 69f0c8aef13af60c3d49e3e0e1b2bc8f1e6bb36f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 11 Jul 2006 21:09:13 +0000 Subject: r16957: fix cut-n-paste error. The check for 'if (\!salt)' make no sense when fetching the DES salting principal (This used to be commit baf554c7934cbd591635196453c19d402358e073) --- source3/libads/kerberos.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index d1b1f7240c..9f197fb50c 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -336,11 +336,6 @@ char* kerberos_secrets_fetch_des_salt( void ) salt = (char*)secrets_fetch( key, NULL ); - if ( !salt ) { - DEBUG(8,("kerberos_secrets_fetch_des_salt: NULL salt!\n")); - secrets_delete( key ); - } - SAFE_FREE( key ); return salt; -- cgit From de5d9675052e311290211ce3656bb050497ae8cf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 13 Jul 2006 00:11:34 +0000 Subject: r17003: Fix coverity #303 - possible null deref. Jerry please check this is your new code. Jeremy. (This used to be commit 144067783d1c56b574911532f074bdaa7cea9c6e) --- source3/libads/kerberos.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 9f197fb50c..af4ba86831 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -311,6 +311,7 @@ BOOL kerberos_secrets_store_des_salt( const char* salt ) if ( !salt ) { DEBUG(8,("kerberos_secrets_store_des_salt: deleting salt\n")); secrets_delete( key ); + return True; } DEBUG(3,("kerberos_secrets_store_des_salt: Storing salt \"%s\"\n", salt)); -- cgit From fd8bae8b1660acefd327121ef3d8a356cb0c09fa Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 31 Jul 2006 20:51:55 +0000 Subject: r17345: Some C++ warnings (This used to be commit 21c8fa2fc8bfd35d203b089ff61efc7c292b4dc0) --- source3/libads/kerberos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index af4ba86831..910207968c 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -45,7 +45,8 @@ kerb_prompter(krb5_context ctx, void *data, memset(prompts[0].reply->data, '\0', prompts[0].reply->length); if (prompts[0].reply->length > 0) { if (data) { - strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); + strncpy(prompts[0].reply->data, (const char *)data, + prompts[0].reply->length-1); prompts[0].reply->length = strlen(prompts[0].reply->data); } else { prompts[0].reply->length = 0; -- cgit From 6fada7a82aa67e7b80ff003bd527092da68542c8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Aug 2006 01:20:21 +0000 Subject: r17943: The horror, the horror. Add KDC site support by writing out a custom krb5.conf file containing the KDC I need. This may suck.... Needs some testing :-). Jeremy. (This used to be commit d500e1f96d92dfcc6292c448d1b399195f762d89) --- source3/libads/kerberos.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 910207968c..4e4e4cfebf 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -464,4 +464,62 @@ int kerberos_kinit_password(const char *principal, 0); } +/************************************************************************ + Create a specific krb5.conf file in the private directory pointing + at a specific kdc for a realm. Keyed off domain name. Sets + KRB5_CONFIG environment variable to point to this file. Must be + run as root or will fail (which is a good thing :-). +************************************************************************/ + +BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, struct in_addr ip) +{ + XFILE *xfp = NULL; + char *fname = talloc_asprintf(NULL, "%s/smb_krb5.conf.%s", lp_private_dir(), domain); + char *file_contents = NULL; + size_t flen = 0; + + if (!fname) { + return False; + } + + file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n" + "[realms]\n\t%s = {\n" + "\t\tkdc = %s\n]\n", + realm, realm, inet_ntoa(ip)); + + if (!file_contents) { + TALLOC_FREE(fname); + return False; + } + + flen = strlen(file_contents); + xfp = x_fopen(fname, O_CREAT|O_WRONLY, 0600); + if (!xfp) { + TALLOC_FREE(fname); + return False; + } + /* Lock the file. */ + if (!fcntl_lock(xfp->fd, F_SETLKW, 0, 1, F_WRLCK)) { + unlink(fname); + x_fclose(xfp); + TALLOC_FREE(fname); + return False; + } + + if (x_fwrite(file_contents, flen, 1, xfp) != flen) { + unlink(fname); + x_fclose(xfp); + TALLOC_FREE(fname); + return False; + } + if (x_fclose(xfp)==-1) { + unlink(fname); + TALLOC_FREE(fname); + return False; + } + /* Set the environment variable to this file. */ + setenv("KRB5_CONFIG", fname, 1); + TALLOC_FREE(fname); + return True; +} #endif -- cgit From cceb492250ce7e273cdc48c030048c0879a7265a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Aug 2006 01:27:51 +0000 Subject: r17944: Handle locking madness. Jeremy. (This used to be commit 408267a2d725a0596be37b019fe4513502b2c0ec) --- source3/libads/kerberos.c | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 4e4e4cfebf..46b64ca22d 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -477,6 +477,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do char *fname = talloc_asprintf(NULL, "%s/smb_krb5.conf.%s", lp_private_dir(), domain); char *file_contents = NULL; size_t flen = 0; + int loopcount = 0; if (!fname) { return False; @@ -493,17 +494,37 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do } flen = strlen(file_contents); - xfp = x_fopen(fname, O_CREAT|O_WRONLY, 0600); - if (!xfp) { - TALLOC_FREE(fname); - return False; - } - /* Lock the file. */ - if (!fcntl_lock(xfp->fd, F_SETLKW, 0, 1, F_WRLCK)) { - unlink(fname); - x_fclose(xfp); - TALLOC_FREE(fname); - return False; + + while (loopcount < 10) { + SMB_STRUCT_STAT st; + + xfp = x_fopen(fname, O_CREAT|O_WRONLY, 0600); + if (!xfp) { + TALLOC_FREE(fname); + return False; + } + /* Lock the file. */ + if (!fcntl_lock(xfp->fd, F_SETLKW, 0, 1, F_WRLCK)) { + unlink(fname); + x_fclose(xfp); + TALLOC_FREE(fname); + return False; + } + + /* We got the lock. Is the file still there ? */ + if (sys_stat(fname,&st)==-1) { + if (errno == ENOENT) { + /* Nope - try again up to 10x */ + x_fclose(xfp); + loopcount++; + continue; + } + unlink(fname); + x_fclose(xfp); + TALLOC_FREE(fname); + return False; + } + break; } if (x_fwrite(file_contents, flen, 1, xfp) != flen) { -- cgit From 2fcd113f5507f643fcf80d5a9770ce72aa121ba8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Aug 2006 04:14:08 +0000 Subject: r17945: Store the server and client sitenames in the ADS struct so we can see when they match - only create the ugly krb5 hack when they do. Jeremy. (This used to be commit 9be4ecf24b6b5dacf4c2891bddb072fa7543753f) --- source3/libads/kerberos.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 46b64ca22d..dc85a77304 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -477,16 +477,20 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do char *fname = talloc_asprintf(NULL, "%s/smb_krb5.conf.%s", lp_private_dir(), domain); char *file_contents = NULL; size_t flen = 0; + char *realm_upper = NULL; int loopcount = 0; if (!fname) { return False; } + realm_upper = talloc_strdup(fname, realm); + strupper_m(realm_upper); + file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n" "[realms]\n\t%s = {\n" "\t\tkdc = %s\n]\n", - realm, realm, inet_ntoa(ip)); + realm_upper, realm_upper, inet_ntoa(ip)); if (!file_contents) { TALLOC_FREE(fname); @@ -541,6 +545,11 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do /* Set the environment variable to this file. */ setenv("KRB5_CONFIG", fname, 1); TALLOC_FREE(fname); + + DEBUG(5,("create_local_private_krb5_conf_for_domain: wrote " + "file %s with realm %s KDC = %s\n", + realm_upper, inet_ntoa(ip)); + return True; } #endif -- cgit From a78c61b9cdb535d43cda6de038ec7718e8b24491 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Aug 2006 04:16:13 +0000 Subject: r17946: Fix couple of typos... Jeremy. (This used to be commit 638d53e2ad524dfe4666b79d36997dea8a44c8cd) --- source3/libads/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index dc85a77304..0707427a22 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -548,7 +548,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do DEBUG(5,("create_local_private_krb5_conf_for_domain: wrote " "file %s with realm %s KDC = %s\n", - realm_upper, inet_ntoa(ip)); + fname, realm_upper, inet_ntoa(ip) )); return True; } -- cgit From 0c9ca3fe19249c19ac3525f3e6e19242b3e77f7f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 01:23:08 +0000 Subject: r17994: Add debugs that showed me why my site code wasn't working right. Don't update the server site when we have a client one... Jeremy. (This used to be commit 7acbcf9a6c71f8e7f9167880488613c930cef4d9) --- source3/libads/kerberos.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 0707427a22..fb15ace7c7 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -484,6 +484,9 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do return False; } + DEBUG(10,("create_local_private_krb5_conf_for_domain: fname = %s, realm = %s, domain = %s\n", + fname, realm, domain )); + realm_upper = talloc_strdup(fname, realm); strupper_m(realm_upper); -- cgit From fc6bce6d9ccd5c56ef0bb7c936a724651ef05c4e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 01:33:13 +0000 Subject: r17995: Ensure we create the domain-specific krb5 files in a separate directory. Jeremy. (This used to be commit 541594153b3a29a4ca30f1897264f2cc715b0698) --- source3/libads/kerberos.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index fb15ace7c7..80bc5a6661 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -474,13 +474,27 @@ int kerberos_kinit_password(const char *principal, BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, struct in_addr ip) { XFILE *xfp = NULL; - char *fname = talloc_asprintf(NULL, "%s/smb_krb5.conf.%s", lp_private_dir(), domain); + char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_private_dir()); + char *fname = NULL; char *file_contents = NULL; size_t flen = 0; char *realm_upper = NULL; int loopcount = 0; + if (!dname) { + return False; + } + if (mkdir(dname, 0700)==-1) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: " + "failed to create directory %s. Error was %s\n", + dname, strerror(errno) )); + TALLOC_FREE(dname); + return False; + } + + fname = talloc_asprintf(dname, "%s/krb5.conf.%s", dname, domain); if (!fname) { + TALLOC_FREE(dname); return False; } @@ -496,7 +510,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do realm_upper, realm_upper, inet_ntoa(ip)); if (!file_contents) { - TALLOC_FREE(fname); + TALLOC_FREE(dname); return False; } @@ -507,14 +521,14 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do xfp = x_fopen(fname, O_CREAT|O_WRONLY, 0600); if (!xfp) { - TALLOC_FREE(fname); + TALLOC_FREE(dname); return False; } /* Lock the file. */ if (!fcntl_lock(xfp->fd, F_SETLKW, 0, 1, F_WRLCK)) { unlink(fname); x_fclose(xfp); - TALLOC_FREE(fname); + TALLOC_FREE(dname); return False; } @@ -528,7 +542,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do } unlink(fname); x_fclose(xfp); - TALLOC_FREE(fname); + TALLOC_FREE(dname); return False; } break; @@ -537,17 +551,17 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do if (x_fwrite(file_contents, flen, 1, xfp) != flen) { unlink(fname); x_fclose(xfp); - TALLOC_FREE(fname); + TALLOC_FREE(dname); return False; } if (x_fclose(xfp)==-1) { unlink(fname); - TALLOC_FREE(fname); + TALLOC_FREE(dname); return False; } /* Set the environment variable to this file. */ setenv("KRB5_CONFIG", fname, 1); - TALLOC_FREE(fname); + TALLOC_FREE(dname); DEBUG(5,("create_local_private_krb5_conf_for_domain: wrote " "file %s with realm %s KDC = %s\n", -- cgit From ef92f91cd7fa7c6dfa3c805882083c951cb3add6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 01:34:37 +0000 Subject: r17996: Don't talloc free the memory then reference it. Doh ! Jeremy. (This used to be commit 188eb9794df265e8a55602d46b6bb4bd7daffa7f) --- source3/libads/kerberos.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 80bc5a6661..4ddbf0abc5 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -559,14 +559,15 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do TALLOC_FREE(dname); return False; } - /* Set the environment variable to this file. */ - setenv("KRB5_CONFIG", fname, 1); - TALLOC_FREE(dname); DEBUG(5,("create_local_private_krb5_conf_for_domain: wrote " "file %s with realm %s KDC = %s\n", fname, realm_upper, inet_ntoa(ip) )); + /* Set the environment variable to this file. */ + setenv("KRB5_CONFIG", fname, 1); + TALLOC_FREE(dname); + return True; } #endif -- cgit From d62c3cff518ffd701b967bb12b487f097b550c38 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 02:04:41 +0000 Subject: r17997: Ensure lockdir exists for winbindd. Store tmp krb5.conf files under lockdir, not privatedir. Jeremy. (This used to be commit c59eff3e53f5bfae3a9fb136e8566628339863ad) --- source3/libads/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 4ddbf0abc5..a077ce1fce 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -474,7 +474,7 @@ int kerberos_kinit_password(const char *principal, BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, struct in_addr ip) { XFILE *xfp = NULL; - char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_private_dir()); + char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_lockdir()); char *fname = NULL; char *file_contents = NULL; size_t flen = 0; -- cgit From 1bd715d9155428afee678fd202483e519820c6df Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 03:42:55 +0000 Subject: r17999: No need to prevent others from reading. Use 755 instead of 700, and 644 instead of 600. Reading might help debugging. Jeremy. (This used to be commit 99f100cfecb53e00d17f7426251a3d4022db791a) --- source3/libads/kerberos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index a077ce1fce..79196f87a7 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -484,7 +484,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do if (!dname) { return False; } - if (mkdir(dname, 0700)==-1) { + if (mkdir(dname, 0755)==-1) { DEBUG(0,("create_local_private_krb5_conf_for_domain: " "failed to create directory %s. Error was %s\n", dname, strerror(errno) )); @@ -519,7 +519,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do while (loopcount < 10) { SMB_STRUCT_STAT st; - xfp = x_fopen(fname, O_CREAT|O_WRONLY, 0600); + xfp = x_fopen(fname, O_CREAT|O_WRONLY, 0644); if (!xfp) { TALLOC_FREE(dname); return False; -- cgit From e05728b6693fb5dcac946e2f278dd09193a680c6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 04:46:27 +0000 Subject: r18000: Get nelem/size args right for x_fwrite. Jeremy. (This used to be commit f1c5409b9fa201c6d726857b02515167b0d7cef1) --- source3/libads/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 79196f87a7..41c1dc00f5 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -548,7 +548,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do break; } - if (x_fwrite(file_contents, flen, 1, xfp) != flen) { + if (x_fwrite(file_contents, 1, flen, xfp) != flen) { unlink(fname); x_fclose(xfp); TALLOC_FREE(dname); -- cgit From d31ee84d888145ca0c89a201befb32def65c5995 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 04:50:08 +0000 Subject: r18001: Proper error reporting on write/close fail. Jeremy. (This used to be commit ba311ac4eac060c12cafeeb8e458f45c2927aabf) --- source3/libads/kerberos.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 41c1dc00f5..fa07602c58 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -478,6 +478,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do char *fname = NULL; char *file_contents = NULL; size_t flen = 0; + size_t ret; char *realm_upper = NULL; int loopcount = 0; @@ -548,13 +549,18 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do break; } - if (x_fwrite(file_contents, 1, flen, xfp) != flen) { + ret = x_fwrite(file_contents, 1, flen, xfp); + if (flen != ret) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: x_fwrite failed," + " returned %u. Errno %s\n", (unsigned int)ret, strerror(errno) )); unlink(fname); x_fclose(xfp); TALLOC_FREE(dname); return False; } if (x_fclose(xfp)==-1) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: x_fclose failed." + " Errno %s\n", strerror(errno) )); unlink(fname); TALLOC_FREE(dname); return False; -- cgit From 0a847b4111c6f5979910bba574e8ab1c86deec88 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 04:53:04 +0000 Subject: r18002: Improved debug. Jeremy. (This used to be commit 5f84c8c815ff0c941ef06d682dcc4be52e8867d2) --- source3/libads/kerberos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index fa07602c58..1d44c28a3c 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -552,7 +552,8 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do ret = x_fwrite(file_contents, 1, flen, xfp); if (flen != ret) { DEBUG(0,("create_local_private_krb5_conf_for_domain: x_fwrite failed," - " returned %u. Errno %s\n", (unsigned int)ret, strerror(errno) )); + " returned %u (should be %u). Errno %s\n", + (unsigned int)ret, (unsigned int)flen, strerror(errno) )); unlink(fname); x_fclose(xfp); TALLOC_FREE(dname); -- cgit From b05c81a184d8763e5f0e25642d7ec4bf80ae8466 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 05:55:47 +0000 Subject: r18003: Creating a directory and getting EEXIST isn't an error. Jeremy. (This used to be commit 515f86167bd9ec64170218f2ea4fb20d12a28365) --- source3/libads/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 1d44c28a3c..a7c9e3dcba 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -485,7 +485,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do if (!dname) { return False; } - if (mkdir(dname, 0755)==-1) { + if ((mkdir(dname, 0755)==-1) && (errno != EEXIST)) { DEBUG(0,("create_local_private_krb5_conf_for_domain: " "failed to create directory %s. Error was %s\n", dname, strerror(errno) )); -- cgit From d0bbe3751a2bc23fc9fa1428423ef2856fb9868e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 06:28:48 +0000 Subject: r18004: If you're writing out a krb5.conf, at least get the syntax right... :-). Jeremy. (This used to be commit ecca467e463ef5c9acd48ee0a5f446755bd2f306) --- source3/libads/kerberos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index a7c9e3dcba..4801aec23e 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -505,9 +505,9 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do realm_upper = talloc_strdup(fname, realm); strupper_m(realm_upper); - file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n" + file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n\n" "[realms]\n\t%s = {\n" - "\t\tkdc = %s\n]\n", + "\t\tkdc = %s\n\t}\n", realm_upper, realm_upper, inet_ntoa(ip)); if (!file_contents) { -- cgit From 0f1bc28744d8c7cae2fe2774b50fc4336408a74d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 19:27:44 +0000 Subject: r18006: Actually a smaller change than it looks. Leverage the get_dc_list code to get the _kerberos. names for site support. This way we don't depend on one KDC to do ticket refresh. Even though we know it's up when we add it, it may go down when we're trying to refresh. Jeremy. (This used to be commit 77fe2a3d7418012a8dbfb6aaeb2a8dd57c6e1a5d) --- source3/libads/kerberos.c | 51 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 4801aec23e..c872508fe8 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -464,6 +464,46 @@ int kerberos_kinit_password(const char *principal, 0); } +/************************************************************************ + Create a string list of available kdc's, possibly searching by sitename. + Does DNS queries. +************************************************************************/ + +static char *get_kdc_ip_string(char *mem_ctx, const char *realm, struct in_addr primary_ip) +{ + struct ip_service *ip_srv; + int count, i; + char *kdc_str = talloc_asprintf(mem_ctx, "\tkdc = %s\n", + inet_ntoa(primary_ip)); + + if (kdc_str == NULL) { + return NULL; + } + + if (!NT_STATUS_IS_OK(get_kdc_list(realm, &ip_srv, &count))) { + DEBUG(10,("get_kdc_ip_string: get_kdc_list failed. Returning %s\n", + kdc_str )); + return kdc_str; + } + + for (i = 0; i < count; i++) { + if (ip_equal(ip_srv[i].ip, primary_ip)) { + continue; + } + /* Append to the string - inefficient but not done often. */ + kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", + kdc_str, inet_ntoa(ip_srv[i].ip)); + if (!kdc_str) { + return NULL; + } + } + + DEBUG(10,("get_kdc_ip_string: Returning %s\n", + kdc_str )); + + return kdc_str; +} + /************************************************************************ Create a specific krb5.conf file in the private directory pointing at a specific kdc for a realm. Keyed off domain name. Sets @@ -477,6 +517,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_lockdir()); char *fname = NULL; char *file_contents = NULL; + char *kdc_ip_string; size_t flen = 0; size_t ret; char *realm_upper = NULL; @@ -505,10 +546,16 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do realm_upper = talloc_strdup(fname, realm); strupper_m(realm_upper); + kdc_ip_string = get_kdc_ip_string(dname, realm, ip); + if (!kdc_ip_string) { + TALLOC_FREE(dname); + return False; + } + file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n\n" "[realms]\n\t%s = {\n" - "\t\tkdc = %s\n\t}\n", - realm_upper, realm_upper, inet_ntoa(ip)); + "\t\t%s\t}\n", + realm_upper, realm_upper, kdc_ip_string); if (!file_contents) { TALLOC_FREE(dname); -- cgit From fea5d59b8411244b31df7980bdcdab9ed20dc712 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 23:06:21 +0000 Subject: r18010: Ensure we don't timeout twice to the same server in winbindd when it's down and listed in the -ve connection cache. Fix memory leak, reduce timeout for cldap calls - minimum 3 secs. Jeremy. (This used to be commit 10b32cb6de234fa17fdd691bb294864d4d40f782) --- source3/libads/kerberos.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index c872508fe8..57233f2182 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -494,10 +494,13 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, struct in_addr kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", kdc_str, inet_ntoa(ip_srv[i].ip)); if (!kdc_str) { + SAFE_FREE(ip_srv); return NULL; } } + SAFE_FREE(ip_srv); + DEBUG(10,("get_kdc_ip_string: Returning %s\n", kdc_str )); -- cgit From 6d4c7b13450f2c302a267f42c1b8bf1e8a30b639 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Sep 2006 04:01:11 +0000 Subject: r18200: Experimental code to allow system /etc/krb5.conf to be overwritten by winbindd. Don't enable this :-). Jeremy. (This used to be commit 88e11ee91a2e97c93f5d34313d45b1e38f793038) --- source3/libads/kerberos.c | 105 +++++++++++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 42 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 57233f2182..d2a2c806a9 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -516,15 +516,15 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, struct in_addr BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, struct in_addr ip) { - XFILE *xfp = NULL; char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_lockdir()); + char *tmpname = NULL; char *fname = NULL; char *file_contents = NULL; char *kdc_ip_string; size_t flen = 0; - size_t ret; + ssize_t ret; + int fd; char *realm_upper = NULL; - int loopcount = 0; if (!dname) { return False; @@ -537,6 +537,12 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do return False; } + tmpname = talloc_asprintf(dname, "%s/smb_tmp_krb5.XXXXXX", lp_lockdir()); + if (!tmpname) { + TALLOC_FREE(dname); + return False; + } + fname = talloc_asprintf(dname, "%s/krb5.conf.%s", dname, domain); if (!fname) { TALLOC_FREE(dname); @@ -567,52 +573,36 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do flen = strlen(file_contents); - while (loopcount < 10) { - SMB_STRUCT_STAT st; - - xfp = x_fopen(fname, O_CREAT|O_WRONLY, 0644); - if (!xfp) { - TALLOC_FREE(dname); - return False; - } - /* Lock the file. */ - if (!fcntl_lock(xfp->fd, F_SETLKW, 0, 1, F_WRLCK)) { - unlink(fname); - x_fclose(xfp); - TALLOC_FREE(dname); - return False; - } - - /* We got the lock. Is the file still there ? */ - if (sys_stat(fname,&st)==-1) { - if (errno == ENOENT) { - /* Nope - try again up to 10x */ - x_fclose(xfp); - loopcount++; - continue; - } - unlink(fname); - x_fclose(xfp); - TALLOC_FREE(dname); - return False; - } - break; + fd = smb_mkstemp(tmpname); + if (fd == -1) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: smb_mkstemp failed," + " for file %s. Errno %s\n", + tmpname, strerror(errno) )); } - ret = x_fwrite(file_contents, 1, flen, xfp); + ret = write(fd, file_contents, flen); if (flen != ret) { - DEBUG(0,("create_local_private_krb5_conf_for_domain: x_fwrite failed," - " returned %u (should be %u). Errno %s\n", - (unsigned int)ret, (unsigned int)flen, strerror(errno) )); - unlink(fname); - x_fclose(xfp); + DEBUG(0,("create_local_private_krb5_conf_for_domain: write failed," + " returned %d (should be %u). Errno %s\n", + (int)ret, (unsigned int)flen, strerror(errno) )); + unlink(tmpname); + close(fd); TALLOC_FREE(dname); return False; } - if (x_fclose(xfp)==-1) { - DEBUG(0,("create_local_private_krb5_conf_for_domain: x_fclose failed." + if (close(fd)==-1) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: close failed." " Errno %s\n", strerror(errno) )); - unlink(fname); + unlink(tmpname); + TALLOC_FREE(dname); + return False; + } + + if (rename(tmpname, fname) == -1) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: rename " + "of %s to %s failed. Errno %s\n", + tmpname, fname, strerror(errno) )); + unlink(tmpname); TALLOC_FREE(dname); return False; } @@ -623,6 +613,37 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do /* Set the environment variable to this file. */ setenv("KRB5_CONFIG", fname, 1); + +#if defined(OVERWRITE_SYSTEM_KRB5_CONF) + + /* Insanity, sheer insanity..... */ + + if (symlink(fname, "/etc/krb5.conf") == -1) { + if (errno != EEXIST) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: symlink " + "of %s to /etc/krb5.conf failed. Errno %s\n", + fname, strerror(errno) )); + TALLOC_FREE(dname); + return True; /* Not a fatal error. */ + } + + if (unlink("/etc/krb5.conf") == -1) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: unlink " + "of /etc/krb5.conf failed. Errno %s\n", + strerror(errno) )); + TALLOC_FREE(dname); + return True; /* Not a fatal error. */ + } + if (symlink(fname, "/etc/krb5.conf") == -1) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: " + "forced symlink of %s to /etc/krb5.conf failed. Errno %s\n", + fname, strerror(errno) )); + TALLOC_FREE(dname); + return True; /* Not a fatal error. */ + } + } +#endif + TALLOC_FREE(dname); return True; -- cgit From 253c01f29ee8b0287eb47a29683a54ec846d142e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Sep 2006 04:17:23 +0000 Subject: r18201: Make explicit what's going on here. Jeremy. (This used to be commit 38b8a2b5278d2538b9803c2b81f767036a16ad65) --- source3/libads/kerberos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index d2a2c806a9..40c3019a31 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -520,7 +520,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do char *tmpname = NULL; char *fname = NULL; char *file_contents = NULL; - char *kdc_ip_string; + char *kdc_ip_string = NULL; size_t flen = 0; ssize_t ret; int fd; @@ -627,6 +627,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do return True; /* Not a fatal error. */ } + /* Yes, this is a race conditon... too bad. */ if (unlink("/etc/krb5.conf") == -1) { DEBUG(0,("create_local_private_krb5_conf_for_domain: unlink " "of /etc/krb5.conf failed. Errno %s\n", -- cgit From 80052bcf13cbac8ac54aacc5dc004a5b5fd4b01e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Sep 2006 17:29:23 +0000 Subject: r18225: If we're going to overwrite krb5.conf, at least be polite enough to make a backup. Jeremy. (This used to be commit c82aac594fd7262029f9c47c2998c9e6b0ffc739) --- source3/libads/kerberos.c | 62 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 20 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 40c3019a31..a0685b8a1c 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -616,31 +616,53 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do #if defined(OVERWRITE_SYSTEM_KRB5_CONF) +#define SYSTEM_KRB5_CONF_PATH "/etc/krb5.conf" /* Insanity, sheer insanity..... */ - if (symlink(fname, "/etc/krb5.conf") == -1) { - if (errno != EEXIST) { - DEBUG(0,("create_local_private_krb5_conf_for_domain: symlink " - "of %s to /etc/krb5.conf failed. Errno %s\n", - fname, strerror(errno) )); - TALLOC_FREE(dname); - return True; /* Not a fatal error. */ - } - /* Yes, this is a race conditon... too bad. */ - if (unlink("/etc/krb5.conf") == -1) { - DEBUG(0,("create_local_private_krb5_conf_for_domain: unlink " - "of /etc/krb5.conf failed. Errno %s\n", - strerror(errno) )); + { + pstring linkpath; + int lret; + + lret = readlink(SYSTEM_KRB5_CONF_PATH, linkpath, sizeof(linkpath)-1); + linkpath[sizeof(pstring)-1] = '\0'; + + if (lret == 0 || strcmp(linkpath, fname) == 0) { + /* Symlink already exists. */ TALLOC_FREE(dname); - return True; /* Not a fatal error. */ + return True; } - if (symlink(fname, "/etc/krb5.conf") == -1) { - DEBUG(0,("create_local_private_krb5_conf_for_domain: " - "forced symlink of %s to /etc/krb5.conf failed. Errno %s\n", - fname, strerror(errno) )); - TALLOC_FREE(dname); - return True; /* Not a fatal error. */ + + /* Try and replace with a symlink. */ + if (symlink(fname, SYSTEM_KRB5_CONF_PATH) == -1) { + if (errno != EEXIST) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: symlink " + "of %s to %s failed. Errno %s\n", + fname, SYSTEM_KRB5_CONF_PATH, strerror(errno) )); + TALLOC_FREE(dname); + return True; /* Not a fatal error. */ + } + + pstrcpy(linkpath, SYSTEM_KRB5_CONF_PATH); + pstrcat(linkpath, ".saved"); + + /* Yes, this is a race conditon... too bad. */ + if (rename(SYSTEM_KRB5_CONF_PATH, linkpath) == -1) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: rename " + "of %s to %s failed. Errno %s\n", + SYSTEM_KRB5_CONF_PATH, linkpath, + strerror(errno) )); + TALLOC_FREE(dname); + return True; /* Not a fatal error. */ + } + + if (symlink(fname, "/etc/krb5.conf") == -1) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: " + "forced symlink of %s to /etc/krb5.conf failed. Errno %s\n", + fname, strerror(errno) )); + TALLOC_FREE(dname); + return True; /* Not a fatal error. */ + } } } #endif -- cgit From 34a25efad28d47db49fe5bd0db08f7988e11bb29 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Sep 2006 18:34:02 +0000 Subject: r18226: Ensure we only do this evil thing if it's our realm. Jeremy. (This used to be commit 0a89b37b1a367470be410ae94b42c813c7dbefe6) --- source3/libads/kerberos.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index a0685b8a1c..7eb0bdc145 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -619,8 +619,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do #define SYSTEM_KRB5_CONF_PATH "/etc/krb5.conf" /* Insanity, sheer insanity..... */ - - { + if (strequal(realm, lp_realm())) { pstring linkpath; int lret; -- cgit From 6cfe7be80e7eb2153d7fb503076d84177da7ad4c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Sep 2006 01:16:01 +0000 Subject: r18241: If replacing the krb5.conf, ensure it's readable. Jeremy. (This used to be commit dfd93a30311ff0e57ef23ae1f1cb58d4019a3eee) --- source3/libads/kerberos.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 7eb0bdc145..6374c515ad 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -580,6 +580,16 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do tmpname, strerror(errno) )); } + if (fchmod(fd, 0644)==-1) { + DEBUG(0,("create_local_private_krb5_conf_for_domain: fchmod failed for %s." + " Errno %s\n", + tmpname, strerror(errno) )); + unlink(tmpname); + close(fd); + TALLOC_FREE(dname); + return False; + } + ret = write(fd, file_contents, flen); if (flen != ret) { DEBUG(0,("create_local_private_krb5_conf_for_domain: write failed," -- cgit From 2ad8c705b238e8ebb87fed51b962b4e165c1202f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 14 Sep 2006 10:21:46 +0000 Subject: r18512: Add krb5conf file environment to debug statement. Guenther (This used to be commit 398f368c8a2df36d522583c733f7c22cac2f2059) --- source3/libads/kerberos.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 6374c515ad..76866a8093 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -86,8 +86,9 @@ int kerberos_kinit_password_ext(const char *principal, krb5_set_real_time(ctx, time(NULL) + time_offset, 0); } - DEBUG(10,("kerberos_kinit_password: using %s as ccache\n", - cache_name ? cache_name: krb5_cc_default_name(ctx))); + DEBUG(10,("kerberos_kinit_password: using [%s] as ccache and config [%s]\n", + cache_name ? cache_name: krb5_cc_default_name(ctx), + getenv("KRB5_CONFIG"))); if ((code = krb5_cc_resolve(ctx, cache_name ? cache_name : krb5_cc_default_name(ctx), &cc))) { krb5_free_context(ctx); -- cgit From bfd099e148ed97394bc858e746a1a998a71ac43c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 Jan 2007 18:25:35 +0000 Subject: r20857: Silence gives assent :-). Checking in the fix for site support in a network where many DC's are down. I heard via Volker there is still a bug w.r.t the wrong site being chosen with trusted domains but we'll have to layer that fix on top of this. Gd - complain if this doesn't work for you. Jeremy. (This used to be commit 97e248f89ac6548274f03f2ae7583a255da5ddb3) --- source3/libads/kerberos.c | 65 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 14 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 76866a8093..95eed6fe27 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -470,10 +470,11 @@ int kerberos_kinit_password(const char *principal, Does DNS queries. ************************************************************************/ -static char *get_kdc_ip_string(char *mem_ctx, const char *realm, struct in_addr primary_ip) +static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sitename, struct in_addr primary_ip) { - struct ip_service *ip_srv; - int count, i; + struct ip_service *ip_srv_site; + struct ip_service *ip_srv_nonsite; + int count_site, count_nonsite, i; char *kdc_str = talloc_asprintf(mem_ctx, "\tkdc = %s\n", inet_ntoa(primary_ip)); @@ -481,26 +482,61 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, struct in_addr return NULL; } - if (!NT_STATUS_IS_OK(get_kdc_list(realm, &ip_srv, &count))) { - DEBUG(10,("get_kdc_ip_string: get_kdc_list failed. Returning %s\n", - kdc_str )); - return kdc_str; + /* Get the KDC's only in this site. */ + + get_kdc_list(realm, sitename, &ip_srv_site, &count_site); + + for (i = 0; i < count_site; i++) { + if (ip_equal(ip_srv_site[i].ip, primary_ip)) { + continue; + } + /* Append to the string - inefficient but not done often. */ + kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", + kdc_str, inet_ntoa(ip_srv_site[i].ip)); + if (!kdc_str) { + SAFE_FREE(ip_srv_site); + return NULL; + } } - for (i = 0; i < count; i++) { - if (ip_equal(ip_srv[i].ip, primary_ip)) { + /* Get all KDC's. */ + + get_kdc_list(realm, NULL, &ip_srv_nonsite, &count_nonsite); + + for (i = 0; i < count_nonsite; i++) { + int j; + + if (ip_equal(ip_srv_nonsite[i].ip, primary_ip)) { + continue; + } + + /* Ensure this isn't an IP already seen (YUK! this is n*n....) */ + for (j = 0; j < count_site; j++) { + if (ip_equal(ip_srv_nonsite[i].ip, ip_srv_site[j].ip)) { + break; + } + /* As the lists are sorted we can break early if nonsite > site. */ + if (ip_service_compare(&ip_srv_nonsite[i], &ip_srv_site[j]) > 0) { + break; + } + } + if (j != i) { continue; } + /* Append to the string - inefficient but not done often. */ kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", - kdc_str, inet_ntoa(ip_srv[i].ip)); + kdc_str, inet_ntoa(ip_srv_nonsite[i].ip)); if (!kdc_str) { - SAFE_FREE(ip_srv); + SAFE_FREE(ip_srv_site); + SAFE_FREE(ip_srv_nonsite); return NULL; } } - SAFE_FREE(ip_srv); + + SAFE_FREE(ip_srv_site); + SAFE_FREE(ip_srv_nonsite); DEBUG(10,("get_kdc_ip_string: Returning %s\n", kdc_str )); @@ -515,7 +551,8 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, struct in_addr run as root or will fail (which is a good thing :-). ************************************************************************/ -BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, struct in_addr ip) +BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, + const char *sitename, struct in_addr ip) { char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_lockdir()); char *tmpname = NULL; @@ -556,7 +593,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do realm_upper = talloc_strdup(fname, realm); strupper_m(realm_upper); - kdc_ip_string = get_kdc_ip_string(dname, realm, ip); + kdc_ip_string = get_kdc_ip_string(dname, realm, sitename, ip); if (!kdc_ip_string) { TALLOC_FREE(dname); return False; -- cgit From f3ad8bb00acf680863902721c57091d2bf622b72 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 17 Jan 2007 19:11:45 +0000 Subject: r20860: Adding some small tweaks. When we have no sitename, there is no need to ask for the list of DCs twice. Guenther (This used to be commit a9baf27e1348dd6dadd7a2fafdf9c269087b80ac) --- source3/libads/kerberos.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 95eed6fe27..d35b59f4cd 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -484,18 +484,21 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit /* Get the KDC's only in this site. */ - get_kdc_list(realm, sitename, &ip_srv_site, &count_site); + if (sitename) { - for (i = 0; i < count_site; i++) { - if (ip_equal(ip_srv_site[i].ip, primary_ip)) { - continue; - } - /* Append to the string - inefficient but not done often. */ - kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", - kdc_str, inet_ntoa(ip_srv_site[i].ip)); - if (!kdc_str) { - SAFE_FREE(ip_srv_site); - return NULL; + get_kdc_list(realm, sitename, &ip_srv_site, &count_site); + + for (i = 0; i < count_site; i++) { + if (ip_equal(ip_srv_site[i].ip, primary_ip)) { + continue; + } + /* Append to the string - inefficient but not done often. */ + kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", + kdc_str, inet_ntoa(ip_srv_site[i].ip)); + if (!kdc_str) { + SAFE_FREE(ip_srv_site); + return NULL; + } } } -- cgit From 1898eaddb805e86d0c36bd289e7fa61d7bbd4810 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 1 Feb 2007 15:10:13 +0000 Subject: r21110: Fix kinit with Heimdal (Bug #4226). Guenther (This used to be commit ea38e1f8362d75e7ac058a7c4aa06f1ca92ec108) --- source3/libads/kerberos.c | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index d35b59f4cd..3d4b8cbcf8 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -75,7 +75,7 @@ int kerberos_kinit_password_ext(const char *principal, krb5_ccache cc = NULL; krb5_principal me; krb5_creds my_creds; - krb5_get_init_creds_opt opt; + krb5_get_init_creds_opt *opt = NULL; smb_krb5_addresses *addr = NULL; initialize_krb5_error_table(); @@ -96,47 +96,60 @@ int kerberos_kinit_password_ext(const char *principal, } if ((code = smb_krb5_parse_name(ctx, principal, &me))) { + krb5_cc_close(ctx, cc); krb5_free_context(ctx); return code; } - krb5_get_init_creds_opt_init(&opt); - krb5_get_init_creds_opt_set_renew_life(&opt, renewable_time); - krb5_get_init_creds_opt_set_forwardable(&opt, 1); - - if (request_pac) { + code = krb5_get_init_creds_opt_alloc(ctx, &opt); + if (code) { + krb5_cc_close(ctx, cc); + krb5_free_context(ctx); + return code; + } + + krb5_get_init_creds_opt_set_renew_life(opt, renewable_time); + krb5_get_init_creds_opt_set_forwardable(opt, True); + #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST - code = krb5_get_init_creds_opt_set_pac_request(ctx, &opt, True); + if (request_pac) { + code = krb5_get_init_creds_opt_set_pac_request(ctx, opt, (krb5_boolean)request_pac); if (code) { + krb5_cc_close(ctx, cc); krb5_free_principal(ctx, me); krb5_free_context(ctx); return code; } -#endif } - +#endif if (add_netbios_addr) { code = smb_krb5_gen_netbios_krb5_address(&addr); if (code) { + krb5_cc_close(ctx, cc); krb5_free_principal(ctx, me); krb5_free_context(ctx); return code; } - krb5_get_init_creds_opt_set_address_list(&opt, addr->addrs); + krb5_get_init_creds_opt_set_address_list(opt, addr->addrs); } if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), - kerb_prompter, NULL, 0, NULL, &opt))) + kerb_prompter, NULL, 0, NULL, opt))) { + krb5_get_init_creds_opt_free(opt); smb_krb5_free_addresses(ctx, addr); + krb5_cc_close(ctx, cc); krb5_free_principal(ctx, me); - krb5_free_context(ctx); + krb5_free_context(ctx); return code; } - + + krb5_get_init_creds_opt_free(opt); + if ((code = krb5_cc_initialize(ctx, cc, me))) { smb_krb5_free_addresses(ctx, addr); krb5_free_cred_contents(ctx, &my_creds); + krb5_cc_close(ctx, cc); krb5_free_principal(ctx, me); krb5_free_context(ctx); return code; -- cgit From aad88ee34f8831891a96da7e462214c6cf1a3b0d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 8 Feb 2007 13:50:47 +0000 Subject: r21238: Fix tab indent in self-written krb5.confs. Guenther (This used to be commit 4df582fa1049afe96bbee7e8cab93cfa82208ba3) --- source3/libads/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 3d4b8cbcf8..92461bd9c1 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -617,7 +617,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n\n" "[realms]\n\t%s = {\n" - "\t\t%s\t}\n", + "\t%s\t}\n", realm_upper, realm_upper, kdc_ip_string); if (!file_contents) { -- cgit From 69cee2a3ec4f39aab83a8cbf55307df182bf3065 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 8 Feb 2007 17:02:39 +0000 Subject: r21240: Fix longstanding Bug #4009. For the winbind cached ADS LDAP connection handling (ads_cached_connection()) we were (incorrectly) assuming that the service ticket lifetime equaled the tgt lifetime. For setups where the service ticket just lives 10 minutes, we were leaving hundreds of LDAP connections in CLOSE_WAIT state, until we fail to service entirely with "Too many open files". Also sequence_number() in winbindd_ads.c needs to delete the cached LDAP connection after the ads_do_search_retry() has failed to submit the search request (although the bind succeeded (returning an expired service ticket that we cannot delete from the memory cred cache - this will get fixed later)). Guenther (This used to be commit 7e1a84b7226fb8dcd5d34c64a3478a6d886a9a91) --- source3/libads/kerberos.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 92461bd9c1..8e8297b07e 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -110,6 +110,10 @@ int kerberos_kinit_password_ext(const char *principal, krb5_get_init_creds_opt_set_renew_life(opt, renewable_time); krb5_get_init_creds_opt_set_forwardable(opt, True); +#if 0 + /* insane testing */ + krb5_get_init_creds_opt_set_tkt_life(opt, 60); +#endif #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST if (request_pac) { @@ -216,7 +220,7 @@ int ads_kinit_password(ADS_STRUCT *ads) } ret = kerberos_kinit_password_ext(s, ads->auth.password, ads->auth.time_offset, - &ads->auth.expire, NULL, NULL, False, False, ads->auth.renewable); + &ads->auth.tgt_expire, NULL, NULL, False, False, ads->auth.renewable); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", -- cgit From 3adeb4274250ec4420d9d874b07d8e688a354402 Mon Sep 17 00:00:00 2001 From: James Peach Date: Fri, 9 Mar 2007 18:51:48 +0000 Subject: r21778: Wrap calls to krb5_get_init_creds_opt_free to handle the different calling convention in the latest MIT changes. Apparantly Heimdal is also changing to this calling convention. (This used to be commit c29c69d2df377fabb88a78e6f5237de106d5c2c5) --- source3/libads/kerberos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 8e8297b07e..1c0e85dd55 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -140,7 +140,7 @@ int kerberos_kinit_password_ext(const char *principal, if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), kerb_prompter, NULL, 0, NULL, opt))) { - krb5_get_init_creds_opt_free(opt); + smb_krb5_get_init_creds_opt_free(ctx, opt); smb_krb5_free_addresses(ctx, addr); krb5_cc_close(ctx, cc); krb5_free_principal(ctx, me); @@ -148,7 +148,7 @@ int kerberos_kinit_password_ext(const char *principal, return code; } - krb5_get_init_creds_opt_free(opt); + smb_krb5_get_init_creds_opt_free(ctx, opt); if ((code = krb5_cc_initialize(ctx, cc, me))) { smb_krb5_free_addresses(ctx, addr); -- cgit From 98e58694eed08f24e9d243445655aa0105b98ecc Mon Sep 17 00:00:00 2001 From: James Peach Date: Fri, 9 Mar 2007 19:28:35 +0000 Subject: r21779: I missd a call to krb5_get_init_creds_opt_alloc in r21778. (This used to be commit 4f6c2826aa1ac240b02122a40fe9a1ccabaaaf27) --- source3/libads/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 1c0e85dd55..b6627075b0 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -101,7 +101,7 @@ int kerberos_kinit_password_ext(const char *principal, return code; } - code = krb5_get_init_creds_opt_alloc(ctx, &opt); + code = smb_krb5_get_init_creds_opt_alloc(ctx, &opt); if (code) { krb5_cc_close(ctx, cc); krb5_free_context(ctx); -- cgit From 6288491e90e542c02857935a528e9765a636cf2a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 4 May 2007 09:46:17 +0000 Subject: r22663: Restructure kerberos_kinit_password_ext() error path. Guenther (This used to be commit 997ded4e3f0dc2199b9a66a9485c919c16fbabc6) --- source3/libads/kerberos.c | 86 ++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 53 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index b6627075b0..72ff2cbdab 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -73,14 +73,16 @@ int kerberos_kinit_password_ext(const char *principal, krb5_context ctx = NULL; krb5_error_code code = 0; krb5_ccache cc = NULL; - krb5_principal me; + krb5_principal me = NULL; krb5_creds my_creds; krb5_get_init_creds_opt *opt = NULL; smb_krb5_addresses *addr = NULL; + ZERO_STRUCT(my_creds); + initialize_krb5_error_table(); if ((code = krb5_init_context(&ctx))) - return code; + goto out; if (time_offset != 0) { krb5_set_real_time(ctx, time(NULL) + time_offset, 0); @@ -91,21 +93,15 @@ int kerberos_kinit_password_ext(const char *principal, getenv("KRB5_CONFIG"))); if ((code = krb5_cc_resolve(ctx, cache_name ? cache_name : krb5_cc_default_name(ctx), &cc))) { - krb5_free_context(ctx); - return code; + goto out; } if ((code = smb_krb5_parse_name(ctx, principal, &me))) { - krb5_cc_close(ctx, cc); - krb5_free_context(ctx); - return code; + goto out; } - code = smb_krb5_get_init_creds_opt_alloc(ctx, &opt); - if (code) { - krb5_cc_close(ctx, cc); - krb5_free_context(ctx); - return code; + if ((code = smb_krb5_get_init_creds_opt_alloc(ctx, &opt))) { + goto out; } krb5_get_init_creds_opt_set_renew_life(opt, renewable_time); @@ -117,55 +113,29 @@ int kerberos_kinit_password_ext(const char *principal, #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST if (request_pac) { - code = krb5_get_init_creds_opt_set_pac_request(ctx, opt, (krb5_boolean)request_pac); - if (code) { - krb5_cc_close(ctx, cc); - krb5_free_principal(ctx, me); - krb5_free_context(ctx); - return code; + if ((code = krb5_get_init_creds_opt_set_pac_request(ctx, opt, (krb5_boolean)request_pac))) { + goto out; } } #endif if (add_netbios_addr) { - code = smb_krb5_gen_netbios_krb5_address(&addr); - if (code) { - krb5_cc_close(ctx, cc); - krb5_free_principal(ctx, me); - krb5_free_context(ctx); - return code; + if ((code = smb_krb5_gen_netbios_krb5_address(&addr))) { + goto out; } krb5_get_init_creds_opt_set_address_list(opt, addr->addrs); } if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), - kerb_prompter, NULL, 0, NULL, opt))) - { - smb_krb5_get_init_creds_opt_free(ctx, opt); - smb_krb5_free_addresses(ctx, addr); - krb5_cc_close(ctx, cc); - krb5_free_principal(ctx, me); - krb5_free_context(ctx); - return code; + kerb_prompter, NULL, 0, NULL, opt))) { + goto out; } - smb_krb5_get_init_creds_opt_free(ctx, opt); - if ((code = krb5_cc_initialize(ctx, cc, me))) { - smb_krb5_free_addresses(ctx, addr); - krb5_free_cred_contents(ctx, &my_creds); - krb5_cc_close(ctx, cc); - krb5_free_principal(ctx, me); - krb5_free_context(ctx); - return code; + goto out; } if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) { - krb5_cc_close(ctx, cc); - smb_krb5_free_addresses(ctx, addr); - krb5_free_cred_contents(ctx, &my_creds); - krb5_free_principal(ctx, me); - krb5_free_context(ctx); - return code; + goto out; } if (expire_time) { @@ -175,14 +145,24 @@ int kerberos_kinit_password_ext(const char *principal, if (renew_till_time) { *renew_till_time = (time_t) my_creds.times.renew_till; } - - krb5_cc_close(ctx, cc); - smb_krb5_free_addresses(ctx, addr); + out: krb5_free_cred_contents(ctx, &my_creds); - krb5_free_principal(ctx, me); - krb5_free_context(ctx); - - return 0; + if (me) { + krb5_free_principal(ctx, me); + } + if (addr) { + smb_krb5_free_addresses(ctx, addr); + } + if (opt) { + smb_krb5_get_init_creds_opt_free(ctx, opt); + } + if (cc) { + krb5_cc_close(ctx, cc); + } + if (ctx) { + krb5_free_context(ctx); + } + return code; } -- cgit From 116c1532e7e8c398a1b22253a361bd88b729fb0f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 4 May 2007 09:55:40 +0000 Subject: r22664: When we have krb5_get_init_creds_opt_get_error() then try to get the NTSTATUS codes directly out of the krb5_error edata. Guenther (This used to be commit dcd902f24a59288bbb7400d59c0afc0c8303ed69) --- source3/libads/kerberos.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 72ff2cbdab..dc3d11a60c 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -55,6 +55,127 @@ kerb_prompter(krb5_context ctx, void *data, return 0; } +static BOOL smb_krb5_err_io_nstatus(TALLOC_CTX *mem_ctx, + DATA_BLOB *edata_blob, + KRB5_EDATA_NTSTATUS *edata) +{ + BOOL ret = False; + prs_struct ps; + + if (!mem_ctx || !edata_blob || !edata) + return False; + + if (!prs_init(&ps, edata_blob->length, mem_ctx, UNMARSHALL)) + return False; + + if (!prs_copy_data_in(&ps, (char *)edata_blob->data, edata_blob->length)) + goto out; + + prs_set_offset(&ps, 0); + + if (!prs_ntstatus("ntstatus", &ps, 1, &edata->ntstatus)) + goto out; + + if (!prs_uint32("unknown1", &ps, 1, &edata->unknown1)) + goto out; + + if (!prs_uint32("unknown2", &ps, 1, &edata->unknown2)) /* only seen 00000001 here */ + goto out; + + ret = True; + out: + prs_mem_free(&ps); + + return ret; +} + + static BOOL smb_krb5_get_ntstatus_from_krb5_error(krb5_error *error, + NTSTATUS *nt_status) +{ + DATA_BLOB edata; + DATA_BLOB unwrapped_edata; + TALLOC_CTX *mem_ctx; + KRB5_EDATA_NTSTATUS parsed_edata; + +#ifdef HAVE_E_DATA_POINTER_IN_KRB5_ERROR + edata = data_blob(error->e_data->data, error->e_data->length); +#else + edata = data_blob(error->e_data.data, error->e_data.length); +#endif /* HAVE_E_DATA_POINTER_IN_KRB5_ERROR */ + +#ifdef DEVELOPER + dump_data(10, edata.data, edata.length); +#endif /* DEVELOPER */ + + mem_ctx = talloc_init("smb_krb5_get_ntstatus_from_krb5_error"); + if (mem_ctx == NULL) { + data_blob_free(&edata); + return False; + } + + if (!unwrap_edata_ntstatus(mem_ctx, &edata, &unwrapped_edata)) { + data_blob_free(&edata); + TALLOC_FREE(mem_ctx); + return False; + } + + data_blob_free(&edata); + + if (!smb_krb5_err_io_nstatus(mem_ctx, &unwrapped_edata, &parsed_edata)) { + data_blob_free(&unwrapped_edata); + TALLOC_FREE(mem_ctx); + return False; + } + + data_blob_free(&unwrapped_edata); + + if (nt_status) { + *nt_status = parsed_edata.ntstatus; + } + + TALLOC_FREE(mem_ctx); + + return True; +} + + static BOOL smb_krb5_get_ntstatus_from_krb5_error_init_creds_opt(krb5_context ctx, + krb5_get_init_creds_opt *opt, + NTSTATUS *nt_status) +{ + BOOL ret = False; + krb5_error *error = NULL; + +#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_GET_ERROR + ret = krb5_get_init_creds_opt_get_error(ctx, opt, &error); + if (ret) { + DEBUG(1,("krb5_get_init_creds_opt_get_error gave: %s\n", + error_message(ret))); + return False; + } +#endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_GET_ERROR */ + + if (!error) { + DEBUG(1,("no krb5_error\n")); + return False; + } + +#ifdef HAVE_E_DATA_POINTER_IN_KRB5_ERROR + if (!error->e_data) { +#else + if (error->e_data.data == NULL) { +#endif /* HAVE_E_DATA_POINTER_IN_KRB5_ERROR */ + DEBUG(1,("no edata in krb5_error\n")); + krb5_free_error(ctx, error); + return False; + } + + ret = smb_krb5_get_ntstatus_from_krb5_error(error, nt_status); + + krb5_free_error(ctx, error); + + return ret; +} + /* simulate a kinit, putting the tgt in the given cache location. If cache_name == NULL place in default cache location. -- cgit From e468268335dd797c540dbd278541340d8c01a7d1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 4 May 2007 10:21:39 +0000 Subject: r22666: Expand kerberos_kinit_password_ext() to return NTSTATUS codes and make winbindd's kerberized pam_auth use that. Guenther (This used to be commit 0f436eab5b2e5891c341c27cb22db52a72bf1af7) --- source3/libads/kerberos.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index dc3d11a60c..c721b56385 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -189,7 +189,8 @@ int kerberos_kinit_password_ext(const char *principal, const char *cache_name, BOOL request_pac, BOOL add_netbios_addr, - time_t renewable_time) + time_t renewable_time, + NTSTATUS *ntstatus) { krb5_context ctx = NULL; krb5_error_code code = 0; @@ -267,6 +268,29 @@ int kerberos_kinit_password_ext(const char *principal, *renew_till_time = (time_t) my_creds.times.renew_till; } out: + if (ntstatus) { + + NTSTATUS status; + + /* fast path */ + if (code == 0) { + *ntstatus = NT_STATUS_OK; + goto cleanup; + } + + /* try to get ntstatus code out of krb5_error when we have it + * inside the krb5_get_init_creds_opt - gd */ + + if (opt && smb_krb5_get_ntstatus_from_krb5_error_init_creds_opt(ctx, opt, &status)) { + *ntstatus = status; + goto cleanup; + } + + /* fall back to self-made-mapping */ + *ntstatus = krb5_to_nt_status(code); + } + + cleanup: krb5_free_cred_contents(ctx, &my_creds); if (me) { krb5_free_principal(ctx, me); @@ -321,7 +345,8 @@ int ads_kinit_password(ADS_STRUCT *ads) } ret = kerberos_kinit_password_ext(s, ads->auth.password, ads->auth.time_offset, - &ads->auth.tgt_expire, NULL, NULL, False, False, ads->auth.renewable); + &ads->auth.tgt_expire, NULL, NULL, False, False, ads->auth.renewable, + NULL); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", @@ -580,7 +605,8 @@ int kerberos_kinit_password(const char *principal, cache_name, False, False, - 0); + 0, + NULL); } /************************************************************************ -- cgit From ad5ff1b8090b225b7ac6d5b7ec08d9f70633db5e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 25 May 2007 22:04:03 +0000 Subject: r23147: Patch #4566 from jacob berkman . Pass password data to krb5_prompter. Jeremy. (This used to be commit 232fc5d69d44404df13f6516864352f9a5721552) --- source3/libads/kerberos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index c721b56385..841674bea5 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -248,7 +248,8 @@ int kerberos_kinit_password_ext(const char *principal, } if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), - kerb_prompter, NULL, 0, NULL, opt))) { + kerb_prompter, CONST_DISCARD(char *,password), + 0, NULL, opt))) { goto out; } -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/libads/kerberos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 841674bea5..ac49408a0a 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -9,7 +9,7 @@ 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 - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/libads/kerberos.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index ac49408a0a..2cf0577687 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -18,8 +18,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From b20269287545926efff02b03642b1920d3afb3e4 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 31 Aug 2007 13:39:51 +0000 Subject: r24836: Initialize some uninitialized variables. This prevents a segfault when get_kdc_ip_string() is called with sitename == NULL. Michael (This used to be commit 58d31e057b57bc69a96e63aabba9aa1da5418d83) --- source3/libads/kerberos.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 2cf0577687..1b5ec88dcf 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -616,9 +616,11 @@ int kerberos_kinit_password(const char *principal, static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sitename, struct in_addr primary_ip) { - struct ip_service *ip_srv_site; - struct ip_service *ip_srv_nonsite; - int count_site, count_nonsite, i; + int i; + struct ip_service *ip_srv_site = NULL; + struct ip_service *ip_srv_nonsite = NULL; + int count_site = 0; + int count_nonsite = 0; char *kdc_str = talloc_asprintf(mem_ctx, "\tkdc = %s\n", inet_ntoa(primary_ip)); -- cgit From 9fa56b9ae9df53b60ff76f4ce08d720ff9a6fc36 Mon Sep 17 00:00:00 2001 From: Lars Müller Date: Sat, 8 Sep 2007 13:53:08 +0000 Subject: r25030: ip_srv_nonsite and count_nonsite are initialized in get_kdc_list() in any case. (This used to be commit 287604a1c7dc7dede4b278de92ad8233f597d0b6) --- source3/libads/kerberos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 1b5ec88dcf..62a4f84e10 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -618,9 +618,9 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit { int i; struct ip_service *ip_srv_site = NULL; - struct ip_service *ip_srv_nonsite = NULL; + struct ip_service *ip_srv_nonsite; int count_site = 0; - int count_nonsite = 0; + int count_nonsite; char *kdc_str = talloc_asprintf(mem_ctx, "\tkdc = %s\n", inet_ntoa(primary_ip)); -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/libads/kerberos.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 62a4f84e10..281ca2fd68 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -54,11 +54,11 @@ kerb_prompter(krb5_context ctx, void *data, return 0; } -static BOOL smb_krb5_err_io_nstatus(TALLOC_CTX *mem_ctx, +static bool smb_krb5_err_io_nstatus(TALLOC_CTX *mem_ctx, DATA_BLOB *edata_blob, KRB5_EDATA_NTSTATUS *edata) { - BOOL ret = False; + bool ret = False; prs_struct ps; if (!mem_ctx || !edata_blob || !edata) @@ -88,7 +88,7 @@ static BOOL smb_krb5_err_io_nstatus(TALLOC_CTX *mem_ctx, return ret; } - static BOOL smb_krb5_get_ntstatus_from_krb5_error(krb5_error *error, + static bool smb_krb5_get_ntstatus_from_krb5_error(krb5_error *error, NTSTATUS *nt_status) { DATA_BLOB edata; @@ -137,11 +137,11 @@ static BOOL smb_krb5_err_io_nstatus(TALLOC_CTX *mem_ctx, return True; } - static BOOL smb_krb5_get_ntstatus_from_krb5_error_init_creds_opt(krb5_context ctx, + static bool smb_krb5_get_ntstatus_from_krb5_error_init_creds_opt(krb5_context ctx, krb5_get_init_creds_opt *opt, NTSTATUS *nt_status) { - BOOL ret = False; + bool ret = False; krb5_error *error = NULL; #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_GET_ERROR @@ -186,8 +186,8 @@ int kerberos_kinit_password_ext(const char *principal, time_t *expire_time, time_t *renew_till_time, const char *cache_name, - BOOL request_pac, - BOOL add_netbios_addr, + bool request_pac, + bool add_netbios_addr, time_t renewable_time, NTSTATUS *ntstatus) { @@ -443,10 +443,10 @@ static char* des_salt_key( void ) /************************************************************************ ************************************************************************/ -BOOL kerberos_secrets_store_des_salt( const char* salt ) +bool kerberos_secrets_store_des_salt( const char* salt ) { char* key; - BOOL ret; + bool ret; if ( (key = des_salt_key()) == NULL ) { DEBUG(0,("kerberos_secrets_store_des_salt: failed to generate key!\n")); @@ -535,12 +535,12 @@ krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, Setting principal to NULL deletes this entry. ************************************************************************/ -BOOL kerberos_secrets_store_salting_principal(const char *service, +bool kerberos_secrets_store_salting_principal(const char *service, int enctype, const char *principal) { char *key = NULL; - BOOL ret = False; + bool ret = False; krb5_context context = NULL; krb5_principal princ = NULL; char *princ_s = NULL; @@ -700,7 +700,7 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit run as root or will fail (which is a good thing :-). ************************************************************************/ -BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, +bool create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, const char *sitename, struct in_addr ip) { char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_lockdir()); -- cgit From f88b7a076be74a29a3bf876b4e2705f4a1ecf42b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 24 Oct 2007 14:16:54 -0700 Subject: This is a large patch (sorry). Migrate from struct in_addr to struct sockaddr_storage in most places that matter (ie. not the nmbd and NetBIOS lookups). This passes make test on an IPv4 box, but I'll have to do more work/testing on IPv6 enabled boxes. This should now give us a framework for testing and finishing the IPv6 migration. It's at the state where someone with a working IPv6 setup should (theorecically) be able to type : smbclient //ipv6-address/share and have it work. Jeremy. (This used to be commit 98e154c3125d5732c37a72d74b0eb5cd7b6155fd) --- source3/libads/kerberos.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 281ca2fd68..f259c21bdb 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -614,7 +614,10 @@ int kerberos_kinit_password(const char *principal, Does DNS queries. ************************************************************************/ -static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sitename, struct in_addr primary_ip) +static char *get_kdc_ip_string(char *mem_ctx, + const char *realm, + const char *sitename, + struct sockaddr_storage *pss) { int i; struct ip_service *ip_srv_site = NULL; @@ -622,7 +625,8 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit int count_site = 0; int count_nonsite; char *kdc_str = talloc_asprintf(mem_ctx, "\tkdc = %s\n", - inet_ntoa(primary_ip)); + print_canonical_sockaddr(mem_ctx, + pss)); if (kdc_str == NULL) { return NULL; @@ -635,12 +639,15 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit get_kdc_list(realm, sitename, &ip_srv_site, &count_site); for (i = 0; i < count_site; i++) { - if (ip_equal(ip_srv_site[i].ip, primary_ip)) { + if (addr_equal(&ip_srv_site[i].ss, pss)) { continue; } - /* Append to the string - inefficient but not done often. */ + /* Append to the string - inefficient + * but not done often. */ kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", - kdc_str, inet_ntoa(ip_srv_site[i].ip)); + kdc_str, + print_canonical_sockaddr(mem_ctx, + &ip_srv_site[i].ss)); if (!kdc_str) { SAFE_FREE(ip_srv_site); return NULL; @@ -655,13 +662,14 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit for (i = 0; i < count_nonsite; i++) { int j; - if (ip_equal(ip_srv_nonsite[i].ip, primary_ip)) { + if (addr_equal(&ip_srv_nonsite[i].ss, pss)) { continue; } /* Ensure this isn't an IP already seen (YUK! this is n*n....) */ for (j = 0; j < count_site; j++) { - if (ip_equal(ip_srv_nonsite[i].ip, ip_srv_site[j].ip)) { + if (addr_equal(&ip_srv_nonsite[i].ss, + &ip_srv_site[j].ss)) { break; } /* As the lists are sorted we can break early if nonsite > site. */ @@ -675,7 +683,9 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit /* Append to the string - inefficient but not done often. */ kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", - kdc_str, inet_ntoa(ip_srv_nonsite[i].ip)); + kdc_str, + print_canonical_sockaddr(mem_ctx, + &ip_srv_nonsite[i].ss)); if (!kdc_str) { SAFE_FREE(ip_srv_site); SAFE_FREE(ip_srv_nonsite); @@ -700,8 +710,10 @@ static char *get_kdc_ip_string(char *mem_ctx, const char *realm, const char *sit run as root or will fail (which is a good thing :-). ************************************************************************/ -bool create_local_private_krb5_conf_for_domain(const char *realm, const char *domain, - const char *sitename, struct in_addr ip) +bool create_local_private_krb5_conf_for_domain(const char *realm, + const char *domain, + const char *sitename, + struct sockaddr_storage *pss) { char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_lockdir()); char *tmpname = NULL; @@ -742,12 +754,12 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, const char *do realm_upper = talloc_strdup(fname, realm); strupper_m(realm_upper); - kdc_ip_string = get_kdc_ip_string(dname, realm, sitename, ip); + kdc_ip_string = get_kdc_ip_string(dname, realm, sitename, pss); if (!kdc_ip_string) { TALLOC_FREE(dname); return False; } - + file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n\n" "[realms]\n\t%s = {\n" "\t%s\t}\n", @@ -806,7 +818,7 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, const char *do DEBUG(5,("create_local_private_krb5_conf_for_domain: wrote " "file %s with realm %s KDC = %s\n", - fname, realm_upper, inet_ntoa(ip) )); + fname, realm_upper, print_canonical_sockaddr(dname, pss) )); /* Set the environment variable to this file. */ setenv("KRB5_CONFIG", fname, 1); -- cgit From de51d3dd5f673019325abba88b100b279169a1c8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Nov 2007 18:55:36 -0800 Subject: More pstring removal.... Jeremy. (This used to be commit 809f5ab4c595740b28425e1667e395a6058b76a8) --- source3/libads/kerberos.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index f259c21bdb..29e5661d3c 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -829,13 +829,15 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, /* Insanity, sheer insanity..... */ if (strequal(realm, lp_realm())) { - pstring linkpath; + char linkpath[PATH_MAX+1]; int lret; lret = readlink(SYSTEM_KRB5_CONF_PATH, linkpath, sizeof(linkpath)-1); - linkpath[sizeof(pstring)-1] = '\0'; + if (lret != -1) { + linkpath[lret] = '\0'; + } - if (lret == 0 || strcmp(linkpath, fname) == 0) { + if (lret != -1 || strcmp(linkpath, fname) == 0) { /* Symlink already exists. */ TALLOC_FREE(dname); return True; @@ -843,6 +845,7 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, /* Try and replace with a symlink. */ if (symlink(fname, SYSTEM_KRB5_CONF_PATH) == -1) { + const char *newpath = SYSTEM_KRB5_CONF_PATH ## ".saved"; if (errno != EEXIST) { DEBUG(0,("create_local_private_krb5_conf_for_domain: symlink " "of %s to %s failed. Errno %s\n", @@ -851,20 +854,17 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, return True; /* Not a fatal error. */ } - pstrcpy(linkpath, SYSTEM_KRB5_CONF_PATH); - pstrcat(linkpath, ".saved"); - /* Yes, this is a race conditon... too bad. */ - if (rename(SYSTEM_KRB5_CONF_PATH, linkpath) == -1) { + if (rename(SYSTEM_KRB5_CONF_PATH, newpath) == -1) { DEBUG(0,("create_local_private_krb5_conf_for_domain: rename " "of %s to %s failed. Errno %s\n", - SYSTEM_KRB5_CONF_PATH, linkpath, + SYSTEM_KRB5_CONF_PATH, newpath, strerror(errno) )); TALLOC_FREE(dname); return True; /* Not a fatal error. */ } - if (symlink(fname, "/etc/krb5.conf") == -1) { + if (symlink(fname, SYSTEM_KRB5_CONF_PATH) == -1) { DEBUG(0,("create_local_private_krb5_conf_for_domain: " "forced symlink of %s to /etc/krb5.conf failed. Errno %s\n", fname, strerror(errno) )); -- cgit From 5dbc4a23bcae0087ab4319b5343cf6f44a4819e3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 15 Dec 2007 23:22:25 -0800 Subject: Added patch originally by Andreas Schneider to cause us to behave like Vista when looking for remote machine principal. Modified by me. Jeremy. (This used to be commit d0e33840fb4cfc85990d3ee327428b0854a22722) --- source3/libads/kerberos.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 29e5661d3c..02e14f468d 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -487,6 +487,58 @@ char* kerberos_secrets_fetch_des_salt( void ) return salt; } +/************************************************************************ + Routine to get the default realm from the kerberos credentials cache. + Caller must free if the return value is not NULL. +************************************************************************/ + +char *kerberos_get_default_realm_from_ccache( void ) +{ + char *realm = NULL; + krb5_context ctx = NULL; + krb5_ccache cc = NULL; + krb5_principal princ = NULL; + + initialize_krb5_error_table(); + if (krb5_init_context(&ctx)) { + return NULL; + } + + DEBUG(5,("kerberos_get_default_realm_from_ccache: " + "Trying to read krb5 cache: %s\n", + krb5_cc_default_name(ctx))); + if (krb5_cc_default(ctx, &cc)) { + DEBUG(0,("kerberos_get_default_realm_from_ccache: " + "failed to read default cache\n")); + goto out; + } + if (krb5_cc_get_principal(ctx, cc, &princ)) { + DEBUG(0,("kerberos_get_default_realm_from_ccache: " + "failed to get default principal\n")); + goto done; + } + +#if defined(HAVE_KRB5_PRINCIPAL_GET_REALM) + realm = SMB_STRDUP(krb5_principal_get_realm(ctx, princ)); +#elif defined(HAVE_KRB5_PRINC_REALM) + realm = SMB_STRDUP(krb5_princ_realm(ctx, princ)->data); +#endif + + out: + + if (princ) { + krb5_free_principal(ctx, princ); + } + if (cc) { + krb5_cc_close(ctx, cc); + } + if (ctx) { + krb5_free_context(ctx); + } +done: + return realm; +} + /************************************************************************ Routine to get the salting principal for this service. This is -- cgit From 8e86b7bb6569fea9f974eb3da68bc282dde068d0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 15 Dec 2007 23:32:28 -0800 Subject: Doh, fix typo in error exit. Jeremy. (This used to be commit 44918f39c0598eec681eb9e5c65452f04809c375) --- source3/libads/kerberos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 02e14f468d..227f95d15e 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -515,7 +515,7 @@ char *kerberos_get_default_realm_from_ccache( void ) if (krb5_cc_get_principal(ctx, cc, &princ)) { DEBUG(0,("kerberos_get_default_realm_from_ccache: " "failed to get default principal\n")); - goto done; + goto out; } #if defined(HAVE_KRB5_PRINCIPAL_GET_REALM) @@ -535,7 +535,7 @@ char *kerberos_get_default_realm_from_ccache( void ) if (ctx) { krb5_free_context(ctx); } -done: + return realm; } -- cgit From 4869ccfed6ba8c44fb49844a5a8abbb671518954 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 17 Dec 2007 15:21:38 -0500 Subject: While 'data' is usually 0 terminated, nothing in the spec requires that. The correct way is to copy only 'length' bytes. Simo. (This used to be commit 814c1b0e0034fb67c7718760dfcf913904f3e7fa) --- source3/libads/kerberos.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 227f95d15e..4fc23956bd 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -521,7 +521,10 @@ char *kerberos_get_default_realm_from_ccache( void ) #if defined(HAVE_KRB5_PRINCIPAL_GET_REALM) realm = SMB_STRDUP(krb5_principal_get_realm(ctx, princ)); #elif defined(HAVE_KRB5_PRINC_REALM) - realm = SMB_STRDUP(krb5_princ_realm(ctx, princ)->data); + { + krb5_data *realm_data = krb5_princ_realm(ctx, princ); + realm = SMB_STRNDUP(realm_data->data, realm_data->length); + } #endif out: -- cgit From a32cca7f372217e483ffda059e7775e3327982cc Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 14 Jan 2008 14:18:53 +0100 Subject: Print principal in debug statement in kerberos_kinit_password() as well. Guenther (This used to be commit 44d67e84625a2a1a93baecef0e418b48e982443b) --- source3/libads/kerberos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 4fc23956bd..e9222e8401 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -209,7 +209,8 @@ int kerberos_kinit_password_ext(const char *principal, krb5_set_real_time(ctx, time(NULL) + time_offset, 0); } - DEBUG(10,("kerberos_kinit_password: using [%s] as ccache and config [%s]\n", + DEBUG(10,("kerberos_kinit_password: as %s using [%s] as ccache and config [%s]\n", + principal, cache_name ? cache_name: krb5_cc_default_name(ctx), getenv("KRB5_CONFIG"))); -- cgit From bd8abea49fed09e131ab5162821b0ed05c1ab1b0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Jan 2008 13:21:46 -0800 Subject: Fix IPv6 bug #5204, which caused krb5 DNS lookups for a name '['. Jeremy. (This used to be commit f2aa921505e49f894bfed4e5e2f9fc01918b1bb0) --- source3/libads/kerberos.c | 69 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 13 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index e9222e8401..f7e947b1e7 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -25,6 +25,8 @@ #ifdef HAVE_KRB5 +#define DEFAULT_KRB5_PORT 88 + #define LIBADS_CCACHE_NAME "MEMORY:libads" /* @@ -665,6 +667,51 @@ int kerberos_kinit_password(const char *principal, NULL); } +/************************************************************************ +************************************************************************/ + +static char *print_kdc_line(char *mem_ctx, + const char *prev_line, + const struct sockaddr_storage *pss) +{ + char *kdc_str = NULL; + + if (pss->ss_family == AF_INET) { + kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", + prev_line, + print_canonical_sockaddr(mem_ctx, pss)); + } else { + char addr[INET6_ADDRSTRLEN]; + uint16_t port = get_sockaddr_port(pss); + + if (port != 0 && port != DEFAULT_KRB5_PORT) { + /* Currently for IPv6 we can't specify a non-default + krb5 port with an address, as this requires a ':'. + Resolve to a name. */ + char hostname[MAX_DNS_NAME_LENGTH]; + if (sys_getnameinfo((const struct sockaddr *)pss, + sizeof(*pss), + hostname, sizeof(hostname), + NULL, 0, + NI_NAMEREQD) == 0) { + /* Success, use host:port */ + kdc_str = talloc_asprintf(mem_ctx, + "%s\tkdc = %s:%u\n", + prev_line, + hostname, + (unsigned int)port); + return kdc_str; + } + } + kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", + prev_line, + print_sockaddr(addr, + sizeof(addr), + pss)); + } + return kdc_str; +} + /************************************************************************ Create a string list of available kdc's, possibly searching by sitename. Does DNS queries. @@ -677,12 +724,10 @@ static char *get_kdc_ip_string(char *mem_ctx, { int i; struct ip_service *ip_srv_site = NULL; - struct ip_service *ip_srv_nonsite; + struct ip_service *ip_srv_nonsite = NULL; int count_site = 0; int count_nonsite; - char *kdc_str = talloc_asprintf(mem_ctx, "\tkdc = %s\n", - print_canonical_sockaddr(mem_ctx, - pss)); + char *kdc_str = print_kdc_line(mem_ctx, "", pss); if (kdc_str == NULL) { return NULL; @@ -700,10 +745,9 @@ static char *get_kdc_ip_string(char *mem_ctx, } /* Append to the string - inefficient * but not done often. */ - kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", - kdc_str, - print_canonical_sockaddr(mem_ctx, - &ip_srv_site[i].ss)); + kdc_str = print_kdc_line(mem_ctx, + kdc_str, + &ip_srv_site[i].ss); if (!kdc_str) { SAFE_FREE(ip_srv_site); return NULL; @@ -738,10 +782,9 @@ static char *get_kdc_ip_string(char *mem_ctx, } /* Append to the string - inefficient but not done often. */ - kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", + kdc_str = print_kdc_line(mem_ctx, kdc_str, - print_canonical_sockaddr(mem_ctx, - &ip_srv_nonsite[i].ss)); + &ip_srv_nonsite[i].ss); if (!kdc_str) { SAFE_FREE(ip_srv_site); SAFE_FREE(ip_srv_nonsite); @@ -873,8 +916,8 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, } DEBUG(5,("create_local_private_krb5_conf_for_domain: wrote " - "file %s with realm %s KDC = %s\n", - fname, realm_upper, print_canonical_sockaddr(dname, pss) )); + "file %s with realm %s KDC list = %s\n", + fname, realm_upper, kdc_ip_string)); /* Set the environment variable to this file. */ setenv("KRB5_CONFIG", fname, 1); -- cgit From 70426bdd307be2bbaa2ec6f111440bae69216933 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Jan 2008 13:28:24 -0800 Subject: Tidy up code and debug for non-default krb5 IPv6 port. Jeremy. (This used to be commit 79b7972de4c2a8c71e37642ddf7e5bbed53dd58a) --- source3/libads/kerberos.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index f7e947b1e7..b99525047f 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -689,25 +689,31 @@ static char *print_kdc_line(char *mem_ctx, krb5 port with an address, as this requires a ':'. Resolve to a name. */ char hostname[MAX_DNS_NAME_LENGTH]; - if (sys_getnameinfo((const struct sockaddr *)pss, + int ret = sys_getnameinfo((const struct sockaddr *)pss, sizeof(*pss), hostname, sizeof(hostname), NULL, 0, - NI_NAMEREQD) == 0) { - /* Success, use host:port */ - kdc_str = talloc_asprintf(mem_ctx, + NI_NAMEREQD); + if (ret) { + DEBUG(0,("print_kdc_line: can't resolve name " + "for kdc with non-default port %s. " + "Error %s\n.", + print_canonical_sockaddr(mem_ctx, pss), + gai_strerror(ret))); + } + /* Success, use host:port */ + kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s:%u\n", - prev_line, + prev_line, hostname, (unsigned int)port); - return kdc_str; - } - } - kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", + } else { + kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", prev_line, print_sockaddr(addr, sizeof(addr), pss)); + } } return kdc_str; } -- cgit From c0c93dc2ba8bf6b32b0bcc228d947ee588ee4099 Mon Sep 17 00:00:00 2001 From: "Gerald W. Carter" Date: Mon, 28 Jan 2008 11:32:09 -0600 Subject: Restrict the enctypes in the generated krb5.conf files to Win2003 types. This fixes the failure observed on FC8 when joining a Windows 2008 RC1 domain. We currently do not handle user session keys correctly when the KDC uses AES in the ticket replies. (This used to be commit 8039a2518caae54bc876368c73ec493f3cd4eb73) --- source3/libads/kerberos.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index b99525047f..d47e8a3ff1 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -865,10 +865,14 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, return False; } - file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n\n" - "[realms]\n\t%s = {\n" - "\t%s\t}\n", - realm_upper, realm_upper, kdc_ip_string); + file_contents = talloc_asprintf(fname, + "[libdefaults]\n\tdefault_realm = %s\n" + "default_tgs_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n" + "default_tkt_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n" + "preferred_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n\n" + "[realms]\n\t%s = {\n" + "\t%s\t}\n", + realm_upper, realm_upper, kdc_ip_string); if (!file_contents) { TALLOC_FREE(dname); -- cgit From 317639287886181edf08ccecad1b324e4cc55d0b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 25 Feb 2008 15:24:49 +0100 Subject: Fix some warnings warning: ignoring return value of 'asprintf', declared with attribute warn_unused_result (This used to be commit ad37b7b0aee265a3e4d8b7552610f4b9a105434d) --- source3/libads/kerberos.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index d47e8a3ff1..b37b9a500f 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -407,8 +407,8 @@ static char *kerberos_secrets_fetch_salting_principal(const char *service, int e char *key = NULL; char *ret = NULL; - asprintf(&key, "%s/%s/enctype=%d", SECRETS_SALTING_PRINCIPAL, service, enctype); - if (!key) { + if (asprintf(&key, "%s/%s/enctype=%d", + SECRETS_SALTING_PRINCIPAL, service, enctype) == -1) { return NULL; } ret = (char *)secrets_fetch(key, NULL); @@ -438,7 +438,10 @@ static char* des_salt_key( void ) { char *key; - asprintf(&key, "%s/DES/%s", SECRETS_SALTING_PRINCIPAL, lp_realm()); + if (asprintf(&key, "%s/DES/%s", SECRETS_SALTING_PRINCIPAL, + lp_realm()) == -1) { + return NULL; + } return key; } @@ -609,9 +612,13 @@ bool kerberos_secrets_store_salting_principal(const char *service, return False; } if (strchr_m(service, '@')) { - asprintf(&princ_s, "%s", service); + if (asprintf(&princ_s, "%s", service) == -1) { + goto out; + } } else { - asprintf(&princ_s, "%s@%s", service, lp_realm()); + if (asprintf(&princ_s, "%s@%s", service, lp_realm()) == -1) { + goto out; + } } if (smb_krb5_parse_name(context, princ_s, &princ) != 0) { @@ -622,8 +629,9 @@ bool kerberos_secrets_store_salting_principal(const char *service, goto out; } - asprintf(&key, "%s/%s/enctype=%d", SECRETS_SALTING_PRINCIPAL, unparsed_name, enctype); - if (!key) { + if (asprintf(&key, "%s/%s/enctype=%d", + SECRETS_SALTING_PRINCIPAL, unparsed_name, enctype) + == -1) { goto out; } -- cgit From 87805819f108f0d2a7376ca78952a6e6a36bc6db Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 8 Mar 2008 23:48:12 +0100 Subject: Fix Coverity ID 551 Correctly return if we can't create the temporary krb5.conf Jeremy, please check! (This used to be commit c2401811aa3d02a9e27969687b9ea035407000c3) --- source3/libads/kerberos.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index b37b9a500f..ee25fb5551 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -894,6 +894,8 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, DEBUG(0,("create_local_private_krb5_conf_for_domain: smb_mkstemp failed," " for file %s. Errno %s\n", tmpname, strerror(errno) )); + TALLOC_FREE(dname); + return false; } if (fchmod(fd, 0644)==-1) { -- cgit From e06aa46b9fab1e107fea8f6453fb13deffa91e96 Mon Sep 17 00:00:00 2001 From: Marc VanHeyningen Date: Fri, 14 Mar 2008 14:26:28 -0800 Subject: Coverity fixes (This used to be commit 3fc85d22590550f0539215d020e4411bf5b14363) --- source3/libads/kerberos.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index ee25fb5551..66f203b12d 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -606,9 +606,11 @@ bool kerberos_secrets_store_salting_principal(const char *service, krb5_principal princ = NULL; char *princ_s = NULL; char *unparsed_name = NULL; + krb5_error_code code; - krb5_init_context(&context); - if (!context) { + if (((code = krb5_init_context(&context)) != 0) || (context == NULL)) { + DEBUG(5, ("kerberos_secrets_store_salting_pricipal: kdb5_init_context failed: %s\n", + error_message(code))); return False; } if (strchr_m(service, '@')) { -- cgit From fc3e6851d3084717d0a1654f6b97f81aabe41e51 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 19 May 2008 02:48:09 +0200 Subject: Fix some comments to match get_kdc_ip_string()'s behaviour (This used to be commit 30956c784f58870ad552a3869d80f99872c31375) --- source3/libads/kerberos.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 66f203b12d..2adf6a4700 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -731,6 +731,9 @@ static char *print_kdc_line(char *mem_ctx, /************************************************************************ Create a string list of available kdc's, possibly searching by sitename. Does DNS queries. + + If "sitename" is given, the DC's in that site are listed first. + ************************************************************************/ static char *get_kdc_ip_string(char *mem_ctx, @@ -749,7 +752,10 @@ static char *get_kdc_ip_string(char *mem_ctx, return NULL; } - /* Get the KDC's only in this site. */ + /* + * First get the KDC's only in this site, the rest will be + * appended later + */ if (sitename) { -- cgit From d5d4a9511d763cc4a63d3020c5537e852da2ed4c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 May 2008 12:27:57 -0700 Subject: Memory leak fixes from Chere Zhou . Jeremy. (This used to be commit 201bcc8ed291b51be6f4508c6aa1cb17ce6dcbe3) --- source3/libads/kerberos.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 2adf6a4700..c4135f24a1 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -649,6 +649,10 @@ bool kerberos_secrets_store_salting_principal(const char *service, SAFE_FREE(princ_s); SAFE_FREE(unparsed_name); + if (princ) { + krb5_free_principal(context, princ); + } + if (context) { krb5_free_context(context); } -- cgit From 6b4b76c40e965c7544097aa652eb6455af2ae8c1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Jun 2008 12:11:06 +0200 Subject: libads: add ADS_AUTH_USER_CREDS to avoid magic overwriting of usernames. Guenther (This used to be commit b5aaf5aa0f280f69e05b613271c96473a79b812e) --- source3/libads/kerberos.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index c4135f24a1..31e5af4224 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -323,6 +323,11 @@ int ads_kinit_password(ADS_STRUCT *ads) const char *account_name; fstring acct_name; + if (ads->auth.flags & ADS_AUTH_USER_CREDS) { + account_name = ads->auth.user_name; + goto got_accountname; + } + if ( IS_DC ) { /* this will end up getting a ticket for DOMAIN@RUSTED.REA.LM */ account_name = lp_workgroup(); @@ -338,6 +343,7 @@ int ads_kinit_password(ADS_STRUCT *ads) account_name = ads->auth.user_name; } + got_accountname: if (asprintf(&s, "%s@%s", account_name, ads->auth.realm) == -1) { return KRB5_CC_NOMEM; } -- cgit From 862ff66da912e840860452ef0846793961f3bb82 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 4 Sep 2008 15:11:22 +0200 Subject: kerberos: fix indent of enc type lines in generated krb5.conf files. Guenther (This used to be commit 18a26f08b6fab4119a1421a7ca59c32dde8bb8cb) --- source3/libads/kerberos.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libads/kerberos.c') diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 31e5af4224..501ef010fd 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -893,9 +893,9 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n" - "default_tgs_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n" - "default_tkt_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n" - "preferred_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n\n" + "\tdefault_tgs_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n" + "\tdefault_tkt_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n" + "\tpreferred_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n\n" "[realms]\n\t%s = {\n" "\t%s\t}\n", realm_upper, realm_upper, kdc_ip_string); -- cgit