]> andersk Git - moira.git/blob - clients/passwd/chpobox.c
393be4970d43c6f75c22736bc98b05f8cf2d1d4b
[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 SMS 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 <strings.h>
35 #include <ctype.h>
36 #include <errno.h>
37
38 /* SMS includes */
39 #include <sms.h>
40 #include <sms_app.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 *smsarg[3], buf[BUFSIZ];
59     char *potype(), *index();
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 = rindex(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     smsarg[0] = uname;
124
125     status = sms_connect(NULL);
126     if (status) {
127         com_err(whoami, status, " while connecting to Moira");
128         exit(1);
129     }
130
131     status = sms_motd(&motd);
132     if (status) {
133         sms_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         sms_disconnect();
140         exit(1);
141     }
142
143     status = sms_auth("chpobox");
144     if (status) {
145         com_err(whoami, status, " while authenticating -- run \"kinit\" and try again.");
146         sms_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 = index(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         smsarg[2] = canonicalize_hostname(strsave(machine));
166         smsarg[1] = potype(smsarg[2]);
167         if (!strcmp(smsarg[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(smsarg[1], "LOCAL")) {
175             strcat(address, "@");
176             strcat(address, smsarg[2]);
177             smsarg[2] = address;
178             if ((address = index(address, '@')) &&
179                 (address = index(address, '.')))
180               *address = 0;
181             strcat(smsarg[2], ".LOCAL");
182             smsarg[1] = "SMTP";
183         } else if (smsarg[1]) {
184             if (*machine != '"' && strcasecmp(smsarg[2], machine))
185               printf("Warning: hostname %s canonicalized to %s\n",
186                      machine, smsarg[2]);
187             strcat(address, "@");
188             strcat(address, smsarg[2]);
189             smsarg[2] = address;
190         } else
191           goto show;
192         status = sms_query("set_pobox", 3, smsarg, scream, NULL);
193         if (status)
194           com_err(whoami, status,
195                   " while setting pobox for %s to type %s, box %s",
196                   smsarg[0], smsarg[1], smsarg[2]);
197     } else if (prevpop) {
198         status = sms_query("set_pobox_pop", 1, smsarg, scream, NULL);
199         if (status == SMS_MACHINE) {
200             fprintf(stderr,
201                     "Moira has no record of a previous POP box for %s\n", uname);
202         } else if (status != 0)
203           com_err(whoami, status, " while setting pobox");
204     }
205
206     /*
207      * get current box
208      */
209 show:
210     status = sms_query("get_pobox", 1, smsarg, get_pobox, NULL);
211     if (status == SMS_NO_MATCH)
212       printf("User %s has no pobox.\n", uname);
213     else if (status != 0)
214       com_err(whoami, status, " while retrieving current mailbox");
215     sms_disconnect();
216     exit(0);
217 }
218
219
220 scream()
221 {
222     com_err(whoami, 0, "Unexpected return value from Moira -- programmer botch");
223     sms_disconnect();
224     exit(1);
225 }
226
227 /*
228  * get_pobox gets all your poboxes and displays them.
229  */
230
231 /* ARGSUSED */
232 int
233 get_pobox(argc, argv, callarg)
234     int argc;
235     char **argv, *callarg;
236 {
237     if (!strcmp(argv[1], "POP"))
238       printf("User %s, Type %s, Box: %s@%s\n",
239              argv[0], argv[1], argv[0], argv[2]);
240     else
241       printf("User %s, Type %s, Box: %s\n",
242              argv[0], argv[1], argv[2]);
243     printf("  Modified by %s on %s with %s\n", argv[4], argv[3], argv[5]);
244     return (0);
245 }
246
247 /*
248  * given a canonicalized machine name, ask the SMS server if it is of type
249  * pop, or of type local -- if neither, we assume that it's of type foreign. 
250  */
251 char *
252 potype(machine)
253     char *machine;
254 {
255     char *service[1];
256     int check_match(), status;
257
258     match = 0;
259     service[0] = "POP";
260     status = sms_query("get_server_locations", 1, service,
261                        check_match, machine);
262     if (status && (status != SMS_NO_MATCH)) {
263         com_err(whoami, status, " while reading list of POP servers");
264         return(NULL);
265     }
266     if (match)
267         return ("POP");
268
269     service[0] = "LOCAL";
270     status = sms_query("get_server_locations", 1, service,
271                        check_match, machine);
272     if (status && (status != SMS_NO_MATCH)) {
273         com_err(whoami, status, " while reading list of LOCAL servers");
274         return(NULL);
275     }
276     if (match)
277         return ("LOCAL");
278     else
279         return ("SMTP");
280 }
281
282 /* ARGSUSED */
283 int
284 check_match(argc, argv, callback)
285     int argc;
286     char **argv, *callback;
287 {
288     if (match)
289         return (0);
290
291     if (strcasecmp(argv[1], callback) == 0)
292         match = 1;
293
294     return (0);
295 }
296
297 usage()
298 {
299     fprintf(stderr, "Usage: %s [-s address] [-p] [-u user]\n", whoami);
300     exit(1);
301 }
This page took 0.048643 seconds and 3 git commands to generate.