]> andersk Git - moira.git/blame - clients/passwd/chpobox.c
Change `SMS' to `Moira' where possible.
[moira.git] / clients / passwd / chpobox.c
CommitLineData
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 12static 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
43char *getlogin();
44char *malloc();
48fbc492 45char *whoami;
8c5c4d26 46uid_t getuid();
48fbc492 47
48int getopt();
48fbc492 49
48fbc492 50static int match;
51
48fbc492 52
5eaef520 53int 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 248show:
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 259int 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 270int 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 286char *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 327int 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 338int 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 349int usage(void)
48fbc492 350{
5eaef520 351 fprintf(stderr, "Usage: %s [-s address] [-p] [-u user]\n", whoami);
352 exit(1);
48fbc492 353}
This page took 0.178953 seconds and 5 git commands to generate.