From db6a42a3ea5f6773e0e4e350211f7fc5b2b342d2 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Tue, 27 Nov 2012 10:24:02 -0500 Subject: [PATCH 19/22] Ticket 20 - Allow automember to work on entries that have already been added Bug Description: If the server can not open a ldif for reading(mapping task), an incorrect error and file name is returned. Fix Description: Report the correct file name, and correctly grab the OS error/string. Also made slapd_pr_strerr() and slapd_system_strerr() public, so I refactored the function names to be "slapi_" - so a lot of files are touched but the main change for this ticket is still in automember.c https://fedorahosted.org/389/ticket/20 Reviewed by: richm(Thanks) (cherry picked from commit bf2bfaab8e61f335442e4341ff33521a822bd830) --- ldap/servers/plugins/automember/automember.c | 44 +++++++++------- ldap/servers/slapd/errormap.c | 10 ++++ ldap/servers/slapd/slapi-plugin.h | 75 ++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 18 deletions(-) diff --git a/ldap/servers/plugins/automember/automember.c b/ldap/servers/plugins/automember/automember.c index a11909f..424b507 100644 --- a/ldap/servers/plugins/automember/automember.c +++ b/ldap/servers/plugins/automember/automember.c @@ -2333,6 +2333,7 @@ void automember_export_task_thread(void *arg){ task_data *td = NULL; PRFileDesc *ldif_fd; int i = 0; + int rc = 0; td = (task_data *)slapi_task_get_data(task); slapi_task_begin(task, 1); @@ -2341,13 +2342,14 @@ void automember_export_task_thread(void *arg){ /* make sure we can open the ldif file */ if (( ldif_fd = PR_Open( td->ldif_out, PR_CREATE_FILE | PR_WRONLY, DEFAULT_FILE_MODE )) == NULL ){ - slapi_task_log_notice(task, "Automember export task could not open ldif file \"%s\" for writing %d\n", - td->ldif_out, PR_GetError() ); - slapi_task_log_status(task, "Automember export task could not open ldif file \"%s\" for writing %d\n", - td->ldif_out, PR_GetError() ); + rc = PR_GetOSError(); + slapi_task_log_notice(task, "Automember export task could not open ldif file \"%s\" for writing, error %d (%s)\n", + td->ldif_out, rc, slapi_system_strerror(rc)); + slapi_task_log_status(task, "Automember export task could not open ldif file \"%s\" for writing, error %d (%s)\n", + td->ldif_out, rc, slapi_system_strerror(rc) ); slapi_log_error( SLAPI_LOG_FATAL, AUTOMEMBER_PLUGIN_SUBSYSTEM, - "Could not open ldif file \"%s\" for writing %d\n", - td->ldif_out, PR_GetError() ); + "Could not open ldif file \"%s\" for writing, error %d (%s)\n", + td->ldif_out, rc, slapi_system_strerror(rc) ); result = SLAPI_DSE_CALLBACK_ERROR; goto out; } @@ -2516,6 +2518,7 @@ void automember_map_task_thread(void *arg){ task_data *td = NULL; PRFileDesc *ldif_fd_out = NULL; char *entrystr = NULL; + char *errstr = NULL; #if defined(USE_OPENLDAP) int buflen = 0; LDIFFP *ldif_fd_in = NULL; @@ -2534,29 +2537,34 @@ void automember_map_task_thread(void *arg){ /* make sure we can open the ldif files */ if(( ldif_fd_out = PR_Open( td->ldif_out, PR_CREATE_FILE | PR_WRONLY, DEFAULT_FILE_MODE )) == NULL ){ - slapi_task_log_notice(task, "The ldif file %s could not be accessed, error %d. Aborting task.\n", - td->ldif_out, rc); - slapi_task_log_status(task, "The ldif file %s could not be accessed, error %d. Aborting task.\n", - td->ldif_out, rc); + rc = PR_GetOSError(); + slapi_task_log_notice(task, "The ldif file %s could not be accessed, error %d (%s). Aborting task.\n", + td->ldif_out, rc, slapi_system_strerror(rc)); + slapi_task_log_status(task, "The ldif file %s could not be accessed, error %d (%s). Aborting task.\n", + td->ldif_out, rc, slapi_system_strerror(rc)); slapi_log_error( SLAPI_LOG_FATAL, AUTOMEMBER_PLUGIN_SUBSYSTEM, - "Could not open ldif file \"%s\" for writing %d\n", - td->ldif_out, PR_GetError() ); + "Could not open ldif file \"%s\" for writing, error %d (%s)\n", + td->ldif_out, rc, slapi_system_strerror(rc) ); result = SLAPI_DSE_CALLBACK_ERROR; goto out; } #if defined(USE_OPENLDAP) if(( ldif_fd_in = ldif_open(td->ldif_in, "r")) == NULL ){ + rc = errno; + errstr = strerror(rc); #else if(( ldif_fd_in = PR_Open( td->ldif_in, PR_RDONLY, DEFAULT_FILE_MODE )) == NULL ){ + rc = PR_GetOSError(); + errstr = slapi_system_strerror(rc); #endif - slapi_task_log_notice(task, "The ldif file %s could not be accessed, error %d. Aborting task.\n", - td->ldif_in, rc); - slapi_task_log_status(task, "The ldif file %s could not be accessed, error %d. Aborting task.\n", - td->ldif_in, rc); + slapi_task_log_notice(task, "The ldif file %s could not be accessed, error %d (%s). Aborting task.\n", + td->ldif_in, rc, errstr); + slapi_task_log_status(task, "The ldif file %s could not be accessed, error %d (%s). Aborting task.\n", + td->ldif_in, rc, errstr); slapi_log_error( SLAPI_LOG_FATAL, AUTOMEMBER_PLUGIN_SUBSYSTEM, - "Could not open ldif file \"%s\" for reading %d\n", - td->ldif_out, PR_GetError() ); + "Could not open ldif file \"%s\" for reading, error %d (%s)\n", + td->ldif_in, rc, errstr ); result = SLAPI_DSE_CALLBACK_ERROR; goto out; } diff --git a/ldap/servers/slapd/errormap.c b/ldap/servers/slapd/errormap.c index d05e495..c585d25 100644 --- a/ldap/servers/slapd/errormap.c +++ b/ldap/servers/slapd/errormap.c @@ -73,6 +73,11 @@ slapd_pr_strerror( const int prerrno ) return( s ); } +char * +slapi_pr_strerror( const int prerrno ) +{ + return slapd_pr_strerror(prerrno); +} /* * return the string equivalent of a system error @@ -92,6 +97,11 @@ slapd_system_strerror( const int syserrno ) return( s ); } +const char * +slapi_system_strerror( const int syserrno ) +{ + return slapd_system_strerror(syserrno); +} /* * return the string equivalent of an NSPR error. If "prerrno" is not diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h index 4316833..4962b2a 100644 --- a/ldap/servers/slapd/slapi-plugin.h +++ b/ldap/servers/slapd/slapi-plugin.h @@ -65,6 +65,7 @@ extern "C" { #include "prtypes.h" #include "ldap.h" #include "prprf.h" +#include "nspr.h" NSPR_API(PRUint32) PR_snprintf(char *out, PRUint32 outlen, const char *fmt, ...) #ifdef __GNUC__ __attribute__ ((format (printf, 3, 4))); @@ -7156,6 +7157,80 @@ uint64_t slapi_str_to_u64(const char *s); void slapi_set_plugin_open_rootdn_bind(Slapi_PBlock *pb); +/* + * Public entry extension getter/setter functions + * + * Currently, only slapi_pw_get/set_entry_ext is implemented. + * The functions are in pw.c. Detailed usage of the factory + * is found in the comments at the top of factory.c. + * + * When you plan to add other entry extension code AND + * the type-value pair is managed via ordinary mod, + * setter, getter and copy function having the same API + * are supposed to be implemented, then add the set to + * attrs_in_extension list in entry.c. The set is called + * in slapi_entry_apply_mod_extension. + * + * Note: setter and getter are public, but copy function + * is not. (for the copy function, see pw_copy_entry_ext in pw.c) + */ +/* operation used in the entry extension setter */ +#define SLAPI_EXT_SET_ADD 0 +#define SLAPI_EXT_SET_REPLACE 1 + +/** + * Get entry extension + * + * \param entry is the entry to retrieve the extension from + * \param vals is the array of (Slapi_Value *), which directly refers the extension. Caller must duplicate it to use it for other than referring. + * + * \return LDAP_SUCCESS if successful. + * \return non-zero otherwise. + */ +int slapi_pw_get_entry_ext(Slapi_Entry *entry, Slapi_Value ***vals); + +/** + * Set entry extension + * + * \param entry is the entry to set the extension to + * \param vals is the array of (Slapi_Value *), which is consumed in slapi_pw_set_ext if the call is successful. + * \param flags: SLAPI_EXT_SET_ADD -- add vals to the existing extension if any. + * SLAPI_EXT_SET_REPLACE -- replace vals with the existing extension if any. + * No difference if there is no extension in the entry. + * + * \return LDAP_SUCCESS if successful. + * \return non-zero otherwise. + */ +int slapi_pw_set_entry_ext(Slapi_Entry *entry, Slapi_Value **vals, int flags); + +/** + * Get stashed clear password. + * If multiple of them are in the extension, the first one is returned. + * + * \param entry is the entry to retrieve the extension from + * + * \return a pointer to the clear password string. Caller is responsible to free the string. + */ +char *slapi_get_first_clear_text_pw(Slapi_Entry *entry); + +/** + * Return the string equivalent of an NSPR error + * * + * \param a NSPR error code + * + * \return a pointer to the error code string. + */ +char *slapi_pr_strerror( const PRErrorCode prerrno ); + +/** + * Return the string equivalent of an OS error + * + * \param a OS error code + * + * \return a pointer to the system error code string. + */ +const char *slapi_system_strerror( const int syserrno ); + #ifdef __cplusplus } #endif -- 1.7.11.7