]> andersk Git - moira.git/blob - clients/passwd/chpobox.c
Append numbers to MUL entries in filsys.db for use with new version of
[moira.git] / clients / passwd / chpobox.c
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  *
9  */
10
11 #ifndef lint
12 static char *rcsid_chpobox_c = "$Header$";
13 #endif not lint
14
15 /*
16  * Talk to the MOIRA database to change a person's home mail machine. This may
17  * be an Athena machine, or a completely arbitrary address.
18  * 
19  * chpobox with no modifiers reports the current mailbox.
20  * 
21  * chpobox -s [address] means set the mailbox to this address.
22  *
23  * chpobox -p restores the pobox to a previous POP box, if there was one.
24  *
25  * chpobox -u [user] is needed if you are logged in as one user, but
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.
29  */
30
31 #include <sys/types.h>
32 #include <stdio.h>
33 #include <pwd.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include <errno.h>
37
38 /* MOIRA includes */
39 #include <moira.h>
40 #include <moira_site.h>
41 #include "mit-copyright.h"
42
43 char *getlogin();
44 char *malloc();
45 char *whoami;
46 uid_t getuid();
47
48 int getopt();
49
50 static int match;
51
52
53 main(argc, argv)
54     int argc;
55     char *argv[];
56 {
57     struct passwd *pwd;
58     char *mrarg[3], buf[BUFSIZ];
59     char *potype();
60     char *address, *uname, *machine, *motd;
61     uid_t u;
62     char *canonicalize_hostname();
63     int get_pobox(), scream();
64     int c, setflag, prevpop, usageflag, status;
65
66     extern int optind;
67     extern char *optarg;
68
69     c = setflag = prevpop = usageflag = 0;
70     address = uname = (char *) NULL;
71     u = getuid();
72
73     if ((whoami = strrchr(argv[0], '/')) == NULL)
74         whoami = argv[0];
75     else
76         whoami++;
77
78     if (argc > 5) {
79         usage();
80     }
81
82     while ((c = getopt(argc, argv, "s:pu:")) != EOF)
83         switch (c) {
84
85         case 's':
86             if (prevpop)
87                 usageflag++;
88             else {
89                 setflag++;
90                 strcpy(buf, optarg);
91                 address = buf;
92             }
93             break;
94         case 'p':
95             if (setflag)
96                 usageflag++;
97             else {
98                 prevpop++;
99             }
100             break;
101         case 'u':
102             uname = strsave(optarg);
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     }
123     mrarg[0] = uname;
124
125     status = mr_connect(NULL);
126     if (status) {
127         com_err(whoami, status, " while connecting to Moira");
128         exit(1);
129     }
130
131     status = mr_motd(&motd);
132     if (status) {
133         mr_disconnect();
134         com_err(whoami, status, " unable to check server status");
135         exit(1);
136     }
137     if (motd) {
138         fprintf(stderr, "The Moira server is currently unavailable:\n%s\n", motd);
139         mr_disconnect();
140         exit(1);
141     }
142
143     status = mr_auth("chpobox");
144     if (status) {
145         com_err(whoami, status, " while authenticating -- run \"kinit\" and try again.");
146         mr_disconnect();
147         exit(1);
148     }
149
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         }
156         machine = strchr(address, '@');
157         if (machine) {
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;
164         }
165         mrarg[2] = canonicalize_hostname(strsave(machine));
166         mrarg[1] = potype(mrarg[2]);
167         if (!strcmp(mrarg[1], "POP")) {
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;
173             }
174         } else if (!strcmp(mrarg[1], "LOCAL")) {
175             strcat(address, "@");
176             strcat(address, mrarg[2]);
177             mrarg[2] = address;
178             if ((address = strchr(address, '@')) &&
179                 (address = strchr(address, '.')))
180               *address = 0;
181             strcat(mrarg[2], ".LOCAL");
182             mrarg[1] = "SMTP";
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);
196         } else if (mrarg[1]) {
197             if (*machine != '"' && strcasecmp(mrarg[2], machine))
198               fprintf(stderr, "Warning: hostname %s canonicalized to %s\n",
199                       machine, mrarg[2]);
200             strcat(address, "@");
201             strcat(address, mrarg[2]);
202             mrarg[2] = address;
203         } else
204           goto show;
205         status = mr_query("set_pobox", 3, mrarg, scream, NULL);
206         if (status)
207           com_err(whoami, status,
208                   " while setting pobox for %s to type %s, box %s",
209                   mrarg[0], mrarg[1], mrarg[2]);
210     } else if (prevpop) {
211         status = mr_query("set_pobox_pop", 1, mrarg, scream, NULL);
212         if (status == MR_MACHINE) {
213             fprintf(stderr,
214                     "Moira has no record of a previous POP box for %s\n", uname);
215         } else if (status != 0)
216           com_err(whoami, status, " while setting pobox");
217     }
218
219     /*
220      * get current box
221      */
222 show:
223     status = mr_query("get_pobox", 1, mrarg, get_pobox, NULL);
224     if (status == MR_NO_MATCH)
225       printf("User %s has no pobox.\n", uname);
226     else if (status != 0)
227       com_err(whoami, status, " while retrieving current mailbox");
228     mr_disconnect();
229     exit(0);
230 }
231
232
233 scream()
234 {
235     com_err(whoami, 0, "Unexpected return value from Moira -- programmer botch");
236     mr_disconnect();
237     exit(1);
238 }
239
240 /*
241  * get_pobox gets all your poboxes and displays them.
242  */
243
244 /* ARGSUSED */
245 int
246 get_pobox(argc, argv, callarg)
247     int argc;
248     char **argv, *callarg;
249 {
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]);
257     return (0);
258 }
259
260 /*
261  * given a canonicalized machine name, ask the MR server if it is of type
262  * pop, or of type local -- if neither, we assume that it's of type foreign. 
263  */
264 char *
265 potype(machine)
266     char *machine;
267 {
268     char *service[1], *argv[3];
269     int check_match(), check_match3(), status;
270
271     match = 0;
272     service[0] = "POP";
273     status = mr_query("get_server_locations", 1, service,
274                        check_match, machine);
275     if (status && (status != MR_NO_MATCH)) {
276         com_err(whoami, status, " while reading list of POP servers");
277         return(NULL);
278     }
279     if (match)
280         return ("POP");
281
282     service[0] = "LOCAL";
283     status = mr_query("get_server_locations", 1, service,
284                        check_match, machine);
285     if (status && (status != MR_NO_MATCH)) {
286         com_err(whoami, status, " while reading list of LOCAL servers");
287         return(NULL);
288     }
289     if (match)
290         return ("LOCAL");
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");
302     else
303         return ("SMTP");
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
315     if (strcasecmp(argv[1], callback) == 0)
316         match = 1;
317
318     return (0);
319 }
320
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
336 usage()
337 {
338     fprintf(stderr, "Usage: %s [-s address] [-p] [-u user]\n", whoami);
339     exit(1);
340 }
This page took 0.069167 seconds and 5 git commands to generate.