[1619] in Moira

home help back first fref pref prev next nref lref last post

better checking of KERBEROS and STRING entries

daemon@ATHENA.MIT.EDU (Garry Zacheiss)
Sun Aug 6 05:08:36 2000

Message-Id: <200008060908.FAA06122@alice-whacker.mit.edu>
To: moiradev@MIT.EDU
Date: Sun, 06 Aug 2000 05:08:33 -0400
From: Garry Zacheiss <zacheiss@MIT.EDU>

	This patch implements several changes in libmrclient.  It adds
support for canonicalizing Kerberos principals on moira lists, i.e,
adding KERBEROS:zacheiss will print a warning and canonicalize to
KERBEROS:zacheiss@<default realm of client>, adding
KERBEROS:zacheiss@athena.mit.edu will print a warning and capitalize it
to KERBEROS:zacheiss@ATHENA.MIT.EDU.  We also do better checking on type
STRING entries to prevent people from adding entries like
STRING:zacheiss@po8.mit.edu.

	This is part 1 of 3.  The changes to blanche and moira to use
the new library functions follow in parts 2 and 3.

Garry

Index: Makefile.in
===================================================================
RCS file: /afs/athena.mit.edu/astaff/project/moiradev/repository/moira/clients/lib/Makefile.in,v
retrieving revision 1.2
diff -c -r1.2 Makefile.in
*** Makefile.in	1999/07/12 16:20:43	1.2
--- Makefile.in	2000/08/06 06:03:13
***************
*** 14,20 ****
  SRCTOP=@top_srcdir@
  BUILDTOP=../..
  
! OBJS=pobox.o utils.o
  
  .c.o:
  	$(CC) -c $(ALL_CFLAGS) $<
--- 14,20 ----
  SRCTOP=@top_srcdir@
  BUILDTOP=../..
  
! OBJS=error.o mail.o member.o pobox.o utils.o
  
  .c.o:
  	$(CC) -c $(ALL_CFLAGS) $<
Index: error.c
===================================================================
RCS file: error.c
diff -N error.c
*** /dev/null	Tue May  5 16:32:27 1998
--- error.c	Sun Aug  6 02:02:39 2000
***************
*** 0 ****
--- 1,72 ----
+ /* $Id: utils.c,v 1.1 1999/05/13 18:52:29 danw Exp $
+  *
+  * mrcl error interface
+  *
+  * Copyright (C) 1999 by the Massachusetts Institute of Technology
+  * For copying and distribution information, please see the file
+  * <mit-copyright.h>.
+  */
+ 
+ #include <mit-copyright.h>
+ #include <moira.h>
+ #include <mrclient.h>
+ #include "mrclient-internal.h"
+ 
+ #include <stdarg.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+ 
+ #include <com_err.h>
+ 
+ RCSID("$Header: /afs/athena.mit.edu/astaff/project/moiradev/repository/moira/clients/lib/utils.c,v 1.1 1999/05/13 18:52:29 danw Exp $");
+ 
+ static char *mrcl_message = NULL;
+ 
+ void mrcl_set_message(char *fmt, ...)
+ {
+   int args, len;
+   char *p;
+   va_list ap;
+ 
+   free(mrcl_message);
+ 
+   /* Count "%s"s */
+   for (args = 0, p = strstr(fmt, "%s"); p; p = strstr(p + 2, "%s"))
+     args++;
+ 
+   /* Measure the output string. */
+   len = strlen(fmt) + 1;
+   va_start(ap, fmt);
+   while (args--)
+     {
+       p = va_arg(ap, char *);
+       len += strlen(p);
+     }
+   va_end(ap);
+ 
+   /* Malloc and print */
+   mrcl_message = malloc(len);
+   if (mrcl_message)
+     {
+       va_start(ap, fmt);
+       vsprintf(mrcl_message, fmt, ap);
+       va_end(ap);
+     }
+ }
+ 
+ char *mrcl_get_message(void)
+ {
+   return mrcl_message;
+ }
+ 
+ void mrcl_clear_message(void)
+ {
+   free(mrcl_message);
+   mrcl_message = NULL;
+ }
+ 
+ void mrcl_com_err(char *whoami)
+ {
+   if (mrcl_message)
+     com_err(whoami, 0, "%s", mrcl_message);
+ }
Index: mail.c
===================================================================
RCS file: mail.c
diff -N mail.c
*** /dev/null	Tue May  5 16:32:27 1998
--- mail.c	Sun Aug  6 02:02:42 2000
***************
*** 0 ****
--- 1,166 ----
+ /* $Id: pobox.c,v 1.1 1999/05/13 18:52:28 danw Exp $
+  *
+  * Library-internal routines for categorizing machines in terms
+  * of email.
+  *
+  * Copyright (C) 1999 by the Massachusetts Institute of Technology
+  * For copying and distribution information, please see the file
+  * <mit-copyright.h>.
+  */
+ 
+ #include <mit-copyright.h>
+ #include <moira.h>
+ #include <mrclient.h>
+ #include "mrclient-internal.h"
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ 
+ RCSID("$Header: /afs/athena.mit.edu/astaff/project/moiradev/repository/moira/clients/lib/pobox.c,v 1.1 1999/05/13 18:52:28 danw Exp $");
+ 
+ static int save_sloc_machine(int argc, char **argv, void *sq);
+ static int save_alias_value(int argc, char **argv, void *sq);
+ 
+ /* Given a canonicalized machine name, ask the Moira server if it is of type
+  * POP, LOCAL, or MAILHUB -- if none of those, we assume it's FOREIGN.
+  */
+ int mailtype(char *machine)
+ {
+   char *name;
+   int status, match = 0;
+   static struct save_queue *pop = NULL, *local = NULL;
+   static struct save_queue *mailhub = NULL, *mailhub_name = NULL;
+ 
+   mrcl_clear_message();
+ 
+   /* 1. Check if the machine is a POP server. */
+   if (!pop)
+     {
+       char *service = "POP";
+       pop = sq_create();
+       status = mr_query("get_server_locations", 1, &service,
+ 			save_sloc_machine, pop);
+       if (!status || status == MR_NO_MATCH)
+ 	{
+ 	  service = "POSTOFFICE";
+ 	  status = mr_query("get_server_locations", 1, &service,
+ 			    save_sloc_machine, pop);
+ 	}
+ 
+       if (status && (status != MR_NO_MATCH))
+ 	{
+ 	  mrcl_set_message("Could not read list of POP servers: %s",
+ 			   error_message(status));
+ 	  return MAILTYPE_ERROR;
+ 	}
+     }
+ 
+   /* Because of how sq_get_data works, we need to go through the entire
+    * queue even if we find a match, so that it gets reset for the next
+    * call.
+    */
+   while (sq_get_data(pop, &name))
+     {
+       if (!match && !strcasecmp(name, machine))
+ 	match = 1;
+     }
+   if (match)
+     return MAILTYPE_POP;
+ 
+ 
+   /* 2. Check if the machine is "LOCAL". */
+   if (!local)
+     {
+       char *service = "LOCAL";
+       local = sq_create();
+       status = mr_query("get_server_locations", 1, &service,
+ 			save_sloc_machine, local);
+       if (status && (status != MR_NO_MATCH))
+ 	{
+ 	  mrcl_set_message("Could not read list of LOCAL servers: %s",
+ 			   error_message(status));
+ 	  return MAILTYPE_ERROR;
+ 	}
+     }
+ 
+   while (sq_get_data(local, &name))
+     {
+       if (!match && !strcasecmp(name, machine))
+ 	match = 1;
+     }
+   if (match)
+     return MAILTYPE_LOCAL;
+ 
+   
+   /* 3. Check if the machine is one of the mailhubs. */
+   if (!mailhub)
+     {
+       char *service = "MAILHUB";
+       mailhub = sq_create();
+       status = mr_query("get_server_locations", 1, &service,
+ 			save_sloc_machine, mailhub);
+       if (!status || status == MR_NO_MATCH)
+ 	{
+ 	  service = "NMAILHUB";
+ 	  status = mr_query("get_server_locations", 1, &service,
+ 			    save_sloc_machine, mailhub);
+ 	}
+ 
+       if (status && (status != MR_NO_MATCH))
+ 	{
+ 	  mrcl_set_message("Could not read list of MAILHUB servers: %s",
+ 			   error_message(status));
+ 	  return MAILTYPE_ERROR;
+ 	}
+ 
+     }
+ 
+   while (sq_get_data(mailhub, &name))
+     {
+       if (!match && !strcasecmp(name, machine))
+ 	match = 1;
+     }
+   if (match)
+     return MAILTYPE_MAILHUB;
+ 
+ 
+   /* 4. Check if the machine is one of the external names of the mailhubs. */
+   if (!mailhub_name)
+     {
+       char *argv[3];
+       mailhub_name = sq_create();
+       argv[0] = "mailhub";
+       argv[1] = "TYPE";
+       argv[2] = "*";
+       status = mr_query("get_alias", 3, argv, save_alias_value, mailhub_name);
+       if (status && (status != MR_NO_MATCH))
+ 	{
+ 	  mrcl_set_message("Could not read list of mailhub names: %s",
+ 			   error_message(status));
+ 	  return MAILTYPE_ERROR;
+ 	}
+     }
+ 
+   while (sq_get_data(mailhub_name, &name))
+     {
+       if (!match && !strcasecmp(name, machine))
+ 	match = 1;
+     }
+   if (match)
+     return MAILTYPE_MAILHUB;
+ 
+   return MAILTYPE_SMTP;
+ }
+ 
+ static int save_sloc_machine(int argc, char **argv, void *sq)
+ {
+   sq_save_data(sq, strdup(argv[1]));
+   return MR_CONT;
+ }
+ 
+ static int save_alias_value(int argc, char **argv, void *sq)
+ {
+   sq_save_data(sq, canonicalize_hostname(strdup(argv[2])));
+   return MR_CONT;
+ }
Index: member.c
===================================================================
RCS file: member.c
diff -N member.c
*** /dev/null	Tue May  5 16:32:27 1998
--- member.c	Sun Aug  6 02:29:10 2000
***************
*** 0 ****
--- 1,103 ----
+ /* $Id: pobox.c,v 1.1 1999/05/13 18:52:28 danw Exp $
+  *
+  * Shared routines for playing with list membership.
+  *
+  * Copyright (C) 1999 by the Massachusetts Institute of Technology
+  * For copying and distribution information, please see the file
+  * <mit-copyright.h>.
+  */
+ 
+ #include <mit-copyright.h>
+ #include <moira.h>
+ #include <mrclient.h>
+ #include "mrclient-internal.h"
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ 
+ #include <krb.h>
+ 
+ RCSID("$Header: /afs/athena.mit.edu/astaff/project/moiradev/repository/moira/clients/lib/pobox.c,v 1.1 1999/05/13 18:52:28 danw Exp $");
+ 
+ static char default_realm[REALM_SZ];
+ 
+ int mrcl_validate_string_member(char *str)
+ {
+   char *p, *lname;
+ 
+   p = strchr(str, '@');
+   if (p)
+     {
+       char *host = canonicalize_hostname(strdup(++p));
+ 
+       if (mailtype(host) != MAILTYPE_SMTP)
+ 	{
+ 	  free(host);
+ 	  lname = strdup(str);
+ 	  *strchr(str, '@') = '\0';
+ 	  mrcl_set_message("STRING \"%s\" should be USER or LIST \"%s\" "
+ 			   "because it is a local name.", lname, str);
+ 	  free(lname);
+ 	  return MRCL_REJECT;
+ 	}
+       free(host);
+     }
+   else if (!strpbrk(str, "%!"))
+     {
+       mrcl_set_message("STRING \"%s\" is not a foreign mail address.\nAdding "
+ 		       "it to a mailing list may cause the list to break.",
+ 		       lname);
+       return MRCL_REJECT;
+     }
+ 
+   mrcl_clear_message();
+   return MRCL_SUCCESS;
+ }
+ 
+ int mrcl_validate_kerberos_member(char *str, char **ret)
+ {
+   char *p;
+ 
+   mrcl_clear_message();
+ 
+   p = strchr(str, '@');
+   if (!p)
+     {
+       /* An IP address is not a Kerberos principal, but we allow it
+        * for AFS purposes.
+        */
+       if (strtoul(str, &p, 10) < 256 && (*p == '.') &&
+ 	  strtoul(p + 1, &p, 10) < 256 && (*p == '.') &&
+ 	  strtoul(p + 1, &p, 10) < 256 && (*p == '.') &&
+ 	  strtoul(p + 1, &p, 10) < 256 && !*p)
+ 	{
+ 	  *ret = strdup(str);
+ 	  return MRCL_SUCCESS;
+ 	}
+ 
+       if (!*default_realm)
+ 	krb_get_lrealm(default_realm, 1);
+ 
+       *ret = malloc(strlen(str) + strlen(default_realm) + 2);
+       sprintf(*ret, "%s@%s", str, default_realm);
+ 
+       mrcl_set_message("Warning: default realm \"%s\" added to principal "
+ 		       "\"%s\"", default_realm, str);
+       return MRCL_SUCCESS;
+     }
+ 
+   /* Check capitalization. */
+   *ret = strdup(str);
+   p = strchr(*ret, '@');
+   while (*++p)
+     {
+       if (islower(*p))
+ 	{
+ 	  *p = toupper(*p);
+ 	  mrcl_set_message("Warning: set realm in \"%s\" to all caps.", *ret);
+ 	}
+     }
+ 
+   return MRCL_SUCCESS;
+ }
Index: mrclient-internal.h
===================================================================
RCS file: mrclient-internal.h
diff -N mrclient-internal.h
*** /dev/null	Tue May  5 16:32:27 1998
--- mrclient-internal.h	Sun Aug  6 02:02:52 2000
***************
*** 0 ****
--- 1,17 ----
+ /* $Id: mrclient.h,v 1.1 1999/05/25 21:19:59 danw Exp $
+  *
+  * Copyright (C) 1999 by the Massachusetts Institute of Technology
+  *
+  */
+ 
+ #ifndef _mrclient_internal_h_
+ #define _mrclient_internal_h_
+ 
+ void mrcl_set_message(char *, ...);
+ void mrcl_clear_message(void);
+ 
+ enum { MAILTYPE_ERROR, MAILTYPE_POP, MAILTYPE_LOCAL,
+        MAILTYPE_MAILHUB, MAILTYPE_SMTP };
+ int mailtype(char *machine);
+ 
+ #endif /* _mrclient_internal_h_ */

home help back first fref pref prev next nref lref last post