1b528cefcSMark Murray /*
2*ae771770SStanislav Sedov * Copyright (c) 1997-2003 Kungliga Tekniska Högskolan
3b528cefcSMark Murray * (Royal Institute of Technology, Stockholm, Sweden).
4b528cefcSMark Murray * All rights reserved.
5b528cefcSMark Murray *
6b528cefcSMark Murray * Redistribution and use in source and binary forms, with or without
7b528cefcSMark Murray * modification, are permitted provided that the following conditions
8b528cefcSMark Murray * are met:
9b528cefcSMark Murray *
10b528cefcSMark Murray * 1. Redistributions of source code must retain the above copyright
11b528cefcSMark Murray * notice, this list of conditions and the following disclaimer.
12b528cefcSMark Murray *
13b528cefcSMark Murray * 2. Redistributions in binary form must reproduce the above copyright
14b528cefcSMark Murray * notice, this list of conditions and the following disclaimer in the
15b528cefcSMark Murray * documentation and/or other materials provided with the distribution.
16b528cefcSMark Murray *
17b528cefcSMark Murray * 3. Neither the name of the Institute nor the names of its contributors
18b528cefcSMark Murray * may be used to endorse or promote products derived from this software
19b528cefcSMark Murray * without specific prior written permission.
20b528cefcSMark Murray *
21b528cefcSMark Murray * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22b528cefcSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23b528cefcSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24b528cefcSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25b528cefcSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26b528cefcSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27b528cefcSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28b528cefcSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29b528cefcSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30b528cefcSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31b528cefcSMark Murray * SUCH DAMAGE.
32b528cefcSMark Murray */
33b528cefcSMark Murray
34b528cefcSMark Murray #ifdef HAVE_CONFIG_H
35b528cefcSMark Murray #include <config.h>
36*ae771770SStanislav Sedov RCSID("$Id$");
37b528cefcSMark Murray #endif
38b528cefcSMark Murray #include <ctype.h>
39bbd80c28SJacques Vidrine #ifdef KRB5
40b528cefcSMark Murray #include <krb5.h>
41bbd80c28SJacques Vidrine #endif
42b528cefcSMark Murray #include <kafs.h>
43b528cefcSMark Murray #include <roken.h>
44b528cefcSMark Murray #include <getarg.h>
455e9cd1aeSAssar Westerlund #include <err.h>
46b528cefcSMark Murray
47b528cefcSMark Murray static int help_flag;
48b528cefcSMark Murray static int version_flag;
49b528cefcSMark Murray static getarg_strings cells;
50b528cefcSMark Murray static char *realm;
51b528cefcSMark Murray static getarg_strings files;
52b528cefcSMark Murray static int unlog_flag;
53b528cefcSMark Murray static int verbose;
54bbd80c28SJacques Vidrine #ifdef KRB5
55c19800e8SDoug Rabson static char *client_string;
56c19800e8SDoug Rabson static char *cache_string;
57bbd80c28SJacques Vidrine static int use_krb5 = 1;
58bbd80c28SJacques Vidrine #endif
59b528cefcSMark Murray
60b528cefcSMark Murray struct getargs args[] = {
61bbd80c28SJacques Vidrine { "cell", 'c', arg_strings, &cells, "cells to get tokens for", "cell" },
62bbd80c28SJacques Vidrine { "file", 'p', arg_strings, &files, "files to get tokens for", "path" },
63b528cefcSMark Murray { "realm", 'k', arg_string, &realm, "realm for afs cell", "realm" },
64b528cefcSMark Murray { "unlog", 'u', arg_flag, &unlog_flag, "remove tokens" },
65bbd80c28SJacques Vidrine #ifdef KRB5
66c19800e8SDoug Rabson { "principal",'P',arg_string,&client_string,"principal to use","principal"},
67c19800e8SDoug Rabson { "cache", 0, arg_string, &cache_string, "ccache to use", "cache"},
68c19800e8SDoug Rabson { "v5", 0, arg_negative_flag, &use_krb5, "don't use Kerberos 5" },
69b528cefcSMark Murray #endif
70b528cefcSMark Murray { "verbose",'v', arg_flag, &verbose },
71b528cefcSMark Murray { "version", 0, arg_flag, &version_flag },
72b528cefcSMark Murray { "help", 'h', arg_flag, &help_flag },
73b528cefcSMark Murray };
74b528cefcSMark Murray
75b528cefcSMark Murray static int num_args = sizeof(args) / sizeof(args[0]);
76b528cefcSMark Murray
77bbd80c28SJacques Vidrine #ifdef KRB5
78bbd80c28SJacques Vidrine krb5_context context;
79bbd80c28SJacques Vidrine krb5_ccache id;
80bbd80c28SJacques Vidrine #endif
81bbd80c28SJacques Vidrine
82b528cefcSMark Murray static const char *
expand_one_file(FILE * f,const char * cell)83bbd80c28SJacques Vidrine expand_one_file(FILE *f, const char *cell)
84b528cefcSMark Murray {
85bbd80c28SJacques Vidrine static char buf[1024];
86b528cefcSMark Murray char *p;
87b528cefcSMark Murray
88b528cefcSMark Murray while (fgets (buf, sizeof(buf), f) != NULL) {
89b528cefcSMark Murray if(buf[0] == '>') {
90b528cefcSMark Murray for(p = buf; *p && !isspace((unsigned char)*p) && *p != '#'; p++)
91b528cefcSMark Murray ;
92b528cefcSMark Murray *p = '\0';
93bbd80c28SJacques Vidrine if(strncmp(buf + 1, cell, strlen(cell)) == 0)
94b528cefcSMark Murray return buf + 1;
95b528cefcSMark Murray }
96bbd80c28SJacques Vidrine buf[0] = '\0';
97b528cefcSMark Murray }
98bbd80c28SJacques Vidrine return NULL;
99b528cefcSMark Murray }
100bbd80c28SJacques Vidrine
101bbd80c28SJacques Vidrine static const char *
expand_cell_name(const char * cell)102bbd80c28SJacques Vidrine expand_cell_name(const char *cell)
103bbd80c28SJacques Vidrine {
104bbd80c28SJacques Vidrine FILE *f;
105bbd80c28SJacques Vidrine const char *c;
106bbd80c28SJacques Vidrine const char **fn, *files[] = { _PATH_CELLSERVDB,
107bbd80c28SJacques Vidrine _PATH_ARLA_CELLSERVDB,
108bbd80c28SJacques Vidrine _PATH_OPENAFS_DEBIAN_CELLSERVDB,
109bbd80c28SJacques Vidrine _PATH_ARLA_DEBIAN_CELLSERVDB,
110bbd80c28SJacques Vidrine NULL };
111bbd80c28SJacques Vidrine for(fn = files; *fn; fn++) {
112bbd80c28SJacques Vidrine f = fopen(*fn, "r");
113bbd80c28SJacques Vidrine if(f == NULL)
114bbd80c28SJacques Vidrine continue;
115bbd80c28SJacques Vidrine c = expand_one_file(f, cell);
116b528cefcSMark Murray fclose(f);
117bbd80c28SJacques Vidrine if(c)
118bbd80c28SJacques Vidrine return c;
119bbd80c28SJacques Vidrine }
120b528cefcSMark Murray return cell;
121b528cefcSMark Murray }
122b528cefcSMark Murray
123b528cefcSMark Murray static void
usage(int ecode)124b528cefcSMark Murray usage(int ecode)
125b528cefcSMark Murray {
126bbd80c28SJacques Vidrine arg_printusage(args, num_args, NULL, "[cell|path]...");
127b528cefcSMark Murray exit(ecode);
128b528cefcSMark Murray }
129b528cefcSMark Murray
130bbd80c28SJacques Vidrine struct cell_list {
131bbd80c28SJacques Vidrine char *cell;
132bbd80c28SJacques Vidrine struct cell_list *next;
133bbd80c28SJacques Vidrine } *cell_list;
134bbd80c28SJacques Vidrine
135b528cefcSMark Murray static int
afslog_cell(const char * cell,int expand)136bbd80c28SJacques Vidrine afslog_cell(const char *cell, int expand)
137b528cefcSMark Murray {
138bbd80c28SJacques Vidrine struct cell_list *p, **q;
139b528cefcSMark Murray const char *c = cell;
140b528cefcSMark Murray if(expand){
141b528cefcSMark Murray c = expand_cell_name(cell);
142b528cefcSMark Murray if(c == NULL){
143bbd80c28SJacques Vidrine warnx("No cell matching \"%s\" found.", cell);
144b528cefcSMark Murray return -1;
145b528cefcSMark Murray }
146bbd80c28SJacques Vidrine if(verbose && strcmp(c, cell) != 0)
147bbd80c28SJacques Vidrine warnx("Cell \"%s\" expanded to \"%s\"", cell, c);
148b528cefcSMark Murray }
149bbd80c28SJacques Vidrine /* add to list of cells to get tokens for, and also remove
150bbd80c28SJacques Vidrine duplicates; the actual afslog takes place later */
151bbd80c28SJacques Vidrine for(p = cell_list, q = &cell_list; p; q = &p->next, p = p->next)
152bbd80c28SJacques Vidrine if(strcmp(p->cell, c) == 0)
153bbd80c28SJacques Vidrine return 0;
154bbd80c28SJacques Vidrine p = malloc(sizeof(*p));
155bbd80c28SJacques Vidrine if(p == NULL)
156bbd80c28SJacques Vidrine return -1;
157bbd80c28SJacques Vidrine p->cell = strdup(c);
158bbd80c28SJacques Vidrine if(p->cell == NULL) {
159bbd80c28SJacques Vidrine free(p);
160bbd80c28SJacques Vidrine return -1;
161bbd80c28SJacques Vidrine }
162bbd80c28SJacques Vidrine p->next = NULL;
163bbd80c28SJacques Vidrine *q = p;
164bbd80c28SJacques Vidrine return 0;
165b528cefcSMark Murray }
166b528cefcSMark Murray
167b528cefcSMark Murray static int
afslog_file(const char * path)168bbd80c28SJacques Vidrine afslog_file(const char *path)
169b528cefcSMark Murray {
170b528cefcSMark Murray char cell[64];
171b528cefcSMark Murray if(k_afs_cell_of_file(path, cell, sizeof(cell))){
172bbd80c28SJacques Vidrine warnx("No cell found for file \"%s\".", path);
173b528cefcSMark Murray return -1;
174b528cefcSMark Murray }
175b528cefcSMark Murray if(verbose)
176bbd80c28SJacques Vidrine warnx("File \"%s\" lives in cell \"%s\"", path, cell);
177bbd80c28SJacques Vidrine return afslog_cell(cell, 0);
178bbd80c28SJacques Vidrine }
179bbd80c28SJacques Vidrine
180bbd80c28SJacques Vidrine static int
do_afslog(const char * cell)181bbd80c28SJacques Vidrine do_afslog(const char *cell)
182bbd80c28SJacques Vidrine {
183*ae771770SStanislav Sedov int k5ret;
184bbd80c28SJacques Vidrine
185*ae771770SStanislav Sedov k5ret = 0;
186bbd80c28SJacques Vidrine
187bbd80c28SJacques Vidrine #ifdef KRB5
188bbd80c28SJacques Vidrine if(context != NULL && id != NULL && use_krb5) {
189c19800e8SDoug Rabson k5ret = krb5_afslog(context, id, cell, realm);
190bbd80c28SJacques Vidrine if(k5ret == 0)
191bbd80c28SJacques Vidrine return 0;
192bbd80c28SJacques Vidrine }
193bbd80c28SJacques Vidrine #endif
1941c43270aSJacques Vidrine if (cell == NULL)
1951c43270aSJacques Vidrine cell = "<default cell>";
196bbd80c28SJacques Vidrine #ifdef KRB5
197bbd80c28SJacques Vidrine if (k5ret)
198*ae771770SStanislav Sedov krb5_warn(context, k5ret, "krb5_afslog(%s)", cell);
199bbd80c28SJacques Vidrine #endif
200*ae771770SStanislav Sedov if (k5ret)
201bbd80c28SJacques Vidrine return 1;
202bbd80c28SJacques Vidrine return 0;
203bbd80c28SJacques Vidrine }
204bbd80c28SJacques Vidrine
205bbd80c28SJacques Vidrine static void
log_func(void * ctx,const char * str)206bbd80c28SJacques Vidrine log_func(void *ctx, const char *str)
207bbd80c28SJacques Vidrine {
208bbd80c28SJacques Vidrine fprintf(stderr, "%s\n", str);
209b528cefcSMark Murray }
210b528cefcSMark Murray
211b528cefcSMark Murray int
main(int argc,char ** argv)212b528cefcSMark Murray main(int argc, char **argv)
213b528cefcSMark Murray {
214b528cefcSMark Murray int optind = 0;
215b528cefcSMark Murray int i;
216b528cefcSMark Murray int num;
217b528cefcSMark Murray int ret = 0;
218bbd80c28SJacques Vidrine int failed = 0;
219bbd80c28SJacques Vidrine struct cell_list *p;
220b528cefcSMark Murray
221adb0ddaeSAssar Westerlund setprogname(argv[0]);
222b528cefcSMark Murray
223b528cefcSMark Murray if(getarg(args, num_args, argc, argv, &optind))
224b528cefcSMark Murray usage(1);
225b528cefcSMark Murray if(help_flag)
226b528cefcSMark Murray usage(0);
227b528cefcSMark Murray if(version_flag) {
228b528cefcSMark Murray print_version(NULL);
229b528cefcSMark Murray exit(0);
230b528cefcSMark Murray }
231b528cefcSMark Murray
232b528cefcSMark Murray if(!k_hasafs())
233bbd80c28SJacques Vidrine errx(1, "AFS does not seem to be present on this machine");
234b528cefcSMark Murray
235b528cefcSMark Murray if(unlog_flag){
236b528cefcSMark Murray k_unlog();
237b528cefcSMark Murray exit(0);
238b528cefcSMark Murray }
239bbd80c28SJacques Vidrine #ifdef KRB5
240bbd80c28SJacques Vidrine ret = krb5_init_context(&context);
241c19800e8SDoug Rabson if (ret) {
242bbd80c28SJacques Vidrine context = NULL;
243c19800e8SDoug Rabson } else {
244c19800e8SDoug Rabson if (client_string) {
245c19800e8SDoug Rabson krb5_principal client;
246c19800e8SDoug Rabson
247c19800e8SDoug Rabson ret = krb5_parse_name(context, client_string, &client);
248c19800e8SDoug Rabson if (ret == 0)
249*ae771770SStanislav Sedov ret = krb5_cc_cache_match(context, client, &id);
250c19800e8SDoug Rabson if (ret)
251c19800e8SDoug Rabson id = NULL;
252c19800e8SDoug Rabson }
253c19800e8SDoug Rabson if (id == NULL && cache_string) {
254c19800e8SDoug Rabson if(krb5_cc_resolve(context, cache_string, &id) != 0) {
255c19800e8SDoug Rabson krb5_warnx(context, "failed to open kerberos 5 cache '%s'",
256c19800e8SDoug Rabson cache_string);
257c19800e8SDoug Rabson id = NULL;
258c19800e8SDoug Rabson }
259c19800e8SDoug Rabson }
260c19800e8SDoug Rabson if (id == NULL)
261bbd80c28SJacques Vidrine if(krb5_cc_default(context, &id) != 0)
262bbd80c28SJacques Vidrine id = NULL;
263c19800e8SDoug Rabson }
264bbd80c28SJacques Vidrine #endif
265bbd80c28SJacques Vidrine
266bbd80c28SJacques Vidrine if (verbose)
267bbd80c28SJacques Vidrine kafs_set_verbose(log_func, NULL);
268bbd80c28SJacques Vidrine
269b528cefcSMark Murray num = 0;
270b528cefcSMark Murray for(i = 0; i < files.num_strings; i++){
271bbd80c28SJacques Vidrine afslog_file(files.strings[i]);
272b528cefcSMark Murray num++;
273bbd80c28SJacques Vidrine }
274adb0ddaeSAssar Westerlund free_getarg_strings (&files);
275b528cefcSMark Murray for(i = 0; i < cells.num_strings; i++){
276bbd80c28SJacques Vidrine afslog_cell(cells.strings[i], 1);
277b528cefcSMark Murray num++;
278b528cefcSMark Murray }
279bbd80c28SJacques Vidrine free_getarg_strings (&cells);
280b528cefcSMark Murray for(i = optind; i < argc; i++){
281b528cefcSMark Murray num++;
282b528cefcSMark Murray if(strcmp(argv[i], ".") == 0 ||
283b528cefcSMark Murray strcmp(argv[i], "..") == 0 ||
284b528cefcSMark Murray strchr(argv[i], '/') ||
285b528cefcSMark Murray access(argv[i], F_OK) == 0)
286bbd80c28SJacques Vidrine afslog_file(argv[i]);
287b528cefcSMark Murray else
288bbd80c28SJacques Vidrine afslog_cell(argv[i], 1);
289b528cefcSMark Murray }
290b528cefcSMark Murray if(num == 0) {
291bbd80c28SJacques Vidrine if(do_afslog(NULL))
292bbd80c28SJacques Vidrine failed++;
293bbd80c28SJacques Vidrine } else
294bbd80c28SJacques Vidrine for(p = cell_list; p; p = p->next) {
295bbd80c28SJacques Vidrine if(verbose)
296bbd80c28SJacques Vidrine warnx("Getting tokens for cell \"%s\"", p->cell);
297bbd80c28SJacques Vidrine if(do_afslog(p->cell))
298bbd80c28SJacques Vidrine failed++;
299b528cefcSMark Murray }
300b528cefcSMark Murray
301bbd80c28SJacques Vidrine return failed;
302b528cefcSMark Murray }
303