#define M_LIST 2
#define M_STRING 3
#define M_KERBEROS 4
-#define M_NONE 5
+#define M_MACHINE 5
+#define M_NONE 6
-char *typename[] = { "ANY", "USER", "LIST", "STRING", "KERBEROS", "NONE" };
+char *typename[] = { "ANY", "USER", "LIST", "STRING", "KERBEROS", "MACHINE",
+ "NONE" };
/* argument parsing macro */
#define argis(a, b) (!strcmp(*arg + 1, a) || !strcmp(*arg + 1, b))
/* flags from command line */
int infoflg, verbose, syncflg, memberflg, recursflg, noauth;
-int showusers, showstrings, showkerberos, showlists, showtags;
+int showusers, showstrings, showkerberos, showlists, showtags, showmachines;
int createflag, setinfo, active, public, hidden, maillist, grouplist;
int nfsgroup;
struct member *owner, *memacl;
/* clear all flags & lists */
infoflg = verbose = syncflg = memberflg = recursflg = 0;
noauth = showusers = showstrings = showkerberos = showlists = 0;
- createflag = setinfo = 0;
+ showtags = showmachines = createflag = setinfo = 0;
active = public = hidden = maillist = grouplist = nfsgroup = -1;
listname = newname = desc = NULL;
owner = NULL;
taglist->q_next != taglist))
memberflg++;
- /* If none of {users,strings,lists,kerberos} specified, turn them all on */
+ /* If none of {users,strings,lists,kerberos,machines} specified,
+ turn them all on */
if (!(showusers || showstrings || showlists || showkerberos))
- showusers = showstrings = showlists = showkerberos = 1;
+ showusers = showstrings = showlists = showkerberos = showmachines = 1;
/* fire up Moira */
status = mrcl_connect(server, "blanche", 4, !noauth);
success = 0;
}
free(membervec[2]);
+ case M_MACHINE:
+ membervec[1] = "MACHINE";
+ membervec[2] = canonicalize_hostname(strdup(memberstruct->name));
+ status = mr_query("add_tagged_member_to_list", 4, membervec,
+ NULL, NULL);
+ if (status != MR_SUCCESS)
+ {
+ com_err(whoami, status, "while adding member %s to %s",
+ memberstruct->name, listname);
+ success = 0;
+ }
+ free(membervec[2]);
}
}
memberstruct->name, listname);
success = 0;
}
+ case M_MACHINE:
+ membervec[1] = "MACHINE";
+ membervec[2] = canonicalize_hostname(memberstruct->name);
+ status = mr_query("delete_member_from_list", 3, membervec,
+ NULL, NULL);
+ if (status != MR_SUCCESS)
+ {
+ com_err(whoami, status, "while deleting member %s from %s",
+ memberstruct->name, listname);
+ success = 0;
+ }
+ free(membervec[2]);
}
}
return;
s = "KERBEROS";
break;
+ case M_MACHINE:
+ if (!showmachines)
+ return;
+ s = "MACHINE";
+ break;
case M_ANY:
printf("%s\n", memberstruct->name);
return;
else if (memberstruct->type == M_STRING &&
!strchr(memberstruct->name, '@'))
printf("STRING:%s", memberstruct->name);
+ else if (memberstruct->type == M_MACHINE)
+ printf("MACHINE:%s", memberstruct->name);
else
printf("%s", memberstruct->name);
}
case 'K':
m->type = M_KERBEROS;
break;
+ case 'M':
+ m->type = M_MACHINE;
+ break;
}
m->name = strdup(argv[1]);
if (argc == 3)
m->type = M_STRING;
else if (!strcasecmp("kerberos", s))
m->type = M_KERBEROS;
+ else if (!strcasecmp("machine", s))
+ m->type = M_MACHINE;
else if (!strcasecmp("none", s))
m->type = M_NONE;
else
case GLOM:
args[0] = name1;
args[1] = name2;
+ if (!strcmp(name1, "MACHINE"))
+ args[1] = canonicalize_hostname(strdup(name2));
if ((status = do_mr_query("get_lists_of_member", 2, args,
StoreInfo, &elem)))
{
free(args[LM_MEMBER]);
args[LM_MEMBER] = canon;
}
+ else if (!strcmp(args[LM_TYPE], "MACHINE"))
+ {
+ char *canon;
+ canon = canonicalize_hostname(strdup(args[LM_MEMBER]));
+ free(args[LM_MEMBER]);
+ args[LM_MEMBER] = canon;
+ }
if ((status = do_mr_query("add_member_to_list", CountArgs(args), args,
NULL, NULL)) != MR_SUCCESS)
}
}
}
+ else if ((status == MR_MACHINE || status == MR_NO_MATCH) &&
+ !strcmp(args[LM_TYPE], "MACHINE"))
+ {
+ char *canon;
+ canon = canonicalize_hostname(args[LM_MEMBER]);
+ free(args[LM_MEMBER]);
+ args[LM_MEMBER] = canon;
+ if (do_mr_query("delete_member_from_list", CountArgs(args),
+ args, NULL, NULL) == MR_SUCCESS)
+ status = MR_SUCCESS;
+ }
}
if (status)
com_err(program_name, status, " in DeleteMember");
args[DM_LIST] = info[GLOM_NAME];
args[DM_TYPE] = type;
args[DM_MEMBER] = name;
+ if (!strcmp("MACHINE", type))
+ args[DM_MEMBER] = canonicalize_hostname(strdup(name));
if ((status = do_mr_query("delete_member_from_list", 3, args,
NULL, NULL)))
{
int show_mem_list(void *id);
int show_mem_str(void *id);
int show_mem_krb(void *id);
+int show_mem_mach(void *id);
void del_mem_user(void *id);
void del_mem_list(void *id);
void del_mem_str(void *id);
void del_mem_krb(void *id);
+void del_mem_mach(void *id);
int show_sh(void *id);
void del_sh_mach(void *id);
void fsmatch(int id, void *nfsphys, void *filesys);
return found;
}
+int show_mem_mach(void *id)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int lid, iid = (int)id, found = 1;
+ EXEC SQL END DECLARE SECTION;
+ struct list *l;
+
+ EXEC SQL DECLARE csr208a CURSOR FOR
+ SELECT list_id FROM imembers
+ WHERE member_id = :iid AND member_type = 'MACHINE';
+ EXEC SQL OPEN csr208a;
+ while (1)
+ {
+ EXEC SQL FETCH csr208a INTO :lid;
+ if (sqlca.sqlcode)
+ break;
+ l = hash_lookup(lists, lid);
+ if (!l)
+ continue;
+
+ found = 0;
+ printf("List %s has nonexistant machine member, id %d\n",
+ l->name, iid);
+ }
+ EXEC SQL CLOSE csr208a;
+ return found;
+}
void del_mem_user(void *id)
{
modified("imembers");
}
+void del_mem_mach(void *id)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int iid = (int)id, rowcount;
+ EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL DELETE FROM imembers WHERE member_type = 'MACHINE' AND
+ member_id = :iid;
+ rowcount = sqlca.sqlerrd[2];
+ if (rowcount > 0)
+ printf("%d entr%s deleted\n", rowcount, rowcount == 1 ? "y" : "ies");
+ else
+ printf("Not deleted\n");
+ modified("imembers");
+}
int show_sh(void *id)
{
sq3 = sq_create();
sq4 = sq_create();
sq5 = sq_create();
+ sq6 = sq_create();
EXEC SQL DECLARE csr223 CURSOR FOR
SELECT list_id, member_type, member_id, tag, ref_count, direct, rowid
sq_save_unique_data(sq4, (void *)id);
else if (type[0] == 'K' && !maybe_fixup_unref_string2("imembers", "member_id", rowid, id))
sq_save_unique_data(sq5, (void *)id);
+ else if (type[0] == 'M' && !maybe_fixup_unref_string2("imembers", "member_id", rowid, id))
+ sq_save_unique_data(sq6, (void *)id);
else
l->members++;
maybe_fixup_unref_string2("imembers", "tag", rowid, tag);
generic_fix(sq3, show_mem_list, "Delete", del_mem_list, 1);
generic_fix(sq4, show_mem_str, "Delete", del_mem_str, 1);
generic_fix(sq5, show_mem_krb, "Delete", del_mem_krb, 1);
+ generic_fix(sq6, show_mem_mach, "Delete", del_mem_mach, 1);
dprintf("Checking servers...\n");
sq1 = sq_create();
char *fs_type, char *fs_pack, int operation);
int get_group_membership(char *group_membership, char *group_ou,
int *security_flag, char **av);
+int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member, char *machine_ou);
int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
char *group_name, char *group_ou, char *group_membership,
int group_security_flag, int type);
char moira_user_id[32];
char group_membership[1];
char group_ou[256];
+ char machine_ou[256];
char *args[16];
char **ptr;
char *av[7];
strcpy(user_name, after[LM_MEMBER]);
strcpy(group_name, after[LM_LIST]);
strcpy(user_type, after[LM_TYPE]);
- if (!strcasecmp(ptr[LM_TYPE], "USER"))
+ if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
+ {
+ if (afterc > LM_EXTRA_GROUP)
+ {
+ strcpy(moira_list_id, before[LM_EXTRA_GID]);
+ strcpy(moira_user_id, before[LMN_LIST_ID]);
+ }
+ }
+ else if (!strcasecmp(ptr[LM_TYPE], "USER"))
{
if (afterc > LMN_LIST_ID)
{
strcpy(user_name, before[LM_MEMBER]);
strcpy(group_name, before[LM_LIST]);
strcpy(user_type, before[LM_TYPE]);
- if (!strcasecmp(ptr[LM_TYPE], "USER"))
+ if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
+ {
+ if (beforec > LM_EXTRA_GROUP)
+ {
+ strcpy(moira_list_id, before[LM_EXTRA_GID]);
+ strcpy(moira_user_id, before[LMN_LIST_ID]);
+ }
+ }
+ else if (!strcasecmp(ptr[LM_TYPE], "USER"))
{
if (beforec > LMN_LIST_ID)
{
{
com_err(whoami, 0, "removing user %s from list %s", user_name, group_name);
pUserOu = user_ou;
+ if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
+ {
+ memset(machine_ou, '\0', sizeof(machine_ou));
+ if (get_machine_ou(ldap_handle, dn_path, ptr[LM_MEMBER], machine_ou))
+ return;
+ pUserOu = machine_ou;
+ }
if (!strcasecmp(ptr[LM_TYPE], "STRING"))
{
if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou))
com_err(whoami, 0, "Adding %s to list %s", user_name, group_name);
pUserOu = user_ou;
- if (!strcasecmp(ptr[LM_TYPE], "STRING"))
+
+ if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
+ {
+ memset(machine_ou, '\0', sizeof(machine_ou));
+ if (get_machine_ou(ldap_handle, dn_path, ptr[LM_MEMBER], machine_ou))
+ return;
+ pUserOu = machine_ou;
+ }
+ else if (!strcasecmp(ptr[LM_TYPE], "STRING"))
{
if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou))
return;
attr_array[1] = NULL;
group_count = 0;
group_base = NULL;
- if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
+ if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
&group_base, &group_count)) == LDAP_SUCCESS)
{
if (group_count == 1)
}
return(0);
}
+
+int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member, char *machine_ou)
+{
+ LK_ENTRY *group_base;
+ int group_count;
+ int i;
+ char filter[128];
+ char *attr_array[3];
+ char cn[256];
+ char dn[256];
+ char temp[256];
+ char *pPtr;
+ int rc;
+
+ pPtr = NULL;
+ pPtr = strchr(member, '.');
+ if (pPtr != NULL)
+ (*pPtr) = '\0';
+
+ group_base = NULL;
+ group_count = 0;
+ sprintf(filter, "(sAMAccountName=%s$)", member);
+ attr_array[0] = "cn";
+ attr_array[1] = NULL;
+ sprintf(temp, "%s", dn_path);
+ if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
+ &group_base, &group_count)) != 0)
+ {
+ com_err(whoami, 0, "LDAP server couldn't process machine %s : %s",
+ member, ldap_err2string(rc));
+ return(1);
+ }
+ if (group_count != 1)
+ {
+ com_err(whoami, 0, "LDAP server couldn't process machine %s : machine not found in AD",
+ member);
+ return(1);
+ }
+ strcpy(dn, group_base->dn);
+ strcpy(cn, group_base->value);
+ for (i = 0; i < (int)strlen(dn); i++)
+ dn[i] = tolower(dn[i]);
+ for (i = 0; i < (int)strlen(cn); i++)
+ cn[i] = tolower(cn[i]);
+ linklist_free(group_base);
+ pPtr = NULL;
+ pPtr = strstr(dn, cn);
+ if (pPtr == NULL)
+ {
+ com_err(whoami, 0, "LDAP server couldn't process machine %s",
+ member);
+ return(1);
+ }
+ pPtr += strlen(cn) + 1;
+ strcpy(machine_ou, pPtr);
+ pPtr = NULL;
+ pPtr = strstr(machine_ou, "dc=");
+ if (pPtr == NULL)
+ {
+ com_err(whoami, 0, "LDAP server couldn't process machine %s",
+ member);
+ return(1);
+ }
+ --pPtr;
+ (*pPtr) = '\0';
+ return(0);
+}
EXEC SQL SELECT list_id INTO :before[9] FROM list
WHERE name = :name;
}
+ else if (!strcmp(before[1], "MACHINE"))
+ {
+ id_to_name(id, MACHINE_TABLE, &name2);
+ EXEC SQL SELECT mach_id INTO :before[9] FROM machine
+ WHERE name = :name;
+ }
strcpy(before[2], name2);
free(name);
free(name2);
EXEC SQL SELECT list_id INTO :after[9] FROM list
WHERE name = :name;
}
+ else if (!strcmp(after[1], "MACHINE"))
+ {
+ id_to_name(id, MACHINE_TABLE, &name2);
+ EXEC SQL SELECT mach_id INTO :after[9] FROM machine
+ WHERE name = :name;
+ }
strcpy(after[2], name2);
free(name);
free(name2);
WHERE mach_id = :id;
if (cnt > 0)
return MR_IN_USE;
+ EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
+ WHERE member_type = 'MACHINE' and member_id = :id;
+ if (cnt > 0)
+ return MR_IN_USE;
EXEC SQL DELETE FROM mcmap WHERE mach_id = :id;
if (dbms_errno)
case 'K':
dtypes[dcount] = "KERBEROS";
break;
+ case 'M':
+ dtypes[dcount] = "MACHINE";
+ break;
default:
error++;
break;
case 'K':
dtypes[dcount] = "KERBEROS";
break;
+ case 'M':
+ dtypes[dcount] = "MACHINE";
+ break;
default:
error++;
break;
/* get_lists_of_member - given a type and a name, return the name and flags
* of all of the lists of the given member. The member_type is one of
- * "LIST", "USER", "STRING", "RLIST", "RUSER", or "RSTRING" in argv[0],
- * and argv[1] will contain the ID of the entity in question. The R*
- * types mean to recursively look at every containing list, not just
- * when the object in question is a direct member.
+ * "LIST", "USER", "STRING", "KERBEROS", "MACHINE", "RLIST", "RUSER",
+ * "RSTRING", "RKERBEROS", or "RMACHINE" in argv[0], and argv[1] will contain
+ * the ID of the entity in question. The R* types mean to recursively look
+ * at every containing list, not just when the object in question is a direct
+ * member.
*/
int get_lists_of_member(struct query *q, char *argv[], client *cl,
atype = "KERBEROS";
direct = 0;
}
+ if (!strcmp(atype, "RMACHINE"))
+ {
+ atype = "MACHINE";
+ direct = 0;
+ }
rargv[0] = name;
rargv[1] = active;
if (dbms_errno)
return mr_errcode;
+ targv[0] = "MACHINE";
+ EXEC SQL DECLARE csr123 CURSOR FOR
+ SELECT m.name, s.string FROM machine m, imembers im, strings s
+ WHERE im.list_id = :list_id AND im.member_type = 'MACHINE'
+ AND im.member_id = m.mach_id AND im.direct > :direct
+ AND s.string_id = im.tag ORDER BY 1;
+ if (dbms_errno)
+ return mr_errcode;
+ EXEC SQL OPEN csr123;
+ if (dbms_errno)
+ return mr_errcode;
+ while (1)
+ {
+ EXEC SQL FETCH csr123 INTO :member_name, :tag;
+ if (sqlca.sqlcode)
+ break;
+ (*action)(targc, targv, actarg);
+ }
+ EXEC SQL CLOSE csr123;
+ if (dbms_errno)
+ return mr_errcode;
+
return MR_SUCCESS;
}