Пример #1
0
int main() {

    mongo conn[1];

    INIT_SOCKETS_FOR_WINDOWS;
    CONN_CLIENT_TEST;

    mongo_cmd_drop_db( conn, db );

    ASSERT( mongo_cmd_authenticate( conn, db, "user", "password" ) == MONGO_ERROR );
    mongo_cmd_add_user( conn, db, "user", "password" );
    ASSERT( mongo_cmd_authenticate( conn, db, "user", "password" ) == MONGO_OK );

    mongo_cmd_drop_db( conn, db );
    mongo_destroy( conn );
    return 0;
}
Пример #2
0
int main(int argc, char **argv) {

    mongo conn[1];

    GETSERVERNAME;
INIT_SOCKETS_FOR_WINDOWS;
    CONN_CLIENT_TEST(_servername)(_servername);

    mongo_cmd_drop_db( conn, db );

    ASSERT( mongo_cmd_authenticate( conn, db, "user", "password" ) == MONGO_ERROR );
    mongo_cmd_add_user( conn, db, "user", "password" );
    ASSERT( mongo_cmd_authenticate( conn, db, "user", "password" ) == MONGO_OK );

    mongo_cmd_drop_db( conn, db );
    mongo_destroy( conn );
    return 0;
}
Пример #3
0
SEXP mongo_authenticate(SEXP mongo_conn, SEXP user, SEXP pass, SEXP db) {
    mongo* conn = _checkMongo(mongo_conn);
    const char* _user = CHAR(STRING_ELT(user, 0));
    const char* _pass = CHAR(STRING_ELT(pass, 0));
    const char* _db = CHAR(STRING_ELT(db, 0));
    SEXP ret;
    PROTECT(ret = allocVector(LGLSXP, 1));
    LOGICAL(ret)[0] = (mongo_cmd_authenticate(conn, _db, _user, _pass) == MONGO_OK);
    UNPROTECT(1);
    return ret;
}
Пример #4
0
static ngx_int_t ngx_http_mongo_authenticate(ngx_log_t *log, ngx_http_gridfs_loc_conf_t *gridfs_loc_conf) {
    ngx_http_mongo_connection_t* mongo_conn;
    ngx_http_mongo_auth_t *mongo_auth;
    mongo_cursor *cursor = NULL;
    bson empty;
    char *test;
    int error;

    mongo_conn = ngx_http_get_mongo_connection( gridfs_loc_conf->mongo );
    if (mongo_conn == NULL) {
        ngx_log_error(NGX_LOG_ERR, log, 0,
                  "Mongo Connection not found: \"%V\"", &gridfs_loc_conf->mongo);
    }

    // Authenticate
    if (gridfs_loc_conf->user.data != NULL && gridfs_loc_conf->pass.data != NULL) {
        if (mongo_cmd_authenticate( &mongo_conn->conn,
				    (const char*)gridfs_loc_conf->db.data,
				    (const char*)gridfs_loc_conf->user.data,
				    (const char*)gridfs_loc_conf->pass.data )
	    != MONGO_OK) {
            ngx_log_error(NGX_LOG_ERR, log, 0,
                          "Invalid mongo user/pass: %s/%s",
                          gridfs_loc_conf->user.data,
                          gridfs_loc_conf->pass.data);
            return NGX_ERROR;
        }

        mongo_auth = ngx_array_push(mongo_conn->auths);
        mongo_auth->db = gridfs_loc_conf->db;
        mongo_auth->user = gridfs_loc_conf->user;
        mongo_auth->pass = gridfs_loc_conf->pass;
    }

    // Run a test command to test authentication.
    test = (char*)malloc( gridfs_loc_conf->db.len + sizeof(".test"));
    ngx_cpystrn((u_char*)test, (u_char*)gridfs_loc_conf->db.data, gridfs_loc_conf->db.len+1);
    ngx_cpystrn((u_char*)(test+gridfs_loc_conf->db.len),(u_char*)".test", sizeof(".test"));
    bson_empty(&empty);
    cursor = mongo_find(&mongo_conn->conn, test, &empty, NULL, 0, 0, 0);
    error =  mongo_cmd_get_last_error(&mongo_conn->conn, (char*)gridfs_loc_conf->db.data, NULL);
    free(test);
    mongo_cursor_destroy(cursor);
    if (error) {
        ngx_log_error(NGX_LOG_ERR, log, 0, "Authentication Required");
        return NGX_ERROR;
    }

    return NGX_OK;
}
bool TMongoDriver::open(const QString &db, const QString &user, const QString &password, const QString &host, quint16 port, const QString &)
{
    if (host.isEmpty()) {
        return false;
    }

    if (!port)
        port = MONGO_DEFAULT_PORT;

    mongo_clear_errors(mongoConnection);
    mongo_set_op_timeout(mongoConnection, 1000);
    int status = mongo_client(mongoConnection, qPrintable(host), port);

    if (status != MONGO_OK) {
        switch (mongoConnection->err) {
        case MONGO_CONN_NO_SOCKET:
            tSystemError("MongoDB socket error: %s", mongoConnection->lasterrstr);
            break;

        case MONGO_CONN_FAIL:
            tSystemError("MongoDB connection failed: %s", mongoConnection->lasterrstr);
            break;

        case MONGO_CONN_NOT_MASTER:
            tSystemDebug("MongoDB not master: %s", mongoConnection->lasterrstr);
            break;

        default:
            tSystemError("MongoDB error: %s", mongoConnection->lasterrstr);
            break;
        }
        return false;
    }

    if (!user.isEmpty()) {
        status = mongo_cmd_authenticate(mongoConnection, qPrintable(db), qPrintable(user), qPrintable(password));
        if (status != MONGO_OK) {
            tSystemDebug("MongoDB authentication error: %s", mongoConnection->lasterrstr);
            return false;
        }
    }

    return (status == MONGO_OK);
}
Пример #6
0
static ngx_int_t ngx_http_mongo_reauth(ngx_log_t *log, ngx_http_mongo_connection_t *mongo_conn) {
    ngx_http_mongo_auth_t *auths;
    volatile ngx_uint_t i, success = 0;
    auths = mongo_conn->auths->elts;

    for (i = 0; i < mongo_conn->auths->nelts; i++) {
        success = mongo_cmd_authenticate( &mongo_conn->conn, 
                                          (const char*)auths[i].db.data, 
                                          (const char*)auths[i].user.data, 
                                          (const char*)auths[i].pass.data );
        if (!success) {
            ngx_log_error(NGX_LOG_ERR, log, 0,
                          "Invalid mongo user/pass: %s/%s, during reauth", 
                          auths[i].user.data, 
                          auths[i].pass.data);   
            return NGX_ERROR;
        }
    }
    
    return NGX_OK;
}
Пример #7
0
static switch_status_t cdr_mongo_authenticate() {
	switch_status_t status = SWITCH_STATUS_SUCCESS;
	mongo_error_t db_status;
	char *ns_tmp, *ns_split[2];

	/* Split namespace db.collection into separate vars */
	switch_strdup(ns_tmp, globals.mongo_namespace);
	switch_separate_string(ns_tmp, '.', ns_split, 2);

	db_status = mongo_cmd_authenticate(globals.mongo_conn, ns_split[0], globals.mongo_username, globals.mongo_password);

	if (db_status != MONGO_OK) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mongo_cmd_authenticate: authentication failed\n");
		status = SWITCH_STATUS_FALSE;
	} else {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Successfully authenticated %s@%s\n", globals.mongo_username, ns_split[0]);
	}

	switch_safe_free(ns_tmp);
	return status;
}
Пример #8
0
static int mongodb_log(struct ast_cdr *cdr)
{
	const char * ns;
	mongo conn[1];

	ast_debug(1, "mongodb: Starting mongodb_log.\n");

	mongo_init( &conn );
	if (mongo_connect( &conn , ast_str_buffer(hostname), dbport ) != MONGO_OK){
		mongo_destroy( &conn );
		ast_log(LOG_ERROR, "Method: mongodb_log, MongoDB failed to connect.\n");
		connected = 0;
		records = 0;
		return -1;
	}

	if (ast_str_strlen(dbuser) != 0 && (mongo_cmd_authenticate(&conn, ast_str_buffer(dbname), ast_str_buffer(dbuser), ast_str_buffer(password)) != MONGO_OK)) {
		mongo_destroy( &conn );
		ast_log(LOG_ERROR, "Method: mongodb_log, MongoDB failed to authenticate to do %s with username %s!\n", ast_str_buffer(dbname), ast_str_buffer(dbuser));
		connected = 0;
		records = 0;
		return -1;
	}

	ast_debug(1, "mongodb: Locking mongodb_lock.\n");
	ast_mutex_lock(&mongodb_lock);

	ast_debug(1, "mongodb: Got connection, Preparing record.\n");

	bson b[1];

	ast_debug(1, "mongodb: Init bson.\n");
	bson_init( &b );
	bson_append_new_oid( &b, "_id" );
	
	ast_debug(1, "mongodb: accountcode.\n");
	bson_append_string( &b , "accountcode",  cdr->accountcode);

	ast_debug(1, "mongodb: src.\n");
	bson_append_string( &b , "src",  cdr->src);

	ast_debug(1, "mongodb: dst.\n");
	bson_append_string( &b, "dst" , cdr->dst );

	ast_debug(1, "mongodb: dcontext.\n");
	bson_append_string( &b, "dcontext" , cdr->dcontext );

	ast_debug(1, "mongodb: clid.\n");
	bson_append_string( &b, "clid" , cdr->clid );

	ast_debug(1, "mongodb: channel.\n");
	bson_append_string( &b, "channel" , cdr->channel );

	ast_debug(1, "mongodb: dstchannel.\n");
	bson_append_string( &b, "dstchannel" , cdr->dstchannel );

	ast_debug(1, "mongodb: lastapp.\n");
	bson_append_string( &b, "lastapp" , cdr->lastapp );

	ast_debug(1, "mongodb: lastdata.\n");
	bson_append_string( &b, "lastdata" , cdr->lastdata );

	ast_debug(1, "mongodb: start.\n");
	bson_append_date( &b, "start", (bson_date_t)cdr->start.tv_sec*1000);

	ast_debug(1, "mongodb: answer.\n");
	bson_append_date( &b, "answer", (bson_date_t)cdr->answer.tv_sec*1000);

	ast_debug(1, "mongodb: end.\n");
	bson_append_date( &b, "end" , (bson_date_t)cdr->end.tv_sec*1000);

	ast_debug(1, "mongodb: duration.\n");
	bson_append_int( &b, "duration" , cdr->duration );

	ast_debug(1, "mongodb: billsec.\n");
	bson_append_int( &b, "billsec" , cdr->billsec );

	ast_debug(1, "mongodb: disposition.\n");
	bson_append_string( &b, "disposition" , ast_cdr_disp2str(cdr->disposition) );

	ast_debug(1, "mongodb: amaflags.\n");
	bson_append_string( &b, "amaflags" , ast_cdr_flags2str(cdr->amaflags) );

	ast_debug(1, "mongodb: uniqueid.\n");
	bson_append_string( &b, "uniqueid" , cdr->uniqueid );

	ast_debug(1, "mongodb: userfield.\n");
	bson_append_string( &b, "userfield" , cdr->userfield );

	bson_finish(&b);

	ast_debug(1, "mongodb: Inserting a CDR record.\n");
	mongo_insert( &conn , ast_str_buffer(dbnamespace) , &b );
	bson_destroy(&b);
	mongo_destroy( &conn );

	connected = 1;
	records++;
	totalrecords++;

	ast_debug(1, "Unlocking mongodb_lock.\n");
	ast_mutex_unlock(&mongodb_lock);
	return 0;
}
Пример #9
0
static int _load_module(int reload)
{
    int res;
	struct ast_config *cfg;
	struct ast_variable *var;
	struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };

	mongo conn[1];
	bson b[1];

	ast_debug(1, "Starting mongodb module load.\n");
	ast_debug(1, "Loading mongodb Config.\n");

	if (!(cfg = ast_config_load(config, config_flags)) || cfg == CONFIG_STATUS_FILEINVALID) {
		ast_log(LOG_WARNING, "Unable to load config for mongodb CDR's: %s\n", config);
		return AST_MODULE_LOAD_SUCCESS;
	} else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
		return AST_MODULE_LOAD_SUCCESS;
	}


	if (reload) {
		_unload_module(1);
	}

	ast_debug(1, "Browsing mongodb Global.\n");
	var = ast_variable_browse(cfg, "global");
	if (!var) {
		return AST_MODULE_LOAD_SUCCESS;
	}

	res = 0;

	res |= load_config_string(cfg, "global", "hostname", &hostname, "localhost");
	res |= load_config_string(cfg, "global", "dbname", &dbname, "astriskcdrdb");
	res |= load_config_string(cfg, "global", "collection", &dbcollection, "cdr");
	res |= load_config_number(cfg, "global", "port", &dbport, 27017);
	res |= load_config_string(cfg, "global", "username", &dbuser, "");
	res |= load_config_string(cfg, "global", "password", &password, "");

	if (res < 0) {
		return AST_MODULE_LOAD_FAILURE;
	}

	ast_debug(1, "Got hostname of %s\n", ast_str_buffer(hostname));
	ast_debug(1, "Got port of %d\n", dbport);
	ast_debug(1, "Got dbname of %s\n", ast_str_buffer(dbname));
	ast_debug(1, "Got dbcollection of %s\n", ast_str_buffer(dbcollection));
	ast_debug(1, "Got user of %s\n", ast_str_buffer(dbuser));
	ast_debug(1, "Got password of %s\n", ast_str_buffer(password));
	
	
	dbnamespace = ast_str_create(255);
	ast_str_set(&dbnamespace, 0, "%s.%s", ast_str_buffer(dbname), ast_str_buffer(dbcollection));

	if (mongo_connect(&conn , ast_str_buffer(hostname), dbport) != MONGO_OK) {
		ast_log(LOG_ERROR, "Method: _load_module, MongoDB failed to connect to %s:%d!\n", ast_str_buffer(hostname), dbport);
		res = -1;
	} else {
		if (ast_str_strlen(dbuser) != 0 && (mongo_cmd_authenticate(&conn, ast_str_buffer(dbname), ast_str_buffer(dbuser), ast_str_buffer(password)) != MONGO_OK)) {
			ast_log(LOG_ERROR, "Method: _load_module, MongoDB failed to authenticate to do %s with username %s!\n", ast_str_buffer(dbname), ast_str_buffer(dbuser));
			res = -1;
		} else {
			connected = 1;
		}
		
		mongo_destroy(&conn);
	}

	ast_config_destroy(cfg);

	res = ast_cdr_register(name, desc, mongodb_log);
	if (res) {
		ast_log(LOG_ERROR, "Unable to register MongoDB CDR handling\n");
	} else {
		res = ast_cli_register_multiple(cdr_mongodb_status_cli, sizeof(cdr_mongodb_status_cli) / sizeof(struct ast_cli_entry));
	}

	return res;
}
Пример #10
0
result_t MongoDB::open(exlib::string connString)
{
    assert(!Isolate::check());

    obj_ptr<Url> u = new Url();
    int32_t result;
    int32_t nPort;

    result_t hr = u->parse(connString);
    if (hr < 0)
        return hr;

    if (qstrchr(u->m_host.c_str(), ','))
    {
        const char *host = u->m_host.c_str();

        mongo_replset_init(&m_conn, "");

        while (true)
        {
            exlib::string hostname;
            exlib::string port;

            Url::parseHost(host, hostname, port);

            nPort = 27017;
            if (!port.empty())
                nPort = atoi(port.c_str());

            mongo_replset_add_seed(&m_conn, hostname.c_str(), nPort);

            if (*host != ',')
                break;

            host++;
        }

        result = mongo_replset_connect(&m_conn);
    }
    else
    {
        nPort = 27017;
        if (!u->m_port.empty())
            nPort = atoi(u->m_port.c_str());

        mongo_init(&m_conn);
        result = mongo_client(&m_conn, u->m_hostname.c_str(), nPort);
    }

    if (result != MONGO_OK)
        return CHECK_ERROR(error());

    if (!u->m_pathname.empty())
        m_ns = u->m_pathname.substr(1);

    if (!u->m_username.empty())
        if (mongo_cmd_authenticate(&m_conn, m_ns.c_str(), u->m_username.c_str(),
                                   u->m_password.c_str()) != MONGO_OK)
            return CHECK_ERROR(error());

    return 0;
}
Пример #11
0
/**
 * \brief This function tries to connect to MongoDB server
 */
int vs_mongo_conn_init(struct VS_CTX *vs_ctx)
{
	int status;

	vs_ctx->mongo_conn = mongo_alloc();
	mongo_init(vs_ctx->mongo_conn);

	/* Set connection timeout */
	mongo_set_op_timeout(vs_ctx->mongo_conn, 1000);

	/* Connect to MongoDB server */
	status = mongo_client(vs_ctx->mongo_conn,
			vs_ctx->mongodb_server, vs_ctx->mongodb_port);

	if( status != MONGO_OK ) {
		switch ( vs_ctx->mongo_conn->err ) {
		case MONGO_CONN_NO_SOCKET:
			v_print_log(VRS_PRINT_ERROR,
					"No MongoDB server %s:%d socket\n",
					vs_ctx->mongodb_server, vs_ctx->mongodb_port);
			break;
		case MONGO_CONN_FAIL:
			v_print_log(VRS_PRINT_ERROR,
					"Connection to MongoDB server %s:%d failed\n",
					vs_ctx->mongodb_server, vs_ctx->mongodb_port);
			break;
		case MONGO_CONN_NOT_MASTER:
			v_print_log(VRS_PRINT_ERROR,
					"MongoDB server %s:%d is not master\n",
					vs_ctx->mongodb_server, vs_ctx->mongodb_port);
			break;
		default:
			v_print_log(VRS_PRINT_ERROR,
					"Failed to connect to MongoDB server %s:%d , error: %d\n",
					vs_ctx->mongodb_server, vs_ctx->mongodb_port,
					vs_ctx->mongo_conn->err);
			break;
		}
		mongo_dealloc(vs_ctx->mongo_conn);
		vs_ctx->mongo_conn = NULL;
		return 0;
	}

	v_print_log(VRS_PRINT_DEBUG_MSG,
			"Connection to MongoDB server %s:%d succeeded\n",
			vs_ctx->mongodb_server, vs_ctx->mongodb_port);

	/* There has to be some db name defined */
	if(vs_ctx->mongodb_db_name == NULL) {
		v_print_log(VRS_PRINT_ERROR,
				"No database name defined\n");
		mongo_dealloc(vs_ctx->mongo_conn);
		vs_ctx->mongo_conn = NULL;
		return 0;
	}

	/* Try to do  when authentication is configured */
	if(vs_ctx->mongodb_user != NULL &&
			vs_ctx->mongodb_pass != NULL)
	{
		status = mongo_cmd_authenticate(vs_ctx->mongo_conn,
				vs_ctx->mongodb_db_name,
				vs_ctx->mongodb_user,
				vs_ctx->mongodb_pass);

		if(status != MONGO_OK) {
			v_print_log(VRS_PRINT_ERROR,
					"Authentication to %s database failed, error: %s\n",
					vs_ctx->mongodb_db_name,
					mongo_get_server_err_string(vs_ctx->mongo_conn));
			mongo_dealloc(vs_ctx->mongo_conn);
			vs_ctx->mongo_conn = NULL;
			return 0;
		}

		v_print_log(VRS_PRINT_DEBUG_MSG,
				"Authentication to %s database succeeded\n",
				vs_ctx->mongodb_db_name);
	} else {
		v_print_log(VRS_PRINT_DEBUG_MSG,
				"No MongoDB authentication required\n");
	}

	/* Namespace used for storing nodes */
	vs_ctx->mongo_node_ns = (char*)malloc(sizeof(char) * (strlen(vs_ctx->mongodb_db_name) + 6 + 1));
	strcpy(vs_ctx->mongo_node_ns, vs_ctx->mongodb_db_name);
	strcat(vs_ctx->mongo_node_ns, ".nodes");

	/* Namespace used for storing tag groups and tags */
	vs_ctx->mongo_tg_ns = (char*)malloc(sizeof(char) * (strlen(vs_ctx->mongodb_db_name) + 11 + 1));
	strcpy(vs_ctx->mongo_tg_ns, vs_ctx->mongodb_db_name);
	strcat(vs_ctx->mongo_tg_ns, ".tag_groups");

	/* Namespace used for storing layers */
	vs_ctx->mongo_layer_ns = (char*)malloc(sizeof(char) * (strlen(vs_ctx->mongodb_db_name) + 7 + 1));
	strcpy(vs_ctx->mongo_layer_ns, vs_ctx->mongodb_db_name);
	strcat(vs_ctx->mongo_layer_ns, ".layers");

	return 1;
}
Пример #12
0
static ngx_int_t ngx_http_gridfs_mongod_connect(ngx_conf_t* directive, ngx_http_gridfs_loc_conf_t* gridfs_conf) {
    mongo_connection_options options;
    bson empty;
    bson_bool_t error;
    char* test;

    if (gridfs_conf->mongod_conn->connected) {
        ngx_conf_log_error(NGX_LOG_ERR, directive, 0,
			 "Mongo Connection is duplicate");
        return NGX_ERROR;
    }

    /* Connect to a mongod */
    ngx_cpystrn( (u_char*)options.host, 
		 gridfs_conf->mongod_host.data, 
		 gridfs_conf->mongod_host.len + 1 );
    options.port = gridfs_conf->mongod_port;
    switch (mongo_connect( gridfs_conf->mongod_conn, &options )) {
        case mongo_conn_success:
            break;
        case mongo_conn_bad_arg:
	    ngx_conf_log_error(NGX_LOG_ERR, directive, 0,
			       "Mongo Exception: Bad Arguments");
            return NGX_ERROR;
        case mongo_conn_no_socket:
            ngx_conf_log_error(NGX_LOG_ERR, directive, 0,
			       "Mongo Exception: No Socket");
            return NGX_ERROR;
        case mongo_conn_fail:
            ngx_conf_log_error(NGX_LOG_ERR, directive, 0,
			       "Mongo Exception: Connection Failure %s:%i;",
			       options.host,options.port/*
							  gridfs_conf->mongod_port*/);
            return NGX_ERROR;
        case mongo_conn_not_master:
            ngx_conf_log_error(NGX_LOG_ERR, directive, 0,
			       "Mongo Exception: Not Master");
            return NGX_ERROR;
        default:
            ngx_conf_log_error(NGX_LOG_ERR, directive, 0,
			       "Mongo Exception: Unknown Error");
            return NGX_ERROR;
    }
    
    /* Authenticate with the user and password */
    if (gridfs_conf->mongod_user.data != NULL && gridfs_conf->mongod_pass.data != NULL) {
        if (!mongo_cmd_authenticate(gridfs_conf->mongod_conn, 
				   (const char*)gridfs_conf->gridfs_db.data, 
				   (const char*)gridfs_conf->mongod_user.data, 
				   (const char*)gridfs_conf->mongod_pass.data)) {
	    ngx_conf_log_error(NGX_LOG_ERR, directive, 0,
			       "Invalid mongo user/pass: %s/%s", 
			       gridfs_conf->mongod_user.data, 
			       gridfs_conf->mongod_pass.data);
	    return NGX_ERROR;
        }
    }
    
    /* Run a test command to test authentication. */
    test = (char*)malloc( gridfs_conf->gridfs_db.len + sizeof(".test"));
    ngx_cpystrn((u_char*)test, (u_char*)gridfs_conf->gridfs_db.data, gridfs_conf->gridfs_db.len+1);
    ngx_cpystrn((u_char*)(test+gridfs_conf->gridfs_db.len),(u_char*)".test", sizeof(".test"));
    bson_empty(&empty);
    mongo_find(gridfs_conf->mongod_conn, test, &empty, NULL, 0, 0, 0);
    error =  mongo_cmd_get_last_error(gridfs_conf->mongod_conn, (char*)gridfs_conf->gridfs_db.data, NULL);
    free(test);
    if (error) {
      ngx_conf_log_error(NGX_LOG_ERR, directive, 0, "Authentication Required");
      return NGX_ERROR;
    }

    return NGX_OK;
}
Пример #13
0
static int wm_write (const data_set_t *ds, /* {{{ */
    const value_list_t *vl,
    user_data_t *ud)
{
  wm_node_t *node = ud->data;
  char collection_name[512];
  bson *bson_record;
  int status;

  ssnprintf (collection_name, sizeof (collection_name), "collectd.%s",
      vl->plugin);

  bson_record = wm_create_bson (ds, vl, node->store_rates);
  if (bson_record == NULL)
    return (ENOMEM);

  pthread_mutex_lock (&node->lock);

  if (!mongo_is_connected (node->conn))
  {
    INFO ("write_mongodb plugin: Connecting to [%s]:%i",
        (node->host != NULL) ? node->host : "localhost",
        (node->port != 0) ? node->port : MONGO_DEFAULT_PORT);
    status = mongo_connect (node->conn, node->host, node->port);
    if (status != MONGO_OK) {
      ERROR ("write_mongodb plugin: Connecting to [%s]:%i failed.",
          (node->host != NULL) ? node->host : "localhost",
          (node->port != 0) ? node->port : MONGO_DEFAULT_PORT);
      mongo_destroy (node->conn);
      pthread_mutex_unlock (&node->lock);
      return (-1);
    }

    if ((node->db != NULL) && (node->user != NULL) && (node->passwd != NULL))
    {
      status = mongo_cmd_authenticate (node->conn,
          node->db, node->user, node->passwd);
      if (status != MONGO_OK)
      {
        ERROR ("write_mongodb plugin: Authenticating to [%s]%i for database "
            "\"%s\" as user \"%s\" failed.",
          (node->host != NULL) ? node->host : "localhost",
          (node->port != 0) ? node->port : MONGO_DEFAULT_PORT,
          node->db, node->user);
        mongo_destroy (node->conn);
        pthread_mutex_unlock (&node->lock);
        return (-1);
      }
    }

    if (node->timeout > 0) {
      status = mongo_set_op_timeout (node->conn, node->timeout);
      if (status != MONGO_OK) {
        WARNING ("write_mongodb plugin: mongo_set_op_timeout(%i) failed: %s",
            node->timeout, node->conn->errstr);
      }
    }
  }

  /* Assert if the connection has been established */
  assert (mongo_is_connected (node->conn));

  #if MONGO_MINOR >= 6
    /* There was an API change in 0.6.0 as linked below */
    /* https://github.com/mongodb/mongo-c-driver/blob/master/HISTORY.md */
    status = mongo_insert (node->conn, collection_name, bson_record, NULL);
  #else
    status = mongo_insert (node->conn, collection_name, bson_record);
  #endif

  if (status != MONGO_OK)
  {
    ERROR ( "write_mongodb plugin: error inserting record: %d", node->conn->err);
    if (node->conn->err != MONGO_BSON_INVALID)
      ERROR ("write_mongodb plugin: %s", node->conn->errstr);
    else
      ERROR ("write_mongodb plugin: Invalid BSON structure, error = %#x",
          (unsigned int) bson_record->err);

    /* Disconnect except on data errors. */
    if ((node->conn->err != MONGO_BSON_INVALID)
        && (node->conn->err != MONGO_BSON_NOT_FINISHED))
      mongo_destroy (node->conn);
  }

  pthread_mutex_unlock (&node->lock);

  /* free our resource as not to leak memory */
  bson_destroy (bson_record); /* matches bson_init() */
  bson_dealloc (bson_record); /* matches bson_alloc() */

  return (0);
} /* }}} int wm_write */