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