42
42
krb5_error_code ret = 0;
43
43
BOOL auth_ok = False;
44
44
krb5_keytab keytab = NULL;
45
fstring my_fqdn, my_name;
46
fstring my_Fqdn, my_NAME;
48
char *host_princ_s[18];
49
krb5_principal host_princ;
45
krb5_kt_cursor kt_cursor;
46
krb5_keytab_entry kt_entry;
47
char *valid_princ_formats[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
48
char *entry_princ_s = NULL;
49
fstring my_name, my_fqdn;
52
ret = krb5_kt_default(context, &keytab);
54
DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_default failed (%s)\n", error_message(ret)));
58
/* Generate the list of principal names which we expect clients might
59
* want to use for authenticating to the file service. */
51
int number_matched_principals = 0;
53
/* Generate the list of principal names which we expect
54
* clients might want to use for authenticating to the file
55
* service. We allow name$,{host,cifs}/{name,fqdn,name.REALM}. */
61
57
fstrcpy(my_name, global_myname());
64
fstrcpy(my_NAME, global_myname());
68
60
name_to_fqdn(my_fqdn, global_myname());
71
p_fqdn = strchr_m(my_fqdn, '.');
72
fstrcpy(my_Fqdn, my_NAME);
74
fstrcat(my_Fqdn, p_fqdn);
77
asprintf(&host_princ_s[0], "%s$@%s", my_name, lp_realm());
78
asprintf(&host_princ_s[1], "%s$@%s", my_NAME, lp_realm());
79
asprintf(&host_princ_s[2], "host/%s@%s", my_name, lp_realm());
80
asprintf(&host_princ_s[3], "host/%s@%s", my_NAME, lp_realm());
81
asprintf(&host_princ_s[4], "host/%s@%s", my_fqdn, lp_realm());
82
asprintf(&host_princ_s[5], "host/%s@%s", my_Fqdn, lp_realm());
83
asprintf(&host_princ_s[6], "HOST/%s@%s", my_name, lp_realm());
84
asprintf(&host_princ_s[7], "HOST/%s@%s", my_NAME, lp_realm());
85
asprintf(&host_princ_s[8], "HOST/%s@%s", my_fqdn, lp_realm());
86
asprintf(&host_princ_s[9], "HOST/%s@%s", my_Fqdn, lp_realm());
87
asprintf(&host_princ_s[10], "cifs/%s@%s", my_name, lp_realm());
88
asprintf(&host_princ_s[11], "cifs/%s@%s", my_NAME, lp_realm());
89
asprintf(&host_princ_s[12], "cifs/%s@%s", my_fqdn, lp_realm());
90
asprintf(&host_princ_s[13], "cifs/%s@%s", my_Fqdn, lp_realm());
91
asprintf(&host_princ_s[14], "CIFS/%s@%s", my_name, lp_realm());
92
asprintf(&host_princ_s[15], "CIFS/%s@%s", my_NAME, lp_realm());
93
asprintf(&host_princ_s[16], "CIFS/%s@%s", my_fqdn, lp_realm());
94
asprintf(&host_princ_s[17], "CIFS/%s@%s", my_Fqdn, lp_realm());
96
/* Now try to verify the ticket using the key associated with each of
97
* the principals which we think clients will expect us to be
98
* participating as. */
99
for (i = 0; i < sizeof(host_princ_s) / sizeof(host_princ_s[0]); i++) {
101
ret = krb5_parse_name(context, host_princ_s[i], &host_princ);
103
DEBUG(1, ("ads_keytab_verify_ticket: krb5_parse_name(%s) failed (%s)\n",
104
host_princ_s[i], error_message(ret)));
62
asprintf(&valid_princ_formats[0], "%s$@%s", my_name, lp_realm());
63
asprintf(&valid_princ_formats[1], "host/%s@%s", my_name, lp_realm());
64
asprintf(&valid_princ_formats[2], "host/%s@%s", my_fqdn, lp_realm());
65
asprintf(&valid_princ_formats[3], "host/%s.%s@%s", my_name, lp_realm(), lp_realm());
66
asprintf(&valid_princ_formats[4], "cifs/%s@%s", my_name, lp_realm());
67
asprintf(&valid_princ_formats[5], "cifs/%s@%s", my_fqdn, lp_realm());
68
asprintf(&valid_princ_formats[6], "cifs/%s.%s@%s", my_name, lp_realm(), lp_realm());
70
ZERO_STRUCT(kt_entry);
71
ZERO_STRUCT(kt_cursor);
73
ret = krb5_kt_default(context, &keytab);
75
DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_default failed (%s)\n", error_message(ret)));
79
/* Iterate through the keytab. For each key, if the principal
80
* name case-insensitively matches one of the allowed formats,
81
* try verifying the ticket using that principal. */
83
ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor);
85
DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_start_seq_get failed (%s)\n", error_message(ret)));
89
ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor);
90
if (ret != KRB5_KT_END && ret != ENOENT ) {
91
while (!auth_ok && (krb5_kt_next_entry(context, keytab, &kt_entry, &kt_cursor) == 0)) {
92
ret = krb5_unparse_name(context, kt_entry.principal, &entry_princ_s);
94
DEBUG(1, ("ads_keytab_verify_ticket: krb5_unparse_name failed (%s)\n", error_message(ret)));
98
for (i = 0; i < sizeof(valid_princ_formats) / sizeof(valid_princ_formats[0]); i++) {
99
if (strequal(entry_princ_s, valid_princ_formats[i])) {
100
number_matched_principals++;
101
p_packet->length = ticket->length;
102
p_packet->data = (krb5_pointer)ticket->data;
104
ret = krb5_rd_req(context, &auth_context, p_packet, kt_entry.principal, keytab, NULL, pp_tkt);
106
DEBUG(10, ("ads_keytab_verify_ticket: krb5_rd_req(%s) failed: %s\n",
107
entry_princ_s, error_message(ret)));
109
DEBUG(3,("ads_keytab_verify_ticket: krb5_rd_req succeeded for principal %s\n",
117
/* Free the name we parsed. */
118
krb5_free_unparsed_name(context, entry_princ_s);
119
entry_princ_s = NULL;
121
/* Free the entry we just read. */
122
smb_krb5_kt_free_entry(context, &kt_entry);
123
ZERO_STRUCT(kt_entry);
107
p_packet->length = ticket->length;
108
p_packet->data = (krb5_pointer)ticket->data;
110
ret = krb5_rd_req(context, &auth_context, p_packet, host_princ, keytab, NULL, pp_tkt);
111
krb5_free_principal(context, host_princ);
113
DEBUG(0, ("krb5_rd_req(%s) failed: %s\n", host_princ_s[i], error_message(ret)));
125
krb5_kt_end_seq_get(context, keytab, &kt_cursor);
128
ZERO_STRUCT(kt_cursor);
133
if (!number_matched_principals) {
134
DEBUG(3, ("ads_keytab_verify_ticket: no keytab principals matched expected file service name.\n"));
115
DEBUG(10,("krb5_rd_req succeeded for principal %s\n", host_princ_s[i]));
121
for (i = 0; i < sizeof(host_princ_s) / sizeof(host_princ_s[0]); i++) {
122
SAFE_FREE(host_princ_s[i]);
136
DEBUG(3, ("ads_keytab_verify_ticket: krb5_rd_req failed for all %d matched keytab principals\n",
137
number_matched_principals));
142
krb5_free_unparsed_name(context, entry_princ_s);
146
krb5_keytab_entry zero_kt_entry;
147
ZERO_STRUCT(zero_kt_entry);
148
if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) {
149
smb_krb5_kt_free_entry(context, &kt_entry);
154
krb5_kt_cursor zero_csr;
155
ZERO_STRUCT(zero_csr);
156
if ((memcmp(&kt_cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) {
157
krb5_kt_end_seq_get(context, keytab, &kt_cursor);
128
162
krb5_kt_close(context, keytab);