]> andersk Git - moira.git/blame - clients/passwd/chpobox.c
changes made by poto. Looks like cleanup
[moira.git] / clients / passwd / chpobox.c
CommitLineData
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$
8 * $Log$
67655a21 9 * Revision 1.2 1987-08-02 19:51:53 ambar
10 * changed from chhome to chpobox; added
11 * #include "mit-copyright.h"
48fbc492 12 *
67655a21 13 * Revision 1.1 87/08/02 19:47:52 ambar
14 * Initial revision
48fbc492 15 *
16 */
17
18#ifndef lint
67655a21 19static char *rcsid_chpobox_c = "$Header$";
48fbc492 20#endif not lint
21
22/*
23 * Talk to the SMS database to change a person's home mail machine. This may
24 * be an Athena machine, or a completely arbitrary address.
25 *
67655a21 26 * chpobox with no modifiers reports all current mailboxes.
48fbc492 27 *
67655a21 28 * chpobox -a [address] means add (not replace) a mailbox to the ones
48fbc492 29 * the user already has. Complains if the user tries to give herself
30 * more than one mailbox of type pop.
31 *
67655a21 32 * chpobox -d [address] means delete the specified mailbox from the list.
48fbc492 33 * Complains if this would mean leaving the user with no mailbox at all.
34 *
67655a21 35 * chpobox -u [user] is needed if you are logged in as one user, but
48fbc492 36 * are trying to change the email address of another. You must have
37 * Kerberos tickets as the person whose address you are trying to
38 * change, or the attempt will fail.
39 *
40 * [address] must always have an @ sign in it.
41 *
42 */
43
44#include <sys/types.h>
45#include <stdio.h>
46#include <pwd.h>
47#include <strings.h>
48#include <ctype.h>
49#include <netdb.h>
50#include <errno.h>
51
52/* SMS includes */
53#include <sms.h>
54#include <sms_app.h>
67655a21 55#include "mit-copyright.h"
48fbc492 56
57char *getlogin();
58char *malloc();
59char *strcpy();
60char *strcat();
61char *whoami;
62
63int getopt();
64int status;
65
66extern int h_errno;
67static int match;
68
69uid_t getuid();
70
71#define DOMAIN ".MIT.EDU"
72#define NET_ADDRESS_SIZE 500 /* You would not believe the length of some
73 * addresses.. */
74main(argc, argv)
75 char *argv[];
76
77{
78 struct passwd *pwd;
79 struct pobox_values getnewmach(), pobox;
80 char *smsarg[1], buf[BUFSIZ];
81 char *ds(), *trim(), *in(), *canon();
82 char *address, *uname, *machine;
83 char **return_args, **crunch_pobox_args();
84 uid_t u;
85 int get_machine(), scream();
86 int c, delflag, add, usageflag;
87
88 extern int optind;
89 extern char *optarg;
90
91 init_sms_err_tbl();
92 init_krb_err_tbl();
93 c = delflag = add = usageflag = 0;
94 address = uname = (char *) NULL;
95 u = getuid();
96
97 if ((whoami = rindex(argv[0], '/')) == NULL)
98 whoami = argv[0];
99 else
100 whoami++;
101
102 if (argc > 5) {
103 usage();
104 }
105
106 while ((c = getopt(argc, argv, "d:a:u:")) != EOF)
107 switch (c) {
108
109 case 'd':
110 if (add)
111 usageflag++;
112 else {
113 delflag++;
114 address = ds(optarg);
115 }
116 break;
117 case 'a':
118 if (delflag)
119 usageflag++;
120 else {
121 add++;
122 address = ds(optarg);
123 }
124 break;
125 case 'u':
126 uname = ds(optarg);
127 break;
128 default:
129 usageflag++;
130 break;
131 }
132 if (argc == 2 && optind == 1 && !uname) {
133 uname = argv[optind++];
134 }
135 if (usageflag || optind != argc) {
136 usage();
137 }
138 if (!uname) {
139 if ((uname = getlogin()) == NULL) {
140 usage();
141 }
142 if (uname[0] == '\0') {
143 pwd = getpwuid((int) u);
144 (void) strcpy(uname, pwd->pw_name);
145 }
146 }
147 smsarg[0] = uname;
148
149 status = sms_connect();
150 if (status) {
151 (void) sprintf(buf, "\nConnection to SMS server failed.");
152 goto punt;
153 }
154
155 status = sms_auth();
156 if (status) {
157 (void) sprintf(buf, "\nAuthorization failed -- please \
158run \"kinit\" and try again.");
159 goto punt;
160 }
161
162 /*
163 * set up some bogus arguments to feed to sms_access
164 */
165 pobox.login = uname;
166 pobox.type = "foreign";
167 pobox.box = "foo";
168 pobox.machine = "baz.bat.quux";
169 return_args = crunch_pobox_args(pobox);
170 /*
171 * do an access check.
172 */
173 status = sms_access("add_pobox", 4, return_args);
174 if (status) {
175 (void) sprintf(buf, "\nUnauthorized attempt to modify %s's \
176email address.", uname);
177 goto punt;
178 }
179 /*
180 * address, if it exists, is of form user@host. It needs to be split up.
181 */
182 if (address) {
183 machine = index(address, '@');
184 if (machine) {
185 *machine++ = '\0'; /* get rid of the @ sign */
186 machine = trim(machine); /* get rid of whitespace */
187 }
188 else {
189 fprintf(stderr, "%s: no at sign (@) in address\n",
190 whoami);
191 sms_disconnect();
192 exit(1);
193 } /* now machine points to the machine name,
194 * and address points to the "box" name */
195 pobox.machine = canon(machine); /* canonicalize the machine name */
196 if (machine == (char *) NULL) { /* nameserver failed in canon */
197 (void) sprintf(buf, "\nNameserver transaction \
198failed.\nI cannot change your mailbox at this time. Please try again \
199later.\n");
200 goto punt;
201 }
202 pobox.type = in(pobox.machine); /* find out the type */
203 pobox.login = uname; /* whose is changing? */
204 pobox.box = address; /* to what mailbox? */
205 }
206
207 if (add) {
208 printf("\nAdding email address %s@%s for %s.",
209 pobox.box, pobox.machine, uname);
210
211 if (strcmp(pobox.type, "pop") == 0) {
212 /*
213 * check to be sure that they're not getting more than one. If
214 * they are, punt.
215 */
216 }
217 return_args = crunch_pobox_args(pobox);
218 status = sms_query("add_pobox", 4, return_args, scream,
219 (char *) NULL);
220 if (status) {
221 (void) sprintf(buf, "\nWrite failed to SMS \
222database.");
223 goto punt;
224 }
225 printf("..done.\n");
226 sms_disconnect();
227 exit(0);
228 }
229 else if (delflag) { /* isn't yet checking to make sure that the
230 * user isn't being left without a mailbox. */
231 printf("Deleting email address %s@%s for %s.", pobox.box,
232 pobox.machine, uname);
233 return_args = crunch_pobox_args(pobox);
234 status = sms_query("delete_pobox", 4, return_args, scream,
235 (char *) NULL);
236 if (status) {
237 (void) sprintf(buf, "\nWrite failed to SMS \
238database.");
239 goto punt;
240 }
241 printf("..done.\n");
242 sms_disconnect();
243 exit(0);
244 }
245 else { /* report all current poboxes */
246 printf("Current mail address(es) for %s is/are:", uname);
247 status = sms_query("get_pobox", 1, smsarg, get_machine,
248 (char *) &pobox);
249 if (status) {
250 if (status == SMS_NO_MATCH)
251 printf(" None\n");
252 else {
253 (void) sprintf(buf, "\nRetrieve from \
254SMS database failed.");
255 goto punt;
256 }
257 }
258 }
259 sms_disconnect();
260 exit(0);
261
262punt:
263 com_err(whoami, status, buf);
264 sms_disconnect();
265 exit(1);
266}
267
268scream()
269{
270 com_err(whoami, status, "Unexpected return value from SMS -- \
271programmer botch\n");
272 sms_disconnect();
273 exit(1);
274}
275
276/*
277 * get_machine gets all your poboxes and displays them.
278 */
279
280/* ARGSUSED */
281int
282get_machine(argc, argv, callarg)
283 int argc;
284 char **argv, *callarg;
285{
286 struct pobox_values *pobox = (struct pobox_values *) callarg;
287
288 pobox->type = ds(argv[1]);
289 pobox->machine = ds(argv[2]);
290 pobox->box = ds(argv[3]);
291
292 printf("\ntype: %s\naddress: %s@%s\n", pobox->type,
293 pobox->box, pobox->machine);
294 return (0);
295}
296
297char *
298ds(str)
299 char *str;
300{
301 register char *newstr = malloc((unsigned) strlen(str) + 1);
302
303 if (newstr == (char *) NULL)
304 return ((char *) NULL);
305 else
306 return (strcpy(newstr, str));
307}
308
309char **
310crunch_pobox_args(in)
311 struct pobox_values in;
312{
313 char **out;
314
315 out = (char **) malloc((unsigned) sizeof(char *) * 4);
316 out[0] = in.login;
317 out[1] = in.type;
318 out[2] = in.machine;
319 out[3] = in.box;
320 return (out);
321}
322
323/*
324 * Trim whitespace off of cp. Side-effects cp.
325 */
326char *
327trim(cp)
328 register char *cp;
329{
330 register char *ep;
331
332 while (isspace(*cp))
333 cp++;
334 ep = cp;
335 while (*ep)
336 ep++;
337 if (ep > cp) {
338 for (--ep; isspace(*ep); --ep)
339 continue;
340 ep++;
341 *ep = '\0';
342 }
343 return cp;
344}
345
346/*
347 * given a canonicalized machine name, ask the SMS server if it is of type
348 * pop, or of type local -- if neither, we assume that it's of type foreign.
349 */
350char *
351in(machine)
352 char *machine;
353{
354 char *service[1], buf[BUFSIZ];
355 int check_match();
356
357 match = 0;
358 service[0] = ds("pop");
359 status = sms_query("get_server_locations", 1, service,
360 check_match, machine);
361 if (status && (status != SMS_NO_MATCH)) {
362 (void) sprintf(buf, "\nRead failed from SMS \
363database.");
364 goto punt;
365 }
366 if (match)
367 return ("pop");
368
369 service[0] = ds("local");
370 status = sms_query("get_server_locations", 1, service,
371 check_match, machine);
372 if (status && (status != SMS_NO_MATCH)) {
373 (void) sprintf(buf, "\nRead failed from SMS \
374database.");
375 goto punt;
376 }
377 if (match)
378 return ("local");
379 else
380 return ("foreign");
381punt:
382 com_err(whoami, status, buf);
383 sms_disconnect();
384 exit(1);
385}
386
387/* ARGSUSED */
388int
389check_match(argc, argv, callback)
390 int argc;
391 char **argv, *callback;
392{
393 if (match)
394 return (0);
395
396 if (strcmp(argv[1], callback) == 0)
397 match = 1;
398
399 return (0);
400}
401
402/*
403 * given a machine name, canonicalize it and return it. Returns (char *)
404 * NULL if the nameserver returns any error.
405 */
406char *
407canon(machine)
408 char *machine;
409{
410 struct hostent *hostinfo;
411
412 hostinfo = gethostbyname(machine);
413 if (hostinfo != (struct hostent *) NULL)
414 machine = hostinfo->h_name;
415 else /* gethostbyname failed; this should be very
416 * rare, since we're dealing with local
67655a21 417 * hosts, so no fancy error recovery.
418 */
48fbc492 419 machine = (char *) NULL;
420 return (machine);
421}
422
423usage()
424{
425 fprintf(stderr, "Usage: %s [-d|a address] [-u user]\n", whoami);
426 exit(1);
427}
428
429/*
430 * Local Variables:
431 * mode: c
432 * c-indent-level: 4
433 * c-continued-statement-offset: 4
434 * c-brace-offset: -4
435 * c-argdecl-indent: 4
436 * c-label-offset: -4
437 * End:
438 */
This page took 0.102645 seconds and 5 git commands to generate.