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