]> andersk Git - moira.git/blame - clients/moira/delete.c
Initial revision
[moira.git] / clients / moira / delete.c
CommitLineData
402461ad 1#if (!defined(lint) && !defined(SABER))
08345b74 2 static char rcsid_module_c[] = "$Header$";
3#endif lint
4
0a2c64cb 5/* This is the file delete.c for the SMS Client, which allows a nieve
6 * user to quickly and easily maintain most parts of the SMS database.
08345b74 7 * It Contains: functions for deleting users and lists.
8 *
9 * Created: 5/18/88
10 * By: Chris D. Peterson
11 *
12 * $Source$
13 * $Author$
14 * $Header$
15 *
0a2c64cb 16 * Copyright 1988 by the Massachusetts Institute of Technology.
08345b74 17 *
18 * For further information on copyright and distribution
19 * see the file mit-copyright.h
20 */
21
08345b74 22#include <stdio.h>
23#include <strings.h>
24#include <sms.h>
25#include <menu.h>
26
461c03b6 27#include "mit-copyright.h"
0a2c64cb 28#include "defs.h"
29#include "f_defs.h"
461c03b6 30#include "globals.h"
31#include "infodefs.h"
32
08345b74 33/* Function Name: CheckListForDeletion
34 * Description: Check one of the lists in which we just removed a member.
35 * if the list is empty then it will delete it.
36 * Arguments: name - name of the list to check.
37 * verbose - verbose mode?
38 * Returns: none.
39 */
40
41void
42CheckListForDeletion(name, verbose)
43char * name;
44Bool verbose;
45{
461c03b6 46 struct qelem *elem = NULL;
075fe5bb 47 int status;
461c03b6 48 char *args[2], buf[BUFSIZ], **info;
08345b74 49
50 if ( (status = sms_query("count_members_of_list", 1, &name, StoreInfo,
51 (char *) &elem)) != 0) {
461c03b6 52 com_err(program_name, status,
53 " in DeleteList (count_members_of_list).");
54 return;
08345b74 55 }
461c03b6 56 info = (char **) elem->q_data;
0a2c64cb 57 if ( strcmp(info[NAME],"0") == 0) {
461c03b6 58 if (verbose) {
59 sprintf(buf, "Delete the empty list %s? ", name);
075fe5bb 60 if (YesNoQuestion(buf, FALSE) != TRUE) {
461c03b6 61 Put_message("Aborting Deletion!");
62 FreeQueue(elem);
63 return;
64 }
08345b74 65 }
461c03b6 66 args[0] = "foo"; /* not used. */
67 args[1] = name;
68 DeleteList(2, args);
08345b74 69 }
461c03b6 70 FreeQueue(elem);
08345b74 71}
72
075fe5bb 73/* Function Name: CheckAce
74 * Description: Checks an ace to see of we should delete it.
75 * Arguments: type - the type of this ace.
76 * name - the name of the ace.
08345b74 77 * verbose - query user?
78 * Returns: none.
79 */
80
81void
075fe5bb 82CheckAce(type, name, verbose)
08345b74 83char * type, *name;
84Bool verbose;
85{
86 char *args[2], buf[BUFSIZ];
075fe5bb 87 int status;
08345b74 88
461c03b6 89 if ( strcmp(type, "LIST") != 0 )
075fe5bb 90 return; /* If the ace is not a list the ignore it. */
08345b74 91
92 args[0] = type;
93 args[1] = name;
075fe5bb 94 status = sms_query("get_ace_use", 2, args, NullFunc, (char *) NULL);
08345b74 95 if (status != SMS_NO_MATCH)
075fe5bb 96 return; /* If this query fails the ace will
461c03b6 97 not be deleted even if it is empty. */
08345b74 98 if (verbose) {
0a2c64cb 99 sprintf(buf, "Delete the unused Access Control Entity (ACE) %s? ",
100 name);
075fe5bb 101 if ( YesNoQuestion(buf, FALSE) != TRUE) {
461c03b6 102 Put_message("Aborting Deletion!");
103 return;
104 }
08345b74 105 }
106/*
075fe5bb 107 * Delete the ACE.
08345b74 108 *
109 * NOTE: Delete list expects only the name of the list to delete in argv[1].
110 * since, 'args' already satisfies this, there is no need to create
111 * a special argument list.
112 */
113 DeleteList(2, args);
114}
115
116
075fe5bb 117/* Function Name: CheckIfAce
118 * Description: Checks to see if this is an ace of another data object.
08345b74 119 * Arguments: name - name of the object.
075fe5bb 120 * Returns: SUB_ERROR if this list is an ace, or if the query did noe
08345b74 121 * succeed.
122 */
123
124int
075fe5bb 125CheckIfAce(name, type, verbose)
461c03b6 126char * name, * type;
08345b74 127Bool verbose;
128{
129 char * args[2], buf[BUFSIZ];
075fe5bb 130 struct qelem *local, *elem;
461c03b6 131 int status;
08345b74 132 elem = NULL;
133
134 args[0] = type;
135 args[1] = name;
075fe5bb 136 switch (status = sms_query("get_ace_use", 2, args,
137 StoreInfo, (char *) &elem)) {
138 case SMS_NO_MATCH:
139 return(DM_NORMAL);
140 case SMS_SUCCESS:
141 local = elem = QueueTop(elem);
142 if (verbose) {
143 sprintf(buf, "%s %s %s %s", type, name,
144 "is the Access Control List (ACE) for the following data",
145 "objects:\n");
146 Put_message(buf);
147 while (local != NULL) {
148 char ** info = (char **) local->q_data;
149 Print( CountArgs(info), info, NULL);
150 local = local->q_forw;
151 }
152 Put_message(
153 "The ACE for each of these items must be changed before");
154 sprintf(buf,"the %s %s can be deleted.\n", type, name);
155 Put_message(buf);
08345b74 156 }
075fe5bb 157 break;
158 default:
159 com_err(program_name, status, " in CheckIfAce (get_ace_use).");
160 return(SUB_ERROR);
08345b74 161 }
162 FreeQueue(elem);
163 return(SUB_ERROR);
08345b74 164}
165
166/* Function Name: RemoveItemFromLists
167 * Description: this function removes a list from all other lists of
168 * which it is a member.
075fe5bb 169 * Arguments: name - name of the item
08345b74 170 * elem - a pointer to a queue element. RETURNED
171 * verbose - verbose mode.
172 * Returns: SUB_ERROR if there is an error.
173 */
174
175int
461c03b6 176RemoveItemFromLists(name, type, elem, verbose)
177char * name, *type;
178struct qelem ** elem;
08345b74 179int verbose;
180{
461c03b6 181 struct qelem *local;
85ca828a 182 char *args[10], temp_buf[BUFSIZ];
0a2c64cb 183 int lists;
075fe5bb 184 register int status;
08345b74 185
186 args[0] = type;
187 args[1] = name;
188 *elem = NULL;
189
190/*
075fe5bb 191 * Get all list of which this item is a member, and store them in a queue.
08345b74 192 */
193
85ca828a 194 status = sms_query("get_lists_of_member", 2, args, StoreInfo,
08345b74 195 (char *) elem);
196
197 if (status == SMS_NO_MATCH)
198 return(SUB_NORMAL);
199
402461ad 200 if (status != SMS_SUCCESS) {
461c03b6 201 com_err(program_name, status, " in DeleteList (get_lists_of_member).");
08345b74 202 return(SUB_ERROR);
203 }
204
205/*
206 * If verbose mode, ask user of we should remove our list from
207 * all these lists.
208 */
209
075fe5bb 210 local = *elem = QueueTop(*elem);
0a2c64cb 211 lists = QueueCount(*elem);
212 if (lists == 0)
213 return(SUB_NORMAL);
08345b74 214 if (verbose) {
0a2c64cb 215 sprintf(temp_buf, "%s %s is a member of %d other list%s.\n", type,
216 name, lists, ((lists == 1) ? "" : "s") );
461c03b6 217 Put_message(temp_buf);
08345b74 218 while (local != NULL) {
461c03b6 219 char ** info = (char **) local->q_data;
402461ad 220 Print( 1, &info[GLOM_NAME], (char *) NULL);
08345b74 221 local = local->q_forw;
222 }
0a2c64cb 223 Put_message(" "); /* Blank Line. */
461c03b6 224 sprintf(temp_buf,"Remove %s %s from these lists? ", type, name);
075fe5bb 225 if (YesNoQuestion(temp_buf, FALSE) != TRUE) {
08345b74 226 Put_message("Aborting...");
227 FreeQueue(*elem);
075fe5bb 228 *elem = NULL;
08345b74 229 return(SUB_ERROR);
230 }
231 }
232
233/*
234 * Remove this list from all lists that it is a member of.
235 */
236
237 local = *elem;
075fe5bb 238 args[DM_MEMBER] = name;
402461ad 239 args[DM_TYPE] = type;
08345b74 240 while (local != NULL) {
461c03b6 241 char ** info = (char **) local->q_data;
075fe5bb 242 args[DM_LIST] = info[GLOM_NAME];
08345b74 243 if ( (status = sms_query("delete_member_from_list",
244 3, args, Scream, NULL)) != 0) {
461c03b6 245 com_err(program_name, status, " in delete_member\nAborting\n");
08345b74 246 FreeQueue(*elem);
247 return(SUB_ERROR);
248 }
249 local = local->q_forw;
250 }
251 return(SUB_NORMAL);
252}
253
254/* Function Name: RemoveMembersOfList
255 * Description: Deletes the members of the list.
256 * Arguments: name - name of the list.
257 * verbose - query user, about deletion?
258 * Returns: SUB_ERROR - if we could not delete, or the user abouted.
259 */
260
261int
461c03b6 262RemoveMembersOfList(name, verbose)
08345b74 263char * name;
264Bool verbose;
265{
461c03b6 266 char buf[BUFSIZ], *args[10];
267 struct qelem *local, *elem = NULL;
0a2c64cb 268 int status, members;
08345b74 269/*
270 * Get the members of this list.
271 */
08345b74 272 status = sms_query("get_members_of_list", 1, &name, StoreInfo,
273 (char *) &elem);
461c03b6 274 if (status == SMS_NO_MATCH)
275 return(SUB_NORMAL);
08345b74 276
277 if (status != 0) {
461c03b6 278 com_err(program_name, status, " in DeleteList (get_members_of_list).");
08345b74 279 return(SUB_ERROR);
280 }
08345b74 281/*
282 * If verbose mode, then ask the user if we should delete.
283 */
85ca828a 284 local = elem = QueueTop(elem);
0a2c64cb 285 if ( (members = QueueCount(elem)) == 0)
286 return(SUB_NORMAL);
08345b74 287 if (verbose) {
075fe5bb 288 sprintf(buf, "List %s has %d member%s:", name, QueueCount(elem),
0a2c64cb 289 ((members == 1) ? "" : "s") );
08345b74 290 Put_message(buf);
0a2c64cb 291 Put_message(" "); /* Blank Line. */
08345b74 292 while (local != NULL) {
461c03b6 293 char ** info = (char **) local->q_data;
08345b74 294 Print( CountArgs(info), info, NULL);
295 local = local->q_forw;
296 }
0a2c64cb 297 Put_message(" "); /* Blank Line. */
075fe5bb 298 sprintf(buf, "Remove th%s member%s from list %s? ",
0a2c64cb 299 ((members == 1) ? "is" : "ese"),
300 ((members == 1) ? "" : "s", name) );
075fe5bb 301 if ( YesNoQuestion(buf, FALSE) != TRUE) {
08345b74 302 Put_message("Aborting...");
461c03b6 303 FreeQueue(elem);
08345b74 304 return(SUB_ERROR);
305 }
306 }
08345b74 307/*
308 * Perform The Removal.
309 */
08345b74 310 local = elem;
311 args[0] = name;
312 while (local != NULL) {
461c03b6 313 char ** info = (char **) local->q_data;
08345b74 314 args[1] = info[0];
315 args[2] = info[1];
316 if ( (status = sms_query("delete_member_from_list",
317 3, args, Scream, NULL)) != 0) {
461c03b6 318 com_err(program_name, status, " in delete_member\nAborting\n");
08345b74 319 FreeQueue(elem);
320 return(SUB_ERROR);
321 }
322 local = local->q_forw;
323 }
324 return(SUB_NORMAL);
325}
326
08345b74 327/* Function Name: DeleteUserGroup
328 * Description: Deletes the list given by name if it exists.
329 * intended to be used to delete user groups
330 * Arguments: name - the name of the list to delete.
331 * verbose - flag that if TRUE queries the user to
332 * ask if list should be deleted.
333 * Returns: SMS_ERROR if there is an error.
334 */
335
336int
337DeleteUserGroup(name, verbose)
338char * name;
339Bool verbose;
340{
341 int status, ans;
461c03b6 342 char buf[BUFSIZ], *args[10];
08345b74 343
344 status = sms_query("get_list_info", 1, &name, NullFunc, (char *) NULL);
345 if (status == 0) {
346 if (verbose) {
347 sprintf(buf, "There is also a list named %s, delete it?", name);
075fe5bb 348 ans = YesNoQuestion(buf, FALSE);
08345b74 349 if (ans == FALSE) {
350 Put_message("Leaving group alone.");
461c03b6 351 return(SUB_NORMAL);
08345b74 352 }
353 if (ans < 0) {
354 Put_message("Aborting...\n");
355 return(SUB_ERROR);
356 }
357 }
358 /* ans == TRUE || ~verbose */
359 args[0] = "foo"; /* not used. */
360 args[1] = name;
361 DeleteList(2, args);
362 }
363 else if (status != SMS_NO_MATCH) {
461c03b6 364 com_err(program_name, status, " Aborting Delete User.");
08345b74 365 return(SUB_ERROR);
366 }
461c03b6 367 return(SUB_NORMAL);
08345b74 368}
369
370/* Function Name: DeleteHomeFilesys
371 * Description: Delete the home filesystem for the named user.
372 * Arguments: name - name of the user (and filsystem) to delete.
373 * verbose - if TRUE query user.
374 * Returns: SUB_NORMAL if home filesystem deleted, or nonexistant.
375 */
376
377int
378DeleteHomeFilesys(name, verbose)
379char * name;
380Bool verbose;
381{
075fe5bb 382 int status;
08345b74 383 char buf[BUFSIZ];
384
075fe5bb 385 switch (status = sms_query("get_filesys_by_label", 1, &name, NullFunc,
386 (char *) NULL)) {
387 case SMS_NO_MATCH:
388 break;
389 case SMS_SUCCESS:
08345b74 390 if (verbose) {
391 sprintf(buf, "Delete the filesystem named %s (y/n)?", name);
075fe5bb 392 switch (YesNoQuestion(buf, FALSE)) {
393 case FALSE:
394 Put_message("Filesystem Not Deleted, continuing...\n");
395 return(SUB_NORMAL);
396 case TRUE:
397 break;
398 default:
08345b74 399 Put_message("Filesystem Not Deleted, aborting...\n\n");
461c03b6 400 return(SUB_ERROR);
08345b74 401 }
402 }
075fe5bb 403 if ( (status = sms_query("delete_filesys", 1, &name, Scream,
404 (char *) NULL) ) != SMS_SUCCESS) {
405 com_err(program_name, status, " in delete_filesys.");
08345b74 406 return(SUB_ERROR);
407 }
075fe5bb 408 else
409 Put_message("Filesystem Successfully Deleted.");
410 break;
411 default:
412 com_err(program_name, status, " in get_filesystem_by_label).");
413 return(SUB_ERROR);
08345b74 414 }
075fe5bb 415 return(SUB_NORMAL);
08345b74 416}
417
075fe5bb 418/* Function Name: RealDeleteUser
419 * Description: Just Deletes the user.
420 * Arguments: name - name of User to delete
421 * Returns: SUB_ERROR if the deletion failed.
08345b74 422 */
423
075fe5bb 424static int
425RealDeleteUser(name)
08345b74 426char * name;
08345b74 427{
075fe5bb 428 char buf[BUFSIZ];
429 int status;
430
431 if ( (status = sms_query("delete_user", 1, &name, Scream,
432 (char *) NULL)) != SMS_SUCCESS) {
433 com_err(program_name, status, ": user not deleted");
08345b74 434 return(SUB_ERROR);
435 }
075fe5bb 436 (void) sprintf(buf, "User %s deleted.", name);
437 Put_message(buf);
08345b74 438 return(SUB_NORMAL);
439}
440
85ca828a 441/* Function Name: RealDeleteList
442 * Description: Just Deletes the list.
443 * Arguments: name - name of list to delete
444 * Returns: SUB_ERROR if the deletion failed.
08345b74 445 */
446
85ca828a 447static int
448RealDeleteList(name)
449char * name;
08345b74 450{
85ca828a 451 char buf[BUFSIZ];
461c03b6 452 int status;
08345b74 453
85ca828a 454 if ( (status = sms_query("delete_list", 1, &name, Scream,
455 (char *) NULL)) != SMS_SUCCESS) {
456 com_err(program_name, status, ": list not deleted");
457 return(SUB_ERROR);
08345b74 458 }
402461ad 459 (void) sprintf(buf, "List %s deleted.", name);
85ca828a 460 Put_message(buf);
402461ad 461 Put_message("");
85ca828a 462 return(SUB_NORMAL);
463}
08345b74 464
85ca828a 465/* Function Name: AttemptToDeleteList
466 * Description: Atempts to delete list, in the following manner:
467 * 1) try to delet it, if this fails in a known error then
468 * a) try to clean up each of those known methods, or
469 * at least explain why we failed.
402461ad 470 * Arguments: list_info - info about this list.
85ca828a 471 * ask_first - (T/F) query user before preparing for deletion,
472 * and cleaning up?
473 * Returns: none - all is taken care of and error messages printed
474 * one way or the other.
08345b74 475 */
476
85ca828a 477void
402461ad 478AttemptToDeleteList(list_info, ask_first)
479char ** list_info;
85ca828a 480Bool ask_first;
481{
482 int status;
402461ad 483 struct qelem *local, *member_of;
484 char *name = list_info[L_NAME];
485 member_of = NULL;
85ca828a 486
487 /*
488 * Attempt delete. - will only work if:
489 * 1) This list has no members.
490 * 2) This list in a member of no other lists.
075fe5bb 491 * 3) This list is not an ace of another object.
85ca828a 492 */
493
494 switch (status = sms_query("delete_list", 1, &name,
495 Scream, (char *) NULL)) {
496 case SMS_SUCCESS:
08345b74 497 Put_message("List Sucessfully Deleted.");
0a2c64cb 498 CheckAce(list_info[L_ACE_TYPE], list_info[L_ACE_NAME], ask_first);
85ca828a 499 break;
500 case SMS_IN_USE:
501 /*
502 * This list is in use. Try to find out why,
503 * and for the cases where we have a good idea of
504 * what to do we will query and then do it.
505 */
506
075fe5bb 507 if ( (CheckIfAce(name, "list", ask_first) == SUB_NORMAL) &&
402461ad 508 (RemoveMembersOfList(name, ask_first) == SUB_NORMAL) &&
85ca828a 509 (RemoveItemFromLists(name, "list",
510 &member_of, ask_first) == SUB_NORMAL) &&
85ca828a 511 (RealDeleteList(name) == SUB_NORMAL) )
512 { /* if... */
075fe5bb 513 CheckAce(list_info[L_ACE_TYPE], list_info[L_ACE_NAME], ask_first);
08345b74 514
0a2c64cb 515 local = QueueTop(member_of);
85ca828a 516 while (local != NULL) {
402461ad 517 char ** info = (char **) local->q_data;
85ca828a 518 CheckListForDeletion(info[LM_LIST], ask_first);
519 local = local->q_forw;
520 }
402461ad 521 FreeQueue(member_of);
08345b74 522 }
85ca828a 523 break;
524 default:
525 com_err(program_name, status, " in DeleteList (delete_list).");
526 break;
08345b74 527 }
08345b74 528}
529
85ca828a 530/* Function Name: DeleteList
531 * Description: deletes a list
532 * Arguments: argc, argv - standard SMS argc and argv.
533 * Returns: DM Status Code.
08345b74 534 */
535
85ca828a 536/* ARGSUSED */
537int
538DeleteList(argc, argv)
539int argc;
540char *argv[];
08345b74 541{
542 char buf[BUFSIZ];
85ca828a 543 struct qelem *top, *list;
544 register int status;
545 Bool one_list;
08345b74 546
85ca828a 547 list = NULL;
548
549 switch(status = sms_query("get_list_info", 1, argv + 1, StoreInfo, &list)){
550 case SMS_SUCCESS:
551 break;
552/* case SMS_NO_WILDCARD:
553 Put_message("Wildcards are not accepted here.");
554 return(DM_NORMAL);
555*/ case SMS_NO_MATCH:
556 case SMS_LIST:
402461ad 557 Put_message("There is no list that matches that name.");
85ca828a 558 return(DM_NORMAL);
559 default:
560 com_err(program_name, status, " in DeleteList (get_list_info).");
561 return(DM_NORMAL);
08345b74 562 }
85ca828a 563
564 top = list = QueueTop(list);
565 one_list = (QueueCount(list) == 1);
566 while (list != NULL) {
567 char ** info = (char**) list->q_data;
568 if (one_list) {
402461ad 569 sprintf( buf, "Are you sure that you want to delete the list %s",
570 info[L_NAME]);
571 if ( Confirm(buf) ) AttemptToDeleteList(info, TRUE);
85ca828a 572 }
573 else {
574 sprintf(buf, "Delete the list %s", info[L_NAME]);
575 switch( YesNoQuestion( buf, FALSE ) ) {
576 case TRUE:
402461ad 577 AttemptToDeleteList(info, TRUE);
85ca828a 578 break;
579 case FALSE:
580 break;
581 default:
582 Put_message ("Aborting...");
583 FreeQueue(top);
584 return(DM_NORMAL);
585 }
586 }
587 list = list->q_forw;
588 }
589 FreeQueue(top);
590 return(DM_NORMAL);
08345b74 591}
592
593/* Function Name: DeleteUser
594 * Description: Deletes a user from the database.
595 * Arguments: argc, argv - name of the user in argv[1].
596 * Returns: DM_NORMAL.
597 */
598
85ca828a 599/* ARGSUSED */
08345b74 600int
601DeleteUser(argc, argv)
602int argc;
603char ** argv;
604{
605 int status;
606 char buf[BUFSIZ];
607 char * name = argv[1]; /* name of the user we are deleting. */
461c03b6 608 struct qelem *local, *member_of = NULL;
08345b74 609
075fe5bb 610 if (!ValidName(name))
611 return(DM_NORMAL);
612
08345b74 613 if (!Confirm("Are you sure that you want to delete this user?"))
614 return(DM_NORMAL);
615
461c03b6 616 status = sms_query("delete_user", 1, &name, Scream, (char *) NULL);
08345b74 617 if (status != SMS_IN_USE && status != 0) {
075fe5bb 618 com_err(program_name, status, ": user not deleted");
08345b74 619 return(DM_NORMAL);
620 }
621 if (status == 0) {
622 sprintf(buf,"User %s deleted.", name);
623 Put_message(buf);
624 }
625 else if (status == SMS_IN_USE) {
626
627/*
628 * Check:
075fe5bb 629 * 1) Query - Delete home filesytem.
630 * 2) Query - Delete user Group.
631 * 2) Is the user an ACE of any object in the database?
632 * 3) Query - Remove user from all list of which he is a member.
08345b74 633 *
634 * If all these have been accomplished, then attempt to delete the user again.
635 */
075fe5bb 636 if ( (DeleteHomeFilesys(name, TRUE) == SUB_ERROR) ||
637 (DeleteUserGroup(name, TRUE) == SUB_ERROR) ||
638 (CheckIfAce(name, "user", TRUE) == SUB_ERROR) ||
08345b74 639 (RemoveItemFromLists(name, "user",
640 &member_of, TRUE) == SUB_ERROR) ||
641 (RealDeleteUser(name) == SUB_ERROR) ) {
08345b74 642 return(DM_NORMAL);
643 }
644 }
645
646/*
08345b74 647 * Query - Delete all empty lists created by removing this user from them.
648 */
649
08345b74 650 local = member_of;
651 while (local != NULL) {
461c03b6 652 char ** info = (char **) local->q_data;
08345b74 653 CheckListForDeletion(info[0], TRUE);
461c03b6 654 local = local->q_forw;
08345b74 655 }
656
657 FreeQueue(member_of); /* Free memory and return. */
658 return(DM_NORMAL);
659}
08345b74 660
661/*
662 * Local Variables:
663 * mode: c
664 * c-indent-level: 4
665 * c-continued-statement-offset: 4
666 * c-brace-offset: -4
667 * c-argdecl-indent: 4
668 * c-label-offset: -4
669 * End:
670 */
This page took 0.157846 seconds and 5 git commands to generate.