[1619] in Moira
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_ */