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