xref: /freebsd/crypto/heimdal/appl/afsutil/afslog.c (revision c19800e8cd5640693f36f2040db4ab5e8d738146)
1b528cefcSMark Murray /*
2bbd80c28SJacques Vidrine  * 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>
36c19800e8SDoug Rabson RCSID("$Id: afslog.c 16438 2006-01-03 09:27:54Z lha $");
37b528cefcSMark Murray #endif
38b528cefcSMark Murray #include <ctype.h>
39bbd80c28SJacques Vidrine #ifdef KRB5
40b528cefcSMark Murray #include <krb5.h>
41bbd80c28SJacques Vidrine #endif
42bbd80c28SJacques Vidrine #ifdef KRB4
43bbd80c28SJacques Vidrine #include <krb.h>
44bbd80c28SJacques Vidrine #endif
45b528cefcSMark Murray #include <kafs.h>
46b528cefcSMark Murray #include <roken.h>
47b528cefcSMark Murray #include <getarg.h>
485e9cd1aeSAssar Westerlund #include <err.h>
49b528cefcSMark Murray 
50b528cefcSMark Murray static int help_flag;
51b528cefcSMark Murray static int version_flag;
52b528cefcSMark Murray static getarg_strings cells;
53b528cefcSMark Murray static char *realm;
54b528cefcSMark Murray static getarg_strings files;
55b528cefcSMark Murray static int unlog_flag;
56b528cefcSMark Murray static int verbose;
57bbd80c28SJacques Vidrine #ifdef KRB4
58bbd80c28SJacques Vidrine static int use_krb4 = 1;
59bbd80c28SJacques Vidrine #endif
60bbd80c28SJacques Vidrine #ifdef KRB5
61c19800e8SDoug Rabson static char *client_string;
62c19800e8SDoug Rabson static char *cache_string;
63bbd80c28SJacques Vidrine static int use_krb5 = 1;
64bbd80c28SJacques Vidrine #endif
65b528cefcSMark Murray 
66b528cefcSMark Murray struct getargs args[] = {
67bbd80c28SJacques Vidrine     { "cell",	'c', arg_strings, &cells, "cells to get tokens for", "cell" },
68bbd80c28SJacques Vidrine     { "file",	'p', arg_strings, &files, "files to get tokens for", "path" },
69b528cefcSMark Murray     { "realm",	'k', arg_string, &realm, "realm for afs cell", "realm" },
70b528cefcSMark Murray     { "unlog",	'u', arg_flag, &unlog_flag, "remove tokens" },
71bbd80c28SJacques Vidrine #ifdef KRB4
72c19800e8SDoug Rabson     { "v4",	 0, arg_negative_flag, &use_krb4, "don't use Kerberos 4" },
73bbd80c28SJacques Vidrine #endif
74bbd80c28SJacques Vidrine #ifdef KRB5
75c19800e8SDoug Rabson     { "principal",'P',arg_string,&client_string,"principal to use","principal"},
76c19800e8SDoug Rabson     { "cache",   0,  arg_string, &cache_string, "ccache to use", "cache"},
77c19800e8SDoug Rabson     { "v5",	 0,  arg_negative_flag, &use_krb5, "don't use Kerberos 5" },
78b528cefcSMark Murray #endif
79b528cefcSMark Murray     { "verbose",'v', arg_flag, &verbose },
80b528cefcSMark Murray     { "version", 0,  arg_flag, &version_flag },
81b528cefcSMark Murray     { "help",	'h', arg_flag, &help_flag },
82b528cefcSMark Murray };
83b528cefcSMark Murray 
84b528cefcSMark Murray static int num_args = sizeof(args) / sizeof(args[0]);
85b528cefcSMark Murray 
86bbd80c28SJacques Vidrine #ifdef KRB5
87bbd80c28SJacques Vidrine krb5_context context;
88bbd80c28SJacques Vidrine krb5_ccache id;
89bbd80c28SJacques Vidrine #endif
90bbd80c28SJacques Vidrine 
91b528cefcSMark Murray static const char *
92bbd80c28SJacques Vidrine expand_one_file(FILE *f, const char *cell)
93b528cefcSMark Murray {
94bbd80c28SJacques Vidrine     static char buf[1024];
95b528cefcSMark Murray     char *p;
96b528cefcSMark Murray 
97b528cefcSMark Murray     while (fgets (buf, sizeof(buf), f) != NULL) {
98b528cefcSMark Murray 	if(buf[0] == '>') {
99b528cefcSMark Murray 	    for(p = buf; *p && !isspace((unsigned char)*p) && *p != '#'; p++)
100b528cefcSMark Murray 		;
101b528cefcSMark Murray 	    *p = '\0';
102bbd80c28SJacques Vidrine 	    if(strncmp(buf + 1, cell, strlen(cell)) == 0)
103b528cefcSMark Murray 		return buf + 1;
104b528cefcSMark Murray 	}
105bbd80c28SJacques Vidrine 	buf[0] = '\0';
106b528cefcSMark Murray     }
107bbd80c28SJacques Vidrine     return NULL;
108b528cefcSMark Murray }
109bbd80c28SJacques Vidrine 
110bbd80c28SJacques Vidrine static const char *
111bbd80c28SJacques Vidrine expand_cell_name(const char *cell)
112bbd80c28SJacques Vidrine {
113bbd80c28SJacques Vidrine     FILE *f;
114bbd80c28SJacques Vidrine     const char *c;
115bbd80c28SJacques Vidrine     const char **fn, *files[] = { _PATH_CELLSERVDB,
116bbd80c28SJacques Vidrine 				  _PATH_ARLA_CELLSERVDB,
117bbd80c28SJacques Vidrine 				  _PATH_OPENAFS_DEBIAN_CELLSERVDB,
118bbd80c28SJacques Vidrine 				  _PATH_ARLA_DEBIAN_CELLSERVDB,
119bbd80c28SJacques Vidrine 				  NULL };
120bbd80c28SJacques Vidrine     for(fn = files; *fn; fn++) {
121bbd80c28SJacques Vidrine 	f = fopen(*fn, "r");
122bbd80c28SJacques Vidrine 	if(f == NULL)
123bbd80c28SJacques Vidrine 	    continue;
124bbd80c28SJacques Vidrine 	c = expand_one_file(f, cell);
125b528cefcSMark Murray 	fclose(f);
126bbd80c28SJacques Vidrine 	if(c)
127bbd80c28SJacques Vidrine 	    return c;
128bbd80c28SJacques Vidrine     }
129b528cefcSMark Murray     return cell;
130b528cefcSMark Murray }
131b528cefcSMark Murray 
132b528cefcSMark Murray static void
133b528cefcSMark Murray usage(int ecode)
134b528cefcSMark Murray {
135bbd80c28SJacques Vidrine     arg_printusage(args, num_args, NULL, "[cell|path]...");
136b528cefcSMark Murray     exit(ecode);
137b528cefcSMark Murray }
138b528cefcSMark Murray 
139bbd80c28SJacques Vidrine struct cell_list {
140bbd80c28SJacques Vidrine     char *cell;
141bbd80c28SJacques Vidrine     struct cell_list *next;
142bbd80c28SJacques Vidrine } *cell_list;
143bbd80c28SJacques Vidrine 
144b528cefcSMark Murray static int
145bbd80c28SJacques Vidrine afslog_cell(const char *cell, int expand)
146b528cefcSMark Murray {
147bbd80c28SJacques Vidrine     struct cell_list *p, **q;
148b528cefcSMark Murray     const char *c = cell;
149b528cefcSMark Murray     if(expand){
150b528cefcSMark Murray 	c = expand_cell_name(cell);
151b528cefcSMark Murray 	if(c == NULL){
152bbd80c28SJacques Vidrine 	    warnx("No cell matching \"%s\" found.", cell);
153b528cefcSMark Murray 	    return -1;
154b528cefcSMark Murray 	}
155bbd80c28SJacques Vidrine 	if(verbose && strcmp(c, cell) != 0)
156bbd80c28SJacques Vidrine 	    warnx("Cell \"%s\" expanded to \"%s\"", cell, c);
157b528cefcSMark Murray     }
158bbd80c28SJacques Vidrine     /* add to list of cells to get tokens for, and also remove
159bbd80c28SJacques Vidrine        duplicates; the actual afslog takes place later */
160bbd80c28SJacques Vidrine     for(p = cell_list, q = &cell_list; p; q = &p->next, p = p->next)
161bbd80c28SJacques Vidrine 	if(strcmp(p->cell, c) == 0)
162bbd80c28SJacques Vidrine 	    return 0;
163bbd80c28SJacques Vidrine     p = malloc(sizeof(*p));
164bbd80c28SJacques Vidrine     if(p == NULL)
165bbd80c28SJacques Vidrine 	return -1;
166bbd80c28SJacques Vidrine     p->cell = strdup(c);
167bbd80c28SJacques Vidrine     if(p->cell == NULL) {
168bbd80c28SJacques Vidrine 	free(p);
169bbd80c28SJacques Vidrine 	return -1;
170bbd80c28SJacques Vidrine     }
171bbd80c28SJacques Vidrine     p->next = NULL;
172bbd80c28SJacques Vidrine     *q = p;
173bbd80c28SJacques Vidrine     return 0;
174b528cefcSMark Murray }
175b528cefcSMark Murray 
176b528cefcSMark Murray static int
177bbd80c28SJacques Vidrine afslog_file(const char *path)
178b528cefcSMark Murray {
179b528cefcSMark Murray     char cell[64];
180b528cefcSMark Murray     if(k_afs_cell_of_file(path, cell, sizeof(cell))){
181bbd80c28SJacques Vidrine 	warnx("No cell found for file \"%s\".", path);
182b528cefcSMark Murray 	return -1;
183b528cefcSMark Murray     }
184b528cefcSMark Murray     if(verbose)
185bbd80c28SJacques Vidrine 	warnx("File \"%s\" lives in cell \"%s\"", path, cell);
186bbd80c28SJacques Vidrine     return afslog_cell(cell, 0);
187bbd80c28SJacques Vidrine }
188bbd80c28SJacques Vidrine 
189bbd80c28SJacques Vidrine static int
190bbd80c28SJacques Vidrine do_afslog(const char *cell)
191bbd80c28SJacques Vidrine {
192bbd80c28SJacques Vidrine     int k5ret, k4ret;
193bbd80c28SJacques Vidrine 
194bbd80c28SJacques Vidrine     k5ret = k4ret = 0;
195bbd80c28SJacques Vidrine 
196bbd80c28SJacques Vidrine #ifdef KRB5
197bbd80c28SJacques Vidrine     if(context != NULL && id != NULL && use_krb5) {
198c19800e8SDoug Rabson 	k5ret = krb5_afslog(context, id, cell, realm);
199bbd80c28SJacques Vidrine 	if(k5ret == 0)
200bbd80c28SJacques Vidrine 	    return 0;
201bbd80c28SJacques Vidrine     }
202bbd80c28SJacques Vidrine #endif
203bbd80c28SJacques Vidrine #if KRB4
204bbd80c28SJacques Vidrine     if (use_krb4) {
205c19800e8SDoug Rabson 	k4ret = krb_afslog(cell, realm);
206bbd80c28SJacques Vidrine 	if(k4ret == 0)
207bbd80c28SJacques Vidrine 	    return 0;
208bbd80c28SJacques Vidrine     }
209bbd80c28SJacques Vidrine #endif
2101c43270aSJacques Vidrine     if (cell == NULL)
2111c43270aSJacques Vidrine 	cell = "<default cell>";
212bbd80c28SJacques Vidrine #ifdef KRB5
213bbd80c28SJacques Vidrine     if (k5ret)
214bbd80c28SJacques Vidrine 	warnx("krb5_afslog(%s): %s", cell, krb5_get_err_text(context, k5ret));
215bbd80c28SJacques Vidrine #endif
216bbd80c28SJacques Vidrine #ifdef KRB4
217bbd80c28SJacques Vidrine     if (k4ret)
218bbd80c28SJacques Vidrine 	warnx("krb_afslog(%s): %s", cell, krb_get_err_text(k4ret));
219bbd80c28SJacques Vidrine #endif
220bbd80c28SJacques Vidrine     if (k5ret || k4ret)
221bbd80c28SJacques Vidrine 	return 1;
222bbd80c28SJacques Vidrine     return 0;
223bbd80c28SJacques Vidrine }
224bbd80c28SJacques Vidrine 
225bbd80c28SJacques Vidrine static void
226bbd80c28SJacques Vidrine log_func(void *ctx, const char *str)
227bbd80c28SJacques Vidrine {
228bbd80c28SJacques Vidrine     fprintf(stderr, "%s\n", str);
229b528cefcSMark Murray }
230b528cefcSMark Murray 
231b528cefcSMark Murray int
232b528cefcSMark Murray main(int argc, char **argv)
233b528cefcSMark Murray {
234b528cefcSMark Murray     int optind = 0;
235b528cefcSMark Murray     int i;
236b528cefcSMark Murray     int num;
237b528cefcSMark Murray     int ret = 0;
238bbd80c28SJacques Vidrine     int failed = 0;
239bbd80c28SJacques Vidrine     struct cell_list *p;
240b528cefcSMark Murray 
241adb0ddaeSAssar Westerlund     setprogname(argv[0]);
242b528cefcSMark Murray 
243b528cefcSMark Murray     if(getarg(args, num_args, argc, argv, &optind))
244b528cefcSMark Murray 	usage(1);
245b528cefcSMark Murray     if(help_flag)
246b528cefcSMark Murray 	usage(0);
247b528cefcSMark Murray     if(version_flag) {
248b528cefcSMark Murray 	print_version(NULL);
249b528cefcSMark Murray 	exit(0);
250b528cefcSMark Murray     }
251b528cefcSMark Murray 
252b528cefcSMark Murray     if(!k_hasafs())
253bbd80c28SJacques Vidrine 	errx(1, "AFS does not seem to be present on this machine");
254b528cefcSMark Murray 
255b528cefcSMark Murray     if(unlog_flag){
256b528cefcSMark Murray 	k_unlog();
257b528cefcSMark Murray 	exit(0);
258b528cefcSMark Murray     }
259bbd80c28SJacques Vidrine #ifdef KRB5
260bbd80c28SJacques Vidrine     ret = krb5_init_context(&context);
261c19800e8SDoug Rabson     if (ret) {
262bbd80c28SJacques Vidrine 	context = NULL;
263c19800e8SDoug Rabson     } else {
264c19800e8SDoug Rabson 	if (client_string) {
265c19800e8SDoug Rabson 	    krb5_principal client;
266c19800e8SDoug Rabson 
267c19800e8SDoug Rabson 	    ret = krb5_parse_name(context, client_string, &client);
268c19800e8SDoug Rabson 	    if (ret == 0)
269c19800e8SDoug Rabson 		ret = krb5_cc_cache_match(context, client, NULL, &id);
270c19800e8SDoug Rabson 	    if (ret)
271c19800e8SDoug Rabson 		id = NULL;
272c19800e8SDoug Rabson 	}
273c19800e8SDoug Rabson 	if (id == NULL && cache_string) {
274c19800e8SDoug Rabson 	    if(krb5_cc_resolve(context, cache_string, &id) != 0) {
275c19800e8SDoug Rabson 		krb5_warnx(context, "failed to open kerberos 5 cache '%s'",
276c19800e8SDoug Rabson 			   cache_string);
277c19800e8SDoug Rabson 		id = NULL;
278c19800e8SDoug Rabson 	    }
279c19800e8SDoug Rabson 	}
280c19800e8SDoug Rabson 	if (id == NULL)
281bbd80c28SJacques Vidrine 	    if(krb5_cc_default(context, &id) != 0)
282bbd80c28SJacques Vidrine 		id = NULL;
283c19800e8SDoug Rabson     }
284bbd80c28SJacques Vidrine #endif
285bbd80c28SJacques Vidrine 
286bbd80c28SJacques Vidrine     if (verbose)
287bbd80c28SJacques Vidrine 	kafs_set_verbose(log_func, NULL);
288bbd80c28SJacques Vidrine 
289b528cefcSMark Murray     num = 0;
290b528cefcSMark Murray     for(i = 0; i < files.num_strings; i++){
291bbd80c28SJacques Vidrine 	afslog_file(files.strings[i]);
292b528cefcSMark Murray 	num++;
293bbd80c28SJacques Vidrine     }
294adb0ddaeSAssar Westerlund     free_getarg_strings (&files);
295b528cefcSMark Murray     for(i = 0; i < cells.num_strings; i++){
296bbd80c28SJacques Vidrine 	afslog_cell(cells.strings[i], 1);
297b528cefcSMark Murray 	num++;
298b528cefcSMark Murray     }
299bbd80c28SJacques Vidrine     free_getarg_strings (&cells);
300b528cefcSMark Murray     for(i = optind; i < argc; i++){
301b528cefcSMark Murray 	num++;
302b528cefcSMark Murray 	if(strcmp(argv[i], ".") == 0 ||
303b528cefcSMark Murray 	   strcmp(argv[i], "..") == 0 ||
304b528cefcSMark Murray 	   strchr(argv[i], '/') ||
305b528cefcSMark Murray 	   access(argv[i], F_OK) == 0)
306bbd80c28SJacques Vidrine 	    afslog_file(argv[i]);
307b528cefcSMark Murray 	else
308bbd80c28SJacques Vidrine 	    afslog_cell(argv[i], 1);
309b528cefcSMark Murray     }
310b528cefcSMark Murray     if(num == 0) {
311bbd80c28SJacques Vidrine 	if(do_afslog(NULL))
312bbd80c28SJacques Vidrine 	    failed++;
313bbd80c28SJacques Vidrine     } else
314bbd80c28SJacques Vidrine 	for(p = cell_list; p; p = p->next) {
315bbd80c28SJacques Vidrine 	    if(verbose)
316bbd80c28SJacques Vidrine 		warnx("Getting tokens for cell \"%s\"", p->cell);
317bbd80c28SJacques Vidrine 	    if(do_afslog(p->cell))
318bbd80c28SJacques Vidrine 		failed++;
319b528cefcSMark Murray     }
320b528cefcSMark Murray 
321bbd80c28SJacques Vidrine     return failed;
322b528cefcSMark Murray }
323