]> git.sur5r.net Git - openldap/blobdiff - clients/tools/ldappasswd.c
Very crude LDIF changes:
[openldap] / clients / tools / ldappasswd.c
index ea440a43c89b13e8ebdf7609b9288dacb9727a5b..3d48a2d2c5eebfd64104a0ffb81f57bacb371a6e 100644 (file)
 
 #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
@@ -80,7 +82,7 @@ static int    auto_gen_pw = 0;
 /*** functions ***/
 
 /*
- * pw_encode() essentially base64 encodes a password and it's salt
+ * pw_encode() essentially base64 encodes a password and its salt
  */
 
 char *
@@ -120,20 +122,15 @@ pw_encode (unsigned char *passwd, Salt * salt, unsigned int len)
 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;
 }
 
 /*
@@ -143,10 +140,13 @@ make_salt (Salt * salt, unsigned int len)
 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++)
@@ -155,16 +155,19 @@ gen_pass (unsigned int len)
        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;
@@ -187,38 +190,24 @@ hash_crypt (const char *pw_in, Salt * salt)
                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 *
@@ -226,36 +215,25 @@ hash_sha1 (const char *pw_in, Salt * salt)
 {
        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},
@@ -272,9 +250,8 @@ modify_dn (LDAP * ld, char *targetdn, char *pwattr, char *oldpw,
        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);
@@ -303,7 +280,7 @@ modify_dn (LDAP * ld, char *targetdn, char *pwattr, char *oldpw,
        /* 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);
@@ -329,12 +306,15 @@ modify_dn (LDAP * ld, char *targetdn, char *pwattr, char *oldpw,
        }
 
        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);
@@ -361,6 +341,7 @@ usage (char *s)
 #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");
@@ -388,9 +369,11 @@ main (int argc, char *argv[])
        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;
@@ -402,16 +385,16 @@ main (int argc, char *argv[])
        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':
@@ -419,15 +402,11 @@ main (int argc, char *argv[])
                        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 */
@@ -435,7 +414,7 @@ main (int argc, char *argv[])
                        break;
 
                case 'e':       /* new password */
-                       newpw = STRDUP (optarg);
+                       newpw = strdup (optarg);
                        break;
 
                case 'g':
@@ -460,7 +439,7 @@ main (int argc, char *argv[])
                        break;
 
                case 'h':       /* ldap host */
-                       ldaphost = STRDUP (optarg);
+                       ldaphost = strdup (optarg);
                        break;
 
                case 'K':       /* use kerberos bind, 1st part only */
@@ -468,6 +447,7 @@ main (int argc, char *argv[])
                        authmethod = LDAP_AUTH_KRBV41;
 #else
                        fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]);
+                       usage (argv[0]);
 #endif
                        break;
 
@@ -476,6 +456,7 @@ main (int argc, char *argv[])
                        authmethod = LDAP_AUTH_KRBV4;
 #else
                        fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]);
+                       usage (argv[0]);
 #endif
                        break;
 
@@ -487,16 +468,30 @@ main (int argc, char *argv[])
                        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
                        {
@@ -506,7 +501,7 @@ main (int argc, char *argv[])
                        break;
 
                case 't':       /* target dn */
-                       targetdn = STRDUP (optarg);
+                       targetdn = strdup (optarg);
                        break;
 
                case 'v':       /* verbose */
@@ -518,7 +513,14 @@ main (int argc, char *argv[])
                        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 */
@@ -527,7 +529,7 @@ main (int argc, char *argv[])
 
                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 */
@@ -541,7 +543,7 @@ main (int argc, char *argv[])
 
        /* grab filter */
        if (!(argc - optind < 1))
-               filtpattern = STRDUP (argv[optind]);
+               filtpattern = strdup (argv[optind]);
 
        /* check for target(s) */
        if (!filtpattern && !targetdn)
@@ -561,26 +563,74 @@ main (int argc, char *argv[])
                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)
@@ -596,9 +646,11 @@ main (int argc, char *argv[])
        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);
@@ -607,8 +659,8 @@ main (int argc, char *argv[])
                    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))
@@ -627,8 +679,6 @@ main (int argc, char *argv[])
 
        /* disconnect from server */
        ldap_unbind (ld);
-       exit(0);
 
-       /* unreached */
-       return (0);
+       return ( EXIT_SUCCESS );
 }