]> andersk Git - moira.git/blob - clients/moira/lists.c
Call mr_access() in AddList so we can bomb out before asking the user
[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_ACE_TYPE    "user"
48 #define DEFAULT_ACE_NAME    (user)
49 #define DEFAULT_MEMACE_TYPE "NONE"
50 #define DEFAULT_MEMACE_NAME "NONE"
51 #define DEFAULT_DESCRIPTION DEFAULT_COMMENT
52
53 /* globals only for this file. */
54
55 static char current_list[BUFSIZ];
56
57
58 /*      Function Name: PrintListAce
59  *      Description: This function prints the list ace information.
60  *      Arguments: info - an info structure.
61  *      Returns: none.
62  */
63
64 static void PrintListAce(char **info)
65 {
66   char buf[BUFSIZ];
67
68   sprintf(buf, "Item: %-20s Name: %s", info[ACE_TYPE], info[ACE_NAME]);
69   Put_message(buf);
70 }
71
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
78 static void PrintListInfo(char **info)
79 {
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     {
93       sprintf(buf, "This list is a Group%s and its ID number is %s",
94               atoi(info[L_NFSGROUP]) ? " and an NFS Group," : "",
95               info[L_GID]);
96       Put_message(buf);
97     }
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);
108     }
109
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
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);
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
133 struct mqelem *GetListInfo(int type, char *name1, char *name2)
134 {
135   char *args[2];
136   struct mqelem *elem = NULL;
137   int status;
138
139   switch (type)
140     {
141     case LIST:
142       args[0] = name1;
143       if ((status = do_mr_query("get_list_info", 1, args, StoreInfo, &elem)))
144         {
145           com_err(program_name, status, " in get_list_info");
146           return NULL;
147         }
148       break;
149     case MEMBERS:
150       args[0] = name1;
151       if ((status = do_mr_query("get_members_of_list", 1, args,
152                                 StoreInfo, &elem)))
153         {
154           com_err(program_name, status, " in get_members_of_list");
155           return NULL;
156         }
157       break;
158     case GLOM:
159       args[0] = name1;
160       args[1] = name2;
161       if (!strcmp(name1, "MACHINE"))
162           args[1] = canonicalize_hostname(strdup(name2));
163       if ((status = do_mr_query("get_lists_of_member", 2, args,
164                                 StoreInfo, &elem)))
165         {
166           com_err(program_name, status, " in get_list_of_members");
167           return NULL;
168         }
169       break;
170     case ACE_USE:
171       args[0] = name1;
172       args[1] = name2;
173       if ((status = do_mr_query("get_ace_use", 2, args, StoreInfo, &elem)))
174         {
175           com_err(program_name, status, " in get_ace_use");
176           return NULL;
177         }
178       break;
179     }
180   return QueueTop(elem);
181 }
182
183 /*      Function Name: AskListInfo.
184  *      Description: This function askes the user for information about a
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
192 char **AskListInfo(char **info, Bool name)
193 {
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         {
205           newname = strdup(info[L_NAME]);
206           if (GetValueFromUser("The new name for this list", &newname) ==
207               SUB_ERROR)
208             return NULL;
209           if (ValidName(newname))
210             break;
211         }
212     }
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     {
229       if (GetYesNoValueFromUser("Is this an NFS group", &info[L_NFSGROUP]) == 
230           SUB_ERROR)
231         return NULL;
232       if (GetValueFromUser("What is the GID for this group.", &info[L_GID]) ==
233           SUB_ERROR)
234         return NULL;
235     }
236
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         
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     }
267   if (GetTypeFromUser("What Type of Membership Administrator", "ace_type",
268                       &info[L_MEMACE_TYPE]) == SUB_ERROR)
269     return NULL;
270   if (strcasecmp(info[L_MEMACE_TYPE], "none"))
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     }
277   if (!strcasecmp(info[L_MEMACE_TYPE], "kerberos"))
278     {
279       char *canon;
280
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     }
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;
301 }
302
303 /* -------------- List functions. -------------- */
304
305 /*      Function Name: ShowListInfo.
306  *      Description: shows info on a list.
307  *      Arguments: argc, argv - name of list in argv[1].
308  *      Returns: DM status code.
309  */
310
311 int ShowListInfo(int argc, char **argv)
312 {
313   struct mqelem *top, *list;
314
315   top = list = GetListInfo(LIST, argv[1], NULL);
316   while (list)
317     {
318       PrintListInfo(list->q_data);
319       list = list->q_forw;
320     }
321
322   FreeQueue(top);
323   return DM_NORMAL;
324 }
325
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  */
332
333 static void RealUpdateList(char **info, Bool junk)
334 {
335   int stat;
336   char **args;
337   struct mqelem *elem = NULL;
338
339   if (!(args = AskListInfo(info, TRUE)))
340     {
341       Put_message("Aborted.");
342       return;
343     }
344
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,
351                   StoreInfo, &elem) != MR_NO_MATCH)
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         }
366     }
367
368   if ((stat = do_mr_query("update_list", CountArgs(args), args,
369                           NULL, NULL)) != MR_SUCCESS)
370     {
371       com_err(program_name, stat, " in UpdateList.");
372       Put_message("List ** NOT ** Updated.");
373     }
374   else
375     Put_message("List successfully updated.");
376 }
377
378 /*      Function Name: UpdateList
379  *      Description: updates the information on a list.
380  *      Arguments: argc, argv - name of list in argv[1].
381  *      Returns: DM Status code.
382  */
383
384 int UpdateList(int argc, char **argv)
385 {
386   struct mqelem *top;
387
388   top = GetListInfo(LIST, argv[1], (char *) NULL);
389   QueryLoop(top, NullPrint, RealUpdateList, "Update the list");
390
391   FreeQueue(top);
392   return DM_NORMAL;
393 }
394
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
402 static char **SetDefaults(char **info, char *name)
403 {
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);
411   info[L_NFSGROUP] = strdup(DEFAULT_NFSGROUP);
412   info[L_ACE_TYPE] = strdup(DEFAULT_ACE_TYPE);
413   info[L_ACE_NAME] = strdup(DEFAULT_ACE_NAME);
414   info[L_MEMACE_TYPE] = strdup(DEFAULT_MEMACE_TYPE);
415   info[L_MEMACE_NAME] = strdup(DEFAULT_MEMACE_NAME);
416   info[L_DESC] =     strdup(DEFAULT_DESCRIPTION);
417   info[L_MODTIME] = info[L_MODBY] = info[L_MODWITH] = info[L_END] = NULL;
418   return info;
419 }
420
421 /*      Function Name: AddList
422  *      Description:
423  *      Arguments: argc, argv - name of list in argv[1].
424  *      Returns: SUB_ERROR if list not created.
425  */
426
427 int AddList(int argc, char **argv)
428 {
429   static char *info[MAX_ARGS_SIZE], **add_args;
430   int status, ret_code = SUB_NORMAL;
431   struct mqelem *elem = NULL;
432
433   if (!ValidName(argv[1]))
434     return DM_NORMAL;
435   status = do_mr_query("get_list_info", 1, argv + 1, NULL, NULL);
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;
443     }
444
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
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,
457                   StoreInfo, &elem) != MR_NO_MATCH)
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);
466       if (YesNoQuestion("Create a list with the same name", FALSE) != TRUE)
467         return SUB_ERROR;
468     }
469
470   if (!(add_args = AskListInfo(SetDefaults(info, argv[1]), FALSE)))
471     {
472       Put_message("Aborted.");
473       return SUB_ERROR;
474     }
475
476   if ((status = do_mr_query("add_list", CountArgs(add_args), add_args,
477                             NULL, NULL)) != MR_SUCCESS)
478     {
479       com_err(program_name, status, " in AddList.");
480       Put_message("List Not Created.");
481       ret_code = SUB_ERROR;
482     }
483
484   FreeInfo(info);
485   return ret_code;
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
494 int ListHelp(int argc, char **argv)
495 {
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);
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
523 int ListmaintMemberMenuEntry(Menu *m, int argc, char **argv)
524 {
525   char temp_buf[BUFSIZ];
526   char *list_name = argv[1];
527   int stat;
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;
540     }
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,
544                                 NULL, NULL)))
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);
560   m->m_title = strdup(temp_buf);
561   strcpy(current_list, list_name);
562   return DM_NORMAL;
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
569  *      Returns: DM_NORMAL
570  */
571
572 int ListmaintMemberMenuExit(Menu *m)
573 {
574   free(m->m_title);
575   strcpy(current_list, "");
576   return DM_NORMAL;
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".
582  *                 tags - whether or not to display tags
583  *      Returns: none.
584  *      NOTE: if type is NULL, all lists members are listed.
585  */
586
587 void ListMembersByType(char *type, int tags)
588 {
589   char temp_buf[BUFSIZ];
590   int status;
591   char *args[10];
592
593   args[0] = current_list;
594   args[1] = NULL;
595
596   found_some = FALSE;
597   if ((status = do_mr_query(tags ? "get_tagged_members_of_list" :
598                             "get_members_of_list", CountArgs(args),
599                             args, PrintByType, type)))
600     com_err(program_name, status, " in ListMembersByType");
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);
609         }
610     }
611 }
612
613 /*      Function Name: ListAllMembers
614  *      Description: lists all members of the current list.
615  *      Arguments:
616  *      Returns: DM_NORMAL
617  */
618
619 int ListAllMembers(int argc, char **argv)
620 {
621   ListMembersByType(NULL, 0);
622   return DM_NORMAL;
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
631 int ListUserMembers(int argc, char **argv)
632 {
633   ListMembersByType("USER", 0);
634   return DM_NORMAL;
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
643 int ListListMembers(int argc, char **argv)
644 {
645   ListMembersByType("LIST", 0);
646   return DM_NORMAL;
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
655 int ListStringMembers(int argc, char **argv)
656 {
657   ListMembersByType("STRING", 0);
658   return DM_NORMAL;
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
671 int GetMemberInfo(char *action, char **ret_argv)
672 {
673   char temp_buf[BUFSIZ];
674
675   ret_argv[LM_LIST] = strdup(current_list);
676
677   ret_argv[LM_TYPE] = strdup("user");
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);
683   ret_argv[LM_MEMBER] = strdup(user);
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;
693     }
694   return SUB_NORMAL;
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
703 int AddMember(int argc, char **argv)
704 {
705   char *args[10], temp_buf[BUFSIZ], *p;
706   int status;
707   struct mqelem *mailhubs, *elem;
708
709   if (GetMemberInfo("add", args) == SUB_ERROR)
710     return DM_NORMAL;
711
712   if (!strcmp(args[LM_TYPE], "STRING"))
713     {
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;
719     }
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     }
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     }
737
738   if ((status = do_mr_query("add_member_to_list", CountArgs(args), args,
739                             NULL, NULL)) != MR_SUCCESS)
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);
746         }
747       else
748         com_err(program_name, status, " in AddMember");
749     }
750
751   FreeInfo(args);
752   return DM_NORMAL;
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
761 int DeleteMember(int argc, char **argv)
762 {
763   char *args[10];
764   int status;
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),
772                                 args, NULL, NULL)))
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             }
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             }
802         }
803       if (status)
804         com_err(program_name, status, " in DeleteMember");
805       else
806         Put_message("Deletion Completed.");
807     }
808   else
809     Put_message("Deletion has been Aborted.");
810
811   FreeInfo(args);
812   return DM_NORMAL;
813 }
814
815 /*      Function Name: TagMember
816  *      Description: Add a tag to a list member
817  *      Arguments:
818  *      Returns: DM_NORMAL
819  */
820
821 int TagMember(int argc, char **argv)
822 {
823   char *args[10];
824   int status;
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
851 int ListMembersWithTags(int argc, char **argv)
852 {
853   ListMembersByType(NULL, 1);
854   return DM_NORMAL;
855 }
856
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.
862  *      NOTES: QueryLoop() does not work here because info does not have
863  *             enough information in it to delete the member from the list.
864  */
865
866 int InterRemoveItemFromLists(int argc, char **argv)
867 {
868   int status;
869   char *type, *name, *args[10], buf[BUFSIZ];
870   struct mqelem *top, *elem;
871
872   type = strdup("USER");
873   if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
874     return DM_NORMAL;
875
876   sprintf(buf, "Name of %s", type);
877   name = strdup(user);
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];
889       char **info = elem->q_data;
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         {
894         case TRUE:
895           Put_message("deleting...");
896           args[DM_LIST] = info[GLOM_NAME];
897           args[DM_TYPE] = type;
898           args[DM_MEMBER] = name;
899           if (!strcmp("MACHINE", type))
900               args[DM_MEMBER] = canonicalize_hostname(strdup(name));
901           if ((status = do_mr_query("delete_member_from_list", 3, args,
902                                     NULL, NULL)))
903             {
904               /* should probabally check to delete list. */
905               com_err(program_name, status, " in delete_member");
906             }
907           break;
908         case FALSE:
909           break;
910         default:
911           Put_message("Aborting...");
912           FreeQueue(top);
913           return DM_NORMAL;
914         }
915       elem = elem->q_forw;
916     }
917   FreeQueue(top);
918   return DM_NORMAL;
919 }
920
921 /*-*-* LIST MENU *-*-*/
922
923 /*      Function Name: ListByMember
924  *      Description: This gets all lists that a given member is a member of.
925  *      Arguments: none.
926  *      Returns: DM_NORMAL.
927  */
928
929 int ListByMember(int argc, char **argv)
930 {
931   char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name, **info;
932   Bool maillist, group, neither;
933   struct mqelem *top, *elem;
934
935   type = strdup("USER");
936   if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
937     return DM_NORMAL;
938
939   sprintf(buf, "Name of %s", type);
940   name = strdup(user);
941   if (GetValueFromUser(buf, &name) == SUB_ERROR)
942     return DM_NORMAL;
943
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     }
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
964   if ((neither = YesNoQuestion("Show Lists that are neither Maillists nor Groups (y/n) ?",
965                                TRUE)) == -1)
966     return DM_NORMAL;
967
968   elem = top = GetListInfo(GLOM, type, name);
969
970   while (elem)
971     {
972       info = elem->q_data;
973       if ((maillist == TRUE && !strcmp(info[GLOM_MAILLIST], "1")) ||
974           (group == TRUE && !strcmp(info[GLOM_GROUP], "1")))
975         Put_message(info[GLOM_NAME]);
976       if (neither == TRUE && !strcmp(info[GLOM_MAILLIST], "0") &&
977            !strcmp(info[GLOM_GROUP], "0"))
978         Put_message(info[GLOM_NAME]);
979       elem = elem->q_forw;
980     }
981   FreeQueue(top);
982   return DM_NORMAL;
983 }
984
985 /*      Function Name: ListByAdministrator
986  *      Description: This function prints all lists which a given user or
987  *                   group administers.
988  *      Arguments: none.
989  *      Returns: DM_NORMAL.
990  */
991
992 int ListByAdministrator(int argc, char **argv)
993 {
994   char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name;
995   struct mqelem *top;
996
997   type = strdup("USER");
998   if (GetTypeFromUser("Type of member", "member", &type) == SUB_ERROR)
999     return DM_NORMAL;
1000
1001   sprintf(buf, "Name of %s", type);
1002   name = strdup(user);
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     {
1008     case TRUE:
1009       sprintf(temp_buf, "R%s", type);   /* "USER" to "RUSER" etc. */
1010       free(type);
1011       type = strdup(temp_buf);
1012       break;
1013     case FALSE:
1014       break;
1015     default:
1016       return DM_NORMAL;
1017     }
1018
1019   top = GetListInfo(ACE_USE, type, name);
1020   Loop(top, PrintListAce);
1021
1022   FreeQueue(top);
1023   return DM_NORMAL;
1024 }
1025
1026 /*      Function Name: ListAllPublicMailLists
1027  *      Description: This function lists all public mailing lists.
1028  *      Arguments: none
1029  *      Returns: DM_NORMAL.
1030  */
1031
1032 int ListAllPublicMailLists(int argc, char **argv)
1033 {
1034   int status;
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     {
1046       if ((status = do_mr_query("qualified_get_lists", 5, args,
1047                                 Print, NULL)) != MR_SUCCESS)
1048         com_err(program_name, status, " in ListAllGroups");
1049     }
1050
1051   return DM_NORMAL;
1052 }
This page took 0.119972 seconds and 5 git commands to generate.