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);
}
Example #2
0
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;
}
Example #3
0
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);
}
Example #4
0
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;
		}
	}
}
Example #5
0
/* 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;
}