123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490 |
- /*
- * Copyright 2005 - 2016 Zarafa and its licensors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- // -*- Mode: c++ -*-
- #ifndef UNIXUSERPLUGIN_H
- #define UNIXUSERPLUGIN_H
- #include <memory>
- #include <mutex>
- #include <string>
- #include <kopano/zcdefs.h>
- #include <kopano/ECIConv.h>
- #include "plugin.h"
- #include "DBBase.h"
- /**
- * @defgroup userplugin_unix UNIX user plugin
- * @ingroup userplugin
- * @{
- */
- namespace KC {
- /**
- * UNIX user plugin
- *
- * User management based on Unix. It uses /etc/passwd for the
- * loginname, fullname; and /etc/shadow for the password. Because it
- * needs to read /etc/shadow the server needs to run as a member of
- * the shadow group. When password updates need to be done, root
- * privileges are required.
- *
- * Extra attributes, such as email addresses, are stored in the objectproperty
- * tables, which are always present. It's exactly the same as the DBUserPlugin.
- */
- class UnixUserPlugin: public DBPlugin {
- public:
- /**
- * @param[in] pluginlock
- * The plugin mutex
- * @param[in] lpSharedData
- * The singleton shared plugin data.
- * @throw runtime_error When configuration file could not be loaded
- * @throw notsupported When multi-server or multi-company support is enabled.
- */
- UnixUserPlugin(std::mutex &, ECPluginSharedData *lpSharedData);
- virtual ~UnixUserPlugin();
- /**
- * Initialize plugin
- */
- void InitPlugin();
- /**
- * Resolve name and company to objectsignature
- *
- * @param[in] objclass
- * The objectclass of the name which should be resolved.
- * The objectclass can be partially unknown (OBJECTCLASS_UNKNOWN, MAILUSER_UNKNOWN, ...)
- * @param[in] name
- * The name which should be resolved
- * @param[in] company
- * The company beneath which the name should be searched
- * This objectid can be empty.
- * @return The object signature of the resolved object
- * @throw toomanyobjects When more then one object was found.
- * @throw objectnotfound When no object was found.
- * @throw runtime_error When an unsupported objectclass was requested.
- */
- virtual objectsignature_t resolveName(objectclass_t objclass, const string &name, const objectid_t &company);
- /**
- * Authenticate user with username and password
- *
- * @param[in] username
- * The username of the user to be authenticated
- * @param[in] password
- * The password of the user to be authenticated
- * @param[in] company
- * The objectid of the company to which the user belongs.
- * This objectid can be empty.
- * @return The objectsignature of the authenticated user
- * @throw objectnotfound When no user with the given name exists.
- * @throw login_error When the wrong password is provied or the user is nonactive.
- */
- virtual objectsignature_t authenticateUser(const string &username, const string &password, const objectid_t &company);
- /**
- * Request a list of objects for a particular company and specified objectclass.
- *
- * @param[in] company
- * The company beneath which the objects should be listed.
- * This objectid can be empty.
- * @param[in] objclass
- * The objectclass of the objects which should be returned.
- * The objectclass can be partially unknown (OBJECTCLASS_UNKNOWN, MAILUSER_UNKNOWN, ...)
- * @return The list of object signatures of all objects which were found
- * @throw std::exception
- */
- virtual std::unique_ptr<signatures_t> getAllObjects(const objectid_t &company, objectclass_t objclass);
- /**
- * Obtain the object details for the given object
- *
- * Besides the information from Unix, the details will also
- * be merged with details from DBPlugin::getObjectDetails()
- *
- * @param[in] objectid
- * The objectid for which is details are requested
- * @return The objectdetails for the given objectid
- * @throw std::exception
- */
- virtual std::unique_ptr<objectdetails_t> getObjectDetails(const objectid_t &objectid);
- /**
- * Obtain the object details for the given objects
- *
- * This will loop through the list of objectids and call
- * UnixUserPlugin::getObjectDetails(const objectid_t &objectid) for each objectid.
- *
- * @param[in] objectids
- * The list of object signatures for which the details are requested
- * @return A map of objectid with the matching objectdetails
- * @throw std::exception
- */
- virtual std::unique_ptr<std::map<objectid_t, objectdetails_t> > getObjectDetails(const std::list<objectid_t> &objectids);
- /**
- * Get all children for a parent for a given relation type.
- * For example all users in a group
- *
- * OBJECTRELATION_GROUP_MEMBER will be queried to Unix directly, for
- * all other relations DBPlugin::getSubObjectsForObject() is called.
- *
- * @param[in] relation
- * The relation type which connects the child and parent object
- * @param[in] parentobject
- * The parent object for which the children are requested
- * @return A list of object signatures of the children of the parent.
- * @throw std::exception
- */
- virtual std::unique_ptr<signatures_t> getSubObjectsForObject(userobject_relation_t relation, const objectid_t &parentobject);
- /**
- * Request all parents for a childobject for a given relation type.
- * For example all groups for a user
- *
- * OBJECTRELATION_GROUP_MEMBER will be queried to Unix directly, for
- * all other relations DBPlugin::getParentObjectsForObject() is called.
- *
- * @param[in] relation
- * The relation type which connects the child and parent object
- * @param[in] childobject
- * The childobject for which the parents are requested
- * @return A list of object signatures of the parents of the child.
- * @throw std::exception
- */
- virtual std::unique_ptr<signatures_t> getParentObjectsForObject(userobject_relation_t relation, const objectid_t &childobject);
- /**
- * Search for all objects which match the given string,
- * the name and email address should be compared for this search.
- *
- * Besides checking Unix information, the email address is also checked by calling
- * DBPlugin::searchObjects().
- *
- * @param[in] match
- * The string which should be found
- * @param[in] ulFlags
- * If EMS_AB_ADDRESS_LOOKUP the string must exactly match the name or email address
- * otherwise a partial match is allowed.
- * @return List of object signatures which match the given string
- * @throw objectnotfound When no object was found
- */
- virtual std::unique_ptr<signatures_t> searchObject(const std::string &match, unsigned int ulFlags);
- /**
- * Obtain details for the public store
- *
- * @note This function has not been implemented and will always throw an exception.
- *
- * @return The public store details
- * @throw notsupported Always when this function is called
- */
- virtual std::unique_ptr<objectdetails_t> getPublicStoreDetails(void);
- /**
- * Obtain the objectdetails for a server
- *
- * @note This function has not been implemented and will always throw an exception.
- *
- * @param[in] server
- * The externid of the server
- * @return The server details
- * @throw notsupported Always when this function is called
- */
- virtual std::unique_ptr<serverdetails_t> getServerDetails(const std::string &server);
-
- /**
- * Obtain server list
- *
- * @return list of servers
- * @throw runtime_error LDAP query failure
- */
- virtual std::unique_ptr<serverlist_t> getServers(void);
- /**
- * Create object in plugin
- *
- * @note This function has not been implemented and will always throw an exception.
- *
- * @param[in] details
- * The object details of the new object.
- * @return The objectsignature of the created object.
- * @throw notimplemented Always when this function is called
- */
- virtual objectsignature_t createObject(const objectdetails_t &details);
- /**
- * Update an object with new details
- *
- * Does not support changing OB_PROP_S_PASSWORD, OB_PROP_S_LOGIN and OB_PROP_S_FULLNAME,
- * all other details are updated by calling DBPlugin::changeObject().
- *
- * @param[in] id
- * The object id of the object which should be updated.
- * @param[in] details
- * The objectdetails which should be written to the object.
- * @param[in] lpRemove
- * List of configuration names which should be removed from the object
- * @throw runtime_error When OB_PROP_S_PASSWORD, OB_PROP_S_LOGIN, OB_PROP_S_FULLNAME or is non-empty.
- */
- virtual void changeObject(const objectid_t &id, const objectdetails_t &details, const std::list<std::string> *lpRemove);
- /**
- * Delete object from plugin
- *
- * @note This function has not been implemented and will always throw an exception.
- *
- * @param[in] id
- * The objectid which should be deleted
- * @throw notimplemented Always when this function is called
- */
- virtual void deleteObject(const objectid_t &id);
- /**
- * Modify id of object in plugin
- *
- * @note This function is not supported by this plugin and will always throw an exception
- *
- * @param[in] oldId
- * The old objectid
- * @param[in] newId
- * The new objectid
- * @throw notsupported Always when this function is called
- */
- virtual void modifyObjectId(const objectid_t &oldId, const objectid_t &newId);
- /**
- * Add relation between child and parent. This can be used
- * for example to add a user to a group or add
- * permission relations on companies.
- *
- * Only OBJECTRELATION_QUOTA_USERRECIPIENT and OBJECTRELATION_USER_SENDAS
- * are supported. All other relation types are forwarded to
- * DBPlugin::addSubObjectRelation()
- *
- * @param[in] relation
- * The relation type which should connect the child and parent.
- * @param[in] parentobject
- * The parent object.
- * @param[in] childobject
- * The child object.
- * @throw notimplemented when an unsupported relation is requested
- */
- virtual void addSubObjectRelation(userobject_relation_t relation,
- const objectid_t &parentobject, const objectid_t &childobject);
- /**
- * Delete relation between child and parent, this can be used
- * for example to delete a user from a group or delete
- * permission relations on companies.
- *
- * Only OBJECTRELATION_QUOTA_USERRECIPIENT and OBJECTRELATION_USER_SENDAS
- * are supported. All other relation types are forwarded to
- * DBPlugin::deleteSubObjectRelation().
- *
- * @param[in] relation
- * The relation type which connected the child and parent.
- * @param[in] parentobject
- * The parent object.
- * @param[in] childobject
- * The child object.
- * @throw notimplemented when an unsupported relation is requested
- */
- virtual void deleteSubObjectRelation(userobject_relation_t relation,
- const objectid_t &parentobject, const objectid_t &childobject);
- private:
- ECIConv *m_iconv = nullptr;
- /**
- * Find a user with specific name
- *
- * @param[in] id
- * The id of the user which must be found
- * @param[out] pwd
- * The found passwd structure
- * @param[out] buffer
- * A buffer which will contain the strings for pwd
- * @throw objectnotfound If no user was found.
- */
- void findUserID(const string &id, struct passwd *pwd, char *buffer);
- /**
- * Find a user with specific name
- *
- * @param[in] name
- * The name of the user which must be found
- * @param[out] pwd
- * The found passwd structure
- * @param[out] buffer
- * A buffer which will contain the strings for pwd
- * @throw objectnotfound If no user was found.
- */
- void findUser(const string &name, struct passwd *pwd, char *buffer);
- /**
- * Find a group with specific ID
- *
- * @param[in] id
- * The id of the group which must be found
- * @param[out] grp
- * The found group structure
- * @param[out] buffer
- * A buffer which will contain the strings for grp
- * @throw objectnotfound If no group was found.
- */
- void findGroupID(const string &id, struct group *grp, char *buffer);
- /**
- * Find a group with specific name
- *
- * @param[in] name
- * The name of the group which must be found
- * @param[out] grp
- * The found group structure
- * @param[out] buffer
- * A buffer which will contain the strings for grp
- * @throw objectnotfound If no group was found.
- */
- void findGroup(const string &name, struct group *grp, char *buffer);
- /**
- * Resolve user name to objectsignature
- *
- * This will call UnixUserPlugin::findUser()
- *
- * @param[in] name
- * Name of the user which must be found
- * @return The objectsignature of the resolved object
- * @throw std::exception
- */
- objectsignature_t resolveUserName(const string &name);
- /**
- * Resolve group name to objectsignature
- *
- * This will call UnixUserPlugin::findGroup()
- *
- * @param[in] name
- * Name of the group which must be found
- * @return The objectsignature of the resolved object
- * @throw std::exception
- */
- objectsignature_t resolveGroupName(const string &name);
- /**
- * Match a user with given search query
- *
- * @param[in] pw
- * The user which should be checked
- * @param[in] match
- * Check if the term matches the user pw
- * @param[in] ulFlags
- * If EMS_AB_ADDRESS_LOOKUP the string must exactlymatch the name or
- * email address otherwise a partial match is allowed.
- * @return True if the user matches the query
- */
- bool matchUserObject(struct passwd *pw, const string &match, unsigned int ulFlags);
- /**
- * Match a group with given search query
- *
- * @param[in] gr
- * The group which should be checked
- * @param[in] match
- * Check if the term matches the group gr
- * @param[in] ulFlags
- * If EMS_AB_ADDRESS_LOOKUP the string must exactlymatch the name or
- * email address otherwise a partial match is allowed.
- * @return True if the group matches the query
- */
- bool matchGroupObject(struct group *gr, const string &match, unsigned int ulFlags);
- /**
- * Create a list containing all users which optionally match the search term.
- *
- * @param[in] match
- * Optional parameter. Search for all users which match the term
- * @param[in] ulFlags
- * Optional parameter. If EMS_AB_ADDRESS_LOOKUP the string must exactly
- * match the name or email address otherwise a partial match is allowed.
- * @return List of objectsignatures
- */
- std::unique_ptr<signatures_t> getAllUserObjects(const std::string &match = std::string(), unsigned int ulFlags = 0);
- /**
- * Create a list containing all groups which optionally match the search term.
- *
- * @param[in] match
- * Optional parameter. Search for all groups which match the term
- * @param[in] ulFlags
- * Optional parameter. If EMS_AB_ADDRESS_LOOKUP the string must exactly
- * match the name or email address otherwise a partial match is allowed.
- * @return List of objectsignatures
- */
- std::unique_ptr<signatures_t> getAllGroupObjects(const std::string &match = std::string(), unsigned int ulFlags = 0);
- /**
- * Copy object details from struct passwd to objectdetails
- *
- * @param[in] pw
- * Pointer to struct pw from which the details must be collected
- * @return The objectdetails which were collected from pw
- */
- std::unique_ptr<objectdetails_t> objectdetailsFromPwent(struct passwd *pw); // PAM part
- /**
- * Copy object details from struct group to objectdetails
- *
- * @param[in] gr
- * Pointer to struct group from which the details must be collected
- * @return The objectdetails which were collected from gr
- */
- std::unique_ptr<objectdetails_t> objectdetailsFromGrent(struct group *gr);
- /**
- * Query the Database to obtain the signature for the objectid.
- *
- * @param[in] id
- * The object for which the signature is requested
- * @return the object signature
- */
- std::string getDBSignature(const objectid_t &id);
- /**
- * Check errno for errors which should trigger an exception
- *
- * @param[in] user
- * The username for which the exception will be thrown.
- * @throw runtime_error Thrown when errno was set.
- */
- void errnoCheck(const std::string &, int) const;
- };
- } /* namespace */
- extern "C" {
- extern _kc_export UserPlugin *getUserPluginInstance(std::mutex &, ECPluginSharedData *);
- extern _kc_export void deleteUserPluginInstance(UserPlugin *);
- extern _kc_export int getUserPluginVersion(void);
- }
- /** @} */
- #endif
|