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