/* * * Copyright (c) 1999 - 2011 my-Channels Ltd * Copyright (c) 2012 - 2017 Software AG, Darmstadt, Germany and/or Software AG USA Inc., Reston, VA, USA, and/or its subsidiaries and/or its affiliates and/or their licensors. * * Use, reproduction, transfer, publication or disclosure is prohibited except as specifically provided for in your License Agreement with Software AG. * */ #include "nSampleApp.h" #include "nRealmNode.h" #include "nLeafNode.h" #include "nChannelACLEntry.h" #include "nSessionAttributes.h" #include "nAdminIllegalArgumentException.h" #include "nACL.h" #include #include namespace com { namespace pcbsys { namespace nirvana { namespace nAdminAPI { namespace apps { using namespace com::pcbsys::nirvana::client; using namespace com::pcbsys::nirvana::nAdminAPI; class modchanacl { /// /// This application can be used to add a new subject to a channel, and assign permissions /// for operations performed on the channel. /// private: std::string m_realm; std::string m_name; std::string m_host; bool m_bPattern; bool m_bFactory; bool m_bCanListAcl; bool m_bCanModifyAcl; bool m_bFullPrivileges; bool m_bCanGetLastEid; bool m_bCanRead; bool m_bCanWrite; bool m_bCanPurge; bool m_bCanNamed; nSessionAttributes *m_pAttr; std::string m_channelName; nRealmNode *m_pNode; nACL *m_pAcl; int m_changeArgc; char **m_changeArgv; public: /// /// * Consruct an instance of this class using the command line arguments passed /// * when it is executed. /// modchanacl(int argc, char** argv) :m_bPattern(false), m_bFactory(false), m_bCanListAcl(false), m_bCanModifyAcl(false), m_bFullPrivileges(false), m_bCanGetLastEid(false), m_bCanRead(false), m_bCanWrite(false), m_bCanPurge(false), m_bCanNamed(false), m_pAttr(NULL), m_pNode(NULL), m_pAcl(NULL), m_changeArgc(argc), m_changeArgv(argv) { try { getOptions(m_changeArgc, m_changeArgv); printf("Connecting to %s\n", m_realm.c_str()); // construct the session attributes from the realm m_pAttr = new nSessionAttributes(m_realm); // get the root realm node from the realm admin m_pNode = new nRealmNode(m_pAttr); if (!m_pNode->isAuthorised()) { printf("User not authorised on this node %s\n", m_realm.c_str()); return; } printf("waiting for namepsace construction....."); m_pNode->waitForEntireNameSpace(); printf("finished\n"); dump(); searchNode (m_pNode); m_pNode->close(); } catch (Exception e) { printf("%s\n", e.message().c_str()); exit(1); } } /// /// * recursively search through the realm node looking for channel nodes /// virtual void setChannel(nRealmNode *pNode, nLeafNode *pLeaf) { try { // get the acl for the channel node m_pAcl = pLeaf->getACLs(); printf("Creating new entry for %s@%s\n", m_name.c_str(), m_host.c_str()); // create a new acl entry with the name and host nChannelACLEntry *pLookup = (nChannelACLEntry*)m_pAcl->find(m_name + "@" + m_host); // set the current permissions from the acl entry setCurrent(pLookup); printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); printf("Current ACL Settings for %s on realm %s\n", pLeaf->getName().c_str(), pNode->getName().c_str()); printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); dump(pLookup); // now set those which have changed setChanges(); // change the entry in the acl pLeaf->modACLEntry(changeACLEntry(pLookup)); // set the node acl to the new acl list printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); printf("New ACL Settings for %s on realm %s\n", pLeaf->getName().c_str(), pNode->getName().c_str()); printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); dump(pLookup); } catch (Exception e) { printf("%s\n", e.message().c_str()); } } /// /// * search the enumeration of child nodes for other realms and channels /// void searchNodes(nRealmNode *pNode, fSortedList& nodes) { for (fSortedList::iterator iterator = nodes.begin(); iterator != nodes.end(); iterator++) { nNode *pChild = iterator->second; int type = pChild->getType(); if (type == fBase::LEAFNODE) { nLeafNode *pLeaf = (nLeafNode*)pChild; std::string fullyQualifiedName = pLeaf->getAbsolutePath(); printf ("Found channel %s\n", fullyQualifiedName.c_str()); if (m_bPattern) { if ((pLeaf->isChannel()) && (fullyQualifiedName.find(m_channelName) != -1)) { setChannel(pNode, pLeaf); return; } } else if (m_bFactory) { if ((pLeaf->isChannel()) && (fullyQualifiedName.find(m_channelName) == 0)) { setChannel(pNode, pLeaf); return; } } else if ((pLeaf->isChannel()) && (fullyQualifiedName.compare(m_channelName) == 0)) { setChannel(pNode, pLeaf); return; } } if (type == fBase::REALMNODE) { searchNode((nRealmNode*)pChild); } else if (type == fBase::CONTAINER) { nContainer *pCont = (nContainer*)pChild; searchNodes(pNode, pCont->getNodes()); } } } /// /// * Change an acl entry and set the permissions based on the permissions flags /// virtual nChannelACLEntry* changeACLEntry(nChannelACLEntry *pAclEntry) { return setPermissions(pAclEntry); } /// /// * If you construct an instance of this class from another class, you can set the name /// * and host for the subject. /// virtual void setSubject(const std::string& name, const std::string& host) { m_name = name; m_host = host; } /// /// * This will set the permissions flags to what the current acl settings are /// * /// * This is so that only those permissions that you wish to change are changed /// virtual void setCurrent(nChannelACLEntry *pEntry) { m_bCanListAcl = pEntry->canList(); m_bCanModifyAcl = pEntry->canModify(); m_bFullPrivileges = pEntry->hasFullPrivileges(); m_bCanGetLastEid = pEntry->canGetLastEID(); m_bCanRead = pEntry->canRead(); m_bCanWrite = pEntry->canWrite(); m_bCanPurge = pEntry->canPurge(); m_bCanNamed = pEntry->canUseNamedSubscription(); } /// /// * Set the permissions on the realm acl entry /// virtual nChannelACLEntry* setPermissions(nChannelACLEntry *pAclEntry) { pAclEntry->setList(m_bCanListAcl); pAclEntry->setModify(m_bCanModifyAcl); pAclEntry->setFullPrivileges(m_bFullPrivileges); pAclEntry->setGetLastEID(m_bCanGetLastEid); pAclEntry->setRead(m_bCanRead); pAclEntry->setWrite(m_bCanWrite); pAclEntry->setPurge(m_bCanPurge); pAclEntry->setUseNamedSubscription(m_bCanNamed); return pAclEntry; } /// /// * Output to system.out the permissions that have been set /// virtual void dump(nChannelACLEntry *pEntry) { printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); printf("List ACL : %d\n", pEntry->canList()); printf("Set ACL : %d\n", pEntry->canModify()); printf("Full Privileges : %d\n", pEntry->hasFullPrivileges()); printf("Get Last EID : %d\n", pEntry->canGetLastEID()); printf("Read channel : %d\n", pEntry->canRead()); printf("Write to channel : %d\n", pEntry->canWrite()); printf("Purge channel : %d\n", pEntry->canPurge()); printf("Use named subscription : %d\n", pEntry->canUseNamedSubscription()); printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); } /// /// * Output to system.out the permissions that will be set /// virtual void dump() { printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); printf("ACL will be set to.... \n"); printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); printf("List ACL : %d\n", m_bCanListAcl); printf("Set ACL : %d\n", m_bCanModifyAcl); printf("Full Privileges : %d\n", m_bFullPrivileges); printf("Get Last EID : %d\n", m_bCanGetLastEid); printf("Read channel : %d\n", m_bCanRead); printf("Write to channel : %d\n", m_bCanWrite); printf("Purge channel : %d\n", m_bCanPurge); printf("Use named subscription : %d\n", m_bCanNamed); printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"); } virtual void getOptions(int argc, char** argv) { if (argv == NULL || argc <5 ) { Usage(); exit(1); } m_realm = argv[1]; m_name = argv[2]; m_host = argv[3]; m_channelName = argv[4]; if(m_channelName.substr(0,1) != "/") m_channelName="/"+m_channelName; if (m_channelName.find("%") != -1) { if ((m_channelName.find("%") == 0) && (m_channelName.find_last_of("%") == (m_channelName.length() - 1))) { m_channelName = m_channelName.substr(1); m_channelName = m_channelName.substr(0, m_channelName.length() - 1); m_bPattern = true; } if (m_channelName.find_last_of("%") == (m_channelName.length() - 1)) { m_channelName = m_channelName.substr(0, m_channelName.length() - 1); m_bFactory = true; } } } /// /// * This method will set the permissions flags, if the command line arguments have been /// * passed for specific permissions. /// * /// * The command line arguments are + or - for either add or remove permission, followed /// * by the actual permission flag /// virtual void setChanges() { for (int i = 0; i < m_changeArgc; i++) { bool hasPermission; if (m_changeArgv[i][0] == '+') { hasPermission = true; } else if (m_changeArgv[i][0] == '-') { hasPermission = false; } else { continue; } std::string permission = &m_changeArgv[i][1]; printf("operation %d for permission %s\n", hasPermission, permission.c_str()); if (permission.compare("list_acl") == 0) { m_bCanListAcl = hasPermission; } else if (permission.compare("modify_acl") == 0) { m_bCanModifyAcl = hasPermission; } else if (permission.compare("full") == 0) { m_bFullPrivileges = hasPermission; } else if (permission.compare("read") == 0) { m_bCanRead = hasPermission; } else if (permission.compare("write") == 0) { m_bCanWrite = hasPermission; } else if (permission.compare("purge") == 0) { m_bCanPurge = hasPermission; } else if (permission.compare("named") == 0) { m_bCanNamed = hasPermission; } else if (permission.compare("all_perms") == 0) { m_bCanListAcl = hasPermission; m_bCanModifyAcl = hasPermission; m_bCanGetLastEid = hasPermission; m_bCanRead = hasPermission; m_bCanWrite = hasPermission; m_bCanPurge = hasPermission; m_bCanNamed = hasPermission; } } } private: /// /// * Search the children of the realm passed as a paremeter /// void searchNode(nRealmNode *pNode) { try { searchNodes(pNode, pNode->getNodes()); } catch (Exception ex) { printf ("%s\n", ex.message().c_str()); } } /// /// * Prints the usage message for this class /// static void Usage() { printf("Usage ...\n\n"); printf("nmodchanacl [list_acl] [modify_acl] [full] [last_eid] [read] [write] [purge] [named]\n\n"); printf(" \n\n"); printf(" - the rname of the server to connect to\n"); printf(" - User name parameter for the new ACL entry\n"); printf(" - Host name parameter for the new ACL entry\n"); printf(" - Channel name parameter for the new ACL entry\n"); printf("\n[Optional Arguments] \n\n"); printf("[+/-] - Prepending + or - specifies whether to add or remove a permission\n"); printf("[list_acl] - Specifies that the list acl permission should be added\n"); printf("[modify_acl] - Specifies that the modify acl permission should be added\n"); printf("[full] - Specifies that the full permission should be added\n"); printf("[last_eid] - Specifies that the get last EID permission should be added\n"); printf("[read] - Specifies that the read permission should be added\n"); printf("[write] - Specifies that the write permission should be added\n"); printf("[purge] - Specifies that the purge permission should be added\n"); printf("[named] - Specifies that the used named subscriber permission should be added\n"); printf("[all_perms] - Specifies that the pop permission should be added/removed\n"); } }; } } } } } using namespace com::pcbsys::nirvana::nAdminAPI::apps; int main (int argc, char** argv) { modchanacl (argc, argv); return 0; }