source: trunk/third/moira/clients/lib/member.c @ 24319

Revision 24319, 3.1 KB checked in by broder, 15 years ago (diff)
New Moira snapshot from SVN.
Line 
1/* $Id: member.c 3956 2010-01-05 20:56:56Z zacheiss $
2 *
3 * Shared routines for playing with list membership.
4 *
5 * Copyright (C) 1999 by the Massachusetts Institute of Technology
6 * For copying and distribution information, please see the file
7 * <mit-copyright.h>.
8 */
9
10#include <mit-copyright.h>
11#include <moira.h>
12#include <mrclient.h>
13#include "mrclient-internal.h"
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include <ctype.h>
19
20#include <krb5.h>
21
22RCSID("$HeadURL: svn+ssh://svn.mit.edu/moira/trunk/moira/clients/lib/member.c $ $Id: member.c 3956 2010-01-05 20:56:56Z zacheiss $");
23
24int mrcl_validate_string_member(char *str)
25{
26  char *p, *lname, *ret;
27
28  for (ret = str; *ret; ret++)
29    {
30      if (iscntrl(*ret))
31        {
32          mrcl_set_message("STRING \"%s\" contains control characters, "
33                           "which are not allowed.", str);
34          return MRCL_REJECT;
35        }
36    }
37
38  p = strchr(str, '@');
39  if (p)
40    {
41      char *host = canonicalize_hostname(strdup(++p));
42
43      if (mailtype(host) != MAILTYPE_SMTP)
44        {
45          free(host);
46          lname = strdup(str);
47          *strchr(str, '@') = '\0';
48          mrcl_set_message("STRING \"%s\" should be USER or LIST \"%s\" "
49                           "because it is a local name.", lname, str);
50          free(lname);
51          return MRCL_REJECT;
52        }
53      free(host);
54    }
55  else if (!strpbrk(str, "%!"))
56    {
57      mrcl_set_message("STRING \"%s\" is not a foreign mail address.\nAdding "
58                       "it to a mailing list may cause the list to break.",
59                       str);
60      return MRCL_WARN;
61    }
62
63  mrcl_clear_message();
64  return MRCL_SUCCESS;
65}
66
67int mrcl_validate_kerberos_member(char *str, char **ret)
68{
69  char *p;
70  int code = 0;
71  krb5_context context = NULL;
72  char *default_realm = NULL;
73
74  mrcl_clear_message();
75
76  for (p = str; *p; p++)
77    {
78      if (isspace(*p) || *p == ',')
79        {
80          mrcl_set_message("KERBEROS member \"%s\" may not contain whitespace "
81                           "or commas.", str);
82          return MRCL_REJECT;
83        }
84    }
85
86  p = strchr(str, '@');
87  if (!p)
88    {
89      /* An IP address is not a Kerberos principal, but we allow it
90       * for AFS purposes.
91       */
92      if (strtoul(str, &p, 10) < 256 && (*p == '.') &&
93          strtoul(p + 1, &p, 10) < 256 && (*p == '.') &&
94          strtoul(p + 1, &p, 10) < 256 && (*p == '.') &&
95          strtoul(p + 1, &p, 10) < 256 && !*p)
96        {
97          *ret = strdup(str);
98          return MRCL_SUCCESS;
99        }
100
101      code = krb5_init_context(&context);
102      if (code)
103        goto out;
104
105      code = krb5_get_default_realm(context, &default_realm);
106      if (code)
107        goto out;
108
109      *ret = malloc(strlen(str) + strlen(default_realm) + 2);
110      sprintf(*ret, "%s@%s", str, default_realm);
111
112      mrcl_set_message("Warning: default realm \"%s\" added to principal "
113                       "\"%s\"", default_realm, str);
114
115    out:
116      if (default_realm)
117        free(default_realm);
118      if (context)
119        krb5_free_context(context);
120      if (!code)
121        return code;
122      return MRCL_SUCCESS;
123    }
124
125  /* Check capitalization. */
126  *ret = strdup(str);
127  p = strchr(*ret, '@');
128  while (*++p)
129    {
130      if (islower(*p))
131        {
132          *p = toupper(*p);
133          mrcl_set_message("Warning: set realm in \"%s\" to all caps.", *ret);
134        }
135    }
136
137  return MRCL_SUCCESS;
138}
Note: See TracBrowser for help on using the repository browser.