static bool mongoc_database_add_user_legacy (mongoc_database_t *database, const char *username, const char *password, bson_error_t *error) { mongoc_collection_t *collection; mongoc_cursor_t *cursor = NULL; const bson_t *doc; bool ret = false; bson_t query; bson_t user; char *input; char *pwd = NULL; ENTRY; BSON_ASSERT (database); BSON_ASSERT (username); BSON_ASSERT (password); /* * Users are stored in the <dbname>.system.users virtual collection. */ collection = mongoc_client_get_collection(database->client, database->name, "system.users"); BSON_ASSERT(collection); /* * Hash the users password. */ input = bson_strdup_printf("%s:mongo:%s", username, password); pwd = _mongoc_hex_md5(input); bson_free(input); /* * Check to see if the user exists. If so, we will update the * password instead of inserting a new user. */ bson_init(&query); bson_append_utf8(&query, "user", 4, username, -1); cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 1, 0, &query, NULL, NULL); if (!mongoc_cursor_next(cursor, &doc)) { if (mongoc_cursor_error(cursor, error)) { GOTO (failure); } bson_init(&user); bson_append_utf8(&user, "user", 4, username, -1); bson_append_bool(&user, "readOnly", 8, false); bson_append_utf8(&user, "pwd", 3, pwd, -1); } else { bson_init(&user); bson_copy_to_excluding_noinit(doc, &user, "pwd", (char *)NULL); bson_append_utf8(&user, "pwd", 3, pwd, -1); } if (!mongoc_collection_save(collection, &user, NULL, error)) { GOTO (failure_with_user); } ret = true; failure_with_user: bson_destroy(&user); failure: if (cursor) { mongoc_cursor_destroy(cursor); } mongoc_collection_destroy(collection); bson_destroy(&query); bson_free(pwd); RETURN (ret); }
static bool mongoc_uri_parse_option (mongoc_uri_t *uri, const char *str) { int32_t v_int; const char *end_key; char *key; char *value; if (!(key = scan_to_unichar(str, '=', "", &end_key))) { return false; } value = bson_strdup(end_key + 1); mongoc_uri_do_unescape(&value); if (!strcasecmp(key, "connecttimeoutms") || !strcasecmp(key, "sockettimeoutms") || !strcasecmp(key, "maxpoolsize") || !strcasecmp(key, "minpoolsize") || !strcasecmp(key, "maxidletimems") || !strcasecmp(key, "waitqueuemultiple") || !strcasecmp(key, "waitqueuetimeoutms") || !strcasecmp(key, "wtimeoutms")) { v_int = (int) strtol (value, NULL, 10); bson_append_int32(&uri->options, key, -1, v_int); } else if (!strcasecmp(key, "w")) { if (*value == '-' || isdigit(*value)) { v_int = (int) strtol (value, NULL, 10); BSON_APPEND_INT32 (&uri->options, "w", v_int); } else if (0 == strcasecmp (value, "majority")) { BSON_APPEND_UTF8 (&uri->options, "w", "majority"); } else if (*value) { BSON_APPEND_UTF8 (&uri->options, "W", value); } } else if (!strcasecmp(key, "canonicalizeHostname") || !strcasecmp(key, "journal") || !strcasecmp(key, "safe") || !strcasecmp(key, "slaveok") || !strcasecmp(key, "ssl")) { bson_append_bool (&uri->options, key, -1, (0 == strcasecmp (value, "true")) || (0 == strcasecmp (value, "t")) || (0 == strcmp (value, "1"))); } else if (!strcasecmp(key, "readpreferencetags")) { mongoc_uri_parse_tags(uri, value, &uri->read_prefs); } else if (!strcasecmp(key, "authmechanism") || !strcasecmp(key, "authsource")) { bson_append_utf8(&uri->credentials, key, -1, value, -1); } else if (!strcasecmp(key, "authmechanismproperties")) { if (!mongoc_uri_parse_auth_mechanism_properties(uri, value)) { bson_free(key); bson_free(value); return false; } } else { bson_append_utf8(&uri->options, key, -1, value, -1); } bson_free(key); bson_free(value); return true; }
void core::append(const types::b_bool& value) { stdx::string_view key = _impl->next_key(); bson_append_bool(_impl->back(), key.data(), key.length(), value.value); }
void Namespace::parseJSON(bson* &p, const char* json, jsmntok_t *tokens, int &tokenCursor, bool createNew, int elementCount) { if (_DEBUG) LOGI("parse"); char buf[100]; int autoKey = 0; char firstChar; int count = 0; char keyBuf[255]; char valueBuf[1024]; bool tokenIsKey = false; for (int i(0); i < elementCount; i++) { jsmntok_t token = tokens[tokenCursor]; tokenIsKey = false; // check if the token contains a key (look for ':' within 5 chars after its end for (int k(0); k < 5; k++) { { if (json[token.end + k] == ':') { memcpy(keyBuf, &json[token.start], token.end - token.start); keyBuf[token.end - token.start] = '\0'; tokenIsKey = true; break; } } } if (tokenIsKey) { tokenCursor++; continue; // that token was key, continue with the rest } switch (token.type) { case JSMN_ARRAY: count = token.size; bson_append_start_array(p, keyBuf); tokenCursor++; parseJSON(p, json, tokens, tokenCursor, false, token.size); bson_append_finish_array(p); break; case JSMN_OBJECT: if (createNew) { createNew = false; tokenCursor++; parseJSON(p, json, tokens, tokenCursor, false, token.size); } else { bson_append_start_object(p, keyBuf); tokenCursor++; parseJSON(p, json, tokens, tokenCursor, false, token.size); bson_append_finish_object(p); } break; case JSMN_STRING: memcpy(valueBuf, &json[token.start], token.end - token.start); valueBuf[token.end - token.start] = '\0'; bson_append_string(p, keyBuf, valueBuf); tokenCursor++; break; case JSMN_PRIMITIVE: firstChar = json[token.start]; if (firstChar == 't' || firstChar == 'f') { // todo: wrong boolean parameter memcpy(valueBuf, &json[token.start], token.end - token.start); valueBuf[token.end - token.start] = '\0'; bson_append_bool(p, keyBuf, atoi(valueBuf)); } else if (firstChar == 'n') { bson_append_null(p, keyBuf); } else { memcpy(valueBuf, &json[token.start], token.end - token.start); valueBuf[token.end - token.start] = '\0'; double v = atof(valueBuf); if (fmod(v, 1) == 0) { /* variable is an integer */ bson_append_int(p, keyBuf, (int) v); } else { bson_append_double(p, keyBuf, v); } } tokenCursor++; break; default: break; } } }
/* Construct and send the aggregate command and create the resulting cursor. * Returns false on error, and sets stream->err. On error, stream->cursor * remains NULL, otherwise it is created and must be destroyed. */ static bool _make_cursor (mongoc_change_stream_t *stream) { mongoc_client_session_t *cs = NULL; bson_t command_opts; bson_t command; /* { aggregate: "coll", pipeline: [], ... } */ bson_t reply; bson_iter_t iter; mongoc_server_description_t *sd; uint32_t server_id; BSON_ASSERT (stream); BSON_ASSERT (!stream->cursor); _make_command (stream, &command); bson_copy_to (&stream->opts, &command_opts); sd = mongoc_client_select_server (stream->coll->client, false /* for_writes */, stream->coll->read_prefs, &stream->err); if (!sd) { goto cleanup; } server_id = mongoc_server_description_id (sd); bson_append_int32 (&command_opts, "serverId", 8, server_id); mongoc_server_description_destroy (sd); if (bson_iter_init_find (&iter, &command_opts, "sessionId")) { if (!_mongoc_client_session_from_iter ( stream->coll->client, &iter, &cs, &stream->err)) { goto cleanup; } } else if (stream->implicit_session) { /* If an implicit session was created before, and this cursor is now * being recreated after resuming, then use the same session as before. */ cs = stream->implicit_session; if (!mongoc_client_session_append (cs, &command_opts, &stream->err)) { goto cleanup; } } else { /* Create an implicit session. This session lsid must be the same for the * agg command and the subsequent getMores. Thus, this implicit session is * passed as if it were an explicit session to * collection_read_command_with_opts and cursor_new_from_reply, but it is * still implicit and its lifetime is owned by this change_stream_t. */ mongoc_session_opt_t *session_opts; session_opts = mongoc_session_opts_new (); mongoc_session_opts_set_causal_consistency (session_opts, false); /* returns NULL if sessions aren't supported. ignore errors. */ cs = mongoc_client_start_session (stream->coll->client, session_opts, NULL); stream->implicit_session = cs; mongoc_session_opts_destroy (session_opts); if (cs && !mongoc_client_session_append (cs, &command_opts, &stream->err)) { goto cleanup; } } /* use inherited read preference and read concern of the collection */ if (!mongoc_collection_read_command_with_opts ( stream->coll, &command, NULL, &command_opts, &reply, &stream->err)) { bson_destroy (&stream->err_doc); bson_copy_to (&reply, &stream->err_doc); bson_destroy (&reply); goto cleanup; } stream->cursor = mongoc_cursor_new_from_command_reply ( stream->coll->client, &reply, server_id); /* steals reply */ if (cs) { stream->cursor->client_session = cs; stream->cursor->explicit_session = true; } /* maxTimeMS is only appended to getMores if these are set in cursor opts */ bson_append_bool (&stream->cursor->opts, MONGOC_CURSOR_TAILABLE, MONGOC_CURSOR_TAILABLE_LEN, true); bson_append_bool (&stream->cursor->opts, MONGOC_CURSOR_AWAIT_DATA, MONGOC_CURSOR_AWAIT_DATA_LEN, true); if (stream->max_await_time_ms > 0) { BSON_ASSERT ( _mongoc_cursor_set_opt_int64 (stream->cursor, MONGOC_CURSOR_MAX_AWAIT_TIME_MS, stream->max_await_time_ms)); } if (stream->batch_size > 0) { mongoc_cursor_set_batch_size (stream->cursor, (uint32_t) stream->batch_size); } cleanup: bson_destroy (&command); bson_destroy (&command_opts); return stream->err.code == 0; }