]> andersk Git - moira.git/blame - clients/lib/pobox.c
Support EXCHANGE poboxes.
[moira.git] / clients / lib / pobox.c
CommitLineData
013096e5 1/* $Id$
2 *
3 * Shared routines for pobox changing.
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>
d5a7ea17 13#include "mrclient-internal.h"
013096e5 14
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18
19#include <com_err.h>
20
21RCSID("$Header$");
22
013096e5 23static int save_sloc_machine(int argc, char **argv, void *sq);
24static int save_alias_value(int argc, char **argv, void *sq);
25
26extern char *whoami;
27
533bacb3 28#ifdef _WIN32
29#define strtok_r(s, tokens, resume) strtok(s, tokens)
30#endif /* _WIN32 */
31
013096e5 32int mrcl_validate_pobox_smtp(char *user, char *address, char **ret)
33{
34 char *addr, *retaddr, *p, *lasts = NULL;
35 char *machine = NULL, *m;
36 int oldlen, len, status = MRCL_SUCCESS;
37
38 /* Make a private copy of address that we can mangle. */
39 addr = strdup(address);
40
41 retaddr = strdup("");
42 len = 1;
43
44 /* For each comma-delimited address, canonicalize the hostname and
45 * verify that the address won't cause mail problems.
46 */
47 for (p = strtok_r(addr, ", ", &lasts); p; p = strtok_r(NULL, ",", &lasts))
48 {
49 m = strchr(p, '@');
50 if (m)
51 {
52 *m++ = '\0'; /* get rid of the @ sign */
53 m = strtrim(m); /* get rid of whitespace */
54 }
55 else
56 {
d5a7ea17 57 mrcl_set_message("No at sign (@) in address \"%s\".", p);
013096e5 58 status = MRCL_REJECT;
59 goto cleanup;
60 }
61
16ed72d4 62 if (strlen(m) > 0)
63 {
64 machine = canonicalize_hostname(strdup(m));
65 }
66 else
67 {
d5a7ea17 68 mrcl_set_message("No hostname in address \"%s@\".", p);
16ed72d4 69 status = MRCL_REJECT;
70 goto cleanup;
71 }
72
d5a7ea17 73 switch (mailtype(machine))
013096e5 74 {
d5a7ea17 75 case MAILTYPE_IMAP:
76 mrcl_set_message("Cannot forward mail to IMAP server %s.\n "
77 "Use \"chpobox -p\" if you are trying to unset "
78 "your mail forwarding.", machine);
798e9c7a 79 status = MRCL_REJECT;
80 goto cleanup;
81
d5a7ea17 82 case MAILTYPE_POP:
013096e5 83 if (strcmp(p, user))
84 {
d5a7ea17 85 mrcl_set_message("The name on the POP box (%s) must match "
86 "the username (%s).", p, user);
013096e5 87 status = MRCL_REJECT;
88 goto cleanup;
89 }
90 /* Fall through */
91
d5a7ea17 92 case MAILTYPE_LOCAL:
013096e5 93 if ((m = strchr(machine, '.')))
94 *m = '\0';
95 machine = realloc(machine, strlen(machine) + 6);
96 strcat(machine, ".LOCAL");
97 break;
98
d5a7ea17 99 case MAILTYPE_MAILHUB:
22bbb6f0 100 case MAILTYPE_EXCHANGE:
013096e5 101 if (!strcmp(p, user))
102 {
d5a7ea17 103 mrcl_set_message("The address \"%s@%s\" would create a mail "
104 "loop.\nSet a POP pobox if you want local "
105 "mail delivery.", p, machine);
013096e5 106 status = MRCL_REJECT;
107 goto cleanup;
108 }
109 else
110 {
d5a7ea17 111 mrcl_set_message("Cannot forward mail to a local mailing "
112 "address (%s@%s).", p, machine);
013096e5 113 status = MRCL_REJECT;
114 goto cleanup;
115 }
116
d5a7ea17 117 case MAILTYPE_SMTP:
013096e5 118 if (*m != '"' && strcasecmp(m, machine))
119 {
d5a7ea17 120 mrcl_set_message("Warning: hostname %s canonicalized to %s\n",
121 m, machine);
013096e5 122 }
123 break;
124
125 default:
126 status = MRCL_MOIRA_ERROR;
127 goto cleanup;
128 }
129
130 oldlen = len;
131 len += (oldlen > 1 ? 2 : 0) + strlen(p) + strlen(machine) + 1;
132 retaddr = realloc(retaddr, len);
133 sprintf(retaddr + oldlen - 1, "%s%s@%s", oldlen > 1 ? ", " : "",
134 p, machine);
135 free(machine);
136 machine = NULL; /* Make sure it doesn't get freed again later. */
137 }
138
139 cleanup:
140 free(addr);
141 if (status == MRCL_SUCCESS)
d0450663 142 *ret = retaddr;
013096e5 143 else
144 free(retaddr);
145 free(machine);
146
147 return status;
148}
149
013096e5 150static int save_sloc_machine(int argc, char **argv, void *sq)
151{
152 sq_save_data(sq, strdup(argv[1]));
153 return MR_CONT;
154}
155
156static int save_alias_value(int argc, char **argv, void *sq)
157{
158 sq_save_data(sq, strdup(argv[2]));
159 return MR_CONT;
160}
This page took 0.166629 seconds and 5 git commands to generate.