~ubuntu-branches/ubuntu/lucid/samba/lucid-proposed

« back to all changes in this revision

Viewing changes to source/libads/kerberos_verify.c

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-07-21 17:53:23 UTC
  • mfrom: (0.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050721175323-m3oh6aoigywohfnq
Tags: 3.0.14a-6ubuntu1
Resynchronise with Debian, resolving merge conflicts (#12360)

Show diffs side-by-side

added added

removed removed

Lines of Context:
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;
47
 
        char *p_fqdn;
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;
50
50
        int i;
51
 
 
52
 
        ret = krb5_kt_default(context, &keytab);
53
 
        if (ret) {
54
 
                DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_default failed (%s)\n", error_message(ret)));
55
 
                goto out;
56
 
        }
57
 
 
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;
 
52
 
 
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}. */
60
56
 
61
57
        fstrcpy(my_name, global_myname());
62
 
        strlower_m(my_name);
63
 
 
64
 
        fstrcpy(my_NAME, global_myname());
65
 
        strupper_m(my_NAME);
66
58
 
67
59
        my_fqdn[0] = '\0';
68
60
        name_to_fqdn(my_fqdn, global_myname());
69
 
        strlower_m(my_fqdn);
70
 
 
71
 
        p_fqdn = strchr_m(my_fqdn, '.');
72
 
        fstrcpy(my_Fqdn, my_NAME);
73
 
        if (p_fqdn) {
74
 
                fstrcat(my_Fqdn, p_fqdn);
75
 
        }
76
 
 
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());
95
 
 
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++) {
100
 
                host_princ = NULL;
101
 
                ret = krb5_parse_name(context, host_princ_s[i], &host_princ);
102
 
                if (ret) {
103
 
                        DEBUG(1, ("ads_keytab_verify_ticket: krb5_parse_name(%s) failed (%s)\n",
104
 
                                host_princ_s[i], error_message(ret)));
105
 
                        goto out;
 
61
 
 
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());
 
69
 
 
70
        ZERO_STRUCT(kt_entry);
 
71
        ZERO_STRUCT(kt_cursor);
 
72
 
 
73
        ret = krb5_kt_default(context, &keytab);
 
74
        if (ret) {
 
75
                DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_default failed (%s)\n", error_message(ret)));
 
76
                goto out;
 
77
        }
 
78
 
 
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. */
 
82
 
 
83
        ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor);
 
84
        if (ret) {
 
85
                DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_start_seq_get failed (%s)\n", error_message(ret)));
 
86
                goto out;
 
87
        }
 
88
  
 
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);
 
93
                        if (ret) {
 
94
                                DEBUG(1, ("ads_keytab_verify_ticket: krb5_unparse_name failed (%s)\n", error_message(ret)));
 
95
                                goto out;
 
96
                        }
 
97
 
 
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;
 
103
                                        *pp_tkt = NULL;
 
104
                                        ret = krb5_rd_req(context, &auth_context, p_packet, kt_entry.principal, keytab, NULL, pp_tkt);
 
105
                                        if (ret) {
 
106
                                                DEBUG(10, ("ads_keytab_verify_ticket: krb5_rd_req(%s) failed: %s\n",
 
107
                                                        entry_princ_s, error_message(ret)));
 
108
                                        } else {
 
109
                                                DEBUG(3,("ads_keytab_verify_ticket: krb5_rd_req succeeded for principal %s\n",
 
110
                                                        entry_princ_s));
 
111
                                                auth_ok = True;
 
112
                                                break;
 
113
                                        }
 
114
                                }
 
115
                        }
 
116
 
 
117
                        /* Free the name we parsed. */
 
118
                        krb5_free_unparsed_name(context, entry_princ_s);
 
119
                        entry_princ_s = NULL;
 
120
 
 
121
                        /* Free the entry we just read. */
 
122
                        smb_krb5_kt_free_entry(context, &kt_entry);
 
123
                        ZERO_STRUCT(kt_entry);
106
124
                }
107
 
                p_packet->length = ticket->length;
108
 
                p_packet->data = (krb5_pointer)ticket->data;
109
 
                *pp_tkt = NULL;
110
 
                ret = krb5_rd_req(context, &auth_context, p_packet, host_princ, keytab, NULL, pp_tkt);
111
 
                krb5_free_principal(context, host_princ);
112
 
                if (ret) {
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);
 
126
        }
 
127
 
 
128
        ZERO_STRUCT(kt_cursor);
 
129
 
 
130
  out:
 
131
 
 
132
        if (!auth_ok) {
 
133
                if (!number_matched_principals) {
 
134
                        DEBUG(3, ("ads_keytab_verify_ticket: no keytab principals matched expected file service name.\n"));
114
135
                } else {
115
 
                        DEBUG(10,("krb5_rd_req succeeded for principal %s\n", host_princ_s[i]));
116
 
                        auth_ok = True;
117
 
                        break;
118
 
                }
119
 
        }
120
 
 
121
 
        for (i = 0; i < sizeof(host_princ_s) / sizeof(host_princ_s[0]); i++) {
122
 
                SAFE_FREE(host_princ_s[i]);
123
 
        }
124
 
 
125
 
  out:
 
136
                        DEBUG(3, ("ads_keytab_verify_ticket: krb5_rd_req failed for all %d matched keytab principals\n",
 
137
                                number_matched_principals));
 
138
                }
 
139
        }
 
140
 
 
141
        if (entry_princ_s) {
 
142
                krb5_free_unparsed_name(context, entry_princ_s);
 
143
        }
 
144
 
 
145
        {
 
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);
 
150
                }
 
151
        }
 
152
 
 
153
        {
 
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);
 
158
                }
 
159
        }
126
160
 
127
161
        if (keytab) {
128
162
                krb5_kt_close(context, keytab);