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