4 krb5_cc_copy_creds_except(context, incc, outcc, princ)
15 flags = 0; /* turns off OPENCLOSE mode */
16 if ((code = krb5_cc_set_flags(context, incc, flags)))
18 if ((code = krb5_cc_set_flags(context, outcc, flags)))
21 if ((code = krb5_cc_start_seq_get(context, incc, &cur)))
24 while (!(code = krb5_cc_next_cred(context, incc, &cur, &creds))) {
25 if (krb5_principal_compare(context, princ, creds.server))
28 code = krb5_cc_store_cred(context, outcc, &creds);
29 krb5_free_cred_contents(context, &creds);
34 if (code != KRB5_CC_END)
40 flags = KRB5_TC_OPENCLOSE;
43 krb5_cc_set_flags(context, incc, flags);
45 code = krb5_cc_set_flags(context, incc, flags);
48 krb5_cc_set_flags(context, outcc, flags);
50 code = krb5_cc_set_flags(context, outcc, flags);
55 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
56 krb5_verify_init_creds(krb5_context context,
58 krb5_principal server_arg,
59 krb5_keytab keytab_arg,
60 krb5_ccache *ccache_arg,
61 krb5_verify_init_creds_opt *options)
64 krb5_principal server;
67 krb5_keytab_entry kte;
68 krb5_creds in_creds, *out_creds;
69 krb5_auth_context authcon;
72 /* KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN */
84 if (ret = krb5_sname_to_principal(context, NULL, NULL,
85 KRB5_NT_SRV_HST, &server))
89 /* first, check if the server is in the keytab. If not, there's
90 no reason to continue. rd_req does all this, but there's
91 no way to know that a given error is caused by a missing
92 keytab or key, and not by some other problem. */
97 if (ret = krb5_kt_default(context, &keytab))
101 if (ret = krb5_kt_get_entry(context, keytab, server, 0, 0, &kte)) {
102 /* this means there is no keying material. This is ok, as long as
103 it is not prohibited by the configuration */
105 krb5_error_code ret2;
109 (options->flags & KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL)) {
110 if (options->ap_req_nofail)
112 } else if ((ret2 = krb5_libdefault_boolean(context,
113 &creds->client->realm,
114 "verify_ap_req_nofail",
125 krb5_kt_free_entry(context, &kte);
127 /* If the creds are for the server principal, we're set, just do
128 a mk_req. Otherwise, do a get_credentials first. */
130 if (krb5_principal_compare(context, server, creds->server)) {
132 if (ret = krb5_mk_req_extended(context, &authcon, 0, NULL, creds,
136 /* this is unclean, but it's the easiest way without ripping the
137 library into very small pieces. store the client's initial cred
138 in a memory ccache, then call the library. Later, we'll copy
139 everything except the initial cred into the ccache we return to
140 the user. A clean implementation would involve library
141 internals with a coherent idea of "in" and "out". */
143 /* insert the initial cred into the ccache */
145 if (ret = krb5_cc_resolve(context, "MEMORY:rd_req", &ccache))
148 if (ret = krb5_cc_initialize(context, ccache, creds->client))
151 if (ret = krb5_cc_store_cred(context, ccache, creds))
154 /* set up for get_creds */
155 memset(&in_creds, 0, sizeof(in_creds));
156 in_creds.client = creds->client;
157 in_creds.server = server;
158 if (ret = krb5_timeofday(context, &in_creds.times.endtime))
160 in_creds.times.endtime += 5*60;
162 if (ret = krb5_get_credentials(context, 0, ccache, &in_creds,
167 if (ret = krb5_mk_req_extended(context, &authcon, 0, NULL, out_creds,
172 /* wipe the auth context for mk_req */
174 krb5_auth_con_free(context, authcon);
178 /* verify the ap_req */
180 if (ret = krb5_rd_req(context, &authcon, &ap_req, server, keytab,
184 /* if we get this far, then the verification succeeded. We can
185 still fail if the library stuff here fails, but that's it */
187 if (ccache_arg && ccache) {
188 if (*ccache_arg == NULL) {
193 if ((ret = krb5_cc_resolve(context, "MEMORY:rd_req2", &retcc)) ||
194 (ret = krb5_cc_initialize(context, retcc, creds->client)) ||
195 (ret = krb5_cc_copy_creds_except(context, ccache, retcc,
198 krb5_cc_destroy(context, retcc);
203 ret = krb5_cc_copy_creds_except(context, ccache, *ccache_arg,
208 /* if any of the above paths returned an errors, then ret is set
209 accordingly. either that, or it's zero, which is fine, too */
212 if (!server_arg && server)
213 krb5_free_principal(context, server);
214 if (!keytab_arg && keytab)
215 krb5_kt_close(context, keytab);
217 krb5_cc_destroy(context, ccache);
219 krb5_free_creds(context, out_creds);
221 krb5_auth_con_free(context, authcon);
223 krb5_xfree(ap_req.data);