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