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