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