void _mongoc_write_command_delete_legacy (mongoc_write_command_t *command, mongoc_client_t *client, mongoc_server_stream_t *server_stream, const char *database, const char *collection, uint32_t offset, mongoc_write_result_t *result, bson_error_t *error) { int64_t started; int32_t max_bson_obj_size; const uint8_t *data; mongoc_rpc_t rpc; uint32_t request_id; bson_iter_t q_iter; uint32_t len; int64_t limit = 0; char ns[MONGOC_NAMESPACE_MAX + 1]; bool r; bson_reader_t *reader; const bson_t *bson; bool eof; ENTRY; BSON_ASSERT (command); BSON_ASSERT (client); BSON_ASSERT (database); BSON_ASSERT (server_stream); BSON_ASSERT (collection); started = bson_get_monotonic_time (); max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream); if (!command->n_documents) { bson_set_error (error, MONGOC_ERROR_COLLECTION, MONGOC_ERROR_COLLECTION_DELETE_FAILED, "Cannot do an empty delete."); result->failed = true; EXIT; } bson_snprintf (ns, sizeof ns, "%s.%s", database, collection); reader = bson_reader_new_from_data (command->payload.data, command->payload.len); while ((bson = bson_reader_read (reader, &eof))) { /* the document is like { "q": { <selector> }, limit: <0 or 1> } */ r = (bson_iter_init (&q_iter, bson) && bson_iter_find (&q_iter, "q") && BSON_ITER_HOLDS_DOCUMENT (&q_iter)); BSON_ASSERT (r); bson_iter_document (&q_iter, &len, &data); BSON_ASSERT (data); BSON_ASSERT (len >= 5); if (len > max_bson_obj_size) { _mongoc_write_command_too_large_error ( error, 0, len, max_bson_obj_size); result->failed = true; bson_reader_destroy (reader); EXIT; } request_id = ++client->cluster.request_id; rpc.header.msg_len = 0; rpc.header.request_id = request_id; rpc.header.response_to = 0; rpc.header.opcode = MONGOC_OPCODE_DELETE; rpc.delete_.zero = 0; rpc.delete_.collection = ns; if (bson_iter_find (&q_iter, "limit") && (BSON_ITER_HOLDS_INT (&q_iter))) { limit = bson_iter_as_int64 (&q_iter); } rpc.delete_.flags = limit ? MONGOC_DELETE_SINGLE_REMOVE : MONGOC_DELETE_NONE; rpc.delete_.selector = data; _mongoc_monitor_legacy_write ( client, command, database, collection, server_stream, request_id); if (!mongoc_cluster_legacy_rpc_sendv_to_server ( &client->cluster, &rpc, server_stream, error)) { result->failed = true; bson_reader_destroy (reader); EXIT; } _mongoc_monitor_legacy_write_succeeded (client, bson_get_monotonic_time () - started, command, server_stream, request_id); started = bson_get_monotonic_time (); } bson_reader_destroy (reader); EXIT; }
void _mongoc_write_command_update_legacy (mongoc_write_command_t *command, mongoc_client_t *client, mongoc_server_stream_t *server_stream, const char *database, const char *collection, uint32_t offset, mongoc_write_result_t *result, bson_error_t *error) { int64_t started; int32_t max_bson_obj_size; mongoc_rpc_t rpc; uint32_t request_id = 0; bson_iter_t subiter, subsubiter; bson_t doc; bson_t update, selector; const uint8_t *data = NULL; uint32_t len = 0; size_t err_offset; bool val = false; char ns[MONGOC_NAMESPACE_MAX + 1]; int vflags = (BSON_VALIDATE_UTF8 | BSON_VALIDATE_UTF8_ALLOW_NULL | BSON_VALIDATE_DOLLAR_KEYS | BSON_VALIDATE_DOT_KEYS); bson_reader_t *reader; const bson_t *bson; bool eof; ENTRY; BSON_ASSERT (command); BSON_ASSERT (client); BSON_ASSERT (database); BSON_ASSERT (server_stream); BSON_ASSERT (collection); started = bson_get_monotonic_time (); max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream); reader = bson_reader_new_from_data (command->payload.data, command->payload.len); while ((bson = bson_reader_read (reader, &eof))) { if (bson_iter_init (&subiter, bson) && bson_iter_find (&subiter, "u") && BSON_ITER_HOLDS_DOCUMENT (&subiter)) { bson_iter_document (&subiter, &len, &data); BSON_ASSERT (bson_init_static (&doc, data, len)); if (bson_iter_init (&subsubiter, &doc) && bson_iter_next (&subsubiter) && (bson_iter_key (&subsubiter)[0] != '$') && !bson_validate ( &doc, (bson_validate_flags_t) vflags, &err_offset)) { result->failed = true; bson_set_error (error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "update document is corrupt or contains " "invalid keys including $ or ."); bson_reader_destroy (reader); EXIT; } } else { result->failed = true; bson_set_error (error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "updates is malformed."); bson_reader_destroy (reader); EXIT; } } bson_snprintf (ns, sizeof ns, "%s.%s", database, collection); bson_reader_destroy (reader); reader = bson_reader_new_from_data (command->payload.data, command->payload.len); while ((bson = bson_reader_read (reader, &eof))) { request_id = ++client->cluster.request_id; rpc.header.msg_len = 0; rpc.header.request_id = request_id; rpc.header.response_to = 0; rpc.header.opcode = MONGOC_OPCODE_UPDATE; rpc.update.zero = 0; rpc.update.collection = ns; rpc.update.flags = MONGOC_UPDATE_NONE; BSON_ASSERT (bson_iter_init (&subiter, bson)); while (bson_iter_next (&subiter)) { if (strcmp (bson_iter_key (&subiter), "u") == 0) { bson_iter_document (&subiter, &len, &data); if (len > max_bson_obj_size) { _mongoc_write_command_too_large_error ( error, 0, len, max_bson_obj_size); result->failed = true; bson_reader_destroy (reader); EXIT; } rpc.update.update = data; BSON_ASSERT (bson_init_static (&update, data, len)); } else if (strcmp (bson_iter_key (&subiter), "q") == 0) { bson_iter_document (&subiter, &len, &data); if (len > max_bson_obj_size) { _mongoc_write_command_too_large_error ( error, 0, len, max_bson_obj_size); result->failed = true; bson_reader_destroy (reader); EXIT; } rpc.update.selector = data; BSON_ASSERT (bson_init_static (&selector, data, len)); } else if (strcmp (bson_iter_key (&subiter), "multi") == 0) { val = bson_iter_bool (&subiter); if (val) { rpc.update.flags = (mongoc_update_flags_t) ( rpc.update.flags | MONGOC_UPDATE_MULTI_UPDATE); } } else if (strcmp (bson_iter_key (&subiter), "upsert") == 0) { val = bson_iter_bool (&subiter); if (val) { rpc.update.flags = (mongoc_update_flags_t) ( rpc.update.flags | MONGOC_UPDATE_UPSERT); } } } _mongoc_monitor_legacy_write ( client, command, database, collection, server_stream, request_id); if (!mongoc_cluster_legacy_rpc_sendv_to_server ( &client->cluster, &rpc, server_stream, error)) { result->failed = true; bson_reader_destroy (reader); EXIT; } _mongoc_monitor_legacy_write_succeeded (client, bson_get_monotonic_time () - started, command, server_stream, request_id); started = bson_get_monotonic_time (); } bson_reader_destroy (reader); }
static void test_find_and_modify (void) { mongoc_collection_t *collection; mongoc_client_t *client; bson_error_t error; bson_iter_t iter; bson_iter_t citer; bson_t *update; bson_t doc = BSON_INITIALIZER; bson_t reply; mongoc_find_and_modify_opts_t *opts; client = test_framework_client_new (); ASSERT (client); collection = get_test_collection (client, "test_find_and_modify"); ASSERT (collection); BSON_APPEND_INT32 (&doc, "superduper", 77889); ASSERT_OR_PRINT (mongoc_collection_insert ( collection, MONGOC_INSERT_NONE, &doc, NULL, &error), error); update = BCON_NEW ("$set", "{", "superduper", BCON_INT32 (1234), "}"); opts = mongoc_find_and_modify_opts_new (); mongoc_find_and_modify_opts_set_update (opts, update); mongoc_find_and_modify_opts_set_fields (opts, tmp_bson ("{'superduper': 1}")); mongoc_find_and_modify_opts_set_sort (opts, tmp_bson ("{'superduper': 1}")); mongoc_find_and_modify_opts_set_flags (opts, MONGOC_FIND_AND_MODIFY_RETURN_NEW); ASSERT_OR_PRINT (mongoc_collection_find_and_modify_with_opts (collection, &doc, opts, &reply, &error), error); assert (bson_iter_init_find (&iter, &reply, "value")); assert (BSON_ITER_HOLDS_DOCUMENT (&iter)); assert (bson_iter_recurse (&iter, &citer)); assert (bson_iter_find (&citer, "superduper")); assert (BSON_ITER_HOLDS_INT32 (&citer)); assert (bson_iter_int32 (&citer) == 1234); assert (bson_iter_init_find (&iter, &reply, "lastErrorObject")); assert (BSON_ITER_HOLDS_DOCUMENT (&iter)); assert (bson_iter_recurse (&iter, &citer)); assert (bson_iter_find (&citer, "updatedExisting")); assert (BSON_ITER_HOLDS_BOOL (&citer)); assert (bson_iter_bool (&citer)); bson_destroy (&reply); bson_destroy (update); ASSERT_OR_PRINT (mongoc_collection_drop (collection, &error), error); mongoc_find_and_modify_opts_destroy (opts); mongoc_collection_destroy (collection); mongoc_client_destroy (client); bson_destroy (&doc); }
static void test_get_collection_info (void) { mongoc_database_t *database; mongoc_collection_t *collection; mongoc_client_t *client; mongoc_cursor_t *cursor; bson_error_t error = { 0 }; bson_iter_t col_iter; bson_t capped_options = BSON_INITIALIZER; bson_t autoindexid_options = BSON_INITIALIZER; bson_t noopts_options = BSON_INITIALIZER; bson_t name_filter = BSON_INITIALIZER; const bson_t *doc; int r; int num_infos = 0; const char *name; char *dbname; char *capped_name; char *autoindexid_name; char *noopts_name; client = mongoc_client_new (gTestUri); assert (client); dbname = gen_collection_name ("dbtest"); database = mongoc_client_get_database (client, dbname); assert (database); bson_free (dbname); capped_name = gen_collection_name ("capped"); BSON_APPEND_BOOL (&capped_options, "capped", true); BSON_APPEND_INT32 (&capped_options, "size", 10000000); BSON_APPEND_INT32 (&capped_options, "max", 1024); autoindexid_name = gen_collection_name ("autoindexid"); BSON_APPEND_BOOL (&autoindexid_options, "autoIndexId", false); noopts_name = gen_collection_name ("noopts"); collection = mongoc_database_create_collection (database, capped_name, &capped_options, &error); assert (collection); mongoc_collection_destroy (collection); collection = mongoc_database_create_collection (database, autoindexid_name, &autoindexid_options, &error); assert (collection); mongoc_collection_destroy (collection); collection = mongoc_database_create_collection (database, noopts_name, &noopts_options, &error); assert (collection); mongoc_collection_destroy (collection); /* first we filter on collection name. */ BSON_APPEND_UTF8 (&name_filter, "name", noopts_name); /* We only test with filters since get_collection_names will * test w/o filters for us. */ /* Filter on an exact match of name */ cursor = mongoc_database_find_collections (database, &name_filter, &error); assert (cursor); assert (!error.domain); assert (!error.code); while (mongoc_cursor_next (cursor, &doc)) { if (bson_iter_init (&col_iter, doc) && bson_iter_find (&col_iter, "name") && BSON_ITER_HOLDS_UTF8 (&col_iter) && (name = bson_iter_utf8 (&col_iter, NULL))) { ++num_infos; assert (0 == strcmp (name, noopts_name)); } else { assert (false); } } assert (1 == num_infos); num_infos = 0; mongoc_cursor_destroy (cursor); r = mongoc_database_drop (database, &error); assert (r); assert (!error.domain); assert (!error.code); bson_free (capped_name); bson_free (noopts_name); bson_free (autoindexid_name); mongoc_database_destroy (database); mongoc_client_destroy (client); }
mongoc_collection_t * mongoc_database_create_collection (mongoc_database_t *database, const char *name, const bson_t *options, bson_error_t *error) { mongoc_collection_t *collection = NULL; bson_iter_t iter; bson_t cmd; bool capped = false; BSON_ASSERT (database); BSON_ASSERT (name); if (strchr (name, '$')) { bson_set_error (error, MONGOC_ERROR_NAMESPACE, MONGOC_ERROR_NAMESPACE_INVALID, "The namespace \"%s\" is invalid.", name); return NULL; } if (options) { if (bson_iter_init_find (&iter, options, "capped")) { if (!BSON_ITER_HOLDS_BOOL (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The argument \"capped\" must be a boolean."); return NULL; } capped = bson_iter_bool (&iter); } if (bson_iter_init_find (&iter, options, "autoIndexId") && !BSON_ITER_HOLDS_BOOL (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The argument \"autoIndexId\" must be a boolean."); return NULL; } if (bson_iter_init_find (&iter, options, "size")) { if (!BSON_ITER_HOLDS_INT32 (&iter) && !BSON_ITER_HOLDS_INT64 (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The argument \"size\" must be an integer."); return NULL; } if (!capped) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The \"size\" parameter requires {\"capped\": true}"); return NULL; } } if (bson_iter_init_find (&iter, options, "max")) { if (!BSON_ITER_HOLDS_INT32 (&iter) && !BSON_ITER_HOLDS_INT64 (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The argument \"max\" must be an integer."); return NULL; } if (!capped) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The \"max\" parameter requires {\"capped\": true}"); return NULL; } } if (bson_iter_init_find (&iter, options, "storage")) { if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The \"storage\" parameter must be a document"); return NULL; } if (bson_iter_find (&iter, "wiredtiger")) { if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The \"wiredtiger\" option must take a document argument with a \"configString\" field"); return NULL; } if (bson_iter_find (&iter, "configString")) { if (!BSON_ITER_HOLDS_UTF8 (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The \"configString\" parameter must be a string"); return NULL; } } else { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The \"wiredtiger\" option must take a document argument with a \"configString\" field"); return NULL; } } } } bson_init (&cmd); BSON_APPEND_UTF8 (&cmd, "create", name); if (options) { if (!bson_iter_init (&iter, options)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The argument \"options\" is corrupt or invalid."); bson_destroy (&cmd); return NULL; } while (bson_iter_next (&iter)) { if (!bson_append_iter (&cmd, bson_iter_key (&iter), -1, &iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "Failed to append \"options\" to create command."); bson_destroy (&cmd); return NULL; } } } if (mongoc_database_command_simple (database, &cmd, NULL, NULL, error)) { collection = _mongoc_collection_new (database->client, database->name, name, database->read_prefs, database->read_concern, database->write_concern); } bson_destroy (&cmd); return collection; }
static void test_find_and_modify (void) { mongoc_collection_t *collection; mongoc_client_t *client; bson_error_t error; bson_iter_t iter; bson_iter_t citer; bson_t *update; bson_t doc = BSON_INITIALIZER; bson_t reply; bool r; client = mongoc_client_new (gTestUri); ASSERT (client); collection = get_test_collection (client, "test_find_and_modify"); ASSERT (collection); BSON_APPEND_INT32 (&doc, "superduper", 77889); r = mongoc_collection_insert (collection, MONGOC_INSERT_NONE, &doc, NULL, &error); assert (r); update = BCON_NEW ("$set", "{", "superduper", BCON_INT32 (1234), "}"); r = mongoc_collection_find_and_modify (collection, &doc, NULL, update, NULL, false, false, true, &reply, &error); assert (r); assert (bson_iter_init_find (&iter, &reply, "value")); assert (BSON_ITER_HOLDS_DOCUMENT (&iter)); assert (bson_iter_recurse (&iter, &citer)); assert (bson_iter_find (&citer, "superduper")); assert (BSON_ITER_HOLDS_INT32 (&citer)); assert (bson_iter_int32 (&citer) == 1234); assert (bson_iter_init_find (&iter, &reply, "lastErrorObject")); assert (BSON_ITER_HOLDS_DOCUMENT (&iter)); assert (bson_iter_recurse (&iter, &citer)); assert (bson_iter_find (&citer, "updatedExisting")); assert (BSON_ITER_HOLDS_BOOL (&citer)); assert (bson_iter_bool (&citer)); bson_destroy (&reply); bson_destroy (update); r = mongoc_collection_drop (collection, &error); assert (r); mongoc_collection_destroy (collection); mongoc_client_destroy (client); bson_destroy (&doc); }
static int mongo_list_realm_options(u08bits *realm) { mongoc_collection_t * collection = mongo_get_collection("realm"); if(!collection) return -1; bson_t query, child; bson_init(&query); bson_append_document_begin(&query, "$orderby", -1, &child); BSON_APPEND_INT32(&child, "realm", 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, "options", 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); int ret = -1; if (!cursor) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'realm'\n"); } else { const bson_t * item; uint32_t length; bson_iter_t iter; while (mongoc_cursor_next(cursor, &item)) { if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "realm") && BSON_ITER_HOLDS_UTF8(&iter)) { const char * _realm = bson_iter_utf8(&iter, &length); if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "options") && BSON_ITER_HOLDS_DOCUMENT(&iter)) { const uint8_t *docbuf = NULL; uint32_t doclen = 0; bson_t options; bson_iter_t options_iter; bson_iter_document(&iter, &doclen, &docbuf); bson_init_static(&options, docbuf, doclen); if (bson_iter_init(&options_iter, &options)) { while(bson_iter_next(&options_iter)) { const char * _k = bson_iter_key(&options_iter); if (BSON_ITER_HOLDS_DOUBLE(&options_iter)) { int32_t _v = (int32_t)bson_iter_double(&options_iter); printf("%s[%s]=%d\n", _k, _realm, _v); } else if (BSON_ITER_HOLDS_INT32(&options_iter)) { int32_t _v = bson_iter_int32(&options_iter); printf("%s[%s]=%d\n", _k, _realm, _v); } else if (BSON_ITER_HOLDS_INT64(&options_iter)) { int32_t _v = (int32_t)bson_iter_int64(&options_iter); printf("%s[%s]=%d\n", _k, _realm, _v); } } } } } } mongoc_cursor_destroy(cursor); ret = 0; } mongoc_collection_destroy(collection); bson_destroy(&query); bson_destroy(&fields); return ret; }
static int mongo_read_realms_ip_lists(const char *kind, ip_range_list_t * list) { int ret = 0; char field_name[129]; sprintf(field_name, "%s_peer_ip", kind); mongoc_collection_t * collection = mongo_get_collection("realm"); if (!collection) return ret; bson_t query; bson_init(&query); bson_t fields; bson_init(&fields); BSON_APPEND_INT32(&fields, "realm", 1); BSON_APPEND_INT32(&fields, field_name, 1); mongoc_cursor_t * cursor; cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, &fields, NULL); if (!cursor) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'realm'\n"); ret = -1; } else { const bson_t * item; uint32_t length; bson_iter_t iter; char realm[513]; while (mongoc_cursor_next(cursor, &item)) { if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "realm") && BSON_ITER_HOLDS_UTF8(&iter)) { STRCPY(realm,bson_iter_utf8(&iter, &length)); if (bson_iter_init(&iter, item) && bson_iter_find(&iter, field_name) && BSON_ITER_HOLDS_ARRAY(&iter)) { const uint8_t *docbuf = NULL; uint32_t doclen = 0; bson_t ip_range_array; bson_iter_t ip_range_iter; bson_iter_array(&iter, &doclen, &docbuf); bson_init_static(&ip_range_array, docbuf, doclen); if (bson_iter_init(&ip_range_iter, &ip_range_array)) { while (bson_iter_next(&ip_range_iter)) { if (BSON_ITER_HOLDS_UTF8(&ip_range_iter)) { const char* ip_range = bson_iter_utf8(&ip_range_iter, &length); add_ip_list_range(ip_range, realm, list); } } } } } } mongoc_cursor_destroy(cursor); } mongoc_collection_destroy(collection); bson_destroy(&query); bson_destroy(&fields); return ret; }
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; 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_APPEND_INT32(&fields, "realm", 1); mongoc_cursor_t * cursor; cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, &fields, NULL); int ret = -1; 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; 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_list_origins(u08bits *realm, secrets_list_t *origins, secrets_list_t *realms) { mongoc_collection_t * collection = mongo_get_collection("realm"); if(!collection) return -1; u08bits realm0[STUN_MAX_REALM_SIZE+1] = "\0"; if(!realm) realm=realm0; bson_t query, child; bson_init(&query); bson_append_document_begin(&query, "$orderby", -1, &child); BSON_APPEND_INT32(&child, "realm", 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, "origin", 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); int ret = -1; if (!cursor) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'realm'\n"); } else { const bson_t * item; uint32_t length; bson_iter_t iter; while (mongoc_cursor_next(cursor, &item)) { if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "realm") && BSON_ITER_HOLDS_UTF8(&iter)) { const char * _realm = bson_iter_utf8(&iter, &length); if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "origin") && BSON_ITER_HOLDS_ARRAY(&iter)) { const uint8_t *docbuf = NULL; uint32_t doclen = 0; bson_t origin_array; bson_iter_t origin_iter; bson_iter_array(&iter, &doclen, &docbuf); bson_init_static(&origin_array, docbuf, doclen); if (bson_iter_init(&origin_iter, &origin_array)) { while(bson_iter_next(&origin_iter)) { if (BSON_ITER_HOLDS_UTF8(&origin_iter)) { const char * _origin = bson_iter_utf8(&origin_iter, &length); if(origins) { add_to_secrets_list(origins,_origin); if(realms) { add_to_secrets_list(realms,_realm); } } else { printf("%s ==>> %s\n", _realm, _origin); } } } } } } } mongoc_cursor_destroy(cursor); ret = 0; } mongoc_collection_destroy(collection); bson_destroy(&query); bson_destroy(&fields); return ret; }
static int mongo_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts) { const char * collection_name = "oauth_key"; mongoc_collection_t * collection = mongo_get_collection(collection_name); if(!collection) return -1; bson_t query; bson_init(&query); bson_t child; bson_append_document_begin(&query, "$orderby", -1, &child); bson_append_int32(&child, "kid", -1, 1); bson_append_document_end(&query, &child); bson_append_document_begin(&query, "$query", -1, &child); bson_append_document_end(&query, &child); bson_t fields; bson_init(&fields); BSON_APPEND_INT32(&fields, "kid", 1); BSON_APPEND_INT32(&fields, "lifetime", 1); BSON_APPEND_INT32(&fields, "timestamp", 1); BSON_APPEND_INT32(&fields, "as_rs_alg", 1); BSON_APPEND_INT32(&fields, "ikm_key", 1); mongoc_cursor_t * cursor; cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, &fields, NULL); int ret = -1; if (!cursor) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection '%s'\n", collection_name); } else { const bson_t * item; oauth_key_data_raw key_; oauth_key_data_raw *key=&key_; uint32_t length; bson_iter_t iter; while (mongoc_cursor_next(cursor, &item)) { ns_bzero(key,sizeof(oauth_key_data_raw)); if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "kid") && BSON_ITER_HOLDS_UTF8(&iter)) { STRCPY(key->kid,bson_iter_utf8(&iter, &length)); } if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "as_rs_alg") && BSON_ITER_HOLDS_UTF8(&iter)) { STRCPY(key->as_rs_alg,bson_iter_utf8(&iter, &length)); } if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "ikm_key") && BSON_ITER_HOLDS_UTF8(&iter)) { STRCPY(key->ikm_key,bson_iter_utf8(&iter, &length)); } if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "timestamp") && BSON_ITER_HOLDS_INT64(&iter)) { key->timestamp = (u64bits)bson_iter_int64(&iter); } if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "lifetime") && BSON_ITER_HOLDS_INT32(&iter)) { key->lifetime = (u32bits)bson_iter_int32(&iter); } if(kids) { add_to_secrets_list(kids,key->kid); add_to_secrets_list(teas,key->as_rs_alg); { char ts[256]; snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp); add_to_secrets_list(tss,ts); } { char lt[256]; snprintf(lt,sizeof(lt)-1,"%lu",(unsigned long)key->lifetime); add_to_secrets_list(lts,lt); } } else { printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s\n", key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->as_rs_alg); } } mongoc_cursor_destroy(cursor); ret = 0; } mongoc_collection_destroy(collection); bson_destroy(&query); bson_destroy(&fields); return ret; }
static int mongo_list_admin_users(int no_print) { const char * collection_name = "admin_user"; mongoc_collection_t * collection = mongo_get_collection(collection_name); if(!collection) return -1; bson_t query, child; bson_init(&query); bson_append_document_begin(&query, "$orderby", -1, &child); bson_append_int32(&child, "name", -1, 1); bson_append_document_end(&query, &child); bson_append_document_begin(&query, "$query", -1, &child); bson_append_document_end(&query, &child); bson_t fields; bson_init(&fields); BSON_APPEND_INT32(&fields, "name", 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); int ret = -1; if (!cursor) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection '%s'\n", collection_name); } else { const bson_t * item; uint32_t length; bson_iter_t iter; bson_iter_t iter_realm; const char * value; ret = 0; while (mongoc_cursor_next(cursor, &item)) { if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "name") && BSON_ITER_HOLDS_UTF8(&iter)) { value = bson_iter_utf8(&iter, &length); if (length) { const char *realm = ""; if (bson_iter_init(&iter_realm, item) && bson_iter_find(&iter_realm, "realm") && BSON_ITER_HOLDS_UTF8(&iter_realm)) { realm = bson_iter_utf8(&iter_realm, &length); } ++ret; if(!no_print) { if(realm && *realm) { printf("%s[%s]\n", value, realm); } else { printf("%s\n", value); } } } } } mongoc_cursor_destroy(cursor); } mongoc_collection_destroy(collection); bson_destroy(&query); bson_destroy(&fields); return ret; }
static void mongo_reread_realms(secrets_list_t * realms_list) { UNUSED_ARG(realms_list); mongoc_collection_t * collection = mongo_get_collection("realm"); if (!collection) return; bson_t query; bson_init(&query); bson_t fields; bson_init(&fields); BSON_APPEND_INT32(&fields, "realm", 1); BSON_APPEND_INT32(&fields, "origin", 1); BSON_APPEND_INT32(&fields, "options", 1); mongoc_cursor_t * cursor; cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, &fields, NULL); if (!cursor) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'realm'\n"); } else { ur_string_map *o_to_realm_new = ur_string_map_create(turn_free_simple); const bson_t * item; uint32_t length; bson_iter_t iter; while (mongoc_cursor_next(cursor, &item)) { if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "realm") && BSON_ITER_HOLDS_UTF8(&iter)) { char * _realm = turn_strdup(bson_iter_utf8(&iter, &length)); get_realm(_realm); if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "origin") && BSON_ITER_HOLDS_ARRAY(&iter)) { const uint8_t *docbuf = NULL; uint32_t doclen = 0; bson_t origin_array; bson_iter_t origin_iter; bson_iter_array(&iter, &doclen, &docbuf); bson_init_static(&origin_array, docbuf, doclen); if (bson_iter_init(&origin_iter, &origin_array)) { while (bson_iter_next(&origin_iter)) { if (BSON_ITER_HOLDS_UTF8(&origin_iter)) { char* _origin = turn_strdup(bson_iter_utf8(&origin_iter, &length)); char *rval = turn_strdup(_realm); ur_string_map_value_type value = (ur_string_map_value_type) (rval); ur_string_map_put(o_to_realm_new, (const ur_string_map_key_type) _origin, value); turn_free(_origin,strlen(_origin)+1); } } } } realm_params_t* rp = get_realm(_realm); lock_realms(); rp->options.perf_options.max_bps = turn_params.max_bps; rp->options.perf_options.total_quota = turn_params.total_quota; rp->options.perf_options.user_quota = turn_params.user_quota; unlock_realms(); if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "options") && BSON_ITER_HOLDS_DOCUMENT(&iter)) { const uint8_t *docbuf = NULL; uint32_t doclen = 0; bson_t options; bson_iter_t options_iter; bson_iter_document(&iter, &doclen, &docbuf); bson_init_static(&options, docbuf, doclen); if (bson_iter_init(&options_iter, &options)) { while (bson_iter_next(&options_iter)) { const char * _k = bson_iter_key(&options_iter); uint64_t _v = 0; if (BSON_ITER_HOLDS_DOUBLE(&options_iter)) { _v = (uint64_t) bson_iter_double(&options_iter); } else if (BSON_ITER_HOLDS_INT32(&options_iter)) { _v = (uint64_t)bson_iter_int32(&options_iter); } else if (BSON_ITER_HOLDS_INT64(&options_iter)) { _v = (uint64_t) bson_iter_int64(&options_iter); } if (_v) { if (!strcmp(_k, "max-bps")) rp->options.perf_options.max_bps = (band_limit_t) _v; else if (!strcmp(_k, "total-quota")) rp->options.perf_options.total_quota = (vint) _v; else if (!strcmp(_k, "user-quota")) rp->options.perf_options.user_quota = (vint) _v; else { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown realm option: %s\n", _k); } } } } } turn_free(_realm,strlen(_realm)+1); } } update_o_to_realm(o_to_realm_new); mongoc_cursor_destroy(cursor); } mongoc_collection_destroy(collection); bson_destroy(&query); bson_destroy(&fields); }
static void test_bson_type (bson_t *scenario, test_bson_type_valid_cb valid) { bson_iter_t iter; bson_iter_t inner_iter; BSON_ASSERT (scenario); if (bson_iter_init_find (&iter, scenario, "valid")) { const char *expected = NULL; bson_t json; bson_t bson_input = BSON_INITIALIZER; bson_iter_recurse (&iter, &inner_iter); while (bson_iter_next (&inner_iter)) { bson_iter_t test; uint8_t *bson_str; uint32_t bson_str_len; const uint8_t *extjson_str; uint32_t extjson_str_len; const uint8_t *canonical_extjson_str; uint32_t canonical_extjson_str_len; bool lossy = false; bool have_extjson = false; bool have_canonical_extjson = false; bson_iter_recurse (&inner_iter, &test); _test_bson_type_print_description (&test); while (bson_iter_next (&test)) { const char *key = bson_iter_key (&test); if (!strcmp (key, "bson") && BSON_ITER_HOLDS_UTF8 (&test)) { const char *input = NULL; unsigned int byte; uint32_t tmp; int x = 0; int i = 0; input = bson_iter_utf8 (&test, &tmp); bson_str_len = tmp / 2; bson_str = bson_malloc (bson_str_len); while (SSCANF (&input[i], "%2x", &byte) == 1) { bson_str[x++] = (uint8_t) byte; i += 2; } } if (!strcmp (key, "extjson") && BSON_ITER_HOLDS_UTF8 (&test)) { extjson_str = (const uint8_t *)bson_iter_utf8 (&test, &extjson_str_len); have_extjson = true; } if (!strcmp (key, "canonical_extjson") && BSON_ITER_HOLDS_UTF8 (&test)) { canonical_extjson_str = (const uint8_t *)bson_iter_utf8 (&test, &canonical_extjson_str_len); have_canonical_extjson = true; } if (!strcmp (key, "canonical_extjson") && BSON_ITER_HOLDS_BOOL (&test)) { lossy = bson_iter_bool (&test); } } valid (bson_str, bson_str_len, bson_str, bson_str_len, have_extjson ? extjson_str : NULL, have_extjson ? extjson_str_len : 0, have_canonical_extjson ? canonical_extjson_str : extjson_str, have_canonical_extjson ? canonical_extjson_str_len : extjson_str_len, lossy); bson_free (bson_str); } } if (bson_iter_init_find (&iter, scenario, "parseErrors")) { bson_iter_recurse (&iter, &inner_iter); while (bson_iter_next (&inner_iter)) { bson_iter_t test; bson_iter_recurse (&inner_iter, &test); _test_bson_type_print_description (&test); if (bson_iter_find (&test, "string") && BSON_ITER_HOLDS_UTF8 (&test)) { bson_decimal128_t d; uint32_t tmp; const char *input = bson_iter_utf8 (&test, &tmp); ASSERT (!bson_decimal128_from_string (input, &d)); ASSERT (IS_NAN (d)); } } } }
static void test_mongoc_metadata_append_success (void) { mock_server_t *server; mongoc_uri_t *uri; mongoc_client_t *client; mongoc_client_pool_t *pool; request_t *request; const bson_t *request_doc; bson_iter_t iter; bson_iter_t md_iter; bson_iter_t inner_iter; const char *val; const char *driver_name = "php driver"; const char *driver_version = "version abc"; const char *platform = "./configure -nottoomanyflags"; char big_string [METADATA_MAX_SIZE]; memset (big_string, 'a', METADATA_MAX_SIZE - 1); big_string [METADATA_MAX_SIZE - 1] = '\0'; _reset_metadata (); /* Make sure setting the metadata works */ ASSERT (mongoc_metadata_append (driver_name, driver_version, platform)); server = mock_server_new (); mock_server_run (server); uri = mongoc_uri_copy (mock_server_get_uri (server)); mongoc_uri_set_option_as_int32 (uri, "heartbeatFrequencyMS", 500); pool = mongoc_client_pool_new (uri); /* Force topology scanner to start */ client = mongoc_client_pool_pop (pool); request = mock_server_receives_ismaster (server); ASSERT (request); request_doc = request_get_doc (request, 0); ASSERT (request_doc); ASSERT (bson_has_field (request_doc, "isMaster")); ASSERT (bson_has_field (request_doc, METADATA_FIELD)); ASSERT (bson_iter_init_find (&iter, request_doc, METADATA_FIELD)); ASSERT (bson_iter_recurse (&iter, &md_iter)); /* Make sure driver.name and driver.version and platform are all right */ ASSERT (bson_iter_find (&md_iter, "driver")); ASSERT (BSON_ITER_HOLDS_DOCUMENT (&md_iter)); ASSERT (bson_iter_recurse (&md_iter, &inner_iter)); ASSERT (bson_iter_find (&inner_iter, "name")); ASSERT (BSON_ITER_HOLDS_UTF8 (&inner_iter)); val = bson_iter_utf8 (&inner_iter, NULL); ASSERT (val); ASSERT (strstr (val, driver_name) != NULL); ASSERT (bson_iter_find (&inner_iter, "version")); ASSERT (BSON_ITER_HOLDS_UTF8 (&inner_iter)); val = bson_iter_utf8 (&inner_iter, NULL); ASSERT (val); ASSERT (strstr (val, driver_version)); /* Check os type not empty */ ASSERT (bson_iter_find (&md_iter, "os")); ASSERT (BSON_ITER_HOLDS_DOCUMENT (&md_iter)); ASSERT (bson_iter_recurse (&md_iter, &inner_iter)); ASSERT (bson_iter_find (&inner_iter, "type")); ASSERT (BSON_ITER_HOLDS_UTF8 (&inner_iter)); val = bson_iter_utf8 (&inner_iter, NULL); ASSERT (val); ASSERT (strlen (val) > 0); /* Not checking os_name, as the spec says it can be NULL. */ /* Check platform field ok */ ASSERT (bson_iter_find (&md_iter, "platform")); ASSERT (BSON_ITER_HOLDS_UTF8 (&md_iter)); val = bson_iter_utf8 (&md_iter, NULL); ASSERT (val); ASSERT (strstr (val, platform) != NULL); mock_server_replies_simple (request, "{'ok': 1, 'ismaster': true}"); request_destroy (request); /* Cleanup */ mongoc_client_pool_push (pool, client); mongoc_client_pool_destroy (pool); mongoc_uri_destroy (uri); mock_server_destroy (server); _reset_metadata (); }