]> andersk Git - moira.git/blame - clients/moira/lists.c
Call mr_access() in AddList so we can bomb out before asking the user
[moira.git] / clients / moira / lists.c
CommitLineData
c441a31a 1/* $Id$
7ac48069 2 *
3 * This is the file lists.c for the Moira Client, which allows users
59ec8dae 4 * to quickly and easily maintain most parts of the Moira database.
0a2c64cb 5 * It Contains: All list manipulation functions, except delete.
5eaef520 6 *
0a2c64cb 7 * Created: 4/12/88
8 * By: Chris D. Peterson
08345b74 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>
375e818a 17#include <mrclient.h>
8defc06b 18#include <moira_site.h>
0a2c64cb 19#include "defs.h"
20#include "f_defs.h"
08345b74 21#include "globals.h"
08345b74 22
7ac48069 23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26
27RCSID("$Header$");
28
600b459e 29struct mqelem *GetListInfo(int type, char *name1, char *name2);
7ac48069 30char **AskListInfo(char **info, Bool name);
31int AddList(int argc, char **argv);
17bbb3bc 32void ListMembersByType(char *type, int tags);
7ac48069 33int GetMemberInfo(char *action, char **ret_argv);
34
08345b74 35#define LIST 0
36#define MEMBERS 1
37#define GLOM 2
075fe5bb 38#define ACE_USE 3
08345b74 39
85ca828a 40#define DEFAULT_ACTIVE DEFAULT_YES
41#define DEFAULT_PUBLIC DEFAULT_YES
42#define DEFAULT_HIDDEN DEFAULT_NO
43#define DEFAULT_MAILLIST DEFAULT_YES
44#define DEFAULT_GROUP DEFAULT_NO
45#define DEFAULT_GID UNIQUE_GID
c55f98d2 46#define DEFAULT_NFSGROUP DEFAULT_NO
075fe5bb 47#define DEFAULT_ACE_TYPE "user"
48#define DEFAULT_ACE_NAME (user)
c9bbc3e4 49#define DEFAULT_MEMACE_TYPE "NONE"
50#define DEFAULT_MEMACE_NAME "NONE"
85ca828a 51#define DEFAULT_DESCRIPTION DEFAULT_COMMENT
52
461c03b6 53/* globals only for this file. */
54
85ca828a 55static char current_list[BUFSIZ];
461c03b6 56
17bbb3bc 57
075fe5bb 58/* Function Name: PrintListAce
59 * Description: This function prints the list ace information.
402461ad 60 * Arguments: info - an info structure.
61 * Returns: none.
62 */
63
5eaef520 64static void PrintListAce(char **info)
402461ad 65{
5eaef520 66 char buf[BUFSIZ];
402461ad 67
5eaef520 68 sprintf(buf, "Item: %-20s Name: %s", info[ACE_TYPE], info[ACE_NAME]);
69 Put_message(buf);
402461ad 70}
71
08345b74 72/* Function Name: PrintListInfo
73 * Description: This function Prints out the List info in a coherent form.
74 * Arguments: info - the List info.
75 * Returns: none.
76 */
77
5eaef520 78static void PrintListInfo(char **info)
08345b74 79{
5eaef520 80 char buf[BUFSIZ];
81
82 Put_message(" ");
83 sprintf(buf, "%20sList: %s", "", info[L_NAME]);
84 Put_message(buf);
85 sprintf(buf, "Description: %s", info[L_DESC]);
86 Put_message(buf);
87 if (atoi(info[L_MAILLIST]))
88 Put_message("This list is a mailing list.");
89 else
90 Put_message("This list is NOT a mailing list.");
91 if (atoi(info[L_GROUP]))
92 {
c55f98d2 93 sprintf(buf, "This list is a Group%s and its ID number is %s",
94 atoi(info[L_NFSGROUP]) ? " and an NFS Group," : "",
5eaef520 95 info[L_GID]);
96 Put_message(buf);
08345b74 97 }
5eaef520 98 else
99 Put_message("This list is NOT a Group.");
100
101 if (!strcmp(info[L_ACE_TYPE], "NONE"))
102 Put_message("This list has no Administrator, how strange?!");
103 else
104 {
105 sprintf(buf, "The Administrator of this list is the %s: %s",
106 info[L_ACE_TYPE], info[L_ACE_NAME]);
107 Put_message(buf);
08345b74 108 }
109
c9bbc3e4 110 if (strcmp(info[L_MEMACE_TYPE], "NONE"))
111 {
112 sprintf(buf, "The Membership Administrator of this list is the %s: %s",
113 info[L_MEMACE_TYPE], info[L_MEMACE_NAME]);
114 Put_message(buf);
115 }
116
5eaef520 117 sprintf(buf, "This list is: %s, %s, and %s",
118 atoi(info[L_ACTIVE]) ? "active" : "inactive",
119 atoi(info[L_PUBLIC]) ? "public" : "private",
120 atoi(info[L_HIDDEN]) ? "hidden" : "visible");
121 Put_message(buf);
122 sprintf(buf, MOD_FORMAT, info[L_MODBY], info[L_MODTIME], info[L_MODWITH]);
123 Put_message(buf);
08345b74 124}
125
126/* Function Name: GetListInfo
127 * Description: Stores all info about a group of lists in a queue.
128 * Arguments: type - type of info to store.
129 * name - name of the info.
130 * Returns: the first element in the queue.
131 */
132
600b459e 133struct mqelem *GetListInfo(int type, char *name1, char *name2)
08345b74 134{
5eaef520 135 char *args[2];
600b459e 136 struct mqelem *elem = NULL;
44d12d58 137 int status;
08345b74 138
5eaef520 139 switch (type)
140 {
08345b74 141 case LIST:
5eaef520 142 args[0] = name1;
7ac48069 143 if ((status = do_mr_query("get_list_info", 1, args, StoreInfo, &elem)))
5eaef520 144 {
145 com_err(program_name, status, " in get_list_info");
146 return NULL;
08345b74 147 }
5eaef520 148 break;
08345b74 149 case MEMBERS:
5eaef520 150 args[0] = name1;
151 if ((status = do_mr_query("get_members_of_list", 1, args,
7ac48069 152 StoreInfo, &elem)))
5eaef520 153 {
154 com_err(program_name, status, " in get_members_of_list");
155 return NULL;
08345b74 156 }
5eaef520 157 break;
08345b74 158 case GLOM:
5eaef520 159 args[0] = name1;
160 args[1] = name2;
5f7b0741 161 if (!strcmp(name1, "MACHINE"))
162 args[1] = canonicalize_hostname(strdup(name2));
5eaef520 163 if ((status = do_mr_query("get_lists_of_member", 2, args,
7ac48069 164 StoreInfo, &elem)))
5eaef520 165 {
166 com_err(program_name, status, " in get_list_of_members");
167 return NULL;
08345b74 168 }
5eaef520 169 break;
075fe5bb 170 case ACE_USE:
5eaef520 171 args[0] = name1;
172 args[1] = name2;
7ac48069 173 if ((status = do_mr_query("get_ace_use", 2, args, StoreInfo, &elem)))
5eaef520 174 {
175 com_err(program_name, status, " in get_ace_use");
176 return NULL;
08345b74 177 }
5eaef520 178 break;
08345b74 179 }
5eaef520 180 return QueueTop(elem);
181}
08345b74 182
183/* Function Name: AskListInfo.
5eaef520 184 * Description: This function askes the user for information about a
08345b74 185 * machine and saves it into a structure.
186 * Arguments: info - a pointer the the structure to put the
187 * info into.
188 * name - add a newname field? (T/F)
189 * Returns: SUB_ERROR or SUB_NORMAL.
190 */
191
5eaef520 192char **AskListInfo(char **info, Bool name)
08345b74 193{
5eaef520 194 char temp_buf[BUFSIZ], *newname;
195
196 Put_message(" ");
197 sprintf(temp_buf, "Setting information of list %s.", info[L_NAME]);
198 Put_message(temp_buf);
199 Put_message(" ");
200
201 if (name)
202 {
203 while (1)
204 {
7ac48069 205 newname = strdup(info[L_NAME]);
5eaef520 206 if (GetValueFromUser("The new name for this list", &newname) ==
207 SUB_ERROR)
208 return NULL;
209 if (ValidName(newname))
210 break;
5df6f171 211 }
08345b74 212 }
5eaef520 213 if (GetYesNoValueFromUser("Is this an active list", &info[L_ACTIVE]) ==
214 SUB_ERROR)
215 return NULL;
216 if (GetYesNoValueFromUser("Is this a public list", &info[L_PUBLIC]) ==
217 SUB_ERROR)
218 return NULL;
219 if (GetYesNoValueFromUser("Is this a hidden list", &info[L_HIDDEN]) ==
220 SUB_ERROR)
221 return NULL;
222 if (GetYesNoValueFromUser("Is this a maillist", &info[L_MAILLIST]) ==
223 SUB_ERROR)
224 return NULL;
225 if (GetYesNoValueFromUser("Is this a group", &info[L_GROUP]) == SUB_ERROR)
226 return NULL;
227 if (atoi(info[L_GROUP]))
228 {
c55f98d2 229 if (GetYesNoValueFromUser("Is this an NFS group", &info[L_NFSGROUP]) ==
230 SUB_ERROR)
231 return NULL;
eb5eb5de 232 if (GetValueFromUser("What is the GID for this group.", &info[L_GID]) ==
233 SUB_ERROR)
5eaef520 234 return NULL;
20b2d2f0 235 }
08345b74 236
66e5e450 237 do {
238 if (GetTypeFromUser("What Type of Administrator", "ace_type",
239 &info[L_ACE_TYPE]) == SUB_ERROR)
240 return NULL;
241 if (strcasecmp(info[L_ACE_TYPE], "none"))
242 {
243 sprintf(temp_buf, "Which %s will be the administrator of this list: ",
244 info[L_ACE_TYPE]);
245 if (GetValueFromUser(temp_buf, &info[L_ACE_NAME]) == SUB_ERROR)
246 return NULL;
247 }
248 else
249 {
250 Put_message("Setting the administrator of this list to 'NONE'");
251 Put_message("will make you unable to further modify the list.");
252 if (YesNoQuestion("Do you really want to do this?", FALSE) == TRUE)
253 break;
254 }
255 } while (!strcasecmp(info[L_ACE_TYPE], "none"));
256
5cef9ecf 257 if (!strcasecmp(info[L_ACE_TYPE], "kerberos"))
258 {
259 char *canon;
260
261 mrcl_validate_kerberos_member(info[L_ACE_NAME], &canon);
262 if (mrcl_get_message())
263 Put_message(mrcl_get_message());
264 free(info[L_ACE_NAME]);
265 info[L_ACE_NAME] = canon;
266 }
c9bbc3e4 267 if (GetTypeFromUser("What Type of Membership Administrator", "ace_type",
268 &info[L_MEMACE_TYPE]) == SUB_ERROR)
269 return NULL;
66e5e450 270 if (strcasecmp(info[L_MEMACE_TYPE], "none"))
c9bbc3e4 271 {
272 sprintf(temp_buf, "Which %s will be the membership administrator of this list: ",
273 info[L_MEMACE_TYPE]);
274 if (GetValueFromUser(temp_buf, &info[L_MEMACE_NAME]) == SUB_ERROR)
275 return NULL;
276 }
5cef9ecf 277 if (!strcasecmp(info[L_MEMACE_TYPE], "kerberos"))
278 {
279 char *canon;
c9bbc3e4 280
5cef9ecf 281 mrcl_validate_kerberos_member(info[L_MEMACE_NAME], &canon);
282 if (mrcl_get_message())
283 Put_message(mrcl_get_message());
284 free(info[L_MEMACE_NAME]);
285 info[L_MEMACE_NAME] = canon;
286 }
5eaef520 287 if (GetValueFromUser("Description: ", &info[L_DESC]) == SUB_ERROR)
288 return NULL;
289
290 FreeAndClear(&info[L_MODTIME], TRUE);
291 FreeAndClear(&info[L_MODBY], TRUE);
292 FreeAndClear(&info[L_MODWITH], TRUE);
293 /*
294 * Slide the newname into the #2 slot, this screws up all future references
295 * to this list.
296 */
297 if (name) /* slide the newname into the #2 slot. */
298 SlipInNewName(info, newname);
299
300 return info;
08345b74 301}
302
303/* -------------- List functions. -------------- */
304
305/* Function Name: ShowListInfo.
306 * Description: shows info on a list.
461c03b6 307 * Arguments: argc, argv - name of list in argv[1].
08345b74 308 * Returns: DM status code.
309 */
310
5eaef520 311int ShowListInfo(int argc, char **argv)
08345b74 312{
600b459e 313 struct mqelem *top, *list;
08345b74 314
5eaef520 315 top = list = GetListInfo(LIST, argv[1], NULL);
316 while (list)
317 {
7ac48069 318 PrintListInfo(list->q_data);
5eaef520 319 list = list->q_forw;
08345b74 320 }
5eaef520 321
322 FreeQueue(top);
323 return DM_NORMAL;
08345b74 324}
325
402461ad 326/* Function Name: RealUpdateList
327 * Description: performs the actual update of the list.
328 * Arguments: info - all information needed to update the list.
329 * junk - an UNUSED boolean.
330 * Returns: none.
331 */
5eaef520 332
333static void RealUpdateList(char **info, Bool junk)
402461ad 334{
44d12d58 335 int stat;
5eaef520 336 char **args;
600b459e 337 struct mqelem *elem = NULL;
5eaef520 338
339 if (!(args = AskListInfo(info, TRUE)))
340 {
341 Put_message("Aborted.");
342 return;
eb5eb5de 343 }
6825fe39 344
5eaef520 345 /*
346 * If the new list name is less than 8 characters, make sure it doesn't
347 * collide with a username.
348 */
349 if ((strlen(args[2]) <= 8) &&
350 do_mr_query("get_user_account_by_login", 1, args + 1,
7ac48069 351 StoreInfo, &elem) != MR_NO_MATCH)
5eaef520 352 {
353 char buf[256];
354
355 sprintf(buf, "\nA user by the name `%s' already exists in the database.",
356 args[1]);
357 Put_message(buf);
358 Loop(QueueTop(elem), FreeInfo);
359 FreeQueue(elem);
360 if (YesNoQuestion("Do you still want to rename this list to that name",
361 FALSE) != TRUE)
362 {
363 Put_message("List ** NOT ** Updated.");
364 return;
365 }
6825fe39 366 }
5eaef520 367
368 if ((stat = do_mr_query("update_list", CountArgs(args), args,
7ac48069 369 NULL, NULL)) != MR_SUCCESS)
5eaef520 370 {
371 com_err(program_name, stat, " in UpdateList.");
372 Put_message("List ** NOT ** Updated.");
402461ad 373 }
5eaef520 374 else
375 Put_message("List successfully updated.");
402461ad 376}
377
08345b74 378/* Function Name: UpdateList
85ca828a 379 * Description: updates the information on a list.
08345b74 380 * Arguments: argc, argv - name of list in argv[1].
381 * Returns: DM Status code.
382 */
383
5eaef520 384int UpdateList(int argc, char **argv)
08345b74 385{
600b459e 386 struct mqelem *top;
402461ad 387
5eaef520 388 top = GetListInfo(LIST, argv[1], (char *) NULL);
389 QueryLoop(top, NullPrint, RealUpdateList, "Update the list");
08345b74 390
5eaef520 391 FreeQueue(top);
392 return DM_NORMAL;
08345b74 393}
394
85ca828a 395/* Function Name: SetDefaults
396 * Description: sets defaults for AddList function
397 * Arguments: info - the array to add them to.
398 * name - name of the program to add.
399 * Returns: defaults - the default information.
400 */
401
5eaef520 402static char **SetDefaults(char **info, char *name)
85ca828a 403{
7ac48069 404 info[L_NAME] = strdup(name);
405 info[L_ACTIVE] = strdup(DEFAULT_ACTIVE);
406 info[L_PUBLIC] = strdup(DEFAULT_PUBLIC);
407 info[L_HIDDEN] = strdup(DEFAULT_HIDDEN);
408 info[L_MAILLIST] = strdup(DEFAULT_MAILLIST);
409 info[L_GROUP] = strdup(DEFAULT_GROUP);
410 info[L_GID] = strdup(DEFAULT_GID);
c55f98d2 411 info[L_NFSGROUP] = strdup(DEFAULT_NFSGROUP);
7ac48069 412 info[L_ACE_TYPE] = strdup(DEFAULT_ACE_TYPE);
413 info[L_ACE_NAME] = strdup(DEFAULT_ACE_NAME);
c9bbc3e4 414 info[L_MEMACE_TYPE] = strdup(DEFAULT_MEMACE_TYPE);
415 info[L_MEMACE_NAME] = strdup(DEFAULT_MEMACE_NAME);
7ac48069 416 info[L_DESC] = strdup(DEFAULT_DESCRIPTION);
5eaef520 417 info[L_MODTIME] = info[L_MODBY] = info[L_MODWITH] = info[L_END] = NULL;
418 return info;
85ca828a 419}
420
08345b74 421/* Function Name: AddList
5eaef520 422 * Description:
08345b74 423 * Arguments: argc, argv - name of list in argv[1].
402461ad 424 * Returns: SUB_ERROR if list not created.
08345b74 425 */
426
5eaef520 427int AddList(int argc, char **argv)
08345b74 428{
5eaef520 429 static char *info[MAX_ARGS_SIZE], **add_args;
430 int status, ret_code = SUB_NORMAL;
600b459e 431 struct mqelem *elem = NULL;
5eaef520 432
433 if (!ValidName(argv[1]))
434 return DM_NORMAL;
7ac48069 435 status = do_mr_query("get_list_info", 1, argv + 1, NULL, NULL);
5eaef520 436 if (status != MR_NO_MATCH)
437 {
438 if (status == MR_SUCCESS)
439 Put_message("This list already exists.");
440 else
441 com_err(program_name, status, " in AddList.");
442 return SUB_ERROR;
08345b74 443 }
444
094277d2 445 if (status = mr_access("add_list", L_MODTIME, SetDefaults(info, argv[1])))
446 {
447 com_err(program_name, status, " in AddList.");
448 return SUB_ERROR;
449 }
450
5eaef520 451 /*
452 * If the listname is less than 8 characters, make sure it doesn't
453 * collide with a username.
454 */
455 if ((strlen(argv[1]) <= 8) &&
456 do_mr_query("get_user_account_by_login", 1, argv + 1,
7ac48069 457 StoreInfo, &elem) != MR_NO_MATCH)
5eaef520 458 {
459 char buf[256];
460
461 sprintf(buf, "\nA user by the name `%s' already exists in the database.",
462 argv[1]);
463 Put_message(buf);
464 Loop(QueueTop(elem), FreeInfo);
465 FreeQueue(elem);
f4169f25 466 if (YesNoQuestion("Create a list with the same name", FALSE) != TRUE)
5eaef520 467 return SUB_ERROR;
dcc803de 468 }
5eaef520 469
470 if (!(add_args = AskListInfo(SetDefaults(info, argv[1]), FALSE)))
471 {
472 Put_message("Aborted.");
473 return SUB_ERROR;
eb5eb5de 474 }
08345b74 475
5eaef520 476 if ((status = do_mr_query("add_list", CountArgs(add_args), add_args,
7ac48069 477 NULL, NULL)) != MR_SUCCESS)
5eaef520 478 {
479 com_err(program_name, status, " in AddList.");
480 Put_message("List Not Created.");
481 ret_code = SUB_ERROR;
08345b74 482 }
483
5eaef520 484 FreeInfo(info);
485 return ret_code;
08345b74 486}
487
488/* Function Name: Instructions
489 * Description: This func prints out instruction on manipulating lists.
490 * Arguments: none
491 * Returns: DM Status Code.
492 */
493
7ac48069 494int ListHelp(int argc, char **argv)
08345b74 495{
5eaef520 496 static char *message[] = {
497 "Listmaint handles the creation, deletion, and updating of lists.",
498 "A list can be a mailing list, a group list, or both.",
499 "The concept behind lists is that a list has an owner",
500 "- administrator - and members.",
501 "The administrator of a list may be another list.",
502 "The members of a list can be users (login names), other lists,",
503 "or address strings.",
504 "You can use certain keys to do the following:",
505 " Refresh the screen - Type ctrl-L.",
506 " Escape from a function - Type ctrl-C.",
507 " Suspend the program (temporarily) - Type ctrl-Z.",
508 NULL,
509 };
510
511 return PrintHelp(message);
08345b74 512}
513
514/*-*-* LISTMAINT UPDATE MENU *-*-*/
515
516/* Function Name: ListmaintMemberMenuEntry
517 * Description: entry routine into the listmaint member menu.
518 * Arguments: m - the member menu.
519 * argc, argv - name of the list in argv[1].
520 * Returns: none.
521 */
522
5eaef520 523int ListmaintMemberMenuEntry(Menu *m, int argc, char **argv)
08345b74 524{
5eaef520 525 char temp_buf[BUFSIZ];
526 char *list_name = argv[1];
44d12d58 527 int stat;
5eaef520 528
529 if (!ValidName(list_name))
530 return DM_QUIT;
531
532 if (*argv[0] == 'a')
533 { /* add_list */
534 if (AddList(argc, argv) == SUB_ERROR)
535 return DM_QUIT;
536 sprintf(temp_buf, "List '%s' created. Do you want to %s", list_name,
537 "change its membership (y/n)? ");
538 if (YesNoQuestion(temp_buf, TRUE) != TRUE)
539 return DM_QUIT;
08345b74 540 }
5eaef520 541 else
542 /* All we want to know is if it exists. */
543 switch ((stat = do_mr_query("count_members_of_list", 1, argv + 1,
7ac48069 544 NULL, NULL)))
5eaef520 545 {
546 case MR_SUCCESS:
547 break;
548 case MR_LIST:
549 Put_message("This list does not exist.");
550 return DM_QUIT;
551 case MR_PERM:
552 Put_message("You are not allowed to view this list.");
553 break;
554 default:
555 com_err(program_name, stat, " in get_list_info");
556 return DM_QUIT;
557 }
558
559 sprintf(temp_buf, "Change/Display membership of '%s'", list_name);
7ac48069 560 m->m_title = strdup(temp_buf);
5eaef520 561 strcpy(current_list, list_name);
562 return DM_NORMAL;
08345b74 563}
564
565/* Function Name: ListmaintMemberMenuExit
566 * Description: This is the function called when the member menu is
567 * exited, it frees the memory that is storing the name.
568 * Arguments: m - the menu
5eaef520 569 * Returns: DM_NORMAL
08345b74 570 */
571
5eaef520 572int ListmaintMemberMenuExit(Menu *m)
08345b74 573{
5eaef520 574 free(m->m_title);
575 strcpy(current_list, "");
576 return DM_NORMAL;
08345b74 577}
578
579/* Function Name: ListMembersByType
580 * Description: This function lists the users of a list by type.
581 * Arguments: type - the type of the list "USER", "LIST", or "STRING".
17bbb3bc 582 * tags - whether or not to display tags
08345b74 583 * Returns: none.
584 * NOTE: if type is NULL, all lists members are listed.
585 */
586
17bbb3bc 587void ListMembersByType(char *type, int tags)
08345b74 588{
5eaef520 589 char temp_buf[BUFSIZ];
44d12d58 590 int status;
5eaef520 591 char *args[10];
592
593 args[0] = current_list;
594 args[1] = NULL;
595
596 found_some = FALSE;
17bbb3bc 597 if ((status = do_mr_query(tags ? "get_tagged_members_of_list" :
598 "get_members_of_list", CountArgs(args),
599 args, PrintByType, type)))
7ac48069 600 com_err(program_name, status, " in ListMembersByType");
5eaef520 601 if (!found_some)
602 {
603 if (!type)
604 Put_message("List is empty (no members).");
605 else
606 {
607 sprintf(temp_buf, "No %s Members", type);
608 Put_message(temp_buf);
08345b74 609 }
610 }
611}
612
613/* Function Name: ListAllMembers
614 * Description: lists all members of the current list.
5eaef520 615 * Arguments:
08345b74 616 * Returns: DM_NORMAL
617 */
618
7ac48069 619int ListAllMembers(int argc, char **argv)
08345b74 620{
17bbb3bc 621 ListMembersByType(NULL, 0);
5eaef520 622 return DM_NORMAL;
08345b74 623}
624
625/* Function Name: ListUserMembers
626 * Description: This function lists all members of a list of type "USER".
627 * Arguments: none
628 * Returns: DM_NORMAL.
629 */
630
7ac48069 631int ListUserMembers(int argc, char **argv)
08345b74 632{
17bbb3bc 633 ListMembersByType("USER", 0);
5eaef520 634 return DM_NORMAL;
08345b74 635}
636
637/* Function Name: ListListMembers
638 * Description: This function lists all members of a list of type "LIST".
639 * Arguments: none
640 * Returns: DM_NORMAL.
641 */
642
7ac48069 643int ListListMembers(int argc, char **argv)
08345b74 644{
17bbb3bc 645 ListMembersByType("LIST", 0);
5eaef520 646 return DM_NORMAL;
08345b74 647}
648
649/* Function Name: ListStringMembers
650 * Description:This function lists all members of a list of type "STRING".
651 * Arguments: none
652 * Returns: DM_NORMAL.
653 */
654
7ac48069 655int ListStringMembers(int argc, char **argv)
08345b74 656{
17bbb3bc 657 ListMembersByType("STRING", 0);
5eaef520 658 return DM_NORMAL;
08345b74 659}
660
661/* Function Name: GetMemberInfo
662 * Description: This function gets the information needed to
663 * add or delete a user from a list.
664 * Arguments: argc, argv - standard.
665 * action - name of the action to be performed either
666 * "add" or "delete".
667 * ret_argc, ret_argv - the returned value of argc and argv.
668 * Returns: SUB_ERROR or SUB_NORMAL.
669 */
670
5eaef520 671int GetMemberInfo(char *action, char **ret_argv)
08345b74 672{
5eaef520 673 char temp_buf[BUFSIZ];
674
7ac48069 675 ret_argv[LM_LIST] = strdup(current_list);
5eaef520 676
7ac48069 677 ret_argv[LM_TYPE] = strdup("user");
5eaef520 678 if (GetTypeFromUser("Type of member", "member", &ret_argv[LM_TYPE]) ==
679 SUB_ERROR)
680 return SUB_ERROR;
681
682 sprintf(temp_buf, "Name of %s to %s", ret_argv[LM_TYPE], action);
7ac48069 683 ret_argv[LM_MEMBER] = strdup(user);
5eaef520 684 if (GetValueFromUser(temp_buf, &ret_argv[LM_MEMBER]) == SUB_ERROR)
685 return SUB_ERROR;
686 ret_argv[LM_END] = NULL; /* NULL terminate this list. */
687
688 if (strcasecmp(ret_argv[LM_TYPE], "string") &&
689 !ValidName(ret_argv[LM_MEMBER]))
690 {
691 FreeInfo(ret_argv);
692 return SUB_ERROR;
402461ad 693 }
5eaef520 694 return SUB_NORMAL;
08345b74 695}
696
697/* Function Name: AddMember
698 * Description: This function adds a member to a list.
699 * Arguments: none.
700 * Returns: DM_NORMAL.
701 */
702
7ac48069 703int AddMember(int argc, char **argv)
08345b74 704{
5eaef520 705 char *args[10], temp_buf[BUFSIZ], *p;
44d12d58 706 int status;
600b459e 707 struct mqelem *mailhubs, *elem;
5eaef520 708
709 if (GetMemberInfo("add", args) == SUB_ERROR)
710 return DM_NORMAL;
711
712 if (!strcmp(args[LM_TYPE], "STRING"))
713 {
12ca8430 714 status = mrcl_validate_string_member(args[LM_MEMBER]);
715 if (status != MRCL_SUCCESS)
716 Put_message(mrcl_get_message());
717 if (status == MRCL_REJECT)
718 return DM_NORMAL;
fc2df2d9 719 }
375e818a 720 else if (!strcmp(args[LM_TYPE], "KERBEROS"))
721 {
722 char *canon;
723
724 mrcl_validate_kerberos_member(args[LM_MEMBER], &canon);
725 if (mrcl_get_message())
726 Put_message(mrcl_get_message());
727 free(args[LM_MEMBER]);
728 args[LM_MEMBER] = canon;
729 }
5f7b0741 730 else if (!strcmp(args[LM_TYPE], "MACHINE"))
731 {
732 char *canon;
733 canon = canonicalize_hostname(strdup(args[LM_MEMBER]));
734 free(args[LM_MEMBER]);
735 args[LM_MEMBER] = canon;
736 }
fc2df2d9 737
5eaef520 738 if ((status = do_mr_query("add_member_to_list", CountArgs(args), args,
7ac48069 739 NULL, NULL)) != MR_SUCCESS)
5eaef520 740 {
741 if (status == MR_EXISTS)
742 {
743 sprintf(temp_buf, "The %s %s is already a member of LIST %s.",
744 args[LM_TYPE], args[LM_MEMBER], args[LM_LIST]);
745 Put_message(temp_buf);
402461ad 746 }
5eaef520 747 else
748 com_err(program_name, status, " in AddMember");
402461ad 749 }
08345b74 750
5eaef520 751 FreeInfo(args);
752 return DM_NORMAL;
08345b74 753}
754
755/* Function Name: DeleteMember
756 * Description: This function deletes a member from a list.
757 * Arguments: none.
758 * Returns: DM_NORMAL
759 */
760
7ac48069 761int DeleteMember(int argc, char **argv)
08345b74 762{
5eaef520 763 char *args[10];
44d12d58 764 int status;
5eaef520 765
766 if (GetMemberInfo("delete", args) == SUB_ERROR)
767 return DM_NORMAL;
768
769 if (Confirm("Are you sure you want to delete this member?"))
770 {
771 if ((status = do_mr_query("delete_member_from_list", CountArgs(args),
7ac48069 772 args, NULL, NULL)))
375e818a 773 {
774 if ((status == MR_STRING || status == MR_NO_MATCH) &&
775 !strcmp(args[LM_TYPE], "KERBEROS"))
776 {
777 char *canon;
778 mrcl_validate_kerberos_member(args[LM_MEMBER], &canon);
779 if (mrcl_get_message())
780 {
781 free(args[LM_MEMBER]);
782 args[LM_MEMBER] = canon;
783 if (do_mr_query("delete_member_from_list", CountArgs(args),
784 args, NULL, NULL) == MR_SUCCESS)
785 {
786 Put_message(mrcl_get_message());
787 status = MR_SUCCESS;
788 }
789 }
790 }
5f7b0741 791 else if ((status == MR_MACHINE || status == MR_NO_MATCH) &&
792 !strcmp(args[LM_TYPE], "MACHINE"))
793 {
794 char *canon;
795 canon = canonicalize_hostname(args[LM_MEMBER]);
796 free(args[LM_MEMBER]);
797 args[LM_MEMBER] = canon;
798 if (do_mr_query("delete_member_from_list", CountArgs(args),
799 args, NULL, NULL) == MR_SUCCESS)
800 status = MR_SUCCESS;
801 }
375e818a 802 }
803 if (status)
5eaef520 804 com_err(program_name, status, " in DeleteMember");
805 else
806 Put_message("Deletion Completed.");
08345b74 807 }
5eaef520 808 else
809 Put_message("Deletion has been Aborted.");
08345b74 810
5eaef520 811 FreeInfo(args);
812 return DM_NORMAL;
08345b74 813}
814
17bbb3bc 815/* Function Name: TagMember
816 * Description: Add a tag to a list member
817 * Arguments:
818 * Returns: DM_NORMAL
819 */
820
821int TagMember(int argc, char **argv)
822{
823 char *args[10];
824 int status;
17bbb3bc 825
826 if (GetMemberInfo("tag", args) == SUB_ERROR)
827 return DM_NORMAL;
828
829 args[LM_TAG] = strdup("");
830 if (GetValueFromUser("Tag" , &args[LM_TAG]) == SUB_ERROR)
831 {
832 Put_message("Aborted.");
833 return DM_NORMAL;
834 }
835 args[LM_TAG_END] = NULL; /* NULL terminate this list. */
836
837 if ((status = do_mr_query("tag_member_of_list", CountArgs(args),
838 args, NULL, NULL)))
839 com_err(program_name, status, " in TagMember");
840
841 FreeInfo(args);
842 return DM_NORMAL;
843}
844
845/* Function Name: ListAllMembers
846 * Description: lists all members of the current list.
847 * Arguments:
848 * Returns: DM_NORMAL
849 */
850
851int ListMembersWithTags(int argc, char **argv)
852{
853 ListMembersByType(NULL, 1);
854 return DM_NORMAL;
855}
856
08345b74 857/* Function Name: InterRemoveItemFromLists
858 * Description: This function allows interactive removal of an item
859 * (user, string, list) for all list that it is on.
860 * Arguments: none.
861 * Returns: DM_NORMAL.
402461ad 862 * NOTES: QueryLoop() does not work here because info does not have
863 * enough information in it to delete the member from the list.
08345b74 864 */
865
7ac48069 866int InterRemoveItemFromLists(int argc, char **argv)
08345b74 867{
44d12d58 868 int status;
5eaef520 869 char *type, *name, *args[10], buf[BUFSIZ];
600b459e 870 struct mqelem *top, *elem;
5eaef520 871
7ac48069 872 type = strdup("USER");
5eaef520 873 if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
874 return DM_NORMAL;
875
876 sprintf(buf, "Name of %s", type);
7ac48069 877 name = strdup(user);
5eaef520 878 if (GetValueFromUser(buf, &name) == SUB_ERROR)
879 return DM_NORMAL;
880
881 if (!ValidName(name))
882 return DM_NORMAL;
883
884 top = elem = GetListInfo(GLOM, type, name);
885
886 while (elem)
887 {
888 char line[BUFSIZ];
7ac48069 889 char **info = elem->q_data;
5eaef520 890 sprintf(line, "Delete %s %s from the list \"%s\" (y/n/q)? ", type,
891 name, info[GLOM_NAME]);
892 switch (YesNoQuitQuestion(line, FALSE))
893 {
402461ad 894 case TRUE:
5eaef520 895 Put_message("deleting...");
896 args[DM_LIST] = info[GLOM_NAME];
897 args[DM_TYPE] = type;
898 args[DM_MEMBER] = name;
5f7b0741 899 if (!strcmp("MACHINE", type))
900 args[DM_MEMBER] = canonicalize_hostname(strdup(name));
5eaef520 901 if ((status = do_mr_query("delete_member_from_list", 3, args,
7ac48069 902 NULL, NULL)))
5eaef520 903 {
904 /* should probabally check to delete list. */
905 com_err(program_name, status, " in delete_member");
906 }
907 break;
402461ad 908 case FALSE:
5eaef520 909 break;
402461ad 910 default:
5eaef520 911 Put_message("Aborting...");
912 FreeQueue(top);
913 return DM_NORMAL;
08345b74 914 }
5eaef520 915 elem = elem->q_forw;
08345b74 916 }
5eaef520 917 FreeQueue(top);
918 return DM_NORMAL;
08345b74 919}
920
921/*-*-* LIST MENU *-*-*/
922
923/* Function Name: ListByMember
924 * Description: This gets all lists that a given member is a member of.
461c03b6 925 * Arguments: none.
08345b74 926 * Returns: DM_NORMAL.
927 */
928
7ac48069 929int ListByMember(int argc, char **argv)
08345b74 930{
5eaef520 931 char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name, **info;
8647d909 932 Bool maillist, group, neither;
600b459e 933 struct mqelem *top, *elem;
5eaef520 934
7ac48069 935 type = strdup("USER");
5eaef520 936 if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
937 return DM_NORMAL;
938
939 sprintf(buf, "Name of %s", type);
7ac48069 940 name = strdup(user);
5eaef520 941 if (GetValueFromUser(buf, &name) == SUB_ERROR)
942 return DM_NORMAL;
943
165ecbb0 944 switch (YesNoQuestion("Do you want a recursive search (y/n)", TRUE))
945 {
946 case TRUE:
947 sprintf(temp_buf, "R%s", type); /* "USER" to "RUSER" etc. */
948 free(type);
949 type = strdup(temp_buf);
950 break;
951 case FALSE:
952 break;
953 default:
954 return DM_NORMAL;
955 }
5eaef520 956
957 if ((maillist = YesNoQuestion("Show Lists that are Maillists (y/n) ?",
958 TRUE)) == -1)
959 return DM_NORMAL;
960 if ((group = YesNoQuestion("Show Lists that are Groups (y/n) ?",
961 TRUE)) == -1)
962 return DM_NORMAL;
963
8647d909 964 if ((neither = YesNoQuestion("Show Lists that are neither Maillists nor Groups (y/n) ?",
965 TRUE)) == -1)
966 return DM_NORMAL;
967
5eaef520 968 elem = top = GetListInfo(GLOM, type, name);
969
970 while (elem)
971 {
7ac48069 972 info = elem->q_data;
5eaef520 973 if ((maillist == TRUE && !strcmp(info[GLOM_MAILLIST], "1")) ||
974 (group == TRUE && !strcmp(info[GLOM_GROUP], "1")))
975 Put_message(info[GLOM_NAME]);
8647d909 976 if (neither == TRUE && !strcmp(info[GLOM_MAILLIST], "0") &&
977 !strcmp(info[GLOM_GROUP], "0"))
978 Put_message(info[GLOM_NAME]);
5eaef520 979 elem = elem->q_forw;
08345b74 980 }
5eaef520 981 FreeQueue(top);
982 return DM_NORMAL;
08345b74 983}
984
985/* Function Name: ListByAdministrator
986 * Description: This function prints all lists which a given user or
987 * group administers.
461c03b6 988 * Arguments: none.
08345b74 989 * Returns: DM_NORMAL.
990 */
991
7ac48069 992int ListByAdministrator(int argc, char **argv)
08345b74 993{
5eaef520 994 char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name;
600b459e 995 struct mqelem *top;
5eaef520 996
7ac48069 997 type = strdup("USER");
5eaef520 998 if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
999 return DM_NORMAL;
1000
1001 sprintf(buf, "Name of %s", type);
7ac48069 1002 name = strdup(user);
5eaef520 1003 if (GetValueFromUser(buf, &name) == SUB_ERROR)
1004 return DM_NORMAL;
1005
1006 switch (YesNoQuestion("Do you want a recursive search (y/n)", FALSE))
1007 {
eb5eb5de 1008 case TRUE:
5eaef520 1009 sprintf(temp_buf, "R%s", type); /* "USER" to "RUSER" etc. */
1010 free(type);
7ac48069 1011 type = strdup(temp_buf);
5eaef520 1012 break;
eb5eb5de 1013 case FALSE:
5eaef520 1014 break;
eb5eb5de 1015 default:
5eaef520 1016 return DM_NORMAL;
08345b74 1017 }
402461ad 1018
5eaef520 1019 top = GetListInfo(ACE_USE, type, name);
1020 Loop(top, PrintListAce);
1021
1022 FreeQueue(top);
1023 return DM_NORMAL;
08345b74 1024}
1025
08345b74 1026/* Function Name: ListAllPublicMailLists
1027 * Description: This function lists all public mailing lists.
1028 * Arguments: none
1029 * Returns: DM_NORMAL.
1030 */
1031
7ac48069 1032int ListAllPublicMailLists(int argc, char **argv)
08345b74 1033{
44d12d58 1034 int status;
5eaef520 1035 static char *args[] = {
1036 "TRUE", /* active */
1037 "TRUE", /* public */
1038 "FALSE", /* hidden */
1039 "TRUE", /* maillist */
1040 "DONTCARE", /* group. */
1041 };
1042
1043 if (YesNoQuestion("This query will take a while. Do you wish to continue?",
1044 TRUE) == TRUE)
1045 {
7ac48069 1046 if ((status = do_mr_query("qualified_get_lists", 5, args,
1047 Print, NULL)) != MR_SUCCESS)
5eaef520 1048 com_err(program_name, status, " in ListAllGroups");
1049 }
1050
1051 return DM_NORMAL;
08345b74 1052}
This page took 0.307384 seconds and 5 git commands to generate.