1*0a6a1f1dSLionel Sambuc /* $NetBSD: kswitch.c,v 1.1.1.2 2014/04/24 12:45:28 pettai Exp $ */
2ebfedea0SLionel Sambuc
3ebfedea0SLionel Sambuc /*
4ebfedea0SLionel Sambuc * Copyright (c) 2008 - 2010 Kungliga Tekniska Högskolan
5ebfedea0SLionel Sambuc * (Royal Institute of Technology, Stockholm, Sweden).
6ebfedea0SLionel Sambuc * All rights reserved.
7ebfedea0SLionel Sambuc *
8ebfedea0SLionel Sambuc * Redistribution and use in source and binary forms, with or without
9ebfedea0SLionel Sambuc * modification, are permitted provided that the following conditions
10ebfedea0SLionel Sambuc * are met:
11ebfedea0SLionel Sambuc *
12ebfedea0SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
13ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer.
14ebfedea0SLionel Sambuc *
15ebfedea0SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
16ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer in the
17ebfedea0SLionel Sambuc * documentation and/or other materials provided with the distribution.
18ebfedea0SLionel Sambuc *
19ebfedea0SLionel Sambuc * 3. Neither the name of the Institute nor the names of its contributors
20ebfedea0SLionel Sambuc * may be used to endorse or promote products derived from this software
21ebfedea0SLionel Sambuc * without specific prior written permission.
22ebfedea0SLionel Sambuc *
23ebfedea0SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24ebfedea0SLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25ebfedea0SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ebfedea0SLionel Sambuc * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27ebfedea0SLionel Sambuc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28ebfedea0SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29ebfedea0SLionel Sambuc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30ebfedea0SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31ebfedea0SLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32ebfedea0SLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33ebfedea0SLionel Sambuc * SUCH DAMAGE.
34ebfedea0SLionel Sambuc */
35ebfedea0SLionel Sambuc
36ebfedea0SLionel Sambuc #include "kuser_locl.h"
37ebfedea0SLionel Sambuc #include "kcc-commands.h"
38ebfedea0SLionel Sambuc
39ebfedea0SLionel Sambuc #ifdef HAVE_READLINE
40*0a6a1f1dSLionel Sambuc char *readline(const char *prompt);
41ebfedea0SLionel Sambuc #else
42ebfedea0SLionel Sambuc
43ebfedea0SLionel Sambuc static char *
readline(const char * prompt)44*0a6a1f1dSLionel Sambuc readline(const char *prompt)
45ebfedea0SLionel Sambuc {
46ebfedea0SLionel Sambuc char buf[BUFSIZ];
47ebfedea0SLionel Sambuc printf ("%s", prompt);
48ebfedea0SLionel Sambuc fflush (stdout);
49ebfedea0SLionel Sambuc if(fgets(buf, sizeof(buf), stdin) == NULL)
50ebfedea0SLionel Sambuc return NULL;
51ebfedea0SLionel Sambuc buf[strcspn(buf, "\r\n")] = '\0';
52ebfedea0SLionel Sambuc return strdup(buf);
53ebfedea0SLionel Sambuc }
54ebfedea0SLionel Sambuc
55ebfedea0SLionel Sambuc #endif
56ebfedea0SLionel Sambuc
57ebfedea0SLionel Sambuc /*
58ebfedea0SLionel Sambuc *
59ebfedea0SLionel Sambuc */
60ebfedea0SLionel Sambuc
61ebfedea0SLionel Sambuc int
kswitch(struct kswitch_options * opt,int argc,char ** argv)62ebfedea0SLionel Sambuc kswitch(struct kswitch_options *opt, int argc, char **argv)
63ebfedea0SLionel Sambuc {
64ebfedea0SLionel Sambuc krb5_error_code ret;
65ebfedea0SLionel Sambuc krb5_ccache id = NULL;
66ebfedea0SLionel Sambuc
67ebfedea0SLionel Sambuc if (opt->cache_string && opt->principal_string)
68ebfedea0SLionel Sambuc krb5_errx(kcc_context, 1,
69ebfedea0SLionel Sambuc N_("Both --cache and --principal given, choose one", ""));
70ebfedea0SLionel Sambuc
71ebfedea0SLionel Sambuc if (opt->interactive_flag) {
72ebfedea0SLionel Sambuc krb5_cc_cache_cursor cursor;
73ebfedea0SLionel Sambuc krb5_ccache *ids = NULL;
74ebfedea0SLionel Sambuc size_t i, len = 0;
75ebfedea0SLionel Sambuc char *name;
76ebfedea0SLionel Sambuc rtbl_t ct;
77ebfedea0SLionel Sambuc
78ebfedea0SLionel Sambuc ct = rtbl_create();
79ebfedea0SLionel Sambuc
80*0a6a1f1dSLionel Sambuc rtbl_add_column_by_id(ct, 0, "#", 0);
81*0a6a1f1dSLionel Sambuc rtbl_add_column_by_id(ct, 1, "Principal", 0);
82*0a6a1f1dSLionel Sambuc rtbl_set_column_affix_by_id(ct, 1, " ", "");
83*0a6a1f1dSLionel Sambuc rtbl_add_column_by_id(ct, 2, "Type", 0);
84*0a6a1f1dSLionel Sambuc rtbl_set_column_affix_by_id(ct, 2, " ", "");
85ebfedea0SLionel Sambuc
86ebfedea0SLionel Sambuc ret = krb5_cc_cache_get_first(kcc_context, NULL, &cursor);
87ebfedea0SLionel Sambuc if (ret)
88ebfedea0SLionel Sambuc krb5_err(kcc_context, 1, ret, "krb5_cc_cache_get_first");
89ebfedea0SLionel Sambuc
90ebfedea0SLionel Sambuc while (krb5_cc_cache_next(kcc_context, cursor, &id) == 0) {
91ebfedea0SLionel Sambuc krb5_principal p;
92ebfedea0SLionel Sambuc char num[10];
93ebfedea0SLionel Sambuc
94ebfedea0SLionel Sambuc ret = krb5_cc_get_principal(kcc_context, id, &p);
95ebfedea0SLionel Sambuc if (ret)
96ebfedea0SLionel Sambuc continue;
97ebfedea0SLionel Sambuc
98ebfedea0SLionel Sambuc ret = krb5_unparse_name(kcc_context, p, &name);
99ebfedea0SLionel Sambuc krb5_free_principal(kcc_context, p);
100ebfedea0SLionel Sambuc
101ebfedea0SLionel Sambuc snprintf(num, sizeof(num), "%d", (int)(len + 1));
102*0a6a1f1dSLionel Sambuc rtbl_add_column_entry_by_id(ct, 0, num);
103*0a6a1f1dSLionel Sambuc rtbl_add_column_entry_by_id(ct, 1, name);
104*0a6a1f1dSLionel Sambuc rtbl_add_column_entry_by_id(ct, 2, krb5_cc_get_type(kcc_context, id));
105ebfedea0SLionel Sambuc free(name);
106ebfedea0SLionel Sambuc
107ebfedea0SLionel Sambuc ids = erealloc(ids, (len + 1) * sizeof(ids[0]));
108ebfedea0SLionel Sambuc ids[len] = id;
109ebfedea0SLionel Sambuc len++;
110ebfedea0SLionel Sambuc }
111ebfedea0SLionel Sambuc krb5_cc_cache_end_seq_get(kcc_context, cursor);
112ebfedea0SLionel Sambuc
113ebfedea0SLionel Sambuc rtbl_format(ct, stdout);
114ebfedea0SLionel Sambuc rtbl_destroy(ct);
115ebfedea0SLionel Sambuc
116ebfedea0SLionel Sambuc name = readline("Select number: ");
117ebfedea0SLionel Sambuc if (name) {
118ebfedea0SLionel Sambuc i = atoi(name);
119ebfedea0SLionel Sambuc if (i == 0)
120ebfedea0SLionel Sambuc krb5_errx(kcc_context, 1, "Cache number '%s' is invalid", name);
121ebfedea0SLionel Sambuc if (i > len)
122ebfedea0SLionel Sambuc krb5_errx(kcc_context, 1, "Cache number '%s' is too large", name);
123ebfedea0SLionel Sambuc
124ebfedea0SLionel Sambuc id = ids[i - 1];
125ebfedea0SLionel Sambuc ids[i - 1] = NULL;
126ebfedea0SLionel Sambuc } else
127ebfedea0SLionel Sambuc krb5_errx(kcc_context, 1, "No cache selected");
128ebfedea0SLionel Sambuc for (i = 0; i < len; i++)
129ebfedea0SLionel Sambuc if (ids[i])
130ebfedea0SLionel Sambuc krb5_cc_close(kcc_context, ids[i]);
131ebfedea0SLionel Sambuc
132ebfedea0SLionel Sambuc } else if (opt->principal_string) {
133ebfedea0SLionel Sambuc krb5_principal p;
134ebfedea0SLionel Sambuc
135ebfedea0SLionel Sambuc ret = krb5_parse_name(kcc_context, opt->principal_string, &p);
136ebfedea0SLionel Sambuc if (ret)
137ebfedea0SLionel Sambuc krb5_err(kcc_context, 1, ret, "krb5_parse_name: %s",
138ebfedea0SLionel Sambuc opt->principal_string);
139ebfedea0SLionel Sambuc
140ebfedea0SLionel Sambuc ret = krb5_cc_cache_match(kcc_context, p, &id);
141ebfedea0SLionel Sambuc if (ret)
142ebfedea0SLionel Sambuc krb5_err(kcc_context, 1, ret,
143ebfedea0SLionel Sambuc N_("Did not find principal: %s", ""),
144ebfedea0SLionel Sambuc opt->principal_string);
145ebfedea0SLionel Sambuc
146ebfedea0SLionel Sambuc krb5_free_principal(kcc_context, p);
147ebfedea0SLionel Sambuc
148ebfedea0SLionel Sambuc } else if (opt->cache_string) {
149ebfedea0SLionel Sambuc const krb5_cc_ops *ops;
150ebfedea0SLionel Sambuc char *str;
151ebfedea0SLionel Sambuc
152ebfedea0SLionel Sambuc ops = krb5_cc_get_prefix_ops(kcc_context, opt->type_string);
153ebfedea0SLionel Sambuc if (ops == NULL)
154ebfedea0SLionel Sambuc krb5_err(kcc_context, 1, 0, "krb5_cc_get_prefix_ops");
155ebfedea0SLionel Sambuc
156ebfedea0SLionel Sambuc asprintf(&str, "%s:%s", ops->prefix, opt->cache_string);
157ebfedea0SLionel Sambuc if (str == NULL)
158ebfedea0SLionel Sambuc krb5_errx(kcc_context, 1, N_("out of memory", ""));
159ebfedea0SLionel Sambuc
160ebfedea0SLionel Sambuc ret = krb5_cc_resolve(kcc_context, str, &id);
161ebfedea0SLionel Sambuc if (ret)
162ebfedea0SLionel Sambuc krb5_err(kcc_context, 1, ret, "krb5_cc_resolve: %s", str);
163ebfedea0SLionel Sambuc
164ebfedea0SLionel Sambuc free(str);
165ebfedea0SLionel Sambuc } else {
166ebfedea0SLionel Sambuc krb5_errx(kcc_context, 1, "missing option for kswitch");
167ebfedea0SLionel Sambuc }
168ebfedea0SLionel Sambuc
169ebfedea0SLionel Sambuc ret = krb5_cc_switch(kcc_context, id);
170ebfedea0SLionel Sambuc if (ret)
171ebfedea0SLionel Sambuc krb5_err(kcc_context, 1, ret, "krb5_cc_switch");
172ebfedea0SLionel Sambuc
173ebfedea0SLionel Sambuc return 0;
174ebfedea0SLionel Sambuc }
175