patch: aklog which queries ptservers (plus small getarg patch)

allbery allbery at TULLY.ECE.CMU.EDU
Mon May 15 00:54:10 CEST 2000


This patch adds a "proper" aklog to Arla:  unlike KTH afslog, it queries the
ptserver to determine the AFS ID associated with the current Kerberos
principal.  It also uses getarg(), and as a side effect has most if not all
of the core dumps in argument parsing fixed.

The argument parsing really wanted a modification to getarg(), which is also
included; this change is backward-compatible with existing getarg():  a flag
telling it to use the first partial match from the argument array instead of
failing.  (Otherwise "aklog -h" tries to get tokens for the first cell
matching "-h" in your CellServDB, which here at CMU is urz.uni-heidelberg.de.)

Patch is also available via AFS (may be useful if mailers mangle this):

	/afs/ece.cmu.edu/usr/allbery/Public/arla-0.33-aklog.patch

++bsa

===============================================================================
diff -ur --unidirectional-new-file arla-0.33-dist/appl/afsutils/Makefile.in arla-0.33/appl/afsutils/Makefile.in
--- arla-0.33-dist/appl/afsutils/Makefile.in	Sun Feb  6 16:30:22 2000
+++ arla-0.33/appl/afsutils/Makefile.in	Sun May 14 08:28:11 2000
@@ -19,7 +19,7 @@
 transform	= @program_transform_name@
 EXECSUFFIX	= @EXECSUFFIX@
 
-APPL_BIN	= klog tokens unlog up
+APPL_BIN	= aklog klog tokens unlog up
 
 DEFS		= @DEFS@
 
@@ -63,17 +63,20 @@
 		  ../../util/libutil.a ../../lib/sl/libsl.a ../../lib/roken/libroken.a \
 		  ../../lib/ko/libko.a
 
-PROGS		= klog sys tokens unlog up
+PROGS		= aklog klog sys tokens unlog up
+AKLOG_SRCS	= aklog.c
 KLOG_SRCS	= klog.c
 SYS_SRCS	= sys.c
 TOKENS_SRCS	= tokens.c
 UNLOG_SRCS	= unlog.c
 UP_SRCS		= up.c
-SRCS		= $(KLOG_SRCS)			\
+SRCS		= $(AKLOG_SRCS)			\
+		  $(KLOG_SRCS)			\
 		  $(SYS_SRCS)			\
 		  $(TOKENS_SRCS)		\
 		  $(UNLOG_SRCS)			\
 		  $(UP_SRCS)
+AKLOG_OBJS	= aklog.o
 KLOG_OBJS	= klog.o
 SYS_OBJS	= sys.o
 TOKENS_OBJS	= tokens.o
@@ -100,6 +103,9 @@
 			f=`echo $$x | sed '$(transform)'`; \
 			rm -f $(DESTDIR)$(bindir)/$$f; \
 		done
+
+aklog:		$(AKLOG_OBJS) $(LIBDEPENDS)
+		$(CC) $(LDFLAGS) -o $@ $(AKLOG_OBJS) $(LIBS)
 
 klog:		$(KLOG_OBJS) $(LIBDEPENDS)
 		$(CC) $(LDFLAGS) -o $@ $(KLOG_OBJS) $(LIBS)
diff -ur --unidirectional-new-file arla-0.33-dist/appl/afsutils/aklog.c arla-0.33/appl/afsutils/aklog.c
--- arla-0.33-dist/appl/afsutils/aklog.c	Wed Dec 31 19:00:00 1969
+++ arla-0.33/appl/afsutils/aklog.c	Sun May 14 10:58:46 2000
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 1995 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * allbery at ece.cmu.edu 2000-05-13
+ * Lifted from kth-krb, bodged parts of klog.c into it.  The result is that
+ * it gets the AFS token for your Kerberos principal, not your user ID.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+RCSID("$Id: aklog.c,v 1.24 1999/12/02 16:58:28 joda Exp $");
+
+#include "appl_locl.h"
+#include "kafs.h"
+
+/* sigh */
+#undef _PATH_THISCELL
+#define _PATH_THISCELL "/usr/arla/etc/ThisCell"
+#undef _PATH_THESECELLS
+#define _PATH_THESECELLS "/usr/arla/etc/TheseCells"
+#undef _PATH_CELLSERVDB
+#define _PATH_CELLSERVDB "/usr/arla/etc/CellServDB"
+
+static int debug = 0;
+
+static void
+DEBUG(const char *, ...)
+#ifdef __GNUC__
+__attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+static void
+DEBUG(const char *fmt, ...)
+{
+  va_list ap;
+  if (debug) {
+    va_start(ap, fmt);
+    vwarnx(fmt, ap);
+    va_end(ap);
+  }
+}
+
+/* 
+ * Figure out the AFS ID of a user name 
+ * Lifted from klog.c.
+ */
+
+static int
+get_afs_id(const char *arg_principal, const char *arg_cell)
+{
+    int32_t returned_id;
+    int ret;
+    struct passwd *pwd;
+
+    ret = arlalib_get_viceid (arg_principal,
+			      arg_cell,
+			      &returned_id);
+    if (ret == 0)
+	return returned_id;
+
+
+    /* 
+     * If we failed to talk to any server, try various stupid means of
+     * guessing the AFS ID 
+     */
+
+    pwd = getpwnam(arg_principal);
+    if(pwd == NULL) {
+	returned_id = getuid();
+	warnx ("Couldn't get AFS ID for %s@%s, using current UID (%d)",
+	       arg_principal, arg_cell, returned_id);
+    } else {
+	returned_id = pwd->pw_uid;
+	warnx ("Couldn't get AFS ID for %s@%s, using %d from /etc/passwd",
+	       arg_principal, arg_cell, returned_id);
+    }
+    return (returned_id);
+}
+
+static char *
+expand_cell_name(char *cell)
+{
+  FILE *f;
+  static char buf[128];
+  char *p;
+
+  f = fopen(_PATH_CELLSERVDB, "r");
+  if(f == NULL)
+    return cell;
+  while(fgets(buf, sizeof(buf), f) != NULL) {
+    if(buf[0] == '>') {
+      for(p=buf; *p && !isspace(*p) && *p != '#'; p++)
+	  ;
+      *p = '\0';
+      if(strstr(buf, cell)){
+	fclose(f);
+	return buf + 1;
+      }
+    }
+    buf[0] = 0;
+  }
+  fclose(f);
+  return cell;
+}
+
+static int
+createuser (char *cell)
+{
+  char cellbuf[64];
+  char name[ANAME_SZ];
+  char instance[INST_SZ];
+  char realm[REALM_SZ];
+  char cmd[1024];
+
+  if (cell == NULL) {
+    FILE *f;
+    int len;
+
+    f = fopen (_PATH_THISCELL, "r");
+    if (f == NULL)
+      err (1, "open(%s)", _PATH_THISCELL);
+    if (fgets (cellbuf, sizeof(cellbuf), f) == NULL)
+      err (1, "read cellname from %s", _PATH_THISCELL);
+    fclose (f);
+    len = strlen(cellbuf);
+    if (cellbuf[len-1] == '\n')
+      cellbuf[len-1] = '\0';
+    cell = cellbuf;
+  }
+
+  if(krb_get_default_principal(name, instance, realm))
+    errx (1, "Could not even figure out who you are");
+
+  snprintf (cmd, sizeof(cmd),
+	    "pts createuser %s%s%s@%s -cell %s",
+	    name, *instance ? "." : "", instance, strlwr(realm),
+	    cell);
+  DEBUG("Executing %s", cmd);
+  return system(cmd);
+}
+
+#ifndef KERBEROS
+
+int
+main(int argc, char **argv)
+{
+  errx (1, "Kerberos support isn't compiled in");
+  return 1;
+}
+
+#else
+
+static char *arg_cell = NULL;
+static int arg_createuser = 0;
+static int arg_debug = 0;
+static int arg_help = 0;
+static int arg_hosts = 0;
+static char *arg_realm = NULL;
+static int arg_noprdb = 0;
+static char *arg_path = NULL;
+static int arg_quiet = 0;
+static int arg_unlog = 0;
+static int arg_version = 0;
+static int arg_zsubs = 0;
+
+struct getargs args[] = {
+  {"cell", 0, arg_string, &arg_cell,
+   "cell to authenticate to", "cell name", arg_optional},
+  {"createuser", 0, arg_flag, &arg_createuser,
+   "create PTS user in remote cell", NULL, arg_optional},
+  {"debug", 0, arg_flag, &arg_debug,
+   "print debugging information", NULL, arg_optional},
+  {"help", 0, arg_flag, &arg_help,
+   "print help", NULL, arg_optional},
+  {"hosts", 0, arg_flag, &arg_hosts,
+   "print host address information (unimplemented)", NULL, arg_optional},
+  {"krbrealm", 0, arg_string, &arg_realm,
+   "kerberos realm for cell", "kerberos realm", arg_optional},
+  {"noprdb", 0, arg_flag, &arg_noprdb,
+   "don't try to determine AFS ID", NULL, arg_optional},
+  {"path", 0, arg_string, &arg_path,
+   "AFS path to authenticate to", "path", arg_optional},
+  {"quiet", 0, arg_flag, &arg_quiet,
+   "fail silently if no ticket cache", NULL, arg_optional},
+  {"unlog", 0, arg_flag, &arg_unlog,
+   "discard tokens", NULL, arg_optional},
+  {"version", 0, arg_flag, &arg_version,
+   "print version", NULL, arg_optional},
+  {"zsubs", 0, arg_flag, &arg_zsubs,
+   "update zephyr subscriptions (unimplemented)"},
+  {NULL, 0, arg_end, NULL, NULL},
+};
+
+int
+main(int argc, char **argv)
+{
+  int i;
+  int do_aklog = -1;
+  int do_createuser = -1;
+  char *cell = NULL;
+  char *realm = NULL;
+  char cellbuf[64];
+  int afsid;
+  char name[ANAME_SZ];
+  char instance[INST_SZ];
+  char rrealm[REALM_SZ];
+  char principal[ANAME_SZ+INST_SZ+2];
+  FILE *fp;
+  int optind = 0;
+  int noprdb = 0;
+  int quiet = 0;
+  int rc;
+
+  rc = getarg(args, argc, argv, &optind, ARG_AFSSTYLE|ARG_USEFIRST);
+  if(rc && *argv[optind] == '-') {
+    warnx ("Bad argument: %s", argv[optind]);
+    arg_printusage(args, NULL, "<cell or path>", ARG_AFSSTYLE|ARG_USEFIRST);
+    exit(1);
+  }
+  if(arg_help) {
+    arg_printusage(args, NULL, "<cell or path>", ARG_AFSSTYLE|ARG_USEFIRST);
+    exit(1);
+  }
+  if(arg_version)
+    errx (0, "part of %s-%s", PACKAGE, VERSION);
+
+  if(!k_hasafs())
+    errx (1, "AFS support is not loaded.");
+  ports_init();
+  cell_init(0); /* XXX */
+
+  if(arg_createuser)
+    do_createuser = do_aklog = 1;
+  if(arg_cell) {
+    cell = expand_cell_name(arg_cell);
+    do_aklog = 1;
+  }
+  if(arg_realm)
+    realm = arg_realm;
+  if(arg_path) {
+    if(k_afs_cell_of_file(arg_path, cellbuf, sizeof(cellbuf)))
+      errx (1, "No cell found for file \"%s\".", arg_path);
+    else
+      cell = cellbuf;
+    do_aklog = 1;
+  }
+  if(arg_unlog)
+    exit(k_unlog());
+  if(arg_hosts)
+    warnx ("Argument -hosts is not implemented.");
+  if(arg_zsubs)
+    warnx ("Argument -zsubs is not implemented.");
+  if(arg_noprdb)
+    noprdb = 1;
+  if(arg_debug)
+    debug = 1;
+  if(arg_quiet)
+    quiet = 1;
+  if(rc && argv[optind]) {
+    if(!strcmp(argv[optind], ".") ||
+       !strcmp(argv[optind], "..") ||
+       strchr(argv[optind], '/')){
+      DEBUG("I guess that \"%s\" is a filename.", argv[optind]);
+      if(k_afs_cell_of_file(argv[optind], cellbuf, sizeof(cellbuf)))
+	errx (1, "No cell found for file \"%s\".", argv[optind]);
+      else {
+	cell = cellbuf;
+	DEBUG("The file \"%s\" lives in cell \"%s\".", argv[optind], cell);
+      }
+    }else{
+      cell = expand_cell_name(argv[optind]);
+      DEBUG("I guess that %s is cell %s.", argv[optind], cell);
+    }
+    do_aklog = 1;
+    if(noprdb)
+      afsid = getuid();
+    else {
+      /* get Kerberos principal; map to AFS id */
+      if(krb_get_default_principal(name, instance, rrealm)) {
+	if(quiet)
+	  exit(0);
+	errx (1, "Could not even figure out who you are");
+      }
+      /* @@@ check if the realms are the same? */
+      if (!realm) realm = rrealm;
+      snprintf(principal, sizeof(principal),
+	       "%s%s%s",
+	       name, *instance ? "." : "", instance);
+      afsid = get_afs_id(principal, cell);
+    }
+    if(do_aklog == 1){
+      do_aklog = 0;
+#ifdef HAVE_KRB_AFSLOG_UID
+      rc = krb_afslog_uid(cell, realm, afsid);
+#else
+      rc = k_afslog_uid(cell, realm, afsid);
+#endif
+      if(rc)
+	errx (1, "Failed getting tokens for cell %s in realm %s.", 
+	      cell?cell:"(local cell)", realm?realm:"(local realm)");
+    }
+    if(do_createuser == 1) {
+      do_createuser = 0;
+      if(createuser(cell))
+	errx (1, "Failed creating user in cell %s", cell?cell:"(local cell)");
+    }
+  }
+  if(do_aklog == -1 && do_createuser == -1) {
+    if(!noprdb) {
+      /* get Kerberos principal; map to AFS id */
+      if(krb_get_default_principal(name, instance, rrealm)) {
+	if(quiet)
+	  exit(0);
+	errx (1, "Could not even figure out who you are");
+      }
+      /* @@@ check if the realms are the same? */
+      if (!realm) realm = rrealm;
+      snprintf(principal, sizeof(principal),
+	       "%s%s%s",
+	       name, *instance ? "." : "", instance);
+    }
+    if (!(fp = fopen(_PATH_THESECELLS, "r")) &&
+	!(fp = fopen(_PATH_THISCELL, "r")))
+      errx (1, "Couldn't determine local cell(s)");
+    i = 0;
+    while(fgets(cellbuf, sizeof(cellbuf), fp) != NULL) {
+      cellbuf[strlen(cellbuf) - 1] = 0;
+      if(noprdb)
+	afsid = getuid();
+      else
+	afsid = get_afs_id(principal, cellbuf);
+#ifdef HAVE_KRB_AFSLOG_UID
+      rc = krb_afslog_uid(cell, realm, afsid);
+#else
+      rc = k_afslog_uid(cell, realm, afsid);
+#endif
+      if (rc) {
+	warnx ("Failed getting tokens for cell %s.", cellbuf);
+	i = 1;
+      }
+    }
+    fclose(fp);
+    if (i)
+      exit(1);
+  }
+  return 0;
+}
+
+#endif /* KERBEROS */
diff -ur --unidirectional-new-file arla-0.33-dist/lib/roken/getarg.c arla-0.33/lib/roken/getarg.c
--- arla-0.33-dist/lib/roken/getarg.c	Sat Mar 11 17:17:02 2000
+++ arla-0.33/lib/roken/getarg.c	Sun May 14 11:00:45 2000
@@ -386,8 +386,10 @@
 		} else if (strncmp (arg->long_name,
 				    p,
 				    p_len) == 0) {
-		    ++partial_match;
-		    partial = arg;
+		    if (!(style & ARG_USEFIRST) || !partial_match) {
+			++partial_match;
+			partial = arg;
+		    }
 		    if (style & ARG_TRANSLONG) {
 			if (ISFLAG(arg)) {
 			    optarg = "";
@@ -413,7 +415,7 @@
     }
     if (current == NULL) {
 	/* Match a generic argument preferentially over a partial match */
-	if (generic_arg)
+	if (generic_arg && (!partial_match || (style & ARG_USEFIRST)))
 	    current = generic_arg;
 	else if (partial_match == 1)
 	    current = partial;
diff -ur --unidirectional-new-file arla-0.33-dist/lib/roken/getarg.h arla-0.33/lib/roken/getarg.h
--- arla-0.33-dist/lib/roken/getarg.h	Sat Mar 11 17:17:02 2000
+++ arla-0.33/lib/roken/getarg.h	Sun May 14 10:57:15 2000
@@ -49,6 +49,7 @@
 #define ARG_TRANSLONG   0x4    /* Incompatible with {SHORT,LONG}ARG */
 #define ARG_SWITCHLESS  0x8    /* No switches */
 #define ARG_SUBOPTION   0xF    /* For manpage generation */
+#define ARG_USEFIRST	0x10   /* Use first partial found instead of failing */
 
 #define ARG_GNUSTYLE (ARG_LONGARG|ARG_SHORTARG)
 #define ARG_AFSSTYLE (ARG_TRANSLONG|ARG_SWITCHLESS)





More information about the Arla-drinkers mailing list