#3 Cyrus-sasl without BerkeleyDB dependency
Closed a year ago by simo. Opened 2 years ago by dbelyavs.
rpms/ dbelyavs/cyrus-sasl no_bdb  into  rawhide

@@ -0,0 +1,411 @@ 

+ diff -Nru cyrus-sasl-2.1.27/tests/runtests.py cyrus-sasl-2.1.27-beldmit/tests/runtests.py

+ --- cyrus-sasl-2.1.27/tests/runtests.py	2020-12-23 14:31:35.564537485 +0100

+ +++ cyrus-sasl-2.1.27-beldmit/tests/runtests.py	2020-12-23 14:30:46.933219377 +0100

+ @@ -313,6 +313,99 @@

+  

+      return err

+  

+ +def setup_plain(testdir):

+ +    """ Create sasldb file """

+ +    sasldbfile = os.path.join(testdir, 'testsasldb.db')

+ +

+ +    sasldbenv = {'SASL_PATH': os.path.join(testdir, '../../plugins/.libs'),

+ +                 'LD_LIBRARY_PATH' : os.path.join(testdir, '../../lib/.libs')}

+ +

+ +    passwdprog = os.path.join(testdir, '../../utils/saslpasswd2')

+ +

+ +    echo = subprocess.Popen(('echo', '1234567'), stdout=subprocess.PIPE)

+ +    subprocess.check_call([

+ +        passwdprog, "-f", sasldbfile, "-c", "test",

+ +        "-u", "host.realm.test", "-p"

+ +        ], stdin=echo.stdout, env=sasldbenv, timeout=5)

+ +

+ +    return (sasldbfile, sasldbenv)

+ +

+ +def plain_test(sasldbfile, sasldbenv):

+ +    try:

+ +        srv = subprocess.Popen(["../tests/t_gssapi_srv", "-P", sasldbfile],

+ +                               stdout=subprocess.PIPE,

+ +                               stderr=subprocess.PIPE, env=sasldbenv)

+ +        srv.stdout.readline() # Wait for srv to say it is ready

+ +        cli = subprocess.Popen(["../tests/t_gssapi_cli", "-P", "1234567"],

+ +                               stdout=subprocess.PIPE,

+ +                               stderr=subprocess.PIPE, env=sasldbenv)

+ +        try:

+ +            cli.wait(timeout=5)

+ +            srv.wait(timeout=5)

+ +        except Exception as e:

+ +            print("Failed on {}".format(e));

+ +            cli.kill()

+ +            srv.kill()

+ +        if cli.returncode != 0 or srv.returncode != 0:

+ +            raise Exception("CLI ({}): {} --> SRV ({}): {}".format(

+ +                cli.returncode, cli.stderr.read().decode('utf-8'),

+ +                srv.returncode, srv.stderr.read().decode('utf-8')))

+ +    except Exception as e:

+ +        print("FAIL: {}".format(e))

+ +        return 1

+ +

+ +    print("PASS: PLAIN CLI({}) SRV({})".format(

+ +        cli.stdout.read().decode('utf-8').strip(),

+ +        srv.stdout.read().decode('utf-8').strip()))

+ +    return 0

+ +

+ +def plain_mismatch_test(sasldbfile, sasldbenv):

+ +    result = "FAIL"

+ +    try:

+ +        srv = subprocess.Popen(["../tests/t_gssapi_srv", "-P", sasldbfile],

+ +                               stdout=subprocess.PIPE,

+ +                               stderr=subprocess.PIPE, env=sasldbenv)

+ +        srv.stdout.readline() # Wait for srv to say it is ready

+ +        bindings = base64.b64encode("CLI CBS".encode('utf-8'))

+ +        cli = subprocess.Popen(["../tests/t_gssapi_cli", "-P", "12345678"],

+ +                               stdout=subprocess.PIPE,

+ +                               stderr=subprocess.PIPE, env=sasldbenv)

+ +        try:

+ +            cli.wait(timeout=5)

+ +            srv.wait(timeout=5)

+ +        except Exception as e:

+ +            print("Failed on {}".format(e));

+ +            cli.kill()

+ +            srv.kill()

+ +        if cli.returncode != 0 or srv.returncode != 0:

+ +            cli_err = cli.stderr.read().decode('utf-8').strip()

+ +            srv_err = srv.stderr.read().decode('utf-8').strip()

+ +            if "authentication failure" in srv_err:

+ +                result = "PASS"

+ +            raise Exception("CLI ({}): {} --> SRV ({}): {}".format(

+ +                cli.returncode, cli_err, srv.returncode, srv_err))

+ +    except Exception as e:

+ +        print("{}: {}".format(result, e))

+ +        return 0

+ +

+ +    print("FAIL: This test should fail [CLI({}) SRV({})]".format(

+ +        cli.stdout.read().decode('utf-8').strip(),

+ +        srv.stdout.read().decode('utf-8').strip()))

+ +    return 1

+ +

+ +def plain_tests(testdir):

+ +    err = 0

+ +    sasldbfile, sasldbenv = setup_plain(testdir)

+ +    #print("DB file: {}, ENV: {}".format(sasldbfile, sasldbenv))

+ +    print('SASLDB PLAIN:')

+ +    print('    ', end='')

+ +    err += plain_test(sasldbfile, sasldbenv)

+ +

+ +    print('SASLDB PLAIN PASSWORD MISMATCH:')

+ +    print('    ', end='')

+ +    err += plain_mismatch_test(sasldbfile, sasldbenv)

+ +

+ +    return err

+  

+  if __name__ == "__main__":

+  

+ @@ -329,5 +422,9 @@

+  

+      err = gssapi_tests(T)

+      if err != 0:

+ -        print('{} test(s) FAILED'.format(err))

+ +        print('{} GSSAPI test(s) FAILED'.format(err))

+ +

+ +    err = plain_tests(T)

+ +    if err != 0:

+ +        print('{} PLAIN test(s) FAILED'.format(err))

+          sys.exit(-1)

+ diff -Nru cyrus-sasl-2.1.27/tests/t_gssapi_cli.c cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_cli.c

+ --- cyrus-sasl-2.1.27/tests/t_gssapi_cli.c	2020-12-23 14:31:35.564537485 +0100

+ +++ cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_cli.c	2021-01-06 11:26:15.460662537 +0100

+ @@ -16,6 +16,8 @@

+  #include <saslplug.h>

+  #include <saslutil.h>

+  

+ +const char *testpass = NULL;

+ +

+  static int setup_socket(void)

+  {

+      struct sockaddr_in addr;

+ @@ -34,9 +36,60 @@

+      return sock;

+  }

+  

+ +static int get_user(void *context __attribute__((unused)),

+ +                  int id,

+ +                  const char **result,

+ +                  unsigned *len)

+ +{

+ +    const char *testuser = "test@host.realm.test";

+ +

+ +    if (! result)

+ +        return SASL_BADPARAM;

+ +

+ +    switch (id) {

+ +    case SASL_CB_USER:

+ +    case SASL_CB_AUTHNAME:

+ +        *result = testuser;

+ +        break;

+ +    default:

+ +        return SASL_BADPARAM;

+ +    }

+ +

+ +    if (len) *len = strlen(*result);

+ +

+ +    return SASL_OK;

+ +}

+ +

+ +static int get_pass(sasl_conn_t *conn __attribute__((unused)),

+ +          void *context __attribute__((unused)),

+ +          int id,

+ +          sasl_secret_t **psecret)

+ +{

+ +    size_t len;

+ +    static sasl_secret_t *x;

+ +

+ +    /* paranoia check */

+ +    if (! conn || ! psecret || id != SASL_CB_PASS)

+ +        return SASL_BADPARAM;

+ +

+ +    len = strlen(testpass);

+ +

+ +    x = (sasl_secret_t *) realloc(x, sizeof(sasl_secret_t) + len);

+ +

+ +    if (!x) {

+ +        return SASL_NOMEM;

+ +    }

+ +

+ +    x->len = len;

+ +    strcpy((char *)x->data, testpass);

+ +

+ +    *psecret = x;

+ +    return SASL_OK;

+ +}

+ +

+  int main(int argc, char *argv[])

+  {

+ -    sasl_callback_t callbacks[2] = {};

+ +    sasl_callback_t callbacks[4] = {};

+      char buf[8192];

+      const char *chosenmech;

+      sasl_conn_t *conn;

+ @@ -49,8 +102,9 @@

+      const char *sasl_mech = "GSSAPI";

+      bool spnego = false;

+      bool zeromaxssf = false;

+ +    bool plain = false;

+  

+ -    while ((c = getopt(argc, argv, "c:zN")) != EOF) {

+ +    while ((c = getopt(argc, argv, "c:zNP:")) != EOF) {

+          switch (c) {

+          case 'c':

+              parse_cb(&cb, cb_buf, 256, optarg);

+ @@ -61,6 +115,10 @@

+          case 'N':

+              spnego = true;

+              break;

+ +        case 'P':

+ +            plain = true;

+ +            testpass = optarg;

+ +            break;

+          default:

+              break;

+          }

+ @@ -73,6 +131,12 @@

+      callbacks[1].id = SASL_CB_LIST_END;

+      callbacks[1].proc = NULL;

+      callbacks[1].context = NULL;

+ +    callbacks[2].id = SASL_CB_LIST_END;

+ +    callbacks[2].proc = NULL;

+ +    callbacks[2].context = NULL;

+ +    callbacks[3].id = SASL_CB_LIST_END;

+ +    callbacks[3].proc = NULL;

+ +    callbacks[3].context = NULL;

+  

+      r = sasl_client_init(callbacks);

+      if (r != SASL_OK) exit(-1);

+ @@ -91,6 +155,16 @@

+          sasl_mech = "GSS-SPNEGO";

+      }

+  

+ +    if (plain) {

+ +        sasl_mech = "PLAIN";

+ +

+ +        callbacks[1].id = SASL_CB_AUTHNAME;

+ +        callbacks[1].proc = (sasl_callback_ft)&get_user;

+ +

+ +        callbacks[2].id = SASL_CB_PASS;

+ +        callbacks[2].proc = (sasl_callback_ft)&get_pass;

+ +    }

+ +

+      if (zeromaxssf) {

+          /* set all security properties to 0 including maxssf */

+          sasl_security_properties_t secprops = { 0 };

+ @@ -99,9 +173,9 @@

+  

+      r = sasl_client_start(conn, sasl_mech, NULL, &data, &len, &chosenmech);

+      if (r != SASL_OK && r != SASL_CONTINUE) {

+ -	saslerr(r, "starting SASL negotiation");

+ -	printf("\n%s\n", sasl_errdetail(conn));

+ -	exit(-1);

+ +        saslerr(r, "starting SASL negotiation");

+ +        printf("\n%s\n", sasl_errdetail(conn));

+ +        exit(-1);

+      }

+  

+      sd = setup_socket();

+ @@ -111,11 +185,11 @@

+          len = 8192;

+          recv_string(sd, buf, &len, false);

+  

+ -	r = sasl_client_step(conn, buf, len, NULL, &data, &len);

+ -	if (r != SASL_OK && r != SASL_CONTINUE) {

+ -	    saslerr(r, "performing SASL negotiation");

+ -	    printf("\n%s\n", sasl_errdetail(conn));

+ -	    exit(-1);

+ +        r = sasl_client_step(conn, buf, len, NULL, &data, &len);

+ +        if (r != SASL_OK && r != SASL_CONTINUE) {

+ +            saslerr(r, "performing SASL negotiation");

+ +            printf("\n%s\n", sasl_errdetail(conn));

+ +            exit(-1);

+          }

+      }

+  

+ diff -Nru cyrus-sasl-2.1.27/tests/t_gssapi_srv.c cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_srv.c

+ --- cyrus-sasl-2.1.27/tests/t_gssapi_srv.c	2020-12-23 14:31:35.565537492 +0100

+ +++ cyrus-sasl-2.1.27-beldmit/tests/t_gssapi_srv.c	2021-01-06 11:27:48.373257373 +0100

+ @@ -1,4 +1,5 @@

+ -/* Copyright (C) Simo Sorce <simo@redhat.com>

+ +/* Copyright (C) Simo Sorce <simo@redhat.com>,

+ + * Dmitry Belyavskiy <dbelyavs@redhat.com>

+   * See COPYING file for License */

+  

+  #include "t_common.h"

+ @@ -15,6 +16,10 @@

+  #include <arpa/inet.h>

+  #include <saslplug.h>

+  

+ +const char *sasldb_path = NULL,

+ +      *auxprop_plugin = "sasldb",

+ +      *pwcheck_method = "auxprop-hashed";

+ +

+  static int setup_socket(void)

+  {

+      struct sockaddr_in addr;

+ @@ -45,9 +50,38 @@

+      return sd;

+  }

+  

+ +static int test_getopt(void *context __attribute__((unused)),

+ +                const char *plugin_name __attribute__((unused)),

+ +                const char *option,

+ +                const char **result,

+ +                unsigned *len)

+ +{

+ +    if (sasldb_path && !strcmp(option, "sasldb_path")) {

+ +        *result = sasldb_path;

+ +        if (len)

+ +            *len = (unsigned) strlen(sasldb_path);

+ +        return SASL_OK;

+ +    }

+ +

+ +    if (sasldb_path && !strcmp(option, "auxprop_plugin")) {

+ +        *result = auxprop_plugin;

+ +        if (len)

+ +            *len = (unsigned) strlen(auxprop_plugin);

+ +        return SASL_OK;

+ +    }

+ +

+ +    if (sasldb_path && !strcmp(option, "pwcheck_method")) {

+ +        *result = pwcheck_method;

+ +        if (len)

+ +            *len = (unsigned) strlen(pwcheck_method);

+ +        return SASL_OK;

+ +    }

+ +    return SASL_FAIL;

+ +}

+ +

+  int main(int argc, char *argv[])

+  {

+ -    sasl_callback_t callbacks[2] = {};

+ +    sasl_callback_t callbacks[3] = {};

+      char buf[8192];

+      sasl_conn_t *conn;

+      const char *data;

+ @@ -59,8 +93,9 @@

+      const char *sasl_mech = "GSSAPI";

+      bool spnego = false;

+      bool zeromaxssf = false;

+ +    bool plain = false;

+  

+ -    while ((c = getopt(argc, argv, "c:zN")) != EOF) {

+ +    while ((c = getopt(argc, argv, "c:zNP:")) != EOF) {

+          switch (c) {

+          case 'c':

+              parse_cb(&cb, cb_buf, 256, optarg);

+ @@ -71,6 +106,10 @@

+          case 'N':

+              spnego = true;

+              break;

+ +        case 'P':

+ +            plain = true;

+ +            sasldb_path = optarg;

+ +            break;

+          default:

+              break;

+          }

+ @@ -81,9 +120,12 @@

+      callbacks[0].id = SASL_CB_GETPATH;

+      callbacks[0].proc = (sasl_callback_ft)&getpath;

+      callbacks[0].context = NULL;

+ -    callbacks[1].id = SASL_CB_LIST_END;

+ -    callbacks[1].proc = NULL;

+ +    callbacks[1].id = SASL_CB_GETOPT;

+ +    callbacks[1].proc = (sasl_callback_ft)&test_getopt;

+      callbacks[1].context = NULL;

+ +    callbacks[2].id = SASL_CB_LIST_END;

+ +    callbacks[2].proc = NULL;

+ +    callbacks[2].context = NULL;

+  

+      r = sasl_server_init(callbacks, "t_gssapi_srv");

+      if (r != SASL_OK) exit(-1);

+ @@ -103,6 +145,10 @@

+          sasl_mech = "GSS-SPNEGO";

+      }

+  

+ +    if (plain) {

+ +        sasl_mech = "PLAIN";

+ +    }

+ +

+      if (zeromaxssf) {

+          /* set all security properties to 0 including maxssf */

+          sasl_security_properties_t secprops = { 0 };

+ @@ -116,9 +162,9 @@

+  

+      r = sasl_server_start(conn, sasl_mech, buf, len, &data, &len);

+      if (r != SASL_OK && r != SASL_CONTINUE) {

+ -	saslerr(r, "starting SASL negotiation");

+ -	printf("\n%s\n", sasl_errdetail(conn));

+ -	exit(-1);

+ +        saslerr(r, "starting SASL negotiation");

+ +        printf("\n%s\n", sasl_errdetail(conn));

+ +        exit(-1);

+      }

+  

+      while (r == SASL_CONTINUE) {

+ @@ -126,12 +172,12 @@

+          len = 8192;

+          recv_string(sd, buf, &len, true);

+  

+ -	r = sasl_server_step(conn, buf, len, &data, &len);

+ -	if (r != SASL_OK && r != SASL_CONTINUE) {

+ -	    saslerr(r, "performing SASL negotiation");

+ -	    printf("\n%s\n", sasl_errdetail(conn));

+ -	    exit(-1);

+ -	}

+ +        r = sasl_server_step(conn, buf, len, &data, &len);

+ +        if (r != SASL_OK && r != SASL_CONTINUE) {

+ +            saslerr(r, "performing SASL negotiation");

+ +            printf("\n%s\n", sasl_errdetail(conn));

+ +            exit(-1);

+ +        }

+      }

+  

+      if (r != SASL_OK) exit(-1);

@@ -0,0 +1,513 @@ 

+ diff -up cyrus-sasl-2.1.27/configure.ac.frombdb cyrus-sasl-2.1.27/configure.ac

+ --- cyrus-sasl-2.1.27/configure.ac.frombdb	2021-01-14 10:25:52.216765830 +0100

+ +++ cyrus-sasl-2.1.27/configure.ac	2021-01-14 10:25:52.224765969 +0100

+ @@ -1091,6 +1091,9 @@ AC_SUBST(SASL_STATIC_SRCS)

+  AC_SUBST(SASL_STATIC_OBJS)

+  AC_SUBST(SASL_STATIC_LIBS)

+  

+ +CYRUS_BERKELEY_DB_STATIC_LIB()

+ +AC_SUBST(BDB_STATIC_LIBADD)

+ +

+  AC_ARG_WITH(plugindir, [  --with-plugindir=DIR    set the directory where plugins will

+                            be found [[LIBDIR/sasl2]] ],

+    plugindir=$withval,

+ diff -up cyrus-sasl-2.1.27/m4/berkdb.m4.frombdb cyrus-sasl-2.1.27/m4/berkdb.m4

+ --- cyrus-sasl-2.1.27/m4/berkdb.m4.frombdb	2016-01-29 18:35:35.000000000 +0100

+ +++ cyrus-sasl-2.1.27/m4/berkdb.m4	2021-01-14 10:25:52.224765969 +0100

+ @@ -286,3 +286,25 @@ AC_DEFUN([CYRUS_BERKELEY_DB_CHK],

+  

+  	CPPFLAGS=$cmu_save_CPPFLAGS

+  ])

+ +

+ +AC_DEFUN([CYRUS_BERKELEY_DB_STATIC_LIB],

+ +[

+ +	BDB_SAVE_LDFLAGS=$LDFLAGS

+ +

+ +	saved_LIBS=$LIBS

+ +	    for dbname in /usr/lib/libdb-5.3.a \

+ +	        /usr/lib64/libdb-5.3.a

+ +	      do

+ +	    LIBS="$saved_LIBS $dbname -lpthread"

+ +	    AC_TRY_LINK([#include <stdio.h>

+ +#include <db.h>],

+ +	    [db_create(NULL, NULL, 0);],

+ +	    BDB_STATIC_LIBADD="$dbname -lpthread"; dblib="berkeley";

+ +            dblib="no")

+ +	    if test "$dblib" = "berkeley"; then break; fi

+ +          done

+ +	LIBS=$saved_LIBS

+ +

+ +	LDFLAGS=$BDB_SAVE_LDFLAGS

+ +    	BDB_STATIC_LIBADD="$dbname -lpthread"

+ +])

+ diff -up cyrus-sasl-2.1.27/m4/sasldb.m4.frombdb cyrus-sasl-2.1.27/m4/sasldb.m4

+ --- cyrus-sasl-2.1.27/m4/sasldb.m4.frombdb	2017-07-13 20:45:19.000000000 +0200

+ +++ cyrus-sasl-2.1.27/m4/sasldb.m4	2021-01-14 10:25:52.224765969 +0100

+ @@ -111,7 +111,7 @@ AC_MSG_RESULT($dblib)

+  SASL_DB_BACKEND="db_${dblib}.lo"

+  SASL_DB_BACKEND_STATIC="db_${dblib}.o allockey.o"

+  SASL_DB_BACKEND_STATIC_SRCS="\$(top_srcdir)/sasldb/db_${dblib}.c \$(top_srcdir)/sasldb/allockey.c"

+ -SASL_DB_UTILS="saslpasswd2 sasldblistusers2"

+ +SASL_DB_UTILS="bdb2current saslpasswd2 sasldblistusers2"

+  SASL_DB_MANS="saslpasswd2.8 sasldblistusers2.8"

+  

+  case "$dblib" in

+ diff -up cyrus-sasl-2.1.27/utils/bdb2current.8.frombdb cyrus-sasl-2.1.27/utils/bdb2current.8

+ --- cyrus-sasl-2.1.27/utils/bdb2current.8.frombdb	2021-01-14 11:01:19.535069703 +0100

+ +++ cyrus-sasl-2.1.27/utils/bdb2current.8	2021-01-14 11:01:07.320030478 +0100

+ @@ -0,0 +1,156 @@

+ +.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40)

+ +.\"

+ +.\" Standard preamble:

+ +.\" ========================================================================

+ +.de Sp \" Vertical space (when we can't use .PP)

+ +.if t .sp .5v

+ +.if n .sp

+ +..

+ +.de Vb \" Begin verbatim text

+ +.ft CW

+ +.nf

+ +.ne \\$1

+ +..

+ +.de Ve \" End verbatim text

+ +.ft R

+ +.fi

+ +..

+ +.\" Set up some character translations and predefined strings.  \*(-- will

+ +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left

+ +.\" double quote, and \*(R" will give a right double quote.  \*(C+ will

+ +.\" give a nicer C++.  Capital omega is used to do unbreakable dashes and

+ +.\" therefore won't be available.  \*(C` and \*(C' expand to `' in nroff,

+ +.\" nothing in troff, for use with C<>.

+ +.tr \(*W-

+ +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'

+ +.ie n \{\

+ +.    ds -- \(*W-

+ +.    ds PI pi

+ +.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch

+ +.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch

+ +.    ds L" ""

+ +.    ds R" ""

+ +.    ds C` ""

+ +.    ds C' ""

+ +'br\}

+ +.el\{\

+ +.    ds -- \|\(em\|

+ +.    ds PI \(*p

+ +.    ds L" ``

+ +.    ds R" ''

+ +.    ds C`

+ +.    ds C'

+ +'br\}

+ +.\"

+ +.\" Escape single quotes in literal strings from groff's Unicode transform.

+ +.ie \n(.g .ds Aq \(aq

+ +.el       .ds Aq '

+ +.\"

+ +.\" If the F register is >0, we'll generate index entries on stderr for

+ +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index

+ +.\" entries marked with X<> in POD.  Of course, you'll have to process the

+ +.\" output yourself in some meaningful fashion.

+ +.\"

+ +.\" Avoid warning from groff about undefined register 'F'.

+ +.de IX

+ +..

+ +.nr rF 0

+ +.if \n(.g .if rF .nr rF 1

+ +.if (\n(rF:(\n(.g==0)) \{\

+ +.    if \nF \{\

+ +.        de IX

+ +.        tm Index:\\$1\t\\n%\t"\\$2"

+ +..

+ +.        if !\nF==2 \{\

+ +.            nr % 0

+ +.            nr F 2

+ +.        \}

+ +.    \}

+ +.\}

+ +.rr rF

+ +.\"

+ +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).

+ +.\" Fear.  Run.  Save yourself.  No user-serviceable parts.

+ +.    \" fudge factors for nroff and troff

+ +.if n \{\

+ +.    ds #H 0

+ +.    ds #V .8m

+ +.    ds #F .3m

+ +.    ds #[ \f1

+ +.    ds #] \fP

+ +.\}

+ +.if t \{\

+ +.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)

+ +.    ds #V .6m

+ +.    ds #F 0

+ +.    ds #[ \&

+ +.    ds #] \&

+ +.\}

+ +.    \" simple accents for nroff and troff

+ +.if n \{\

+ +.    ds ' \&

+ +.    ds ` \&

+ +.    ds ^ \&

+ +.    ds , \&

+ +.    ds ~ ~

+ +.    ds /

+ +.\}

+ +.if t \{\

+ +.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"

+ +.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'

+ +.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'

+ +.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'

+ +.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'

+ +.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'

+ +.\}

+ +.    \" troff and (daisy-wheel) nroff accents

+ +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'

+ +.ds 8 \h'\*(#H'\(*b\h'-\*(#H'

+ +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]

+ +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'

+ +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'

+ +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]

+ +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]

+ +.ds ae a\h'-(\w'a'u*4/10)'e

+ +.ds Ae A\h'-(\w'A'u*4/10)'E

+ +.    \" corrections for vroff

+ +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'

+ +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'

+ +.    \" for low resolution devices (crt and lpr)

+ +.if \n(.H>23 .if \n(.V>19 \

+ +\{\

+ +.    ds : e

+ +.    ds 8 ss

+ +.    ds o a

+ +.    ds d- d\h'-1'\(ga

+ +.    ds D- D\h'-1'\(hy

+ +.    ds th \o'bp'

+ +.    ds Th \o'LP'

+ +.    ds ae ae

+ +.    ds Ae AE

+ +.\}

+ +.rm #[ #] #H #V #F C

+ +.\" ========================================================================

+ +.\"

+ +.IX Title "BDB2CURRENT 1"

+ +.TH BDB2CURRENT 1 "2021-01-14" "perl v5.30.3" "User Contributed Perl Documentation"

+ +.\" For nroff, turn off justification.  Always turn off hyphenation; it makes

+ +.\" way too many mistakes in technical documents.

+ +.if n .ad l

+ +.nh

+ +.SH "NAME"

+ +bdb2current \- command\-line utility converting the SASLDB database from

+ +BerkeleyDB to the database format currently used bys sasldb.

+ +.SH "SYNOPSIS"

+ +.IX Header "SYNOPSIS"

+ +\&\fBbdb2current\fR <sasldb path> <new_path>

+ +.SH "DESCRIPTION"

+ +.IX Header "DESCRIPTION"

+ +bdb2current converts the current sasldb database from BerkeleyDB format to the

+ +currently used database format. It is \fB\s-1STRONGLY RECOMMENDED\s0\fR to make a backup

+ +of the current database before the conversion.

+ +.SH "SEE ALSO"

+ +.IX Header "SEE ALSO"

+ +\&\fBsaslpasswd2\fR\|(8)

+ +.PP

+ +rfc4422 \- Simple Authentication and Security Layer (\s-1SASL\s0)

+ diff -up cyrus-sasl-2.1.27/utils/bdb2current.c.frombdb cyrus-sasl-2.1.27/utils/bdb2current.c

+ --- cyrus-sasl-2.1.27/utils/bdb2current.c.frombdb	2021-01-14 10:25:52.224765969 +0100

+ +++ cyrus-sasl-2.1.27/utils/bdb2current.c	2021-01-14 10:25:52.224765969 +0100

+ @@ -0,0 +1,266 @@

+ +#include <config.h>

+ +

+ +#include <stdio.h>

+ +#include <stdlib.h>

+ +

+ +#include <sasl.h>

+ +#include <saslplug.h>

+ +#include "../sasldb/sasldb.h"

+ +

+ +/* Cheating to make the utils work out right */

+ +extern const sasl_utils_t *sasl_global_utils;

+ +sasl_conn_t *globalconn;

+ +

+ +typedef void *listcb_t(const char *, const char *, const char *,

+ +		       const char *, unsigned);

+ +

+ +void listusers_cb(const char *authid, const char *realm,

+ +		  const char *propName, const char *secret,

+ +		  unsigned seclen)

+ +{

+ +    if (!authid || !propName || !realm) {

+ +	fprintf(stderr,"userlist callback has bad param");

+ +	return;

+ +    }

+ +

+ +    /* the entries that just say the mechanism exists */

+ +    if (strlen(authid)==0) return;

+ +

+ +    printf("Converting: %s@%s (%s)...",authid,realm,propName);

+ +

+ +    _sasldb_putdata(sasl_global_utils, globalconn,

+ +		    authid, realm, propName,

+ +		    secret, seclen);

+ +

+ +    printf("ok\n");

+ +}

+ +

+ +/*

+ + * List all users in database

+ + */

+ +

+ +#include <db.h>

+ +

+ +#define DB_VERSION_FULL ((DB_VERSION_MAJOR << 24) | (DB_VERSION_MINOR << 16) | DB_VERSION_PATCH)

+ +/*

+ + * Open the database

+ + *

+ + */

+ +static int berkeleydb_open(const char *path,DB **mbdb)

+ +{

+ +    int ret;

+ +

+ +#if DB_VERSION_FULL < 0x03000000

+ +    ret = db_open(path, DB_HASH, DB_CREATE, 0664, NULL, NULL, mbdb);

+ +#else /* DB_VERSION_FULL < 0x03000000 */

+ +    ret = db_create(mbdb, NULL, 0);

+ +    if (ret == 0 && *mbdb != NULL)

+ +    {

+ +#if DB_VERSION_FULL >= 0x04010000

+ +	ret = (*mbdb)->open(*mbdb, NULL, path, NULL, DB_HASH, DB_CREATE, 0664);

+ +#else

+ +	ret = (*mbdb)->open(*mbdb, path, NULL, DB_HASH, DB_CREATE, 0664);

+ +#endif

+ +	if (ret != 0)

+ +	{

+ +	    (void) (*mbdb)->close(*mbdb, 0);

+ +	    *mbdb = NULL;

+ +	}

+ +    }

+ +#endif /* DB_VERSION_FULL < 0x03000000 */

+ +

+ +    if (ret != 0) {

+ +	fprintf(stderr,"Error opening password file %s\n", path);

+ +	return SASL_FAIL;

+ +    }

+ +

+ +    return SASL_OK;

+ +}

+ +

+ +/*

+ + * Close the database

+ + *

+ + */

+ +

+ +static void berkeleydb_close(DB *mbdb)

+ +{

+ +    int ret;

+ +    

+ +    ret = mbdb->close(mbdb, 0);

+ +    if (ret!=0) {

+ +	fprintf(stderr,"error closing sasldb: %s",

+ +		db_strerror(ret));

+ +    }

+ +}

+ +

+ +int listusers(const char *path, listcb_t *cb)

+ +{

+ +    int result;

+ +    DB *mbdb = NULL;

+ +    DBC *cursor;

+ +    DBT key, data;

+ +

+ +    /* open the db */

+ +    result=berkeleydb_open(path, &mbdb);

+ +    if (result!=SASL_OK) goto cleanup;

+ +

+ +    /* make cursor */

+ +#if DB_VERSION_FULL < 0x03060000

+ +    result = mbdb->cursor(mbdb, NULL,&cursor); 

+ +#else

+ +    result = mbdb->cursor(mbdb, NULL,&cursor, 0); 

+ +#endif /* DB_VERSION_FULL < 0x03060000 */

+ +

+ +    if (result!=0) {

+ +	fprintf(stderr,"Making cursor failure: %s\n",db_strerror(result));

+ +      result = SASL_FAIL;

+ +      goto cleanup;

+ +    }

+ +

+ +    memset(&key,0, sizeof(key));

+ +    memset(&data,0,sizeof(data));

+ +

+ +    /* loop thru */

+ +    result = cursor->c_get(cursor, &key, &data,

+ +			   DB_FIRST);

+ +

+ +    while (result != DB_NOTFOUND)

+ +    {

+ +	char *authid;

+ +	char *realm;

+ +	char *tmp;

+ +	unsigned int len;

+ +	char prop[1024];

+ +	int numnulls = 0;

+ +	unsigned int lup;

+ +

+ +	/* make sure there are exactly 2 null's */

+ +	for (lup=0;lup<key.size;lup++)

+ +	    if (((char *)key.data)[lup]=='\0')

+ +		numnulls++;

+ +

+ +	if (numnulls != 2) {

+ +	    fprintf(stderr,"warning: probable database corruption\n");

+ +	    result = cursor->c_get(cursor, &key, &data, DB_NEXT);

+ +	    continue;

+ +	}

+ +

+ +	authid = key.data;

+ +	realm  = authid + strlen(authid)+1;

+ +	tmp    = realm + strlen(realm)+1;

+ +	len = key.size - (tmp - authid);

+ +

+ +	/* make sure we have enough space of prop */

+ +	if (len >=sizeof(prop)) {

+ +	    fprintf(stderr,"warning: absurdly long prop name\n");

+ +	    result = cursor->c_get(cursor, &key, &data, DB_NEXT);

+ +	    continue;

+ +	}

+ +

+ +	memcpy(prop, tmp, key.size - (tmp - ((char *)key.data)));

+ +	prop[key.size - (tmp - ((char *)key.data))] = '\0';

+ +

+ +	if (*authid) {

+ +	    /* don't check return values */

+ +	    cb(authid,realm,prop,data.data,data.size);

+ +	}

+ +

+ +	result = cursor->c_get(cursor, &key, &data, DB_NEXT);

+ +    }

+ +

+ +    if (result != DB_NOTFOUND) {

+ +	fprintf(stderr,"failure: %s\n",db_strerror(result));

+ +	result = SASL_FAIL;

+ +	goto cleanup;

+ +    }

+ +

+ +    result = cursor->c_close(cursor);

+ +    if (result != 0) {

+ +        result = SASL_FAIL;

+ +        goto cleanup;

+ +    }

+ +

+ +    result = SASL_OK;

+ +

+ + cleanup:

+ +

+ +    if (mbdb != NULL) berkeleydb_close(mbdb);

+ +    return result;

+ +}

+ +

+ +

+ +char *db = NULL, *db_new=NULL;

+ +

+ +int good_getopt(void *context __attribute__((unused)), 

+ +		const char *plugin_name __attribute__((unused)), 

+ +		const char *option,

+ +		const char **result,

+ +		unsigned *len)

+ +{

+ +    if (db_new && !strcmp(option, "sasldb_path")) {

+ +	*result = db_new;

+ +	if (len)

+ +	    *len = strlen(db_new);

+ +	return SASL_OK;

+ +    }

+ +

+ +    return SASL_FAIL;

+ +}

+ +

+ +static struct sasl_callback goodsasl_cb[] = {

+ +    { SASL_CB_GETOPT, (int (*)(void))&good_getopt, NULL },

+ +    { SASL_CB_LIST_END, NULL, NULL }

+ +};

+ +

+ +int main(int argc, char **argv)

+ +{

+ +    int result;

+ +

+ +    if (argc != 3) {

+ +	printf("Usage: bdb2current old_sasldb new_sasldb\n");

+ +	return 1;

+ +    }

+ +

+ +    db = argv[1];

+ +    db_new = argv[2];

+ +

+ +    result = sasl_server_init(goodsasl_cb, "dbconverter");

+ +    if (result != SASL_OK) {

+ +	printf("couldn't init saslv2\n");

+ +	return 1;

+ +    }

+ +

+ +    result = sasl_server_new("sasldb",

+ +			     "localhost",

+ +			     NULL,

+ +			     NULL,

+ +			     NULL,

+ +			     NULL,

+ +			     0,

+ +			     &globalconn);

+ +    if (result != SASL_OK) {

+ +	printf("couldn't create globalconn\n");

+ +	return 1;

+ +    }

+ +

+ +    if(_sasl_check_db(sasl_global_utils,globalconn) != SASL_OK) {

+ +	printf("target DB %s is not OK\n", db_new);

+ +	return 1;

+ +    }

+ +

+ +    printf("\nThis program will take the sasldb file specified on the\n"

+ +           "command line and convert it to a new sasldb specified\n"

+ +           "on the command line. It is STRONGLY RECOMMENDED that you\n"

+ +           "backup sasldb before allowing this program to run\n\n"

+ +	   "We are going to convert %s and our output will be in %s\n\n"

+ +           "Press return to continue\n", db, db_new);

+ +

+ +    getchar();

+ +

+ +    listusers(db, (listcb_t *) &listusers_cb);

+ +

+ +    sasl_dispose(&globalconn);

+ +    sasl_done();

+ +

+ +    exit(0);

+ +}

+ diff -up cyrus-sasl-2.1.27/utils/Makefile.am.frombdb cyrus-sasl-2.1.27/utils/Makefile.am

+ --- cyrus-sasl-2.1.27/utils/Makefile.am.frombdb	2018-10-05 16:40:16.000000000 +0200

+ +++ cyrus-sasl-2.1.27/utils/Makefile.am	2021-01-14 11:03:26.847478498 +0100

+ @@ -45,7 +45,7 @@

+  all_sasl_libs = ../lib/libsasl2.la $(SASL_DB_LIB) $(LIB_SOCKET)

+  all_sasl_static_libs = ../lib/.libs/libsasl2.a $(SASL_DB_LIB) $(LIB_SOCKET) $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(SASL_KRB_LIB) $(LIB_DES) $(PLAIN_LIBS) $(SRP_LIBS) $(LIB_MYSQL) $(LIB_PGSQL) $(LIB_SQLITE)

+  

+ -sbin_PROGRAMS = @SASL_DB_UTILS@ @SMTPTEST_PROGRAM@ pluginviewer

+ +sbin_PROGRAMS = @SASL_DB_UTILS@ @SMTPTEST_PROGRAM@ pluginviewer bdb2current

+  EXTRA_PROGRAMS = saslpasswd2 sasldblistusers2 testsuite testsuitestatic smtptest pluginviewer

+  

+  noinst_PROGRAMS = dbconverter-2

+ @@ -53,7 +53,7 @@ noinst_PROGRAMS = dbconverter-2

+  if NO_SASL_DB_MANS

+  man_MANS = 

+  else

+ -man_MANS = saslpasswd2.8 sasldblistusers2.8 pluginviewer.8

+ +man_MANS = saslpasswd2.8 sasldblistusers2.8 pluginviewer.8 bdb2current.8

+  endif

+  

+  saslpasswd2_LDADD = ../sasldb/libsasldb.la $(all_sasl_libs)

+ @@ -63,6 +63,7 @@ sasldblistusers2_SOURCES = sasldblistuse

+  dbconverter_2_LDADD = ../sasldb/libsasldb.la $(all_sasl_libs)

+  pluginviewer_LDADD = $(all_sasl_libs)

+  pluginviewer_SOURCES = pluginviewer.c

+ +bdb2current_LDADD = ../sasldb/libsasldb.la @BDB_STATIC_LIBADD@ $(all_sasl_libs)

+  

+  testsuite_LDADD = $(all_sasl_libs) @DMALLOC_LIBS@

+  

file modified
+23 -5
@@ -5,10 +5,12 @@ 

  %global _plugindir2 %{_libdir}/sasl2

  %global bootstrap_cyrus_sasl 0

  

+ %global gdbm_db_file /etc/sasl2/sasldb2

+ 

  Summary: The Cyrus SASL library

  Name: cyrus-sasl

  Version: 2.1.27

- Release: 6%{?dist}

+ Release: 7%{?dist}

  License: BSD with advertising

  URL: https://www.cyrusimap.org/sasl/

  
@@ -38,17 +40,20 @@ 

  Patch102: cyrus-sasl-2.1.27-Add-Channel-Binding-support-for-GSSAPI-GSS-SPNEGO.patch

  Patch103: cyrus-sasl-2.1.27-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO.patch

  Patch104: cyrus-sasl-2.1.27-Emit-debug-log-only-in-case-of-errors.patch

+ # Upstream PR: https://github.com/cyrusimap/cyrus-sasl/pull/635

+ Patch105: cyrus-sasl-2.1.27-Add-basic-test-plain-auth.patch

+ Patch106: cyrus-sasl-2.1.27-Migration-from-BerkeleyDB.patch

  

  BuildRequires: autoconf, automake, libtool, gdbm-devel, groff

  BuildRequires: krb5-devel >= 1.2.2, openssl-devel, pam-devel, pkgconfig

  BuildRequires: mariadb-connector-c-devel, libpq-devel, zlib-devel

- BuildRequires: libdb-devel

  %if ! %{bootstrap_cyrus_sasl}

  BuildRequires: openldap-devel

  %endif

+ #build reqs for migration from BerkeleyDB

+ BuildRequires: libdb-devel-static

  #build reqs for make check

  BuildRequires: python3 nss_wrapper socket_wrapper krb5-server

- BuildRequires: make

  %{?systemd_requires}

  Requires(pre): /usr/sbin/useradd /usr/sbin/groupadd

  Requires(postun): /usr/sbin/userdel /usr/sbin/groupdel
@@ -165,6 +170,8 @@ 

  %patch102 -p1 -b .gssapi_cbs

  %patch103 -p1 -b .maxssf0

  %patch104 -p1 -b .nolog

+ %patch105 -p1 -b .plaintests

+ %patch106 -p1 -b .frombdb

  

  %build

  # reconfigure
@@ -224,8 +231,8 @@ 

          --enable-gssapi${krb5_prefix:+=${krb5_prefix}} \

          --with-gss_impl=mit \

          --with-rc4 \

-         --with-dblib=berkeley \

-         --with-bdb=db \

+         --with-dblib=gdbm \

+         --with-dbpath=%{gdbm_db_file} \

          --with-saslauthd=/run/saslauthd --without-pwcheck \

  %if ! %{bootstrap_cyrus_sasl}

          --with-ldap \
@@ -306,6 +313,11 @@ 

  %post

  %systemd_post saslauthd.service

  

+ %post lib

+ if [ -e /etc/sasldb2 ]; then

+ %{_sbindir}/bdb2current /etc/sasldb2 %{gdbm_db_file}

+ fi

+ 

  %preun

  %systemd_preun saslauthd.service

  
@@ -334,6 +346,7 @@ 

  %{_plugindir2}/*sasldb*.so*

  %{_sbindir}/saslpasswd2

  %{_sbindir}/sasldblistusers2

+ %{_sbindir}/bdb2current

  

  %files plain

  %{_plugindir2}/*plain*.so*
@@ -373,6 +386,11 @@ 

  %{_sbindir}/sasl2-shared-mechlist

  

  %changelog

+ * Wed Jan 13 2021 Dmitry Belyavskiy - 2.1.27-7

+ - Set default sasldb database to GDBM instead of BerkeleyDB

+ - Add the migration tool from BerkeleyDB

+ - Add some PLAIN auth tests

+ 

  * Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.27-6

  - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild

  

  • Switched from BerkeleyDB to gdbm
  • A migration tool is provided
  • Some PLAIN mechanism tests are added

The code looks good to me.
Should we add an upgrade scriplet to try to convert the default saslauthdb if one is present on the system ?

I think we also want a README or a man page for the conversion tool to point people that may have sasldbs in non-standard location so they know what they should do (provide a workflow example with the commands to run in order).

I don't think we need a scriptlet but I agree about the README/man page. Will do.

rebased onto a318114

2 years ago

I've added the necessary man page (minimalistic).

rebased onto b78a6a0

2 years ago

This was merged directly a year ago, closing

Pull-Request has been closed by simo

a year ago