xref: /freebsd/crypto/heimdal/appl/afsutil/afslog.c (revision 6a068746777241722b2b32c5d0bc443a2a64d80b)
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