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
40 #include <parse_units.h>
41 #include <parse_time.h>
43 static int krbtgt_only_flag
;
44 static char *service_string
;
45 static char *enctype_string
;
46 static char *flags_string
;
47 static char *valid_string
;
48 static int fcache_version
;
50 static int version_flag
;
52 static struct getargs args
[] = {
53 { "krbtgt-only", 0, arg_flag
, &krbtgt_only_flag
,
54 "only copy local krbtgt" },
55 { "service", 0, arg_string
, &service_string
,
56 "limit to this service", "principal" },
57 { "enctype", 0, arg_string
, &enctype_string
,
58 "limit to this enctype", "enctype" },
59 { "flags", 0, arg_string
, &flags_string
,
60 "limit to these flags", "ticketflags" },
61 { "valid-for", 0, arg_string
, &valid_string
,
62 "limit to creds valid for at least this long", "time" },
63 { "fcache-version", 0, arg_integer
, &fcache_version
,
64 "file cache version to create" },
65 { "version", 0, arg_flag
, &version_flag
},
66 { "help", 'h', arg_flag
, &help_flag
}
73 sizeof(args
) / sizeof(*args
),
75 "[from-cache] to-cache");
84 for (i
= 0; i
< 32; i
++) {
92 parse_ticket_flags(krb5_context context
,
93 const char *string
, krb5_ticket_flags
*ret_flags
)
96 int flags
= parse_flags(string
, asn1_TicketFlags_units(), 0);
97 if (flags
== -1) /* XXX */
98 krb5_errx(context
, 1, "bad flags specified: \"%s\"", string
);
100 memset(&ff
, 0, sizeof(ff
));
102 if (parse_flags("proxy", asn1_TicketFlags_units(), 0) == TicketFlags2int(ff
))
103 ret_flags
->i
= flags
;
105 ret_flags
->i
= bitswap32(flags
);
109 krb5_flags whichfields
;
114 matchfunc(krb5_context context
, void *ptr
, const krb5_creds
*creds
)
116 struct ctx
*ctx
= ptr
;
117 if (krb5_compare_creds(context
, ctx
->whichfields
, &ctx
->mcreds
, creds
))
123 main(int argc
, char **argv
)
126 krb5_context context
;
128 const char *from_name
, *to_name
;
129 krb5_ccache from_ccache
, to_ccache
;
130 unsigned int matched
;
133 setprogname(argv
[0]);
135 memset(&ctx
, 0, sizeof(ctx
));
137 if (getarg(args
, sizeof(args
) / sizeof(args
[0]), argc
, argv
, &optidx
))
150 if (argc
< 1 || argc
> 2)
153 if (krb5_init_context(&context
))
154 errx(1, "krb5_init_context failed");
156 if (service_string
) {
157 ret
= krb5_parse_name(context
, service_string
, &ctx
.mcreds
.server
);
159 krb5_err(context
, 1, ret
, "%s", service_string
);
161 if (enctype_string
) {
162 krb5_enctype enctype
;
163 ret
= krb5_string_to_enctype(context
, enctype_string
, &enctype
);
165 krb5_err(context
, 1, ret
, "%s", enctype_string
);
166 ctx
.whichfields
|= KRB5_TC_MATCH_KEYTYPE
;
167 ctx
.mcreds
.session
.keytype
= enctype
;
170 parse_ticket_flags(context
, flags_string
, &ctx
.mcreds
.flags
);
171 ctx
.whichfields
|= KRB5_TC_MATCH_FLAGS
;
174 time_t t
= parse_time(valid_string
, "s");
176 errx(1, "unknown time \"%s\"", valid_string
);
177 ctx
.mcreds
.times
.endtime
= time(NULL
) + t
;
178 ctx
.whichfields
|= KRB5_TC_MATCH_TIMES
;
181 krb5_set_fcache_version(context
, fcache_version
);
184 from_name
= krb5_cc_default_name(context
);
191 ret
= krb5_cc_resolve(context
, from_name
, &from_ccache
);
193 krb5_err(context
, 1, ret
, "%s", from_name
);
195 if (krbtgt_only_flag
) {
196 krb5_principal client
;
197 ret
= krb5_cc_get_principal(context
, from_ccache
, &client
);
199 krb5_err(context
, 1, ret
, "getting default principal");
200 ret
= krb5_make_principal(context
, &ctx
.mcreds
.server
,
201 krb5_principal_get_realm(context
, client
),
203 krb5_principal_get_realm(context
, client
),
206 krb5_err(context
, 1, ret
, "constructing krbtgt principal");
207 krb5_free_principal(context
, client
);
209 ret
= krb5_cc_resolve(context
, to_name
, &to_ccache
);
211 krb5_err(context
, 1, ret
, "%s", to_name
);
213 ret
= krb5_cc_copy_match_f(context
, from_ccache
, to_ccache
,
214 matchfunc
, &ctx
, &matched
);
216 krb5_err(context
, 1, ret
, "copying cred cache");
218 krb5_cc_close(context
, from_ccache
);
220 krb5_cc_destroy(context
, to_ccache
);
222 krb5_cc_close(context
, to_ccache
);
223 krb5_free_context(context
);