]> git.sur5r.net Git - openldap/commitdiff
First cut SASL "interactive" and "quiet" modes (default is "automatic")
authorKurt Zeilenga <kurt@openldap.org>
Mon, 17 Jul 2000 00:56:29 +0000 (00:56 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Mon, 17 Jul 2000 00:56:29 +0000 (00:56 +0000)
14 files changed:
clients/tools/ldapdelete.c
clients/tools/ldapmodify.c
clients/tools/ldapmodrdn.c
clients/tools/ldappasswd.c
clients/tools/ldapsearch.c
include/ldap.h
include/lutil_ldap.h
libraries/libldap/cyrus.c
libraries/libldap/init.c
libraries/libldap/ldap-int.h
libraries/libldap/open.c
libraries/libldap/sasl.c
libraries/liblutil/sasl.c
servers/slapd/tools/slappasswd.c

index 686f9ff764078f01bdb1ab97294e282505b25b74..ef9f94245f4d86de86dda46896ef8b97239b4eb7 100644 (file)
@@ -27,9 +27,11 @@ static char  *ldaphost = NULL;
 static int     ldapport = 0;
 static int     prune = 0;
 #ifdef HAVE_CYRUS_SASL
+static unsigned sasl_flags = LUTIL_SASL_AUTOMATIC;
+static char    *sasl_mech = NULL;
+static char *sasl_realm = NULL;
 static char    *sasl_authc_id = NULL;
 static char    *sasl_authz_id = NULL;
-static char    *sasl_mech = NULL;
 static char    *sasl_secprops = NULL;
 #endif
 static int     use_tls = 0;
@@ -61,6 +63,7 @@ usage( const char *s )
 "      -D binddn\tbind DN\n"
 "      -f file\t\tread operations from `file'\n"
 "      -h host\t\tLDAP server\n"
+"      -I\t\tuse SASL Interactive mode\n"
 "      -k\t\tuse Kerberos authentication\n"
 "      -K\t\tlike -k, but do only step 1 of the Kerberos bind\n"
 "      -M\t\tenable Manage DSA IT control (-MM to make it critical)\n"
@@ -68,6 +71,8 @@ usage( const char *s )
 "      -O secprops\tSASL security properties\n"
 "      -p port\t\tport on LDAP server\n"
 "      -P version\tprocotol version (default: 3)\n"
+"      -Q\t\tuse SASL Quiet mode\n"
+"      -R realm\tSASL realm\n"
 "      -U user\t\tSASL authentication identity (username)\n"
 "      -v\t\trun in verbose mode (diagnostics to standard output)\n"
 "      -w passwd\tbind passwd (for simple authentication)\n"
@@ -96,13 +101,17 @@ main( int argc, char **argv )
 
     prog = (prog = strrchr(argv[0], *LDAP_DIRSEP)) == NULL ? argv[0] : ++prog;
 
-    while (( i = getopt( argc, argv, "cf:r" "Cd:D:h:kKMnO:p:P:U:vw:WxX:Y:Z" )) != EOF ) {
+    while (( i = getopt( argc, argv, "cf:r" "Cd:D:h:IkKMnO:p:P:QRU:vw:WxX:Y:Z" )) != EOF ) {
        switch( i ) {
        /* Delete Specific Options */
        case 'c':       /* continuous operation mode */
            ++contoper;
            break;
        case 'f':       /* read DNs from a file */
+               if( fp != NULL ) {
+                       fprintf( stderr, "%s: -f previously specified\n" );
+                       return EXIT_FAILURE;
+               }
            if (( fp = fopen( optarg, "r" )) == NULL ) {
                perror( optarg );
                exit( EXIT_FAILURE );
@@ -120,9 +129,17 @@ main( int argc, char **argv )
            debug |= atoi( optarg );
            break;
        case 'D':       /* bind DN */
+               if( binddn != NULL ) {
+                       fprintf( stderr, "%s: -D previously specified\n" );
+                       return EXIT_FAILURE;
+               }
            binddn = strdup( optarg );
            break;
        case 'h':       /* ldap host */
+               if( ldaphost != NULL ) {
+                       fprintf( stderr, "%s: -h previously specified\n" );
+                       return EXIT_FAILURE;
+               }
            ldaphost = strdup( optarg );
            break;
        case 'k':       /* kerberos bind */
@@ -179,8 +196,12 @@ main( int argc, char **argv )
            break;
        case 'O':
 #ifdef HAVE_CYRUS_SASL
+               if( sasl_secprops != NULL ) {
+                       fprintf( stderr, "%s: -O previously specified\n" );
+                       return EXIT_FAILURE;
+               }
                if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s -O incompatible with LDAPv%d\n",
+                       fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
                                prog, version );
                        return EXIT_FAILURE;
                }
@@ -189,9 +210,9 @@ main( int argc, char **argv )
                                "authentication choice\n", prog );
                        return EXIT_FAILURE;
                }
-               sasl_secprops = strdup( optarg );
                authmethod = LDAP_AUTH_SASL;
                version = LDAP_VERSION3;
+               sasl_secprops = strdup( optarg );
 #else
                fprintf( stderr, "%s: not compiled with SASL support\n",
                        prog );
@@ -199,6 +220,10 @@ main( int argc, char **argv )
 #endif
                break;
        case 'p':
+               if( ldapport ) {
+                       fprintf( stderr, "%s: -p previously specified\n" );
+                       return EXIT_FAILURE;
+               }
            ldapport = atoi( optarg );
            break;
        case 'P':
@@ -225,8 +250,59 @@ main( int argc, char **argv )
                        usage( prog );
                        return( EXIT_FAILURE );
                } break;
+       case 'Q':
+#ifdef HAVE_CYRUS_SASL
+               if( version == LDAP_VERSION2 ) {
+                       fprintf( stderr, "%s: -Q incompatible with version %d\n",
+                               prog, version );
+                       return EXIT_FAILURE;
+               }
+               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                       fprintf( stderr, "%s: incompatible previous "
+                               "authentication choice\n",
+                               prog );
+                       return EXIT_FAILURE;
+               }
+               authmethod = LDAP_AUTH_SASL;
+               version = LDAP_VERSION3;
+               sasl_flags = LUTIL_SASL_QUIET;
+#else
+               fprintf( stderr, "%s: was not compiled with SASL support\n",
+                       prog );
+               return( EXIT_FAILURE );
+#endif
+       case 'R':
+#ifdef HAVE_CYRUS_SASL
+               if( sasl_realm != NULL ) {
+                       fprintf( stderr, "%s: -R previously specified\n" );
+                       return EXIT_FAILURE;
+               }
+               if( version == LDAP_VERSION2 ) {
+                       fprintf( stderr, "%s: -R incompatible with version %d\n",
+                               prog, version );
+                       return EXIT_FAILURE;
+               }
+               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                       fprintf( stderr, "%s: incompatible previous "
+                               "authentication choice\n",
+                               prog );
+                       return EXIT_FAILURE;
+               }
+               authmethod = LDAP_AUTH_SASL;
+               version = LDAP_VERSION3;
+               sasl_realm = strdup( optarg );
+#else
+               fprintf( stderr, "%s: was not compiled with SASL support\n",
+                       prog );
+               return( EXIT_FAILURE );
+#endif
+               break;
        case 'U':
 #ifdef HAVE_CYRUS_SASL
+               if( sasl_authc_id != NULL ) {
+                       fprintf( stderr, "%s: -U previously specified\n" );
+                       return EXIT_FAILURE;
+               }
                if( version == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -U incompatible with version %d\n",
                                prog, version );
@@ -240,9 +316,7 @@ main( int argc, char **argv )
                }
                authmethod = LDAP_AUTH_SASL;
                version = LDAP_VERSION3;
-
                sasl_authc_id = strdup( optarg );
-               authmethod = LDAP_AUTH_SASL;
 #else
                fprintf( stderr, "%s: was not compiled with SASL support\n",
                        prog );
@@ -258,7 +332,7 @@ main( int argc, char **argv )
                        char* p;
 
                        for( p = optarg; *p == '\0'; p++ ) {
-                               *p = '*';
+                               *p = '\0';
                        }
                }
                passwd.bv_len = strlen( passwd.bv_val );
@@ -268,6 +342,10 @@ main( int argc, char **argv )
                break;
        case 'Y':
 #ifdef HAVE_CYRUS_SASL
+               if( sasl_mech != NULL ) {
+                       fprintf( stderr, "%s: -Y previously specified\n" );
+                       return EXIT_FAILURE;
+               }
                if( version == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -Y incompatible with version %d\n",
                                prog, version );
@@ -277,9 +355,9 @@ main( int argc, char **argv )
                        fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
                        return EXIT_FAILURE;
                }
-
                authmethod = LDAP_AUTH_SASL;
                version = LDAP_VERSION3;
+               sasl_mech = strdup( optarg );
 #else
                fprintf( stderr, "%s: was not compiled with SASL support\n",
                        prog );
@@ -296,6 +374,10 @@ main( int argc, char **argv )
                break;
        case 'X':
 #ifdef HAVE_CYRUS_SASL
+               if( sasl_authz_id != NULL ) {
+                       fprintf( stderr, "%s: -X previously specified\n" );
+                       return EXIT_FAILURE;
+               }
                if( version == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
                                prog, version );
@@ -308,9 +390,7 @@ main( int argc, char **argv )
                }
                authmethod = LDAP_AUTH_SASL;
                version = LDAP_VERSION3;
-
                sasl_authz_id = strdup( optarg );
-               authmethod = LDAP_AUTH_SASL;
 #else
                fprintf( stderr, "%s: not compiled with SASL support\n",
                        prog );
@@ -413,6 +493,8 @@ main( int argc, char **argv )
 
        if ( authmethod == LDAP_AUTH_SASL ) {
 #ifdef HAVE_CYRUS_SASL
+               void *defaults;
+
                if( sasl_secprops != NULL ) {
                        rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
                                (void *) sasl_secprops );
@@ -425,8 +507,16 @@ main( int argc, char **argv )
                        }
                }
                
+               defaults = lutil_sasl_defaults( ld, sasl_flags,
+                       sasl_mech,
+                       sasl_realm,
+                       sasl_authc_id,
+                       passwd.bv_val,
+                       sasl_authz_id );
+
                rc = ldap_sasl_interactive_bind_s( ld, binddn,
-                       sasl_mech, NULL, NULL, lutil_sasl_interact );
+                       sasl_mech, NULL, NULL,
+                       lutil_sasl_interact, defaults );
 
                if( rc != LDAP_SUCCESS ) {
                        ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
index 3134361851ffae5df13cdafc7812b91b6ba80f34..e5a2af05f24a99f923a21056ff1de083e371d766 100644 (file)
@@ -39,6 +39,8 @@ static struct berval passwd = { 0, NULL };
 static char    *ldaphost = NULL;
 static int     ldapport = 0;
 #ifdef HAVE_CYRUS_SASL
+static unsigned sasl_flags = LUTIL_SASL_AUTOMATIC;
+static char *sasl_realm = NULL;
 static char    *sasl_authc_id = NULL;
 static char    *sasl_authz_id = NULL;
 static char    *sasl_mech = NULL;
@@ -109,12 +111,15 @@ usage( const char *prog )
 "      -D dn\t\tbind DN\n"
 "      -f file\t\tread operations from `file'\n"
 "      -h host\t\tLDAP server\n"
+"      -I\t\tuse SASL Interactive mode\n"
 "      -k\t\tuse Kerberos authentication\n"
 "      -K\t\tlike -k, but do only step 1 of the Kerberos bind\n"
 "      -M\t\tenable Manage DSA IT control (-MM to make it critical)\n"
 "      -n\t\tprint changes, don't actually do them\n"
 "      -O secprops\tSASL security properties\n"
 "      -p port\t\tport on LDAP server\n"
+"      -Q\t\tuse SASL Quiet mode\n"
+"      -R realm\tSASL realm\n"
 "      -U user\t\tSASL authentication identity (username)\n"
 "      -v\t\tverbose mode\n"
 "      -w passwd\tbind password (for Simple authentication)\n"
@@ -151,7 +156,7 @@ main( int argc, char **argv )
     authmethod = -1;
        version = -1;
 
-    while (( i = getopt( argc, argv, "acrf:F" "Cd:D:h:kKMnO:p:P:U:vw:WxX:Y:Z" )) != EOF ) {
+    while (( i = getopt( argc, argv, "acrf:F" "Cd:D:h:IkKMnO:p:P:QRU:vw:WxX:Y:Z" )) != EOF ) {
        switch( i ) {
        /* Modify Options */
        case 'a':       /* add */
@@ -161,6 +166,10 @@ main( int argc, char **argv )
            contoper = 1;
            break;
        case 'f':       /* read from file */
+               if( infile != NULL ) {
+                       fprintf( stderr, "%s: -f previously specified\n" );
+                       return EXIT_FAILURE;
+               }
            infile = strdup( optarg );
            break;
        case 'F':       /* force all changes records to be used */
@@ -178,9 +187,17 @@ main( int argc, char **argv )
            debug |= atoi( optarg );
            break;
        case 'D':       /* bind DN */
+               if( binddn != NULL ) {
+                       fprintf( stderr, "%s: -D previously specified\n" );
+                       return EXIT_FAILURE;
+               }
            binddn = strdup( optarg );
            break;
        case 'h':       /* ldap host */
+               if( ldaphost != NULL ) {
+                       fprintf( stderr, "%s: -h previously specified\n" );
+                       return EXIT_FAILURE;
+               }
            ldaphost = strdup( optarg );
            break;
        case 'k':       /* kerberos bind */
@@ -237,8 +254,12 @@ main( int argc, char **argv )
            break;
        case 'O':
 #ifdef HAVE_CYRUS_SASL
+               if( sasl_secprops != NULL ) {
+                       fprintf( stderr, "%s: -O previously specified\n" );
+                       return EXIT_FAILURE;
+               }
                if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s -O incompatible with LDAPv%d\n",
+                       fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
                                prog, version );
                        return EXIT_FAILURE;
                }
@@ -247,9 +268,9 @@ main( int argc, char **argv )
                                "authentication choice\n", prog );
                        return EXIT_FAILURE;
                }
-               sasl_secprops = strdup( optarg );
                authmethod = LDAP_AUTH_SASL;
                version = LDAP_VERSION3;
+               sasl_secprops = strdup( optarg );
 #else
                fprintf( stderr, "%s: not compiled with SASL support\n",
                        prog );
@@ -257,6 +278,10 @@ main( int argc, char **argv )
 #endif
                break;
        case 'p':
+               if( ldapport ) {
+                       fprintf( stderr, "%s: -p previously specified\n" );
+                       return EXIT_FAILURE;
+               }
            ldapport = atoi( optarg );
            break;
        case 'P':
@@ -283,8 +308,59 @@ main( int argc, char **argv )
                        usage( prog );
                        return( EXIT_FAILURE );
                } break;
+       case 'Q':
+#ifdef HAVE_CYRUS_SASL
+               if( version == LDAP_VERSION2 ) {
+                       fprintf( stderr, "%s: -Q incompatible with version %d\n",
+                               prog, version );
+                       return EXIT_FAILURE;
+               }
+               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                       fprintf( stderr, "%s: incompatible previous "
+                               "authentication choice\n",
+                               prog );
+                       return EXIT_FAILURE;
+               }
+               authmethod = LDAP_AUTH_SASL;
+               version = LDAP_VERSION3;
+               sasl_flags = LUTIL_SASL_QUIET;
+#else
+               fprintf( stderr, "%s: was not compiled with SASL support\n",
+                       prog );
+               return( EXIT_FAILURE );
+#endif
+       case 'R':
+#ifdef HAVE_CYRUS_SASL
+               if( sasl_realm != NULL ) {
+                       fprintf( stderr, "%s: -R previously specified\n" );
+                       return EXIT_FAILURE;
+               }
+               if( version == LDAP_VERSION2 ) {
+                       fprintf( stderr, "%s: -R incompatible with version %d\n",
+                               prog, version );
+                       return EXIT_FAILURE;
+               }
+               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                       fprintf( stderr, "%s: incompatible previous "
+                               "authentication choice\n",
+                               prog );
+                       return EXIT_FAILURE;
+               }
+               authmethod = LDAP_AUTH_SASL;
+               version = LDAP_VERSION3;
+               sasl_realm = strdup( optarg );
+#else
+               fprintf( stderr, "%s: was not compiled with SASL support\n",
+                       prog );
+               return( EXIT_FAILURE );
+#endif
+               break;
        case 'U':
 #ifdef HAVE_CYRUS_SASL
+               if( sasl_authc_id != NULL ) {
+                       fprintf( stderr, "%s: -U previously specified\n" );
+                       return EXIT_FAILURE;
+               }
                if( version == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -U incompatible with version %d\n",
                                prog, version );
@@ -298,9 +374,7 @@ main( int argc, char **argv )
                }
                authmethod = LDAP_AUTH_SASL;
                version = LDAP_VERSION3;
-
                sasl_authc_id = strdup( optarg );
-               authmethod = LDAP_AUTH_SASL;
 #else
                fprintf( stderr, "%s: was not compiled with SASL support\n",
                        prog );
@@ -316,7 +390,7 @@ main( int argc, char **argv )
                        char* p;
 
                        for( p = optarg; *p == '\0'; p++ ) {
-                               *p = '*';
+                               *p = '\0';
                        }
                }
                passwd.bv_len = strlen( passwd.bv_val );
@@ -326,6 +400,10 @@ main( int argc, char **argv )
                break;
        case 'Y':
 #ifdef HAVE_CYRUS_SASL
+               if( sasl_mech != NULL ) {
+                       fprintf( stderr, "%s: -Y previously specified\n" );
+                       return EXIT_FAILURE;
+               }
                if( version == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -Y incompatible with version %d\n",
                                prog, version );
@@ -335,9 +413,9 @@ main( int argc, char **argv )
                        fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
                        return EXIT_FAILURE;
                }
-
                authmethod = LDAP_AUTH_SASL;
                version = LDAP_VERSION3;
+               sasl_mech = strdup( optarg );
 #else
                fprintf( stderr, "%s: was not compiled with SASL support\n",
                        prog );
@@ -354,6 +432,10 @@ main( int argc, char **argv )
                break;
        case 'X':
 #ifdef HAVE_CYRUS_SASL
+               if( sasl_authz_id != NULL ) {
+                       fprintf( stderr, "%s: -X previously specified\n" );
+                       return EXIT_FAILURE;
+               }
                if( version == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
                                prog, version );
@@ -366,9 +448,7 @@ main( int argc, char **argv )
                }
                authmethod = LDAP_AUTH_SASL;
                version = LDAP_VERSION3;
-
                sasl_authz_id = strdup( optarg );
-               authmethod = LDAP_AUTH_SASL;
 #else
                fprintf( stderr, "%s: not compiled with SASL support\n",
                        prog );
@@ -477,6 +557,8 @@ main( int argc, char **argv )
 
        if ( authmethod == LDAP_AUTH_SASL ) {
 #ifdef HAVE_CYRUS_SASL
+               void *defaults;
+
                if( sasl_secprops != NULL ) {
                        rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
                                (void *) sasl_secprops );
@@ -489,8 +571,16 @@ main( int argc, char **argv )
                        }
                }
                
+               defaults = lutil_sasl_defaults( ld, sasl_flags,
+                       sasl_mech,
+                       sasl_realm,
+                       sasl_authc_id,
+                       passwd.bv_val,
+                       sasl_authz_id );
+
                rc = ldap_sasl_interactive_bind_s( ld, binddn,
-                       sasl_mech, NULL, NULL, lutil_sasl_interact );
+                       sasl_mech, NULL, NULL,
+                       lutil_sasl_interact, defaults );
 
                if( rc != LDAP_SUCCESS ) {
                        ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
index cc8cc724faa65b9fc33611d6bfc7244a81c20c48..101a651c65bda8916ef44de37b07353bfc27b340 100644 (file)
@@ -37,6 +37,8 @@ static struct berval passwd = { 0, NULL };
 static char    *ldaphost = NULL;
 static int     ldapport = 0;
 #ifdef HAVE_CYRUS_SASL
+static unsigned sasl_flags = LUTIL_SASL_AUTOMATIC;
+static char *sasl_realm = NULL;
 static char    *sasl_authc_id = NULL;
 static char    *sasl_authz_id = NULL;
 static char    *sasl_mech = NULL;
@@ -73,6 +75,7 @@ usage( const char *s )
 "      -d level\tset LDAP debugging level to `level'\n"
 "      -D binddn\tbind DN\n"
 "      -h host\t\tLDAP server\n"
+"      -I\t\tuse SASL Interactive mode\n"
 "      -k\t\tuse Kerberos authentication\n"
 "      -K\t\tlike -k, but do only step 1 of the Kerberos bind\n"
 "      -M\t\tenable Manage DSA IT control (-MM to make it critical)\n"
@@ -80,6 +83,8 @@ usage( const char *s )
 "      -O secprops\tSASL security properties\n"
 "      -p port\t\tport on LDAP server\n"
 "      -P version\tprocotol version (default: 3)\n"
+"      -Q\t\tuse SASL Quiet mode\n"
+"      -R realm\tSASL realm\n"
 "      -U user\t\tSASL authentication identity (username)\n"
 "      -v\t\trun in verbose mode (diagnostics to standard output)\n"
 "      -w passwd\tbind passwd (for simple authentication)\n"
@@ -109,12 +114,22 @@ main(int argc, char **argv)
 
     prog = (prog = strrchr(argv[0], *LDAP_DIRSEP)) == NULL ? argv[0] : ++prog;
 
-    while (( i = getopt( argc, argv, "cf:rs:" "Cd:D:h:kKMnO:p:P:U:vw:WxX:Y:Z" )) != EOF ) {
+    while (( i = getopt( argc, argv, "cf:rs:" "Cd:D:h:IkKMnO:p:P:QRU:vw:WxX:Y:Z" )) != EOF ) {
        switch( i ) {
        /* Modrdn Options */
        case 'c':
                contoper++;
                break;
+       case 'f':       /* read from file */
+               if( infile != NULL ) {
+                       fprintf( stderr, "%s: -f previously specified\n" );
+                       return EXIT_FAILURE;
+               }
+           infile = strdup( optarg );
+           break;
+       case 'r':       /* remove old RDN */
+           remove++;
+           break;
        case 's':       /* newSuperior */
                if( version == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
@@ -124,9 +139,6 @@ main(int argc, char **argv)
            newSuperior = strdup( optarg );
            version = LDAP_VERSION3;
            break;
-       case 'r':       /* remove old RDN */
-           remove++;
-           break;
 
        /* Common Options */
        case 'C':
@@ -136,9 +148,17 @@ main(int argc, char **argv)
            debug |= atoi( optarg );
            break;
        case 'D':       /* bind DN */
+               if( binddn != NULL ) {
+                       fprintf( stderr, "%s: -D previously specified\n" );
+                       return EXIT_FAILURE;
+               }
            binddn = strdup( optarg );
            break;
        case 'h':       /* ldap host */
+               if( ldaphost != NULL ) {
+                       fprintf( stderr, "%s: -h previously specified\n" );
+                       return EXIT_FAILURE;
+               }
            ldaphost = strdup( optarg );
            break;
        case 'k':       /* kerberos bind */
@@ -195,8 +215,12 @@ main(int argc, char **argv)
            break;
        case 'O':
 #ifdef HAVE_CYRUS_SASL
+               if( sasl_secprops != NULL ) {
+                       fprintf( stderr, "%s: -O previously specified\n" );
+                       return EXIT_FAILURE;
+               }
                if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s -O incompatible with LDAPv%d\n",
+                       fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
                                prog, version );
                        return EXIT_FAILURE;
                }
@@ -205,9 +229,9 @@ main(int argc, char **argv)
                                "authentication choice\n", prog );
                        return EXIT_FAILURE;
                }
-               sasl_secprops = strdup( optarg );
                authmethod = LDAP_AUTH_SASL;
                version = LDAP_VERSION3;
+               sasl_secprops = strdup( optarg );
 #else
                fprintf( stderr, "%s: not compiled with SASL support\n",
                        prog );
@@ -215,6 +239,10 @@ main(int argc, char **argv)
 #endif
                break;
        case 'p':
+               if( ldapport ) {
+                       fprintf( stderr, "%s: -p previously specified\n" );
+                       return EXIT_FAILURE;
+               }
            ldapport = atoi( optarg );
            break;
        case 'P':
@@ -241,8 +269,59 @@ main(int argc, char **argv)
                        usage( prog );
                        return( EXIT_FAILURE );
                } break;
+       case 'Q':
+#ifdef HAVE_CYRUS_SASL
+               if( version == LDAP_VERSION2 ) {
+                       fprintf( stderr, "%s: -Q incompatible with version %d\n",
+                               prog, version );
+                       return EXIT_FAILURE;
+               }
+               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                       fprintf( stderr, "%s: incompatible previous "
+                               "authentication choice\n",
+                               prog );
+                       return EXIT_FAILURE;
+               }
+               authmethod = LDAP_AUTH_SASL;
+               version = LDAP_VERSION3;
+               sasl_flags = LUTIL_SASL_QUIET;
+#else
+               fprintf( stderr, "%s: was not compiled with SASL support\n",
+                       prog );
+               return( EXIT_FAILURE );
+#endif
+       case 'R':
+#ifdef HAVE_CYRUS_SASL
+               if( sasl_realm != NULL ) {
+                       fprintf( stderr, "%s: -R previously specified\n" );
+                       return EXIT_FAILURE;
+               }
+               if( version == LDAP_VERSION2 ) {
+                       fprintf( stderr, "%s: -R incompatible with version %d\n",
+                               prog, version );
+                       return EXIT_FAILURE;
+               }
+               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                       fprintf( stderr, "%s: incompatible previous "
+                               "authentication choice\n",
+                               prog );
+                       return EXIT_FAILURE;
+               }
+               authmethod = LDAP_AUTH_SASL;
+               version = LDAP_VERSION3;
+               sasl_realm = strdup( optarg );
+#else
+               fprintf( stderr, "%s: was not compiled with SASL support\n",
+                       prog );
+               return( EXIT_FAILURE );
+#endif
+               break;
        case 'U':
 #ifdef HAVE_CYRUS_SASL
+               if( sasl_authc_id != NULL ) {
+                       fprintf( stderr, "%s: -U previously specified\n" );
+                       return EXIT_FAILURE;
+               }
                if( version == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -U incompatible with version %d\n",
                                prog, version );
@@ -256,9 +335,7 @@ main(int argc, char **argv)
                }
                authmethod = LDAP_AUTH_SASL;
                version = LDAP_VERSION3;
-
                sasl_authc_id = strdup( optarg );
-               authmethod = LDAP_AUTH_SASL;
 #else
                fprintf( stderr, "%s: was not compiled with SASL support\n",
                        prog );
@@ -274,7 +351,7 @@ main(int argc, char **argv)
                        char* p;
 
                        for( p = optarg; *p == '\0'; p++ ) {
-                               *p = '*';
+                               *p = '\0';
                        }
                }
                passwd.bv_len = strlen( passwd.bv_val );
@@ -284,6 +361,10 @@ main(int argc, char **argv)
                break;
        case 'Y':
 #ifdef HAVE_CYRUS_SASL
+               if( sasl_mech != NULL ) {
+                       fprintf( stderr, "%s: -Y previously specified\n" );
+                       return EXIT_FAILURE;
+               }
                if( version == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -Y incompatible with version %d\n",
                                prog, version );
@@ -293,9 +374,9 @@ main(int argc, char **argv)
                        fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
                        return EXIT_FAILURE;
                }
-
                authmethod = LDAP_AUTH_SASL;
                version = LDAP_VERSION3;
+               sasl_mech = strdup( optarg );
 #else
                fprintf( stderr, "%s: was not compiled with SASL support\n",
                        prog );
@@ -312,6 +393,10 @@ main(int argc, char **argv)
                break;
        case 'X':
 #ifdef HAVE_CYRUS_SASL
+               if( sasl_authz_id != NULL ) {
+                       fprintf( stderr, "%s: -X previously specified\n" );
+                       return EXIT_FAILURE;
+               }
                if( version == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
                                prog, version );
@@ -324,9 +409,7 @@ main(int argc, char **argv)
                }
                authmethod = LDAP_AUTH_SASL;
                version = LDAP_VERSION3;
-
                sasl_authz_id = strdup( optarg );
-               authmethod = LDAP_AUTH_SASL;
 #else
                fprintf( stderr, "%s: not compiled with SASL support\n",
                        prog );
@@ -444,6 +527,8 @@ main(int argc, char **argv)
 
        if ( authmethod == LDAP_AUTH_SASL ) {
 #ifdef HAVE_CYRUS_SASL
+               void *defaults;
+
                if( sasl_secprops != NULL ) {
                        rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
                                (void *) sasl_secprops );
@@ -456,8 +541,16 @@ main(int argc, char **argv)
                        }
                }
                
+               defaults = lutil_sasl_defaults( ld, sasl_flags,
+                       sasl_mech,
+                       sasl_realm,
+                       sasl_authc_id,
+                       passwd.bv_val,
+                       sasl_authz_id );
+
                rc = ldap_sasl_interactive_bind_s( ld, binddn,
-                       sasl_mech, NULL, NULL, lutil_sasl_interact );
+                       sasl_mech, NULL, NULL,
+                       lutil_sasl_interact, defaults );
 
                if( rc != LDAP_SUCCESS ) {
                        ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
index 124ed1d425658ed28099987dbc4d7a79f4f1943e..be5f5d1b11f91f2da6408822be49e5c2f9027745 100644 (file)
@@ -42,9 +42,12 @@ usage(const char *s)
 "      -C\t\tchase referrals\n"
 "      -D binddn\tbind DN\n"
 "      -h host\t\tLDAP server (default: localhost)\n"
+"      -I\t\tuse SASL Interactive mode\n"
 "      -n\t\tmake no modifications\n"
 "      -O secprops\tSASL security properties\n"
 "      -p port\t\tport on LDAP server\n"
+"      -Q\t\tuse SASL Quiet mode\n"
+"      -R realm\tSASL realm\n"
 "      -U user\t\tSASL authentication identity (username)\n"
 "      -v\t\tverbose mode\n"
 "      -w passwd\tbind password (for simple authentication)\n"
@@ -76,13 +79,16 @@ main( int argc, char *argv[] )
        int             want_newpw = 0;
        int             want_oldpw = 0;
 
-       int             noupdates = 0;
+       int             not = 0;
        int             i;
        int             ldapport = 0;
        int             debug = 0;
        int             version = -1;
        int             authmethod = -1;
+       int             manageDSAit = 0;
 #ifdef HAVE_CYRUS_SASL
+       unsigned        sasl_flags = LUTIL_SASL_AUTOMATIC;
+       char            *sasl_realm = NULL;
        char            *sasl_authc_id = NULL;
        char            *sasl_authz_id = NULL;
        char            *sasl_mech = NULL;
@@ -105,7 +111,7 @@ main( int argc, char *argv[] )
                usage (argv[0]);
 
        while( (i = getopt( argc, argv,
-               "Aa:Ss:" "Cd:D:h:nO:p:U:vw:WxX:Y:Z" )) != EOF )
+               "Aa:Ss:" "Cd:D:h:InO:p:QRU:vw:WxX:Y:Z" )) != EOF )
        {
                switch (i) {
                /* Password Options */
@@ -120,7 +126,7 @@ main( int argc, char *argv[] )
                                char* p;
 
                                for( p = optarg; *p == '\0'; p++ ) {
-                                       *p = '*';
+                                       *p = '\0';
                                }
                        }
                        break;
@@ -135,116 +141,303 @@ main( int argc, char *argv[] )
                                char* p;
 
                                for( p = optarg; *p == '\0'; p++ ) {
-                                       *p = '*';
+                                       *p = '\0';
                                }
                        }
                        break;
 
-               /* Common Options */
-               case 'C':
-                       referrals++;
-                       break;
-
-               case 'D':       /* bind distinguished name */
-                       binddn = strdup (optarg);
-                       break;
-
-               case 'd':       /* debugging option */
-                       debug |= atoi (optarg);
-                       break;
-
-               case 'h':       /* ldap host */
-                       ldaphost = strdup (optarg);
-                       break;
-
-               case 'n':       /* don't update entry(s) */
-                       noupdates++;
-                       break;
-
-               case 'p':       /* ldap port */
-                       ldapport = strtol( optarg, NULL, 10 );
-                       break;
+       /* Common Options (including options we don't use) */
+       case 'C':
+               referrals++;
+               break;
+       case 'd':
+           debug |= atoi( optarg );
+           break;
+       case 'D':       /* bind DN */
+               if( binddn != NULL ) {
+                       fprintf( stderr, "%s: -D previously specified\n" );
+                       return EXIT_FAILURE;
+               }
+           binddn = strdup( optarg );
+           break;
+       case 'h':       /* ldap host */
+               if( ldaphost != NULL ) {
+                       fprintf( stderr, "%s: -h previously specified\n" );
+                       return EXIT_FAILURE;
+               }
+           ldaphost = strdup( optarg );
+           break;
+       case 'k':       /* kerberos bind */
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
+               if( version > LDAP_VERSION2 ) {
+                       fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
+                               prog, version );
+                       return EXIT_FAILURE;
+               }
 
-               case 'v':       /* verbose */
-                       verbose++;
-                       break;
+               if( authmethod != -1 ) {
+                       fprintf( stderr, "%s: -k incompatible with previous "
+                               "authentication choice\n", prog );
+                       return EXIT_FAILURE;
+               }
+                       
+               authmethod = LDAP_AUTH_KRBV4;
+#else
+               fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
+               return EXIT_FAILURE;
+#endif
+           break;
+       case 'K':       /* kerberos bind, part one only */
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
+               if( version > LDAP_VERSION2 ) {
+                       fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
+                               prog, version );
+                       return EXIT_FAILURE;
+               }
+               if( authmethod != -1 ) {
+                       fprintf( stderr, "%s: incompatible with previous "
+                               "authentication choice\n", prog );
+                       return EXIT_FAILURE;
+               }
 
-               case 'W':       /* prompt for bind password */
-                       want_bindpw++;
+               authmethod = LDAP_AUTH_KRBV41;
+#else
+               fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
+               return( EXIT_FAILURE );
+#endif
+           break;
+       case 'M':
+               /* enable Manage DSA IT */
+               if( version == LDAP_VERSION2 ) {
+                       fprintf( stderr, "%s: -M incompatible with LDAPv%d\n",
+                               prog, version );
+                       return EXIT_FAILURE;
+               }
+               manageDSAit++;
+               version = LDAP_VERSION3;
+               break;
+       case 'n':       /* print deletes, don't actually do them */
+           ++not;
+           break;
+       case 'O':
+#ifdef HAVE_CYRUS_SASL
+               if( sasl_secprops != NULL ) {
+                       fprintf( stderr, "%s: -O previously specified\n" );
+                       return EXIT_FAILURE;
+               }
+               if( version == LDAP_VERSION2 ) {
+                       fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
+                               prog, version );
+                       return EXIT_FAILURE;
+               }
+               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                       fprintf( stderr, "%s: incompatible previous "
+                               "authentication choice\n", prog );
+                       return EXIT_FAILURE;
+               }
+               authmethod = LDAP_AUTH_SASL;
+               version = LDAP_VERSION3;
+               sasl_secprops = strdup( optarg );
+#else
+               fprintf( stderr, "%s: not compiled with SASL support\n",
+                       prog );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'p':
+               if( ldapport ) {
+                       fprintf( stderr, "%s: -p previously specified\n" );
+                       return EXIT_FAILURE;
+               }
+           ldapport = atoi( optarg );
+           break;
+       case 'P':
+               switch( atoi(optarg) ) {
+               case 2:
+                       if( version == LDAP_VERSION3 ) {
+                               fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
+                                       prog, version );
+                               return EXIT_FAILURE;
+                       }
+                       version = LDAP_VERSION2;
                        break;
-
-               case 'w':       /* bind password */
-                       passwd.bv_val = strdup (optarg);
-                       {
-                               char* p;
-
-                               for( p = optarg; *p == '\0'; p++ ) {
-                                       *p = '*';
-                               }
+               case 3:
+                       if( version == LDAP_VERSION2 ) {
+                               fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
+                                       prog, version );
+                               return EXIT_FAILURE;
                        }
-                       passwd.bv_len = strlen( passwd.bv_val );
+                       version = LDAP_VERSION3;
                        break;
-
-               case 'O':
+               default:
+                       fprintf( stderr, "%s: protocol version should be 2 or 3\n",
+                               prog );
+                       usage( prog );
+                       return( EXIT_FAILURE );
+               } break;
+       case 'Q':
 #ifdef HAVE_CYRUS_SASL
-                       sasl_secprops = strdup( optarg );
-                       authmethod = LDAP_AUTH_SASL;
+               if( version == LDAP_VERSION2 ) {
+                       fprintf( stderr, "%s: -Q incompatible with version %d\n",
+                               prog, version );
+                       return EXIT_FAILURE;
+               }
+               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                       fprintf( stderr, "%s: incompatible previous "
+                               "authentication choice\n",
+                               prog );
+                       return EXIT_FAILURE;
+               }
+               authmethod = LDAP_AUTH_SASL;
+               version = LDAP_VERSION3;
+               sasl_flags = LUTIL_SASL_QUIET;
 #else
-                       fprintf( stderr, "%s was not compiled with SASL support\n",
-                               argv[0] );
-                       return( EXIT_FAILURE );
+               fprintf( stderr, "%s: was not compiled with SASL support\n",
+                       prog );
+               return( EXIT_FAILURE );
 #endif
-                       break;
-               case 'Y':
+       case 'R':
 #ifdef HAVE_CYRUS_SASL
-                       if ( strcasecmp( optarg, "any" ) &&
-                                       strcmp( optarg, "*" ) ) {
-                               sasl_mech = strdup( optarg );
-                       }
-                       authmethod = LDAP_AUTH_SASL;
+               if( sasl_realm != NULL ) {
+                       fprintf( stderr, "%s: -R previously specified\n" );
+                       return EXIT_FAILURE;
+               }
+               if( version == LDAP_VERSION2 ) {
+                       fprintf( stderr, "%s: -R incompatible with version %d\n",
+                               prog, version );
+                       return EXIT_FAILURE;
+               }
+               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                       fprintf( stderr, "%s: incompatible previous "
+                               "authentication choice\n",
+                               prog );
+                       return EXIT_FAILURE;
+               }
+               authmethod = LDAP_AUTH_SASL;
+               version = LDAP_VERSION3;
+               sasl_realm = strdup( optarg );
 #else
-                       fprintf( stderr, "%s was not compiled with SASL "
-                               "support\n", argv[0] );
-                       return( EXIT_FAILURE );
+               fprintf( stderr, "%s: was not compiled with SASL support\n",
+                       prog );
+               return( EXIT_FAILURE );
 #endif
-                       break;
-               case 'U':
+               break;
+       case 'U':
 #ifdef HAVE_CYRUS_SASL
-                       sasl_authc_id = strdup( optarg );
-                       authmethod = LDAP_AUTH_SASL;
+               if( sasl_authc_id != NULL ) {
+                       fprintf( stderr, "%s: -U previously specified\n" );
+                       return EXIT_FAILURE;
+               }
+               if( version == LDAP_VERSION2 ) {
+                       fprintf( stderr, "%s: -U incompatible with version %d\n",
+                               prog, version );
+                       return EXIT_FAILURE;
+               }
+               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                       fprintf( stderr, "%s: incompatible previous "
+                               "authentication choice\n",
+                               prog );
+                       return EXIT_FAILURE;
+               }
+               authmethod = LDAP_AUTH_SASL;
+               version = LDAP_VERSION3;
+               sasl_authc_id = strdup( optarg );
 #else
-                       fprintf( stderr, "%s was not compiled with SASL "
-                               "support\n", argv[0] );
-                       return( EXIT_FAILURE );
+               fprintf( stderr, "%s: was not compiled with SASL support\n",
+                       prog );
+               return( EXIT_FAILURE );
 #endif
-                       break;
-               case 'x':
-                       if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
-                               fprintf( stderr, "%s: incompatible with previous "
-                                       "authentication choice\n", prog );
-                               return EXIT_FAILURE;
+               break;
+       case 'v':       /* verbose mode */
+           verbose++;
+           break;
+       case 'w':       /* password */
+           passwd.bv_val = strdup( optarg );
+               {
+                       char* p;
+
+                       for( p = optarg; *p == '\0'; p++ ) {
+                               *p = '\0';
                        }
-                       authmethod = LDAP_AUTH_SIMPLE;
-                       break;
-               case 'X':
+               }
+               passwd.bv_len = strlen( passwd.bv_val );
+           break;
+       case 'W':
+               want_bindpw++;
+               break;
+       case 'Y':
+#ifdef HAVE_CYRUS_SASL
+               if( sasl_mech != NULL ) {
+                       fprintf( stderr, "%s: -Y previously specified\n" );
+                       return EXIT_FAILURE;
+               }
+               if( version == LDAP_VERSION2 ) {
+                       fprintf( stderr, "%s: -Y incompatible with version %d\n",
+                               prog, version );
+                       return EXIT_FAILURE;
+               }
+               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                       fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
+                       return EXIT_FAILURE;
+               }
+               authmethod = LDAP_AUTH_SASL;
+               version = LDAP_VERSION3;
+               sasl_mech = strdup( optarg );
+#else
+               fprintf( stderr, "%s: was not compiled with SASL support\n",
+                       prog );
+               return( EXIT_FAILURE );
+#endif
+               break;
+       case 'x':
+               if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
+                       fprintf( stderr, "%s: incompatible with previous "
+                               "authentication choice\n", prog );
+                       return EXIT_FAILURE;
+               }
+               authmethod = LDAP_AUTH_SIMPLE;
+               break;
+       case 'X':
 #ifdef HAVE_CYRUS_SASL
-                       sasl_authz_id = strdup( optarg );
-                       authmethod = LDAP_AUTH_SASL;
+               if( sasl_authz_id != NULL ) {
+                       fprintf( stderr, "%s: -X previously specified\n" );
+                       return EXIT_FAILURE;
+               }
+               if( version == LDAP_VERSION2 ) {
+                       fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
+                               prog, version );
+                       return EXIT_FAILURE;
+               }
+               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                       fprintf( stderr, "%s: -X incompatible with "
+                               "authentication choice\n", prog );
+                       return EXIT_FAILURE;
+               }
+               authmethod = LDAP_AUTH_SASL;
+               version = LDAP_VERSION3;
+               sasl_authz_id = strdup( optarg );
 #else
-                       fprintf( stderr, "%s was not compiled with SASL "
-                               "support\n", argv[0] );
-                       return( EXIT_FAILURE );
+               fprintf( stderr, "%s: not compiled with SASL support\n",
+                       prog );
+               return( EXIT_FAILURE );
 #endif
-                       break;
-               case 'Z':
+               break;
+       case 'Z':
 #ifdef HAVE_TLS
-                       use_tls++;
+               if( version == LDAP_VERSION2 ) {
+                       fprintf( stderr, "%s -Z incompatible with version %d\n",
+                               prog, version );
+                       return EXIT_FAILURE;
+               }
+               version = LDAP_VERSION3;
+               use_tls++;
 #else
-                       fprintf( stderr, "%s was not compiled with TLS "
-                               "support\n", argv[0] );
-                       return( EXIT_FAILURE );
+               fprintf( stderr, "%s: not compiled with TLS support\n",
+                       prog );
+               return( EXIT_FAILURE );
 #endif
-                       break;
+               break;
+
 
                default:
                        fprintf( stderr, "%s: unrecongized option -%c\n",
@@ -359,6 +552,8 @@ main( int argc, char *argv[] )
 
        if ( authmethod == LDAP_AUTH_SASL ) {
 #ifdef HAVE_CYRUS_SASL
+               void *defaults;
+
                if( sasl_secprops != NULL ) {
                        rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
                                (void *) sasl_secprops );
@@ -371,8 +566,16 @@ main( int argc, char *argv[] )
                        }
                }
                
+               defaults = lutil_sasl_defaults( ld, sasl_flags,
+                       sasl_mech,
+                       sasl_realm,
+                       sasl_authc_id,
+                       passwd.bv_val,
+                       sasl_authz_id );
+
                rc = ldap_sasl_interactive_bind_s( ld, binddn,
-                       sasl_mech, NULL, NULL, lutil_sasl_interact );
+                       sasl_mech, NULL, NULL,
+                       lutil_sasl_interact, defaults );
 
                if( rc != LDAP_SUCCESS ) {
                        ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
@@ -435,7 +638,7 @@ main( int argc, char *argv[] )
                ber_free( ber, 1 );
        }
 
-       if ( noupdates ) {
+       if ( not ) {
                rc = LDAP_SUCCESS;
                goto skip;
        }
index 4b51feb1f3f407a07e23e4ecb6c432020357b5d3..01f0510584a35ff1415a75ba9e1833920ef3d916 100644 (file)
@@ -68,6 +68,7 @@ usage( const char *s )
 "\t-D binddn\tbind DN\n"
 "\t-f file\t\tread operations from `file'\n"
 "\t-h host\t\tLDAP server\n"
+"\t-I\t\tuse SASL Interactive mode\n"
 "\t-k\t\tuse Kerberos authentication\n"
 "\t-K\t\tlike -k, but do only step 1 of the Kerberos bind\n"
 "\t-M\t\tenable Manage DSA IT control (-MM to make critical)\n"
@@ -75,6 +76,8 @@ usage( const char *s )
 "\t-O secprops\tSASL security properties\n"
 "\t-p port\t\tport on LDAP server\n"
 "\t-P version\tprocotol version (default: 3)\n"
+"\t-Q\t\tuse SASL Quiet mode\n"
+"\t-R realm\tSASL realm\n"
 "\t-U user\t\tSASL authentication identity (username)\n"
 "\t-v\t\trun in verbose mode (diagnostics to standard output)\n"
 "\t-V prefix\tURL prefix for files (default: \"" LDAP_FILE_URI_PREFIX ")\n"
@@ -143,6 +146,8 @@ static char *base = NULL;
 static char    *ldaphost = NULL;
 static int     ldapport = 0;
 #ifdef HAVE_CYRUS_SASL
+static unsigned sasl_flags = LUTIL_SASL_AUTOMATIC;
+static char    *sasl_realm = NULL;
 static char    *sasl_authc_id = NULL;
 static char    *sasl_authz_id = NULL;
 static char    *sasl_mech = NULL;
@@ -174,7 +179,7 @@ main( int argc, char **argv )
     prog = (prog = strrchr(argv[0], *LDAP_DIRSEP)) == NULL ? argv[0] : ++prog;
 
        while (( i = getopt( argc, argv,
-               "Aa:b:f:Ll:S:s:T:tuV:z:" "Cd:D:h:kKMnO:p:P:U:vw:WxX:Y:Z")) != EOF )
+               "Aa:b:f:Ll:S:s:T:tuV:z:" "Cd:D:h:IkKMnO:p:P:QRU:vw:WxX:Y:Z")) != EOF )
        {
        switch( i ) {
        /* Search Options */
@@ -199,6 +204,10 @@ main( int argc, char **argv )
                base = strdup( optarg );
                break;
        case 'f':       /* input file */
+               if( infile != NULL ) {
+                       fprintf( stderr, "%s: -f previously specified\n" );
+                       return EXIT_FAILURE;
+               }
                infile = strdup( optarg );
                break;
        case 'l':       /* time limit */
@@ -248,9 +257,17 @@ main( int argc, char **argv )
            debug |= atoi( optarg );
            break;
        case 'D':       /* bind DN */
+               if( binddn != NULL ) {
+                       fprintf( stderr, "%s: -D previously specified\n" );
+                       return EXIT_FAILURE;
+               }
            binddn = strdup( optarg );
            break;
        case 'h':       /* ldap host */
+               if( ldaphost != NULL ) {
+                       fprintf( stderr, "%s: -h previously specified\n" );
+                       return EXIT_FAILURE;
+               }
            ldaphost = strdup( optarg );
            break;
        case 'k':       /* kerberos bind */
@@ -307,8 +324,12 @@ main( int argc, char **argv )
            break;
        case 'O':
 #ifdef HAVE_CYRUS_SASL
+               if( sasl_secprops != NULL ) {
+                       fprintf( stderr, "%s: -O previously specified\n" );
+                       return EXIT_FAILURE;
+               }
                if( version == LDAP_VERSION2 ) {
-                       fprintf( stderr, "%s -O incompatible with LDAPv%d\n",
+                       fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
                                prog, version );
                        return EXIT_FAILURE;
                }
@@ -317,9 +338,9 @@ main( int argc, char **argv )
                                "authentication choice\n", prog );
                        return EXIT_FAILURE;
                }
-               sasl_secprops = strdup( optarg );
                authmethod = LDAP_AUTH_SASL;
                version = LDAP_VERSION3;
+               sasl_secprops = strdup( optarg );
 #else
                fprintf( stderr, "%s: not compiled with SASL support\n",
                        prog );
@@ -327,6 +348,10 @@ main( int argc, char **argv )
 #endif
                break;
        case 'p':
+               if( ldapport ) {
+                       fprintf( stderr, "%s: -p previously specified\n" );
+                       return EXIT_FAILURE;
+               }
            ldapport = atoi( optarg );
            break;
        case 'P':
@@ -353,8 +378,59 @@ main( int argc, char **argv )
                        usage( prog );
                        return( EXIT_FAILURE );
                } break;
+       case 'Q':
+#ifdef HAVE_CYRUS_SASL
+               if( version == LDAP_VERSION2 ) {
+                       fprintf( stderr, "%s: -Q incompatible with version %d\n",
+                               prog, version );
+                       return EXIT_FAILURE;
+               }
+               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                       fprintf( stderr, "%s: incompatible previous "
+                               "authentication choice\n",
+                               prog );
+                       return EXIT_FAILURE;
+               }
+               authmethod = LDAP_AUTH_SASL;
+               version = LDAP_VERSION3;
+               sasl_flags = LUTIL_SASL_QUIET;
+#else
+               fprintf( stderr, "%s: was not compiled with SASL support\n",
+                       prog );
+               return( EXIT_FAILURE );
+#endif
+       case 'R':
+#ifdef HAVE_CYRUS_SASL
+               if( sasl_realm != NULL ) {
+                       fprintf( stderr, "%s: -R previously specified\n" );
+                       return EXIT_FAILURE;
+               }
+               if( version == LDAP_VERSION2 ) {
+                       fprintf( stderr, "%s: -R incompatible with version %d\n",
+                               prog, version );
+                       return EXIT_FAILURE;
+               }
+               if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
+                       fprintf( stderr, "%s: incompatible previous "
+                               "authentication choice\n",
+                               prog );
+                       return EXIT_FAILURE;
+               }
+               authmethod = LDAP_AUTH_SASL;
+               version = LDAP_VERSION3;
+               sasl_realm = strdup( optarg );
+#else
+               fprintf( stderr, "%s: was not compiled with SASL support\n",
+                       prog );
+               return( EXIT_FAILURE );
+#endif
+               break;
        case 'U':
 #ifdef HAVE_CYRUS_SASL
+               if( sasl_authc_id != NULL ) {
+                       fprintf( stderr, "%s: -U previously specified\n" );
+                       return EXIT_FAILURE;
+               }
                if( version == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -U incompatible with version %d\n",
                                prog, version );
@@ -368,9 +444,7 @@ main( int argc, char **argv )
                }
                authmethod = LDAP_AUTH_SASL;
                version = LDAP_VERSION3;
-
                sasl_authc_id = strdup( optarg );
-               authmethod = LDAP_AUTH_SASL;
 #else
                fprintf( stderr, "%s: was not compiled with SASL support\n",
                        prog );
@@ -386,7 +460,7 @@ main( int argc, char **argv )
                        char* p;
 
                        for( p = optarg; *p == '\0'; p++ ) {
-                               *p = '*';
+                               *p = '\0';
                        }
                }
                passwd.bv_len = strlen( passwd.bv_val );
@@ -396,6 +470,10 @@ main( int argc, char **argv )
                break;
        case 'Y':
 #ifdef HAVE_CYRUS_SASL
+               if( sasl_mech != NULL ) {
+                       fprintf( stderr, "%s: -Y previously specified\n" );
+                       return EXIT_FAILURE;
+               }
                if( version == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -Y incompatible with version %d\n",
                                prog, version );
@@ -405,9 +483,9 @@ main( int argc, char **argv )
                        fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
                        return EXIT_FAILURE;
                }
-
                authmethod = LDAP_AUTH_SASL;
                version = LDAP_VERSION3;
+               sasl_mech = strdup( optarg );
 #else
                fprintf( stderr, "%s: was not compiled with SASL support\n",
                        prog );
@@ -424,6 +502,10 @@ main( int argc, char **argv )
                break;
        case 'X':
 #ifdef HAVE_CYRUS_SASL
+               if( sasl_authz_id != NULL ) {
+                       fprintf( stderr, "%s: -X previously specified\n" );
+                       return EXIT_FAILURE;
+               }
                if( version == LDAP_VERSION2 ) {
                        fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
                                prog, version );
@@ -436,9 +518,7 @@ main( int argc, char **argv )
                }
                authmethod = LDAP_AUTH_SASL;
                version = LDAP_VERSION3;
-
                sasl_authz_id = strdup( optarg );
-               authmethod = LDAP_AUTH_SASL;
 #else
                fprintf( stderr, "%s: not compiled with SASL support\n",
                        prog );
@@ -604,6 +684,8 @@ main( int argc, char **argv )
 
        if ( authmethod == LDAP_AUTH_SASL ) {
 #ifdef HAVE_CYRUS_SASL
+               void *defaults;
+
                if( sasl_secprops != NULL ) {
                        rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
                                (void *) sasl_secprops );
@@ -616,8 +698,16 @@ main( int argc, char **argv )
                        }
                }
                
+               defaults = lutil_sasl_defaults( ld, sasl_flags,
+                       sasl_mech,
+                       sasl_realm,
+                       sasl_authc_id,
+                       passwd.bv_val,
+                       sasl_authz_id );
+
                rc = ldap_sasl_interactive_bind_s( ld, binddn,
-                       sasl_mech, NULL, NULL, lutil_sasl_interact );
+                       sasl_mech, NULL, NULL,
+                       lutil_sasl_interact, defaults );
 
                if( rc != LDAP_SUCCESS ) {
                        ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
index 75322dd8a69a080926dcf02ab27afe6e981a6926..33479405cd833706a69399a2a8327d08a7b66cfb 100644 (file)
@@ -131,13 +131,16 @@ LDAP_BEGIN_DECL
 #define LDAP_OPT_X_TLS_TRY             4
 
 /* OpenLDAP SASL options */
-#define LDAP_OPT_X_SASL_SSF                            0x6100 /* read-only */
-#define LDAP_OPT_X_SASL_SSF_EXTERNAL   0x6101 /* write-only */
-#define LDAP_OPT_X_SASL_SECPROPS               0x6102 /* write-only */
-
-#define LDAP_OPT_X_SASL_SSF_MIN                        0x6103
-#define LDAP_OPT_X_SASL_SSF_MAX                        0x6104
-#define        LDAP_OPT_X_SASL_MAXBUFSIZE              0x6105
+#define LDAP_OPT_X_SASL_MECH                   0x6100
+#define LDAP_OPT_X_SASL_REALM                  0x6101
+#define LDAP_OPT_X_SASL_AUTHCID                        0x6102
+#define LDAP_OPT_X_SASL_AUTHZID                        0x6103
+#define LDAP_OPT_X_SASL_SSF                            0x6104 /* read-only */
+#define LDAP_OPT_X_SASL_SSF_EXTERNAL   0x6105 /* write-only */
+#define LDAP_OPT_X_SASL_SECPROPS               0x6106 /* write-only */
+#define LDAP_OPT_X_SASL_SSF_MIN                        0x6107
+#define LDAP_OPT_X_SASL_SSF_MAX                        0x6108
+#define        LDAP_OPT_X_SASL_MAXBUFSIZE              0x6109
 
 
 /* on/off values */
@@ -695,7 +698,7 @@ ldap_sasl_bind LDAP_P((
 /* V3 SASL Interaction Function Callback Prototype */
 /*     when using Cyrus SASL, interact is pointer to sasl_interact_t */
 typedef int (LDAP_SASL_INTERACT_PROC) LDAP_P((
-       LDAP *ld, void *interact ));
+       LDAP *ld, void* defaults, void *interact ));
 
 LDAP_F( int )
 ldap_sasl_interactive_bind_s LDAP_P((
@@ -704,7 +707,8 @@ ldap_sasl_interactive_bind_s LDAP_P((
        LDAP_CONST char *saslMechanism,
        LDAPControl **serverControls,
        LDAPControl **clientControls,
-       LDAP_SASL_INTERACT_PROC *proc ));
+       LDAP_SASL_INTERACT_PROC *proc,
+       LDAP_CONST void *defaults ));
 
 LDAP_F( int )
 ldap_sasl_bind_s LDAP_P((
index 86da3ae3c3d96e5e78ce29faac729b04ac173128..0c5467c0e5284bdcf18b62060e3fff54cb8624b0 100644 (file)
 
 LDAP_BEGIN_DECL
 
+/*
+ * Automatic (default): use defaults, prompt otherwise
+ * Interactive: prompt always
+ * Quiet: never prompt
+ */
+#define LUTIL_SASL_AUTOMATIC   0U
+#define LUTIL_SASL_INTERACTIVE 1U
+#define LUTIL_SASL_QUIET               2U
+
+LDAP_LUTIL_F( void * )
+lutil_sasl_defaults LDAP_P((
+       LDAP *ld,
+       unsigned flags,
+       char *mech,
+       char *realm,
+       char *authcid,
+       char *passwd,
+       char *authzid ));
+
 LDAP_LUTIL_F( int )
 lutil_sasl_interact LDAP_P((
-       LDAP *ld, void *p ));
+       LDAP *ld, void *defaults, void *p ));
 
 LDAP_END_DECL
 
index 7a34bbe4071912b28e79e9175705afc65eadd8be..c6058fca2a2488bc9e57028229442dda5576f364 100644 (file)
@@ -455,7 +455,8 @@ ldap_int_sasl_bind(
        const char              *mechs,
        LDAPControl             **sctrls,
        LDAPControl             **cctrls,
-       LDAP_SASL_INTERACT_PROC *interact )
+       LDAP_SASL_INTERACT_PROC *interact,
+       void * defaults )
 {
        char *data;
        const char *mech = NULL;
@@ -525,7 +526,7 @@ ldap_int_sasl_bind(
 
                if( saslrc == SASL_INTERACT ) {
                        if( !interact ) break;
-                       rc = (interact)( ld, prompts );
+                       rc = (interact)( ld, defaults, prompts );
                        if( rc != LDAP_SUCCESS ) {
                                break;
                        }
@@ -574,7 +575,7 @@ ldap_int_sasl_bind(
                        if( saslrc == SASL_INTERACT ) {
                                int res;
                                if( !interact ) break;
-                               res = (interact)( ld, prompts );
+                               res = (interact)( ld, defaults, prompts );
                                if( res != LDAP_SUCCESS ) {
                                        break;
                                }
@@ -740,6 +741,23 @@ ldap_int_sasl_get_option( LDAP *ld, int option, void *arg )
                return -1;
 
        switch ( option ) {
+               case LDAP_OPT_X_SASL_MECH: {
+                       *(char **)arg = ld->ld_options.ldo_def_sasl_mech
+                               ? LDAP_STRDUP( ld->ld_options.ldo_def_sasl_mech ) : NULL;
+               } break;
+               case LDAP_OPT_X_SASL_REALM: {
+                       *(char **)arg = ld->ld_options.ldo_def_sasl_realm
+                               ? LDAP_STRDUP( ld->ld_options.ldo_def_sasl_realm ) : NULL;
+               } break;
+               case LDAP_OPT_X_SASL_AUTHCID: {
+                       *(char **)arg = ld->ld_options.ldo_def_sasl_authcid
+                               ? LDAP_STRDUP( ld->ld_options.ldo_def_sasl_authcid ) : NULL;
+               } break;
+               case LDAP_OPT_X_SASL_AUTHZID: {
+                       *(char **)arg = ld->ld_options.ldo_def_sasl_authzid
+                               ? LDAP_STRDUP( ld->ld_options.ldo_def_sasl_authzid ) : NULL;
+               } break;
+
                case LDAP_OPT_X_SASL_SSF: {
                        int sc;
                        sasl_ssf_t      *ssf;
index b7558f75ecef5e2ced51c365231fa116f55eb9a9..164761b6edfa4254a540a7cc4ecc5bb863b8da05 100644 (file)
@@ -69,17 +69,25 @@ static const struct ol_attribute {
        {0, ATTR_BOOL,          "RESTART",              NULL,   LDAP_BOOL_RESTART},
 
 #ifdef HAVE_CYRUS_SASL
-       {0, ATTR_SASL,          "SASL_SECPROPS",NULL,   LDAP_OPT_X_SASL_SECPROPS},
+       {1, ATTR_STRING,        "SASL_MECH",            NULL,
+               offsetof(struct ldapoptions, ldo_def_sasl_mech)},
+       {1, ATTR_STRING,        "SASL_REALM",           NULL,
+               offsetof(struct ldapoptions, ldo_def_sasl_realm)},
+       {1, ATTR_STRING,        "SASL_AUTHCID",         NULL,
+               offsetof(struct ldapoptions, ldo_def_sasl_authcid)},
+       {1, ATTR_STRING,        "SASL_AUTHZID",         NULL,
+               offsetof(struct ldapoptions, ldo_def_sasl_authzid)},
+       {0, ATTR_SASL,          "SASL_SECPROPS",        NULL,   LDAP_OPT_X_SASL_SECPROPS},
 #endif
 
 #ifdef HAVE_TLS
        {0, ATTR_TLS,           "TLS",                  NULL,   LDAP_OPT_X_TLS},
-       {0, ATTR_TLS,           "TLS_CERT",             NULL,   LDAP_OPT_X_TLS_CERTFILE},
-       {0, ATTR_TLS,           "TLS_KEY",              NULL,   LDAP_OPT_X_TLS_KEYFILE},
+       {1, ATTR_TLS,           "TLS_CERT",             NULL,   LDAP_OPT_X_TLS_CERTFILE},
+       {1, ATTR_TLS,           "TLS_KEY",              NULL,   LDAP_OPT_X_TLS_KEYFILE},
        {0, ATTR_TLS,           "TLS_CACERT",   NULL,   LDAP_OPT_X_TLS_CACERTFILE},
        {0, ATTR_TLS,           "TLS_CACERTDIR",NULL,   LDAP_OPT_X_TLS_CACERTDIR},
-       {0, ATTR_TLS,           "TLS_REQCERT",  NULL,   LDAP_OPT_X_TLS_REQUIRE_CERT},
-       {0, ATTR_TLS,           "TLS_RANDFILE", NULL,   LDAP_OPT_X_TLS_RANDOM_FILE},
+       {1, ATTR_TLS,           "TLS_REQCERT",  NULL,   LDAP_OPT_X_TLS_REQUIRE_CERT},
+       {1, ATTR_TLS,           "TLS_RANDFILE", NULL,   LDAP_OPT_X_TLS_RANDOM_FILE},
 #endif
 
        {0, ATTR_NONE,          NULL,           NULL,   0}
@@ -395,10 +403,12 @@ void ldap_int_initialize_global_options( struct ldapoptions *gopts, int *dbglvl
 
        LDAP_BOOL_SET(gopts, LDAP_BOOL_REFERRALS);
 
-#ifdef HAVE_TLS
-       gopts->ldo_tls_ctx = NULL;
-#endif
 #ifdef HAVE_CYRUS_SASL
+       gopts->ldo_def_sasl_mech = NULL;
+       gopts->ldo_def_sasl_realm = NULL;
+       gopts->ldo_def_sasl_authcid = NULL;
+       gopts->ldo_def_sasl_authzid = NULL;
+
        memset( &gopts->ldo_sasl_secprops, '\0', sizeof(gopts->ldo_sasl_secprops) );
 
        gopts->ldo_sasl_secprops.max_ssf = INT_MAX;
@@ -406,6 +416,10 @@ void ldap_int_initialize_global_options( struct ldapoptions *gopts, int *dbglvl
        gopts->ldo_sasl_secprops.security_flags = SASL_SEC_NOPLAINTEXT|SASL_SEC_NOANONYMOUS;
 #endif
 
+#ifdef HAVE_TLS
+       gopts->ldo_tls_ctx = NULL;
+#endif
+
        gopts->ldo_valid = LDAP_INITIALIZED;
 
        return;
@@ -450,6 +464,21 @@ void ldap_int_initialize( struct ldapoptions *gopts, int *dbglvl )
                return;
        }
 
+#ifdef HAVE_CYRUS_SASL
+       {
+               /* set authentication identity to current user name */
+               char *user = getenv("USER");
+
+               if( user == NULL ) user = getenv("USERNAME");
+               if( user == NULL ) user = getenv("LOGNAME");
+
+               if( user != NULL ) {
+                       /* this value is leaked, need at_exit() handler */
+                       gopts->ldo_def_sasl_authcid = LDAP_STRDUP( user );
+               }
+    }
+#endif
+
        openldap_ldap_init_w_sysconf(LDAP_CONF_FILE);
        openldap_ldap_init_w_userconf(LDAP_USERRC_FILE);
 
index 7b196497abfe987cacdb19a030bf5bdc623bb109..51939c37017cca61d80256d8971775a8045a8698 100644 (file)
@@ -125,7 +125,17 @@ struct ldapoptions {
        LDAPURLDesc *ldo_defludp;
        int             ldo_defport;
        char*   ldo_defbase;
-       char*   ldo_defbinddn;  /* simple bind dn */
+       char*   ldo_defbinddn;  /* bind dn */
+
+#ifdef HAVE_CYRUS_SASL
+       char*   ldo_def_sasl_mech;              /* SASL Mechanism(s) */
+       char*   ldo_def_sasl_realm;             /* SASL realm */
+       char*   ldo_def_sasl_authcid;   /* SASL authentication identity */
+       char*   ldo_def_sasl_authzid;   /* SASL authorization identity */
+
+       /* SASL Security Properties */
+       struct sasl_security_properties ldo_sasl_secprops;
+#endif
 
 #ifdef LDAP_CONNECTIONLESS
        int             ldo_cldaptries; /* connectionless search retry count */
@@ -145,9 +155,6 @@ struct ldapoptions {
        /* tls context */
        void            *ldo_tls_ctx;
        int             ldo_tls_mode;
-#endif
-#ifdef HAVE_CYRUS_SASL
-       struct sasl_security_properties ldo_sasl_secprops;
 #endif
        LDAP_BOOLEANS ldo_booleans;     /* boolean options */
 };
@@ -545,9 +552,12 @@ LDAP_F (int) ldap_int_sasl_config LDAP_P(( struct ldapoptions *lo,
        int option, const char *arg ));
 
 LDAP_F (int) ldap_int_sasl_bind LDAP_P((
-       struct ldap *, LDAP_CONST char *,
-       const char *, LDAPControl **, LDAPControl **,
-       LDAP_SASL_INTERACT_PROC *interact ));
+       struct ldap *ld,
+       const char *,
+       const char *,
+       LDAPControl **, LDAPControl **,
+       LDAP_SASL_INTERACT_PROC *interact,
+       void *defaults));
 
 /*
  * in tls.c
index 1e34a73cfebd4e22d96fcecd20f652235eece7b8..4ee3c1b269d56c0f06f89c55153338b4ddec22c4 100644 (file)
@@ -140,10 +140,20 @@ ldap_create( LDAP **ldp )
        ld->ld_valid = LDAP_VALID_SESSION;
 
        /* but not pointers to malloc'ed items */
-       ld->ld_options.ldo_defludp = NULL;
        ld->ld_options.ldo_sctrls = NULL;
        ld->ld_options.ldo_cctrls = NULL;
 
+#ifdef HAVE_CYRUS_SASL
+       ld->ld_options.ldo_def_sasl_mech = gopts->ldo_def_sasl_mech
+               ? LDAP_STRDUP( gopts->ldo_def_sasl_mech ) : NULL;
+       ld->ld_options.ldo_def_sasl_realm = gopts->ldo_def_sasl_realm
+               ? LDAP_STRDUP( gopts->ldo_def_sasl_realm ) : NULL;
+       ld->ld_options.ldo_def_sasl_authcid = gopts->ldo_def_sasl_authcid
+               ? LDAP_STRDUP( gopts->ldo_def_sasl_authcid ) : NULL;
+       ld->ld_options.ldo_def_sasl_authzid = gopts->ldo_def_sasl_authzid
+               ? LDAP_STRDUP( gopts->ldo_def_sasl_authzid ) : NULL;
+#endif
+
        ld->ld_options.ldo_defludp = ldap_url_duplist(gopts->ldo_defludp);
 
        if ( ld->ld_options.ldo_defludp == NULL ) {
index 2660a271aad69bed1424ac6f1f41d1596477a918..c63efd5d0d0ee11f52cacba86e13cf4b1e9da1c0 100644 (file)
@@ -410,7 +410,8 @@ ldap_sasl_interactive_bind_s(
        LDAP_CONST char *mechs,
        LDAPControl **serverControls,
        LDAPControl **clientControls,
-       LDAP_SASL_INTERACT_PROC *interact )
+       LDAP_SASL_INTERACT_PROC *interact,
+       void *defaults )
 {
        int rc;
 
@@ -436,7 +437,8 @@ ldap_sasl_interactive_bind_s(
        }
 
        rc = ldap_int_sasl_bind( ld, dn, mechs,
-               serverControls, clientControls, interact );
+               serverControls, clientControls,
+               interact, defaults );
 
        return rc;
 }
index a005cdf6bc61e3def38a71fb57b26eb999efd4ae..c1636e639ea79fa4ff3d5c2fbfbbdd4be9a85bb3 100644 (file)
 #include <ldap.h>
 #include "lutil_ldap.h"
 
+
+typedef struct lutil_sasl_defaults_s {
+       unsigned flags;
+       char *mech;
+       char *realm;
+       char *authcid;
+       char *passwd;
+       char *authzid;
+} lutilSASLdefaults;
+
+
+void *
+lutil_sasl_defaults(
+       LDAP *ld,
+       unsigned flags,
+       char *mech,
+       char *realm,
+       char *authcid,
+       char *passwd,
+       char *authzid )
+{
+       lutilSASLdefaults *defaults;
+       
+       defaults = ber_memalloc( sizeof( lutilSASLdefaults ) );
+
+       if( defaults == NULL ) return NULL;
+
+       defaults->flags = flags;
+       defaults->mech = mech;
+       defaults->realm = realm;
+       defaults->authcid = authcid;
+       defaults->passwd = passwd;
+       defaults->authzid = authzid;
+
+       if( defaults->mech == NULL ) {
+               ldap_get_option( ld, LDAP_OPT_X_SASL_MECH, &defaults->mech );
+       }
+       if( defaults->realm == NULL ) {
+               ldap_get_option( ld, LDAP_OPT_X_SASL_REALM, &defaults->realm );
+       }
+       if( defaults->authcid == NULL ) {
+               ldap_get_option( ld, LDAP_OPT_X_SASL_AUTHCID, &defaults->authcid );
+       }
+       if( defaults->authzid == NULL ) {
+               ldap_get_option( ld, LDAP_OPT_X_SASL_AUTHZID, &defaults->authzid );
+       }
+
+       return defaults;
+}
+
 static int interaction(
-       sasl_interact_t *interact )
+       sasl_interact_t *interact, lutilSASLdefaults *defaults )
 {
+       unsigned flags = defaults ? defaults->flags : 0;
+       const char *dflt = interact->defresult;
        char input[1024];
 
        int noecho=0;
        int challenge=0;
 
        switch( interact->id ) {
+       case SASL_CB_GETREALM:
+               if( defaults ) dflt = defaults->realm;
+               break;
+       case SASL_CB_AUTHNAME:
+               if( defaults ) dflt = defaults->authcid;
+               break;
+       case SASL_CB_PASS:
+               if( defaults ) dflt = defaults->passwd;
+               noecho = 1;
+               break;
+       case SASL_CB_USER:
+               if( defaults ) dflt = defaults->authzid;
+               break;
        case SASL_CB_NOECHOPROMPT:
                noecho = 1;
                challenge = 1;
@@ -34,22 +99,31 @@ static int interaction(
        case SASL_CB_ECHOPROMPT:
                challenge = 1;
                break;
-       case SASL_CB_PASS:
-               noecho = 1;
-               break;
+       }
+
+       if( dflt && !*dflt ) dflt = NULL;
+
+       if( flags != LUTIL_SASL_INTERACTIVE && dflt ) {
+               goto use_default;
+       }
+
+       if( flags == LUTIL_SASL_QUIET ) {
+               /* don't prompt */
+               return LDAP_OTHER;
        }
 
        if( challenge ) {
                if( interact->challenge ) {
                        fprintf( stderr, "Challenge: %s\n", interact->challenge );
                }
-               if( interact->defresult ) {
-                       fprintf( stderr, "Default Result: %s\n", interact->defresult );
-               }
+       }
+
+       if( dflt ) {
+               fprintf( stderr, "Default: %s\n", dflt );
        }
 
        sprintf( input, "%s: ",
-               interact->prompt ? interact->prompt : "Interaction required" );
+               interact->prompt ? interact->prompt : "Interact" );
 
        if( noecho ) {
                interact->result = (char *) getpassphrase( input );
@@ -88,8 +162,17 @@ static int interaction(
                memset( p, '\0', interact->len );
 
        } else {
+use_default:
                /* must be empty */
-               interact->result = strdup("");
+               interact->result = strdup( (dflt && *dflt) ? dflt : "" );
+               interact->len = interact->result
+                       ? strlen( interact->result ) : 0;
+       }
+
+       if( defaults && defaults->passwd && interact->id == SASL_CB_PASS ) {
+               /* zap password after first use */
+               memset( defaults->passwd, '\0', strlen(defaults->passwd) );
+               defaults->passwd = NULL;
        }
 
        return LDAP_SUCCESS;
@@ -97,6 +180,7 @@ static int interaction(
 
 int lutil_sasl_interact(
        LDAP *ld,
+       void *defaults,
        void *in )
 {
        sasl_interact_t *interact = in;
@@ -104,7 +188,7 @@ int lutil_sasl_interact(
        fputs( "SASL Interaction\n", stderr );
 
        while( interact->id != SASL_CB_LIST_END ) {
-               int rc = interaction( interact );
+               int rc = interaction( interact, defaults );
 
                if( rc )  return rc;
                interact++;
@@ -112,5 +196,4 @@ int lutil_sasl_interact(
        
        return LDAP_SUCCESS;
 }
-
 #endif
index 37c32c4e94a1e41c58e30341831a929c6f7f1269..c433ab63573a9498c6e8e6c97bb92efeb1969128 100644 (file)
@@ -63,7 +63,7 @@ main( int argc, char *argv[] )
                                char* p;
 
                                for( p = optarg; *p == '\0'; p++ ) {
-                                       *p = '*';
+                                       *p = '\0';
                                }
                        }
                        break;