void test_mongo_sync_cmd_get_last_error (void) { mongo_sync_connection *c; gchar *error; test_env_setup (); c = test_make_fake_sync_conn (-1, FALSE); errno = 0; ok (mongo_sync_cmd_get_last_error (NULL, config.db, &error) == FALSE, "mongo_sync_cmd_get_last_error() returns FALSE with a NULL connection"); cmp_ok (errno, "==", ENOTCONN, "errno is set to ENOTCONN"); ok (mongo_sync_cmd_get_last_error (c, NULL, &error) == FALSE, "mongo_sync_cmd_get_last_error() fails with a NULL db"); errno = 0; ok (mongo_sync_cmd_get_last_error (c, config.db, NULL) == FALSE, "mongo_sync_cmd_get_last_error() fails with a NULL error destination"); cmp_ok (errno, "==", EINVAL, "errno is set to EINVAL"); mongo_sync_disconnect (c); test_env_free (); }
static void do_query (mongo_sync_connection *conn) { mongo_sync_cursor *c; bson *query; gchar *error = NULL; query = bson_build (BSON_TYPE_TIMESTAMP, "processed", 1294860709000, BSON_TYPE_NONE); bson_finish (query); c = mongo_sync_cursor_new (conn, "blahblah.plurals", mongo_sync_cmd_query (conn, "blahblah.plurals", 0, 0, 10, query, NULL)); if (!c) { fprintf (stderr, "Error creating the query cursor: %s\n", strerror (errno)); exit (1); } bson_free (query); while (mongo_sync_cursor_next (c)) { bson *b = mongo_sync_cursor_get_data (c); bson_cursor *bc; gint32 w_t; gint64 w_i; if (!b) { int e = errno; mongo_sync_cmd_get_last_error (conn, "blahblah.plurals", &error); fprintf (stderr, "Error retrieving cursor data: %s\n", (error) ? error : strerror (e)); exit (1); } bc = bson_find (b, "word_type"); bson_cursor_get_int32 (bc, &w_t); printf ("\rWord type: %d\n", w_t); bc = bson_find (b, "word_id"); bson_cursor_get_int64 (bc, &w_i); printf ("\rWord id: %d\n", (int)w_i); bson_cursor_free (bc); bson_free (b); } printf ("\n"); mongo_sync_cursor_free (c); }
static void do_query (mongo_sync_connection *conn) { mongo_sync_cursor *c; bson *query; gchar *error = NULL; query = bson_build (BSON_TYPE_STRING, "tutorial-program", "tut_hl_client.c", -1, BSON_TYPE_NONE); bson_finish (query); c = mongo_sync_cursor_new (conn, "lmc.tutorial", mongo_sync_cmd_query (conn, "lmc.tutorial", 0, 0, 10, query, NULL)); if (!c) { fprintf (stderr, "Error creating the query cursor: %s\n", strerror (errno)); exit (1); } bson_free (query); while (mongo_sync_cursor_next (c)) { bson *b = mongo_sync_cursor_get_data (c); bson_cursor *bc; gint32 cnt; if (!b) { int e = errno; mongo_sync_cmd_get_last_error (conn, "lmc", &error); fprintf (stderr, "Error retrieving cursor data: %s\n", (error) ? error : strerror (e)); exit (1); } bc = bson_find (b, "counter"); bson_cursor_get_int32 (bc, &cnt); printf ("\rCounter: %d", cnt); bson_cursor_free (bc); bson_free (b); } printf ("\n"); mongo_sync_cursor_free (c); }
/** * pam_sm_authenticate() * pamh - Handle to PAM structure/interface [in] * flags - Special settings for PAM (PAM_SILENT or PAM_DISALLKOW_NULL_AUTHTOK) [in] * argc - Number of arguments that are being passed to the module [in] * argv - Arguments that have been passed to module [in] * * Handler function for PAM. This is needed for authentication to happen. **/ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char *argv[]){ struct pam_conv *conv; // Ability to prompt user for information or display text struct pam_message msg[5], *msgp; // Structure for pam_conv{} (holds values for prompts) struct pam_response *resp; // Contains the user's response of conv // Holds username of current user (why pam_get_user() asks for a const char, I don't know...) const char *user; // Holder values for both db_user and db_pass (LOGIN_NAME_MAX is generally 256) char db_user[LOGIN_NAME_MAX] = {'\0'}; char db_pass[LOGIN_NAME_MAX] = {'\0'}; // Stores data for both prompts and user's answers (see below) char *answer, *prompt[5]; // Holder for return values of PAM functions (defaults to PAM_SUCCESS if nothing changes) int pam_err = PAM_SUCCESS; // Useful struct for options struct options opts; // Actually parses all of the options we were given parse_options(argc, argv, &opts); // Used for MongoDB connection mongo_sync_connection *conn; // Holds errno value so it doesn't get erased int e; // Since mongo-client uses glib, we have to use some glib-typecast variables gchar *error = NULL; // Set up PAM to allow us to use conversation items pam_err = pam_get_item(pamh, PAM_CONV, (const void**)&conv); // Failed to get items if(pam_err != PAM_SUCCESS) return PAM_SYSTEM_ERR; // Get username that's trying to authenticate pam_err = pam_get_user(pamh, &user, NULL); // Unable to do this, so we have to return failure if(pam_err != PAM_SUCCESS){ printf("Unable to get login name: %s", pam_strerror(pamh, pam_err)); return PAM_AUTH_ERR; } // Set up prompts to ask the user prompt[0] = (char*)strdup("Username (leave blank for log in name): "); prompt[1] = (char*)strdup("Password: "******"Server Host or IP: "); prompt[3] = (char*)strdup("Port number: "); prompt[4] = (char*)strdup("Database: "); /** * msg_style: * Sets display of user's text while inputting. * PAM_PROMPT_ECHO_ON - Display what the user types (less secure) * PAM_PROMPT_ECHO_OFF - Don't dispaly what the user types (more secure) * * For msg[2] - msg[4], if you want it to be more secretive/secure, then * change the msg_style. I did this just because I can. **/ msg[0].msg_style = PAM_PROMPT_ECHO_ON; msg[0].msg = prompt[0]; msg[1].msg_style = PAM_PROMPT_ECHO_OFF; msg[1].msg = prompt[1]; msg[2].msg_style = PAM_PROMPT_ECHO_ON; msg[2].msg = prompt[2]; msg[3].msg_style = PAM_PROMPT_ECHO_ON; msg[3].msg = prompt[3]; msg[4].msg_style = PAM_PROMPT_ECHO_ON; msg[4].msg = prompt[4]; // If user is to answer all fields, prompt for all, otherwise just ask for username & password int end = (opts.ask_all == 1) ? 5 : 2; int cred = 0; for(; cred < end; cred++){ // Get a pointer to the current message to ask the user msgp = &msg[cred]; // Sanity check to make sure no response is carried over resp = NULL; // Ask the user (&msg), getting the input (&resp)...argument 1 cannot be more than 1 pam_err = (*conv->conv)(1,(const struct pam_message**)&msgp,&resp,conv->appdata_ptr); // Nothing went wrong! if(pam_err == PAM_SUCCESS){ // Store the user's response into a buffer answer = resp->resp; // We don't want something longer than our buffers can hold if(strlen(answer) > LOGIN_NAME_MAX){ pam_err = PAM_SERVICE_ERR; break; } // If no answer was given AND we already asked for the username, error out if(!answer && (cred != 0)){ pam_err = PAM_AUTH_ERR; break; } // If asked for username... if(cred == 0){ // ...and no response, make it logged in user, otherwise use the given name if(!answer) sprintf(db_user, "%s", user); else sprintf(db_user, "%s", answer); } else{ if(cred == 1) sprintf(db_pass, "%s", answer); else if(cred == 2) sprintf(opts.server, "%s", answer); else if(cred == 3) opts.port = atoi(answer); else if(cred == 4) sprintf(opts.db, "%s", answer); } } } if(pam_err != PAM_SUCCESS){ printf("Issue making a conversation.\n"); return PAM_SYSTEM_ERR; } // Connect to MongoDB server conn = mongo_sync_connect((gchar*)opts.server, opts.port, 0); // In the event an issue happens, store the errno into buffer e e = errno; if(!conn){ printf("Unable to connect to mongoDB server (%d).\n", e); // Should this be PAM_SYSTEM_ERR instead? It's really neither but...yeah return PAM_AUTH_ERR; } // No issues so far, time to authenticate if(pam_err == PAM_SUCCESS){ // Another glib typecast...have to typecast db, user & pass due to (gchar*) != (char*) gboolean auth = mongo_sync_cmd_authenticate(conn, (gchar*)opts.db, (gchar*)db_user, (gchar*)db_pass); int errn = errno; // Authentication failed (usually a connectivity issue) if(!auth){ gchar *err = NULL; // Get the last error, and store it into err mongo_sync_cmd_get_last_error(conn, opts.db, &err); // Tell the user the message (errn tends to more specific surprisingly) printf("Unable to authenticate with mongoDB %d (%s).\n", errn, err); // Free up allocation space g_free(err); // We failed to authenticate pam_err = PAM_AUTH_ERR; } else printf("Successful authentication.\n"); } // Use this to free up any space left by the conversation if(resp){ if(resp > resp) free(resp->resp); free(resp); } // Must be called to close the socket to the server. mongo_sync_disconnect(conn); return pam_err; }
void mongo_dump (config_t *config) { mongo_sync_connection *conn; mongo_sync_cursor *cursor; bson *b; int fd; glong cnt, pos = 0; gchar *error = NULL; int e; if (config->port == MONGO_CONN_LOCAL) { VLOG ("Connecting to %s/%s.%s...\n", config->addr, config->db, config->coll); } else { VLOG ("Connecting to %s:%d/%s.%s...\n", config->addr, config->port, config->db, config->coll); } conn = mongo_sync_connect (config->addr, config->port, config->slaveok); if (!conn) { e = errno; mongo_sync_cmd_get_last_error (conn, config->db, &error); fprintf (stderr, "Error connecting to %s:%d: %s\n", config->addr, config->port, (error) ? error : strerror (e)); g_free (error); exit (1); } if (config->master_sync) { VLOG ("Syncing to master...\n"); conn = mongo_sync_reconnect (conn, TRUE); if (!conn) { e = errno; mongo_sync_cmd_get_last_error (conn, config->db, &error); fprintf (stderr, "Error reconnecting to the master of %s:%d: %s\n", config->addr, config->port, (error) ? error : strerror (e)); exit (1); } } VLOG ("Counting documents...\n"); cnt = mongo_sync_cmd_count (conn, config->db, config->coll, NULL); if (cnt < 0) { e = errno; mongo_sync_cmd_get_last_error (conn, config->db, &error); fprintf (stderr, "Error counting documents in %s.%s: %s\n", config->db, config->coll, (error) ? error : strerror (e)); mongo_sync_disconnect (conn); exit (1); } VLOG ("Opening output file '%s'...\n", config->output); if (strcmp (config->output, "-") == 0) fd = 1; else { fd = open (config->output, O_RDWR | O_CREAT | O_TRUNC, 0600); if (fd == -1) { fprintf (stderr, "Error opening output file '%s': %s\n", config->output, strerror (errno)); mongo_sync_disconnect (conn); exit (1); } } VLOG ("Launching initial query...\n"); b = bson_new (); bson_finish (b); cursor = mongo_sync_cursor_new (conn, config->ns, mongo_sync_cmd_query (conn, config->ns, MONGO_WIRE_FLAG_QUERY_NO_CURSOR_TIMEOUT, 0, 10, b, NULL)); bson_free (b); while ((pos < cnt) && mongo_sync_cursor_next (cursor)) { bson *b = mongo_sync_cursor_get_data (cursor); pos++; if (!b) { e = errno; mongo_sync_cmd_get_last_error (conn, config->db, &error); fprintf (stderr, "Error advancing the cursor: %s\n", (error) ? error : strerror (e)); mongo_sync_disconnect (conn); exit (1); } if (pos % 10 == 0) VLOG ("\rDumping... %03.2f%%", (pos * 1.0) / (cnt * 1.0) * 100); if (write (fd, bson_data (b), bson_size (b)) != bson_size (b)) { perror ("write()"); exit (1); } bson_free (b); } VLOG ("\rDumping... %03.2f%%\n", (double)((pos / cnt) * 100)); mongo_sync_cursor_free (cursor); close (fd); mongo_sync_disconnect (conn); }
void test_func_mongo_sync_safe_mode (void) { mongo_sync_connection *conn; const bson *docs[10]; bson *b1, *b2, *b3, *b4, *cmd; mongo_packet *p; gchar *error; mongo_util_oid_init (0); b1 = bson_new (); bson_append_string (b1, "func_mongo_sync_safe_mode", "works", -1); bson_finish (b1); b2 = bson_new (); bson_append_int32 (b2, "int32", 1984); bson_finish (b2); b3 = test_bson_generate_full (); b4 = test_bson_generate_full (); docs[0] = b1; docs[1] = b2; docs[2] = b3; docs[3] = b4; conn = mongo_sync_connect (config.primary_host, config.primary_port, FALSE); /* Test inserts */ mongo_sync_conn_set_safe_mode (conn, FALSE); ok (mongo_sync_cmd_insert_n (conn, config.ns, 4, docs) == TRUE, "mongo_sync_cmd_insert_n() should not fail with safe mode off"); mongo_sync_conn_set_safe_mode (conn, TRUE); ok (mongo_sync_cmd_insert_n (conn, config.ns, 4, docs) == FALSE, "mongo_sync_cmd_insert_n() should fail with safe mode on"); /* Test a custom command */ cmd = bson_new (); bson_append_int32 (cmd, "bogusCommand", 1); bson_finish (cmd); mongo_sync_cmd_reset_error (conn, config.db); mongo_sync_conn_set_safe_mode (conn, FALSE); p = mongo_sync_cmd_custom (conn, config.db, cmd); mongo_sync_cmd_get_last_error (conn, config.db, &error); ok (p == NULL && strcmp (error, "no such cmd: bogusCommand") == 0, "mongo_sync_cmd_custom() with a bogus command fails with safe-mode off"); bson_free (cmd); cmd = bson_new (); bson_append_int32 (cmd, "bogusCommand2", 1); bson_finish (cmd); mongo_sync_cmd_reset_error (conn, config.db); mongo_sync_conn_set_safe_mode (conn, TRUE); p = mongo_sync_cmd_custom (conn, config.db, cmd); mongo_sync_cmd_get_last_error (conn, config.db, &error); ok (p == NULL && strcmp (error, "no such cmd: bogusCommand2") == 0, "mongo_sync_cmd_custom() with a bogus command fails with safe-mode on"); bson_free (cmd); mongo_sync_disconnect (conn); bson_free (b1); bson_free (b2); bson_free (b3); bson_free (b4); }
int mongo_dump (config_t *config) { mongo_sync_connection *conn; bson *b; int fd; mongo_packet *p; mongo_reply_packet_header rh; gint64 cid; gdouble cnt, pos = 0; gchar *error; int e; VLOG ("Connecting to %s:%d/%s.%s...\n", config->host, config->port, config->db, config->coll); conn = mongo_sync_connect (config->host, config->port, config->slaveok); if (!conn) { e = errno; mongo_sync_cmd_get_last_error (conn, config->db, &error); fprintf (stderr, "Error connecting to %s:%d: %s\n", config->host, config->port, (error) ? error : strerror (e)); g_free (error); exit (1); } if (config->master_sync) { VLOG ("Syncing to master...\n"); conn = mongo_sync_reconnect (conn, TRUE); if (!conn) { e = errno; mongo_sync_cmd_get_last_error (conn, config->db, &error); fprintf (stderr, "Error reconnecting to the master of %s:%d: %s\n", config->host, config->port, (error) ? error : strerror (e)); exit (1); } } VLOG ("Counting documents...\n"); cnt = mongo_sync_cmd_count (conn, config->db, config->coll, NULL); if (cnt < 0) { e = errno; mongo_sync_cmd_get_last_error (conn, config->db, &error); fprintf (stderr, "Error counting documents in %s.%s: %s\n", config->db, config->coll, (error) ? error : strerror (e)); mongo_sync_disconnect (conn); exit (1); } VLOG ("Opening output file '%s'...\n", config->output); if (strcmp (config->output, "-") == 0) fd = 1; else { fd = open (config->output, O_RDWR | O_CREAT | O_TRUNC, 0600); if (fd == -1) { fprintf (stderr, "Error opening output file '%s': %s\n", config->output, strerror (errno)); mongo_sync_disconnect (conn); exit (1); } } VLOG ("Launching initial query...\n"); b = bson_new (); bson_finish (b); p = mongo_sync_cmd_query (conn, config->ns, MONGO_WIRE_FLAG_QUERY_NO_CURSOR_TIMEOUT, 0, 10, b, NULL); if (!p) { e = errno; bson_free (b); unlink (config->output); close (fd); mongo_sync_cmd_get_last_error (conn, config->db, &error); fprintf (stderr, "Error retrieving the cursor: %s\n", (error) ? error : strerror (e)); mongo_sync_disconnect (conn); exit (1); } bson_free (b); mongo_wire_reply_packet_get_header (p, &rh); cid = rh.cursor_id; pos = mongo_dump_packet (config, p, pos, fd); mongo_wire_packet_free (p); while (pos < cnt) { gdouble pr = (pos + 10) / cnt; VLOG ("\rDumping... %03.2f%%", ((pr > 1) ? 1 : pr) * 100); if (config->verbose) fflush (stderr); p = mongo_sync_cmd_get_more (conn, config->ns, 10, cid); if (!p) { e = errno; unlink (config->output); close (fd); mongo_sync_cmd_get_last_error (conn, config->db, &error); fprintf (stderr, "Error advancing the cursor: %s\n", (error) ? error : strerror (e)); mongo_sync_disconnect (conn); exit (1); } pos = mongo_dump_packet (config, p, pos, fd); mongo_wire_packet_free (p); } close (fd); mongo_sync_disconnect (conn); return 0; }