]> andersk Git - moira.git/blame - clients/moira/delete.c
Did some casting for ANSI standard.
[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) {
219bbe64 143 sprintf(buf, "%s %s %s", type, name,
144 "is the ACE for the following data objects:");
075fe5bb 145 Put_message(buf);
219bbe64 146 Put_message("");
075fe5bb 147 while (local != NULL) {
148 char ** info = (char **) local->q_data;
149 Print( CountArgs(info), info, NULL);
150 local = local->q_forw;
151 }
219bbe64 152 Put_message("");
075fe5bb 153 Put_message(
154 "The ACE for each of these items must be changed before");
155 sprintf(buf,"the %s %s can be deleted.\n", type, name);
156 Put_message(buf);
08345b74 157 }
075fe5bb 158 break;
159 default:
160 com_err(program_name, status, " in CheckIfAce (get_ace_use).");
161 return(SUB_ERROR);
08345b74 162 }
163 FreeQueue(elem);
164 return(SUB_ERROR);
08345b74 165}
166
167/* Function Name: RemoveItemFromLists
168 * Description: this function removes a list from all other lists of
169 * which it is a member.
075fe5bb 170 * Arguments: name - name of the item
08345b74 171 * elem - a pointer to a queue element. RETURNED
172 * verbose - verbose mode.
173 * Returns: SUB_ERROR if there is an error.
174 */
175
176int
461c03b6 177RemoveItemFromLists(name, type, elem, verbose)
178char * name, *type;
179struct qelem ** elem;
08345b74 180int verbose;
181{
461c03b6 182 struct qelem *local;
85ca828a 183 char *args[10], temp_buf[BUFSIZ];
0a2c64cb 184 int lists;
075fe5bb 185 register int status;
08345b74 186
187 args[0] = type;
188 args[1] = name;
189 *elem = NULL;
190
191/*
075fe5bb 192 * Get all list of which this item is a member, and store them in a queue.
08345b74 193 */
194
85ca828a 195 status = sms_query("get_lists_of_member", 2, args, StoreInfo,
08345b74 196 (char *) elem);
197
198 if (status == SMS_NO_MATCH)
199 return(SUB_NORMAL);
200
402461ad 201 if (status != SMS_SUCCESS) {
461c03b6 202 com_err(program_name, status, " in DeleteList (get_lists_of_member).");
08345b74 203 return(SUB_ERROR);
204 }
205
206/*
207 * If verbose mode, ask user of we should remove our list from
208 * all these lists.
209 */
210
075fe5bb 211 local = *elem = QueueTop(*elem);
0a2c64cb 212 lists = QueueCount(*elem);
213 if (lists == 0)
214 return(SUB_NORMAL);
08345b74 215 if (verbose) {
0a2c64cb 216 sprintf(temp_buf, "%s %s is a member of %d other list%s.\n", type,
217 name, lists, ((lists == 1) ? "" : "s") );
461c03b6 218 Put_message(temp_buf);
08345b74 219 while (local != NULL) {
461c03b6 220 char ** info = (char **) local->q_data;
402461ad 221 Print( 1, &info[GLOM_NAME], (char *) NULL);
08345b74 222 local = local->q_forw;
223 }
0a2c64cb 224 Put_message(" "); /* Blank Line. */
461c03b6 225 sprintf(temp_buf,"Remove %s %s from these lists? ", type, name);
075fe5bb 226 if (YesNoQuestion(temp_buf, FALSE) != TRUE) {
08345b74 227 Put_message("Aborting...");
228 FreeQueue(*elem);
075fe5bb 229 *elem = NULL;
08345b74 230 return(SUB_ERROR);
231 }
232 }
233
234/*
235 * Remove this list from all lists that it is a member of.
236 */
237
238 local = *elem;
075fe5bb 239 args[DM_MEMBER] = name;
402461ad 240 args[DM_TYPE] = type;
08345b74 241 while (local != NULL) {
461c03b6 242 char ** info = (char **) local->q_data;
075fe5bb 243 args[DM_LIST] = info[GLOM_NAME];
08345b74 244 if ( (status = sms_query("delete_member_from_list",
245 3, args, Scream, NULL)) != 0) {
461c03b6 246 com_err(program_name, status, " in delete_member\nAborting\n");
08345b74 247 FreeQueue(*elem);
248 return(SUB_ERROR);
249 }
250 local = local->q_forw;
251 }
252 return(SUB_NORMAL);
253}
254
255/* Function Name: RemoveMembersOfList
256 * Description: Deletes the members of the list.
257 * Arguments: name - name of the list.
258 * verbose - query user, about deletion?
259 * Returns: SUB_ERROR - if we could not delete, or the user abouted.
260 */
261
262int
461c03b6 263RemoveMembersOfList(name, verbose)
08345b74 264char * name;
265Bool verbose;
266{
461c03b6 267 char buf[BUFSIZ], *args[10];
268 struct qelem *local, *elem = NULL;
0a2c64cb 269 int status, members;
08345b74 270/*
271 * Get the members of this list.
272 */
08345b74 273 status = sms_query("get_members_of_list", 1, &name, StoreInfo,
274 (char *) &elem);
461c03b6 275 if (status == SMS_NO_MATCH)
276 return(SUB_NORMAL);
08345b74 277
278 if (status != 0) {
461c03b6 279 com_err(program_name, status, " in DeleteList (get_members_of_list).");
08345b74 280 return(SUB_ERROR);
281 }
08345b74 282/*
283 * If verbose mode, then ask the user if we should delete.
284 */
85ca828a 285 local = elem = QueueTop(elem);
0a2c64cb 286 if ( (members = QueueCount(elem)) == 0)
287 return(SUB_NORMAL);
08345b74 288 if (verbose) {
075fe5bb 289 sprintf(buf, "List %s has %d member%s:", name, QueueCount(elem),
0a2c64cb 290 ((members == 1) ? "" : "s") );
08345b74 291 Put_message(buf);
0a2c64cb 292 Put_message(" "); /* Blank Line. */
08345b74 293 while (local != NULL) {
461c03b6 294 char ** info = (char **) local->q_data;
08345b74 295 Print( CountArgs(info), info, NULL);
296 local = local->q_forw;
297 }
0a2c64cb 298 Put_message(" "); /* Blank Line. */
075fe5bb 299 sprintf(buf, "Remove th%s member%s from list %s? ",
0a2c64cb 300 ((members == 1) ? "is" : "ese"),
219bbe64 301 ((members == 1) ? "" : "s"), name );
075fe5bb 302 if ( YesNoQuestion(buf, FALSE) != TRUE) {
08345b74 303 Put_message("Aborting...");
461c03b6 304 FreeQueue(elem);
08345b74 305 return(SUB_ERROR);
306 }
307 }
08345b74 308/*
309 * Perform The Removal.
310 */
08345b74 311 local = elem;
312 args[0] = name;
313 while (local != NULL) {
461c03b6 314 char ** info = (char **) local->q_data;
08345b74 315 args[1] = info[0];
316 args[2] = info[1];
317 if ( (status = sms_query("delete_member_from_list",
318 3, args, Scream, NULL)) != 0) {
461c03b6 319 com_err(program_name, status, " in delete_member\nAborting\n");
08345b74 320 FreeQueue(elem);
321 return(SUB_ERROR);
322 }
323 local = local->q_forw;
324 }
325 return(SUB_NORMAL);
326}
327
08345b74 328/* Function Name: DeleteUserGroup
329 * Description: Deletes the list given by name if it exists.
330 * intended to be used to delete user groups
331 * Arguments: name - the name of the list to delete.
332 * verbose - flag that if TRUE queries the user to
333 * ask if list should be deleted.
334 * Returns: SMS_ERROR if there is an error.
335 */
336
337int
338DeleteUserGroup(name, verbose)
339char * name;
340Bool verbose;
341{
342 int status, ans;
461c03b6 343 char buf[BUFSIZ], *args[10];
08345b74 344
345 status = sms_query("get_list_info", 1, &name, NullFunc, (char *) NULL);
346 if (status == 0) {
347 if (verbose) {
348 sprintf(buf, "There is also a list named %s, delete it?", name);
075fe5bb 349 ans = YesNoQuestion(buf, FALSE);
08345b74 350 if (ans == FALSE) {
351 Put_message("Leaving group alone.");
461c03b6 352 return(SUB_NORMAL);
08345b74 353 }
354 if (ans < 0) {
355 Put_message("Aborting...\n");
356 return(SUB_ERROR);
357 }
358 }
359 /* ans == TRUE || ~verbose */
360 args[0] = "foo"; /* not used. */
361 args[1] = name;
362 DeleteList(2, args);
363 }
364 else if (status != SMS_NO_MATCH) {
461c03b6 365 com_err(program_name, status, " Aborting Delete User.");
08345b74 366 return(SUB_ERROR);
367 }
461c03b6 368 return(SUB_NORMAL);
08345b74 369}
370
371/* Function Name: DeleteHomeFilesys
372 * Description: Delete the home filesystem for the named user.
373 * Arguments: name - name of the user (and filsystem) to delete.
374 * verbose - if TRUE query user.
375 * Returns: SUB_NORMAL if home filesystem deleted, or nonexistant.
376 */
377
378int
379DeleteHomeFilesys(name, verbose)
380char * name;
381Bool verbose;
382{
075fe5bb 383 int status;
08345b74 384 char buf[BUFSIZ];
385
075fe5bb 386 switch (status = sms_query("get_filesys_by_label", 1, &name, NullFunc,
387 (char *) NULL)) {
388 case SMS_NO_MATCH:
389 break;
390 case SMS_SUCCESS:
08345b74 391 if (verbose) {
392 sprintf(buf, "Delete the filesystem named %s (y/n)?", name);
075fe5bb 393 switch (YesNoQuestion(buf, FALSE)) {
394 case FALSE:
395 Put_message("Filesystem Not Deleted, continuing...\n");
396 return(SUB_NORMAL);
397 case TRUE:
398 break;
399 default:
08345b74 400 Put_message("Filesystem Not Deleted, aborting...\n\n");
461c03b6 401 return(SUB_ERROR);
08345b74 402 }
403 }
075fe5bb 404 if ( (status = sms_query("delete_filesys", 1, &name, Scream,
405 (char *) NULL) ) != SMS_SUCCESS) {
406 com_err(program_name, status, " in delete_filesys.");
08345b74 407 return(SUB_ERROR);
408 }
075fe5bb 409 else
410 Put_message("Filesystem Successfully Deleted.");
411 break;
412 default:
413 com_err(program_name, status, " in get_filesystem_by_label).");
414 return(SUB_ERROR);
08345b74 415 }
075fe5bb 416 return(SUB_NORMAL);
08345b74 417}
418
075fe5bb 419/* Function Name: RealDeleteUser
420 * Description: Just Deletes the user.
421 * Arguments: name - name of User to delete
422 * Returns: SUB_ERROR if the deletion failed.
08345b74 423 */
424
075fe5bb 425static int
426RealDeleteUser(name)
08345b74 427char * name;
08345b74 428{
075fe5bb 429 char buf[BUFSIZ];
430 int status;
431
432 if ( (status = sms_query("delete_user", 1, &name, Scream,
433 (char *) NULL)) != SMS_SUCCESS) {
434 com_err(program_name, status, ": user not deleted");
08345b74 435 return(SUB_ERROR);
436 }
075fe5bb 437 (void) sprintf(buf, "User %s deleted.", name);
438 Put_message(buf);
08345b74 439 return(SUB_NORMAL);
440}
441
85ca828a 442/* Function Name: RealDeleteList
443 * Description: Just Deletes the list.
444 * Arguments: name - name of list to delete
445 * Returns: SUB_ERROR if the deletion failed.
08345b74 446 */
447
85ca828a 448static int
449RealDeleteList(name)
450char * name;
08345b74 451{
85ca828a 452 char buf[BUFSIZ];
461c03b6 453 int status;
08345b74 454
85ca828a 455 if ( (status = sms_query("delete_list", 1, &name, Scream,
456 (char *) NULL)) != SMS_SUCCESS) {
457 com_err(program_name, status, ": list not deleted");
458 return(SUB_ERROR);
08345b74 459 }
402461ad 460 (void) sprintf(buf, "List %s deleted.", name);
85ca828a 461 Put_message(buf);
402461ad 462 Put_message("");
85ca828a 463 return(SUB_NORMAL);
464}
08345b74 465
85ca828a 466/* Function Name: AttemptToDeleteList
467 * Description: Atempts to delete list, in the following manner:
468 * 1) try to delet it, if this fails in a known error then
469 * a) try to clean up each of those known methods, or
470 * at least explain why we failed.
402461ad 471 * Arguments: list_info - info about this list.
85ca828a 472 * ask_first - (T/F) query user before preparing for deletion,
473 * and cleaning up?
474 * Returns: none - all is taken care of and error messages printed
475 * one way or the other.
08345b74 476 */
477
85ca828a 478void
402461ad 479AttemptToDeleteList(list_info, ask_first)
480char ** list_info;
85ca828a 481Bool ask_first;
482{
483 int status;
402461ad 484 struct qelem *local, *member_of;
485 char *name = list_info[L_NAME];
486 member_of = NULL;
85ca828a 487
488 /*
489 * Attempt delete. - will only work if:
490 * 1) This list has no members.
491 * 2) This list in a member of no other lists.
075fe5bb 492 * 3) This list is not an ace of another object.
85ca828a 493 */
494
495 switch (status = sms_query("delete_list", 1, &name,
496 Scream, (char *) NULL)) {
497 case SMS_SUCCESS:
08345b74 498 Put_message("List Sucessfully Deleted.");
0a2c64cb 499 CheckAce(list_info[L_ACE_TYPE], list_info[L_ACE_NAME], ask_first);
85ca828a 500 break;
501 case SMS_IN_USE:
502 /*
503 * This list is in use. Try to find out why,
504 * and for the cases where we have a good idea of
505 * what to do we will query and then do it.
506 */
507
075fe5bb 508 if ( (CheckIfAce(name, "list", ask_first) == SUB_NORMAL) &&
402461ad 509 (RemoveMembersOfList(name, ask_first) == SUB_NORMAL) &&
85ca828a 510 (RemoveItemFromLists(name, "list",
511 &member_of, ask_first) == SUB_NORMAL) &&
85ca828a 512 (RealDeleteList(name) == SUB_NORMAL) )
513 { /* if... */
075fe5bb 514 CheckAce(list_info[L_ACE_TYPE], list_info[L_ACE_NAME], ask_first);
08345b74 515
0a2c64cb 516 local = QueueTop(member_of);
85ca828a 517 while (local != NULL) {
402461ad 518 char ** info = (char **) local->q_data;
85ca828a 519 CheckListForDeletion(info[LM_LIST], ask_first);
520 local = local->q_forw;
521 }
402461ad 522 FreeQueue(member_of);
08345b74 523 }
85ca828a 524 break;
525 default:
526 com_err(program_name, status, " in DeleteList (delete_list).");
527 break;
08345b74 528 }
08345b74 529}
530
85ca828a 531/* Function Name: DeleteList
532 * Description: deletes a list
533 * Arguments: argc, argv - standard SMS argc and argv.
534 * Returns: DM Status Code.
08345b74 535 */
536
85ca828a 537/* ARGSUSED */
538int
539DeleteList(argc, argv)
540int argc;
541char *argv[];
08345b74 542{
543 char buf[BUFSIZ];
85ca828a 544 struct qelem *top, *list;
545 register int status;
546 Bool one_list;
08345b74 547
85ca828a 548 list = NULL;
549
550 switch(status = sms_query("get_list_info", 1, argv + 1, StoreInfo, &list)){
551 case SMS_SUCCESS:
552 break;
553/* case SMS_NO_WILDCARD:
554 Put_message("Wildcards are not accepted here.");
555 return(DM_NORMAL);
556*/ case SMS_NO_MATCH:
557 case SMS_LIST:
402461ad 558 Put_message("There is no list that matches that name.");
85ca828a 559 return(DM_NORMAL);
560 default:
561 com_err(program_name, status, " in DeleteList (get_list_info).");
562 return(DM_NORMAL);
08345b74 563 }
85ca828a 564
565 top = list = QueueTop(list);
566 one_list = (QueueCount(list) == 1);
567 while (list != NULL) {
568 char ** info = (char**) list->q_data;
569 if (one_list) {
402461ad 570 sprintf( buf, "Are you sure that you want to delete the list %s",
571 info[L_NAME]);
572 if ( Confirm(buf) ) AttemptToDeleteList(info, TRUE);
85ca828a 573 }
574 else {
575 sprintf(buf, "Delete the list %s", info[L_NAME]);
576 switch( YesNoQuestion( buf, FALSE ) ) {
577 case TRUE:
402461ad 578 AttemptToDeleteList(info, TRUE);
85ca828a 579 break;
580 case FALSE:
581 break;
582 default:
583 Put_message ("Aborting...");
584 FreeQueue(top);
585 return(DM_NORMAL);
586 }
587 }
588 list = list->q_forw;
589 }
590 FreeQueue(top);
591 return(DM_NORMAL);
08345b74 592}
593
594/* Function Name: DeleteUser
595 * Description: Deletes a user from the database.
596 * Arguments: argc, argv - name of the user in argv[1].
597 * Returns: DM_NORMAL.
598 */
599
85ca828a 600/* ARGSUSED */
08345b74 601int
602DeleteUser(argc, argv)
603int argc;
604char ** argv;
605{
606 int status;
607 char buf[BUFSIZ];
608 char * name = argv[1]; /* name of the user we are deleting. */
461c03b6 609 struct qelem *local, *member_of = NULL;
08345b74 610
075fe5bb 611 if (!ValidName(name))
612 return(DM_NORMAL);
613
08345b74 614 if (!Confirm("Are you sure that you want to delete this user?"))
615 return(DM_NORMAL);
616
461c03b6 617 status = sms_query("delete_user", 1, &name, Scream, (char *) NULL);
08345b74 618 if (status != SMS_IN_USE && status != 0) {
075fe5bb 619 com_err(program_name, status, ": user not deleted");
08345b74 620 return(DM_NORMAL);
621 }
622 if (status == 0) {
623 sprintf(buf,"User %s deleted.", name);
624 Put_message(buf);
625 }
626 else if (status == SMS_IN_USE) {
627
628/*
629 * Check:
075fe5bb 630 * 1) Query - Delete home filesytem.
631 * 2) Query - Delete user Group.
632 * 2) Is the user an ACE of any object in the database?
633 * 3) Query - Remove user from all list of which he is a member.
08345b74 634 *
635 * If all these have been accomplished, then attempt to delete the user again.
636 */
075fe5bb 637 if ( (DeleteHomeFilesys(name, TRUE) == SUB_ERROR) ||
638 (DeleteUserGroup(name, TRUE) == SUB_ERROR) ||
639 (CheckIfAce(name, "user", TRUE) == SUB_ERROR) ||
08345b74 640 (RemoveItemFromLists(name, "user",
641 &member_of, TRUE) == SUB_ERROR) ||
642 (RealDeleteUser(name) == SUB_ERROR) ) {
08345b74 643 return(DM_NORMAL);
644 }
645 }
646
647/*
08345b74 648 * Query - Delete all empty lists created by removing this user from them.
649 */
650
08345b74 651 local = member_of;
652 while (local != NULL) {
461c03b6 653 char ** info = (char **) local->q_data;
08345b74 654 CheckListForDeletion(info[0], TRUE);
461c03b6 655 local = local->q_forw;
08345b74 656 }
657
658 FreeQueue(member_of); /* Free memory and return. */
659 return(DM_NORMAL);
660}
08345b74 661
662/*
663 * Local Variables:
664 * mode: c
665 * c-indent-level: 4
666 * c-continued-statement-offset: 4
667 * c-brace-offset: -4
668 * c-argdecl-indent: 4
669 * c-label-offset: -4
670 * End:
671 */
This page took 0.162799 seconds and 5 git commands to generate.