1 #if (!defined(lint) && !defined(SABER))
2 static char rcsid_module_c[] = "$Header$";
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.
7 * It Contains: functions for deleting users and lists.
10 * By: Chris D. Peterson
16 * Copyright 1988 by the Massachusetts Institute of Technology.
18 * For further information on copyright and distribution
19 * see the file mit-copyright.h
27 #include "mit-copyright.h"
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?
42 CheckListForDeletion(name, verbose)
46 struct qelem *elem = NULL;
48 char *args[2], buf[BUFSIZ], **info;
50 if ( (status = sms_query("count_members_of_list", 1, &name, StoreInfo,
51 (char *) &elem)) != 0) {
52 com_err(program_name, status,
53 " in DeleteList (count_members_of_list).");
56 info = (char **) elem->q_data;
57 if ( strcmp(info[NAME],"0") == 0) {
59 sprintf(buf, "Delete the empty list %s? ", name);
60 if (YesNoQuestion(buf, FALSE) != TRUE) {
61 Put_message("Aborting Deletion!");
66 args[0] = "foo"; /* not used. */
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.
77 * verbose - query user?
82 CheckAce(type, name, verbose)
86 char *args[2], buf[BUFSIZ];
89 if ( strcmp(type, "LIST") != 0 )
90 return; /* If the ace is not a list the ignore it. */
94 status = sms_query("get_ace_use", 2, args, NullFunc, (char *) NULL);
95 if (status != SMS_NO_MATCH)
96 return; /* If this query fails the ace will
97 not be deleted even if it is empty. */
99 sprintf(buf, "Delete the unused Access Control Entity (ACE) %s? ",
101 if ( YesNoQuestion(buf, FALSE) != TRUE) {
102 Put_message("Aborting Deletion!");
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.
117 /* Function Name: CheckIfAce
118 * Description: Checks to see if this is an ace of another data object.
119 * Arguments: name - name of the object.
120 * Returns: SUB_ERROR if this list is an ace, or if the query did not
125 CheckIfAce(name, type, verbose)
129 char * args[2], buf[BUFSIZ], **info;
130 struct qelem *local, *elem;
136 switch (status = sms_query("get_ace_use", 2, args,
137 StoreInfo, (char *) &elem)) {
141 local = elem = QueueTop(elem);
142 info = (char **) local->q_data;
143 if (QueueCount(elem) == 1 &&
144 !strcmp(info[0], "LIST") &&
145 !strcmp(info[1], name)) {
150 sprintf(buf, "%s %s %s", type, name,
151 "is the ACE for the following data objects:");
154 while (local != NULL) {
155 info = (char **) local->q_data;
156 if (!strcmp(info[0], "LIST") &&
157 !strcmp(info[1], name))
159 Print(CountArgs(info), info, NULL);
160 local = local->q_forw;
164 "The ACE for each of these items must be changed before");
165 sprintf(buf,"the %s %s can be deleted.\n", type, name);
170 com_err(program_name, status, " in CheckIfAce (get_ace_use).");
177 /* Function Name: RemoveItemFromLists
178 * Description: this function removes a list from all other lists of
179 * which it is a member.
180 * Arguments: name - name of the item
181 * elem - a pointer to a queue element. RETURNED
182 * verbose - verbose mode.
183 * Returns: SUB_ERROR if there is an error.
187 RemoveItemFromLists(name, type, elem, verbose)
189 struct qelem ** elem;
193 char *args[10], temp_buf[BUFSIZ];
202 * Get all list of which this item is a member, and store them in a queue.
205 status = sms_query("get_lists_of_member", 2, args, StoreInfo,
208 if (status == SMS_NO_MATCH)
211 if (status != SMS_SUCCESS) {
212 com_err(program_name, status, " in DeleteList (get_lists_of_member).");
217 * If verbose mode, ask user of we should remove our list from
221 local = *elem = QueueTop(*elem);
222 lists = QueueCount(*elem);
226 sprintf(temp_buf, "%s %s is a member of %d other list%s.\n", type,
227 name, lists, ((lists == 1) ? "" : "s") );
228 Put_message(temp_buf);
229 while (local != NULL) {
230 char ** info = (char **) local->q_data;
231 Print( 1, &info[GLOM_NAME], (char *) NULL);
232 local = local->q_forw;
234 Put_message(" "); /* Blank Line. */
235 sprintf(temp_buf,"Remove %s %s from these lists? ", type, name);
236 if (YesNoQuestion(temp_buf, FALSE) != TRUE) {
237 Put_message("Aborting...");
245 * Remove this list from all lists that it is a member of.
249 args[DM_MEMBER] = name;
250 args[DM_TYPE] = type;
251 while (local != NULL) {
252 char ** info = (char **) local->q_data;
253 args[DM_LIST] = info[GLOM_NAME];
254 if ( (status = sms_query("delete_member_from_list",
255 3, args, Scream, NULL)) != 0) {
256 com_err(program_name, status, " in delete_member\nAborting\n");
260 local = local->q_forw;
265 /* Function Name: RemoveMembersOfList
266 * Description: Deletes the members of the list.
267 * Arguments: name - name of the list.
268 * verbose - query user, about deletion?
269 * Returns: SUB_ERROR - if we could not delete, or the user abouted.
273 RemoveMembersOfList(name, verbose)
277 char buf[BUFSIZ], *args[10];
278 struct qelem *local, *elem = NULL;
281 * Get the members of this list.
283 status = sms_query("get_members_of_list", 1, &name, StoreInfo,
285 if (status == SMS_NO_MATCH)
289 com_err(program_name, status, " in DeleteList (get_members_of_list).");
293 * If verbose mode, then ask the user if we should delete.
295 local = elem = QueueTop(elem);
296 if ( (members = QueueCount(elem)) == 0)
299 sprintf(buf, "List %s has %d member%s:", name, QueueCount(elem),
300 ((members == 1) ? "" : "s") );
302 Put_message(" "); /* Blank Line. */
303 while (local != NULL) {
304 char ** info = (char **) local->q_data;
305 Print( CountArgs(info), info, NULL);
306 local = local->q_forw;
308 Put_message(" "); /* Blank Line. */
309 sprintf(buf, "Remove th%s member%s from list %s? ",
310 ((members == 1) ? "is" : "ese"),
311 ((members == 1) ? "" : "s"), name );
312 if ( YesNoQuestion(buf, FALSE) != TRUE) {
313 Put_message("Aborting...");
319 * Perform The Removal.
323 while (local != NULL) {
324 char ** info = (char **) local->q_data;
327 if ( (status = sms_query("delete_member_from_list",
328 3, args, Scream, NULL)) != 0) {
329 com_err(program_name, status, " in delete_member\nAborting\n");
333 local = local->q_forw;
338 /* Function Name: DeleteUserGroup
339 * Description: Deletes the list given by name if it exists.
340 * intended to be used to delete user groups
341 * Arguments: name - the name of the list to delete.
342 * verbose - flag that if TRUE queries the user to
343 * ask if list should be deleted.
344 * Returns: SMS_ERROR if there is an error.
348 DeleteUserGroup(name, verbose)
353 char buf[BUFSIZ], *args[10];
355 status = sms_query("get_list_info", 1, &name, NullFunc, (char *) NULL);
358 sprintf(buf, "There is also a list named %s, delete it?", name);
359 ans = YesNoQuestion(buf, FALSE);
361 Put_message("Leaving group alone.");
365 Put_message("Aborting...\n");
369 /* ans == TRUE || ~verbose */
370 args[0] = "foo"; /* not used. */
374 else if (status != SMS_NO_MATCH) {
375 com_err(program_name, status, " Aborting Delete User.");
381 /* Function Name: DeleteHomeFilesys
382 * Description: Delete the home filesystem for the named user.
383 * Arguments: name - name of the user (and filsystem) to delete.
384 * verbose - if TRUE query user.
385 * Returns: SUB_NORMAL if home filesystem deleted, or nonexistant.
389 DeleteHomeFilesys(name, verbose)
396 switch (status = sms_query("get_filesys_by_label", 1, &name, NullFunc,
402 sprintf(buf, "Delete the filesystem named %s (y/n)?", name);
403 switch (YesNoQuestion(buf, FALSE)) {
405 Put_message("Filesystem Not Deleted, continuing...\n");
410 Put_message("Filesystem Not Deleted, aborting...\n\n");
414 if ( (status = sms_query("delete_filesys", 1, &name, Scream,
415 (char *) NULL) ) != SMS_SUCCESS) {
416 com_err(program_name, status, " in delete_filesys.");
420 Put_message("Filesystem Successfully Deleted.");
423 com_err(program_name, status, " in get_filesystem_by_label).");
429 /* Function Name: RealDeleteUser
430 * Description: Just Deletes the user.
431 * Arguments: name - name of User to delete
432 * Returns: SUB_ERROR if the deletion failed.
442 if ( (status = sms_query("delete_user", 1, &name, Scream,
443 (char *) NULL)) != SMS_SUCCESS) {
444 com_err(program_name, status, ": user not deleted");
447 (void) sprintf(buf, "User %s deleted.", name);
452 /* Function Name: RealDeleteList
453 * Description: Just Deletes the list.
454 * Arguments: name - name of list to delete
455 * Returns: SUB_ERROR if the deletion failed.
465 if ( (status = sms_query("delete_list", 1, &name, Scream,
466 (char *) NULL)) != SMS_SUCCESS) {
467 com_err(program_name, status, ": list not deleted");
470 (void) sprintf(buf, "List %s deleted.", name);
476 /* Function Name: AttemptToDeleteList
477 * Description: Atempts to delete list, in the following manner:
478 * 1) try to delet it, if this fails in a known error then
479 * a) try to clean up each of those known methods, or
480 * at least explain why we failed.
481 * Arguments: list_info - info about this list.
482 * ask_first - (T/F) query user before preparing for deletion,
484 * Returns: none - all is taken care of and error messages printed
485 * one way or the other.
489 AttemptToDeleteList(list_info, ask_first)
494 struct qelem *local, *member_of;
495 char *name = list_info[L_NAME];
499 * Attempt delete. - will only work if:
500 * 1) This list has no members.
501 * 2) This list in a member of no other lists.
502 * 3) This list is not an ace of another object.
505 switch (status = sms_query("delete_list", 1, &name,
506 Scream, (char *) NULL)) {
508 Put_message("List Sucessfully Deleted.");
509 CheckAce(list_info[L_ACE_TYPE], list_info[L_ACE_NAME], ask_first);
513 * This list is in use. Try to find out why,
514 * and for the cases where we have a good idea of
515 * what to do we will query and then do it.
518 if ( (CheckIfAce(name, "list", ask_first) == SUB_NORMAL) &&
519 (RemoveMembersOfList(name, ask_first) == SUB_NORMAL) &&
520 (RemoveItemFromLists(name, "list",
521 &member_of, ask_first) == SUB_NORMAL) &&
522 (RealDeleteList(name) == SUB_NORMAL) )
524 CheckAce(list_info[L_ACE_TYPE], list_info[L_ACE_NAME], ask_first);
526 local = QueueTop(member_of);
527 while (local != NULL) {
528 char ** info = (char **) local->q_data;
529 CheckListForDeletion(info[LM_LIST], ask_first);
530 local = local->q_forw;
532 FreeQueue(member_of);
536 com_err(program_name, status, " in DeleteList (delete_list).");
541 /* Function Name: DeleteList
542 * Description: deletes a list
543 * Arguments: argc, argv - standard SMS argc and argv.
544 * Returns: DM Status Code.
549 DeleteList(argc, argv)
554 struct qelem *top, *list;
560 switch(status = sms_query("get_list_info", 1, argv + 1,
561 StoreInfo, (char *) &list)){
564 /* case SMS_NO_WILDCARD:
565 Put_message("Wildcards are not accepted here.");
567 */ case SMS_NO_MATCH:
569 Put_message("There is no list that matches that name.");
572 com_err(program_name, status, " in DeleteList (get_list_info).");
576 top = list = QueueTop(list);
577 one_list = (QueueCount(list) == 1);
578 while (list != NULL) {
579 char ** info = (char**) list->q_data;
581 sprintf( buf, "Are you sure that you want to delete the list %s",
583 if ( Confirm(buf) ) AttemptToDeleteList(info, TRUE);
586 sprintf(buf, "Delete the list %s", info[L_NAME]);
587 switch( YesNoQuestion( buf, FALSE ) ) {
589 AttemptToDeleteList(info, TRUE);
594 Put_message ("Aborting...");
605 /* Function Name: DeleteUser
606 * Description: Deletes a user from the database.
607 * Arguments: argc, argv - name of the user in argv[1].
608 * Returns: DM_NORMAL.
613 DeleteUser(argc, argv)
619 char * name = argv[1]; /* name of the user we are deleting. */
620 struct qelem *local, *member_of = NULL;
622 if (!ValidName(name))
625 if (!Confirm("Are you sure that you want to delete this user?"))
628 status = sms_query("delete_user", 1, &name, Scream, (char *) NULL);
629 if (status != SMS_IN_USE && status != 0) {
630 com_err(program_name, status, ": user not deleted");
634 sprintf(buf,"User %s deleted.", name);
637 /* Design decision not to allow registered users to be deleted.
639 Put_message("Sorry, registered users cannot be deleted.");
641 else if (status == SMS_IN_USE) {
645 * 1) Query - Delete home filesytem.
646 * 2) Query - Delete user Group.
647 * 2) Is the user an ACE of any object in the database?
648 * 3) Query - Remove user from all list of which he is a member.
650 * If all these have been accomplished, then attempt to delete the user again.
652 if ( (DeleteHomeFilesys(name, TRUE) == SUB_ERROR) ||
653 (DeleteUserGroup(name, TRUE) == SUB_ERROR) ||
654 (CheckIfAce(name, "user", TRUE) == SUB_ERROR) ||
655 (RemoveItemFromLists(name, "user",
656 &member_of, TRUE) == SUB_ERROR) ||
657 (RealDeleteUser(name) == SUB_ERROR) ) {
663 * Query - Delete all empty lists created by removing this user from them.
667 while (local != NULL) {
668 char ** info = (char **) local->q_data;
669 CheckListForDeletion(info[0], TRUE);
670 local = local->q_forw;
673 FreeQueue(member_of); /* Free memory and return. */
682 * c-continued-statement-offset: 4
684 * c-argdecl-indent: 4