summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Sulfrian <alex@spline.inf.fu-berlin.de>2016-01-14 04:48:06 +0100
committerAlexander Sulfrian <alex@spline.inf.fu-berlin.de>2016-01-14 04:48:06 +0100
commiteadecd41caf9a15b973f704ad77801507d68f961 (patch)
tree08fef450086e8fd96f85654b47503a8447a45c9f
parent864d0352619afa1887db553c2e61df61ddb121ee (diff)
downloadldap-plugin-eadecd41caf9a15b973f704ad77801507d68f961.tar.gz
ldap-plugin-eadecd41caf9a15b973f704ad77801507d68f961.tar.bz2
ldap-plugin-eadecd41caf9a15b973f704ad77801507d68f961.zip
Add more documentation
Add doxygen compatible comments to most functions.
-rw-r--r--service_passwords.c124
1 files changed, 114 insertions, 10 deletions
diff --git a/service_passwords.c b/service_passwords.c
index fdd4bbd..bf70770 100644
--- a/service_passwords.c
+++ b/service_passwords.c
@@ -9,7 +9,21 @@ extern int slapi_pw_find(struct berval **vals, struct berval *v);
static Slapi_ComponentId *plugin_id = NULL;
-/* Get an entry specified by a DN and with the specified attributes. */
+/** Get an entry specified by a DN and with the specified attributes.
+ *
+ * This functions get a entry specified by a \c DN. It's doing this with an
+ * internal search and limit the requested attributes to the requested
+ * values. The entry is written to an \c Slapi_Entry pointer.
+ *
+ * @param[in] dn \c DN of the requested entry.
+ * @param[in] attrs \c NULL terminated list of requested attributes.
+ * @param[out] entry Pointer to a pointer to \c Slapi_Entry to be filled with
+ * the entry. The caller is responsible to free the filled
+ * pointer with \c slapi_entry_free.
+ * @return
+ * * 0 on success
+ * * not 0 on error (maybe an ldap errno like \c LDAP_NO_SUCH_OBJECT)
+ */
static int get_entry(const char *dn, char **attrs, Slapi_Entry **entry)
{
Slapi_Entry **entries = NULL;
@@ -59,7 +73,14 @@ static int get_entry(const char *dn, char **attrs, Slapi_Entry **entry)
return rc;
}
-/* Check if the parent entry contains a uid attribute. */
+/** Check if the given DN contains a \c uid attribute.
+ *
+ * This function checks, if the entry specified by the DN contains a \c uid
+ * attribute and that this attribute is not empty.
+ *
+ * @param[in] dn DN of the entry.
+ * @return 0 if the \c uid attribute was found, 1 otherwise
+ */
static int dn_contains_uid(const char *dn)
{
char *attrs[] = { "uid", NULL };
@@ -96,7 +117,21 @@ fail1:
return rc;
}
-static char* is_service_dn(const char *dn)
+/** Check if the given DN is a service account.
+ *
+ * This function checks, if the given DN is a DN of a service account. All
+ * services have to do a bind on such a DN before a search so that this plugin
+ * can identify the service and rewrite the search results to the service
+ * specific password entries.
+ *
+ * @param[in] dn The DN to check (most times this should be the bound DN of the
+ * connection).
+ * @return If the DN is a service account, this function returns a zero
+ * terminated string with the name of the service, otherwise it simply
+ * returns a \c NULL pointer. The caller is responsible to free the
+ * returned string with \c slapi_ch_free_string.
+ */
+static char* is_service(const char *dn)
{
char *service = NULL;
@@ -143,6 +178,22 @@ fail1:
return service;
}
+/** Try to authenticate agains a specific DN with given credentials.
+ *
+ * This functions simply checks if the given credentials match the saved
+ * password in the \c userPassword attribute of the entry specified by the
+ * given DN. This function does nothing magic and use a slapi method to
+ * check the password and should support therefore all the password hashing
+ * schemes supported by the slapd.
+ *
+ * @param[in] dn The DN of the entry.
+ * @param[in] credentials A \c berval with the supplied password.
+ *
+ * @return
+ * * 0 is auth was successfull
+ * * -1 if the specified DN was not found
+ * * 1 in all other cases
+ */
static int auth(char *dn, struct berval *credentials)
{
char *attrs[] = { "userPassword", NULL };
@@ -181,6 +232,23 @@ fail1:
return rc;
}
+/** Check if the supplied credentials match the stored password of a given entry
+ * or the parent entry (if the given entry does not exists).
+ *
+ * This function tries to check the supplied credentials against the
+ * \c userPassword attribute of the entry specified by the supplied DN.
+ * If the supplied DN does not exists, it will try to authenticate agains
+ * the direct parent of the specified DN. If the entry exists, but does not
+ * have a \c userPassword attribute or the attribute is empty, the
+ * authentication will fail.
+ *
+ * @param[in] dn The DN of the entry.
+ * @param[in] credentials A \c berval with the supplied password.
+ *
+ * @return
+ * * 0 if the authentication was successfull
+ * * 1 otherwise
+ */
static int auth_with_password_fallback(char *dn, struct berval *credentials)
{
char *parent_dn;
@@ -215,6 +283,25 @@ static int auth_with_password_fallback(char *dn, struct berval *credentials)
return 1;
}
+/** \c PRE_BIND plugin to allow password fallback.
+ *
+ * This function is called before a bind operation. If the BIND_DN is a user
+ * entry with a \c cn=<service> prefix we try to authenticate against the
+ * service password entry or fallback to the user entry if the serice password
+ * does not exist.
+ *
+ * @param[in,out] pb Parameter block of the operation.
+ * @return
+ * * SLAPI_BIND_SUCCESS: \b CONFUSING! This does not force the bind to
+ * succeed. This simply means to continue the processing and handle the bind
+ * in the backend.
+ * * SLAPI_BIND_FAIL: This force the bind to fail and send
+ * LDAP_INVALID_CREDENTIALS back to the client.
+ * * All other values causes special handling. If no error is set and
+ * LDAP_CONN_DN in the pb is set to a value the bind succeed. Otherwise the
+ * bind will fail. But in both cases this method is responsible for sending
+ * the response to the client.
+ */
static int pre_bind(Slapi_PBlock *pb)
{
char *dn;
@@ -248,7 +335,7 @@ static int pre_bind(Slapi_PBlock *pb)
}
if (is_replication || is_internal) {
- return 0;
+ return SLAPI_BIND_SUCCESS;
}
if (method != LDAP_AUTH_SIMPLE) {
@@ -258,7 +345,7 @@ static int pre_bind(Slapi_PBlock *pb)
"(method %d).\n",
method);
- return 0;
+ return SLAPI_BIND_SUCCESS;
}
parent_dn = slapi_dn_parent(dn);
@@ -267,7 +354,7 @@ static int pre_bind(Slapi_PBlock *pb)
if (rc != 0) {
/* parent_dn is not an user, so we ignore this bind request. */
- return 0;
+ return SLAPI_BIND_SUCCESS;
}
if (auth_with_password_fallback(dn, credentials) == 0) {
@@ -290,11 +377,28 @@ static int pre_bind(Slapi_PBlock *pb)
}
/* auth fail */
- rc = LDAP_INVALID_CREDENTIALS;
- slapi_send_ldap_result(pb, rc, NULL, NULL, 0, NULL);
- return rc;
+ return SLAPI_BIND_FAIL;
}
+/** \c PRE_ENTRY plugin to rewrite returned search results to keep the service
+ * name until bind.
+ *
+ * We want to have optional service specific password. Therefore we need to know
+ * the service during bind of the user. To keep this information, we add a
+ * simple (virtual) service prefix to the user DN. If a service search for
+ * users, it has to do a bind with a service account before. The service name is
+ * extracted from this bind and the dn of the found entries is extended to
+ * \c cn=<service>,<user_dn>. During a bind the plugin can extract the service
+ * name and do magic stuff.
+ *
+ * This function is called for each search result entry before sending it back
+ * to the client and the result can be change by updating the parameter block.
+ *
+ * @param[in,out] pb Parameter block of the operation.
+ * @return
+ * * <tt>>= 0</tt> send the result to the client and continue
+ * * <tt>< 0</tt> do not send this result, but continue with the other results
+ */
static int pre_entry(Slapi_PBlock *pb)
{
char *bind_dn;
@@ -345,7 +449,7 @@ static int pre_entry(Slapi_PBlock *pb)
return 0;
}
- service = is_service_dn(bind_dn);
+ service = is_service(bind_dn);
if (service == NULL) {
goto fail1;
}