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