]> andersk Git - moira.git/blame - clients/userreg/reg_stubs.c
eliminate use of the `register' keyword: let the compiler decide
[moira.git] / clients / userreg / reg_stubs.c
CommitLineData
6e6374cb 1/*
2 * $Source$
3 * $Author$
4 * $Header$
5 *
7189310c 6 * (c) Copyright 1988 by the Massachusetts Institute of Technology.
7 * For copying and distribution information, please see the file
8 * <mit-copyright.h>.
6e6374cb 9 */
10
11#ifndef lint
12static char *rcsid_reg_stubs_c = "$Header$";
7ff930df 13#endif
7189310c 14
15#include <mit-copyright.h>
6e6374cb 16#include <stdio.h>
7ff930df 17#include <stdlib.h>
6e6374cb 18#include <sys/types.h>
19#include <sys/time.h>
20#include <sys/socket.h>
21#include <netinet/in.h>
22#include <netdb.h>
23#include <des.h>
b7ed754f 24#include <krb.h>
25#include <krb_err.h>
6e6374cb 26#include <errno.h>
8defc06b 27#include <moira.h>
28#include <moira_site.h>
7ff930df 29#include <hesiod.h>
6e6374cb 30#include "ureg_err.h"
31#include "ureg_proto.h"
f071d8a7 32#include <string.h>
b7ed754f 33#include <ctype.h>
6e6374cb 34
35static int reg_sock = -1;
8edc0757 36static int seq_no = 0;
b7ed754f 37static char *host;
6e6374cb 38extern errno;
39#define UNKNOWN_HOST -1
40#define UNKNOWN_SERVICE -2
41
8b7874ce 42#ifndef FD_SET
43#define FD_ZERO(p) ((p)->fds_bits[0] = 0)
44#define FD_SET(n, p) ((p)->fds_bits[0] |= (1 << (n)))
45#define FD_ISSET(n, p) ((p)->fds_bits[0] & (1 << (n)))
46#endif /* FD_SET */
47
5eaef520 48int ureg_init(void)
6e6374cb 49{
5eaef520 50 struct servent *sp;
51 char **p, *s;
52 struct hostent *hp;
53 struct sockaddr_in s_in;
54
55 initialize_ureg_error_table();
56 initialize_krb_error_table();
57 initialize_sms_error_table();
58 initialize_kadm_error_table();
59
60 seq_no = getpid();
61
62 host = NULL;
63 host = getenv("REGSERVER");
028ff1c1 64#ifdef HESIOD
5eaef520 65 if (!host || (strlen(host) == 0))
66 {
67 p = hes_resolve("registration", "sloc");
68 if (p)
69 host = *p;
028ff1c1 70 }
7ff930df 71#endif
5eaef520 72 if (!host || (strlen(host) == 0))
73 {
74 host = strsave(MOIRA_SERVER);
75 s = strchr(host, ':');
76 if (s)
77 *s = '\0';
028ff1c1 78 }
5eaef520 79 hp = gethostbyname(host);
80 host = strsave(hp->h_name);
81 if (hp == NULL)
82 return UNKNOWN_HOST;
6e6374cb 83
5eaef520 84 sp = getservbyname("sms_ureg", "udp");
6e6374cb 85
5eaef520 86 if (sp == NULL)
87 return UNKNOWN_SERVICE;
6e6374cb 88
5eaef520 89 close(reg_sock);
90 reg_sock = socket(AF_INET, SOCK_DGRAM, 0);
91 if (reg_sock < 0)
92 return errno;
6e6374cb 93
5eaef520 94 memset(&s_in, 0, sizeof(s_in));
95 s_in.sin_port = sp->s_port;
96 memcpy(&s_in.sin_addr, hp->h_addr, sizeof(struct in_addr));
97 s_in.sin_family = AF_INET;
98
99 if (connect(reg_sock, (struct sockaddr *)&s_in, sizeof(s_in)) < 0)
100 return errno;
101 return 0;
6e6374cb 102}
103
5eaef520 104int verify_user(char *first, char *last, char *idnumber,
105 char *hashidnumber, char *login)
6e6374cb 106{
5eaef520 107 char buf[1024];
108 int version = ntohl((u_long)1);
109 int call = ntohl((u_long)UREG_VERIFY_USER);
110 des_cblock key;
111 des_key_schedule ks;
44d12d58 112 char *bp = buf;
113 int len;
5eaef520 114 char crypt_src[1024];
115
116 memcpy(bp, &version, sizeof(int));
117 bp += sizeof(int);
118 seq_no++;
119 memcpy(bp, &seq_no, sizeof(int));
120
121 bp += sizeof(int);
122
123 memcpy(bp, &call, sizeof(int));
124
125 bp += sizeof(int);
126
127 strcpy(bp, first);
128 bp += strlen(bp) + 1;
129
130 strcpy(bp, last);
131 bp += strlen(bp) + 1;
132
133 len = strlen(idnumber) + 1;
134 memcpy(crypt_src, idnumber, len);
135
136 memcpy(crypt_src + len, hashidnumber, 13);
137
138 des_string_to_key(hashidnumber, key);
139 des_key_sched(key, ks);
140 des_pcbc_encrypt(crypt_src, bp, len + 13, ks, key, DES_ENCRYPT);
141 bp += len + 14 + 8;
142 len = bp - buf;
143 return do_call(buf, len, seq_no, login);
6e6374cb 144}
145
5eaef520 146int do_operation(char *first, char *last, char *idnumber, char *hashidnumber,
147 char *data, u_long opcode)
6e6374cb 148{
5eaef520 149 char buf[1024];
150 int version = ntohl((u_long)1);
151 int call = ntohl(opcode);
152 des_cblock key;
153 des_key_schedule ks;
44d12d58 154 char *bp = buf;
155 int len;
5eaef520 156
157 char crypt_src[1024];
158 char *cbp;
159
160 memcpy(bp, &version, sizeof(int));
161 bp += sizeof(int);
162 seq_no++;
163 memcpy(bp, &seq_no, sizeof(int));
164
165 bp += sizeof(int);
166
167 memcpy(bp, &call, sizeof(int));
168
169 bp += sizeof(int);
170
171 strcpy(bp, first);
172 bp += strlen(bp) + 1;
173
174 strcpy(bp, last);
175 bp += strlen(bp) + 1;
6e6374cb 176
5eaef520 177 len = strlen(idnumber) + 1;
178 cbp = crypt_src;
179
180 memcpy(crypt_src, idnumber, len);
181 cbp += len;
182
183 memcpy(cbp, hashidnumber, 14);
184 cbp += 14;
185
186 len = strlen(data) + 1;
187 memcpy(cbp, data, len);
188 cbp += len;
189
190 len = cbp - crypt_src;
191 des_string_to_key(hashidnumber, key);
192 des_key_sched(key, ks);
193 des_pcbc_encrypt(crypt_src, bp, len, ks, key, 1);
194 len = ((len + 7) >> 3) << 3;
195 bp += len;
196
197 len = bp - buf;
198 return do_call(buf, len, seq_no, 0);
6e6374cb 199}
200
5eaef520 201int grab_login(char *first, char *last, char *idnumber, char *hashidnumber,
202 char *login)
6e6374cb 203{
5eaef520 204 return do_operation(first, last, idnumber, hashidnumber, login,
205 UREG_RESERVE_LOGIN);
5dee7862 206}
6e6374cb 207
5eaef520 208int enroll_login(char *first, char *last, char *idnumber, char *hashidnumber,
209 char *login)
5dee7862 210{
5eaef520 211 return do_operation(first, last, idnumber, hashidnumber, login,
212 UREG_SET_IDENT);
5dee7862 213}
6e6374cb 214
5eaef520 215int set_password(char *first, char *last, char *idnumber, char *hashidnumber,
216 char *password)
5dee7862 217{
5eaef520 218 return do_operation(first, last, idnumber, hashidnumber, password,
219 UREG_SET_PASSWORD);
5dee7862 220}
6e6374cb 221
5eaef520 222int get_krb(char *first, char *last, char *idnumber, char *hashidnumber,
223 char *password)
5dee7862 224{
5eaef520 225 return do_operation(first, last, idnumber, hashidnumber, password,
226 UREG_GET_KRB);
6e6374cb 227}
228
b7ed754f 229
230/* The handles the operations for secure passwords.
8de2273d 231 * To find out if a user has a secure instance, the newpasswd
232 * field is ignored (but must be a valid char *)
b7ed754f 233 * and the opcode = UREG_GET_SECURE need to be specified (but the
234 * other strings must be valid char*'s). This will return
235 * UREG_ALREADY_REGISTERED if it is set, or SUCCESS if not.
236 * To set the password, fill in the rest of the fields, and
237 * use opcode = UREG_SET_SECURE. This returns SUCCESS or any number
238 * of failure codes.
239 */
240
5eaef520 241int do_secure_operation(char *login, char *idnumber, char *passwd,
242 char *newpasswd, u_long opcode)
b7ed754f 243{
5eaef520 244 char buf[1500], data[128], tktstring[128];
245 int version = ntohl((u_long)1);
246 int call = ntohl(opcode);
247 char inst[INST_SZ], hosti[INST_SZ];
248 char *bp = buf, *src, *dst, *realm;
249 int len, status, i;
250 KTEXT_ST cred;
251 CREDENTIALS creds;
252 Key_schedule keys;
253 char *krb_get_phost(), *krb_realmofhost();
254
255 memmove(bp, &version, sizeof(int));
256 bp += sizeof(int);
257 seq_no++;
258 memmove(bp, &seq_no, sizeof(int));
259
260 bp += sizeof(int);
261 memmove(bp, &call, sizeof(int));
262
263 bp += sizeof(int);
264
265 /* put the login name in the firstname field */
266 strcpy(bp, login);
267 bp += strlen(bp) + 1;
268
269 /* the old lastname field */
270 strcpy(bp, "");
271 bp += strlen(bp) + 1;
272
273 /* don't overwrite existing ticket file */
274 sprintf(tktstring, "/tmp/tkt_cpw_%d", getpid());
275 krb_set_tkt_string(tktstring);
276
277 /* get realm and canonizalized hostname of server */
278 realm = krb_realmofhost(host);
279 for (src = host, dst = hosti; *src && *src != '.'; src++)
280 {
b7ed754f 281 if (isupper(*src))
282 *dst++ = tolower(*src);
283 else
284 *dst++ = *src;
b7ed754f 285 }
5eaef520 286 *dst = '\0';
287 inst[0] = '\0';
288
289 /* get changepw tickets. We use this service because it's the
290 * only one that guarantees we used the password rather than a
291 * ticket granting ticket.
292 */
293 status = krb_get_pw_in_tkt(login, inst, realm, "changepw", hosti, 5, passwd);
294 if (status)
295 return status + krb_err_base;
296
297 status = krb_mk_req(&cred, "changepw", hosti, realm, 0);
298 if (status)
299 return status + krb_err_base;
300
301 /* round up to word boundry */
302 bp = (char *)((((u_long)bp) + 3) & 0xfffffffc);
303
304 /* put the ticket in the packet */
305 len = cred.length;
306 cred.length = htonl(cred.length);
307 memmove(bp, &(cred), sizeof(int) + len);
308 bp += sizeof(int) + len;
309
310 /* encrypt the data in the session key */
311 sprintf(data, "%s,%s", idnumber, newpasswd);
312 len = strlen(data);
313 len = ((len + 7) >> 3) << 3;
314
315 status = krb_get_cred("changepw", hosti, realm, &creds);
316 if (status)
317 {
318 memset(data, 0, strlen(data));
319 return status + krb_err_base;
320 }
321 dest_tkt();
b7ed754f 322
5eaef520 323 des_key_sched(creds.session, keys);
324 des_pcbc_encrypt(data, bp + sizeof(int), len, keys, creds.session, 1);
325 *((int *)bp) = htonl(len);
326 memset(data, 0, strlen(data));
b7ed754f 327
5eaef520 328 bp += len + sizeof(int);
b7ed754f 329
5eaef520 330 len = bp - buf;
331 return do_call(buf, len, seq_no, 0);
b7ed754f 332}
333
5eaef520 334int do_call(char *buf, int len, int seq_no, char *login)
6e6374cb 335{
5eaef520 336 struct timeval timeout;
337 char ibuf[1024];
338 fd_set set;
339
340 int retry = 0;
341
342 do
343 {
344 if (write(reg_sock, buf, len) != len)
345 return errno;
346
347 FD_ZERO(&set);
348 FD_SET(reg_sock, &set);
349 timeout.tv_sec = 30;
350 timeout.tv_usec = 0;
351 do
352 {
353 int rtn;
354 struct sockaddr_in s_in;
355 int addrlen = sizeof(s_in);
356 int vno;
357 int sno;
358 int stat;
359
360 rtn = select(reg_sock + 1, &set, NULL, NULL, &timeout);
361 if (rtn == 0)
362 break;
363 else if (rtn < 0)
364 return errno;
365
366 len = recvfrom(reg_sock, ibuf, BUFSIZ, 0,
367 (struct sockaddr *)&s_in, &addrlen);
368 if (len < 0)
369 return errno;
370 if (len < 12)
371 return UREG_BROKEN_PACKET;
372 memcpy(&vno, ibuf, sizeof(long));
373 vno = ntohl((u_long)vno);
374 if (vno != 1)
375 continue;
376 memcpy(&sno, ibuf + 4, sizeof(long));
377
378 if (sno != seq_no)
379 continue;
380
381 memcpy(&stat, ibuf + 8, sizeof(long));
382 stat = ntohl((u_long)stat);
383 if (login && len > 12)
384 {
385 memcpy(login, ibuf + 12, len - 12);
386 login[len - 12] = '\0';
387 }
388 else if (login)
389 *login = '\0';
390 return stat;
391 }
392 while (1);
393 }
394 while (++retry < 10);
395 return ETIMEDOUT;
396}
This page took 0.150917 seconds and 5 git commands to generate.