]>
Commit | Line | Data |
---|---|---|
7ac48069 | 1 | /* $Id$ |
73cf66ba | 2 | * |
7ac48069 | 3 | * Query followup routines |
4 | * | |
5 | * Copyright (C) 1987-1998 by the Massachusetts Institute of Technology | |
6 | * For copying and distribution information, please see the file | |
7 | * <mit-copyright.h>. | |
73cf66ba | 8 | * |
9 | */ | |
10 | ||
73cf66ba | 11 | #include <mit-copyright.h> |
73cf66ba | 12 | #include "mr_server.h" |
03c05291 | 13 | #include "query.h" |
7ac48069 | 14 | #include "qrtn.h" |
15 | ||
85330553 | 16 | #include <errno.h> |
73cf66ba | 17 | #include <ctype.h> |
7ac48069 | 18 | #include <stdlib.h> |
03c05291 | 19 | #include <string.h> |
73cf66ba | 20 | #ifdef GDSS |
21 | #include "gdss.h" | |
22 | #endif /* GDSS */ | |
7ac48069 | 23 | |
73cf66ba | 24 | EXEC SQL INCLUDE sqlca; |
7ac48069 | 25 | |
26 | RCSID("$Header$"); | |
73cf66ba | 27 | |
03c05291 | 28 | extern char *whoami, *table_name[]; |
29 | extern int dbms_errno, mr_errcode; | |
73cf66ba | 30 | |
31 | EXEC SQL BEGIN DECLARE SECTION; | |
32 | extern char stmt_buf[]; | |
33 | EXEC SQL END DECLARE SECTION; | |
34 | ||
03c05291 | 35 | EXEC SQL WHENEVER SQLERROR DO dbmserr(); |
73cf66ba | 36 | |
37 | ||
38 | /* FOLLOWUP ROUTINES */ | |
39 | ||
03c05291 | 40 | /* generic set_modtime routine. This takes the table id from the query, |
73cf66ba | 41 | * and will update the modtime, modby, and modwho fields in the entry in |
42 | * the table whose name field matches argv[0]. | |
43 | */ | |
44 | ||
5eaef520 | 45 | int set_modtime(struct query *q, char *argv[], client *cl) |
73cf66ba | 46 | { |
5eaef520 | 47 | char *name, *entity, *table; |
48 | int who; | |
73cf66ba | 49 | |
5eaef520 | 50 | entity = cl->entity; |
51 | who = cl->client_id; | |
52 | table = table_name[q->rtable]; | |
53 | name = argv[0]; | |
73cf66ba | 54 | |
5eaef520 | 55 | sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, " |
56 | "modwith = '%s' WHERE name = '%s'", table, who, entity, name); | |
57 | EXEC SQL EXECUTE IMMEDIATE :stmt_buf; | |
73cf66ba | 58 | |
5eaef520 | 59 | return MR_SUCCESS; |
73cf66ba | 60 | } |
61 | ||
03c05291 | 62 | /* generic set_modtime_by_id routine. This takes the table id from |
73cf66ba | 63 | * the query, and the id name from the validate record, |
64 | * and will update the modtime, modby, and modwho fields in the entry in | |
65 | * the table whose id matches argv[0]. | |
66 | */ | |
67 | ||
5eaef520 | 68 | int set_modtime_by_id(struct query *q, char *argv[], client *cl) |
73cf66ba | 69 | { |
5eaef520 | 70 | char *entity, *table, *id_name; |
71 | int who, id; | |
72 | ||
73 | entity = cl->entity; | |
74 | who = cl->client_id; | |
75 | table = table_name[q->rtable]; | |
76 | id_name = q->validate->object_id; | |
77 | ||
78 | id = *(int *)argv[0]; | |
79 | sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, " | |
80 | "modwith = '%s' WHERE %s = %d", table, who, entity, id_name, id); | |
81 | EXEC SQL EXECUTE IMMEDIATE :stmt_buf; | |
82 | return MR_SUCCESS; | |
73cf66ba | 83 | } |
84 | ||
85 | ||
86 | /* Sets the finger modtime on a user record. The users_id will be in argv[0]. | |
87 | */ | |
88 | ||
5eaef520 | 89 | int set_finger_modtime(struct query *q, char *argv[], client *cl) |
73cf66ba | 90 | { |
5eaef520 | 91 | EXEC SQL BEGIN DECLARE SECTION; |
92 | int users_id, who; | |
93 | char *entity; | |
94 | EXEC SQL END DECLARE SECTION; | |
73cf66ba | 95 | |
5eaef520 | 96 | entity = cl->entity; |
97 | who = cl->client_id; | |
98 | users_id = *(int *)argv[0]; | |
73cf66ba | 99 | |
5eaef520 | 100 | EXEC SQL UPDATE users SET fmodtime = SYSDATE, fmodby = :who, |
101 | fmodwith = :entity WHERE users_id = :users_id; | |
73cf66ba | 102 | |
5eaef520 | 103 | return MR_SUCCESS; |
73cf66ba | 104 | } |
105 | ||
106 | ||
107 | /* Sets the pobox modtime on a user record. The users_id will be in argv[0]. | |
108 | */ | |
109 | ||
5eaef520 | 110 | int set_pobox_modtime(struct query *q, char *argv[], client *cl) |
73cf66ba | 111 | { |
5eaef520 | 112 | EXEC SQL BEGIN DECLARE SECTION; |
113 | int users_id, who; | |
114 | char *entity; | |
115 | EXEC SQL END DECLARE SECTION; | |
73cf66ba | 116 | |
5eaef520 | 117 | entity = cl->entity; |
118 | who = cl->client_id; | |
119 | users_id = *(int *)argv[0]; | |
73cf66ba | 120 | |
5eaef520 | 121 | EXEC SQL UPDATE users SET pmodtime = SYSDATE, pmodby = :who, |
122 | pmodwith = :entity WHERE users_id = :users_id; | |
73cf66ba | 123 | |
5eaef520 | 124 | return MR_SUCCESS; |
73cf66ba | 125 | } |
126 | ||
127 | ||
128 | /* Like set_modtime, but uppercases the name first. | |
129 | */ | |
130 | ||
5eaef520 | 131 | int set_uppercase_modtime(struct query *q, char *argv[], client *cl) |
73cf66ba | 132 | { |
5eaef520 | 133 | char *name, *entity, *table; |
134 | int who; | |
73cf66ba | 135 | |
5eaef520 | 136 | entity = cl->entity; |
137 | who = cl->client_id; | |
138 | table = table_name[q->rtable]; | |
139 | name = argv[0]; | |
73cf66ba | 140 | |
5eaef520 | 141 | sprintf(stmt_buf, "UPDATE %s SET modtime = SYSDATE, modby = %d, " |
142 | "modwith = '%s' WHERE name = UPPER('%s')", table, who, entity, name); | |
143 | EXEC SQL EXECUTE IMMEDIATE :stmt_buf; | |
73cf66ba | 144 | |
5eaef520 | 145 | return MR_SUCCESS; |
73cf66ba | 146 | } |
147 | ||
148 | ||
149 | /* Sets the modtime on the machine whose mach_id is in argv[0]. This routine | |
150 | * is necessary for add_machine_to_cluster becuase the table that query | |
151 | * operates on is "mcm", not "machine". | |
152 | */ | |
153 | ||
5eaef520 | 154 | int set_mach_modtime_by_id(struct query *q, char *argv[], client *cl) |
73cf66ba | 155 | { |
5eaef520 | 156 | EXEC SQL BEGIN DECLARE SECTION; |
157 | char *entity; | |
158 | int who, id; | |
159 | EXEC SQL END DECLARE SECTION; | |
160 | ||
161 | entity = cl->entity; | |
162 | who = cl->client_id; | |
163 | id = *(int *)argv[0]; | |
164 | EXEC SQL UPDATE machine SET modtime = SYSDATE, modby = :who, | |
165 | modwith = :entity WHERE mach_id = :id; | |
166 | ||
167 | return MR_SUCCESS; | |
73cf66ba | 168 | } |
169 | ||
170 | ||
171 | /* Sets the modtime on the cluster whose mach_id is in argv[0]. This routine | |
172 | * is necessary for add_cluster_data and delete_cluster_data becuase the | |
173 | * table that query operates on is "svc", not "cluster". | |
174 | */ | |
175 | ||
5eaef520 | 176 | int set_cluster_modtime_by_id(struct query *q, char *argv[], client *cl) |
73cf66ba | 177 | { |
5eaef520 | 178 | EXEC SQL BEGIN DECLARE SECTION; |
179 | char *entity; | |
180 | int who, id; | |
181 | EXEC SQL END DECLARE SECTION; | |
182 | ||
183 | entity = cl->entity; | |
184 | who = cl->client_id; | |
185 | ||
186 | id = *(int *)argv[0]; | |
187 | EXEC SQL UPDATE clusters SET modtime = SYSDATE, modby = :who, | |
188 | modwith = :entity WHERE clu_id = :id; | |
189 | return MR_SUCCESS; | |
73cf66ba | 190 | } |
191 | ||
192 | ||
193 | /* sets the modtime on the serverhost where the service name is in argv[0] | |
194 | * and the mach_id is in argv[1]. | |
195 | */ | |
196 | ||
5eaef520 | 197 | int set_serverhost_modtime(struct query *q, char *argv[], client *cl) |
73cf66ba | 198 | { |
5eaef520 | 199 | EXEC SQL BEGIN DECLARE SECTION; |
200 | char *entity, *serv; | |
201 | int who, id; | |
202 | EXEC SQL END DECLARE SECTION; | |
203 | ||
204 | entity = cl->entity; | |
205 | who = cl->client_id; | |
206 | ||
207 | serv = argv[0]; | |
208 | id = *(int *)argv[1]; | |
209 | EXEC SQL UPDATE serverhosts | |
210 | SET modtime = SYSDATE, modby = :who, modwith = :entity | |
211 | WHERE service = :serv AND mach_id = :id; | |
212 | return MR_SUCCESS; | |
73cf66ba | 213 | } |
214 | ||
215 | ||
216 | /* sets the modtime on the nfsphys where the mach_id is in argv[0] and the | |
217 | * directory name is in argv[1]. | |
218 | */ | |
219 | ||
5eaef520 | 220 | int set_nfsphys_modtime(struct query *q, char *argv[], client *cl) |
73cf66ba | 221 | { |
5eaef520 | 222 | EXEC SQL BEGIN DECLARE SECTION; |
223 | char *entity, *dir; | |
224 | int who, id; | |
225 | EXEC SQL END DECLARE SECTION; | |
226 | ||
227 | entity = cl->entity; | |
228 | who = cl->client_id; | |
229 | ||
230 | id = *(int *)argv[0]; | |
231 | dir = argv[1]; | |
232 | EXEC SQL UPDATE nfsphys SET modtime = SYSDATE, modby = :who, | |
233 | modwith = :entity WHERE dir = :dir AND mach_id = :id; | |
234 | return MR_SUCCESS; | |
73cf66ba | 235 | } |
236 | ||
237 | ||
238 | /* sets the modtime on a filesystem, where argv[0] contains the filesys | |
239 | * label. | |
240 | */ | |
241 | ||
5eaef520 | 242 | int set_filesys_modtime(struct query *q, char *argv[], client *cl) |
73cf66ba | 243 | { |
5eaef520 | 244 | EXEC SQL BEGIN DECLARE SECTION; |
245 | char *label, *entity; | |
246 | int who; | |
247 | extern int _var_phys_id; | |
248 | EXEC SQL END DECLARE SECTION; | |
249 | ||
250 | entity = cl->entity; | |
251 | who = cl->client_id; | |
252 | ||
253 | label = argv[0]; | |
254 | if (!strcmp(q->shortname, "ufil")) | |
255 | label = argv[1]; | |
256 | ||
257 | EXEC SQL UPDATE filesys SET modtime = SYSDATE, modby = :who, | |
258 | modwith = :entity, phys_id = :_var_phys_id | |
259 | WHERE label = :label; | |
260 | return MR_SUCCESS; | |
73cf66ba | 261 | } |
262 | ||
263 | ||
264 | /* sets the modtime on a zephyr class, where argv[0] contains the class | |
265 | * name. | |
266 | */ | |
267 | ||
5eaef520 | 268 | int set_zephyr_modtime(struct query *q, char *argv[], client *cl) |
73cf66ba | 269 | { |
5eaef520 | 270 | EXEC SQL BEGIN DECLARE SECTION; |
271 | char *class, *entity; | |
272 | int who; | |
273 | EXEC SQL END DECLARE SECTION; | |
73cf66ba | 274 | |
5eaef520 | 275 | entity = cl->entity; |
276 | who = cl->client_id; | |
73cf66ba | 277 | |
5eaef520 | 278 | class = argv[0]; |
73cf66ba | 279 | |
5eaef520 | 280 | EXEC SQL UPDATE zephyr SET modtime = SYSDATE, modby = :who, |
281 | modwith = :entity WHERE class = :class; | |
73cf66ba | 282 | |
5eaef520 | 283 | return MR_SUCCESS; |
73cf66ba | 284 | } |
285 | ||
286 | ||
287 | /* fixes the modby field. This will be the second to last thing in the | |
288 | * argv, the argv length is determined from the query structure. It is | |
289 | * passed as a pointer to an integer. This will either turn it into a | |
290 | * username, or # + the users_id. | |
291 | */ | |
5eaef520 | 292 | int followup_fix_modby(struct query *q, struct save_queue *sq, |
7ac48069 | 293 | struct validate *v, int (*action)(int, char *[], void *), |
294 | void *actarg, client *cl) | |
73cf66ba | 295 | { |
44d12d58 | 296 | int i, j; |
5eaef520 | 297 | char **argv; |
298 | int id, status; | |
299 | ||
300 | i = q->vcnt - 2; | |
301 | while (sq_get_data(sq, &argv)) | |
302 | { | |
303 | id = atoi(argv[i]); | |
304 | if (id > 0) | |
305 | status = id_to_name(id, USERS_TABLE, &argv[i]); | |
306 | else | |
307 | status = id_to_name(-id, STRINGS_TABLE, &argv[i]); | |
308 | if (status && status != MR_NO_MATCH) | |
309 | return status; | |
310 | (*action)(q->vcnt, argv, actarg); | |
311 | for (j = 0; j < q->vcnt; j++) | |
312 | free(argv[j]); | |
313 | free(argv); | |
73cf66ba | 314 | } |
5eaef520 | 315 | sq_destroy(sq); |
316 | return MR_SUCCESS; | |
73cf66ba | 317 | } |
318 | ||
319 | ||
320 | /* After retrieving a user account, fix the modby field and signature. | |
321 | * The modby field is the second to last thing in the | |
322 | * argv, the argv length is determined from the query structure. It is | |
323 | * passed as a pointer to an integer. This will either turn it into a | |
324 | * username, or # + the users_id. Only "gua*" queries have a signature, | |
325 | * these are ones with U_END return values. "gub*" queries also use this | |
326 | * routine but don't have a signature. | |
327 | */ | |
5eaef520 | 328 | int followup_guax(struct query *q, struct save_queue *sq, struct validate *v, |
7ac48069 | 329 | int (*action)(int, char *[], void *), void *actarg, |
330 | client *cl) | |
73cf66ba | 331 | { |
44d12d58 | 332 | int i, j; |
5eaef520 | 333 | char **argv; |
73cf66ba | 334 | #ifdef GDSS |
e688520a | 335 | unsigned char sigbuf[512]; |
5eaef520 | 336 | char *kname; |
337 | SigInfo si; | |
338 | EXEC SQL BEGIN DECLARE SECTION; | |
7ac48069 | 339 | int timestamp, who; |
5eaef520 | 340 | char *login; |
e688520a | 341 | char rsig[USERS_SIGNATURE_SIZE]; |
342 | EXEC SQL VAR rsig IS STRING(USERS_SIGNATURE_SIZE); | |
5eaef520 | 343 | EXEC SQL END DECLARE SECTION; |
73cf66ba | 344 | #endif /* GDSS */ |
5eaef520 | 345 | int id, status; |
346 | ||
347 | i = q->vcnt - 2; | |
348 | while (sq_get_data(sq, &argv)) | |
349 | { | |
350 | id = atoi(argv[i]); | |
351 | if (id > 0) | |
352 | status = id_to_name(id, USERS_TABLE, &argv[i]); | |
353 | else | |
354 | status = id_to_name(-id, STRINGS_TABLE, &argv[i]); | |
355 | if (status && status != MR_NO_MATCH) | |
356 | return status; | |
73cf66ba | 357 | #ifdef GDSS |
5eaef520 | 358 | if (q->vcnt == U_END && strlen(argv[U_SIGNATURE])) |
359 | { | |
360 | login = strtrim(argv[U_NAME]); | |
361 | EXEC SQL SELECT signature, sigdate, sigwho | |
362 | INTO :rsig, :timestamp, :who FROM users | |
363 | WHERE login = :login; | |
364 | if (dbms_errno) | |
365 | return mr_errcode; | |
e688520a | 366 | kname = malloc(0); |
5eaef520 | 367 | status = id_to_name(who, STRINGS_TABLE, &kname); |
368 | si.timestamp = timestamp; | |
369 | si.SigInfoVersion = 0; /* XXXXX this isn't used */ | |
370 | kname_parse(si.pname, si.pinst, si.prealm, kname); | |
371 | free(kname); | |
e688520a | 372 | si.rawsig = (unsigned char *)xstrdup(rsig); |
5eaef520 | 373 | GDSS_Recompose(&si, sigbuf); |
374 | free(si.rawsig); | |
375 | free(argv[U_SIGNATURE]); | |
e688520a | 376 | argv[U_SIGNATURE] = xstrdup(sigbuf); |
73cf66ba | 377 | } |
378 | #endif /* GDSS */ | |
5eaef520 | 379 | (*action)(q->vcnt, argv, actarg); |
380 | for (j = 0; j < q->vcnt; j++) | |
381 | free(argv[j]); | |
382 | free(argv); | |
73cf66ba | 383 | } |
5eaef520 | 384 | sq_destroy(sq); |
385 | return MR_SUCCESS; | |
73cf66ba | 386 | } |
387 | ||
388 | ||
389 | /** | |
390 | ** followup_ausr - add finger and pobox entries, set_user_modtime | |
391 | ** | |
392 | ** Inputs: | |
393 | ** argv[0] - login (add_user) | |
394 | ** argv[3] - last name | |
395 | ** argv[4] - first name | |
396 | ** argv[5] - middle name | |
397 | ** | |
398 | **/ | |
399 | ||
5eaef520 | 400 | int followup_ausr(struct query *q, char *argv[], client *cl) |
73cf66ba | 401 | { |
5eaef520 | 402 | EXEC SQL BEGIN DECLARE SECTION; |
403 | int who, status; | |
404 | char *login, *entity, *name; | |
e688520a | 405 | char fullname[USERS_FIRST_SIZE + USERS_MIDDLE_SIZE + USERS_LAST_SIZE]; |
5eaef520 | 406 | EXEC SQL END DECLARE SECTION; |
73cf66ba | 407 | #ifdef GDSS |
e688520a | 408 | char databuf[USERS_LOGIN_SIZE + USERS_CLEARID_SIZE]; |
5eaef520 | 409 | EXEC SQL BEGIN DECLARE SECTION; |
e688520a | 410 | char rawsig[512]; |
5eaef520 | 411 | int sigwho, timestamp; |
412 | EXEC SQL END DECLARE SECTION; | |
413 | SigInfo si; | |
73cf66ba | 414 | #endif /* GDSS */ |
415 | ||
5eaef520 | 416 | /* build fullname */ |
417 | if (strlen(argv[4]) && strlen(argv[5])) | |
418 | sprintf(fullname, "%s %s %s", argv[4], argv[5], argv[3]); | |
419 | else if (strlen(argv[4])) | |
420 | sprintf(fullname, "%s %s", argv[4], argv[3]); | |
421 | else | |
422 | sprintf(fullname, "%s", argv[3]); | |
73cf66ba | 423 | |
424 | #ifdef GDSS | |
5eaef520 | 425 | if (q->vcnt == U_END && *argv[U_SIGNATURE]) |
426 | { | |
427 | sprintf(databuf, "%s:%s", argv[U_NAME], argv[U_MITID]); | |
428 | /* skip bytes for timestamp & kname */ | |
429 | si.rawsig = (unsigned char *) rawsig; | |
430 | status = GDSS_Verify(databuf, strlen(databuf), argv[U_SIGNATURE], &si); | |
431 | if (strlen(rawsig) > mr_sig_length) | |
432 | { | |
433 | com_err(whoami, 0, "GDSS signature would be truncated."); | |
434 | return MR_INTERNAL; | |
73cf66ba | 435 | } |
5eaef520 | 436 | if (status == 0) |
437 | { | |
438 | name = kname_unparse(si.pname, si.pinst, si.prealm); | |
439 | status = name_to_id(name, STRINGS_TABLE, &sigwho); | |
440 | if (status == MR_NO_MATCH) | |
441 | sigwho = add_string(name); | |
442 | else if (status) | |
443 | return status; | |
444 | timestamp = si.timestamp; | |
445 | } | |
446 | else | |
85330553 | 447 | return gdss2et(status); |
5eaef520 | 448 | } |
449 | else | |
450 | { | |
451 | rawsig[0] = '\0'; | |
452 | sigwho = 0; | |
453 | timestamp = 0; | |
454 | } | |
73cf66ba | 455 | #endif /* GDSS */ |
456 | ||
5eaef520 | 457 | login = argv[0]; |
458 | who = cl->client_id; | |
459 | entity = cl->entity; | |
73cf66ba | 460 | |
5eaef520 | 461 | /* create finger entry, pobox & set modtime on user */ |
73cf66ba | 462 | #ifdef GDSS |
5eaef520 | 463 | EXEC SQL UPDATE users |
464 | SET modtime = SYSDATE, modby = :who, modwith = :entity, | |
465 | fullname = NVL(:fullname, CHR(0)), affiliation = type, | |
466 | signature = NVL(:rawsig, CHR(0)), sigdate = :timestamp, | |
467 | sigwho = :sigwho, fmodtime = SYSDATE, fmodby = :who, | |
468 | fmodwith = :entity, potype = 'NONE', pmodtime = SYSDATE, | |
469 | pmodby = :who, pmodwith = :entity | |
470 | WHERE login = :login; | |
73cf66ba | 471 | #else /* GDSS */ |
5eaef520 | 472 | EXEC SQL UPDATE users |
473 | SET modtime = SYSDATE, modby = :who, modwith = :entity, | |
474 | fullname = NVL(:fullname, CHR(0)), affiliation = type, | |
475 | fmodtime = SYSDATE, fmodby = :who, fmodwith = :entity, | |
476 | potype = 'NONE', pmodtime = SYSDATE, pmodby = :who, pmodwith = :entity | |
477 | WHERE login = :login; | |
73cf66ba | 478 | #endif /* GDSS */ |
479 | ||
5eaef520 | 480 | return MR_SUCCESS; |
73cf66ba | 481 | } |
482 | ||
483 | ||
484 | /** | |
03c05291 | 485 | ** followup_uuac - do signature, set_user_modtime |
73cf66ba | 486 | ** |
487 | ** Inputs: | |
488 | ** argv[0] - login (add_user) | |
489 | ** argv[U_SIGNATURE] - sig | |
490 | ** | |
491 | **/ | |
492 | ||
5eaef520 | 493 | int followup_uuac(struct query *q, char *argv[], client *cl) |
73cf66ba | 494 | { |
5eaef520 | 495 | EXEC SQL BEGIN DECLARE SECTION; |
496 | int who, status, id; | |
497 | char *entity, *name; | |
498 | EXEC SQL END DECLARE SECTION; | |
73cf66ba | 499 | #ifdef GDSS |
e688520a | 500 | char databuf[USERS_LOGIN_SIZE + USERS_CLEARID_SIZE]; |
5eaef520 | 501 | EXEC SQL BEGIN DECLARE SECTION; |
e688520a | 502 | char rawsig[512]; |
5eaef520 | 503 | char *login; |
504 | int sigwho, timestamp; | |
505 | EXEC SQL END DECLARE SECTION; | |
506 | SigInfo si; | |
73cf66ba | 507 | #endif /* GDSS */ |
5eaef520 | 508 | |
509 | id = *(int *)argv[0]; | |
510 | who = cl->client_id; | |
511 | entity = cl->entity; | |
512 | ||
73cf66ba | 513 | #ifdef GDSS |
5eaef520 | 514 | if (q->vcnt == U_MODTIME && *argv[U_SIGNATURE + 1]) |
515 | { | |
e688520a | 516 | login = malloc(0); |
5eaef520 | 517 | status = id_to_name(id, USERS_TABLE, &login); |
518 | sprintf(databuf, "%s:%s", login, argv[U_MITID + 1]); | |
519 | free(login); | |
520 | /* skip bytes for timestamp & kname */ | |
521 | si.rawsig = (unsigned char *) rawsig; | |
522 | status = GDSS_Verify(databuf, strlen(databuf), argv[U_SIGNATURE + 1], | |
523 | &si); | |
524 | if (strlen(rawsig) > mr_sig_length) | |
525 | { | |
526 | com_err(whoami, 0, "GDSS signature would be truncated."); | |
527 | return MR_INTERNAL; | |
73cf66ba | 528 | } |
5eaef520 | 529 | if (status == 0) |
530 | { | |
531 | name = kname_unparse(si.pname, si.pinst, si.prealm); | |
532 | status = name_to_id(name, STRINGS_TABLE, &sigwho); | |
533 | if (status == MR_NO_MATCH) | |
534 | sigwho = add_string(name); | |
535 | else if (status) | |
536 | return status; | |
537 | timestamp = si.timestamp; | |
538 | } | |
539 | else | |
85330553 | 540 | return gdss2et(status); |
5eaef520 | 541 | } |
542 | else | |
543 | { | |
544 | rawsig[0] = '\0'; | |
545 | sigwho = 0; | |
546 | timestamp = 0; | |
73cf66ba | 547 | } |
548 | #endif /* GDSS */ | |
5eaef520 | 549 | |
550 | /* create finger entry, pobox & set modtime on user */ | |
73cf66ba | 551 | |
552 | #ifdef GDSS | |
5eaef520 | 553 | EXEC SQL UPDATE users SET modtime = SYSDATE, modby = :who, modwith = :entity, |
554 | signature = NVL(:rawsig, CHR(0)), sigdate = :timestamp, sigwho = :sigwho | |
555 | WHERE users_id = :id; | |
73cf66ba | 556 | #else /* GDSS */ |
5eaef520 | 557 | EXEC SQL UPDATE users SET modtime = SYSDATE, modby = :who, modwith = :entity |
558 | WHERE users_id = :id; | |
73cf66ba | 559 | #endif /* GDSS */ |
5eaef520 | 560 | return MR_SUCCESS; |
73cf66ba | 561 | } |
5eaef520 | 562 | |
2884200f | 563 | |
73cf66ba | 564 | /* followup_gpob: fixes argv[2] based on the IDs currently there and the |
565 | * type in argv[1]. Then completes the upcall to the user. | |
566 | * | |
567 | * argv[2] is of the form "123:234" where the first integer is the machine | |
568 | * ID if it is a pop box, and the second is the string ID if it is an SMTP | |
569 | * box. argv[1] should be "POP", "SMTP", or "NONE". Boxes of type NONE | |
570 | * are skipped. | |
571 | */ | |
572 | ||
5eaef520 | 573 | int followup_gpob(struct query *q, struct save_queue *sq, struct validate *v, |
7ac48069 | 574 | int (*action)(int, char *[], void *), void *actarg, |
575 | client *cl) | |
73cf66ba | 576 | { |
5eaef520 | 577 | char **argv; |
578 | char *ptype, *p; | |
579 | int mid, sid, status, i; | |
580 | ||
581 | /* for each row */ | |
582 | while (sq_get_data(sq, &argv)) | |
583 | { | |
584 | mr_trim_args(2, argv); | |
585 | ptype = argv[1]; | |
586 | p = strchr(argv[2], ':'); | |
587 | *p++ = '\0'; | |
588 | mid = atoi(argv[2]); | |
589 | sid = atoi(p); | |
590 | ||
591 | if (!strcmp(ptype, "POP")) | |
592 | { | |
593 | status = id_to_name(mid, MACHINE_TABLE, &argv[2]); | |
594 | if (status == MR_NO_MATCH) | |
595 | return MR_MACHINE; | |
596 | } | |
597 | else if (!strcmp(ptype, "SMTP")) | |
598 | { | |
599 | status = id_to_name(sid, STRINGS_TABLE, &argv[2]); | |
600 | if (status == MR_NO_MATCH) | |
601 | return MR_STRING; | |
73cf66ba | 602 | } |
5eaef520 | 603 | else /* ptype == "NONE" */ |
604 | goto skip; | |
605 | if (status) | |
606 | return status; | |
607 | ||
608 | if (!strcmp(q->shortname, "gpob")) | |
609 | { | |
610 | sid = atoi(argv[4]); | |
611 | if (sid > 0) | |
612 | status = id_to_name(sid, USERS_TABLE, &argv[4]); | |
613 | else | |
614 | status = id_to_name(-sid, STRINGS_TABLE, &argv[4]); | |
73cf66ba | 615 | } |
5eaef520 | 616 | if (status && status != MR_NO_MATCH) |
617 | return status; | |
73cf66ba | 618 | |
5eaef520 | 619 | (*action)(q->vcnt, argv, actarg); |
73cf66ba | 620 | skip: |
5eaef520 | 621 | /* free saved data */ |
622 | for (i = 0; i < q->vcnt; i++) | |
623 | free(argv[i]); | |
624 | free(argv); | |
73cf66ba | 625 | } |
626 | ||
5eaef520 | 627 | sq_destroy(sq); |
628 | return MR_SUCCESS; | |
73cf66ba | 629 | } |
630 | ||
631 | ||
632 | /* followup_gsnt: fix the ace_name in argv[7]. argv[6] will contain the | |
633 | * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[7] into the | |
634 | * proper name based on the type, and repace that string in the argv. | |
635 | * Also fixes the modby field by called followup_fix_modby. | |
636 | */ | |
637 | ||
5eaef520 | 638 | int followup_gsnt(struct query *q, struct save_queue *sq, struct validate *v, |
7ac48069 | 639 | int (*action)(int, char *[], void *), void *actarg, |
640 | client *cl) | |
73cf66ba | 641 | { |
5eaef520 | 642 | char **argv, *type; |
643 | int id, i, idx, status; | |
644 | ||
645 | idx = 8; | |
646 | ||
647 | while (sq_get_data(sq, &argv)) | |
648 | { | |
649 | mr_trim_args(q->vcnt, argv); | |
650 | ||
651 | id = atoi(argv[i = q->vcnt - 2]); | |
652 | if (id > 0) | |
653 | status = id_to_name(id, USERS_TABLE, &argv[i]); | |
654 | else | |
655 | status = id_to_name(-id, STRINGS_TABLE, &argv[i]); | |
656 | if (status && status != MR_NO_MATCH) | |
657 | return status; | |
658 | ||
659 | id = atoi(argv[idx]); | |
660 | type = argv[idx - 1]; | |
661 | ||
662 | if (!strcmp(type, "LIST")) | |
663 | status = id_to_name(id, LIST_TABLE, &argv[idx]); | |
664 | else if (!strcmp(type, "USER")) | |
665 | status = id_to_name(id, USERS_TABLE, &argv[idx]); | |
666 | else if (!strcmp(type, "KERBEROS")) | |
667 | status = id_to_name(id, STRINGS_TABLE, &argv[idx]); | |
668 | else if (!strcmp(type, "NONE")) | |
669 | { | |
670 | status = 0; | |
671 | free(argv[idx]); | |
e688520a | 672 | argv[idx] = xstrdup("NONE"); |
5eaef520 | 673 | } |
674 | else | |
675 | { | |
676 | status = 0; | |
677 | free(argv[idx]); | |
e688520a | 678 | argv[idx] = xstrdup("???"); |
fde7313c | 679 | } |
5eaef520 | 680 | if (status && status != MR_NO_MATCH) |
681 | return status; | |
fde7313c | 682 | |
5eaef520 | 683 | /* send the data */ |
684 | (*action)(q->vcnt, argv, actarg); | |
fde7313c | 685 | |
5eaef520 | 686 | /* free saved data */ |
687 | for (i = 0; i < q->vcnt; i++) | |
688 | free(argv[i]); | |
689 | free(argv); | |
fde7313c | 690 | } |
691 | ||
5eaef520 | 692 | sq_destroy(sq); |
693 | return MR_SUCCESS; | |
fde7313c | 694 | } |
695 | ||
696 | ||
697 | /* followup_ghst: fix the ace_name in argv[12]. argv[11] will contain the | |
698 | * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[12] into the | |
699 | * proper name based on the type, and repace that string in the argv. | |
700 | * Also fixes the modby field by called followup_fix_modby. | |
701 | */ | |
702 | ||
5eaef520 | 703 | int followup_ghst(struct query *q, struct save_queue *sq, struct validate *v, |
7ac48069 | 704 | int (*action)(int, char *[], void *), void *actarg, |
705 | client *cl) | |
fde7313c | 706 | { |
5eaef520 | 707 | char **argv, *type; |
708 | int id, i, idx, status; | |
709 | ||
710 | while (sq_get_data(sq, &argv)) | |
711 | { | |
712 | mr_trim_args(q->vcnt, argv); | |
713 | ||
714 | id = atoi(argv[i = q->vcnt - 2]); | |
715 | if (id > 0) | |
716 | status = id_to_name(id, USERS_TABLE, &argv[i]); | |
717 | else | |
718 | status = id_to_name(-id, STRINGS_TABLE, &argv[i]); | |
719 | if (status && status != MR_NO_MATCH) | |
720 | return status; | |
721 | ||
722 | id = atoi(argv[13]); | |
723 | status = id_to_name(id, STRINGS_TABLE, &argv[13]); | |
724 | if (status) | |
725 | return status; | |
726 | id = atoi(argv[14]); | |
727 | status = id_to_name(id, STRINGS_TABLE, &argv[14]); | |
728 | if (status) | |
729 | return status; | |
730 | id = atoi(argv[16]); | |
731 | if (id < 0) | |
732 | status = id_to_name(-id, STRINGS_TABLE, &argv[16]); | |
733 | else | |
734 | status = id_to_name(id, USERS_TABLE, &argv[16]); | |
735 | if (status && status != MR_NO_MATCH) | |
736 | return status; | |
737 | ||
738 | idx = 12; | |
739 | id = atoi(argv[idx]); | |
740 | type = strtrim(argv[idx - 1]); | |
741 | ||
742 | if (!strcmp(type, "LIST")) | |
743 | status = id_to_name(id, LIST_TABLE, &argv[idx]); | |
744 | else if (!strcmp(type, "USER")) | |
745 | status = id_to_name(id, USERS_TABLE, &argv[idx]); | |
746 | else if (!strcmp(type, "KERBEROS")) | |
747 | status = id_to_name(id, STRINGS_TABLE, &argv[idx]); | |
748 | else if (!strcmp(type, "NONE")) | |
749 | { | |
750 | status = 0; | |
751 | free(argv[idx]); | |
e688520a | 752 | argv[idx] = xstrdup("NONE"); |
73cf66ba | 753 | } |
5eaef520 | 754 | else |
755 | { | |
756 | status = 0; | |
757 | free(argv[idx]); | |
e688520a | 758 | argv[idx] = xstrdup("???"); |
5eaef520 | 759 | } |
760 | if (status && status != MR_NO_MATCH) | |
761 | return status; | |
73cf66ba | 762 | |
5eaef520 | 763 | /* send the data */ |
764 | (*action)(q->vcnt, argv, actarg); | |
73cf66ba | 765 | |
5eaef520 | 766 | /* free saved data */ |
767 | for (i = 0; i < q->vcnt; i++) | |
768 | free(argv[i]); | |
769 | free(argv); | |
73cf66ba | 770 | } |
771 | ||
5eaef520 | 772 | sq_destroy(sq); |
773 | return MR_SUCCESS; | |
73cf66ba | 774 | } |
775 | ||
776 | ||
777 | /* followup_glin: fix the ace_name in argv[8]. argv[7] will contain the | |
778 | * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[8] into the | |
779 | * proper name based on the type, and repace that string in the argv. | |
780 | * Also fixes the modby field by called followup_fix_modby. | |
781 | */ | |
782 | ||
5eaef520 | 783 | int followup_glin(struct query *q, struct save_queue *sq, struct validate *v, |
7ac48069 | 784 | int (*action)(int, char *[], void *), void *actarg, |
785 | client *cl) | |
73cf66ba | 786 | { |
5eaef520 | 787 | char **argv, *type; |
788 | int id, i, idx, status; | |
789 | ||
790 | idx = 8; | |
791 | if (!strcmp(q->shortname, "gsin")) | |
792 | idx = 12; | |
793 | ||
794 | while (sq_get_data(sq, &argv)) | |
795 | { | |
796 | mr_trim_args(q->vcnt, argv); | |
797 | ||
798 | id = atoi(argv[i = q->vcnt - 2]); | |
799 | if (id > 0) | |
800 | status = id_to_name(id, USERS_TABLE, &argv[i]); | |
801 | else | |
802 | status = id_to_name(-id, STRINGS_TABLE, &argv[i]); | |
803 | if (status && status != MR_NO_MATCH) | |
804 | return status; | |
805 | ||
806 | id = atoi(argv[idx]); | |
807 | type = argv[idx - 1]; | |
808 | ||
809 | if (!strcmp(type, "LIST")) | |
810 | status = id_to_name(id, LIST_TABLE, &argv[idx]); | |
811 | else if (!strcmp(type, "USER")) | |
812 | status = id_to_name(id, USERS_TABLE, &argv[idx]); | |
813 | else if (!strcmp(type, "KERBEROS")) | |
814 | status = id_to_name(id, STRINGS_TABLE, &argv[idx]); | |
815 | else if (!strcmp(type, "NONE")) | |
816 | { | |
817 | status = 0; | |
818 | free(argv[idx]); | |
e688520a | 819 | argv[idx] = xstrdup("NONE"); |
73cf66ba | 820 | } |
5eaef520 | 821 | else |
822 | { | |
823 | status = 0; | |
824 | free(argv[idx]); | |
e688520a | 825 | argv[idx] = xstrdup("???"); |
5eaef520 | 826 | } |
827 | if (status && status != MR_NO_MATCH) | |
828 | return status; | |
73cf66ba | 829 | |
5eaef520 | 830 | if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1) |
831 | { | |
e688520a | 832 | argv[6] = xrealloc(argv[6], strlen(UNIQUE_GID) + 1); |
5eaef520 | 833 | strcpy(argv[6], UNIQUE_GID); |
73cf66ba | 834 | } |
835 | ||
5eaef520 | 836 | /* send the data */ |
837 | (*action)(q->vcnt, argv, actarg); | |
73cf66ba | 838 | |
5eaef520 | 839 | /* free saved data */ |
840 | for (i = 0; i < q->vcnt; i++) | |
841 | free(argv[i]); | |
842 | free(argv); | |
73cf66ba | 843 | } |
844 | ||
5eaef520 | 845 | sq_destroy(sq); |
846 | return MR_SUCCESS; | |
73cf66ba | 847 | } |
848 | ||
1a9a0a59 | 849 | int followup_gpsv(struct query *q, struct save_queue *sq, struct validate *v, |
850 | int (*action)(int, char *[], void *), void *actarg, | |
851 | client *cl) | |
852 | { | |
853 | char **argv, *type; | |
854 | int id, i, status; | |
855 | ||
856 | while (sq_get_data(sq, &argv)) | |
857 | { | |
858 | mr_trim_args(q->vcnt, argv); | |
859 | ||
860 | id = atoi(argv[PRINTSERVER_OWNER_NAME]); | |
861 | type = argv[PRINTSERVER_OWNER_TYPE]; | |
862 | ||
863 | if (!strcmp(type, "LIST")) | |
864 | status = id_to_name(id, LIST_TABLE, &argv[PRINTSERVER_OWNER_NAME]); | |
865 | else if (!strcmp(type, "USER")) | |
866 | status = id_to_name(id, USERS_TABLE, &argv[PRINTSERVER_OWNER_NAME]); | |
867 | else if (!strcmp(type, "KERBEROS")) | |
868 | status = id_to_name(id, STRINGS_TABLE, &argv[PRINTSERVER_OWNER_NAME]); | |
869 | else | |
870 | { | |
871 | status = 0; | |
872 | free(argv[PRINTSERVER_OWNER_NAME]); | |
873 | argv[PRINTSERVER_OWNER_NAME] = xstrdup("NONE"); | |
874 | } | |
875 | if (status && status != MR_NO_MATCH) | |
876 | return status; | |
877 | } | |
878 | ||
879 | return followup_fix_modby(q, sq, v, action, actarg, cl); | |
880 | } | |
881 | ||
73cf66ba | 882 | |
883 | /* followup_gqot: Fix the entity name, directory name & modby fields | |
884 | * argv[0] = filsys_id | |
885 | * argv[1] = type | |
886 | * argv[2] = entity_id | |
887 | * argv[3] = ascii(quota) | |
888 | */ | |
889 | ||
5eaef520 | 890 | int followup_gqot(struct query *q, struct save_queue *sq, struct validate *v, |
7ac48069 | 891 | int (*action)(int, char *[], void *), void *actarg, |
892 | client *cl) | |
73cf66ba | 893 | { |
44d12d58 | 894 | int j; |
5eaef520 | 895 | char **argv; |
896 | EXEC SQL BEGIN DECLARE SECTION; | |
897 | int id; | |
898 | char *name, *label; | |
899 | EXEC SQL END DECLARE SECTION; | |
900 | int status, idx; | |
901 | ||
902 | if (!strcmp(q->name, "get_quota") || | |
903 | !strcmp(q->name, "get_quota_by_filesys")) | |
904 | idx = 4; | |
905 | else | |
906 | idx = 3; | |
907 | while (sq_get_data(sq, &argv)) | |
908 | { | |
909 | if (idx == 4) | |
910 | { | |
911 | switch (argv[1][0]) | |
912 | { | |
73cf66ba | 913 | case 'U': |
5eaef520 | 914 | status = id_to_name(atoi(argv[2]), USERS_TABLE, &argv[2]); |
915 | break; | |
73cf66ba | 916 | case 'G': |
917 | case 'L': | |
5eaef520 | 918 | status = id_to_name(atoi(argv[2]), LIST_TABLE, &argv[2]); |
919 | break; | |
73cf66ba | 920 | case 'A': |
5eaef520 | 921 | free(argv[2]); |
e688520a | 922 | argv[2] = xstrdup("system:anyuser"); |
5eaef520 | 923 | break; |
73cf66ba | 924 | default: |
5eaef520 | 925 | id = atoi(argv[2]); |
e688520a | 926 | argv[2] = xmalloc(8); |
5eaef520 | 927 | sprintf(argv[2], "%d", id); |
73cf66ba | 928 | } |
929 | } | |
5eaef520 | 930 | id = atoi(argv[idx]); |
931 | free(argv[idx]); | |
e688520a | 932 | argv[idx] = xmalloc(id ? NFSPHYS_DIR_SIZE : FILESYS_NAME_SIZE); |
5eaef520 | 933 | name = argv[idx]; |
e688520a | 934 | name[0] = '\0'; |
5eaef520 | 935 | if (id == 0) |
936 | { | |
937 | label = argv[0]; | |
938 | EXEC SQL SELECT name INTO :name FROM filesys | |
939 | WHERE label = :label; | |
73cf66ba | 940 | } |
5eaef520 | 941 | else |
942 | { | |
943 | EXEC SQL SELECT dir INTO :name FROM nfsphys | |
944 | WHERE nfsphys_id = :id; | |
73cf66ba | 945 | } |
5eaef520 | 946 | if (sqlca.sqlerrd[2] != 1) |
947 | sprintf(argv[idx], "#%d", id); | |
948 | ||
949 | id = atoi(argv[idx + 3]); | |
950 | if (id > 0) | |
951 | status = id_to_name(id, USERS_TABLE, &argv[idx + 3]); | |
952 | else | |
953 | status = id_to_name(-id, STRINGS_TABLE, &argv[idx + 3]); | |
954 | if (status && status != MR_NO_MATCH) | |
955 | return status; | |
956 | (*action)(q->vcnt, argv, actarg); | |
957 | for (j = 0; j < q->vcnt; j++) | |
958 | free(argv[j]); | |
959 | free(argv); | |
73cf66ba | 960 | } |
5eaef520 | 961 | sq_destroy(sq); |
962 | return MR_SUCCESS; | |
73cf66ba | 963 | } |
964 | ||
965 | ||
966 | /* followup_aqot: Add allocation to nfsphys after creating quota. | |
967 | * argv[0] = filsys_id | |
968 | * argv[1] = type if "add_quota" or "update_quota" | |
969 | * argv[2 or 1] = id | |
970 | * argv[3 or 2] = ascii(quota) | |
971 | */ | |
972 | ||
5eaef520 | 973 | int followup_aqot(struct query *q, char *argv[], client *cl) |
73cf66ba | 974 | { |
5eaef520 | 975 | EXEC SQL BEGIN DECLARE SECTION; |
976 | int quota, id, fs, who, physid, table; | |
977 | char *entity, *qtype, *tname; | |
978 | EXEC SQL END DECLARE SECTION; | |
979 | char incr_qual[60]; | |
980 | char *incr_argv[2]; | |
981 | int status; | |
982 | ||
983 | table = q->rtable; | |
984 | tname = table_name[table]; | |
985 | fs = *(int *)argv[0]; | |
986 | EXEC SQL SELECT phys_id INTO :physid FROM filesys | |
987 | WHERE filsys_id = :fs; | |
988 | if (dbms_errno) | |
989 | return mr_errcode; | |
990 | ||
991 | if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot")) | |
992 | { | |
993 | qtype = argv[1]; | |
994 | id = *(int *)argv[2]; | |
995 | quota = atoi(argv[3]); | |
996 | sprintf(incr_qual, "q.filsys_id = %d", fs); | |
997 | } | |
998 | else | |
999 | { | |
1000 | qtype = "USER"; | |
1001 | id = *(int *)argv[1]; | |
1002 | quota = atoi(argv[2]); | |
1003 | sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND " | |
1004 | "q.entity_id = %d", fs, qtype, id); | |
73cf66ba | 1005 | } |
1006 | ||
5eaef520 | 1007 | /* quota case of incremental_{before|after} only looks at slot 1 */ |
1008 | incr_argv[1] = qtype; | |
1009 | ||
1010 | /* Follows one of many possible gross hacks to fix these particular | |
1011 | * conflicts between what is possible in the query table and what | |
1012 | * is possible in SQL. | |
1013 | */ | |
1014 | if (q->type == APPEND) | |
1015 | { | |
1016 | incremental_clear_before(); | |
1017 | EXEC SQL INSERT INTO quota | |
1018 | (filsys_id, type, entity_id, quota, phys_id) | |
1019 | VALUES (:fs, NVL(:qtype, CHR(0)), :id, :quota, :physid); | |
1020 | incremental_after(table, incr_qual, incr_argv); | |
1021 | } | |
1022 | else | |
1023 | { | |
1024 | incremental_before(table, incr_qual, incr_argv); | |
1025 | EXEC SQL UPDATE quota SET quota = :quota | |
1026 | WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id; | |
1027 | status = mr_errcode; | |
1028 | incremental_after(table, incr_qual, incr_argv); | |
73cf66ba | 1029 | } |
1030 | ||
5eaef520 | 1031 | if (dbms_errno) |
1032 | return mr_errcode; | |
1033 | flush_name(argv[0], table); | |
1034 | if (q->type == APPEND) | |
1035 | { | |
1036 | EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = SYSDATE | |
1037 | WHERE table_name = :tname; | |
1038 | } | |
1039 | else | |
1040 | { | |
1041 | EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = SYSDATE | |
1042 | WHERE table_name = :tname; | |
73cf66ba | 1043 | } |
5eaef520 | 1044 | |
1045 | /* Proceed with original followup */ | |
1046 | who = cl->client_id; | |
1047 | entity = cl->entity; | |
1048 | ||
1049 | EXEC SQL UPDATE quota | |
1050 | SET modtime = SYSDATE, modby = :who, modwith = :entity | |
1051 | WHERE filsys_id = :fs and type = :qtype and entity_id = :id; | |
1052 | EXEC SQL UPDATE nfsphys SET allocated = allocated + :quota | |
1053 | WHERE nfsphys_id = :physid; | |
1054 | if (dbms_errno) | |
1055 | return mr_errcode; | |
1056 | return MR_SUCCESS; | |
73cf66ba | 1057 | } |
1058 | ||
1059 | ||
1060 | /* Necessitated by the requirement of a correlation name by the incremental | |
5eaef520 | 1061 | * routines, since query table deletes don't provide one. |
73cf66ba | 1062 | */ |
5eaef520 | 1063 | int followup_dqot(struct query *q, char **argv, client *cl) |
73cf66ba | 1064 | { |
5eaef520 | 1065 | char *qtype; |
1066 | int id, fs, table; | |
1067 | char *incr_argv[2]; | |
1068 | EXEC SQL BEGIN DECLARE SECTION; | |
1069 | char incr_qual[80], *tname; | |
1070 | EXEC SQL END DECLARE SECTION; | |
1071 | ||
1072 | table = q->rtable; | |
1073 | tname = table_name[table]; | |
1074 | fs = *(int *)argv[0]; | |
1075 | if (!strcmp(q->shortname, "dqot")) | |
1076 | { | |
1077 | qtype = argv[1]; | |
1078 | id = *(int *)argv[2]; | |
1079 | } | |
1080 | else | |
1081 | { | |
1082 | qtype = "USER"; | |
1083 | id = *(int *)argv[1]; | |
73cf66ba | 1084 | } |
5eaef520 | 1085 | sprintf(incr_qual, "q.filsys_id = %d AND q.type = '%s' AND q.entity_id = %d", |
1086 | fs, qtype, id); | |
73cf66ba | 1087 | |
5eaef520 | 1088 | /* quota case of incremental_{before|after} only looks at slot 1 */ |
1089 | incr_argv[1] = qtype; | |
73cf66ba | 1090 | |
5eaef520 | 1091 | incremental_before(table, incr_qual, incr_argv); |
1092 | EXEC SQL DELETE FROM quota q WHERE q.filsys_id = :fs AND q.type = :qtype | |
1093 | AND q.entity_id = :id; | |
1094 | incremental_clear_after(); | |
73cf66ba | 1095 | |
5eaef520 | 1096 | if (dbms_errno) |
1097 | return mr_errcode; | |
1098 | flush_name(argv[0], table); | |
73cf66ba | 1099 | |
5eaef520 | 1100 | EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = SYSDATE |
1101 | WHERE table_name = :tname; | |
1102 | return MR_SUCCESS; | |
73cf66ba | 1103 | } |
1104 | ||
73cf66ba | 1105 | /* followup_gzcl: |
1106 | */ | |
1107 | ||
5eaef520 | 1108 | int followup_gzcl(struct query *q, struct save_queue *sq, struct validate *v, |
7ac48069 | 1109 | int (*action)(int, char *[], void *), void *actarg, |
1110 | client *cl) | |
73cf66ba | 1111 | { |
5eaef520 | 1112 | int id, i, status; |
1113 | char **argv; | |
1114 | ||
1115 | while (sq_get_data(sq, &argv)) | |
1116 | { | |
1117 | mr_trim_args(q->vcnt, argv); | |
1118 | ||
1119 | id = atoi(argv[i = q->vcnt - 2]); | |
1120 | if (id > 0) | |
1121 | status = id_to_name(id, USERS_TABLE, &argv[i]); | |
1122 | else | |
1123 | status = id_to_name(-id, STRINGS_TABLE, &argv[i]); | |
1124 | if (status && status != MR_NO_MATCH) | |
1125 | return status; | |
1126 | ||
1127 | for (i = 1; i < 8; i += 2) | |
1128 | { | |
1129 | id = atoi(argv[i + 1]); | |
1130 | if (!strcmp(argv[i], "LIST")) | |
1131 | status = id_to_name(id, LIST_TABLE, &argv[i + 1]); | |
1132 | else if (!strcmp(argv[i], "USER")) | |
1133 | status = id_to_name(id, USERS_TABLE, &argv[i + 1]); | |
1134 | else if (!strcmp(argv[i], "KERBEROS")) | |
1135 | status = id_to_name(id, STRINGS_TABLE, &argv[i + 1]); | |
1136 | else if (!strcmp(argv[i], "NONE")) | |
1137 | { | |
1138 | status = 0; | |
1139 | free(argv[i + 1]); | |
e688520a | 1140 | argv[i + 1] = xstrdup("NONE"); |
73cf66ba | 1141 | } |
5eaef520 | 1142 | else |
1143 | { | |
1144 | status = 0; | |
1145 | free(argv[i + 1]); | |
e688520a | 1146 | argv[i + 1] = xstrdup("???"); |
5eaef520 | 1147 | } |
1148 | if (status && status != MR_NO_MATCH) | |
1149 | return status; | |
73cf66ba | 1150 | } |
1151 | ||
5eaef520 | 1152 | /* send the data */ |
1153 | (*action)(q->vcnt, argv, actarg); | |
73cf66ba | 1154 | |
5eaef520 | 1155 | /* free saved data */ |
1156 | for (i = 0; i < q->vcnt; i++) | |
1157 | free(argv[i]); | |
1158 | free(argv); | |
73cf66ba | 1159 | } |
5eaef520 | 1160 | sq_destroy(sq); |
1161 | return MR_SUCCESS; | |
73cf66ba | 1162 | } |
1163 | ||
1164 | ||
1165 | /* followup_gsha: | |
1166 | */ | |
1167 | ||
5eaef520 | 1168 | int followup_gsha(struct query *q, struct save_queue *sq, struct validate *v, |
7ac48069 | 1169 | int (*action)(int, char *[], void *), void *actarg, |
1170 | client *cl) | |
73cf66ba | 1171 | { |
5eaef520 | 1172 | char **argv; |
1173 | int i, id, status; | |
1174 | ||
1175 | while (sq_get_data(sq, &argv)) | |
1176 | { | |
1177 | mr_trim_args(q->vcnt, argv); | |
1178 | ||
1179 | id = atoi(argv[4]); | |
1180 | if (id > 0) | |
1181 | status = id_to_name(id, USERS_TABLE, &argv[4]); | |
1182 | else | |
1183 | status = id_to_name(-id, STRINGS_TABLE, &argv[4]); | |
1184 | if (status && status != MR_NO_MATCH) | |
1185 | return status; | |
1186 | ||
1187 | id = atoi(argv[2]); | |
1188 | if (!strcmp(argv[1], "LIST")) | |
1189 | status = id_to_name(id, LIST_TABLE, &argv[2]); | |
1190 | else if (!strcmp(argv[1], "USER")) | |
1191 | status = id_to_name(id, USERS_TABLE, &argv[2]); | |
1192 | else if (!strcmp(argv[1], "KERBEROS")) | |
1193 | status = id_to_name(id, STRINGS_TABLE, &argv[2]); | |
1194 | else if (!strcmp(argv[1], "NONE")) | |
1195 | { | |
1196 | status = 0; | |
1197 | free(argv[2]); | |
e688520a | 1198 | argv[2] = xstrdup("NONE"); |
5eaef520 | 1199 | } |
1200 | else | |
1201 | { | |
1202 | status = 0; | |
1203 | free(argv[2]); | |
e688520a | 1204 | argv[2] = xstrdup("???"); |
73cf66ba | 1205 | } |
5eaef520 | 1206 | if (status && status != MR_NO_MATCH) |
1207 | return status; | |
73cf66ba | 1208 | |
5eaef520 | 1209 | /* send the data */ |
1210 | (*action)(q->vcnt, argv, actarg); | |
73cf66ba | 1211 | |
5eaef520 | 1212 | /* free saved data */ |
1213 | for (i = 0; i < q->vcnt; i++) | |
1214 | free(argv[i]); | |
1215 | free(argv); | |
73cf66ba | 1216 | } |
5eaef520 | 1217 | sq_destroy(sq); |
1218 | return MR_SUCCESS; | |
73cf66ba | 1219 | } |
1220 | ||
1221 | ||
5eaef520 | 1222 | int _sdl_followup(struct query *q, char *argv[], client *cl) |
73cf66ba | 1223 | { |
85330553 | 1224 | if (atoi(argv[0])) |
5eaef520 | 1225 | EXEC SQL ALTER SESSION SET SQL_TRACE TRUE; |
1226 | else | |
1227 | EXEC SQL ALTER SESSION SET SQL_TRACE FALSE; | |
1228 | ||
1229 | return MR_SUCCESS; | |
73cf66ba | 1230 | } |
1231 | ||
1232 | ||
85330553 | 1233 | int trigger_dcm(struct query *q, char *argv[], client *cl) |
73cf66ba | 1234 | { |
85330553 | 1235 | pid_t pid; |
e688520a | 1236 | char prog[MAXPATHLEN]; |
85330553 | 1237 | |
1238 | sprintf(prog, "%s/startdcm", BIN_DIR); | |
1239 | pid = vfork(); | |
1240 | switch (pid) | |
5eaef520 | 1241 | { |
85330553 | 1242 | case 0: |
1243 | execl(prog, "startdcm", 0); | |
1244 | exit(1); | |
1245 | ||
1246 | case -1: | |
1247 | return errno; | |
1248 | ||
73cf66ba | 1249 | default: |
85330553 | 1250 | return MR_SUCCESS; |
73cf66ba | 1251 | } |
1252 | } |