#include "portable.h"
-#include <ctype.h>
#include <stdio.h>
-#include <stdlib.h>
-#include <sys/time.h>
+#include <ac/stdlib.h>
+
+#include <ac/ctype.h>
+#include <ac/signal.h>
+#include <ac/socket.h>
#include <ac/string.h>
+#include <ac/time.h>
#include <ac/unistd.h>
#include <lber.h>
#include <lutil_md5.h>
#include <lutil_sha1.h>
-#include "ldapconfig.h"
+#include "ldap_defaults.h"
/* local macros */
-#define CEILING(x) ((double)x > (int)x ? (int)x + 1 : (int)x)
-#define STRDUP(x) (x ? strcpy(malloc(strlen(x) + 1), x) : NULL)
+#define CEILING(x) ((double)(x) > (int)(x) ? (int)(x) + 1 : (int)(x))
#define LDAP_PASSWD_ATTRIB "userPassword"
-#define LDAP_PASSWD_CONF DEFAULT_SYSCONFDIR"/passwd.conf"
+#define LDAP_PASSWD_CONF LDAP_SYSCONFDIR LDAP_DIRSEP "passwd.conf"
#define HS_NONE 0
#define HS_PLAIN 1
/*** functions ***/
/*
- * pw_encode() essentially base64 encodes a password and it's salt
+ * pw_encode() essentially base64 encodes a password and its salt
*/
char *
void
make_salt (Salt * salt, unsigned int len)
{
- struct timeval tv;
if (!salt)
return;
- /* seed random number generator */
- gettimeofday (&tv, NULL);
- srand (tv.tv_usec);
-
salt->len = len;
salt->salt = (unsigned char *)malloc (len);
for (len = 0; len < salt->len; len++)
- salt->salt[len] = (tv.tv_usec ^ rand ()) & 0xff;
+ salt->salt[len] = rand () & 0xff;
}
/*
char *
gen_pass (unsigned int len)
{
- const unsigned char autogen[] =
+ static const unsigned char autogen[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890.,";
- int i;
- Salt salt = {NULL, 0};
+ unsigned int i;
+ Salt salt;
+
+ salt.salt = NULL;
+ salt.len = 0;
make_salt (&salt, len);
for (i = 0; i < len; i++)
return ((char *)salt.salt);
}
+#ifdef SLAPD_CLEARTEXT
char *
hash_none (const char *pw_in, Salt * salt)
{
- return (STRDUP (pw_in));
+ return (strdup (pw_in));
}
+#endif
+#ifdef SLAPD_CRYPT
char *
hash_crypt (const char *pw_in, Salt * salt)
{
- const unsigned char crypt64[] =
+ static const unsigned char crypt64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890./";
char *crypted_pw = NULL;
Salt lsalt;
crypted_pw = crypt (pw_in, (char *)lsalt.salt);
free (lsalt.salt);
}
- return (STRDUP (crypted_pw));
+ return (strdup (crypted_pw));
}
+#endif
char *
hash_md5 (const char *pw_in, Salt * salt)
{
lutil_MD5_CTX MD5context;
unsigned char MD5digest[16];
- unsigned char *hashing_pw = (unsigned char *)pw_in;
- char *base64digest = NULL;
- int tot_len = strlen (pw_in);
- int salted = (salt && salt->salt && salt->len);
-
- /* append salt to password */
- if (salted)
- {
- hashing_pw = (unsigned char *)malloc (tot_len + salt->len);
- memcpy (hashing_pw, pw_in, tot_len);
- memcpy (&hashing_pw[tot_len], salt->salt, salt->len);
- tot_len += salt->len;
- }
lutil_MD5Init (&MD5context);
- lutil_MD5Update (&MD5context, hashing_pw, tot_len);
+ lutil_MD5Update (&MD5context,
+ (const unsigned char *)pw_in, strlen(pw_in));
+ if (salt && salt->salt && salt->len)
+ lutil_MD5Update (&MD5context, salt->salt, salt->len);
lutil_MD5Final (MD5digest, &MD5context);
- base64digest = pw_encode (MD5digest, salt, sizeof (MD5digest));
-
- if (salted)
- free (hashing_pw);
-
- return (base64digest);
+ return (pw_encode (MD5digest, salt, sizeof (MD5digest)));
}
char *
{
lutil_SHA1_CTX SHA1context;
unsigned char SHA1digest[20];
- unsigned char *hashing_pw = (unsigned char *)pw_in;
- char *base64digest = NULL;
- int tot_len = strlen (pw_in);
- int salted = (salt && salt->salt);
-
- /* append salt to password */
- if (salted)
- {
- hashing_pw = (unsigned char *)malloc (tot_len + salt->len);
- memcpy (hashing_pw, pw_in, tot_len);
- memcpy (&hashing_pw[tot_len], salt->salt, salt->len);
- tot_len += salt->len;
- }
lutil_SHA1Init (&SHA1context);
- lutil_SHA1Update (&SHA1context, hashing_pw, tot_len);
+ lutil_SHA1Update (&SHA1context,
+ (const unsigned char *)pw_in, strlen(pw_in));
+ if (salt && salt->salt && salt->len)
+ lutil_SHA1Update (&SHA1context, salt->salt, salt->len);
lutil_SHA1Final (SHA1digest, &SHA1context);
- base64digest = pw_encode (SHA1digest, salt, sizeof (SHA1digest));
-
- if (salted)
- free (hashing_pw);
-
- return (base64digest);
+ return (pw_encode (SHA1digest, salt, sizeof (SHA1digest)));
}
static Hash hashes[] =
{
+#ifdef SLAPD_CLEARTEXT
{"none", 4, hash_none, 0, HASHTYPE_NONE, HASHTYPE_NONE, 0},
+#endif
+#ifdef SLAPD_CRYPT
{"crypt", 5, hash_crypt, 1, HASHTYPE_CRYPT, HASHTYPE_CRYPT, 2},
+#endif
{"md5", 3, hash_md5, 0, HASHTYPE_MD5, HASHTYPE_SMD5, 0},
{"smd5", 4, hash_md5, 1, HASHTYPE_SMD5, HASHTYPE_SMD5, 4},
{"sha", 3, hash_sha1, 0, HASHTYPE_SHA1, HASHTYPE_SSHA1, 0},
int want_salt = salt->len && !salted;
char *buf = NULL;
char *hashed_pw = NULL;
- char *strvals[2] = {NULL, NULL};
- LDAPMod mod;
- LDAPMod *mods[2] = {&mod, NULL};
+ char *strvals[2];
+ LDAPMod mod, *mods[2];
if (!ld || !targetdn || !newpw)
return (1);
/* hash password */
hashed_pw = hashes[htype].func (newpw, salt->len ? salt : NULL);
- /* return salt back to it's original state */
+ /* return salt back to its original state */
if (want_salt)
{
free (salt->salt);
}
strvals[0] = buf;
- mod.mod_vals.modv_strvals = strvals;
+ strvals[1] = NULL;
+ mod.mod_values = strvals;
mod.mod_type = pwattr;
mod.mod_op = LDAP_MOD_REPLACE;
+ mods[0] = &mod;
+ mods[1] =NULL;
if (!noupdates && (ret = ldap_modify_s (ld, targetdn, mods)) != LDAP_SUCCESS)
- ldap_perror (ld, "ldap_modify_s");
+ ldap_perror (ld, "ldap_modify");
free (hashed_pw);
free (buf);
#endif
fprintf (stderr, " -l time\ttime limit\n");
fprintf (stderr, " -n\t\tmake no modifications\n");
+ fprintf (stderr, " -P version\tprotocol version (2 or 3)\n");
fprintf (stderr, " -p port\tldap port\n");
fprintf (stderr, " -s scope\tsearch scope: base, one, sub (default: sub)\n");
fprintf (stderr, " -t targetdn\tdn to change password\n");
int hashtype = HASHTYPE_CRYPT;
int i, j;
int ldapport = 0;
+ int debug = 0;
int scope = LDAP_SCOPE_SUBTREE;
- int sizelimit = LDAP_NO_LIMIT;
- int timelimit = LDAP_NO_LIMIT;
+ int sizelimit = -1;
+ int timelimit = -1;
+ int version = -1;
int want_bindpw = 0;
int want_newpw = 0;
LDAP *ld;
if (argc == 1)
usage (argv[0]);
- while ((i = getopt (argc, argv, "a:b:C:D:d:Ee:g:H:h:Kkl:np:s:t:vWw:Y:y:z:")) != EOF)
+ while ((i = getopt (argc, argv, "a:b:C:D:d:Ee:g:H:h:Kkl:nP:p:s:t:vWw:Y:y:z:")) != EOF)
{
switch (i)
{
case 'a': /* password attribute */
- pwattr = STRDUP (optarg);
+ pwattr = strdup (optarg);
break;
case 'b': /* base search dn */
- base = STRDUP (optarg);
+ base = strdup (optarg);
break;
case 'C':
break;
case 'D': /* bind distinguished name */
- binddn = STRDUP (optarg);
+ binddn = strdup (optarg);
break;
case 'd': /* debugging option */
-#ifdef LDAP_DEBUG
- ldap_debug = lber_debug = atoi (optarg); /* */
-#else
- fprintf (stderr, "compile with -DLDAP_DEBUG for debugging\n");
-#endif
+ debug |= atoi (optarg);
break;
case 'E': /* prompt for new password */
break;
case 'e': /* new password */
- newpw = STRDUP (optarg);
+ newpw = strdup (optarg);
break;
case 'g':
break;
case 'h': /* ldap host */
- ldaphost = STRDUP (optarg);
+ ldaphost = strdup (optarg);
break;
case 'K': /* use kerberos bind, 1st part only */
authmethod = LDAP_AUTH_KRBV41;
#else
fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]);
+ usage (argv[0]);
#endif
break;
authmethod = LDAP_AUTH_KRBV4;
#else
fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]);
+ usage (argv[0]);
#endif
break;
noupdates++;
break;
+ case 'P':
+ switch( atoi( optarg ) ) {
+ case 2:
+ version = LDAP_VERSION2;
+ break;
+ case 3:
+ version = LDAP_VERSION3;
+ break;
+ default:
+ fprintf( stderr, "protocol version should be 2 or 3\n" );
+ usage( argv[0] );
+ }
+ break;
+
case 'p': /* ldap port */
ldapport = strtol (optarg, NULL, 10);
break;
case 's': /* scope */
- if (strncasecmp (optarg, "base", 4) == 0)
+ if (strcasecmp (optarg, "base") == 0)
scope = LDAP_SCOPE_BASE;
- else if (strncasecmp (optarg, "one", 3) == 0)
+ else if (strcasecmp (optarg, "one") == 0)
scope = LDAP_SCOPE_ONELEVEL;
- else if (strncasecmp (optarg, "sub", 3) == 0)
+ else if (strcasecmp (optarg, "sub") == 0)
scope = LDAP_SCOPE_SUBTREE;
else
{
break;
case 't': /* target dn */
- targetdn = STRDUP (optarg);
+ targetdn = strdup (optarg);
break;
case 'v': /* verbose */
break;
case 'w': /* bind password */
- bindpw = STRDUP (optarg);
+ bindpw = strdup (optarg);
+ {
+ char* p;
+
+ for( p = optarg; *p == '\0'; p++ ) {
+ *p = '*';
+ }
+ }
break;
case 'Y': /* salt length */
case 'y': /* user specified salt */
salt.len = strlen (optarg);
- salt.salt = (unsigned char *)STRDUP (optarg);
+ salt.salt = (unsigned char *)strdup (optarg);
break;
case 'z': /* time limit */
/* grab filter */
if (!(argc - optind < 1))
- filtpattern = STRDUP (argv[optind]);
+ filtpattern = strdup (argv[optind]);
/* check for target(s) */
if (!filtpattern && !targetdn)
if (strncmp (newpw, cknewpw, strlen (newpw)))
{
fprintf (stderr, "passwords do not match\n");
- exit (1);
+ return ( EXIT_FAILURE );
+ }
+ }
+
+ if ( debug ) {
+ if( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug ) != LBER_OPT_SUCCESS ) {
+ fprintf( stderr, "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug );
+ }
+ if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
+ fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
}
}
+#ifdef SIGPIPE
+ (void) SIGNAL( SIGPIPE, SIG_IGN );
+#endif
+ /* seed random number generator */
+
+#ifdef HAVE_GETTIMEOFDAY
+ /* this is of questionable value
+ * gettimeofday not provide much usec
+ */
+ {
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+ srand (tv.tv_usec);
+ }
+#else
+ /* The traditional seed */
+ srand((unsigned)time( NULL ));
+#endif
+
/* connect to server */
- if ((ld = ldap_open (ldaphost, ldapport)) == NULL)
+ if ((ld = ldap_init (ldaphost, ldapport)) == NULL)
{
- perror (ldaphost);
- exit (1);
+ perror ("ldap_init");
+ return ( EXIT_FAILURE );
}
/* set options */
- ldap_set_option (ld, LDAP_OPT_TIMELIMIT, (void *)&timelimit);
- ldap_set_option (ld, LDAP_OPT_SIZELIMIT, (void *)&sizelimit);
+ if (timelimit != -1 &&
+ ldap_set_option( ld, LDAP_OPT_TIMELIMIT, (void *) &timelimit ) != LDAP_OPT_SUCCESS )
+ {
+ fprintf( stderr, "Could not set LDAP_OPT_TIMELIMIT %d\n", timelimit );
+ }
+ if (sizelimit != -1 &&
+ ldap_set_option( ld, LDAP_OPT_SIZELIMIT, (void *) &sizelimit ) != LDAP_OPT_SUCCESS )
+ {
+ fprintf( stderr, "Could not set LDAP_OPT_SIZELIMIT %d\n", sizelimit );
+ }
+
+ /* this seems prudent */
+ {
+ int deref = LDAP_DEREF_NEVER;
+ ldap_set_option( ld, LDAP_OPT_DEREF, &deref);
+ }
+
+ if (version != -1 &&
+ ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ) != LDAP_OPT_SUCCESS )
+ {
+ fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version );
+ }
/* authenticate to server */
if (ldap_bind_s (ld, binddn, bindpw, authmethod) != LDAP_SUCCESS)
{
ldap_perror (ld, "ldap_bind");
- exit (1);
+ return ( EXIT_FAILURE );
}
if (targetdn)
if (filtpattern)
{
char filter[BUFSIZ];
- LDAPMessage *result = NULL, *e = NULL;
- char *attrs[3] = {"dn", NULL, NULL};
+ LDAPMessage *result = NULL, *e;
+ char *attrs[3];
+ attrs[0] = "dn";
attrs[1] = pwattr;
+ attrs[2] = NULL;
/* search */
sprintf (filter, "%s", filtpattern);
i != LDAP_TIMELIMIT_EXCEEDED &&
i != LDAP_SIZELIMIT_EXCEEDED)
{
- ldap_perror (ld, "ldap_search_s");
- exit (1);
+ ldap_perror (ld, "ldap_search");
+ return ( EXIT_FAILURE );
}
for (e = ldap_first_entry (ld, result); e; e = ldap_next_entry (ld, e))
/* disconnect from server */
ldap_unbind (ld);
- exit(0);
- /* unreached */
- return (0);
+ return ( EXIT_SUCCESS );
}