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