2 * Copyright (c) 2004 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 #include <parse_units.h>
44 #include <parse_time.h>
46 static int krbtgt_only_flag
;
47 static char *service_string
;
48 static char *enctype_string
;
49 static char *flags_string
;
50 static char *valid_string
;
51 static int fcache_version
;
53 static int version_flag
;
55 static struct getargs args
[] = {
56 { "krbtgt-only", 0, arg_flag
, &krbtgt_only_flag
,
57 "only copy local krbtgt" },
58 { "service", 0, arg_string
, &service_string
,
59 "limit to this service", "principal" },
60 { "enctype", 0, arg_string
, &enctype_string
,
61 "limit to this enctype", "enctype" },
62 { "flags", 0, arg_string
, &flags_string
,
63 "limit to these flags", "ticketflags" },
64 { "valid-for", 0, arg_string
, &valid_string
,
65 "limit to creds valid for at least this long", "time" },
66 { "fcache-version", 0, arg_integer
, &fcache_version
,
67 "file cache version to create" },
68 { "version", 0, arg_flag
, &version_flag
},
69 { "help", 'h', arg_flag
, &help_flag
}
76 sizeof(args
) / sizeof(*args
),
78 "[from-cache] to-cache");
87 for (i
= 0; i
< 32; i
++) {
95 parse_ticket_flags(krb5_context context
,
96 const char *string
, krb5_ticket_flags
*ret_flags
)
99 int flags
= parse_flags(string
, asn1_TicketFlags_units(), 0);
100 if (flags
== -1) /* XXX */
101 krb5_errx(context
, 1, "bad flags specified: \"%s\"", string
);
103 memset(&ff
, 0, sizeof(ff
));
105 if (parse_flags("proxy", asn1_TicketFlags_units(), 0) == TicketFlags2int(ff
))
106 ret_flags
->i
= flags
;
108 ret_flags
->i
= bitswap32(flags
);
112 krb5_flags whichfields
;
117 matchfunc(krb5_context context
, void *ptr
, const krb5_creds
*creds
)
119 struct ctx
*ctx
= ptr
;
120 if (krb5_compare_creds(context
, ctx
->whichfields
, &ctx
->mcreds
, creds
))
126 main(int argc
, char **argv
)
129 krb5_context context
;
131 const char *from_name
, *to_name
;
132 krb5_ccache from_ccache
, to_ccache
;
133 unsigned int matched
;
136 setprogname(argv
[0]);
138 memset(&ctx
, 0, sizeof(ctx
));
140 if (getarg(args
, sizeof(args
) / sizeof(args
[0]), argc
, argv
, &optidx
))
153 if (argc
< 1 || argc
> 2)
156 if (krb5_init_context(&context
))
157 errx(1, "krb5_init_context failed");
159 if (service_string
) {
160 ret
= krb5_parse_name(context
, service_string
, &ctx
.mcreds
.server
);
162 krb5_err(context
, 1, ret
, "%s", service_string
);
164 if (enctype_string
) {
165 krb5_enctype enctype
;
166 ret
= krb5_string_to_enctype(context
, enctype_string
, &enctype
);
168 krb5_err(context
, 1, ret
, "%s", enctype_string
);
169 ctx
.whichfields
|= KRB5_TC_MATCH_KEYTYPE
;
170 ctx
.mcreds
.session
.keytype
= enctype
;
173 parse_ticket_flags(context
, flags_string
, &ctx
.mcreds
.flags
);
174 ctx
.whichfields
|= KRB5_TC_MATCH_FLAGS
;
177 time_t t
= parse_time(valid_string
, "s");
179 errx(1, "unknown time \"%s\"", valid_string
);
180 ctx
.mcreds
.times
.endtime
= time(NULL
) + t
;
181 ctx
.whichfields
|= KRB5_TC_MATCH_TIMES
;
184 krb5_set_fcache_version(context
, fcache_version
);
187 from_name
= krb5_cc_default_name(context
);
194 ret
= krb5_cc_resolve(context
, from_name
, &from_ccache
);
196 krb5_err(context
, 1, ret
, "%s", from_name
);
198 if (krbtgt_only_flag
) {
199 krb5_principal client
;
200 ret
= krb5_cc_get_principal(context
, from_ccache
, &client
);
202 krb5_err(context
, 1, ret
, "getting default principal");
203 ret
= krb5_make_principal(context
, &ctx
.mcreds
.server
,
204 krb5_principal_get_realm(context
, client
),
206 krb5_principal_get_realm(context
, client
),
209 krb5_err(context
, 1, ret
, "constructing krbtgt principal");
210 krb5_free_principal(context
, client
);
212 ret
= krb5_cc_resolve(context
, to_name
, &to_ccache
);
214 krb5_err(context
, 1, ret
, "%s", to_name
);
216 ret
= krb5_cc_copy_match_f(context
, from_ccache
, to_ccache
,
217 matchfunc
, &ctx
, &matched
);
219 krb5_err(context
, 1, ret
, "copying cred cache");
221 krb5_cc_close(context
, from_ccache
);
223 krb5_cc_destroy(context
, to_ccache
);
225 krb5_cc_close(context
, to_ccache
);
226 krb5_free_context(context
);