krb5_keytab_entry kt_entry;
krb5_keytab_entry zero_kt_entry;
char *ktprinc = NULL;
+ krb5_kvno old_kvno = kvno - 1;
ZERO_STRUCT(cursor);
ZERO_STRUCT(zero_csr);
* 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.
+ * Some keytab files only store the kvno in 8bits, limit
+ * the compare accordingly.
*/
- if (!flush && (kt_entry.vno == kvno - 1)) {
+ if (!flush && ((kt_entry.vno & 0xff) == (old_kvno & 0xff))) {
DEBUG(5, (__location__ ": Saving previous (kvno %d) "
"entry for principal: %s.\n",
- kvno - 1, princ_s));
+ old_kvno, princ_s));
continue;
}
return (int)ret;
}
+#ifdef HAVE_ADS
+
/**********************************************************************
Adds a single service principal, i.e. 'host' to the system keytab
***********************************************************************/
krb5_keytab keytab = NULL;
krb5_data password;
krb5_kvno kvno;
- krb5_enctype enctypes[4] = {
+ krb5_enctype enctypes[6] = {
ENCTYPE_DES_CBC_CRC,
ENCTYPE_DES_CBC_MD5,
+#ifdef HAVE_ENCTYPE_AES128_CTS_HMAC_SHA1_96
+ ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+#endif
+#ifdef HAVE_ENCTYPE_AES256_CTS_HMAC_SHA1_96
+ ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+#endif
ENCTYPE_ARCFOUR_HMAC,
0
};
goto out;
}
- my_fqdn = ads_get_dnshostname(ads, tmpctx, global_myname());
+ my_fqdn = ads_get_dnshostname(ads, tmpctx, lp_netbios_name());
if (!my_fqdn) {
DEBUG(0, (__location__ ": unable to determine machine "
"account's dns name in AD!\n"));
goto out;
}
- machine_name = ads_get_samaccountname(ads, tmpctx, global_myname());
+ machine_name = ads_get_samaccountname(ads, tmpctx, lp_netbios_name());
if (!machine_name) {
DEBUG(0, (__location__ ": unable to determine machine "
"account's short name in AD!\n"));
short_princ_s = talloc_asprintf(tmpctx, "%s/%s@%s",
srvPrinc, machine_name,
lp_realm());
- if (!princ_s) {
+ if (short_princ_s == NULL) {
ret = -1;
goto out;
}
"'%s'\n", princ_s));
aderr = ads_add_service_principal_name(ads,
- global_myname(), my_fqdn, srvPrinc);
+ lp_netbios_name(), my_fqdn, srvPrinc);
if (!ADS_ERR_OK(aderr)) {
DEBUG(1, (__location__ ": failed to "
"ads_add_service_principal_name.\n"));
}
}
- kvno = (krb5_kvno)ads_get_machine_kvno(ads, global_myname());
+ kvno = (krb5_kvno)ads_get_machine_kvno(ads, lp_netbios_name());
if (kvno == -1) {
/* -1 indicates failure, everything else is OK */
DEBUG(1, (__location__ ": ads_get_machine_kvno failed to "
goto out;
}
- kvno = (krb5_kvno)ads_get_machine_kvno(ads, global_myname());
+ kvno = (krb5_kvno)ads_get_machine_kvno(ads, lp_netbios_name());
if (kvno == -1) {
/* -1 indicates a failure */
DEBUG(1, (__location__ ": Error determining the kvno.\n"));
goto out;
}
- aderr = ads_clear_service_principal_names(ads, global_myname());
+ aderr = ads_clear_service_principal_names(ads, lp_netbios_name());
if (!ADS_ERR_OK(aderr)) {
DEBUG(1, (__location__ ": Error while clearing service "
"principal listings in LDAP.\n"));
krb5_kt_cursor cursor;
krb5_keytab_entry kt_entry;
krb5_kvno kvno;
- int i, found = 0;
+ size_t found = 0;
char *sam_account_name, *upn;
char **oldEntries = NULL, *princ_s[26];
- TALLOC_CTX *tmpctx = NULL;
+ TALLOC_CTX *frame;
char *machine_name;
+ char **spn_array;
+ size_t num_spns;
+ size_t i;
+ ADS_STATUS status;
- /* these are the main ones we need */
- ret = ads_keytab_add_entry(ads, "host");
- if (ret != 0) {
- DEBUG(1, (__location__ ": ads_keytab_add_entry failed while "
- "adding 'host' principal.\n"));
- return ret;
+ frame = talloc_stackframe();
+ if (frame == NULL) {
+ ret = -1;
+ goto done;
}
+ status = ads_get_service_principal_names(frame,
+ ads,
+ lp_netbios_name(),
+ &spn_array,
+ &num_spns);
+ if (!ADS_ERR_OK(status)) {
+ ret = -1;
+ goto done;
+ }
+
+ for (i = 0; i < num_spns; i++) {
+ char *srv_princ;
+ char *p;
+
+ srv_princ = strlower_talloc(frame, spn_array[i]);
+ if (srv_princ == NULL) {
+ ret = -1;
+ goto done;
+ }
+
+ p = strchr_m(srv_princ, '/');
+ if (p == NULL) {
+ continue;
+ }
+ p[0] = '\0';
+
+ /* Add the SPNs found on the DC */
+ ret = ads_keytab_add_entry(ads, srv_princ);
+ if (ret != 0) {
+ DEBUG(1, ("ads_keytab_add_entry failed while "
+ "adding '%s' principal.\n",
+ spn_array[i]));
+ goto done;
+ }
+ }
#if 0 /* don't create the CIFS/... keytab entries since no one except smbd
really needs them and we will fall back to verifying against
if (ret) {
DEBUG(1, (__location__ ": could not krb5_init_context: %s\n",
error_message(ret)));
- return ret;
- }
-
- tmpctx = talloc_init(__location__);
- if (!tmpctx) {
- DEBUG(0, (__location__ ": talloc_init() failed!\n"));
- ret = -1;
goto done;
}
- machine_name = talloc_strdup(tmpctx, global_myname());
+ machine_name = talloc_strdup(frame, lp_netbios_name());
if (!machine_name) {
ret = -1;
goto done;
}
/* now add the userPrincipalName and sAMAccountName entries */
- sam_account_name = ads_get_samaccountname(ads, tmpctx, machine_name);
+ sam_account_name = ads_get_samaccountname(ads, frame, machine_name);
if (!sam_account_name) {
DEBUG(0, (__location__ ": unable to determine machine "
"account's name in AD!\n"));
/* upper case the sAMAccountName to make it easier for apps to
know what case to use in the keytab file */
- strupper_m(sam_account_name);
+ if (!strupper_m(sam_account_name)) {
+ ret = -1;
+ goto done;
+ }
ret = ads_keytab_add_entry(ads, sam_account_name);
if (ret != 0) {
}
/* remember that not every machine account will have a upn */
- upn = ads_get_upn(ads, tmpctx, machine_name);
+ upn = ads_get_upn(ads, frame, machine_name);
if (upn) {
ret = ads_keytab_add_entry(ads, upn);
if (ret != 0) {
/* Now loop through the keytab and update any other existing entries */
kvno = (krb5_kvno)ads_get_machine_kvno(ads, machine_name);
- if (kvno == -1) {
+ if (kvno == (krb5_kvno)-1) {
DEBUG(1, (__location__ ": ads_get_machine_kvno() failed to "
"determine the system's kvno.\n"));
goto done;
* have a race condition where someone else could add entries after
* we've counted them. Re-open asap to minimise the race. JRA.
*/
- DEBUG(3, (__location__ ": Found %d entries in the keytab.\n", found));
+ DEBUG(3, (__location__ ": Found %zd entries in the keytab.\n", found));
if (!found) {
goto done;
}
- oldEntries = talloc_array(tmpctx, char *, found);
+ oldEntries = talloc_zero_array(frame, char *, found + 1);
if (!oldEntries) {
DEBUG(1, (__location__ ": Failed to allocate space to store "
"the old keytab entries (talloc failed?).\n"));
ret = -1;
goto done;
}
- memset(oldEntries, '\0', found * sizeof(char *));
ret = krb5_kt_start_seq_get(context, keytab, &cursor);
if (ret == KRB5_KT_END || ret == ENOENT) {
done:
TALLOC_FREE(oldEntries);
- TALLOC_FREE(tmpctx);
+ TALLOC_FREE(frame);
{
krb5_keytab_entry zero_kt_entry;
return ret;
}
+#endif /* HAVE_ADS */
+
/**********************************************************************
List system keytab.
***********************************************************************/
ret = krb5_kt_start_seq_get(context, keytab, &cursor);
if (ret) {
+ ZERO_STRUCT(cursor);
goto out;
}
- printf("Vno Type Principal\n");
+ printf("Vno Type Principal\n");
while (krb5_kt_next_entry(context, keytab, &kt_entry, &cursor) == 0) {
goto out;
}
- printf("%3d %s\t\t %s\n", kt_entry.vno, etype_s, princ_s);
+ printf("%3d %-43s %s\n", kt_entry.vno, etype_s, princ_s);
TALLOC_FREE(princ_s);
SAFE_FREE(etype_s);