diff options
author | cvsadm <cvsadm> | 2005-01-21 00:44:34 +0000 |
---|---|---|
committer | cvsadm <cvsadm> | 2005-01-21 00:44:34 +0000 |
commit | b2093e3016027d6b5cf06b3f91f30769bfc099e2 (patch) | |
tree | cf58939393a9032182c4fbc4441164a9456e82f8 /ldap/servers/slapd/tools/pwenc.c | |
download | ds-b2093e3016027d6b5cf06b3f91f30769bfc099e2.tar.gz ds-b2093e3016027d6b5cf06b3f91f30769bfc099e2.tar.xz ds-b2093e3016027d6b5cf06b3f91f30769bfc099e2.zip |
Moving NSCP Directory Server from DirectoryBranch to TRUNK, initial drop. (foxworth)ldapserver7x
Diffstat (limited to 'ldap/servers/slapd/tools/pwenc.c')
-rw-r--r-- | ldap/servers/slapd/tools/pwenc.c | 400 |
1 files changed, 400 insertions, 0 deletions
diff --git a/ldap/servers/slapd/tools/pwenc.c b/ldap/servers/slapd/tools/pwenc.c new file mode 100644 index 00000000..7a150860 --- /dev/null +++ b/ldap/servers/slapd/tools/pwenc.c @@ -0,0 +1,400 @@ +/** BEGIN COPYRIGHT BLOCK + * Copyright 2001 Sun Microsystems, Inc. + * Portions copyright 1999, 2001-2003 Netscape Communications Corporation. + * All rights reserved. + * END COPYRIGHT BLOCK **/ +#if defined( _WIN32 ) +#include <sys/stat.h> /* for S_IREAD and S_IWRITE */ +#include <windows.h> +#include <time.h> +#include "proto-ntutil.h" +#else +#include <sys/socket.h> +#include <sys/errno.h> +#include <sys/param.h> +#include <sys/types.h> +#if defined(LINUX) /* I bet other Unix would like + * this flag. But don't want to + * break other builds so far */ +#include <unistd.h> +#endif +#endif +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <stdlib.h> +#include "ldap.h" +#include "ldif.h" +#include "../slapi-plugin.h" +#include "../slap.h" +#include <nspr.h> +#include <nss.h> +#include "../../plugins/pwdstorage/pwdstorage.h" + +int ldap_syslog; +int ldap_syslog_level; +int slapd_ldap_debug = LDAP_DEBUG_ANY; +#ifdef _WIN32 +int *module_ldap_debug; +#endif +int detached; +FILE *error_logfp; +FILE *access_logfp; +struct pw_scheme *pwdhashscheme; +int heflag = 0; + +static int slapd_config(const char *configdir); +static int entry_has_attr_and_value(Slapi_Entry *e, const char *attrname, char *value); + +static void +usage( name ) +char *name; +{ + fprintf( stderr, "usage: %s -D instance-dir [-H] [-s scheme | -c comparepwd ] password...\n", name ); + exit( 1 ); +} + + +/* + * If global "heflag" is non-zero, un-hex-encode the string + * and return a decoded copy. Otherwise return a copy of the + * string. + */ +static char * +decode( char *orig ) +{ + char *r; + + if ( NULL == orig ) { + return NULL; + } + r = calloc( 1, strlen( orig ) + 2 ); + strcpy( r, orig ); + + if ( heflag ) { + char *s; + + for ( s = r; *s != '\0'; ++s ) { + if ( *s == '%' && ldap_utf8isxdigit( s+1 ) && ldap_utf8isxdigit( s+2 )) { + memmove( s, s + 1, 2 ); + s[ 2 ] = '\0'; + *s = strtoul( s, NULL, 16 ); + memmove( s + 1, s + 3, strlen( s + 3 ) + 1 ); + } + } + } + return r; +} + + +int +main( argc, argv ) + int argc; + char *argv[]; +{ + int i, rc; + char *enc, *cmp, *name; + struct pw_scheme *pwsp, *cmppwsp; + extern int optind; + char *cpwd = NULL; /* candidate password for comparison */ + char errorbuf[BUFSIZ]; + slapdFrontendConfig_t *slapdFrontendConfig = NULL; + + char *opts = "Hs:c:D:"; + char *instancedir = NULL; + name = argv[ 0 ]; + pwsp = cmppwsp = NULL; + +#ifdef _WIN32 + module_ldap_debug = &slapd_ldap_debug; + libldap_init_debug_level(&slapd_ldap_debug); +#endif + + PR_Init( PR_USER_THREAD, PR_PRIORITY_NORMAL, 0 ); + + /* Initialize NSS to make ds_salted_sha1_pw_enc() work */ + if (NSS_NoDB_Init(NULL) != SECSuccess) { + fprintf( stderr, "Fatal error: unable to initialize the NSS subcomponent." ); + return( 1 ); + } + + + while (( i = getopt( argc, argv, opts )) != EOF ) { + switch ( i ) { + case 'D': + /* kexcoff: quite the same as slapd_bootstrap_config */ + FrontendConfig_init(); + + instancedir = rel2abspath( optarg ); + if ( config_set_instancedir( "configdir (-D)", instancedir, + errorbuf, 1) != LDAP_SUCCESS ) { + fprintf( stderr, "%s\n", errorbuf ); + return( 1 ); + } + slapi_ch_free((void **)&instancedir); + + + slapdFrontendConfig = getFrontendConfig(); + if (0 == slapd_config(slapdFrontendConfig->configdir)) { + fprintf(stderr, + "The configuration files in directory %s could not be read or were not found. Please refer to the error log or output for more information.\n", + slapdFrontendConfig->configdir); + return(1); + } + break; + + case 's': /* set hash scheme */ + if (!slapdFrontendConfig) { + usage( name ); + return( 1 ); + } + if (( pwsp = pw_name2scheme( optarg )) == NULL ) { + fprintf( stderr, "%s: unknown hash scheme \"%s\"\n", name, + optarg ); + return( 1 ); + } + break; + + case 'c': /* compare encoded password to password */ + if (!slapdFrontendConfig) { + usage( name ); + return( 1 ); + } + cpwd = optarg; + break; + + case 'H': /* password(s) is(are) hex-encoded */ + if (!slapdFrontendConfig) { + usage( name ); + return( 1 ); + } + heflag = 1; + break; + + default: + usage( name ); + } + } + + if (!slapdFrontendConfig) { + usage( name ); + return( 1 ); + } + + 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 ( cmppwsp == NULL && pwsp == NULL ) { + pwsp = pw_name2scheme( SALTED_SHA1_SCHEME_NAME ); + } + + if ( argc <= optind ) { + usage( name ); + } + + if ( cmppwsp == NULL && pwsp->pws_enc == NULL ) { + fprintf( stderr, + "The scheme \"%s\" does not support password encoding.\n", + pwsp->pws_name ); + return( 1 ); + } + + srand((int)time(NULL)); /* schemes such as crypt use random salt */ + + 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 ); + } + + puts( enc ); + free( enc ); + } else { /* compare passwords */ + if (( rc = (*(cmppwsp->pws_cmp))( decode( argv[ optind ]), cmp )) == 0 ) { + printf( "%s: password ok.\n", name ); + } else { + printf( "%s: password does not match.\n", name ); + } + } + } + + return( rc == 0 ? 0 : 1 ); +} + +/* -------------------------------------------------------------- */ + +/* + kexcoff: quite similar to slapd_bootstrap_config() from the server, + but it only loads password storage scheme plugins + */ +static int +slapd_config(const char *configdir) +{ + char configfile[MAXPATHLEN+1]; + PRFileInfo prfinfo; + int rc = 0; /* Fail */ + int done = 0; + PRInt32 nr = 0; + PRFileDesc *prfd = 0; + char *buf = 0; + char *lastp = 0; + char *entrystr = 0; + + sprintf(configfile, "%s/%s", configdir, CONFIG_FILENAME); + if ( (rc = PR_GetFileInfo( configfile, &prfinfo )) != PR_SUCCESS ) + { + fprintf(stderr, + "The given config file %s could not be accessed, error %d\n", + configfile, rc); + exit( 1 ); + } + else if (( prfd = PR_Open( configfile, PR_RDONLY, + SLAPD_DEFAULT_FILE_MODE )) == NULL ) + { + fprintf(stderr, + "The given config file %s could not be read\n", + configfile); + exit( 1 ); + } + else + { + /* read the entire file into core */ + buf = slapi_ch_malloc( prfinfo.size + 1 ); + if (( nr = slapi_read_buffer( prfd, buf, prfinfo.size )) < 0 ) + { + fprintf(stderr, + "Could only read %d of %d bytes from config file %s\n", + nr, prfinfo.size, configfile); + exit( 1 ); + } + + (void)PR_Close(prfd); + buf[ nr ] = '\0'; + + if(!done) + { + /* Convert LDIF to entry structures */ + Slapi_DN plug_dn; + slapi_sdn_init_dn_byref(&plug_dn, PLUGIN_BASE_DN); + while ((entrystr = dse_read_next_entry(buf, &lastp)) != NULL) + { + /* + * XXXmcs: it would be better to also pass + * SLAPI_STR2ENTRY_REMOVEDUPVALS in the flags, but + * duplicate value checking requires that the syntax + * and schema subsystems be initialized... and they + * are not yet. + */ + Slapi_Entry *e = slapi_str2entry(entrystr, + SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF); + if (e == NULL) + { + fprintf(stderr, + "The entry [%s] in the configfile %s was empty or could not be parsed\n", + entrystr, configfile); + continue; + } + + /* see if the entry is a child of the plugin base dn */ + if (slapi_sdn_isgrandparent(&plug_dn, + slapi_entry_get_sdn_const(e))) + { + 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)) + { + fprintf(stderr, + "The plugin entry [%s] in the configfile %s was invalid\n", + slapi_entry_get_dn(e), configfile); + 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); + } + + /* kexcoff: initialize rootpwstoragescheme and pw_storagescheme + * if not explicilty set in the config file + */ + config_set_storagescheme(); + + slapi_sdn_done(&plug_dn); + rc= 1; /* OK */ + } + + slapi_ch_free((void **)&buf); + } + + return rc; +} + +/* + kexcoff: direclty copied fron the server code + See if the given entry has an attribute with the given name and the + given value; if value is NULL, just test for the presence of the given + attribute; if value is an empty string (i.e. value[0] == 0), + the first value in the attribute will be copied into the given buffer + and returned +*/ +static int +entry_has_attr_and_value(Slapi_Entry *e, const char *attrname, + char *value) +{ + int retval = 0; + Slapi_Attr *attr = 0; + if (!e || !attrname) + return retval; + + /* see if the entry has the specified attribute name */ + if (!slapi_entry_attr_find(e, attrname, &attr) && attr) + { + /* if value is not null, see if the attribute has that + value */ + if (!value) + { + retval = 1; + } + else + { + Slapi_Value *v = 0; + int index = 0; + for (index = slapi_attr_first_value(attr, &v); + v && (index != -1); + index = slapi_attr_next_value(attr, index, &v)) + { + const char *s = slapi_value_get_string(v); + if (!s) + continue; + + if (!*value) + { + strcpy(value, s); + retval = 1; + break; + } + else if (!strcasecmp(s, value)) + { + retval = 1; + break; + } + } + } + } + + return retval; +} + |