-/* $Id $
+/* $Id$
*
* This is the file lists.c for the Moira Client, which allows users
* to quickly and easily maintain most parts of the Moira database.
#include <mit-copyright.h>
#include <moira.h>
+#include <mrclient.h>
#include <moira_site.h>
#include "defs.h"
#include "f_defs.h"
struct mqelem *GetListInfo(int type, char *name1, char *name2);
char **AskListInfo(char **info, Bool name);
int AddList(int argc, char **argv);
-void ListMembersByType(char *type);
+void ListMembersByType(char *type, int tags);
int GetMemberInfo(char *action, char **ret_argv);
#define LIST 0
#define DEFAULT_MAILLIST DEFAULT_YES
#define DEFAULT_GROUP DEFAULT_NO
#define DEFAULT_GID UNIQUE_GID
+#define DEFAULT_NFSGROUP DEFAULT_NO
#define DEFAULT_ACE_TYPE "user"
#define DEFAULT_ACE_NAME (user)
+#define DEFAULT_MEMACE_TYPE "NONE"
+#define DEFAULT_MEMACE_NAME "NONE"
#define DEFAULT_DESCRIPTION DEFAULT_COMMENT
/* globals only for this file. */
static char current_list[BUFSIZ];
+
/* Function Name: PrintListAce
* Description: This function prints the list ace information.
* Arguments: info - an info structure.
Put_message("This list is NOT a mailing list.");
if (atoi(info[L_GROUP]))
{
- sprintf(buf, "This list is a Group and its ID number is %s",
+ sprintf(buf, "This list is a Group%s and its ID number is %s",
+ atoi(info[L_NFSGROUP]) ? " and an NFS Group," : "",
info[L_GID]);
Put_message(buf);
}
Put_message(buf);
}
+ if (strcmp(info[L_MEMACE_TYPE], "NONE"))
+ {
+ sprintf(buf, "The Membership Administrator of this list is the %s: %s",
+ info[L_MEMACE_TYPE], info[L_MEMACE_NAME]);
+ Put_message(buf);
+ }
+
sprintf(buf, "This list is: %s, %s, and %s",
atoi(info[L_ACTIVE]) ? "active" : "inactive",
atoi(info[L_PUBLIC]) ? "public" : "private",
return NULL;
if (atoi(info[L_GROUP]))
{
+ if (GetYesNoValueFromUser("Is this an NFS group", &info[L_NFSGROUP]) ==
+ SUB_ERROR)
+ return NULL;
if (GetValueFromUser("What is the GID for this group.", &info[L_GID]) ==
SUB_ERROR)
return NULL;
}
- if (GetTypeFromUser("What Type of Administrator", "ace_type",
- &info[L_ACE_TYPE]) == SUB_ERROR)
+ do {
+ if (GetTypeFromUser("What Type of Administrator", "ace_type",
+ &info[L_ACE_TYPE]) == SUB_ERROR)
+ return NULL;
+ if (strcasecmp(info[L_ACE_TYPE], "none"))
+ {
+ sprintf(temp_buf, "Which %s will be the administrator of this list: ",
+ info[L_ACE_TYPE]);
+ if (GetValueFromUser(temp_buf, &info[L_ACE_NAME]) == SUB_ERROR)
+ return NULL;
+ }
+ else
+ {
+ Put_message("Setting the administrator of this list to 'NONE'");
+ Put_message("will make you unable to further modify the list.");
+ if (YesNoQuestion("Do you really want to do this?", FALSE) == TRUE)
+ break;
+ }
+ } while (!strcasecmp(info[L_ACE_TYPE], "none"));
+
+ if (!strcasecmp(info[L_ACE_TYPE], "kerberos"))
+ {
+ char *canon;
+
+ mrcl_validate_kerberos_member(info[L_ACE_NAME], &canon);
+ if (mrcl_get_message())
+ Put_message(mrcl_get_message());
+ free(info[L_ACE_NAME]);
+ info[L_ACE_NAME] = canon;
+ }
+ if (GetTypeFromUser("What Type of Membership Administrator", "ace_type",
+ &info[L_MEMACE_TYPE]) == SUB_ERROR)
return NULL;
- if (strcasecmp(info[L_ACE_TYPE], "NONE") &&
- strcasecmp(info[L_ACE_TYPE], "none"))
+ if (strcasecmp(info[L_MEMACE_TYPE], "none"))
{
- sprintf(temp_buf, "Which %s will be the administrator of this list: ",
- info[L_ACE_TYPE]);
- if (GetValueFromUser(temp_buf, &info[L_ACE_NAME]) == SUB_ERROR)
+ sprintf(temp_buf, "Which %s will be the membership administrator of this list: ",
+ info[L_MEMACE_TYPE]);
+ if (GetValueFromUser(temp_buf, &info[L_MEMACE_NAME]) == SUB_ERROR)
return NULL;
}
+ if (!strcasecmp(info[L_MEMACE_TYPE], "kerberos"))
+ {
+ char *canon;
+
+ mrcl_validate_kerberos_member(info[L_MEMACE_NAME], &canon);
+ if (mrcl_get_message())
+ Put_message(mrcl_get_message());
+ free(info[L_MEMACE_NAME]);
+ info[L_MEMACE_NAME] = canon;
+ }
if (GetValueFromUser("Description: ", &info[L_DESC]) == SUB_ERROR)
return NULL;
info[L_MAILLIST] = strdup(DEFAULT_MAILLIST);
info[L_GROUP] = strdup(DEFAULT_GROUP);
info[L_GID] = strdup(DEFAULT_GID);
+ info[L_NFSGROUP] = strdup(DEFAULT_NFSGROUP);
info[L_ACE_TYPE] = strdup(DEFAULT_ACE_TYPE);
info[L_ACE_NAME] = strdup(DEFAULT_ACE_NAME);
+ info[L_MEMACE_TYPE] = strdup(DEFAULT_MEMACE_TYPE);
+ info[L_MEMACE_NAME] = strdup(DEFAULT_MEMACE_NAME);
info[L_DESC] = strdup(DEFAULT_DESCRIPTION);
info[L_MODTIME] = info[L_MODBY] = info[L_MODWITH] = info[L_END] = NULL;
return info;
Put_message(buf);
Loop(QueueTop(elem), FreeInfo);
FreeQueue(elem);
- if (YesNoQuestion("Crate a list with the same name", FALSE) != TRUE)
+ if (YesNoQuestion("Create a list with the same name", FALSE) != TRUE)
return SUB_ERROR;
}
/* Function Name: ListMembersByType
* Description: This function lists the users of a list by type.
* Arguments: type - the type of the list "USER", "LIST", or "STRING".
+ * tags - whether or not to display tags
* Returns: none.
* NOTE: if type is NULL, all lists members are listed.
*/
-void ListMembersByType(char *type)
+void ListMembersByType(char *type, int tags)
{
char temp_buf[BUFSIZ];
int status;
args[1] = NULL;
found_some = FALSE;
- if ((status = do_mr_query("get_members_of_list", CountArgs(args), args,
- PrintByType, type)))
+ if ((status = do_mr_query(tags ? "get_tagged_members_of_list" :
+ "get_members_of_list", CountArgs(args),
+ args, PrintByType, type)))
com_err(program_name, status, " in ListMembersByType");
if (!found_some)
{
int ListAllMembers(int argc, char **argv)
{
- ListMembersByType(NULL);
+ ListMembersByType(NULL, 0);
return DM_NORMAL;
}
int ListUserMembers(int argc, char **argv)
{
- ListMembersByType("USER");
+ ListMembersByType("USER", 0);
return DM_NORMAL;
}
int ListListMembers(int argc, char **argv)
{
- ListMembersByType("LIST");
+ ListMembersByType("LIST", 0);
return DM_NORMAL;
}
int ListStringMembers(int argc, char **argv)
{
- ListMembersByType("STRING");
+ ListMembersByType("STRING", 0);
return DM_NORMAL;
}
if (!strcmp(args[LM_TYPE], "STRING"))
{
- if ((p = strchr(args[LM_MEMBER], '@')))
- {
- char *host = canonicalize_hostname(strdup(++p));
- mailhubs = GetTypeValues("mailhub");
- for (elem = mailhubs; elem; elem = elem->q_forw)
- {
- if (!strcasecmp(host, elem->q_data))
- {
- free(host);
- host = strdup(args[LM_MEMBER]);
- *(--p) = 0;
- sprintf(temp_buf, "String \"%s\" should be USER or LIST "
- "\"%s\" because it is a local name.", host,
- args[LM_MEMBER]);
- Put_message(temp_buf);
- free(args[LM_TYPE]);
- free(host);
- return DM_NORMAL;
- }
- }
- free(host);
- }
- else if (!strchr(args[LM_MEMBER], '!'))
- {
- Put_message("Member which is not a foreign mail address "
- "should not be type STRING.");
- return DM_NORMAL;
- }
+ status = mrcl_validate_string_member(args[LM_MEMBER]);
+ if (status != MRCL_SUCCESS)
+ Put_message(mrcl_get_message());
+ if (status == MRCL_REJECT)
+ return DM_NORMAL;
+ }
+ else if (!strcmp(args[LM_TYPE], "KERBEROS"))
+ {
+ char *canon;
+
+ mrcl_validate_kerberos_member(args[LM_MEMBER], &canon);
+ if (mrcl_get_message())
+ Put_message(mrcl_get_message());
+ free(args[LM_MEMBER]);
+ args[LM_MEMBER] = canon;
}
if ((status = do_mr_query("add_member_to_list", CountArgs(args), args,
{
if ((status = do_mr_query("delete_member_from_list", CountArgs(args),
args, NULL, NULL)))
+ {
+ if ((status == MR_STRING || status == MR_NO_MATCH) &&
+ !strcmp(args[LM_TYPE], "KERBEROS"))
+ {
+ char *canon;
+ mrcl_validate_kerberos_member(args[LM_MEMBER], &canon);
+ if (mrcl_get_message())
+ {
+ free(args[LM_MEMBER]);
+ args[LM_MEMBER] = canon;
+ if (do_mr_query("delete_member_from_list", CountArgs(args),
+ args, NULL, NULL) == MR_SUCCESS)
+ {
+ Put_message(mrcl_get_message());
+ status = MR_SUCCESS;
+ }
+ }
+ }
+ }
+ if (status)
com_err(program_name, status, " in DeleteMember");
else
Put_message("Deletion Completed.");
return DM_NORMAL;
}
+/* Function Name: TagMember
+ * Description: Add a tag to a list member
+ * Arguments:
+ * Returns: DM_NORMAL
+ */
+
+int TagMember(int argc, char **argv)
+{
+ char *args[10];
+ int status;
+
+ if (GetMemberInfo("tag", args) == SUB_ERROR)
+ return DM_NORMAL;
+
+ args[LM_TAG] = strdup("");
+ if (GetValueFromUser("Tag" , &args[LM_TAG]) == SUB_ERROR)
+ {
+ Put_message("Aborted.");
+ return DM_NORMAL;
+ }
+ args[LM_TAG_END] = NULL; /* NULL terminate this list. */
+
+ if ((status = do_mr_query("tag_member_of_list", CountArgs(args),
+ args, NULL, NULL)))
+ com_err(program_name, status, " in TagMember");
+
+ FreeInfo(args);
+ return DM_NORMAL;
+}
+
+/* Function Name: ListAllMembers
+ * Description: lists all members of the current list.
+ * Arguments:
+ * Returns: DM_NORMAL
+ */
+
+int ListMembersWithTags(int argc, char **argv)
+{
+ ListMembersByType(NULL, 1);
+ return DM_NORMAL;
+}
+
/* Function Name: InterRemoveItemFromLists
* Description: This function allows interactive removal of an item
* (user, string, list) for all list that it is on.
int ListByMember(int argc, char **argv)
{
char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name, **info;
- Bool maillist, group;
+ Bool maillist, group, neither;
struct mqelem *top, *elem;
type = strdup("USER");
if (GetValueFromUser(buf, &name) == SUB_ERROR)
return DM_NORMAL;
- /* What we really want is a recursive search */
- sprintf(temp_buf, "R%s", type);
- free(type);
- type = strdup(temp_buf);
+ switch (YesNoQuestion("Do you want a recursive search (y/n)", TRUE))
+ {
+ case TRUE:
+ sprintf(temp_buf, "R%s", type); /* "USER" to "RUSER" etc. */
+ free(type);
+ type = strdup(temp_buf);
+ break;
+ case FALSE:
+ break;
+ default:
+ return DM_NORMAL;
+ }
if ((maillist = YesNoQuestion("Show Lists that are Maillists (y/n) ?",
TRUE)) == -1)
TRUE)) == -1)
return DM_NORMAL;
+ if ((neither = YesNoQuestion("Show Lists that are neither Maillists nor Groups (y/n) ?",
+ TRUE)) == -1)
+ return DM_NORMAL;
+
elem = top = GetListInfo(GLOM, type, name);
while (elem)
if ((maillist == TRUE && !strcmp(info[GLOM_MAILLIST], "1")) ||
(group == TRUE && !strcmp(info[GLOM_GROUP], "1")))
Put_message(info[GLOM_NAME]);
+ if (neither == TRUE && !strcmp(info[GLOM_MAILLIST], "0") &&
+ !strcmp(info[GLOM_GROUP], "0"))
+ Put_message(info[GLOM_NAME]);
elem = elem->q_forw;
}
FreeQueue(top);