From 2e5f0ffef4108cf4aca0adfb554e207c3132101c Mon Sep 17 00:00:00 2001 From: William Brown Date: May 26 2016 23:15:58 +0000 Subject: Ticket 48850 - Correct memory leaks in pwdhash-bin and ns-slapd Bug Description: pwdhash-bin had two memory leaks in the handling of strings and password types. We also leaked plugin component id's and the name of password plugin types. Fix Description: Free the data correctly. https://fedorahosted.org/389/ticket/48850 Author: wibrown Review by: nhosoi (Thanks!) --- diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c index 5d63baa..39bfcef 100644 --- a/ldap/servers/slapd/plugin.c +++ b/ldap/servers/slapd/plugin.c @@ -52,6 +52,7 @@ static PRBool plugin_matches_operation (Slapi_DN *target_spec, PluginTargetData static void plugin_config_init (struct pluginconfig *config); static void plugin_config_cleanup (struct pluginconfig *config); +static void plugin_free(struct slapdplugin *plugin); static int plugin_config_set_action (int *action, char *value); static struct pluginconfig* plugin_get_config (struct slapdplugin *plugin); static void default_plugin_init(); @@ -1951,6 +1952,7 @@ plugin_closeall(int close_backends, int close_globals) while (iterp) { nextp = iterp->next; slapi_entry_free(iterp->e); + plugin_free(iterp->plugin); slapi_ch_free((void **)&iterp); iterp = nextp; } @@ -2709,6 +2711,8 @@ plugin_free(struct slapdplugin *plugin) slapi_ch_free_string(&plugin->plg_initfunc); slapi_ch_free_string(&plugin->plg_name); slapi_ch_free_string(&plugin->plg_dn); + slapi_ch_free_string(&plugin->plg_pwdstorageschemename); + release_componentid(plugin->plg_identity); slapi_counter_destroy(&plugin->plg_op_counter); if (!plugin->plg_group) plugin_config_cleanup(&plugin->plg_conf); @@ -3005,8 +3009,10 @@ plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid *group, slapi_pblock_set(&pb, SLAPI_PLUGIN, plugin); slapi_pblock_set(&pb, SLAPI_PLUGIN_VERSION, (void *)SLAPI_PLUGIN_CURRENT_VERSION); - cid = generate_componentid (plugin,NULL); - slapi_pblock_set(&pb, SLAPI_PLUGIN_IDENTITY, (void*)cid); + cid = generate_componentid (plugin,NULL); + /* We take a copy of the pointer to this so we can free it correctly. */ + plugin->plg_identity = cid; + slapi_pblock_set(&pb, SLAPI_PLUGIN_IDENTITY, (void*)cid); configdir = config_get_configdir(); slapi_pblock_set(&pb, SLAPI_CONFIG_DIRECTORY, configdir); diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h index c6763e4..20a2a3a 100644 --- a/ldap/servers/slapd/slap.h +++ b/ldap/servers/slapd/slap.h @@ -792,6 +792,7 @@ struct slapdplugin { int plg_type; /* discriminates union */ char *plg_dn; /* config dn for this plugin */ char *plg_id; /* plugin id, used when adding/removing plugins */ + struct slapi_componentid *plg_identity; /* Slapi component id */ int plg_precedence; /* for plugin execution ordering */ struct slapdplugin *plg_group; /* pointer to the group to which this plugin belongs */ struct pluginconfig plg_conf; /* plugin configuration parameters */ diff --git a/ldap/servers/slapd/tools/pwenc.c b/ldap/servers/slapd/tools/pwenc.c index c5ed37c..525cd15 100644 --- a/ldap/servers/slapd/tools/pwenc.c +++ b/ldap/servers/slapd/tools/pwenc.c @@ -129,6 +129,7 @@ main( argc, argv ) { int i, rc; char *enc, *cmp, *name; + char *decoded = NULL; struct pw_scheme *pwsp, *cmppwsp; extern int optind; char *cpwd = NULL; /* candidate password for comparison */ @@ -206,51 +207,63 @@ main( argc, argv ) } } - if ( cpwd != NULL ) { - cmppwsp = pw_val2scheme( decode( cpwd ), &cmp, 1 ); - } - - if ( cmppwsp != NULL && pwsp != NULL ) { - fprintf( stderr, "%s: do not use -s with -c\n", name ); - usage( name ); - } + if ( cpwd != NULL ) { + decoded = decode( cpwd ); + cmppwsp = pw_val2scheme(decoded, &cmp, 1 ); + } + + if ( cmppwsp != NULL && pwsp != NULL ) { + fprintf( stderr, "%s: do not use -s with -c\n", name ); + usage( name ); + } - if ( cmppwsp == NULL && pwsp == NULL ) { - pwsp = pw_name2scheme( SALTED_SHA1_SCHEME_NAME ); - } + if ( cmppwsp == NULL && pwsp == NULL ) { + pwsp = pw_name2scheme( SALTED_SHA1_SCHEME_NAME ); + } - if ( argc <= optind ) { - usage( name ); - } + if ( argc <= optind ) { + usage( name ); + } - if ( cmppwsp == NULL && pwsp->pws_enc == NULL ) { + if ( cmppwsp == NULL && pwsp->pws_enc == NULL ) { fprintf( stderr, "The scheme \"%s\" does not support password encoding.\n", pwsp->pws_name ); - return( 1 ); - } + rc = 1; + goto out; + } - srand((int)time(NULL)); /* schemes such as crypt use random salt */ + srand((int)time(NULL)); /* schemes such as crypt use random salt */ - for ( rc = 0; optind < argc && rc == 0; ++optind ) { + for ( rc = 0; optind < argc && rc == 0; ++optind ) { if ( cmppwsp == NULL ) { /* encode passwords */ - if (( enc = (*pwsp->pws_enc)( decode( argv[ optind ] ))) == NULL ) { - perror( name ); - return( 1 ); + decoded = decode( argv[ optind ] ); + if (( enc = (*pwsp->pws_enc)( decoded )) == NULL ) { + perror( name ); + rc = 1; + goto out; } puts( enc ); slapi_ch_free_string( &enc ); - } else { /* compare passwords */ - if (( rc = (*(cmppwsp->pws_cmp))( decode( argv[ optind ]), cmp )) == 0 ) { - printf( "%s: password ok.\n", name ); + } else { /* compare passwords */ + decoded = decode( argv[ optind ] ); + if (( rc = (*(cmppwsp->pws_cmp))( decoded, cmp )) == 0 ) { + printf( "%s: password ok.\n", name ); } else { - printf( "%s: password does not match.\n", name ); + printf( "%s: password does not match.\n", name ); } } - } + } + +out: - return( rc == 0 ? 0 : 1 ); + free_pw_scheme(pwsp); + slapi_ch_free_string(&decoded); + + plugin_closeall( 1 /* Close Backends */, 1 /* Close Globals */); + + return( rc == 0 ? 0 : 1 ); } /* -------------------------------------------------------------- */ @@ -322,7 +335,7 @@ slapd_config(const char *configdir, const char *givenconfigfile) * and schema subsystems be initialized... and they * are not yet. */ - Slapi_Entry *e = slapi_str2entry(entrystr, + Slapi_Entry *e = slapi_str2entry(entrystr, // this one SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF); if (e == NULL) { @@ -339,22 +352,18 @@ slapd_config(const char *configdir, const char *givenconfigfile) if ( entry_has_attr_and_value(e, ATTR_PLUGIN_TYPE, "pwdstoragescheme")) { /* add the syntax/matching/pwd storage scheme rule plugin */ - if (plugin_setup(e, 0, 0, 1, returntext)) + /* Because add_entry is 1, plugin_entry is duplicated */ + if (plugin_setup(e, 0, 0, 1, returntext)) // This one { fprintf(stderr, "The plugin entry [%s] in the configfile %s was invalid. %s\n", slapi_entry_get_dn(e), configfile, returntext); exit(1); /* yes this sucks, but who knows what else would go on if I did the right thing */ } - else - { - e = 0; /* successful plugin_setup consumes entry */ - } } } - if (e) - slapi_entry_free(e); + slapi_entry_free(e); } /* kexcoff: initialize rootpwstoragescheme and pw_storagescheme