Ejemplo n.º 1
0
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);
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
/**
 * 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;
}
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
0
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);
}
Ejemplo n.º 7
0
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;
}