.BI \-c \ salt-format\fR]
[\c
.BR \-n ]
-.B
+[\c
+.BI \-o \ option\fR[ = value\fR]]
.LP
.SH DESCRIPTION
.LP
.BI \-n
Omit the trailing newline; useful to pipe the credentials
into a command.
+.TP
+.BI \-o \ option\fR[ = value\fR]
+Specify an
+.I option
+with a(n optional)
+.IR value .
+Possible generic options/values are:
+.LP
+.nf
+ module\-path=<pathspec> (see `\fBmodulepath\fP' in slapd.conf(5))
+ module\-load=<filename> (see `\fBmoduleload\fP' in slapd.conf(5))
+
+.in
+You can load a dynamically loadable password hash module by
+using this option.
.SH LIMITATIONS
The practice of storing hashed passwords in userPassword violates
Standard Track (RFC 4519) schema specifications and may hinder
#include "slap.h"
static int verbose = 0;
+static char *modulepath = NULL;
+static char *moduleload = NULL;
static void
usage(const char *s)
" -g\t\tgenerate random password\n"
" -h hash\tpassword scheme\n"
" -n\t\tomit trailing newline\n"
+ " -o <opt>[=val] specify an option with a(n optional) value\n"
+ " \tmodule-path=<pathspec>\n"
+ " \tmodule-load=<filename>\n"
" -s secret\tnew password\n"
" -u\t\tgenerate RFC2307 values (default)\n"
" -v\t\tincrease verbosity\n"
exit( EXIT_FAILURE );
}
+static int
+parse_slappasswdopt( void )
+{
+ size_t len = 0;
+ char *p;
+
+ p = strchr( optarg, '=' );
+ if ( p != NULL ) {
+ len = p - optarg;
+ p++;
+ }
+
+ if ( strncasecmp( optarg, "module-path", len ) == 0 ) {
+ if ( modulepath )
+ ch_free( modulepath );
+ modulepath = ch_strdup( p );
+
+ } else if ( strncasecmp( optarg, "module-load", len ) == 0 ) {
+ if ( moduleload )
+ ch_free( moduleload );
+ moduleload = ch_strdup( p );
+
+ } else {
+ return -1;
+ }
+
+ return 0;
+}
+
int
slappasswd( int argc, char *argv[] )
{
+ int rc = EXIT_SUCCESS;
#ifdef LUTIL_SHA1_BYTES
char *default_scheme = "{SSHA}";
#else
struct berval passwd = BER_BVNULL;
struct berval hash;
+#ifdef LDAP_DEBUG
+ /* tools default to "none", so that at least LDAP_DEBUG_ANY
+ * messages show up; use -d 0 to reset */
+ slap_debug = LDAP_DEBUG_NONE;
+#endif
+ ldap_syslog = 0;
+
while( (i = getopt( argc, argv,
- "c:d:gh:ns:T:vu" )) != EOF )
+ "c:d:gh:no:s:T:vu" )) != EOF )
{
switch (i) {
case 'c': /* crypt salt format */
newline = "";
break;
+ case 'o':
+ if ( parse_slappasswdopt() ) {
+ usage ( progname );
+ }
+ break;
+
case 's': /* new password (secret) */
if ( pwfile != NULL ) {
fprintf( stderr, "Option -s incompatible with -T\n" );
if( argc - optind != 0 ) {
usage( progname );
- }
+ }
+
+#ifdef SLAPD_MODULES
+ if ( module_init() != 0 ) {
+ fprintf( stderr, "%s: module_init failed\n", progname );
+ return EXIT_FAILURE;
+ }
+
+ if ( modulepath && module_path(modulepath) ) {
+ rc = EXIT_FAILURE;
+ goto destroy;
+ }
+
+ if ( moduleload && module_load(moduleload, 0, NULL) ) {
+ rc = EXIT_FAILURE;
+ goto destroy;
+ }
+#endif
if( pwfile != NULL ) {
if( lutil_get_filed_password( pwfile, &passwd )) {
- return EXIT_FAILURE;
+ rc = EXIT_FAILURE;
+ goto destroy;
}
} else if ( BER_BVISEMPTY( &passwd )) {
if( newpw == NULL ) {
if( strcmp( newpw, cknewpw )) {
fprintf( stderr, "Password values do not match\n" );
- return EXIT_FAILURE;
+ rc = EXIT_FAILURE;
+ goto destroy;
}
}
fprintf( stderr,
"Password generation failed for scheme %s: %s\n",
scheme, text ? text : "" );
- return EXIT_FAILURE;
+ rc = EXIT_FAILURE;
+ goto destroy;
}
if( lutil_passwd( &hash, &passwd, NULL, &text ) ) {
fprintf( stderr, "Password verification failed. %s\n",
text ? text : "" );
- return EXIT_FAILURE;
+ rc = EXIT_FAILURE;
+ goto destroy;
}
print_pw:;
printf( "%s%s" , hash.bv_val, newline );
- return EXIT_SUCCESS;
+
+destroy:;
+#ifdef SLAPD_MODULES
+ module_kill();
+#endif
+
+ return rc;
}