diff --git a/ChangeLog b/ChangeLog index e19a758a..208138e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,11 @@ 1/12/2015 Oleg Moskalenko Version 4.4.1.1 'Ardee West': - https admin server; - - SSLv2 support removed; + - SSLv2 support removed (security concern fixed); - The server-side short-term credentials mechanism support removed; - OpenSSL 1.1.0 supported; + - shared secrets fixed in MongoDB: multiple secrets per realm allowed; + - shared secrets admin fixed in Redis; 12/24/2014 Oleg Moskalenko Version 4.3.3.1 'Tolomei': diff --git a/examples/var/db/turndb b/examples/var/db/turndb index f2a2cb5e..6689f169 100644 Binary files a/examples/var/db/turndb and b/examples/var/db/turndb differ diff --git a/src/apps/relay/dbdrivers/dbd_mongo.c b/src/apps/relay/dbdrivers/dbd_mongo.c index ce9772ca..d8ae1a4c 100644 --- a/src/apps/relay/dbdrivers/dbd_mongo.c +++ b/src/apps/relay/dbdrivers/dbd_mongo.c @@ -583,47 +583,76 @@ static int mongo_list_oauth_keys(void) { return ret; } -static int mongo_show_secret(u08bits *realm) { - mongoc_collection_t * collection = mongo_get_collection("turn_secret"); +static int mongo_list_secrets(u08bits *realm, secrets_list_t *secrets, secrets_list_t *realms) +{ + mongoc_collection_t * collection = mongo_get_collection("turn_secret"); + + u08bits realm0[STUN_MAX_REALM_SIZE+1] = "\0"; + if(!realm) realm=realm0; if(!collection) - return -1; + return -1; - bson_t query; - bson_init(&query); - BSON_APPEND_UTF8(&query, "realm", (const char *)realm); + bson_t query, child; + bson_init(&query); + bson_append_document_begin(&query, "$orderby", -1, &child); + bson_append_int32(&child, "realm", -1, 1); + bson_append_int32(&child, "value", -1, 1); + bson_append_document_end(&query, &child); + bson_append_document_begin(&query, "$query", -1, &child); + if (realm && realm[0]) { + BSON_APPEND_UTF8(&child, "realm", (const char *)realm); + } + bson_append_document_end(&query, &child); - bson_t fields; - bson_init(&fields); - BSON_APPEND_INT32(&fields, "value", 1); + bson_t fields; + bson_init(&fields); + BSON_APPEND_INT32(&fields, "value", 1); + BSON_APPEND_INT32(&fields, "realm", 1); - mongoc_cursor_t * cursor; - cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, &fields, NULL); + mongoc_cursor_t * cursor; + cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, &fields, NULL); - int ret = -1; + int ret = -1; - if (!cursor) { + if (!cursor) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'turn_secret'\n"); - } else { - const bson_t * item; - uint32_t length; - bson_iter_t iter; - const char * value; - while (mongoc_cursor_next(cursor, &item)) { - if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "value") && BSON_ITER_HOLDS_UTF8(&iter)) { - value = bson_iter_utf8(&iter, &length); - if (length) { - printf("%s\n", value); - } - } - } - mongoc_cursor_destroy(cursor); - ret = 0; - } - mongoc_collection_destroy(collection); - bson_destroy(&query); - bson_destroy(&fields); - return ret; + } else { + const bson_t * item; + uint32_t length; + bson_iter_t iter; + bson_iter_t iter_realm; + const char * value; + while (mongoc_cursor_next(cursor, &item)) { + if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "value") && BSON_ITER_HOLDS_UTF8(&iter)) { + value = bson_iter_utf8(&iter, &length); + if (length) { + const char *rval = ""; + if (bson_iter_init(&iter_realm, item) && bson_iter_find(&iter_realm, "realm") && BSON_ITER_HOLDS_UTF8(&iter_realm)) { + rval = bson_iter_utf8(&iter_realm, &length); + } + if(secrets) { + add_to_secrets_list(secrets,value); + if(realms) { + if(rval && *rval) { + add_to_secrets_list(realms,rval); + } else { + add_to_secrets_list(realms,(char*)realm); + } + } + } else { + printf("%s[%s]\n", value, rval); + } + } + } + } + mongoc_cursor_destroy(cursor); + ret = 0; + } + mongoc_collection_destroy(collection); + bson_destroy(&query); + bson_destroy(&fields); + return ret; } static int mongo_del_secret(u08bits *secret, u08bits *realm) { @@ -1277,7 +1306,7 @@ static const turn_dbdriver_t driver = { &mongo_set_user_key, &mongo_del_user, &mongo_list_users, - &mongo_show_secret, + &mongo_list_secrets, &mongo_del_secret, &mongo_set_secret, &mongo_add_origin, diff --git a/src/apps/relay/dbdrivers/dbd_mysql.c b/src/apps/relay/dbdrivers/dbd_mysql.c index 07f9b0e9..ca2977de 100644 --- a/src/apps/relay/dbdrivers/dbd_mysql.c +++ b/src/apps/relay/dbdrivers/dbd_mysql.c @@ -605,10 +605,19 @@ static int mysql_list_users(u08bits *realm, secrets_list_t *users, secrets_list_ return ret; } -static int mysql_show_secret(u08bits *realm) { - int ret = -1; +static int mysql_list_secrets(u08bits *realm, secrets_list_t *secrets, secrets_list_t *realms) +{ + int ret = -1; + + u08bits realm0[STUN_MAX_REALM_SIZE+1] = "\0"; + if(!realm) realm=realm0; + char statement[TURN_LONG_STRING_SIZE]; - snprintf(statement,sizeof(statement)-1,"select value from turn_secret where realm='%s'",realm); + if (realm[0]) { + snprintf(statement, sizeof(statement), "select value,realm from turn_secret where realm='%s' order by value", realm); + } else { + snprintf(statement, sizeof(statement), "select value,realm from turn_secret order by realm,value"); + } donot_print_connection_success=1; @@ -621,7 +630,7 @@ static int mysql_show_secret(u08bits *realm) { MYSQL_RES *mres = mysql_store_result(myc); if(!mres) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc)); - } else if(mysql_field_count(myc)!=1) { + } else if(mysql_field_count(myc)!=2) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement); } else { for(;;) { @@ -629,19 +638,32 @@ static int mysql_show_secret(u08bits *realm) { if(!row) { break; } else { - if(row[0]) { - printf("%s\n",row[0]); + const char* kval = row[0]; + if(kval) { + const char* rval = row[1]; + if(secrets) { + add_to_secrets_list(secrets,kval); + if(realms) { + if(rval && *rval) { + add_to_secrets_list(realms,rval); + } else { + add_to_secrets_list(realms,(char*)realm); + } + } + } else { + printf("%s[%s]\n",kval,rval); + } } } } - ret = 0; + ret = 0; } if(mres) mysql_free_result(mres); } } - return ret; + return ret; } static int mysql_del_secret(u08bits *secret, u08bits *realm) { @@ -1145,7 +1167,7 @@ static const turn_dbdriver_t driver = { &mysql_set_user_key, &mysql_del_user, &mysql_list_users, - &mysql_show_secret, + &mysql_list_secrets, &mysql_del_secret, &mysql_set_secret, &mysql_add_origin, diff --git a/src/apps/relay/dbdrivers/dbd_pgsql.c b/src/apps/relay/dbdrivers/dbd_pgsql.c index bdf2af91..c2d4402d 100644 --- a/src/apps/relay/dbdrivers/dbd_pgsql.c +++ b/src/apps/relay/dbdrivers/dbd_pgsql.c @@ -376,10 +376,19 @@ static int pgsql_list_users(u08bits *realm, secrets_list_t *users, secrets_list_ return ret; } -static int pgsql_show_secret(u08bits *realm) { - int ret = -1; +static int pgsql_list_secrets(u08bits *realm, secrets_list_t *secrets, secrets_list_t *realms) +{ + int ret = -1; + + u08bits realm0[STUN_MAX_REALM_SIZE+1] = "\0"; + if(!realm) realm=realm0; + char statement[TURN_LONG_STRING_SIZE]; - snprintf(statement,sizeof(statement)-1,"select value from turn_secret where realm='%s'",realm); + if (realm[0]) { + snprintf(statement, sizeof(statement), "select value,realm from turn_secret where realm='%s' order by value", realm); + } else { + snprintf(statement, sizeof(statement), "select value,realm from turn_secret order by realm,value"); + } donot_print_connection_success=1; @@ -393,16 +402,28 @@ static int pgsql_show_secret(u08bits *realm) { for(i=0;itype != REDIS_REPLY_NIL) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", rget->type); } else { + + char *s = keys.secrets[isz]; + + char *sh = strstr(s,"turn/realm/"); + if(sh != s) continue; + sh += rhsz; + char* st = strchr(sh,'/'); + if(!st) continue; + *st=0; + const char *rval = sh; + size_t i; for (i = 0; i < rget->elements; ++i) { - printf("%s\n", rget->element[i]->str); + const char *kval = rget->element[i]->str; + if(secrets) { + add_to_secrets_list(secrets,kval); + if(realms) { + if(rval && *rval) { + add_to_secrets_list(realms,rval); + } else { + add_to_secrets_list(realms,(char*)realm); + } + } + } else { + printf("%s[%s]\n", kval, rval); + } } } } @@ -1262,7 +1291,7 @@ static const turn_dbdriver_t driver = { &redis_set_user_key, &redis_del_user, &redis_list_users, - &redis_show_secret, + &redis_list_secrets, &redis_del_secret, &redis_set_secret, &redis_add_origin, diff --git a/src/apps/relay/dbdrivers/dbd_sqlite.c b/src/apps/relay/dbdrivers/dbd_sqlite.c index 4a59bc2e..19dd1dba 100644 --- a/src/apps/relay/dbdrivers/dbd_sqlite.c +++ b/src/apps/relay/dbdrivers/dbd_sqlite.c @@ -581,13 +581,22 @@ static int sqlite_list_users(u08bits *realm, secrets_list_t *users, secrets_list return ret; } -static int sqlite_show_secret(u08bits *realm) +static int sqlite_list_secrets(u08bits *realm, secrets_list_t *secrets, secrets_list_t *realms) { int ret = -1; char statement[TURN_LONG_STRING_SIZE]; + + u08bits realm0[STUN_MAX_REALM_SIZE+1] = "\0"; + if(!realm) realm=realm0; + sqlite3_stmt *st = NULL; int rc = 0; - snprintf(statement,sizeof(statement)-1,"select value from turn_secret where realm='%s'",realm); + + if (realm[0]) { + snprintf(statement, sizeof(statement), "select value,realm from turn_secret where realm='%s' order by value", realm); + } else { + snprintf(statement, sizeof(statement), "select value,realm from turn_secret order by realm,value"); + } donot_print_connection_success=1; @@ -597,17 +606,37 @@ static int sqlite_show_secret(u08bits *realm) sqlite_lock(0); if ((rc = sqlite3_prepare(sqliteconnection, statement, -1, &st, 0)) == SQLITE_OK) { - int res = sqlite3_step(st); - if (res == SQLITE_ROW) { - ret = 0; - const char* kval = (const char*) sqlite3_column_text(st, 0); - if(kval) { - printf("%s\n",kval); + + int res = 0; + while(1) { + res = sqlite3_step(st); + if (res == SQLITE_ROW) { + ret = 0; + const char* kval = (const char*) sqlite3_column_text(st, 0); + if(kval) { + const char* rval = (const char*) sqlite3_column_text(st, 1); + if(secrets) { + add_to_secrets_list(secrets,kval); + if(realms) { + if(rval && *rval) { + add_to_secrets_list(realms,rval); + } else { + add_to_secrets_list(realms,(char*)realm); + } + } + } else { + printf("%s[%s]\n",kval,rval); + } + } + } else if (res == SQLITE_DONE) { + break; + } else { + const char* errmsg = sqlite3_errmsg(sqliteconnection); + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); + ret = -1; + break; } } - } else { - const char* errmsg = sqlite3_errmsg(sqliteconnection); - TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving SQLite DB information: %s\n", errmsg); } sqlite3_finalize(st); @@ -1200,7 +1229,7 @@ static const turn_dbdriver_t driver = { &sqlite_set_user_key, &sqlite_del_user, &sqlite_list_users, - &sqlite_show_secret, + &sqlite_list_secrets, &sqlite_del_secret, &sqlite_set_secret, &sqlite_add_origin, diff --git a/src/apps/relay/dbdrivers/dbdriver.h b/src/apps/relay/dbdrivers/dbdriver.h index c08e15a7..da5c6ffe 100644 --- a/src/apps/relay/dbdrivers/dbdriver.h +++ b/src/apps/relay/dbdrivers/dbdriver.h @@ -53,7 +53,7 @@ typedef struct _turn_dbdriver_t { int (*set_user_key)(u08bits *usname, u08bits *realm, const char *key); int (*del_user)(u08bits *usname, u08bits *realm); int (*list_users)(u08bits *realm, secrets_list_t *users, secrets_list_t *realms); - int (*show_secret)(u08bits *realm); + int (*list_secrets)(u08bits *realm, secrets_list_t *users, secrets_list_t *realms); int (*del_secret)(u08bits *secret, u08bits *realm); int (*set_secret)(u08bits *secret, u08bits *realm); int (*add_origin)(u08bits *origin, u08bits *realm); diff --git a/src/apps/relay/http_server.c b/src/apps/relay/http_server.c index 2d47d325..416c2364 100644 --- a/src/apps/relay/http_server.c +++ b/src/apps/relay/http_server.c @@ -61,7 +61,7 @@ static void write_http_echo(ioa_socket_handle s) char data_http[1025]; char content_http[1025]; const char* title = "TURN Server"; - snprintf(content_http,sizeof(content_http)-1,"\r\n\r\n \r\n %s\r\n \r\n \r\n %s\r\n \r\n\r\n",title,title); + snprintf(content_http,sizeof(content_http)-1,"\r\n\r\n \r\n %s\r\n \r\n \r\n %s
use https connection for the admin session\r\n \r\n\r\n",title,title); snprintf(data_http,sizeof(data_http)-1,"HTTP/1.1 200 OK\r\nServer: %s\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Length: %d\r\n\r\n%s",TURN_SOFTWARE,(int)strlen(content_http),content_http); len_http = strlen(data_http); ns_bcopy(data_http,data,len_http); diff --git a/src/apps/relay/turn_admin_server.c b/src/apps/relay/turn_admin_server.c index ae6bb794..20c341bb 100644 --- a/src/apps/relay/turn_admin_server.c +++ b/src/apps/relay/turn_admin_server.c @@ -1361,6 +1361,7 @@ enum _AS_FORM { AS_FORM_UPDATE, AS_FORM_PS, AS_FORM_USERS, + AS_FORM_SS, AS_FORM_UNKNOWN }; @@ -1371,13 +1372,15 @@ typedef enum _AS_FORM AS_FORM; #define HR_PASSWORD1 "pwd1" #define HR_REALM "realm" #define HR_ADD_USER "add_user" -#define HR_ADD_USER_REALM "add_user_realm" +#define HR_ADD_REALM "add_user_realm" +#define HR_ADD_SECRET "add_secret" #define HR_CLIENT_PROTOCOL "cprotocol" #define HR_USER_PATTERN "puser" #define HR_MAX_SESSIONS "maxsess" #define HR_CANCEL_SESSION "cs" #define HR_DELETE_USER "du" #define HR_DELETE_REALM "dr" +#define HR_DELETE_SECRET "ds" struct form_name { AS_FORM form; @@ -1393,6 +1396,7 @@ static struct form_name form_names[] = { {AS_FORM_UPDATE,"/update"}, {AS_FORM_PS,"/ps"}, {AS_FORM_USERS,"/us"}, + {AS_FORM_SS,"/ss"}, {AS_FORM_UNKNOWN,NULL} }; @@ -1531,6 +1535,10 @@ static void write_https_home_page(ioa_socket_handle s) str_buffer_append(sb,form_names[AS_FORM_USERS].name); str_buffer_append(sb,"\">"); + str_buffer_append(sb,"
"); + str_buffer_append(sb,"\r\n"); str_buffer_append(sb,"\r\n"); @@ -2325,7 +2333,7 @@ static void write_users_page(ioa_socket_handle s, const u08bits *add_user, const } str_buffer_append(sb,"
Realm name: list_secrets) { + secrets_list_t secrets,realms; + init_secrets_list(&secrets); + init_secrets_list(&realms); + dbd->list_secrets((u08bits*)current_socket->as_eff_realm,&secrets,&realms); + + size_t sz = get_secrets_list_size(&secrets); + size_t i; + for(i=0;i"); + str_buffer_append_sz(sb,i); + str_buffer_append(sb,""); + str_buffer_append(sb,""); + str_buffer_append(sb,get_secrets_list_elem(&secrets,i)); + str_buffer_append(sb,""); + if(!current_socket->as_eff_realm[0]) { + str_buffer_append(sb,""); + str_buffer_append(sb,get_secrets_list_elem(&realms,i)); + str_buffer_append(sb,""); + } + str_buffer_append(sb," delete"); + str_buffer_append(sb,""); + str_buffer_append(sb,""); + ++ret; + } + + clean_secrets_list(&secrets); + clean_secrets_list(&realms); + } + + return ret; +} + +static void write_shared_secrets_page(ioa_socket_handle s, const char* add_secret, const char* add_realm, const char* msg) +{ + if(s && !ioa_socket_tobeclosed(s)) { + + if(!(s->as_ok)) { + write_https_logon_page(s); + } else { + + struct str_buffer* sb = str_buffer_new(); + + str_buffer_append(sb,"\r\n\r\n \r\n "); + str_buffer_append(sb,admin_title); + str_buffer_append(sb,"\r\n \r\n \r\n "); + str_buffer_append(sb,bold_admin_title); + str_buffer_append(sb,"
\r\n"); + str_buffer_append(sb,home_link); + str_buffer_append(sb,"
\r\n"); + + str_buffer_append(sb,"
\r\n"); + str_buffer_append(sb,"
Filter:\r\n"); + + str_buffer_append(sb,"
Realm name: "); + + str_buffer_append(sb,"
"); + + str_buffer_append(sb,"
\r\n"); + str_buffer_append(sb,"
\r\n"); + + str_buffer_append(sb,"
\r\n"); + str_buffer_append(sb,"
Secret:\r\n"); + + if(msg && msg[0]) { + str_buffer_append(sb,"
"); + str_buffer_append(sb,msg); + str_buffer_append(sb,"

"); + } + + str_buffer_append(sb,"
Realm name:
\r\n"); + + str_buffer_append(sb,"
Secret:
\r\n"); + + str_buffer_append(sb,"
"); + + str_buffer_append(sb,"
\r\n"); + str_buffer_append(sb,"
\r\n"); + + str_buffer_append(sb,"Secrets:
\r\n"); + str_buffer_append(sb,"\r\n"); + str_buffer_append(sb,""); + if(!current_socket->as_eff_realm[0]) { + str_buffer_append(sb,""); + } + str_buffer_append(sb,""); + str_buffer_append(sb,"\r\n"); + + size_t total_sz = https_print_secrets(sb); + + str_buffer_append(sb,"\r\n
NValueRealm
\r\n"); + + str_buffer_append(sb,"
Total secrets = "); + str_buffer_append_sz(sb,total_sz); + str_buffer_append(sb,"
\r\n"); + + str_buffer_append(sb,"\r\n\r\n"); + + send_str_from_ioa_socket_tcp(s,"HTTP/1.1 200 OK\r\nServer: "); + send_str_from_ioa_socket_tcp(s,TURN_SOFTWARE); + send_str_from_ioa_socket_tcp(s,"\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Length: "); + + send_ulong_from_ioa_socket_tcp(s,str_buffer_get_str_len(sb)); + + send_str_from_ioa_socket_tcp(s,"\r\n\r\n"); + send_str_from_ioa_socket_tcp(s,str_buffer_get_str(sb)); + + str_buffer_free(sb); + } + } +} + static void handle_toggle_request(ioa_socket_handle s, struct http_request* hr) { if(s && hr) { @@ -2563,7 +2722,7 @@ static void handle_https(ioa_socket_handle s, ioa_network_buffer_handle nbh) add_user = (const u08bits*)""; } if(add_user[0]) { - add_realm = (const u08bits*)get_http_header_value(hr, HR_ADD_USER_REALM); + add_realm = (const u08bits*)get_http_header_value(hr, HR_ADD_REALM); if(!add_realm) { add_realm=(const u08bits*)""; } @@ -2626,6 +2785,82 @@ static void handle_https(ioa_socket_handle s, ioa_network_buffer_handle nbh) } break; } + case AS_FORM_SS: { + if(s->as_ok) { + { + const char *realm0 = get_http_header_value(hr, HR_REALM); + if(!realm0) + realm0=""; + if(!is_superuser()) + realm0 = current_socket->as_realm; + STRCPY(current_socket->as_eff_realm,realm0); + } + + { + const u08bits *secret = (const u08bits*)get_http_header_value(hr, HR_DELETE_SECRET); + if(secret && secret[0]) { + const u08bits *realm = (const u08bits*)get_http_header_value(hr, HR_DELETE_REALM); + if(!is_superuser()) { + realm = (const u08bits*)current_socket->as_realm; + } + if(realm && realm[0]) { + const turn_dbdriver_t * dbd = get_dbdriver(); + if (dbd && dbd->del_secret) { + u08bits ss[AUTH_SECRET_SIZE+1]; + u08bits r[STUN_MAX_REALM_SIZE+1]; + STRCPY(ss,secret); + STRCPY(r,realm); + dbd->del_secret(ss,r); + } + } + } + } + + const u08bits *add_realm = (const u08bits*)current_socket->as_eff_realm; + const u08bits *add_secret = (const u08bits*)get_http_header_value(hr, HR_ADD_SECRET); + const char* msg = ""; + if(!add_secret) add_secret = (const u08bits*)""; + if(wrong_html_name((const char*)add_secret)) { + msg = "Error: wrong secret value"; + add_secret = (const u08bits*)""; + } + if(add_secret[0]) { + add_realm = (const u08bits*)get_http_header_value(hr, HR_ADD_REALM); + if(!add_realm) { + add_realm=(const u08bits*)""; + } + if(!is_superuser()) { + add_realm = (const u08bits*)current_socket->as_realm; + } + if(!add_realm[0]) { + add_realm=(const u08bits*)current_socket->as_eff_realm; + } + if(wrong_html_name((const char*)add_realm)) { + msg = "Error: wrong realm name"; + add_realm = (const u08bits*)""; + } + if(add_realm[0]) { + const turn_dbdriver_t * dbd = get_dbdriver(); + if (dbd && dbd->set_secret) { + u08bits ss[AUTH_SECRET_SIZE+1]; + u08bits r[STUN_MAX_REALM_SIZE+1]; + STRCPY(ss,add_secret); + STRCPY(r,add_realm); + (*dbd->set_secret)(ss, r); + } + + add_secret=(const u08bits*)""; + add_realm=(const u08bits*)""; + } + } + + write_shared_secrets_page(s,(const char*)add_secret,(const char*)add_realm,msg); + + } else { + write_https_logon_page(s); + } + break; + } case AS_FORM_TOGGLE: if(s->as_ok) { handle_toggle_request(s,hr); diff --git a/src/apps/relay/userdb.c b/src/apps/relay/userdb.c index 3796de99..1c18d2b3 100644 --- a/src/apps/relay/userdb.c +++ b/src/apps/relay/userdb.c @@ -785,11 +785,9 @@ static int list_users(u08bits *realm, int is_admin) static int show_secret(u08bits *realm) { - must_set_admin_realm(realm); - const turn_dbdriver_t * dbd = get_dbdriver(); - if (dbd && dbd->show_secret) { - (*dbd->show_secret)(realm); + if (dbd && dbd->list_secrets) { + (*dbd->list_secrets)(realm,NULL,NULL); } return 0; diff --git a/turndb/testmongosetup.sh b/turndb/testmongosetup.sh index dba4757d..b7c32fb1 100755 --- a/turndb/testmongosetup.sh +++ b/turndb/testmongosetup.sh @@ -5,7 +5,7 @@ mongo $* <