]> andersk Git - moira.git/blob - clients/passwd/chpobox.c
056bf0e7eec4d6460e6a7b953284593bfaf7e278
[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;
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(SMS_SERVER);
126     if (status) {
127         com_err(whoami, status, " while connecting to SMS");
128         exit(1);
129     }
130
131     status = sms_auth("chpobox");
132     if (status) {
133         com_err(whoami, status, " while authenticating -- run \"kinit\" and try again.");
134         sms_disconnect();
135         exit(1);
136     }
137
138     if (setflag) {
139         /* Address is of form user@host.  Split it up. */
140         if (!address) {
141             fprintf(stderr, "%s: no address was specified.\n", whoami);
142             goto show;
143         }
144         machine = index(address, '@');
145         if (machine) {
146             *machine++ = '\0';          /* get rid of the @ sign */
147             machine = strtrim(machine); /* get rid of whitespace */
148         } else {
149             fprintf(stderr, "%s: no at sign (@) in address \"%s\"\n",
150                     whoami, address);
151             goto show;
152         }
153         smsarg[2] = canonicalize_hostname(strsave(machine));
154         smsarg[1] = potype(smsarg[2]);
155         if (!strcmp(smsarg[1], "POP")) {
156             if (strcmp(address, uname)) {
157                 fprintf(stderr,
158                         "%s: the name on the POP box must match the username\n",
159                         whoami);
160                 goto show;
161             }
162         } else if (!strcmp(smsarg[1], "LOCAL")) {
163             strcat(address, "@");
164             strcat(address, smsarg[2]);
165             smsarg[2] = address;
166             if ((address = index(address, '@')) &&
167                 (address = index(address, '.')))
168               *address = 0;
169             strcat(smsarg[2], ".LOCAL");
170             smsarg[1] = "SMTP";
171         } else if (smsarg[1]) {
172             if (*machine != '"' && strcasecmp(smsarg[2], machine))
173               printf("Warning: hostname %s canonicalized to %s\n",
174                      machine, smsarg[2]);
175             strcat(address, "@");
176             strcat(address, smsarg[2]);
177             smsarg[2] = address;
178         } else
179           goto show;
180         status = sms_query("set_pobox", 3, smsarg, scream, NULL);
181         if (status)
182           com_err(whoami, status,
183                   " while setting pobox for %s to type %s, box %s",
184                   smsarg[0], smsarg[1], smsarg[2]);
185     } else if (prevpop) {
186         status = sms_query("set_pobox_pop", 1, smsarg, scream, NULL);
187         if (status == SMS_MACHINE) {
188             fprintf(stderr,
189                     "SMS has no record of a previous POP box for %s\n", uname);
190         } else if (status != 0)
191           com_err(whoami, status, " while setting pobox");
192     }
193
194     /*
195      * get current box
196      */
197 show:
198     status = sms_query("get_pobox", 1, smsarg, get_pobox, NULL);
199     if (status == SMS_NO_MATCH)
200       printf("User %s has no pobox.\n", uname);
201     else if (status != 0)
202       com_err(whoami, status, " while retrieving current mailbox");
203     sms_disconnect();
204     exit(0);
205 }
206
207
208 scream()
209 {
210     com_err(whoami, 0, "Unexpected return value from SMS -- programmer botch");
211     sms_disconnect();
212     exit(1);
213 }
214
215 /*
216  * get_pobox gets all your poboxes and displays them.
217  */
218
219 /* ARGSUSED */
220 int
221 get_pobox(argc, argv, callarg)
222     int argc;
223     char **argv, *callarg;
224 {
225     if (!strcmp(argv[1], "POP"))
226       printf("User %s, Type %s, Box: %s@%s\n",
227              argv[0], argv[1], argv[0], argv[2]);
228     else
229       printf("User %s, Type %s, Box: %s\n",
230              argv[0], argv[1], argv[2]);
231     printf("  Modified by %s on %s with %s\n", argv[4], argv[3], argv[5]);
232     return (0);
233 }
234
235 /*
236  * given a canonicalized machine name, ask the SMS server if it is of type
237  * pop, or of type local -- if neither, we assume that it's of type foreign. 
238  */
239 char *
240 potype(machine)
241     char *machine;
242 {
243     char *service[1];
244     int check_match(), status;
245
246     match = 0;
247     service[0] = "POP";
248     status = sms_query("get_server_locations", 1, service,
249                        check_match, machine);
250     if (status && (status != SMS_NO_MATCH)) {
251         com_err(whoami, status, " while reading list of POP servers");
252         return(NULL);
253     }
254     if (match)
255         return ("POP");
256
257     service[0] = "LOCAL";
258     status = sms_query("get_server_locations", 1, service,
259                        check_match, machine);
260     if (status && (status != SMS_NO_MATCH)) {
261         com_err(whoami, status, " while reading list of LOCAL servers");
262         return(NULL);
263     }
264     if (match)
265         return ("LOCAL");
266     else
267         return ("SMTP");
268 }
269
270 /* ARGSUSED */
271 int
272 check_match(argc, argv, callback)
273     int argc;
274     char **argv, *callback;
275 {
276     if (match)
277         return (0);
278
279     if (strcasecmp(argv[1], callback) == 0)
280         match = 1;
281
282     return (0);
283 }
284
285 usage()
286 {
287     fprintf(stderr, "Usage: %s [-s address] [-p] [-u user]\n", whoami);
288     exit(1);
289 }
This page took 0.04523 seconds and 3 git commands to generate.