]>
Commit | Line | Data |
---|---|---|
48fbc492 | 1 | /* |
2 | * Copyright 1987 by the Massachusetts Institute of Technology. For copying | |
5eaef520 | 3 | * and distribution information, see the file "mit-copyright.h". |
48fbc492 | 4 | * |
5 | * $Source$ | |
6 | * $Header$ | |
7 | * $Author$ | |
48fbc492 | 8 | * |
9 | */ | |
10 | ||
11 | #ifndef lint | |
67655a21 | 12 | static char *rcsid_chpobox_c = "$Header$"; |
ca1102ea | 13 | #endif |
48fbc492 | 14 | |
15 | /* | |
59ec8dae | 16 | * Talk to the Moira database to change a person's home mail machine. This may |
48fbc492 | 17 | * be an Athena machine, or a completely arbitrary address. |
5eaef520 | 18 | * |
8c5c4d26 | 19 | * chpobox with no modifiers reports the current mailbox. |
5eaef520 | 20 | * |
8c5c4d26 | 21 | * chpobox -s [address] means set the mailbox to this address. |
48fbc492 | 22 | * |
8c5c4d26 | 23 | * chpobox -p restores the pobox to a previous POP box, if there was one. |
48fbc492 | 24 | * |
67655a21 | 25 | * chpobox -u [user] is needed if you are logged in as one user, but |
48fbc492 | 26 | * are trying to change the email address of another. You must have |
27 | * Kerberos tickets as the person whose address you are trying to | |
28 | * change, or the attempt will fail. | |
48fbc492 | 29 | */ |
30 | ||
31 | #include <sys/types.h> | |
32 | #include <stdio.h> | |
33 | #include <pwd.h> | |
f071d8a7 | 34 | #include <string.h> |
48fbc492 | 35 | #include <ctype.h> |
48fbc492 | 36 | #include <errno.h> |
37 | ||
59ec8dae | 38 | /* Moira includes */ |
8defc06b | 39 | #include <moira.h> |
40 | #include <moira_site.h> | |
67655a21 | 41 | #include "mit-copyright.h" |
48fbc492 | 42 | |
43 | char *getlogin(); | |
44 | char *malloc(); | |
48fbc492 | 45 | char *whoami; |
8c5c4d26 | 46 | uid_t getuid(); |
48fbc492 | 47 | |
48 | int getopt(); | |
48fbc492 | 49 | |
48fbc492 | 50 | static int match; |
51 | ||
48fbc492 | 52 | |
5eaef520 | 53 | int main(int argc, char *argv[]) |
48fbc492 | 54 | { |
5eaef520 | 55 | struct passwd *pwd; |
56 | char *mrarg[3], buf[BUFSIZ]; | |
57 | char *potype(); | |
58 | char *address, *uname, *machine, *motd; | |
59 | uid_t u; | |
60 | char *canonicalize_hostname(); | |
61 | int get_pobox(), scream(); | |
62 | int c, setflag, prevpop, usageflag, status; | |
63 | ||
64 | extern int optind; | |
65 | extern char *optarg; | |
66 | ||
67 | c = setflag = prevpop = usageflag = 0; | |
68 | address = uname = (char *) NULL; | |
69 | u = getuid(); | |
70 | ||
71 | if ((whoami = strrchr(argv[0], '/')) == NULL) | |
72 | whoami = argv[0]; | |
73 | else | |
74 | whoami++; | |
75 | ||
76 | if (argc > 5) | |
77 | usage(); | |
78 | ||
79 | while ((c = getopt(argc, argv, "s:pu:")) != -1) | |
80 | switch (c) | |
81 | { | |
82 | case 's': | |
83 | if (prevpop) | |
84 | usageflag++; | |
85 | else | |
86 | { | |
87 | setflag++; | |
88 | strcpy(buf, optarg); | |
89 | address = buf; | |
90 | } | |
91 | break; | |
92 | case 'p': | |
93 | if (setflag) | |
94 | usageflag++; | |
95 | else | |
96 | prevpop++; | |
97 | break; | |
98 | case 'u': | |
99 | uname = strsave(optarg); | |
100 | break; | |
101 | default: | |
102 | usageflag++; | |
103 | break; | |
104 | } | |
105 | if (argc == 2 && optind == 1 && !uname) | |
106 | uname = argv[optind++]; | |
107 | ||
108 | if (usageflag || optind != argc) | |
109 | usage(); | |
110 | ||
111 | if (!uname) | |
112 | { | |
113 | if (!(uname = getlogin())) | |
48fbc492 | 114 | usage(); |
48fbc492 | 115 | |
5eaef520 | 116 | if (uname[0] == '\0') |
117 | { | |
118 | pwd = getpwuid(u); | |
119 | strcpy(uname, pwd->pw_name); | |
48fbc492 | 120 | } |
121 | } | |
5eaef520 | 122 | mrarg[0] = uname; |
48fbc492 | 123 | |
5eaef520 | 124 | status = mr_connect(NULL); |
125 | if (status) | |
126 | { | |
127 | com_err(whoami, status, " while connecting to Moira"); | |
128 | exit(1); | |
48fbc492 | 129 | } |
130 | ||
5eaef520 | 131 | status = mr_motd(&motd); |
132 | if (status) | |
133 | { | |
134 | mr_disconnect(); | |
135 | com_err(whoami, status, " unable to check server status"); | |
136 | exit(1); | |
262ca740 | 137 | } |
5eaef520 | 138 | if (motd) |
139 | { | |
140 | fprintf(stderr, "The Moira server is currently unavailable:\n%s\n", | |
141 | motd); | |
142 | mr_disconnect(); | |
143 | exit(1); | |
262ca740 | 144 | } |
145 | ||
5eaef520 | 146 | status = mr_auth("chpobox"); |
147 | if (status) | |
148 | { | |
149 | com_err(whoami, status, " while authenticating -- " | |
150 | "run \"kinit\" and try again."); | |
151 | mr_disconnect(); | |
152 | exit(1); | |
ccd5efe6 | 153 | } |
154 | ||
5eaef520 | 155 | if (setflag) |
156 | { | |
157 | /* Address is of form user@host. Split it up. */ | |
158 | if (!address) | |
159 | { | |
160 | fprintf(stderr, "%s: no address was specified.\n", whoami); | |
161 | goto show; | |
8c5c4d26 | 162 | } |
5eaef520 | 163 | machine = strchr(address, '@'); |
164 | if (machine) | |
165 | { | |
166 | *machine++ = '\0'; /* get rid of the @ sign */ | |
167 | machine = strtrim(machine); /* get rid of whitespace */ | |
48fbc492 | 168 | } |
5eaef520 | 169 | else |
170 | { | |
171 | fprintf(stderr, "%s: no at sign (@) in address \"%s\"\n", | |
172 | whoami, address); | |
173 | goto show; | |
174 | } | |
175 | mrarg[2] = canonicalize_hostname(strsave(machine)); | |
176 | mrarg[1] = potype(mrarg[2]); | |
177 | if (!strcmp(mrarg[1], "POP")) | |
178 | { | |
179 | if (strcmp(address, uname)) | |
180 | { | |
181 | fprintf(stderr, | |
182 | "%s: the name on the POP box must match the username\n", | |
183 | whoami); | |
184 | goto show; | |
ccd5efe6 | 185 | } |
5eaef520 | 186 | } |
187 | else if (!strcmp(mrarg[1], "LOCAL")) | |
188 | { | |
189 | strcat(address, "@"); | |
190 | strcat(address, mrarg[2]); | |
191 | mrarg[2] = address; | |
192 | if ((address = strchr(address, '@')) && | |
193 | (address = strchr(address, '.'))) | |
194 | *address = 0; | |
195 | strcat(mrarg[2], ".LOCAL"); | |
196 | mrarg[1] = "SMTP"; | |
197 | } | |
198 | else if (!strcmp(mrarg[1], "MAILHUB")) | |
199 | { | |
200 | if (!strcmp(address, uname)) | |
201 | { | |
202 | fprintf(stderr, | |
203 | "Error: this will set a mail forwarding loop.\n"); | |
204 | fprintf(stderr, | |
205 | "Use \"%s -p\" to set a local post office server.\n", | |
206 | whoami); | |
207 | exit(1); | |
108a5f18 | 208 | } |
5eaef520 | 209 | fprintf(stderr, "Error: \"%s@%s\" is a local mail address.\n", |
210 | address, machine); | |
211 | fprintf(stderr, "Your mail drop must be on a post office server " | |
212 | "or an external mail address.\n"); | |
213 | exit(1); | |
214 | } | |
215 | else if (mrarg[1]) | |
216 | { | |
217 | if (*machine != '"' && strcasecmp(mrarg[2], machine)) | |
218 | { | |
108a5f18 | 219 | fprintf(stderr, "Warning: hostname %s canonicalized to %s\n", |
220 | machine, mrarg[2]); | |
5eaef520 | 221 | } |
222 | strcat(address, "@"); | |
223 | strcat(address, mrarg[2]); | |
224 | mrarg[2] = address; | |
8c5c4d26 | 225 | } else |
226 | goto show; | |
5eaef520 | 227 | status = mr_query("set_pobox", 3, mrarg, scream, NULL); |
228 | if (status) | |
229 | com_err(whoami, status, | |
230 | " while setting pobox for %s to type %s, box %s", | |
231 | mrarg[0], mrarg[1], mrarg[2]); | |
232 | } | |
233 | else if (prevpop) | |
234 | { | |
235 | status = mr_query("set_pobox_pop", 1, mrarg, scream, NULL); | |
236 | if (status == MR_MACHINE) | |
237 | { | |
238 | fprintf(stderr, | |
239 | "Moira has no record of a previous POP box for %s\n", uname); | |
240 | } | |
241 | else if (status != 0) | |
242 | com_err(whoami, status, " while setting pobox"); | |
48fbc492 | 243 | } |
ccd5efe6 | 244 | |
5eaef520 | 245 | /* |
246 | * get current box | |
247 | */ | |
8c5c4d26 | 248 | show: |
5eaef520 | 249 | status = mr_query("get_pobox", 1, mrarg, get_pobox, NULL); |
250 | if (status == MR_NO_MATCH) | |
251 | printf("User %s has no pobox.\n", uname); | |
252 | else if (status != 0) | |
253 | com_err(whoami, status, " while retrieving current mailbox"); | |
254 | mr_disconnect(); | |
255 | exit(0); | |
48fbc492 | 256 | } |
257 | ||
8c5c4d26 | 258 | |
5eaef520 | 259 | int scream(void) |
48fbc492 | 260 | { |
5eaef520 | 261 | com_err(whoami, 0, "Unexpected return value from Moira -- programmer botch"); |
262 | mr_disconnect(); | |
263 | exit(1); | |
48fbc492 | 264 | } |
265 | ||
266 | /* | |
dbe34e72 | 267 | * get_pobox gets all your poboxes and displays them. |
48fbc492 | 268 | */ |
269 | ||
5eaef520 | 270 | int get_pobox(int argc, char **argv, char *callarg) |
48fbc492 | 271 | { |
5eaef520 | 272 | if (!strcmp(argv[1], "POP")) |
273 | printf("User %s, Type %s, Box: %s@%s\n", | |
274 | argv[0], argv[1], argv[0], argv[2]); | |
275 | else | |
276 | printf("User %s, Type %s, Box: %s\n", | |
277 | argv[0], argv[1], argv[2]); | |
278 | printf(" Modified by %s on %s with %s\n", argv[4], argv[3], argv[5]); | |
279 | return 0; | |
48fbc492 | 280 | } |
281 | ||
48fbc492 | 282 | /* |
59ec8dae | 283 | * given a canonicalized machine name, ask the Moira server if it is of type |
5eaef520 | 284 | * pop, or of type local -- if neither, we assume that it's of type foreign. |
48fbc492 | 285 | */ |
5eaef520 | 286 | char *potype(char *machine) |
48fbc492 | 287 | { |
5eaef520 | 288 | char *service[1], *argv[3]; |
289 | int check_match(), check_match3(), status; | |
290 | ||
291 | match = 0; | |
292 | service[0] = "POP"; | |
293 | status = mr_query("get_server_locations", 1, service, check_match, machine); | |
294 | if (status && (status != MR_NO_MATCH)) | |
295 | { | |
296 | com_err(whoami, status, " while reading list of POP servers"); | |
297 | return NULL; | |
48fbc492 | 298 | } |
5eaef520 | 299 | if (match) |
300 | return "POP"; | |
301 | ||
302 | service[0] = "LOCAL"; | |
303 | status = mr_query("get_server_locations", 1, service, check_match, machine); | |
304 | if (status && (status != MR_NO_MATCH)) | |
305 | { | |
306 | com_err(whoami, status, " while reading list of LOCAL servers"); | |
307 | return NULL; | |
48fbc492 | 308 | } |
5eaef520 | 309 | if (match) |
310 | return "LOCAL"; | |
311 | ||
312 | argv[0] = "mailhub"; | |
313 | argv[1] = "TYPE"; | |
314 | argv[2] = "*"; | |
315 | status = mr_query("get_alias", 3, argv, check_match3, machine); | |
316 | if (status && (status != MR_NO_MATCH)) | |
317 | { | |
318 | com_err(whoami, status, " while reading list of MAILHUB servers"); | |
319 | return NULL; | |
108a5f18 | 320 | } |
5eaef520 | 321 | if (match) |
322 | return "MAILHUB"; | |
323 | else | |
324 | return "SMTP"; | |
48fbc492 | 325 | } |
326 | ||
5eaef520 | 327 | int check_match(int argc, char **argv, char *callback) |
48fbc492 | 328 | { |
5eaef520 | 329 | if (match) |
330 | return 0; | |
48fbc492 | 331 | |
5eaef520 | 332 | if (!strcasecmp(argv[1], callback)) |
333 | match = 1; | |
48fbc492 | 334 | |
5eaef520 | 335 | return 0; |
48fbc492 | 336 | } |
337 | ||
5eaef520 | 338 | int check_match3(int argc, char **argv, char *callback) |
108a5f18 | 339 | { |
5eaef520 | 340 | if (match) |
341 | return 0; | |
108a5f18 | 342 | |
5eaef520 | 343 | if (!strcasecmp(argv[2], callback)) |
344 | match = 1; | |
108a5f18 | 345 | |
5eaef520 | 346 | return 0; |
108a5f18 | 347 | } |
348 | ||
5eaef520 | 349 | int usage(void) |
48fbc492 | 350 | { |
5eaef520 | 351 | fprintf(stderr, "Usage: %s [-s address] [-p] [-u user]\n", whoami); |
352 | exit(1); | |
48fbc492 | 353 | } |