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; }
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; }
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; }
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); }
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; }
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; }
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; }
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; }
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; }
/** * \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; }
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; }
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 */