]> andersk Git - moira.git/blame - clients/passwd/chpobox.c
add in krb4/krb5 kadmin stuff
[moira.git] / clients / passwd / chpobox.c
CommitLineData
c441a31a 1/* $Id$
48fbc492 2 *
59ec8dae 3 * Talk to the Moira database to change a person's home mail machine. This may
48fbc492 4 * be an Athena machine, or a completely arbitrary address.
5eaef520 5 *
8c5c4d26 6 * chpobox with no modifiers reports the current mailbox.
5eaef520 7 *
8c5c4d26 8 * chpobox -s [address] means set the mailbox to this address.
48fbc492 9 *
8c5c4d26 10 * chpobox -p restores the pobox to a previous POP box, if there was one.
48fbc492 11 *
67655a21 12 * chpobox -u [user] is needed if you are logged in as one user, but
48fbc492 13 * are trying to change the email address of another. You must have
14 * Kerberos tickets as the person whose address you are trying to
15 * change, or the attempt will fail.
7ac48069 16 *
17 * Copyright (C) 1987-1998 by the Massachusetts Institute of Technology
18 * For copying and distribution information, please see the file
19 * <mit-copyright.h>.
48fbc492 20 */
21
7ac48069 22#include <mit-copyright.h>
23#include <moira.h>
24#include <moira_site.h>
25
48fbc492 26#include <pwd.h>
7ac48069 27#include <stdio.h>
28#include <stdlib.h>
f071d8a7 29#include <string.h>
7ac48069 30#include <unistd.h>
48fbc492 31
7a40dcd4 32#include <krb.h>
33
7ac48069 34RCSID("$Header$");
48fbc492 35
7ac48069 36int get_pobox(int argc, char **argv, void *callarg);
37char *potype(char *machine);
38int check_match(int argc, char **argv, void *callback);
39int check_match3(int argc, char **argv, void *callback);
40int usage(void);
48fbc492 41
7ac48069 42char *whoami;
48fbc492 43
48fbc492 44static int match;
45
5eaef520 46int main(int argc, char *argv[])
48fbc492 47{
5eaef520 48 struct passwd *pwd;
7a40dcd4 49 char *mrarg[3], buf[BUFSIZ], pname[ANAME_SZ];
5eaef520 50 char *address, *uname, *machine, *motd;
51 uid_t u;
5eaef520 52 int c, setflag, prevpop, usageflag, status;
53
54 extern int optind;
55 extern char *optarg;
56
57 c = setflag = prevpop = usageflag = 0;
7ac48069 58 address = uname = NULL;
5eaef520 59 u = getuid();
60
61 if ((whoami = strrchr(argv[0], '/')) == NULL)
62 whoami = argv[0];
63 else
64 whoami++;
65
66 if (argc > 5)
67 usage();
68
69 while ((c = getopt(argc, argv, "s:pu:")) != -1)
70 switch (c)
71 {
72 case 's':
73 if (prevpop)
74 usageflag++;
75 else
76 {
77 setflag++;
78 strcpy(buf, optarg);
79 address = buf;
80 }
81 break;
82 case 'p':
83 if (setflag)
84 usageflag++;
85 else
86 prevpop++;
87 break;
88 case 'u':
7ac48069 89 uname = strdup(optarg);
5eaef520 90 break;
91 default:
92 usageflag++;
93 break;
94 }
95 if (argc == 2 && optind == 1 && !uname)
96 uname = argv[optind++];
97
98 if (usageflag || optind != argc)
99 usage();
100
101 if (!uname)
102 {
7a40dcd4 103 if ((status = tf_init(TKT_FILE, R_TKT_FIL)) ||
104 (status = tf_get_pname(pname)))
5eaef520 105 {
7a40dcd4 106 com_err(whoami, status, "reading Kerberos ticket file");
107 exit(1);
48fbc492 108 }
7a40dcd4 109 tf_close();
110 uname = pname;
48fbc492 111 }
5eaef520 112 mrarg[0] = uname;
48fbc492 113
5eaef520 114 status = mr_connect(NULL);
115 if (status)
116 {
117 com_err(whoami, status, " while connecting to Moira");
118 exit(1);
48fbc492 119 }
120
5eaef520 121 status = mr_motd(&motd);
122 if (status)
123 {
124 mr_disconnect();
125 com_err(whoami, status, " unable to check server status");
126 exit(1);
262ca740 127 }
5eaef520 128 if (motd)
129 {
130 fprintf(stderr, "The Moira server is currently unavailable:\n%s\n",
131 motd);
132 mr_disconnect();
133 exit(1);
262ca740 134 }
135
5eaef520 136 status = mr_auth("chpobox");
137 if (status)
138 {
139 com_err(whoami, status, " while authenticating -- "
140 "run \"kinit\" and try again.");
141 mr_disconnect();
142 exit(1);
ccd5efe6 143 }
144
5eaef520 145 if (setflag)
146 {
147 /* Address is of form user@host. Split it up. */
148 if (!address)
149 {
150 fprintf(stderr, "%s: no address was specified.\n", whoami);
151 goto show;
8c5c4d26 152 }
5eaef520 153 machine = strchr(address, '@');
154 if (machine)
155 {
156 *machine++ = '\0'; /* get rid of the @ sign */
157 machine = strtrim(machine); /* get rid of whitespace */
48fbc492 158 }
5eaef520 159 else
160 {
161 fprintf(stderr, "%s: no at sign (@) in address \"%s\"\n",
162 whoami, address);
163 goto show;
164 }
7ac48069 165 mrarg[2] = canonicalize_hostname(strdup(machine));
5eaef520 166 mrarg[1] = potype(mrarg[2]);
167 if (!strcmp(mrarg[1], "POP"))
168 {
169 if (strcmp(address, uname))
170 {
171 fprintf(stderr,
172 "%s: the name on the POP box must match the username\n",
173 whoami);
174 goto show;
ccd5efe6 175 }
5eaef520 176 }
177 else if (!strcmp(mrarg[1], "LOCAL"))
178 {
179 strcat(address, "@");
180 strcat(address, mrarg[2]);
181 mrarg[2] = address;
182 if ((address = strchr(address, '@')) &&
183 (address = strchr(address, '.')))
184 *address = 0;
185 strcat(mrarg[2], ".LOCAL");
186 mrarg[1] = "SMTP";
187 }
188 else if (!strcmp(mrarg[1], "MAILHUB"))
189 {
190 if (!strcmp(address, uname))
191 {
192 fprintf(stderr,
193 "Error: this will set a mail forwarding loop.\n");
194 fprintf(stderr,
195 "Use \"%s -p\" to set a local post office server.\n",
196 whoami);
197 exit(1);
108a5f18 198 }
5eaef520 199 fprintf(stderr, "Error: \"%s@%s\" is a local mail address.\n",
200 address, machine);
201 fprintf(stderr, "Your mail drop must be on a post office server "
202 "or an external mail address.\n");
203 exit(1);
204 }
205 else if (mrarg[1])
206 {
207 if (*machine != '"' && strcasecmp(mrarg[2], machine))
208 {
108a5f18 209 fprintf(stderr, "Warning: hostname %s canonicalized to %s\n",
210 machine, mrarg[2]);
5eaef520 211 }
212 strcat(address, "@");
213 strcat(address, mrarg[2]);
214 mrarg[2] = address;
8c5c4d26 215 } else
216 goto show;
7ac48069 217 status = mr_query("set_pobox", 3, mrarg, NULL, NULL);
5eaef520 218 if (status)
219 com_err(whoami, status,
220 " while setting pobox for %s to type %s, box %s",
221 mrarg[0], mrarg[1], mrarg[2]);
222 }
223 else if (prevpop)
224 {
7ac48069 225 status = mr_query("set_pobox_pop", 1, mrarg, NULL, NULL);
5eaef520 226 if (status == MR_MACHINE)
227 {
228 fprintf(stderr,
229 "Moira has no record of a previous POP box for %s\n", uname);
230 }
231 else if (status != 0)
232 com_err(whoami, status, " while setting pobox");
48fbc492 233 }
ccd5efe6 234
5eaef520 235 /*
236 * get current box
237 */
8c5c4d26 238show:
5eaef520 239 status = mr_query("get_pobox", 1, mrarg, get_pobox, NULL);
240 if (status == MR_NO_MATCH)
241 printf("User %s has no pobox.\n", uname);
242 else if (status != 0)
243 com_err(whoami, status, " while retrieving current mailbox");
244 mr_disconnect();
245 exit(0);
48fbc492 246}
247
8c5c4d26 248
48fbc492 249/*
dbe34e72 250 * get_pobox gets all your poboxes and displays them.
48fbc492 251 */
252
7ac48069 253int get_pobox(int argc, char **argv, void *callarg)
48fbc492 254{
5eaef520 255 if (!strcmp(argv[1], "POP"))
256 printf("User %s, Type %s, Box: %s@%s\n",
257 argv[0], argv[1], argv[0], argv[2]);
258 else
259 printf("User %s, Type %s, Box: %s\n",
260 argv[0], argv[1], argv[2]);
261 printf(" Modified by %s on %s with %s\n", argv[4], argv[3], argv[5]);
262 return 0;
48fbc492 263}
264
48fbc492 265/*
59ec8dae 266 * given a canonicalized machine name, ask the Moira server if it is of type
5eaef520 267 * pop, or of type local -- if neither, we assume that it's of type foreign.
48fbc492 268 */
5eaef520 269char *potype(char *machine)
48fbc492 270{
5eaef520 271 char *service[1], *argv[3];
7ac48069 272 int status;
5eaef520 273
274 match = 0;
275 service[0] = "POP";
276 status = mr_query("get_server_locations", 1, service, check_match, machine);
277 if (status && (status != MR_NO_MATCH))
278 {
279 com_err(whoami, status, " while reading list of POP servers");
280 return NULL;
48fbc492 281 }
5eaef520 282 if (match)
283 return "POP";
284
285 service[0] = "LOCAL";
286 status = mr_query("get_server_locations", 1, service, check_match, machine);
287 if (status && (status != MR_NO_MATCH))
288 {
289 com_err(whoami, status, " while reading list of LOCAL servers");
290 return NULL;
48fbc492 291 }
5eaef520 292 if (match)
293 return "LOCAL";
294
295 argv[0] = "mailhub";
296 argv[1] = "TYPE";
297 argv[2] = "*";
298 status = mr_query("get_alias", 3, argv, check_match3, machine);
299 if (status && (status != MR_NO_MATCH))
300 {
301 com_err(whoami, status, " while reading list of MAILHUB servers");
302 return NULL;
108a5f18 303 }
5eaef520 304 if (match)
305 return "MAILHUB";
306 else
307 return "SMTP";
48fbc492 308}
309
7ac48069 310int check_match(int argc, char **argv, void *callback)
48fbc492 311{
5eaef520 312 if (match)
313 return 0;
48fbc492 314
5eaef520 315 if (!strcasecmp(argv[1], callback))
316 match = 1;
48fbc492 317
5eaef520 318 return 0;
48fbc492 319}
320
7ac48069 321int check_match3(int argc, char **argv, void *callback)
108a5f18 322{
5eaef520 323 if (match)
324 return 0;
108a5f18 325
5eaef520 326 if (!strcasecmp(argv[2], callback))
327 match = 1;
108a5f18 328
5eaef520 329 return 0;
108a5f18 330}
331
5eaef520 332int usage(void)
48fbc492 333{
5eaef520 334 fprintf(stderr, "Usage: %s [-s address] [-p] [-u user]\n", whoami);
335 exit(1);
48fbc492 336}
This page took 2.113442 seconds and 5 git commands to generate.