From 5f7b0741c3729fc988f8ae34c07e471b6854503b Mon Sep 17 00:00:00 2001 From: zacheiss Date: Fri, 14 Dec 2001 21:04:54 +0000 Subject: [PATCH] Support MACHINE members of lists. --- clients/blanche/blanche.c | 51 +++++++++++++++--- clients/moira/lists.c | 22 ++++++++ dbck/phase2.pc | 48 +++++++++++++++++ incremental/winad/winad.c | 108 ++++++++++++++++++++++++++++++++++++-- server/increment.pc | 12 +++++ server/qsetup.pc | 4 ++ server/qsupport.pc | 42 +++++++++++++-- 7 files changed, 273 insertions(+), 14 deletions(-) diff --git a/clients/blanche/blanche.c b/clients/blanche/blanche.c index 5bec6df9..5742f7a2 100644 --- a/clients/blanche/blanche.c +++ b/clients/blanche/blanche.c @@ -33,16 +33,18 @@ struct member { #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; @@ -79,7 +81,7 @@ int main(int argc, char **argv) /* 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; @@ -328,9 +330,10 @@ int main(int argc, char **argv) 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); @@ -735,6 +738,18 @@ int main(int argc, char **argv) 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]); } } @@ -845,6 +860,18 @@ int main(int argc, char **argv) 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]); } } @@ -1032,6 +1059,11 @@ void show_list_member(struct member *memberstruct) return; s = "KERBEROS"; break; + case M_MACHINE: + if (!showmachines) + return; + s = "MACHINE"; + break; case M_ANY: printf("%s\n", memberstruct->name); return; @@ -1048,6 +1080,8 @@ void show_list_member(struct member *memberstruct) 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); } @@ -1188,6 +1222,9 @@ int get_list_members(int argc, char **argv, void *sq) case 'K': m->type = M_KERBEROS; break; + case 'M': + m->type = M_MACHINE; + break; } m->name = strdup(argv[1]); if (argc == 3) @@ -1287,6 +1324,8 @@ struct member *parse_member(char *s) 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 diff --git a/clients/moira/lists.c b/clients/moira/lists.c index b839836f..a398ef02 100644 --- a/clients/moira/lists.c +++ b/clients/moira/lists.c @@ -158,6 +158,8 @@ struct mqelem *GetListInfo(int type, char *name1, char *name2) 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))) { @@ -719,6 +721,13 @@ int AddMember(int argc, char **argv) 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) @@ -773,6 +782,17 @@ int DeleteMember(int argc, char **argv) } } } + 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"); @@ -870,6 +890,8 @@ int InterRemoveItemFromLists(int argc, char **argv) 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))) { diff --git a/dbck/phase2.pc b/dbck/phase2.pc index 39ae1524..5a401798 100644 --- a/dbck/phase2.pc +++ b/dbck/phase2.pc @@ -55,10 +55,12 @@ int show_mem_user(void *id); 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); @@ -1095,6 +1097,33 @@ int show_mem_krb(void *id) 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) { @@ -1161,6 +1190,21 @@ void del_mem_krb(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) { @@ -1944,6 +1988,7 @@ void phase2(void) 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 @@ -1972,6 +2017,8 @@ void phase2(void) 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); @@ -1982,6 +2029,7 @@ void phase2(void) 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(); diff --git a/incremental/winad/winad.c b/incremental/winad/winad.c index 93ce3a04..d3b94e69 100755 --- a/incremental/winad/winad.c +++ b/incremental/winad/winad.c @@ -312,6 +312,7 @@ int filesys_process(LDAP *ldap_handle, char *dn_path, char *fs_name, 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); @@ -885,6 +886,7 @@ void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, 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]; @@ -909,7 +911,15 @@ void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, 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) { @@ -935,7 +945,15 @@ void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, 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) { @@ -1015,6 +1033,13 @@ void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, { 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)) @@ -1036,7 +1061,15 @@ void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, 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; @@ -4181,7 +4214,7 @@ int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName, 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) @@ -4316,3 +4349,70 @@ int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName) } 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); +} diff --git a/server/increment.pc b/server/increment.pc index b045091c..9c10b04c 100644 --- a/server/increment.pc +++ b/server/increment.pc @@ -216,6 +216,12 @@ void incremental_before(enum tables table, char *qual, char **argv) 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); @@ -373,6 +379,12 @@ void incremental_after(enum tables table, char *qual, char **argv) 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); diff --git a/server/qsetup.pc b/server/qsetup.pc index 62484540..83b6d228 100644 --- a/server/qsetup.pc +++ b/server/qsetup.pc @@ -224,6 +224,10 @@ int setup_dmac(struct query *q, char *argv[], client *cl) 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) diff --git a/server/qsupport.pc b/server/qsupport.pc index 0a29f0ce..c133a0ee 100644 --- a/server/qsupport.pc +++ b/server/qsupport.pc @@ -272,6 +272,9 @@ int add_member_to_list(struct query *q, char **argv, client *cl) case 'K': dtypes[dcount] = "KERBEROS"; break; + case 'M': + dtypes[dcount] = "MACHINE"; + break; default: error++; break; @@ -444,6 +447,9 @@ int delete_member_from_list(struct query *q, char **argv, client *cl) case 'K': dtypes[dcount] = "KERBEROS"; break; + case 'M': + dtypes[dcount] = "MACHINE"; + break; default: error++; break; @@ -1036,10 +1042,11 @@ int get_host_by_owner(struct query *q, char *argv[], client *cl, /* 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, @@ -1076,6 +1083,11 @@ 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; @@ -1269,6 +1281,28 @@ int get_members_of_list(struct query *q, char *argv[], client *cl, 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; } -- 2.45.2