process.c revision c048b52e
19fe995a9Smrg/* 29fe995a9Smrg * 39fe995a9SmrgCopyright 1989, 1998 The Open Group 49fe995a9Smrg 59fe995a9SmrgPermission to use, copy, modify, distribute, and sell this software and its 69fe995a9Smrgdocumentation for any purpose is hereby granted without fee, provided that 79fe995a9Smrgthe above copyright notice appear in all copies and that both that 89fe995a9Smrgcopyright notice and this permission notice appear in supporting 99fe995a9Smrgdocumentation. 109fe995a9Smrg 119fe995a9SmrgThe above copyright notice and this permission notice shall be included in 129fe995a9Smrgall copies or substantial portions of the Software. 139fe995a9Smrg 149fe995a9SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 159fe995a9SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 169fe995a9SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 179fe995a9SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 189fe995a9SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 199fe995a9SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 209fe995a9Smrg 219fe995a9SmrgExcept as contained in this notice, the name of The Open Group shall not be 229fe995a9Smrgused in advertising or otherwise to promote the sale, use or other dealings 239fe995a9Smrgin this Software without prior written authorization from The Open Group. 249fe995a9Smrg * * 259fe995a9Smrg * Original Author of "xauth" : Jim Fulton, MIT X Consortium 269fe995a9Smrg * Modified into "iceauth" : Ralph Mor, X Consortium 279fe995a9Smrg */ 289fe995a9Smrg 299fe995a9Smrg#include "iceauth.h" 309fe995a9Smrg#include <ctype.h> 319fe995a9Smrg#include <errno.h> 329fe995a9Smrg#include <sys/types.h> 339fe995a9Smrg#include <sys/stat.h> 349fe995a9Smrg#include <signal.h> 359fe995a9Smrg 369fe995a9Smrg#define SECURERPC "SUN-DES-1" 379fe995a9Smrg#define K5AUTH "KERBEROS-V5-1" 389fe995a9Smrg 399fe995a9Smrg#define ICEAUTH_DEFAULT_RETRIES 10 /* number of competitors we expect */ 409fe995a9Smrg#define ICEAUTH_DEFAULT_TIMEOUT 2 /* in seconds, be quick */ 419fe995a9Smrg#define ICEAUTH_DEFAULT_DEADTIME 600L /* 10 minutes in seconds */ 429fe995a9Smrg 439fe995a9Smrgtypedef struct _AuthList { /* linked list of entries */ 449fe995a9Smrg struct _AuthList *next; 459fe995a9Smrg IceAuthFileEntry *auth; 469fe995a9Smrg} AuthList; 479fe995a9Smrg 489fe995a9Smrg#define add_to_list(h,t,e) {if (t) (t)->next = (e); else (h) = (e); (t) = (e);} 499fe995a9Smrg 50e8ac26b0Smrgtypedef int (*ProcessFunc)(const char *, int, int, const char **); 519d794632Smrgtypedef int (*DoFunc)(const char *, int, IceAuthFileEntry *, void *); 529fe995a9Smrg 539fe995a9Smrgtypedef struct _CommandTable { /* commands that are understood */ 549d794632Smrg const char *name; /* full name */ 559d794632Smrg unsigned int minlen; /* unique prefix */ 569d794632Smrg unsigned int maxlen; /* strlen(name) */ 579fe995a9Smrg ProcessFunc processfunc; /* handler */ 589d794632Smrg const char *helptext; /* what to print for help */ 599fe995a9Smrg} CommandTable; 609fe995a9Smrg 619fe995a9Smrgstruct _extract_data { /* for iterating */ 629fe995a9Smrg FILE *fp; /* input source */ 639d794632Smrg const char *filename; /* name of input */ 649fe995a9Smrg Bool used_stdout; /* whether or not need to close */ 659fe995a9Smrg int nwritten; /* number of entries written */ 669d794632Smrg const char *cmd; /* for error messages */ 679fe995a9Smrg}; 689fe995a9Smrg 699fe995a9Smrgstruct _list_data { /* for iterating */ 709fe995a9Smrg FILE *fp; /* output file */ 719fe995a9Smrg}; 729fe995a9Smrg 739fe995a9Smrg 749fe995a9Smrg/* 759fe995a9Smrg * private data 769fe995a9Smrg */ 779d794632Smrgstatic const char *stdin_filename = "(stdin)"; /* for messages */ 789d794632Smrgstatic const char *stdout_filename = "(stdout)"; /* for messages */ 799fe995a9Smrgstatic const char *Yes = "yes"; /* for messages */ 809fe995a9Smrgstatic const char *No = "no"; /* for messages */ 819fe995a9Smrg 829fe995a9Smrgstatic int binaryEqual ( const char *a, const char *b, unsigned len ); 839fe995a9Smrgstatic void prefix ( const char *fn, int n ); 849fe995a9Smrgstatic void badcommandline ( const char *cmd ); 859fe995a9Smrgstatic char *skip_space ( char *s ); 869fe995a9Smrgstatic char *skip_nonspace ( char *s ); 879fe995a9Smrgstatic char **split_into_words ( char *src, int *argcp ); 889d794632Smrgstatic FILE *open_file ( const char **filenamep, const char *mode, Bool *usedstdp, const char *srcfn, int srcln, const char *cmd ); 899fe995a9Smrgstatic int read_auth_entries ( FILE *fp, AuthList **headp, AuthList **tailp ); 909d794632Smrgstatic int cvthexkey ( const char *hexstr, char **ptrp ); 91e8ac26b0Smrgstatic int dispatch_command ( const char *inputfilename, int lineno, int argc, const char **argv, const CommandTable *tab, int *statusp ); 929d794632Smrgstatic void die ( int sig ) _X_NORETURN; 939d794632Smrgstatic void catchsig ( int sig ) _X_NORETURN; 949fe995a9Smrgstatic void register_signals ( void ); 959fe995a9Smrgstatic int write_auth_file ( char *tmp_nam, size_t tmp_nam_len ); 969fe995a9Smrgstatic void fprintfhex ( FILE *fp, unsigned int len, const char *cp ); 979d794632Smrgstatic int dump_entry ( const char *inputfilename, int lineno, IceAuthFileEntry *auth, void *data ); 989d794632Smrgstatic int extract_entry ( const char *inputfilename, int lineno, IceAuthFileEntry *auth, void *data ); 999fe995a9Smrgstatic int match_auth ( IceAuthFileEntry *a, IceAuthFileEntry *b, int *authDataSame ); 1009fe995a9Smrgstatic int merge_entries ( AuthList **firstp, AuthList *second, int *nnewp, int *nreplp, int *ndupp ); 101e8ac26b0Smrgstatic int search_and_do ( const char *inputfilename, int lineno, int start, int argc, const char *argv[], DoFunc do_func, void *data ); 1029d794632Smrgstatic int remove_entry ( const char *inputfilename, int lineno, IceAuthFileEntry *auth, void *data ); 103e8ac26b0Smrgstatic int do_help ( const char *inputfilename, int lineno, int argc, const char **argv ); 104e8ac26b0Smrgstatic int do_questionmark ( const char *inputfilename, int lineno, int argc, const char **argv ); 105e8ac26b0Smrgstatic int do_list ( const char *inputfilename, int lineno, int argc, const char **argv ); 106e8ac26b0Smrgstatic int do_merge ( const char *inputfilename, int lineno, int argc, const char **argv ); 107e8ac26b0Smrgstatic int do_extract ( const char *inputfilename, int lineno, int argc, const char **argv ); 108e8ac26b0Smrgstatic int do_add ( const char *inputfilename, int lineno, int argc, const char **argv ); 109e8ac26b0Smrgstatic int do_remove ( const char *inputfilename, int lineno, int argc, const char **argv ); 110e8ac26b0Smrgstatic int do_info ( const char *inputfilename, int lineno, int argc, const char **argv ); 111e8ac26b0Smrgstatic int do_exit ( const char *inputfilename, int lineno, int argc, const char **argv ); 112e8ac26b0Smrgstatic int do_quit ( const char *inputfilename, int lineno, int argc, const char **argv ); 113e8ac26b0Smrgstatic int do_source ( const char *inputfilename, int lineno, int argc, const char **argv ); 1149fe995a9Smrg 1159fe995a9Smrgstatic const CommandTable command_table[] = { /* table of known commands */ 1169fe995a9Smrg{ "add", 2, 3, do_add, 1179fe995a9Smrg"\ 1189fe995a9Smrgadd add an entry\n\ 1199fe995a9Smrg add protoname protodata netid authname authdata" 1209fe995a9Smrg}, 1219fe995a9Smrg 1229fe995a9Smrg{ "exit", 3, 4, do_exit, 1239fe995a9Smrg"\ 1249fe995a9Smrgexit save changes and exit program" 1259fe995a9Smrg}, 1269fe995a9Smrg 1279fe995a9Smrg{ "extract", 3, 7, do_extract, 1289fe995a9Smrg"\ 1299fe995a9Smrgextract extract entries into file\n\ 1309fe995a9Smrg extract filename <protoname=$> <protodata=$> <netid=$> <authname=$>" 1319fe995a9Smrg}, 1329fe995a9Smrg 1339fe995a9Smrg{ "help", 1, 4, do_help, 1349fe995a9Smrg"\ 1359fe995a9Smrghelp print help\n\ 1369fe995a9Smrg help <topic>" 1379fe995a9Smrg}, 1389fe995a9Smrg 1399fe995a9Smrg{ "info", 1, 4, do_info, 1409fe995a9Smrg"\ 1419fe995a9Smrginfo print information about entries" 1429fe995a9Smrg}, 1439fe995a9Smrg 1449fe995a9Smrg{ "list", 1, 4, do_list, 1459fe995a9Smrg"\ 1469fe995a9Smrglist list entries\n\ 1479fe995a9Smrg list <protoname=$> <protodata=$> <netid=$> <authname=$>" 1489fe995a9Smrg}, 1499fe995a9Smrg 1509fe995a9Smrg{ "merge", 1, 5, do_merge, 1519fe995a9Smrg"\ 1529fe995a9Smrgmerge merge entries from files\n\ 1539fe995a9Smrg merge filename1 <filename2> <filename3> ..." 1549fe995a9Smrg}, 1559fe995a9Smrg 1569fe995a9Smrg{ "quit", 1, 4, do_quit, 1579fe995a9Smrg"\ 1589fe995a9Smrgquit abort changes and exit program" }, 1599fe995a9Smrg 1609fe995a9Smrg{ "remove", 1, 6, do_remove, 1619fe995a9Smrg"\ 1629fe995a9Smrgremove remove entries\n\ 1639fe995a9Smrg remove <protoname=$> <protodata=$> <netid=$> <authname=$>" 1649fe995a9Smrg}, 1659fe995a9Smrg 1669fe995a9Smrg{ "source", 1, 6, do_source, 1679fe995a9Smrg"\ 1689fe995a9Smrgsource read commands from file\n\ 1699fe995a9Smrg source filename" 1709fe995a9Smrg}, 1719fe995a9Smrg 1729fe995a9Smrg{ "?", 1, 1, do_questionmark, 1739fe995a9Smrg"\ 1749fe995a9Smrg? list available commands" }, 1759fe995a9Smrg 1769fe995a9Smrg{ NULL, 0, 0, NULL, NULL }, 1779fe995a9Smrg}; 1789fe995a9Smrg 1799fe995a9Smrg#define COMMAND_NAMES_PADDED_WIDTH 10 /* wider than anything above */ 1809fe995a9Smrg 1819fe995a9Smrg 1829fe995a9Smrgstatic Bool okay_to_use_stdin = True; /* set to false after using */ 1839fe995a9Smrg 1849fe995a9Smrgstatic const char * const hex_table[] = { /* for printing hex digits */ 1859fe995a9Smrg "00", "01", "02", "03", "04", "05", "06", "07", 1869fe995a9Smrg "08", "09", "0a", "0b", "0c", "0d", "0e", "0f", 1879fe995a9Smrg "10", "11", "12", "13", "14", "15", "16", "17", 1889fe995a9Smrg "18", "19", "1a", "1b", "1c", "1d", "1e", "1f", 1899fe995a9Smrg "20", "21", "22", "23", "24", "25", "26", "27", 1909fe995a9Smrg "28", "29", "2a", "2b", "2c", "2d", "2e", "2f", 1919fe995a9Smrg "30", "31", "32", "33", "34", "35", "36", "37", 1929fe995a9Smrg "38", "39", "3a", "3b", "3c", "3d", "3e", "3f", 1939fe995a9Smrg "40", "41", "42", "43", "44", "45", "46", "47", 1949fe995a9Smrg "48", "49", "4a", "4b", "4c", "4d", "4e", "4f", 1959fe995a9Smrg "50", "51", "52", "53", "54", "55", "56", "57", 1969fe995a9Smrg "58", "59", "5a", "5b", "5c", "5d", "5e", "5f", 1979fe995a9Smrg "60", "61", "62", "63", "64", "65", "66", "67", 1989fe995a9Smrg "68", "69", "6a", "6b", "6c", "6d", "6e", "6f", 1999fe995a9Smrg "70", "71", "72", "73", "74", "75", "76", "77", 2009fe995a9Smrg "78", "79", "7a", "7b", "7c", "7d", "7e", "7f", 2019fe995a9Smrg "80", "81", "82", "83", "84", "85", "86", "87", 2029fe995a9Smrg "88", "89", "8a", "8b", "8c", "8d", "8e", "8f", 2039fe995a9Smrg "90", "91", "92", "93", "94", "95", "96", "97", 2049fe995a9Smrg "98", "99", "9a", "9b", "9c", "9d", "9e", "9f", 2059fe995a9Smrg "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", 2069fe995a9Smrg "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af", 2079fe995a9Smrg "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", 2089fe995a9Smrg "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf", 2099fe995a9Smrg "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", 2109fe995a9Smrg "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf", 2119fe995a9Smrg "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", 2129fe995a9Smrg "d8", "d9", "da", "db", "dc", "dd", "de", "df", 2139fe995a9Smrg "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", 2149fe995a9Smrg "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef", 2159fe995a9Smrg "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", 2169fe995a9Smrg "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff", 2179fe995a9Smrg}; 2189fe995a9Smrg 2199fe995a9Smrgstatic unsigned int hexvalues[256]; /* for parsing hex input */ 2209fe995a9Smrg 2219fe995a9Smrgstatic mode_t original_umask = 0; /* for restoring */ 2229fe995a9Smrg 2239fe995a9Smrg 2249fe995a9Smrg/* 2259fe995a9Smrg * private utility procedures 2269fe995a9Smrg */ 2279fe995a9Smrg 2289fe995a9Smrg#define copystring(s) ( s != NULL ? strdup(s) : NULL ) 2299fe995a9Smrg 2309fe995a9Smrgstatic int 2319fe995a9SmrgbinaryEqual ( 2329fe995a9Smrg register const char *a, 2339fe995a9Smrg register const char *b, 2349fe995a9Smrg register unsigned len) 2359fe995a9Smrg 2369fe995a9Smrg{ 2379fe995a9Smrg while (len--) 2389fe995a9Smrg if (*a++ != *b++) 2399fe995a9Smrg return 0; 2409fe995a9Smrg return 1; 2419fe995a9Smrg} 2429fe995a9Smrg 2439fe995a9Smrgstatic void prefix (const char *fn, int n) 2449fe995a9Smrg{ 2459fe995a9Smrg fprintf (stderr, "%s: %s:%d: ", ProgramName, fn, n); 2469fe995a9Smrg} 2479fe995a9Smrg 2489fe995a9Smrgstatic void badcommandline (const char *cmd) 2499fe995a9Smrg{ 2509fe995a9Smrg fprintf (stderr, "bad \"%s\" command line\n", cmd); 2519fe995a9Smrg} 2529fe995a9Smrg 2539fe995a9Smrgstatic char *skip_space (register char *s) 2549fe995a9Smrg{ 2559fe995a9Smrg if (!s) return NULL; 2569fe995a9Smrg 2579fe995a9Smrg for ( ; *s && isascii(*s) && isspace(*s); s++) 2589fe995a9Smrg ; 2599fe995a9Smrg return s; 2609fe995a9Smrg} 2619fe995a9Smrg 2629fe995a9Smrg 2639fe995a9Smrgstatic char *skip_nonspace (register char *s) 2649fe995a9Smrg{ 2659fe995a9Smrg if (!s) return NULL; 2669fe995a9Smrg 2679fe995a9Smrg /* put quoting into loop if need be */ 2689fe995a9Smrg for ( ; *s && isascii(*s) && !isspace(*s); s++) 2699fe995a9Smrg ; 2709fe995a9Smrg return s; 2719fe995a9Smrg} 2729fe995a9Smrg 2739fe995a9Smrgstatic char **split_into_words ( /* argvify string */ 2749fe995a9Smrg char *src, 2759fe995a9Smrg int *argcp) 2769fe995a9Smrg{ 2779fe995a9Smrg char *jword; 2789fe995a9Smrg char savec; 2799fe995a9Smrg char **argv; 2809fe995a9Smrg int cur, total; 2819fe995a9Smrg 2829fe995a9Smrg *argcp = 0; 2839fe995a9Smrg#define WORDSTOALLOC 4 /* most lines are short */ 2849fe995a9Smrg argv = (char **) malloc (WORDSTOALLOC * sizeof (char *)); 2859fe995a9Smrg if (!argv) return NULL; 2869fe995a9Smrg cur = 0; 2879fe995a9Smrg total = WORDSTOALLOC; 2889fe995a9Smrg 2899fe995a9Smrg /* 2909fe995a9Smrg * split the line up into separate, nul-terminated tokens; the last 2919fe995a9Smrg * "token" will point to the empty string so that it can be bashed into 2929fe995a9Smrg * a null pointer. 2939fe995a9Smrg */ 2949fe995a9Smrg 2959fe995a9Smrg do { 2969fe995a9Smrg jword = skip_space (src); 2979fe995a9Smrg src = skip_nonspace (jword); 2989fe995a9Smrg savec = *src; 2999fe995a9Smrg *src = '\0'; 3009fe995a9Smrg if (cur == total) { 301e8ac26b0Smrg char **prevargv = argv; 3029fe995a9Smrg total += WORDSTOALLOC; 3039fe995a9Smrg argv = (char **) realloc (argv, total * sizeof (char *)); 304e8ac26b0Smrg if (!argv) { 305e8ac26b0Smrg free (prevargv); 306e8ac26b0Smrg return NULL; 307e8ac26b0Smrg } 3089fe995a9Smrg } 3099fe995a9Smrg argv[cur++] = jword; 3109fe995a9Smrg if (savec) src++; /* if not last on line advance */ 3119fe995a9Smrg } while (jword != src); 3129fe995a9Smrg 3139fe995a9Smrg argv[--cur] = NULL; /* smash empty token to end list */ 3149fe995a9Smrg *argcp = cur; 3159fe995a9Smrg return argv; 3169fe995a9Smrg} 3179fe995a9Smrg 3189fe995a9Smrg 3199fe995a9Smrgstatic FILE *open_file ( 3209d794632Smrg const char **filenamep, 3219fe995a9Smrg const char *mode, 3229fe995a9Smrg Bool *usedstdp, 3239fe995a9Smrg const char *srcfn, 3249fe995a9Smrg int srcln, 3259fe995a9Smrg const char *cmd) 3269fe995a9Smrg{ 3279fe995a9Smrg FILE *fp; 3289fe995a9Smrg 3299fe995a9Smrg if (strcmp (*filenamep, "-") == 0) { 3309fe995a9Smrg *usedstdp = True; 3319fe995a9Smrg /* select std descriptor to use */ 3329fe995a9Smrg if (mode[0] == 'r') { 3339fe995a9Smrg if (okay_to_use_stdin) { 3349fe995a9Smrg okay_to_use_stdin = False; 3359fe995a9Smrg *filenamep = stdin_filename; 3369fe995a9Smrg return stdin; 3379fe995a9Smrg } else { 3389fe995a9Smrg prefix (srcfn, srcln); 3399fe995a9Smrg fprintf (stderr, "%s: stdin already in use\n", cmd); 3409fe995a9Smrg return NULL; 3419fe995a9Smrg } 3429fe995a9Smrg } else { 3439fe995a9Smrg *filenamep = stdout_filename; 3449fe995a9Smrg return stdout; /* always okay to use stdout */ 3459fe995a9Smrg } 3469fe995a9Smrg } 3479fe995a9Smrg 3489fe995a9Smrg fp = fopen (*filenamep, mode); 3499fe995a9Smrg if (!fp) { 3509fe995a9Smrg prefix (srcfn, srcln); 3519fe995a9Smrg fprintf (stderr, "%s: unable to open file %s\n", cmd, *filenamep); 3529fe995a9Smrg } 3539fe995a9Smrg return fp; 3549fe995a9Smrg} 3559fe995a9Smrg 3569fe995a9Smrg 3579fe995a9Smrgstatic int read_auth_entries (FILE *fp, AuthList **headp, AuthList **tailp) 3589fe995a9Smrg{ 3599fe995a9Smrg IceAuthFileEntry *auth; 3609fe995a9Smrg AuthList *head, *tail; 3619fe995a9Smrg int n; 3629fe995a9Smrg 3639fe995a9Smrg head = tail = NULL; 3649fe995a9Smrg n = 0; 3659fe995a9Smrg /* put all records into linked list */ 3669fe995a9Smrg while ((auth = IceReadAuthFileEntry (fp)) != NULL) { 3679fe995a9Smrg AuthList *l = (AuthList *) malloc (sizeof (AuthList)); 3689fe995a9Smrg if (!l) { 3699fe995a9Smrg fprintf (stderr, 3709fe995a9Smrg "%s: unable to alloc entry reading auth file\n", 3719fe995a9Smrg ProgramName); 3729fe995a9Smrg exit (1); 3739fe995a9Smrg } 3749fe995a9Smrg l->next = NULL; 3759fe995a9Smrg l->auth = auth; 3769fe995a9Smrg if (tail) /* if not first time through append */ 3779fe995a9Smrg tail->next = l; 3789fe995a9Smrg else 3799fe995a9Smrg head = l; /* first time through, so assign */ 3809fe995a9Smrg tail = l; 3819fe995a9Smrg n++; 3829fe995a9Smrg } 3839fe995a9Smrg *headp = head; 3849fe995a9Smrg *tailp = tail; 3859fe995a9Smrg return n; 3869fe995a9Smrg} 3879fe995a9Smrg 3889fe995a9Smrg 3899fe995a9Smrgstatic int cvthexkey ( /* turn hex key string into octets */ 3909d794632Smrg const char *hexstr, 3919fe995a9Smrg char **ptrp) 3929fe995a9Smrg{ 3939d794632Smrg unsigned int i; 3949d794632Smrg unsigned int len = 0; 3959d794632Smrg char *retval; 3969d794632Smrg const char *s; 3979fe995a9Smrg unsigned char *us; 3989fe995a9Smrg char c; 3999fe995a9Smrg char savec = '\0'; 4009fe995a9Smrg 4019fe995a9Smrg /* count */ 4029fe995a9Smrg for (s = hexstr; *s; s++) { 4039fe995a9Smrg if (!isascii(*s)) return -1; 4049fe995a9Smrg if (isspace(*s)) continue; 4059fe995a9Smrg if (!isxdigit(*s)) return -1; 4069fe995a9Smrg len++; 4079fe995a9Smrg } 4089fe995a9Smrg 40990b6713cSmrg /* if 0 or odd, then there was an error */ 41090b6713cSmrg if (len == 0 || (len & 1) == 1) return -1; 4119fe995a9Smrg 4129fe995a9Smrg 4139fe995a9Smrg /* now we know that the input is good */ 4149fe995a9Smrg len >>= 1; 4159fe995a9Smrg retval = malloc (len); 4169fe995a9Smrg if (!retval) { 4179fe995a9Smrg fprintf (stderr, "%s: unable to allocate %d bytes for hexkey\n", 4189fe995a9Smrg ProgramName, len); 4199fe995a9Smrg return -1; 4209fe995a9Smrg } 4219fe995a9Smrg 4229fe995a9Smrg for (us = (unsigned char *) retval, i = len; i > 0; hexstr++) { 4239fe995a9Smrg c = *hexstr; 4249fe995a9Smrg if (isspace(c)) continue; /* already know it is ascii */ 4259fe995a9Smrg if (isupper(c)) 4269fe995a9Smrg c = tolower(c); 4279fe995a9Smrg if (savec) { 4289fe995a9Smrg#define atoh(c) ((c) - (((c) >= '0' && (c) <= '9') ? '0' : ('a'-10))) 4299fe995a9Smrg *us = (unsigned char)((atoh(savec) << 4) + atoh(c)); 4309fe995a9Smrg#undef atoh 4319fe995a9Smrg savec = 0; /* ready for next character */ 4329fe995a9Smrg us++; 4339fe995a9Smrg i--; 4349fe995a9Smrg } else { 4359fe995a9Smrg savec = c; 4369fe995a9Smrg } 4379fe995a9Smrg } 4389fe995a9Smrg *ptrp = retval; 4399d794632Smrg return (int) len; 4409fe995a9Smrg} 4419fe995a9Smrg 4429fe995a9Smrgstatic int dispatch_command ( 4439fe995a9Smrg const char *inputfilename, 4449fe995a9Smrg int lineno, 4459fe995a9Smrg int argc, 446e8ac26b0Smrg const char **argv, 4479fe995a9Smrg const CommandTable *tab, 4489fe995a9Smrg int *statusp) 4499fe995a9Smrg{ 4509fe995a9Smrg const CommandTable *ct; 4519d794632Smrg const char *cmd; 4529d794632Smrg size_t n; 4539fe995a9Smrg /* scan table for command */ 4549fe995a9Smrg cmd = argv[0]; 4559fe995a9Smrg n = strlen (cmd); 4569fe995a9Smrg for (ct = tab; ct->name; ct++) { 4579fe995a9Smrg /* look for unique prefix */ 4589fe995a9Smrg if (n >= ct->minlen && n <= ct->maxlen && 4599fe995a9Smrg strncmp (cmd, ct->name, n) == 0) { 4609fe995a9Smrg *statusp = (*(ct->processfunc))(inputfilename, lineno, argc, argv); 4619fe995a9Smrg return 1; 4629fe995a9Smrg } 4639fe995a9Smrg } 4649fe995a9Smrg 4659fe995a9Smrg *statusp = 1; 4669fe995a9Smrg return 0; 4679fe995a9Smrg} 4689fe995a9Smrg 4699fe995a9Smrg 4709fe995a9Smrgstatic AuthList *iceauth_head = NULL; /* list of auth entries */ 4719fe995a9Smrgstatic Bool iceauth_existed = False; /* if was present at initialize */ 4729fe995a9Smrgstatic Bool iceauth_modified = False; /* if added, removed, or merged */ 4739fe995a9Smrgstatic Bool iceauth_allowed = True; /* if allowed to write auth file */ 4749fe995a9Smrgstatic char *iceauth_filename = NULL; 475c048b52eSmrgstatic volatile Bool dying = False; 4769fe995a9Smrg 4779fe995a9Smrg/* poor man's puts(), for under signal handlers */ 4789fe995a9Smrg#define WRITES(fd, S) (void)write((fd), (S), strlen((S))) 4799fe995a9Smrg 4809fe995a9Smrg/* ARGSUSED */ 4819d794632Smrgstatic void die (_X_UNUSED int sig) 4829fe995a9Smrg{ 483c048b52eSmrg dying = True; 4849fe995a9Smrg _exit (auth_finalize ()); 4859fe995a9Smrg /* NOTREACHED */ 4869fe995a9Smrg} 4879fe995a9Smrg 4889d794632Smrgstatic void catchsig (int sig) 4899fe995a9Smrg{ 4909fe995a9Smrg#ifdef SYSV 4919fe995a9Smrg if (sig > 0) signal (sig, die); /* re-establish signal handler */ 4929fe995a9Smrg#endif 4939fe995a9Smrg /* 4949fe995a9Smrg * fileno() might not be reentrant, avoid it if possible, and use 4959fe995a9Smrg * stderr instead of stdout 4969fe995a9Smrg */ 4979fe995a9Smrg#ifdef STDERR_FILENO 4989fe995a9Smrg if (verbose && iceauth_modified) WRITES(STDERR_FILENO, "\r\n"); 4999fe995a9Smrg#else 5009fe995a9Smrg if (verbose && iceauth_modified) WRITES(fileno(stderr), "\r\n"); 5019fe995a9Smrg#endif 5029fe995a9Smrg die (sig); 5039fe995a9Smrg /* NOTREACHED */ 5049fe995a9Smrg} 5059fe995a9Smrg 5069fe995a9Smrgstatic void register_signals (void) 5079fe995a9Smrg{ 5089fe995a9Smrg signal (SIGINT, catchsig); 5099fe995a9Smrg signal (SIGTERM, catchsig); 5109fe995a9Smrg#ifdef SIGHUP 5119fe995a9Smrg signal (SIGHUP, catchsig); 5129fe995a9Smrg#endif 5139fe995a9Smrg return; 5149fe995a9Smrg} 5159fe995a9Smrg 5169fe995a9Smrg 5179fe995a9Smrg/* 5189fe995a9Smrg * public procedures for parsing lines of input 5199fe995a9Smrg */ 5209fe995a9Smrg 5219fe995a9Smrgint auth_initialize ( char *authfilename ) 5229fe995a9Smrg{ 5239fe995a9Smrg int n; 5249fe995a9Smrg AuthList *head, *tail; 5259fe995a9Smrg FILE *authfp; 5269fe995a9Smrg Bool exists; 5279fe995a9Smrg 5289fe995a9Smrg register_signals (); 5299fe995a9Smrg 5309fe995a9Smrg bzero ((char *) hexvalues, sizeof hexvalues); 5319fe995a9Smrg hexvalues['0'] = 0; 5329fe995a9Smrg hexvalues['1'] = 1; 5339fe995a9Smrg hexvalues['2'] = 2; 5349fe995a9Smrg hexvalues['3'] = 3; 5359fe995a9Smrg hexvalues['4'] = 4; 5369fe995a9Smrg hexvalues['5'] = 5; 5379fe995a9Smrg hexvalues['6'] = 6; 5389fe995a9Smrg hexvalues['7'] = 7; 5399fe995a9Smrg hexvalues['8'] = 8; 5409fe995a9Smrg hexvalues['9'] = 9; 5419fe995a9Smrg hexvalues['a'] = hexvalues['A'] = 0xa; 5429fe995a9Smrg hexvalues['b'] = hexvalues['B'] = 0xb; 5439fe995a9Smrg hexvalues['c'] = hexvalues['C'] = 0xc; 5449fe995a9Smrg hexvalues['d'] = hexvalues['D'] = 0xd; 5459fe995a9Smrg hexvalues['e'] = hexvalues['E'] = 0xe; 5469fe995a9Smrg hexvalues['f'] = hexvalues['F'] = 0xf; 5479fe995a9Smrg 5489fe995a9Smrg if (break_locks && verbose) { 5499fe995a9Smrg printf ("Attempting to break locks on authority file %s\n", 5509fe995a9Smrg authfilename); 5519fe995a9Smrg } 5529fe995a9Smrg 5539fe995a9Smrg iceauth_filename = strdup(authfilename); 5549fe995a9Smrg 5559fe995a9Smrg if (ignore_locks) { 5569fe995a9Smrg if (break_locks) IceUnlockAuthFile (authfilename); 5579fe995a9Smrg } else { 5589fe995a9Smrg n = IceLockAuthFile (authfilename, ICEAUTH_DEFAULT_RETRIES, 5599fe995a9Smrg ICEAUTH_DEFAULT_TIMEOUT, 5609fe995a9Smrg (break_locks ? 0L : ICEAUTH_DEFAULT_DEADTIME)); 5619fe995a9Smrg if (n != IceAuthLockSuccess) { 5629d794632Smrg const char *reason = "unknown error"; 5639fe995a9Smrg switch (n) { 5649fe995a9Smrg case IceAuthLockError: 5659fe995a9Smrg reason = "error"; 5669fe995a9Smrg break; 5679fe995a9Smrg case IceAuthLockTimeout: 5689fe995a9Smrg reason = "timeout"; 5699fe995a9Smrg break; 5709fe995a9Smrg } 5719fe995a9Smrg fprintf (stderr, "%s: %s in locking authority file %s\n", 5729fe995a9Smrg ProgramName, reason, authfilename); 5739fe995a9Smrg return -1; 5749fe995a9Smrg } 5759fe995a9Smrg } 5769fe995a9Smrg 5779fe995a9Smrg /* these checks can only be done reliably after the file is locked */ 5789fe995a9Smrg exists = (access (authfilename, F_OK) == 0); 5799fe995a9Smrg if (exists && access (authfilename, W_OK) != 0) { 5809fe995a9Smrg fprintf (stderr, 5819fe995a9Smrg "%s: %s not writable, changes will be ignored\n", 5829fe995a9Smrg ProgramName, authfilename); 5839fe995a9Smrg iceauth_allowed = False; 5849fe995a9Smrg } 5859fe995a9Smrg 5869fe995a9Smrg original_umask = umask (0077); /* disallow non-owner access */ 5879fe995a9Smrg 5889fe995a9Smrg authfp = fopen (authfilename, "rb"); 5899fe995a9Smrg if (!authfp) { 5909fe995a9Smrg int olderrno = errno; 5919fe995a9Smrg 5929fe995a9Smrg /* if file there then error */ 5939fe995a9Smrg if (access (authfilename, F_OK) == 0) { /* then file does exist! */ 5949fe995a9Smrg errno = olderrno; 5959fe995a9Smrg return -1; 5969fe995a9Smrg } /* else ignore it */ 5979fe995a9Smrg fprintf (stderr, 5989fe995a9Smrg "%s: creating new authority file %s\n", 5999fe995a9Smrg ProgramName, authfilename); 6009fe995a9Smrg } else { 6019fe995a9Smrg iceauth_existed = True; 6029fe995a9Smrg n = read_auth_entries (authfp, &head, &tail); 6039fe995a9Smrg (void) fclose (authfp); 6049fe995a9Smrg if (n < 0) { 6059fe995a9Smrg fprintf (stderr, 6069fe995a9Smrg "%s: unable to read auth entries from file \"%s\"\n", 6079fe995a9Smrg ProgramName, authfilename); 6089fe995a9Smrg return -1; 6099fe995a9Smrg } 6109fe995a9Smrg iceauth_head = head; 6119fe995a9Smrg } 6129fe995a9Smrg 6139fe995a9Smrg iceauth_modified = False; 6149fe995a9Smrg 6159fe995a9Smrg if (verbose) { 6169fe995a9Smrg printf ("%s authority file %s\n", 6179fe995a9Smrg ignore_locks ? "Ignoring locks on" : "Using", authfilename); 6189fe995a9Smrg } 6199fe995a9Smrg return 0; 6209fe995a9Smrg} 6219fe995a9Smrg 6229fe995a9Smrgstatic int write_auth_file (char *tmp_nam, size_t tmp_nam_len) 6239fe995a9Smrg{ 6249fe995a9Smrg FILE *fp; 6259fe995a9Smrg AuthList *list; 6269fe995a9Smrg 6279fe995a9Smrg if ((strlen(iceauth_filename) + 3) > tmp_nam_len) { 6289fe995a9Smrg strncpy(tmp_nam, "filename too long", tmp_nam_len); 6299fe995a9Smrg tmp_nam[tmp_nam_len - 1] = '\0'; 6309fe995a9Smrg return -1; 6319fe995a9Smrg } 6329fe995a9Smrg 6339fe995a9Smrg strcpy (tmp_nam, iceauth_filename); 6349fe995a9Smrg strcat (tmp_nam, "-n"); /* for new */ 6359fe995a9Smrg (void) unlink (tmp_nam); 6369fe995a9Smrg fp = fopen (tmp_nam, "wb"); /* umask is still set to 0077 */ 6379fe995a9Smrg if (!fp) { 6389fe995a9Smrg fprintf (stderr, "%s: unable to open tmp file \"%s\"\n", 6399fe995a9Smrg ProgramName, tmp_nam); 6409fe995a9Smrg return -1; 6419fe995a9Smrg } 6429fe995a9Smrg 6439fe995a9Smrg for (list = iceauth_head; list; list = list->next) 6449fe995a9Smrg IceWriteAuthFileEntry (fp, list->auth); 6459fe995a9Smrg 6469fe995a9Smrg (void) fclose (fp); 6479fe995a9Smrg return 0; 6489fe995a9Smrg} 6499fe995a9Smrg 6509fe995a9Smrgint auth_finalize (void) 6519fe995a9Smrg{ 6529fe995a9Smrg char temp_name[1024]; /* large filename size */ 6539fe995a9Smrg 6549fe995a9Smrg if (iceauth_modified) { 655c048b52eSmrg if (dying) { 6569fe995a9Smrg if (verbose) { 6579fe995a9Smrg /* 6589fe995a9Smrg * called from a signal handler -- printf is *not* reentrant; also 6599fe995a9Smrg * fileno() might not be reentrant, avoid it if possible, and use 6609fe995a9Smrg * stderr instead of stdout 6619fe995a9Smrg */ 6629fe995a9Smrg#ifdef STDERR_FILENO 6639fe995a9Smrg WRITES(STDERR_FILENO, "\nAborting changes to authority file "); 6649fe995a9Smrg WRITES(STDERR_FILENO, iceauth_filename); 6659fe995a9Smrg WRITES(STDERR_FILENO, "\n"); 6669fe995a9Smrg#else 6679fe995a9Smrg WRITES(fileno(stderr), "\nAborting changes to authority file "); 6689fe995a9Smrg WRITES(fileno(stderr), iceauth_filename); 6699fe995a9Smrg WRITES(fileno(stderr), "\n"); 6709fe995a9Smrg#endif 6719fe995a9Smrg } 6729fe995a9Smrg } else if (!iceauth_allowed) { 6739fe995a9Smrg fprintf (stderr, 6749fe995a9Smrg "%s: %s not writable, changes ignored\n", 6759fe995a9Smrg ProgramName, iceauth_filename); 6769fe995a9Smrg } else { 6779fe995a9Smrg if (verbose) { 6789fe995a9Smrg printf ("%s authority file %s\n", 6799fe995a9Smrg ignore_locks ? "Ignoring locks and writing" : 6809fe995a9Smrg "Writing", iceauth_filename); 6819fe995a9Smrg } 6829fe995a9Smrg temp_name[0] = '\0'; 6839fe995a9Smrg if (write_auth_file (temp_name, sizeof(temp_name)) == -1) { 6849fe995a9Smrg fprintf (stderr, 6859fe995a9Smrg "%s: unable to write authority file %s\n", 6869fe995a9Smrg ProgramName, temp_name); 6879fe995a9Smrg } else { 6889fe995a9Smrg (void) unlink (iceauth_filename); 6899fe995a9Smrg#if defined(WIN32) || defined(__UNIXOS2__) 6909fe995a9Smrg if (rename(temp_name, iceauth_filename) == -1) 6919fe995a9Smrg#else 69290b6713cSmrg /* Attempt to rename() if link() fails, since this may be on a FS that does not support hard links */ 69390b6713cSmrg if (link (temp_name, iceauth_filename) == -1 && rename(temp_name, iceauth_filename) == -1) 6949fe995a9Smrg#endif 6959fe995a9Smrg { 6969fe995a9Smrg fprintf (stderr, 6979fe995a9Smrg "%s: unable to link authority file %s, use %s\n", 6989fe995a9Smrg ProgramName, iceauth_filename, temp_name); 6999fe995a9Smrg } else { 7009fe995a9Smrg (void) unlink (temp_name); 7019fe995a9Smrg } 7029fe995a9Smrg } 7039fe995a9Smrg } 7049fe995a9Smrg } 7059fe995a9Smrg 7069fe995a9Smrg if (!ignore_locks && (iceauth_filename != NULL)) { 7079fe995a9Smrg IceUnlockAuthFile (iceauth_filename); 7089fe995a9Smrg } 7099fe995a9Smrg (void) umask (original_umask); 7109fe995a9Smrg return 0; 7119fe995a9Smrg} 7129fe995a9Smrg 7139fe995a9Smrgint process_command ( 7149fe995a9Smrg const char *inputfilename, 7159fe995a9Smrg int lineno, 7169fe995a9Smrg int argc, 717e8ac26b0Smrg const char **argv) 7189fe995a9Smrg{ 7199fe995a9Smrg int status; 7209fe995a9Smrg 7219fe995a9Smrg if (argc < 1 || !argv || !argv[0]) return 1; 7229fe995a9Smrg 7239fe995a9Smrg if (dispatch_command (inputfilename, lineno, argc, argv, 7249fe995a9Smrg command_table, &status)) 7259fe995a9Smrg return status; 7269fe995a9Smrg 7279fe995a9Smrg prefix (inputfilename, lineno); 7289fe995a9Smrg fprintf (stderr, "unknown command \"%s\"\n", argv[0]); 7299fe995a9Smrg return 1; 7309fe995a9Smrg} 7319fe995a9Smrg 7329fe995a9Smrg 7339fe995a9Smrg/* 7349fe995a9Smrg * utility routines 7359fe995a9Smrg */ 7369fe995a9Smrg 7379fe995a9Smrgstatic void fprintfhex ( 7389fe995a9Smrg register FILE *fp, 7399fe995a9Smrg unsigned int len, 7409fe995a9Smrg const char *cp) 7419fe995a9Smrg{ 7429fe995a9Smrg const unsigned char *ucp = (const unsigned char *) cp; 7439fe995a9Smrg 7449fe995a9Smrg for (; len > 0; len--, ucp++) { 7459fe995a9Smrg register const char *s = hex_table[*ucp]; 7469fe995a9Smrg putc (s[0], fp); 7479fe995a9Smrg putc (s[1], fp); 7489fe995a9Smrg } 7499fe995a9Smrg return; 7509fe995a9Smrg} 7519fe995a9Smrg 7529fe995a9Smrg/* ARGSUSED */ 7539fe995a9Smrgstatic int dump_entry ( 7549d794632Smrg const char *inputfilename _X_UNUSED, 7559d794632Smrg int lineno _X_UNUSED, 7569fe995a9Smrg IceAuthFileEntry *auth, 7579d794632Smrg void *data) 7589fe995a9Smrg{ 7599fe995a9Smrg struct _list_data *ld = (struct _list_data *) data; 7609fe995a9Smrg FILE *fp = ld->fp; 7619fe995a9Smrg 7629fe995a9Smrg fprintf (fp, "%s", auth->protocol_name); 7639fe995a9Smrg putc (' ', fp); 7649fe995a9Smrg if (auth->protocol_data_length > 0) 7659fe995a9Smrg fprintfhex (fp, auth->protocol_data_length, auth->protocol_data); 7669fe995a9Smrg else 7679fe995a9Smrg fprintf (fp, "\"\""); 7689fe995a9Smrg putc (' ', fp); 7699fe995a9Smrg fprintf (fp, "%s", auth->network_id); 7709fe995a9Smrg putc (' ', fp); 7719fe995a9Smrg fprintf (fp, "%s", auth->auth_name); 7729fe995a9Smrg putc (' ', fp); 7739fe995a9Smrg 7749fe995a9Smrg if (auth->auth_data_length == 0) 7759fe995a9Smrg fprintf (fp, "\"\""); 7769fe995a9Smrg else if (!strcmp(auth->auth_name, SECURERPC) || 7779fe995a9Smrg !strcmp(auth->auth_name, K5AUTH)) 7789fe995a9Smrg fwrite (auth->auth_data, sizeof (char), auth->auth_data_length, fp); 7799fe995a9Smrg else 7809fe995a9Smrg fprintfhex (fp, auth->auth_data_length, auth->auth_data); 7819fe995a9Smrg putc ('\n', fp); 7829fe995a9Smrg 7839fe995a9Smrg return 0; 7849fe995a9Smrg} 7859fe995a9Smrg 7869fe995a9Smrgstatic int extract_entry ( 7879fe995a9Smrg const char *inputfilename, 7889fe995a9Smrg int lineno, 7899fe995a9Smrg IceAuthFileEntry *auth, 7909d794632Smrg void *data) 7919fe995a9Smrg{ 7929fe995a9Smrg struct _extract_data *ed = (struct _extract_data *) data; 7939fe995a9Smrg 7949fe995a9Smrg if (!ed->fp) { 7959fe995a9Smrg ed->fp = open_file (&ed->filename, "wb", 7969fe995a9Smrg &ed->used_stdout, 7979fe995a9Smrg inputfilename, lineno, ed->cmd); 7989fe995a9Smrg if (!ed->fp) { 7999fe995a9Smrg prefix (inputfilename, lineno); 8009fe995a9Smrg fprintf (stderr, 8019fe995a9Smrg "unable to open extraction file \"%s\"\n", 8029fe995a9Smrg ed->filename); 8039fe995a9Smrg return -1; 8049fe995a9Smrg } 8059fe995a9Smrg } 8069fe995a9Smrg IceWriteAuthFileEntry (ed->fp, auth); 8079fe995a9Smrg ed->nwritten++; 8089fe995a9Smrg 8099fe995a9Smrg return 0; 8109fe995a9Smrg} 8119fe995a9Smrg 8129fe995a9Smrg 8139fe995a9Smrgstatic int match_auth ( 8149fe995a9Smrg register IceAuthFileEntry *a, 8159fe995a9Smrg register IceAuthFileEntry *b, 8169fe995a9Smrg int *authDataSame) 8179fe995a9Smrg{ 8189fe995a9Smrg int match = strcmp (a->protocol_name, b->protocol_name) == 0 && 8199fe995a9Smrg strcmp (a->network_id, b->network_id) == 0 && 8209fe995a9Smrg strcmp (a->auth_name, b->auth_name) == 0; 8219fe995a9Smrg 8229fe995a9Smrg if (match) 8239fe995a9Smrg { 8249fe995a9Smrg *authDataSame = (a->auth_data_length == b->auth_data_length && 8259fe995a9Smrg binaryEqual (a->auth_data, b->auth_data, a->auth_data_length)); 8269fe995a9Smrg } 8279fe995a9Smrg else 8289fe995a9Smrg *authDataSame = 0; 8299fe995a9Smrg 8309fe995a9Smrg return (match); 8319fe995a9Smrg} 8329fe995a9Smrg 8339fe995a9Smrg 8349fe995a9Smrgstatic int merge_entries ( 8359fe995a9Smrg AuthList **firstp, AuthList *second, 8369fe995a9Smrg int *nnewp, int *nreplp, int *ndupp) 8379fe995a9Smrg{ 8389fe995a9Smrg AuthList *a, *b, *first, *tail; 8399fe995a9Smrg int n = 0, nnew = 0, nrepl = 0, ndup = 0; 8409fe995a9Smrg 8419fe995a9Smrg if (!second) return 0; 8429fe995a9Smrg 8439fe995a9Smrg if (!*firstp) { /* if nothing to merge into */ 8449fe995a9Smrg *firstp = second; 8459fe995a9Smrg for (tail = *firstp, n = 1; tail->next; n++, tail = tail->next) ; 8469fe995a9Smrg *nnewp = n; 8479fe995a9Smrg *nreplp = 0; 8489fe995a9Smrg *ndupp = 0; 8499fe995a9Smrg return n; 8509fe995a9Smrg } 8519fe995a9Smrg 8529fe995a9Smrg first = *firstp; 8539fe995a9Smrg /* 8549fe995a9Smrg * find end of first list and stick second list on it 8559fe995a9Smrg */ 8569fe995a9Smrg for (tail = first; tail->next; tail = tail->next) ; 8579fe995a9Smrg tail->next = second; 8589fe995a9Smrg 8599fe995a9Smrg /* 8609fe995a9Smrg * run down list freeing duplicate entries; if an entry is okay, then 8619fe995a9Smrg * bump the tail up to include it, otherwise, cut the entry out of 8629fe995a9Smrg * the chain. 8639fe995a9Smrg */ 8649fe995a9Smrg for (b = second; b; ) { 8659fe995a9Smrg AuthList *next = b->next; /* in case we free it */ 8669fe995a9Smrg int duplicate; 8679fe995a9Smrg 8689fe995a9Smrg duplicate = 0; 8699fe995a9Smrg a = first; 8709fe995a9Smrg for (;;) { 8719fe995a9Smrg int authDataSame; 8729fe995a9Smrg if (match_auth (a->auth, b->auth, &authDataSame)) { 8739fe995a9Smrg if (authDataSame) 8749fe995a9Smrg { 8759fe995a9Smrg /* found a complete duplicate, ignore */ 8769fe995a9Smrg duplicate = 1; 8779fe995a9Smrg break; 8789fe995a9Smrg } 8799fe995a9Smrg else 8809fe995a9Smrg { 8819fe995a9Smrg /* found a duplicate, but auth data differs */ 8829fe995a9Smrg 8839fe995a9Smrg AuthList tmp; /* swap it in for old one */ 8849fe995a9Smrg tmp = *a; 8859fe995a9Smrg *a = *b; 8869fe995a9Smrg *b = tmp; 8879fe995a9Smrg a->next = b->next; 8889fe995a9Smrg IceFreeAuthFileEntry (b->auth); 8899fe995a9Smrg free ((char *) b); 8909fe995a9Smrg b = NULL; 8919fe995a9Smrg tail->next = next; 8929fe995a9Smrg nrepl++; 8939fe995a9Smrg nnew--; 8949fe995a9Smrg break; 8959fe995a9Smrg } 8969fe995a9Smrg } 8979fe995a9Smrg if (a == tail) break; /* if have looked at left side */ 8989fe995a9Smrg a = a->next; 8999fe995a9Smrg } 9009fe995a9Smrg if (!duplicate && b) { /* if we didn't remove it */ 9019fe995a9Smrg tail = b; /* bump end of first list */ 9029fe995a9Smrg } 9039fe995a9Smrg b = next; 9049fe995a9Smrg 9059fe995a9Smrg if (duplicate) 9069fe995a9Smrg ndup++; 9079fe995a9Smrg else 9089fe995a9Smrg { 9099fe995a9Smrg n++; 9109fe995a9Smrg nnew++; 9119fe995a9Smrg } 9129fe995a9Smrg } 9139fe995a9Smrg 9149fe995a9Smrg *nnewp = nnew; 9159fe995a9Smrg *nreplp = nrepl; 9169fe995a9Smrg *ndupp = ndup; 9179fe995a9Smrg return n; 9189fe995a9Smrg 9199fe995a9Smrg} 9209fe995a9Smrg 9219fe995a9Smrg 9229fe995a9Smrgstatic int search_and_do ( 9239fe995a9Smrg const char *inputfilename, 9249fe995a9Smrg int lineno, 9259fe995a9Smrg int start, 9269fe995a9Smrg int argc, 927e8ac26b0Smrg const char *argv[], 9289fe995a9Smrg DoFunc do_func, 9299d794632Smrg void *data) 9309fe995a9Smrg{ 9319fe995a9Smrg int i; 9329fe995a9Smrg int status = 0; 9339fe995a9Smrg int errors = 0; 9349fe995a9Smrg AuthList *l, *next; 935e8ac26b0Smrg const char *protoname, *protodata, *netid, *authname; 9369fe995a9Smrg 9379fe995a9Smrg for (l = iceauth_head; l; l = next) 9389fe995a9Smrg { 9399fe995a9Smrg next = l->next; 9409fe995a9Smrg 9419fe995a9Smrg protoname = protodata = netid = authname = NULL; 9429fe995a9Smrg 9439fe995a9Smrg for (i = start; i < argc; i++) 9449fe995a9Smrg { 9459fe995a9Smrg if (!strncmp ("protoname=", argv[i], 10)) 9469fe995a9Smrg protoname = argv[i] + 10; 9479fe995a9Smrg else if (!strncmp ("protodata=", argv[i], 10)) 9489fe995a9Smrg protodata = argv[i] + 10; 9499fe995a9Smrg else if (!strncmp ("netid=", argv[i], 6)) 9509fe995a9Smrg netid = argv[i] + 6; 9519fe995a9Smrg else if (!strncmp ("authname=", argv[i], 9)) 9529fe995a9Smrg authname = argv[i] + 9; 9539fe995a9Smrg } 9549fe995a9Smrg 9559fe995a9Smrg status = 0; 9569fe995a9Smrg 9579fe995a9Smrg if (protoname || protodata || netid || authname) 9589fe995a9Smrg { 9599fe995a9Smrg if (protoname && strcmp (protoname, l->auth->protocol_name)) 9609fe995a9Smrg continue; 9619fe995a9Smrg 9629fe995a9Smrg if (protodata && !binaryEqual (protodata, 9639fe995a9Smrg l->auth->protocol_data, l->auth->protocol_data_length)) 9649fe995a9Smrg continue; 9659fe995a9Smrg 9669fe995a9Smrg if (netid && strcmp (netid, l->auth->network_id)) 9679fe995a9Smrg continue; 9689fe995a9Smrg 9699fe995a9Smrg if (authname && strcmp (authname, l->auth->auth_name)) 9709fe995a9Smrg continue; 9719fe995a9Smrg 9729fe995a9Smrg status = (*do_func) (inputfilename, lineno, l->auth, data); 9739fe995a9Smrg 9749fe995a9Smrg if (status < 0) 9759fe995a9Smrg break; 9769fe995a9Smrg } 9779fe995a9Smrg } 9789fe995a9Smrg 9799fe995a9Smrg if (status < 0) 9809fe995a9Smrg errors -= status; /* since status is negative */ 9819fe995a9Smrg 9829fe995a9Smrg return (errors); 9839fe995a9Smrg} 9849fe995a9Smrg 9859fe995a9Smrg 9869fe995a9Smrg/* ARGSUSED */ 9879fe995a9Smrgstatic int remove_entry ( 9889d794632Smrg const char *inputfilename _X_UNUSED, 9899d794632Smrg int lineno _X_UNUSED, 9909fe995a9Smrg IceAuthFileEntry *auth, 9919d794632Smrg void *data) 9929fe995a9Smrg{ 9939fe995a9Smrg int *nremovedp = (int *) data; 9949fe995a9Smrg AuthList **listp = &iceauth_head; 9959fe995a9Smrg AuthList *list; 9969fe995a9Smrg 9979fe995a9Smrg /* 9989fe995a9Smrg * unlink the auth we were asked to 9999fe995a9Smrg */ 10009fe995a9Smrg while ((list = *listp)->auth != auth) 10019fe995a9Smrg listp = &list->next; 10029fe995a9Smrg *listp = list->next; 10039fe995a9Smrg IceFreeAuthFileEntry (list->auth); /* free the auth */ 10049fe995a9Smrg free (list); /* free the link */ 10059fe995a9Smrg iceauth_modified = True; 10069fe995a9Smrg (*nremovedp)++; 10079fe995a9Smrg return 1; 10089fe995a9Smrg} 10099fe995a9Smrg 10109fe995a9Smrg/* 10119fe995a9Smrg * action routines 10129fe995a9Smrg */ 10139fe995a9Smrg 10149fe995a9Smrg/* 10159fe995a9Smrg * help 10169fe995a9Smrg */ 10179fe995a9Smrgint print_help ( 10189fe995a9Smrg FILE *fp, 10199fe995a9Smrg const char *cmd) 10209fe995a9Smrg{ 10219fe995a9Smrg const CommandTable *ct; 10229fe995a9Smrg int n = 0; 10239fe995a9Smrg 10249fe995a9Smrg fprintf (fp, "\n"); 10259fe995a9Smrg if (!cmd) { /* if no cmd, print all help */ 10269fe995a9Smrg for (ct = command_table; ct->name; ct++) { 10279fe995a9Smrg fprintf (fp, "%s\n\n", ct->helptext); 10289fe995a9Smrg n++; 10299fe995a9Smrg } 10309fe995a9Smrg } else { 10319d794632Smrg size_t len = strlen (cmd); 10329fe995a9Smrg for (ct = command_table; ct->name; ct++) { 10339fe995a9Smrg if (strncmp (cmd, ct->name, len) == 0) { 10349fe995a9Smrg fprintf (fp, "%s\n\n", ct->helptext); 10359fe995a9Smrg n++; 10369fe995a9Smrg } 10379fe995a9Smrg } 10389fe995a9Smrg } 10399fe995a9Smrg 10409fe995a9Smrg return n; 10419fe995a9Smrg} 10429fe995a9Smrg 10439fe995a9Smrgstatic int do_help ( 10449fe995a9Smrg const char *inputfilename, 10459fe995a9Smrg int lineno, 10469fe995a9Smrg int argc, 1047e8ac26b0Smrg const char **argv) 10489fe995a9Smrg{ 1049e8ac26b0Smrg const char *cmd = (argc > 1 ? argv[1] : NULL); 10509fe995a9Smrg int n; 10519fe995a9Smrg 10529fe995a9Smrg n = print_help (stdout, cmd); 10539fe995a9Smrg 10549fe995a9Smrg if (n < 0 || (n == 0 && !cmd)) { 10559fe995a9Smrg prefix (inputfilename, lineno); 10569fe995a9Smrg fprintf (stderr, "internal error with help"); 10579fe995a9Smrg if (cmd) { 10589fe995a9Smrg fprintf (stderr, " on command \"%s\"", cmd); 10599fe995a9Smrg } 10609fe995a9Smrg fprintf (stderr, "\n"); 10619fe995a9Smrg return 1; 10629fe995a9Smrg } 10639fe995a9Smrg 10649fe995a9Smrg if (n == 0) { 10659fe995a9Smrg prefix (inputfilename, lineno); 10669fe995a9Smrg /* already know that cmd is set in this case */ 1067e8ac26b0Smrg fprintf (stderr, "no help for nonexistent command \"%s\"\n", cmd); 10689fe995a9Smrg } 10699fe995a9Smrg 10709fe995a9Smrg return 0; 10719fe995a9Smrg} 10729fe995a9Smrg 10739fe995a9Smrg/* 10749fe995a9Smrg * questionmark 10759fe995a9Smrg */ 10769fe995a9Smrg/* ARGSUSED */ 10779fe995a9Smrgstatic int do_questionmark ( 10789d794632Smrg const char *inputfilename _X_UNUSED, 10799d794632Smrg int lineno _X_UNUSED, 10809d794632Smrg int argc _X_UNUSED, 1081e8ac26b0Smrg const char **argv _X_UNUSED) 10829fe995a9Smrg{ 10839fe995a9Smrg const CommandTable *ct; 10849d794632Smrg unsigned int i; 10859fe995a9Smrg#define WIDEST_COLUMN 72 10869d794632Smrg unsigned int col = WIDEST_COLUMN; 10879fe995a9Smrg 10889fe995a9Smrg printf ("Commands:\n"); 10899fe995a9Smrg for (ct = command_table; ct->name; ct++) { 10909fe995a9Smrg if ((col + ct->maxlen) > WIDEST_COLUMN) { 10919fe995a9Smrg if (ct != command_table) { 10929fe995a9Smrg putc ('\n', stdout); 10939fe995a9Smrg } 10949fe995a9Smrg fputs (" ", stdout); 10959fe995a9Smrg col = 8; /* length of string above */ 10969fe995a9Smrg } 10979fe995a9Smrg fputs (ct->name, stdout); 10989fe995a9Smrg col += ct->maxlen; 10999fe995a9Smrg for (i = ct->maxlen; i < COMMAND_NAMES_PADDED_WIDTH; i++) { 11009fe995a9Smrg putc (' ', stdout); 11019fe995a9Smrg col++; 11029fe995a9Smrg } 11039fe995a9Smrg } 11049fe995a9Smrg if (col != 0) { 11059fe995a9Smrg putc ('\n', stdout); 11069fe995a9Smrg } 11079fe995a9Smrg 11089fe995a9Smrg /* allow bad lines since this is help */ 11099fe995a9Smrg return 0; 11109fe995a9Smrg} 11119fe995a9Smrg 11129fe995a9Smrg/* 11139fe995a9Smrg * list [displayname ...] 11149fe995a9Smrg */ 11159fe995a9Smrgstatic int do_list ( 11169fe995a9Smrg const char *inputfilename, 11179fe995a9Smrg int lineno, 11189fe995a9Smrg int argc, 1119e8ac26b0Smrg const char **argv) 11209fe995a9Smrg{ 11219fe995a9Smrg struct _list_data ld; 11229fe995a9Smrg 11239fe995a9Smrg ld.fp = stdout; 11249fe995a9Smrg 11259fe995a9Smrg if (argc == 1) { 11269fe995a9Smrg register AuthList *l; 11279fe995a9Smrg 11289fe995a9Smrg if (iceauth_head) { 11299fe995a9Smrg for (l = iceauth_head; l; l = l->next) { 11309d794632Smrg dump_entry (inputfilename, lineno, l->auth, &ld); 11319fe995a9Smrg } 11329fe995a9Smrg } 11339fe995a9Smrg return 0; 11349fe995a9Smrg } 11359fe995a9Smrg else 11369fe995a9Smrg { 11379fe995a9Smrg return (search_and_do (inputfilename, lineno, 1, argc, argv, 11389d794632Smrg dump_entry, &ld)); 11399fe995a9Smrg } 11409fe995a9Smrg} 11419fe995a9Smrg 11429fe995a9Smrg/* 11439fe995a9Smrg * merge filename [filename ...] 11449fe995a9Smrg */ 11459fe995a9Smrgstatic int do_merge ( 11469fe995a9Smrg const char *inputfilename, 11479fe995a9Smrg int lineno, 11489fe995a9Smrg int argc, 1149e8ac26b0Smrg const char **argv) 11509fe995a9Smrg{ 11519fe995a9Smrg int i; 11529fe995a9Smrg int errors = 0; 11539fe995a9Smrg AuthList *head, *tail, *listhead, *listtail; 11549fe995a9Smrg int nentries, nnew, nrepl, ndup; 11559fe995a9Smrg 11569fe995a9Smrg if (argc < 2) { 11579fe995a9Smrg prefix (inputfilename, lineno); 11589fe995a9Smrg badcommandline (argv[0]); 11599fe995a9Smrg return 1; 11609fe995a9Smrg } 11619fe995a9Smrg 11629fe995a9Smrg listhead = listtail = NULL; 11639fe995a9Smrg 11649fe995a9Smrg for (i = 1; i < argc; i++) { 11659d794632Smrg const char *filename = argv[i]; 11669fe995a9Smrg FILE *fp; 11679fe995a9Smrg Bool used_stdin = False; 11689fe995a9Smrg 11699fe995a9Smrg fp = open_file (&filename, "rb", 11709fe995a9Smrg &used_stdin, inputfilename, lineno, 11719fe995a9Smrg argv[0]); 11729fe995a9Smrg if (!fp) { 11739fe995a9Smrg errors++; 11749fe995a9Smrg continue; 11759fe995a9Smrg } 11769fe995a9Smrg 11779fe995a9Smrg head = tail = NULL; 11789fe995a9Smrg nentries = read_auth_entries (fp, &head, &tail); 11799fe995a9Smrg if (nentries == 0) { 11809fe995a9Smrg prefix (inputfilename, lineno); 11819fe995a9Smrg fprintf (stderr, "unable to read any entries from file \"%s\"\n", 11829fe995a9Smrg filename); 11839fe995a9Smrg errors++; 11849fe995a9Smrg } else { /* link it in */ 11859fe995a9Smrg add_to_list (listhead, listtail, head); 11869fe995a9Smrg } 11879fe995a9Smrg 11889fe995a9Smrg if (!used_stdin) (void) fclose (fp); 11899fe995a9Smrg } 11909fe995a9Smrg 11919fe995a9Smrg /* 11929fe995a9Smrg * if we have new entries, merge them in (freeing any duplicates) 11939fe995a9Smrg */ 11949fe995a9Smrg if (listhead) { 11959fe995a9Smrg nentries = merge_entries (&iceauth_head, listhead, 11969fe995a9Smrg &nnew, &nrepl, &ndup); 11979fe995a9Smrg if (verbose) 11989fe995a9Smrg printf ("%d entries read in: %d new, %d replacement%s\n", 11999fe995a9Smrg nentries, nnew, nrepl, nrepl != 1 ? "s" : ""); 12009fe995a9Smrg if (nentries > 0) iceauth_modified = True; 12019fe995a9Smrg } 12029fe995a9Smrg 12039fe995a9Smrg return 0; 12049fe995a9Smrg} 12059fe995a9Smrg 12069fe995a9Smrg/* 12079fe995a9Smrg * extract filename displayname [displayname ...] 12089fe995a9Smrg */ 12099fe995a9Smrgstatic int do_extract ( 12109fe995a9Smrg const char *inputfilename, 12119fe995a9Smrg int lineno, 12129fe995a9Smrg int argc, 1213e8ac26b0Smrg const char **argv) 12149fe995a9Smrg{ 12159fe995a9Smrg int errors; 12169fe995a9Smrg struct _extract_data ed; 12179fe995a9Smrg 12189fe995a9Smrg if (argc < 3) { 12199fe995a9Smrg prefix (inputfilename, lineno); 12209fe995a9Smrg badcommandline (argv[0]); 12219fe995a9Smrg return 1; 12229fe995a9Smrg } 12239fe995a9Smrg 12249fe995a9Smrg ed.fp = NULL; 12259fe995a9Smrg ed.filename = argv[1]; 12269fe995a9Smrg ed.nwritten = 0; 12279fe995a9Smrg ed.cmd = argv[0]; 12289fe995a9Smrg 12299fe995a9Smrg errors = search_and_do (inputfilename, lineno, 2, argc, argv, 12309d794632Smrg extract_entry, &ed); 12319fe995a9Smrg 12329fe995a9Smrg if (!ed.fp) { 12339fe995a9Smrg fprintf (stderr, 12349fe995a9Smrg "No matches found, authority file \"%s\" not written\n", 12359fe995a9Smrg ed.filename); 12369fe995a9Smrg } else { 12379fe995a9Smrg if (verbose) { 12389fe995a9Smrg printf ("%d entries written to \"%s\"\n", 12399fe995a9Smrg ed.nwritten, ed.filename); 12409fe995a9Smrg } 12419fe995a9Smrg if (!ed.used_stdout) { 12429fe995a9Smrg (void) fclose (ed.fp); 12439fe995a9Smrg } 12449fe995a9Smrg } 12459fe995a9Smrg 12469fe995a9Smrg return errors; 12479fe995a9Smrg} 12489fe995a9Smrg 12499fe995a9Smrg 12509fe995a9Smrg/* 12519fe995a9Smrg * add protoname protodata netid authname authdata 12529fe995a9Smrg */ 12539fe995a9Smrgstatic int do_add ( 12549fe995a9Smrg const char *inputfilename, 12559fe995a9Smrg int lineno, 12569fe995a9Smrg int argc, 1257e8ac26b0Smrg const char **argv) 12589fe995a9Smrg{ 12599fe995a9Smrg int n, nnew, nrepl, ndup; 1260e8ac26b0Smrg const char *protoname; 1261e8ac26b0Smrg const char *protodata_hex; 12629fe995a9Smrg char *protodata = NULL; /* not required */ 1263e8ac26b0Smrg const char *netid; 1264e8ac26b0Smrg const char *authname; 1265e8ac26b0Smrg const char *authdata_hex; 12669fe995a9Smrg char *authdata = NULL; 12679fe995a9Smrg int protodata_len, authdata_len; 12689fe995a9Smrg IceAuthFileEntry *auth = NULL; 12699fe995a9Smrg AuthList *list; 12709fe995a9Smrg int status = 0; 12719fe995a9Smrg 12729fe995a9Smrg if (argc != 6 || !argv[1] || !argv[2] || 12739fe995a9Smrg !argv[3] || !argv[4] || !argv[5]) 12749fe995a9Smrg { 12759fe995a9Smrg prefix (inputfilename, lineno); 12769fe995a9Smrg badcommandline (argv[0]); 12779fe995a9Smrg return 1; 12789fe995a9Smrg } 12799fe995a9Smrg 12809fe995a9Smrg protoname = argv[1]; 12819fe995a9Smrg protodata_hex = argv[2]; 12829fe995a9Smrg netid = argv[3]; 12839fe995a9Smrg authname = argv[4]; 12849fe995a9Smrg authdata_hex = argv[5]; 12859fe995a9Smrg 12869fe995a9Smrg protodata_len = strlen (protodata_hex); 12879fe995a9Smrg if (protodata_len > 0) 12889fe995a9Smrg { 1289c048b52eSmrg if (protodata_len > 1 && 1290c048b52eSmrg protodata_hex[0] == '"' && protodata_hex[protodata_len - 1] == '"') 12919fe995a9Smrg { 12929fe995a9Smrg protodata = malloc (protodata_len - 1); 12939fe995a9Smrg if (protodata) 12949fe995a9Smrg { 12959fe995a9Smrg strncpy (protodata, protodata_hex + 1, protodata_len - 2); 12969fe995a9Smrg protodata_len -= 2; 12979fe995a9Smrg } 12989fe995a9Smrg else 12999fe995a9Smrg goto add_bad_malloc; 13009fe995a9Smrg } 13019fe995a9Smrg else 13029fe995a9Smrg { 13039fe995a9Smrg protodata_len = cvthexkey (protodata_hex, &protodata); 13049fe995a9Smrg if (protodata_len < 0) 13059fe995a9Smrg { 13069fe995a9Smrg prefix (inputfilename, lineno); 13079fe995a9Smrg fprintf (stderr, 13089fe995a9Smrg "protodata_hex contains odd number of or non-hex characters\n"); 13099fe995a9Smrg return (1); 13109fe995a9Smrg } 13119fe995a9Smrg } 13129fe995a9Smrg } 13139fe995a9Smrg 13149fe995a9Smrg authdata_len = strlen (authdata_hex); 1315c048b52eSmrg if (authdata_len > 1 && 1316c048b52eSmrg authdata_hex[0] == '"' && authdata_hex[authdata_len - 1] == '"') 13179fe995a9Smrg { 13189fe995a9Smrg authdata = malloc (authdata_len - 1); 13199fe995a9Smrg if (authdata) 13209fe995a9Smrg { 13219fe995a9Smrg strncpy (authdata, authdata_hex + 1, authdata_len - 2); 13229fe995a9Smrg authdata_len -= 2; 13239fe995a9Smrg } 13249fe995a9Smrg else 13259fe995a9Smrg goto add_bad_malloc; 13269fe995a9Smrg } 13279fe995a9Smrg else if (!strcmp (protoname, SECURERPC) || !strcmp (protoname, K5AUTH)) 13289fe995a9Smrg { 13299fe995a9Smrg authdata = malloc (authdata_len + 1); 13309fe995a9Smrg if (authdata) 13319fe995a9Smrg strcpy (authdata, authdata_hex); 13329fe995a9Smrg else 13339fe995a9Smrg goto add_bad_malloc; 13349fe995a9Smrg } 13359fe995a9Smrg else 13369fe995a9Smrg { 13379fe995a9Smrg authdata_len = cvthexkey (authdata_hex, &authdata); 13389fe995a9Smrg if (authdata_len < 0) 13399fe995a9Smrg { 13409fe995a9Smrg prefix (inputfilename, lineno); 13419fe995a9Smrg fprintf (stderr, 13429fe995a9Smrg "authdata_hex contains odd number of or non-hex characters\n"); 13439fe995a9Smrg free (protodata); 13449fe995a9Smrg return (1); 13459fe995a9Smrg } 13469fe995a9Smrg } 13479fe995a9Smrg 13489fe995a9Smrg auth = (IceAuthFileEntry *) malloc (sizeof (IceAuthFileEntry)); 13499fe995a9Smrg 13509fe995a9Smrg if (!auth) 13519fe995a9Smrg goto add_bad_malloc; 13529fe995a9Smrg 13539fe995a9Smrg auth->protocol_name = copystring (protoname); 13549fe995a9Smrg auth->protocol_data_length = protodata_len; 13559fe995a9Smrg auth->protocol_data = protodata; 13569fe995a9Smrg auth->network_id = copystring (netid); 13579fe995a9Smrg auth->auth_name = copystring (authname); 13589fe995a9Smrg auth->auth_data_length = authdata_len; 13599fe995a9Smrg auth->auth_data = authdata; 13609fe995a9Smrg 13619fe995a9Smrg if (!auth->protocol_name || 13629fe995a9Smrg (!auth->protocol_data && auth->protocol_data_length > 0) || 13639fe995a9Smrg !auth->network_id || !auth->auth_name || 13649fe995a9Smrg (!auth->auth_data && auth->auth_data_length > 0)) 13659fe995a9Smrg { 13669fe995a9Smrg goto add_bad_malloc; 13679fe995a9Smrg } 13689fe995a9Smrg 13699fe995a9Smrg list = (AuthList *) malloc (sizeof (AuthList)); 13709fe995a9Smrg 13719fe995a9Smrg if (!list) 13729fe995a9Smrg goto add_bad_malloc; 13739fe995a9Smrg 13749fe995a9Smrg list->next = NULL; 13759fe995a9Smrg list->auth = auth; 13769fe995a9Smrg 13779fe995a9Smrg /* 13789fe995a9Smrg * merge it in; note that merge will deal with allocation 13799fe995a9Smrg */ 13809fe995a9Smrg 13819fe995a9Smrg n = merge_entries (&iceauth_head, list, &nnew, &nrepl, &ndup); 13829fe995a9Smrg 13839fe995a9Smrg if (n > 0) 13849fe995a9Smrg iceauth_modified = True; 13859fe995a9Smrg else 13869fe995a9Smrg { 13879fe995a9Smrg prefix (inputfilename, lineno); 13889fe995a9Smrg if (ndup > 0) 13899fe995a9Smrg { 13909fe995a9Smrg status = 0; 13919fe995a9Smrg fprintf (stderr, "no records added - all duplicate\n"); 13929fe995a9Smrg } 13939fe995a9Smrg else 13949fe995a9Smrg { 13959fe995a9Smrg status = 1; 13969fe995a9Smrg fprintf (stderr, "unable to merge in added record\n"); 13979fe995a9Smrg } 13989fe995a9Smrg goto cant_add; 13999fe995a9Smrg } 14009fe995a9Smrg 14019fe995a9Smrg return 0; 14029fe995a9Smrg 14039fe995a9Smrg 14049fe995a9Smrgadd_bad_malloc: 14059fe995a9Smrg 14069fe995a9Smrg status = 1; 14079fe995a9Smrg prefix (inputfilename, lineno); 14089fe995a9Smrg fprintf (stderr, "unable to allocate memory to add an entry\n"); 14099fe995a9Smrg 14109fe995a9Smrgcant_add: 14119fe995a9Smrg 14129fe995a9Smrg if (protodata) 14139fe995a9Smrg free (protodata); 14149fe995a9Smrg if (authdata) 14159fe995a9Smrg free (authdata); 14169fe995a9Smrg if (auth) 14179fe995a9Smrg { 14189fe995a9Smrg if (auth->protocol_name) 14199fe995a9Smrg free (auth->protocol_name); 14209fe995a9Smrg /* auth->protocol_data already freed, 14219fe995a9Smrg since it's the same as protodata */ 14229fe995a9Smrg if (auth->network_id) 14239fe995a9Smrg free (auth->network_id); 14249fe995a9Smrg if (auth->auth_name) 14259fe995a9Smrg free (auth->auth_name); 14269fe995a9Smrg /* auth->auth_data already freed, 14279fe995a9Smrg since it's the same as authdata */ 14289fe995a9Smrg free ((char *) auth); 14299fe995a9Smrg } 14309fe995a9Smrg 14319fe995a9Smrg return status; 14329fe995a9Smrg} 14339fe995a9Smrg 14349fe995a9Smrg/* 14359fe995a9Smrg * remove displayname 14369fe995a9Smrg */ 14379fe995a9Smrgstatic int do_remove ( 14389fe995a9Smrg const char *inputfilename, 14399fe995a9Smrg int lineno, 14409fe995a9Smrg int argc, 1441e8ac26b0Smrg const char **argv) 14429fe995a9Smrg{ 14439fe995a9Smrg int nremoved = 0; 14449fe995a9Smrg int errors; 14459fe995a9Smrg 14469fe995a9Smrg if (argc < 2) { 14479fe995a9Smrg prefix (inputfilename, lineno); 14489fe995a9Smrg badcommandline (argv[0]); 14499fe995a9Smrg return 1; 14509fe995a9Smrg } 14519fe995a9Smrg 14529fe995a9Smrg errors = search_and_do (inputfilename, lineno, 1, argc, argv, 14539d794632Smrg remove_entry, &nremoved); 14549fe995a9Smrg if (verbose) printf ("%d entries removed\n", nremoved); 14559fe995a9Smrg return errors; 14569fe995a9Smrg} 14579fe995a9Smrg 14589fe995a9Smrg/* 14599fe995a9Smrg * info 14609fe995a9Smrg */ 14619fe995a9Smrgstatic int do_info ( 14629fe995a9Smrg const char *inputfilename, 14639fe995a9Smrg int lineno, 14649fe995a9Smrg int argc, 1465e8ac26b0Smrg const char **argv) 14669fe995a9Smrg{ 14679fe995a9Smrg int n; 14689fe995a9Smrg AuthList *l; 14699fe995a9Smrg 14709fe995a9Smrg if (argc != 1) { 14719fe995a9Smrg prefix (inputfilename, lineno); 14729fe995a9Smrg badcommandline (argv[0]); 14739fe995a9Smrg return 1; 14749fe995a9Smrg } 14759fe995a9Smrg 14769fe995a9Smrg for (l = iceauth_head, n = 0; l; l = l->next, n++) ; 14779fe995a9Smrg 14789fe995a9Smrg printf ("Authority file: %s\n", 14799fe995a9Smrg iceauth_filename ? iceauth_filename : "(none)"); 14809fe995a9Smrg printf ("File new: %s\n", iceauth_existed ? No : Yes); 14819fe995a9Smrg printf ("File locked: %s\n", ignore_locks ? No : Yes); 14829fe995a9Smrg printf ("Number of entries: %d\n", n); 14839fe995a9Smrg printf ("Changes honored: %s\n", iceauth_allowed ? Yes : No); 14849fe995a9Smrg printf ("Changes made: %s\n", iceauth_modified ? Yes : No); 14859fe995a9Smrg printf ("Current input: %s:%d\n", inputfilename, lineno); 14869fe995a9Smrg return 0; 14879fe995a9Smrg} 14889fe995a9Smrg 14899fe995a9Smrg 14909fe995a9Smrg/* 14919fe995a9Smrg * exit 14929fe995a9Smrg */ 14939fe995a9Smrgstatic Bool alldone = False; 14949fe995a9Smrg 14959fe995a9Smrg/* ARGSUSED */ 14969fe995a9Smrgstatic int do_exit ( 14979d794632Smrg const char *inputfilename _X_UNUSED, 14989d794632Smrg int lineno _X_UNUSED, 14999d794632Smrg int argc _X_UNUSED, 1500e8ac26b0Smrg const char **argv _X_UNUSED) 15019fe995a9Smrg{ 15029fe995a9Smrg /* allow bogus stuff */ 15039fe995a9Smrg alldone = True; 15049fe995a9Smrg return 0; 15059fe995a9Smrg} 15069fe995a9Smrg 15079fe995a9Smrg/* 15089fe995a9Smrg * quit 15099fe995a9Smrg */ 15109fe995a9Smrg/* ARGSUSED */ 15119fe995a9Smrgstatic int do_quit ( 15129d794632Smrg const char *inputfilename _X_UNUSED, 15139d794632Smrg int lineno _X_UNUSED, 15149d794632Smrg int argc _X_UNUSED, 1515e8ac26b0Smrg const char **argv _X_UNUSED) 15169fe995a9Smrg{ 15179fe995a9Smrg /* allow bogus stuff */ 15189fe995a9Smrg die (0); 15199fe995a9Smrg /* NOTREACHED */ 15209fe995a9Smrg return -1; /* for picky compilers */ 15219fe995a9Smrg} 15229fe995a9Smrg 15239fe995a9Smrg 15249fe995a9Smrg/* 15259fe995a9Smrg * source filename 15269fe995a9Smrg */ 15279fe995a9Smrgstatic int do_source ( 15289fe995a9Smrg const char *inputfilename, 15299fe995a9Smrg int lineno, 15309fe995a9Smrg int argc, 1531e8ac26b0Smrg const char **argv) 15329fe995a9Smrg{ 15339d794632Smrg const char *script; 15349fe995a9Smrg char buf[BUFSIZ]; 15359fe995a9Smrg FILE *fp; 15369fe995a9Smrg Bool used_stdin = False; 15379d794632Smrg size_t len; 15389fe995a9Smrg int errors = 0, status; 15399fe995a9Smrg int sublineno = 0; 15409fe995a9Smrg char **subargv; 15419fe995a9Smrg int subargc; 15429fe995a9Smrg Bool prompt = False; /* only true if reading from tty */ 15439fe995a9Smrg 15449fe995a9Smrg if (argc != 2 || !argv[1]) { 15459fe995a9Smrg prefix (inputfilename, lineno); 15469fe995a9Smrg badcommandline (argv[0]); 15479fe995a9Smrg return 1; 15489fe995a9Smrg } 15499fe995a9Smrg 15509fe995a9Smrg script = argv[1]; 15519fe995a9Smrg 15529fe995a9Smrg fp = open_file (&script, "r", &used_stdin, inputfilename, lineno, argv[0]); 15539fe995a9Smrg if (!fp) { 15549fe995a9Smrg return 1; 15559fe995a9Smrg } 15569fe995a9Smrg 15579fe995a9Smrg if (verbose && used_stdin && isatty (fileno (fp))) prompt = True; 15589fe995a9Smrg 15599fe995a9Smrg while (!alldone) { 15609fe995a9Smrg buf[0] = '\0'; 15619fe995a9Smrg if (prompt) { 15629fe995a9Smrg printf ("iceauth> "); 15639fe995a9Smrg fflush (stdout); 15649fe995a9Smrg } 15659fe995a9Smrg if (fgets (buf, sizeof buf, fp) == NULL) break; 15669fe995a9Smrg sublineno++; 15679fe995a9Smrg len = strlen (buf); 15689fe995a9Smrg if (len == 0 || buf[0] == '#') continue; 15699fe995a9Smrg if (buf[len-1] != '\n') { 15709fe995a9Smrg prefix (script, sublineno); 15719fe995a9Smrg fprintf (stderr, "line too long\n"); 15729fe995a9Smrg errors++; 15739fe995a9Smrg break; 15749fe995a9Smrg } 15759fe995a9Smrg buf[--len] = '\0'; /* remove new line */ 15769fe995a9Smrg subargv = split_into_words (buf, &subargc); 15779fe995a9Smrg if (subargv) { 1578e8ac26b0Smrg status = process_command (script, sublineno, subargc, 1579e8ac26b0Smrg (const char **) subargv); 15809fe995a9Smrg free ((char *) subargv); 15819fe995a9Smrg errors += status; 15829fe995a9Smrg } else { 15839fe995a9Smrg prefix (script, sublineno); 15849fe995a9Smrg fprintf (stderr, "unable to break line into words\n"); 15859fe995a9Smrg errors++; 15869fe995a9Smrg } 15879fe995a9Smrg } 15889fe995a9Smrg 15899fe995a9Smrg if (!used_stdin) { 15909fe995a9Smrg (void) fclose (fp); 15919fe995a9Smrg } 15929fe995a9Smrg return errors; 15939fe995a9Smrg} 1594