]> andersk Git - moira.git/blame - regtape/common.pc
Add sponsor_type/sponsor_id column to users table, and client support for manipulatin...
[moira.git] / regtape / common.pc
CommitLineData
f0df8832 1/* $Id$
2 *
3 * Staff/Student load common code
4 *
5 * Copyright (C) 1999 by the Massachusetts Institute of Technology
6 * For copying and distribution information, please see the file
7 * <mit-copyright.h>.
8 */
9
10#include <mit-copyright.h>
11#include <moira.h>
12#include <moira_site.h>
13#include <moira_schema.h>
14#include "common.h"
15
16#include <ctype.h>
17#include <string.h>
18
19EXEC SQL INCLUDE sqlca;
20extern void sqlglm(char *, unsigned int *, unsigned int *);
21
22RCSID("$Header$");
23
24EXEC SQL BEGIN DECLARE SECTION;
25extern char *prog;
26extern int who;
27EXEC SQL END DECLARE SECTION;
28
29extern char *whoami;
30
31#define MIN_ID_VALUE 100
4f15c8b6 32#define MAX_ID_VALUE 131072
f0df8832 33
34/* Remove non-digits from a phone number. */
35void fixphone(char *phone)
36{
37 char *d = phone;
38
39 while (*phone)
40 {
41 if (isdigit(*phone))
42 *d++ = *phone;
43 phone++;
44 }
45 *d = '\0';
46}
47
48/* Remove characters from address that aren't safe for passwd files. */
49void fixaddress(char *address)
50{
51 char *p;
52
53 while ((p = strchr(address, ',')))
54 *p = ';';
55 while ((p = strchr(address, ':')))
56 *p = ';';
57}
58
59void process_entry(struct entry *e, int secure)
60{
61 int changed;
62 char buf[MAX_FIELD_WIDTH], *from, *to;
63 EXEC SQL BEGIN DECLARE SECTION;
64 char *first, *last, *middle, *sid;
65 char *name = e->name, *xtitle = e->xtitle, *xaddr = e->xaddress;
66 char *xphone1 = e->xphone1, *xphone2 = e->xphone2;
67 char type[USERS_TYPE_SIZE], oaddr[USERS_OFFICE_ADDR_SIZE];
68 char ophone[USERS_OFFICE_PHONE_SIZE], dept[USERS_DEPARTMENT_SIZE];
69 char haddr[USERS_HOME_ADDR_SIZE], hphone[USERS_HOME_PHONE_SIZE];
70 char dfirst[USERS_FIRST_SIZE], dlast[USERS_LAST_SIZE];
7902e669 71 char dmiddle[USERS_MIDDLE_SIZE], fullname[USERS_FULLNAME_SIZE];
f0df8832 72 int id, status, fmodby, xnlen = USERS_XNAME_SIZE - 1;
73 EXEC SQL END DECLARE SECTION;
74
75 sid = e->id;
76 last = e->last;
77 if (strlen(last) > USERS_LAST_SIZE - 1)
78 last[USERS_LAST_SIZE - 1] = '\0';
79 first = e->first;
80 if (strlen(first) > USERS_FIRST_SIZE - 1)
81 first[USERS_FIRST_SIZE - 1] = '\0';
82 middle = e->middle;
83 if (strlen(middle) > USERS_MIDDLE_SIZE - 1)
84 middle[USERS_MIDDLE_SIZE - 1] = '\0';
85 id = 0;
86
87 /* Get user info */
88 EXEC SQL SELECT users_id, first, last, middle, type, office_addr,
7902e669 89 office_phone, home_addr, home_phone, fullname, department, status, fmodby
f0df8832 90 INTO :id, :dfirst, :dlast, :dmiddle, :type, :oaddr,
7902e669 91 :ophone, :haddr, :hphone, :fullname, :dept, :status, :fmodby
f0df8832 92 FROM users
93 WHERE clearid = :sid AND status != 3;
94 if (sqlfail())
95 {
96 if (sqlca.sqlcode == SQL_DUPLICATE)
97 {
98 com_err(whoami, 0, "duplicate ID number %s on user %s %s",
99 sid, first, last);
100 return;
101 }
102 else
103 sqlexit();
104 }
105 if (id == 0)
106 {
107 newuser(e, secure);
108 return;
109 }
110 strtrim(dfirst);
111 strtrim(dlast);
112 strtrim(dmiddle);
113 strtrim(type);
114
115 /* Update type/state if necessary. (Exclude several spacial cases.) */
116 if (strcmp(e->type, type) &&
117 strcmp(type, "STAFF") && strcmp(type, "SIPBMEM") &&
118 strcmp(type, "KNIGHT"))
119 {
120 com_err(whoami, 0, "updating type for %s %s from \"%s\" to \"%s\"",
121 first, last, type, e->type);
122 if (status == US_NOT_ALLOWED)
123 status = US_NO_LOGIN_YET;
124 else if (status == US_ENROLL_NOT_ALLOWED)
125 status = US_ENROLLED;
126 strcpy(type, e->type);
127 EXEC SQL UPDATE users
128 SET type = NVL(:type, CHR(0)), status = :status,
129 modtime = SYSDATE, modby = :who, modwith = :prog
130 WHERE users_id = :id;
131 if (sqlca.sqlcode)
132 {
133 dbmserr("updating user", sqlca.sqlcode);
134 exit(1);
135 }
136 }
137
138 /* Update name if necessary */
139 if (strcmp(first, dfirst) || strcmp(last, dlast) || strcmp(middle, dmiddle))
140 {
141 com_err(whoami, 0, "updating real name for %s%s%s %s (was %s%s%s %s)",
142 first, *middle ? " " : "", middle, last,
143 dfirst, *dmiddle ? " " : "", dmiddle, dlast);
144 EXEC SQL UPDATE users
145 SET first = NVL(:first, CHR(0)), last = NVL(:last, CHR(0)),
146 middle = NVL(:middle, CHR(0)), modby = :who, modwith = :prog,
147 modtime = SYSDATE
148 WHERE users_id = :id;
149 if (sqlca.sqlcode)
150 {
151 dbmserr("updating name", sqlca.sqlcode);
152 exit(1);
153 }
154 }
155
156 /* Update finger info fields if they have changed and the user
157 * didn't set them blank.
158 */
159 changed = 0;
160
161 if (strncmp(strtrim(oaddr), e->oaddr, USERS_OFFICE_ADDR_SIZE - 1) &&
162 (*oaddr || fmodby != id))
163 {
164 changed++;
165 com_err(whoami, 0, "office for %s %s changed from \"%s\" to \"%s\"",
166 first, last, oaddr, e->oaddr);
167 strlcpy(oaddr, e->oaddr, USERS_OFFICE_ADDR_SIZE);
168 }
169
170 if (strncmp(strtrim(ophone), e->ophone, USERS_OFFICE_PHONE_SIZE - 1) &&
171 (*ophone || fmodby != id))
172 {
173 changed++;
174 com_err(whoami, 0, "Phone for %s %s changed from \"%s\" to \"%s\"",
175 first, last, ophone, e->ophone);
176 strlcpy(ophone, e->ophone, USERS_OFFICE_PHONE_SIZE);
177 }
178
179 if (strncmp(strtrim(haddr), e->haddr, USERS_HOME_ADDR_SIZE - 1) &&
180 (*haddr || fmodby != id))
181 {
182 changed++;
183 com_err(whoami, 0, "home addr for %s %s changed from \"%s\" to \"%s\"",
184 first, last, haddr, e->haddr);
185 strlcpy(haddr, e->haddr, USERS_HOME_ADDR_SIZE);
186 }
187
188 if (strncmp(strtrim(hphone), e->hphone, USERS_HOME_PHONE_SIZE - 1) &&
189 (*hphone || fmodby != id))
190 {
191 changed++;
192 com_err(whoami, 0, "Phone for %s %s changed from \"%s\" to \"%s\"",
193 first, last, hphone, e->hphone);
194 strlcpy(hphone, e->hphone, USERS_HOME_PHONE_SIZE);
195 }
196
197 if (strncmp(strtrim(dept), e->dept, USERS_DEPARTMENT_SIZE - 1) &&
198 (*dept || fmodby != id))
199 {
200 changed++;
201 com_err(whoami, 0, "Department for %s %s changed from \"%s\" to \"%s\"",
202 first, last, dept, e->dept);
203 strlcpy(dept, e->dept, USERS_DEPARTMENT_SIZE);
204 }
205
7902e669 206 if (strncmp(strtrim(fullname), e->name, USERS_FULLNAME_SIZE - 1) &&
207 (*fullname || fmodby != id))
208 {
209 changed++;
210 com_err(whoami, 0, "Fullname for %s %s changed from \"%s\" to \"%s\"",
211 first, last, fullname, e->name);
212 strlcpy(fullname, e->name, USERS_FULLNAME_SIZE);
213 }
214
f0df8832 215 if (changed)
216 {
217 com_err(whoami, 0, "updating finger for %s %s", first, last);
218 EXEC SQL UPDATE users
219 SET office_addr = NVL(:oaddr, CHR(0)),
220 office_phone = NVL(:ophone, CHR(0)), home_addr = NVL(:haddr, CHR(0)),
221 home_phone = NVL(:hphone, CHR(0)), department = NVL(:dept, CHR(0)),
7902e669 222 fullname = NVL(:fullname, CHR(0)), fmodtime = SYSDATE, fmodby = :who,
223 fmodwith = :prog, xname = NVL(SUBSTR(:name, 0, :xnlen), CHR(0)),
f0df8832 224 xdept = NVL(:dept, CHR(0)), xtitle = NVL(:xtitle, CHR(0)),
225 xaddress = NVL(:xaddr, CHR(0)), xphone1 = NVL(:xphone1, CHR(0)),
226 xphone2 = NVL(:xphone2, CHR(0)), xmodtime = SYSDATE
227 WHERE users_id = :id;
228 if (sqlca.sqlcode)
229 {
230 dbmserr(NULL, sqlca.sqlcode);
231 exit(1);
232 }
233 }
234 else
235 {
236 EXEC SQL UPDATE users
237 SET xname = NVL(SUBSTR(:name, 0, :xnlen), CHR(0)),
238 xdept = NVL(:dept, CHR(0)), xtitle = NVL(:xtitle, CHR(0)),
239 xaddress = NVL(:xaddr, CHR(0)), xphone1 = NVL(:xphone1, CHR(0)),
240 xphone2 = NVL(:xphone2, CHR(0)), xmodtime = SYSDATE
241 WHERE users_id = :id;
242 if (sqlca.sqlcode)
243 {
244 dbmserr(NULL, sqlca.sqlcode);
245 exit(1);
246 }
247 }
248}
249
250void newuser(struct entry *e, int secure)
251{
252 EXEC SQL BEGIN DECLARE SECTION;
253 int issecure = secure, users_id, uid, st, xnlen = USERS_XNAME_SIZE - 1;
254 int oadlen = USERS_OFFICE_ADDR_SIZE - 1;
255 int ophlen = USERS_OFFICE_PHONE_SIZE - 1;
256 char login[USERS_LOGIN_SIZE];
257 char *id, *last, *first, *middle, *type;
258 char *name, *dept, *haddr, *hphone, *oaddr, *ophone;
259 char *xtitle, *xaddress, *xphone1, *xphone2;
260 EXEC SQL END DECLARE SECTION;
261
262 users_id = set_next_users_id();
263 uid = set_next_uid();
44a2baf1 264 sprintf(login, "#%d", uid);
e9e7acde 265 if (!strcmp(e->type, "LINCOLN"))
44a2baf1 266 st = US_NO_LOGIN_YET_KERBEROS_ONLY;
e9e7acde 267 else
44a2baf1 268 st = US_NO_LOGIN_YET;
f0df8832 269 last = e->last;
270 first = e->first;
271 middle = e->middle;
272 id = e->id;
273 type = e->type;
274 name = e->name;
275 dept = e->dept;
276 haddr = e->haddr;
277 hphone = e->hphone;
278 oaddr = e->oaddr;
279 ophone = e->ophone;
280 xtitle = e->xtitle;
281 xaddress = e->xaddress;
282 xphone1 = e->xphone1;
283 xphone2 = e->xphone2;
284
285 com_err(whoami, 0, "adding user %s %s", e->first, e->last);
286
287 EXEC SQL INSERT INTO users
288 (login, users_id, unix_uid, shell, winconsoleshell, last, first,
289 middle, status, clearid, type, modtime, modby, modwith, fullname,
290 department, home_addr, home_phone, office_addr, office_phone, fmodtime,
291 fmodby, fmodwith, potype, pmodtime, pmodby, pmodwith,
7ba40987 292 xname, xdept, xtitle, xaddress, xphone1, xphone2, xmodtime, secure,
7902e669 293 created, creator, winhomedir, winprofiledir, sponsor_type, sponsor_id)
f0df8832 294 VALUES (:login, :users_id, :uid, '/bin/athena/tcsh', 'cmd',
295 NVL(:last, CHR(0)), NVL(:first, CHR(0)), NVL(:middle, CHR(0)),
296 :st, NVL(:id, CHR(0)), NVL(:type, CHR(0)), SYSDATE, :who, :prog,
297 NVL(:name, CHR(0)), NVL(:dept, CHR(0)), NVL(:haddr, CHR(0)),
298 NVL(:hphone, CHR(0)), NVL(SUBSTR(:oaddr, 0, :oadlen), CHR(0)),
299 NVL(SUBSTR(:ophone, 0, :ophlen), CHR(0)), SYSDATE, :who, :prog,
300 'NONE', SYSDATE, :who, :prog,
301 NVL(SUBSTR(:name, 0, :xnlen), CHR(0)), NVL(:dept, CHR(0)),
302 NVL(:xtitle, CHR(0)), NVL(:xaddress, CHR(0)),
7ba40987 303 NVL(:xphone1, CHR(0)), NVL(:xphone2, CHR(0)), SYSDATE, :issecure,
7902e669 304 SYSDATE, :who, '[DFS]', '[DFS]', 'NONE', 0);
f0df8832 305 if (sqlca.sqlcode)
306 {
307 dbmserr("adding user", sqlca.sqlcode);
308 exit(1);
309 }
310}
311
312int set_next_users_id(void)
313{
314 EXEC SQL BEGIN DECLARE SECTION;
315 int flag, value, retval;
316 EXEC SQL END DECLARE SECTION;
317
318 EXEC SQL SELECT value INTO :value FROM numvalues
319 WHERE name = 'users_id';
320 if (sqlfail())
321 sqlexit();
322 if (sqlca.sqlerrd[2] != 1)
323 {
324 EXEC SQL ROLLBACK;
325 com_err(whoami, MR_INTERNAL, "values table inconsistancy");
326 exit(1);
327 }
328
329 flag = 0;
330 EXEC SQL SELECT users_id INTO :flag FROM users
331 WHERE users_id = :value;
332 if (sqlfail())
333 sqlexit();
334 if (sqlca.sqlerrd[2] == 0)
335 flag = 0;
336 while (flag)
337 {
338 value++;
339 flag = 0;
340 EXEC SQL SELECT users_id INTO :flag FROM users
341 WHERE users_id = :value;
342 if (sqlfail())
343 sqlexit();
344 if (sqlca.sqlerrd[2] == 0)
345 flag = 0;
346 }
347
348 retval = value++;
349 EXEC SQL UPDATE numvalues SET value = :value
350 WHERE name = 'users_id';
351 if (sqlca.sqlcode)
352 {
353 dbmserr("assigning ID", sqlca.sqlcode);
354 exit(1);
355 }
356 return retval;
357}
358
359int set_next_uid(void)
360{
361 EXEC SQL BEGIN DECLARE SECTION;
362 int flag, initial, value, retval;
363 EXEC SQL END DECLARE SECTION;
364
365 EXEC SQL SELECT value INTO :initial FROM numvalues
366 WHERE name = 'unix_uid';
367 if (sqlfail())
368 sqlexit();
369 if (sqlca.sqlerrd[2] != 1)
370 {
371 EXEC SQL ROLLBACK;
372 com_err(whoami, MR_INTERNAL, "values table inconsistancy");
373 exit(1);
374 }
375
376 value = initial;
377 flag = 0;
378 EXEC SQL SELECT COUNT(unix_uid) INTO :flag
379 FROM users WHERE unix_uid = :value;
380 if (sqlfail())
381 sqlexit();
382 if (sqlca.sqlerrd[2] == 0)
383 flag = 0;
384 while (flag)
385 {
386 value++;
387#ifdef ULTRIX_ID_HOLE
388 if (value > 31999 && value < 32768)
389 value = 32768;
390#endif
391 if (value > MAX_ID_VALUE)
392 value = MIN_ID_VALUE;
393 if (value == initial)
394 {
395 com_err(whoami, 0, "Out of uids!");
396 EXEC SQL ROLLBACK WORK;
397 exit(1);
398 }
399 flag = 0;
400 EXEC SQL SELECT COUNT(unix_uid) INTO :flag
401 FROM users WHERE unix_uid = :value;
402 if (sqlfail())
403 sqlexit();
404 }
405
406 retval = value++;
407 if (value > MAX_ID_VALUE)
408 value = MIN_ID_VALUE;
409 EXEC SQL UPDATE numvalues SET value = :value WHERE name = 'unix_uid';
410 if (sqlca.sqlcode)
411 {
412 dbmserr("assigning ID", sqlca.sqlcode);
413 exit(1);
414 }
415 return retval;
416}
417
418void sqlexit(void)
419{
420 dbmserr(NULL, sqlca.sqlcode);
421 EXEC SQL ROLLBACK WORK;
422 exit(1);
423}
424
425void dbmserr(char *where, int what)
426{
427 char err_msg[256];
428 int bufsize = 256, msglength = 0;
429
430 sqlglm(err_msg, &bufsize, &msglength);
431 err_msg[msglength] = '\0';
432
433 if (where)
434 com_err(whoami, 0, "DBMS error %swhile %s", err_msg, where);
435 else
436 com_err(whoami, 0, "DBMS error %s", err_msg);
437}
This page took 0.115237 seconds and 5 git commands to generate.