[SCM] Samba Shared Repository - branch master updated
Simo Sorce
idra at samba.org
Wed Aug 18 05:47:30 MDT 2010
The branch, master has been updated
via 71dfa62... s3-ads: cleanup ads_keytab_list()
via 64d8300... s3-ads: cleanup ads_keytab_create_default()
via 3a99123... s3-ads: cleanup ads_keytab_add_entry()
via d6d1ed8... s3-ads: Split, simplify and cleanup keytab functions
from b9353c6... s3: Fix serverid_register_msg_flags
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 71dfa62b61380396785c7856c38f45c77c966ff0
Author: Simo Sorce <idra at samba.org>
Date: Wed Aug 18 06:46:53 2010 -0400
s3-ads: cleanup ads_keytab_list()
commit 64d8300a56eb0891389a5a2afc5e4902c2d909a2
Author: Simo Sorce <idra at samba.org>
Date: Wed Aug 18 06:09:27 2010 -0400
s3-ads: cleanup ads_keytab_create_default()
commit 3a9912370dc36500d207aeb9d1ae58834526b6c3
Author: Simo Sorce <idra at samba.org>
Date: Wed Aug 18 04:33:32 2010 -0400
s3-ads: cleanup ads_keytab_add_entry()
commit d6d1ed8bdfb290ac6e1fa4264f2b84d0e4790d98
Author: Simo Sorce <idra at samba.org>
Date: Wed Aug 18 04:16:41 2010 -0400
s3-ads: Split, simplify and cleanup keytab functions
add helper function for both smb_krb5_kt_add_entry_ext() and
ads_keytab_flush()
-----------------------------------------------------------------------
Summary of changes:
source3/libads/kerberos_keytab.c | 756 ++++++++++++++++++++------------------
1 files changed, 404 insertions(+), 352 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c
index 386ce83..d2215ec 100644
--- a/source3/libads/kerberos_keytab.c
+++ b/source3/libads/kerberos_keytab.c
@@ -35,130 +35,184 @@
/**********************************************************************
**********************************************************************/
-int smb_krb5_kt_add_entry_ext(krb5_context context,
- krb5_keytab keytab,
- krb5_kvno kvno,
- const char *princ_s,
- krb5_enctype *enctypes,
- krb5_data password,
- bool no_salt,
- bool keep_old_entries)
+static krb5_error_code seek_and_delete_old_entries(krb5_context context,
+ krb5_keytab keytab,
+ krb5_kvno kvno,
+ const char *princ_s,
+ krb5_principal princ,
+ bool flush,
+ bool keep_old_entries)
{
- krb5_error_code ret = 0;
+ krb5_error_code ret;
krb5_kt_cursor cursor;
+ krb5_kt_cursor zero_csr;
krb5_keytab_entry kt_entry;
- krb5_principal princ = NULL;
- int i;
+ krb5_keytab_entry zero_kt_entry;
char *ktprinc = NULL;
- ZERO_STRUCT(kt_entry);
ZERO_STRUCT(cursor);
-
- ret = smb_krb5_parse_name(context, princ_s, &princ);
- if (ret) {
- DEBUG(1,("smb_krb5_kt_add_entry_ext: smb_krb5_parse_name(%s) failed (%s)\n", princ_s, error_message(ret)));
- goto out;
- }
+ ZERO_STRUCT(zero_csr);
+ ZERO_STRUCT(kt_entry);
+ ZERO_STRUCT(zero_kt_entry);
- /* Seek and delete old keytab entries */
ret = krb5_kt_start_seq_get(context, keytab, &cursor);
- if (ret != KRB5_KT_END && ret != ENOENT ) {
- DEBUG(3,("smb_krb5_kt_add_entry_ext: Will try to delete old keytab entries\n"));
- while(!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) {
- bool compare_name_ok = False;
+ if (ret == KRB5_KT_END && ret == ENOENT ) {
+ /* no entries */
+ return 0;
+ }
+
+ DEBUG(3, (__location__ ": Will try to delete old keytab entries\n"));
+ while (!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) {
+ bool name_ok = False;
- ret = smb_krb5_unparse_name(talloc_tos(), context, kt_entry.principal, &ktprinc);
+ if (!flush && (princ_s != NULL)) {
+ ret = smb_krb5_unparse_name(talloc_tos(), context,
+ kt_entry.principal,
+ &ktprinc);
if (ret) {
- DEBUG(1,("smb_krb5_kt_add_entry_ext: smb_krb5_unparse_name failed (%s)\n",
- error_message(ret)));
+ DEBUG(1, (__location__
+ ": smb_krb5_unparse_name failed "
+ "(%s)\n", error_message(ret)));
goto out;
}
- /*---------------------------------------------------------------------------
- * Save the entries with kvno - 1. This is what microsoft does
- * to allow people with existing sessions that have kvno - 1 to still
- * work. Otherwise, when the password for the machine changes, all
- * kerberizied sessions will 'break' until either the client reboots or
- * the client's session key expires and they get a new session ticket
- * with the new kvno.
- */
-
#ifdef HAVE_KRB5_KT_COMPARE
- compare_name_ok = (krb5_kt_compare(context, &kt_entry, princ, 0, 0) == True);
+ name_ok = krb5_kt_compare(context, &kt_entry,
+ princ, 0, 0);
#else
- compare_name_ok = (strcmp(ktprinc, princ_s) == 0);
+ name_ok = (strcmp(ktprinc, princ_s) == 0);
#endif
- if (!compare_name_ok) {
- DEBUG(10,("smb_krb5_kt_add_entry_ext: ignoring keytab entry principal %s, kvno = %d\n",
- ktprinc, kt_entry.vno));
+ if (!name_ok) {
+ DEBUG(10, (__location__ ": ignoring keytab "
+ "entry principal %s, kvno = %d\n",
+ ktprinc, kt_entry.vno));
+
+ /* Not a match,
+ * just free this entry and continue. */
+ ret = smb_krb5_kt_free_entry(context,
+ &kt_entry);
+ ZERO_STRUCT(kt_entry);
+ if (ret) {
+ DEBUG(1, (__location__
+ ": smb_krb5_kt_free_entry "
+ "failed (%s)\n",
+ error_message(ret)));
+ goto out;
+ }
+
+ TALLOC_FREE(ktprinc);
+ continue;
}
TALLOC_FREE(ktprinc);
+ }
- if (compare_name_ok) {
- if (kt_entry.vno == kvno - 1) {
- DEBUG(5,("smb_krb5_kt_add_entry_ext: Saving previous (kvno %d) entry for principal: %s.\n",
- kvno - 1, princ_s));
- } else if (!keep_old_entries) {
- DEBUG(5,("smb_krb5_kt_add_entry_ext: Found old entry for principal: %s (kvno %d) - trying to remove it.\n",
- princ_s, kt_entry.vno));
- ret = krb5_kt_end_seq_get(context, keytab, &cursor);
- ZERO_STRUCT(cursor);
- if (ret) {
- DEBUG(1,("smb_krb5_kt_add_entry_ext: krb5_kt_end_seq_get() failed (%s)\n",
- error_message(ret)));
- goto out;
- }
- ret = krb5_kt_remove_entry(context, keytab, &kt_entry);
- if (ret) {
- DEBUG(1,("smb_krb5_kt_add_entry_ext: krb5_kt_remove_entry failed (%s)\n",
- error_message(ret)));
- goto out;
- }
-
- DEBUG(5,("smb_krb5_kt_add_entry_ext: removed old entry for principal: %s (kvno %d).\n",
- princ_s, kt_entry.vno));
-
- ret = krb5_kt_start_seq_get(context, keytab, &cursor);
- if (ret) {
- DEBUG(1,("smb_krb5_kt_add_entry_ext: krb5_kt_start_seq failed (%s)\n",
- error_message(ret)));
- goto out;
- }
- ret = smb_krb5_kt_free_entry(context, &kt_entry);
- ZERO_STRUCT(kt_entry);
- if (ret) {
- DEBUG(1,("smb_krb5_kt_add_entry_ext: krb5_kt_remove_entry failed (%s)\n",
- error_message(ret)));
- goto out;
- }
- continue;
- }
- }
+ /*------------------------------------------------------------
+ * Save the entries with kvno - 1. This is what microsoft does
+ * to allow people with existing sessions that have kvno - 1
+ * to still work. Otherwise, when the password for the machine
+ * changes, all kerberizied sessions will 'break' until either
+ * the client reboots or the client's session key expires and
+ * they get a new session ticket with the new kvno.
+ */
+
+ if (!flush && (kt_entry.vno == kvno - 1)) {
+ DEBUG(5, (__location__ ": Saving previous (kvno %d) "
+ "entry for principal: %s.\n",
+ kvno - 1, princ_s));
+ continue;
+ }
- /* Not a match, just free this entry and continue. */
- ret = smb_krb5_kt_free_entry(context, &kt_entry);
- ZERO_STRUCT(kt_entry);
- if (ret) {
- DEBUG(1,("smb_krb5_kt_add_entry_ext: smb_krb5_kt_free_entry failed (%s)\n", error_message(ret)));
- goto out;
- }
+ if (keep_old_entries) {
+ DEBUG(5, (__location__ ": Saving old (kvno %d) "
+ "entry for principal: %s.\n",
+ kvno, princ_s));
+ continue;
}
+ DEBUG(5, (__location__ ": Found old entry for principal: %s "
+ "(kvno %d) - trying to remove it.\n",
+ princ_s, kt_entry.vno));
+
ret = krb5_kt_end_seq_get(context, keytab, &cursor);
ZERO_STRUCT(cursor);
if (ret) {
- DEBUG(1,("smb_krb5_kt_add_entry_ext: krb5_kt_end_seq_get failed (%s)\n",error_message(ret)));
+ DEBUG(1, (__location__ ": krb5_kt_end_seq_get() "
+ "failed (%s)\n", error_message(ret)));
+ goto out;
+ }
+ ret = krb5_kt_remove_entry(context, keytab, &kt_entry);
+ if (ret) {
+ DEBUG(1, (__location__ ": krb5_kt_remove_entry() "
+ "failed (%s)\n", error_message(ret)));
+ goto out;
+ }
+
+ DEBUG(5, (__location__ ": removed old entry for principal: "
+ "%s (kvno %d).\n", princ_s, kt_entry.vno));
+
+ ret = krb5_kt_start_seq_get(context, keytab, &cursor);
+ if (ret) {
+ DEBUG(1, (__location__ ": krb5_kt_start_seq() failed "
+ "(%s)\n", error_message(ret)));
+ goto out;
+ }
+ ret = smb_krb5_kt_free_entry(context, &kt_entry);
+ ZERO_STRUCT(kt_entry);
+ if (ret) {
+ DEBUG(1, (__location__ ": krb5_kt_remove_entry() "
+ "failed (%s)\n", error_message(ret)));
goto out;
}
}
- /* Ensure we don't double free. */
+out:
+ if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) {
+ smb_krb5_kt_free_entry(context, &kt_entry);
+ }
+ if (keytab) {
+ if (memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) {
+ krb5_kt_end_seq_get(context, keytab, &cursor);
+ }
+ }
+
+ return ret;
+}
+
+int smb_krb5_kt_add_entry_ext(krb5_context context,
+ krb5_keytab keytab,
+ krb5_kvno kvno,
+ const char *princ_s,
+ krb5_enctype *enctypes,
+ krb5_data password,
+ bool no_salt,
+ bool keep_old_entries)
+{
+ krb5_error_code ret;
+ krb5_keytab_entry kt_entry;
+ krb5_principal princ = NULL;
+ int i;
+
ZERO_STRUCT(kt_entry);
- ZERO_STRUCT(cursor);
- /* If we get here, we have deleted all the old entries with kvno's not equal to the current kvno-1. */
+ ret = smb_krb5_parse_name(context, princ_s, &princ);
+ if (ret) {
+ DEBUG(1, (__location__ ": smb_krb5_parse_name(%s) "
+ "failed (%s)\n", princ_s, error_message(ret)));
+ goto out;
+ }
+
+ /* Seek and delete old keytab entries */
+ ret = seek_and_delete_old_entries(context, keytab, kvno,
+ princ_s, princ, false,
+ keep_old_entries);
+ if (ret) {
+ goto out;
+ }
+
+ /* If we get here, we have deleted all the old entries with kvno's
+ * not equal to the current kvno-1. */
/* Now add keytab entries for all encryption types */
for (i = 0; enctypes[i]; i++) {
@@ -166,45 +220,33 @@ int smb_krb5_kt_add_entry_ext(krb5_context context,
keyp = KRB5_KT_KEY(&kt_entry);
- if (create_kerberos_key_from_string(context, princ, &password, keyp, enctypes[i], no_salt)) {
+ if (create_kerberos_key_from_string(context, princ,
+ &password, keyp,
+ enctypes[i], no_salt)) {
continue;
}
kt_entry.principal = princ;
kt_entry.vno = kvno;
- DEBUG(3,("smb_krb5_kt_add_entry_ext: adding keytab entry for (%s) with encryption type (%d) and version (%d)\n",
- princ_s, enctypes[i], kt_entry.vno));
+ DEBUG(3, (__location__ ": adding keytab entry for (%s) with "
+ "encryption type (%d) and version (%d)\n",
+ princ_s, enctypes[i], kt_entry.vno));
ret = krb5_kt_add_entry(context, keytab, &kt_entry);
krb5_free_keyblock_contents(context, keyp);
ZERO_STRUCT(kt_entry);
if (ret) {
- DEBUG(1,("smb_krb5_kt_add_entry_ext: adding entry to keytab failed (%s)\n", error_message(ret)));
+ DEBUG(1, (__location__ ": adding entry to keytab "
+ "failed (%s)\n", error_message(ret)));
goto out;
}
}
-
out:
- {
- krb5_keytab_entry zero_kt_entry;
- ZERO_STRUCT(zero_kt_entry);
- if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) {
- smb_krb5_kt_free_entry(context, &kt_entry);
- }
- }
if (princ) {
krb5_free_principal(context, princ);
}
-
- {
- krb5_kt_cursor zero_csr;
- ZERO_STRUCT(zero_csr);
- if ((memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) {
- krb5_kt_end_seq_get(context, keytab, &cursor);
- }
- }
-
+
return (int)ret;
}
@@ -236,38 +278,44 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc)
krb5_keytab keytab = NULL;
krb5_data password;
krb5_kvno kvno;
- krb5_enctype enctypes[4] = { ENCTYPE_DES_CBC_CRC,
- ENCTYPE_DES_CBC_MD5,
- ENCTYPE_ARCFOUR_HMAC,
- 0 };
- char *princ_s = NULL, *short_princ_s = NULL;
+ krb5_enctype enctypes[4] = {
+ ENCTYPE_DES_CBC_CRC,
+ ENCTYPE_DES_CBC_MD5,
+ ENCTYPE_ARCFOUR_HMAC,
+ 0
+ };
+ char *princ_s = NULL;
+ char *short_princ_s = NULL;
char *password_s = NULL;
char *my_fqdn;
- TALLOC_CTX *ctx = NULL;
+ TALLOC_CTX *tmpctx = NULL;
char *machine_name;
+ ADS_STATUS aderr;
initialize_krb5_error_table();
ret = krb5_init_context(&context);
if (ret) {
- DEBUG(1,("ads_keytab_add_entry: could not krb5_init_context: %s\n",error_message(ret)));
+ DEBUG(1, (__location__ ": could not krb5_init_context: %s\n",
+ error_message(ret)));
return -1;
}
ret = smb_krb5_open_keytab(context, NULL, True, &keytab);
if (ret) {
- DEBUG(1,("ads_keytab_add_entry: smb_krb5_open_keytab failed (%s)\n", error_message(ret)));
+ DEBUG(1, (__location__ ": smb_krb5_open_keytab failed (%s)\n",
+ error_message(ret)));
goto out;
}
/* retrieve the password */
if (!secrets_init()) {
- DEBUG(1,("ads_keytab_add_entry: secrets_init failed\n"));
+ DEBUG(1, (__location__ ": secrets_init failed\n"));
ret = -1;
goto out;
}
password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
if (!password_s) {
- DEBUG(1,("ads_keytab_add_entry: failed to fetch machine password\n"));
+ DEBUG(1, (__location__ ": failed to fetch machine password\n"));
ret = -1;
goto out;
}
@@ -276,38 +324,44 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc)
password.length = strlen(password_s);
/* we need the dNSHostName value here */
-
- if ( (ctx = talloc_init("ads_keytab_add_entry")) == NULL ) {
- DEBUG(0,("ads_keytab_add_entry: talloc() failed!\n"));
+ tmpctx = talloc_init(__location__);
+ if (!tmpctx) {
+ DEBUG(0, (__location__ ": talloc_init() failed!\n"));
ret = -1;
goto out;
}
-
- if ( (my_fqdn = ads_get_dnshostname( ads, ctx, global_myname())) == NULL ) {
- DEBUG(0,("ads_keytab_add_entry: unable to determine machine account's dns name in AD!\n"));
+
+ my_fqdn = ads_get_dnshostname(ads, tmpctx, global_myname());
+ if (!my_fqdn) {
+ DEBUG(0, (__location__ ": unable to determine machine "
+ "account's dns name in AD!\n"));
ret = -1;
- goto out;
+ goto out;
}
-
- if ( (machine_name = ads_get_samaccountname( ads, ctx, global_myname())) == NULL ) {
- DEBUG(0,("ads_keytab_add_entry: unable to determine machine account's short name in AD!\n"));
+
+ machine_name = ads_get_samaccountname(ads, tmpctx, global_myname());
+ if (!machine_name) {
+ DEBUG(0, (__location__ ": unable to determine machine "
+ "account's short name in AD!\n"));
ret = -1;
- goto out;
+ goto out;
}
/*strip the trailing '$' */
machine_name[strlen(machine_name)-1] = '\0';
-
- /* Construct our principal */
+ /* Construct our principal */
if (strchr_m(srvPrinc, '@')) {
/* It's a fully-named principal. */
- if (asprintf(&princ_s, "%s", srvPrinc) == -1) {
+ princ_s = talloc_asprintf(tmpctx, "%s", srvPrinc);
+ if (!princ_s) {
ret = -1;
goto out;
}
} else if (srvPrinc[strlen(srvPrinc)-1] == '$') {
/* It's the machine account, as used by smbclient clients. */
- if (asprintf(&princ_s, "%s@%s", srvPrinc, lp_realm()) == -1) {
+ princ_s = talloc_asprintf(tmpctx, "%s@%s",
+ srvPrinc, lp_realm());
+ if (!princ_s) {
ret = -1;
goto out;
}
@@ -315,61 +369,72 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc)
/* It's a normal service principal. Add the SPN now so that we
* can obtain credentials for it and double-check the salt value
* used to generate the service's keys. */
-
- if (asprintf(&princ_s, "%s/%s@%s", srvPrinc, my_fqdn, lp_realm()) == -1) {
+
+ princ_s = talloc_asprintf(tmpctx, "%s/%s@%s",
+ srvPrinc, my_fqdn, lp_realm());
+ if (!princ_s) {
ret = -1;
goto out;
}
- if (asprintf(&short_princ_s, "%s/%s@%s", srvPrinc, machine_name, lp_realm()) == -1) {
+ short_princ_s = talloc_asprintf(tmpctx, "%s/%s@%s",
+ srvPrinc, machine_name,
+ lp_realm());
+ if (!princ_s) {
ret = -1;
goto out;
}
-
- /* According to http://support.microsoft.com/kb/326985/en-us,
- certain principal names are automatically mapped to the host/...
- principal in the AD account. So only create these in the
- keytab, not in AD. --jerry */
-
- if ( !strequal( srvPrinc, "cifs" ) && !strequal(srvPrinc, "host" ) ) {
- DEBUG(3,("ads_keytab_add_entry: Attempting to add/update '%s'\n", princ_s));
-
- if (!ADS_ERR_OK(ads_add_service_principal_name(ads, global_myname(), my_fqdn, srvPrinc))) {
- DEBUG(1,("ads_keytab_add_entry: ads_add_service_principal_name failed.\n"));
+
+ /* According to http://support.microsoft.com/kb/326985/en-us,
+ certain principal names are automatically mapped to the
+ host/... principal in the AD account.
+ So only create these in the keytab, not in AD. --jerry */
+
+ if (!strequal(srvPrinc, "cifs") &&
+ !strequal(srvPrinc, "host")) {
+ DEBUG(3, (__location__ ": Attempting to add/update "
+ "'%s'\n", princ_s));
+
+ aderr = ads_add_service_principal_name(ads,
+ global_myname(), my_fqdn, srvPrinc);
+ if (!ADS_ERR_OK(aderr)) {
+ DEBUG(1, (__location__ ": failed to "
+ "ads_add_service_principal_name.\n"));
goto out;
}
--
Samba Shared Repository
More information about the samba-cvs
mailing list