Esempio n. 1
0
krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
					    void *data,
					    krb5_krbhst_info *hi,
					    time_t timeout,
					    const krb5_data *send_buf,
					    krb5_data *recv_buf)
{
	krb5_error_code ret;
	struct addrinfo *ai;

	struct tevent_context *ev;
	TALLOC_CTX *tmp_ctx = talloc_new(NULL);
	if (!tmp_ctx) {
		return ENOMEM;
	}

	if (!data) {
		/* If no event context was available, then create one for this loop */
		ev = samba_tevent_context_init(tmp_ctx);
		if (!ev) {
			talloc_free(tmp_ctx);
			return ENOMEM;
		}
	} else {
		ev = talloc_get_type_abort(data, struct tevent_context);
	}

	ret = krb5_krbhst_get_addrinfo(context, hi, &ai);
	if (ret) {
		talloc_free(tmp_ctx);
		return ret;
	}
	return smb_krb5_send_and_recv_func_int(context, ev, hi, ai, smb_krb5_send_and_recv_func, data, timeout, send_buf, recv_buf);
}
Esempio n. 2
0
krb5_error_code smb_krb5_send_and_recv_func_forced(krb5_context context,
						   void *data, /* struct addrinfo */
						   krb5_krbhst_info *hi,
						   time_t timeout,
						   const krb5_data *send_buf,
						   krb5_data *recv_buf)
{
	struct addrinfo *ai = data;

	struct tevent_context *ev;
	TALLOC_CTX *tmp_ctx = talloc_new(NULL);
	if (!tmp_ctx) {
		return ENOMEM;
	}

	/* If no event context was available, then create one for this loop */
	ev = samba_tevent_context_init(tmp_ctx);
	if (!ev) {
		talloc_free(tmp_ctx);
		return ENOMEM;
	}

	/* No need to pass in send_and_recv functions, we won't nest on this private event loop */
	return smb_krb5_send_and_recv_func_int(context, ev, hi, ai, NULL, NULL,
					       timeout, send_buf, recv_buf);
}
Esempio n. 3
0
static bool net_g_lock_init(TALLOC_CTX *mem_ctx,
			    struct tevent_context **pev,
			    struct messaging_context **pmsg,
			    struct g_lock_ctx **pg_ctx)
{
	struct tevent_context *ev = NULL;
	struct messaging_context *msg = NULL;
	struct g_lock_ctx *g_ctx = NULL;

	ev = samba_tevent_context_init(mem_ctx);
	if (ev == NULL) {
		d_fprintf(stderr, "ERROR: could not init event context\n");
		goto fail;
	}
	msg = messaging_init(mem_ctx, ev);
	if (msg == NULL) {
		d_fprintf(stderr, "ERROR: could not init messaging context\n");
		goto fail;
	}
	g_ctx = g_lock_ctx_init(mem_ctx, msg);
	if (g_ctx == NULL) {
		d_fprintf(stderr, "ERROR: could not init g_lock context\n");
		goto fail;
	}

	*pev = ev;
	*pmsg = msg;
	*pg_ctx = g_ctx;
	return true;
fail:
	TALLOC_FREE(g_ctx);
	TALLOC_FREE(msg);
	TALLOC_FREE(ev);
	return false;
}
Esempio n. 4
0
/**
* @brief open a socket
*
* @param pss a struct sockaddr_storage defining the address to connect to
* @param port to connect to
* @param timeout in MILLISECONDS
* @param pfd file descriptor returned
*
* @return NTSTATUS code
*/
NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port,
			 int timeout, int *pfd)
{
	TALLOC_CTX *frame = talloc_stackframe();
	struct tevent_context *ev;
	struct tevent_req *req;
	NTSTATUS status = NT_STATUS_NO_MEMORY;

	ev = samba_tevent_context_init(frame);
	if (ev == NULL) {
		goto fail;
	}

	req = open_socket_out_send(frame, ev, pss, port, timeout);
	if (req == NULL) {
		goto fail;
	}
	if (!tevent_req_poll(req, ev)) {
		status = NT_STATUS_INTERNAL_ERROR;
		goto fail;
	}
	status = open_socket_out_recv(req, pfd);
 fail:
	TALLOC_FREE(frame);
	return status;
}
/**
 * test fdpass1:
 *
 * Try to pass an fd to the sending process - fails.
 */
bool run_messaging_fdpass1(int dummy)
{
	struct tevent_context *ev = NULL;
	struct messaging_context *msg_ctx = NULL;
	bool retval = false;
	int pipe_fds[2];
	int pass_fds[1] = { 0 };
	int ret;
	NTSTATUS status;
	struct server_id dst;
	TALLOC_CTX *frame = talloc_stackframe();

	ev = samba_tevent_context_init(frame);
	if (ev == NULL) {
		fprintf(stderr, "tevent_context_init failed\n");
		goto fail;
	}
	msg_ctx = messaging_init(ev, ev);
	if (msg_ctx == NULL) {
		fprintf(stderr, "messaging_init failed\n");
		goto fail;
	}

	dst = messaging_server_id(msg_ctx);

	ret = pipe(pipe_fds);
	if (ret != 0) {
		perror("pipe failed");
		goto fail;
	}

	pass_fds[0] = pipe_fds[0];

	status = messaging_send_iov(msg_ctx, dst, MSG_PING, NULL, 0,
				    pass_fds, 1);
	if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
		fprintf(stderr,
			"messaging_send_iov gave: %s\n", nt_errstr(status));
		goto fail;
	}

	retval = true;

fail:
	TALLOC_FREE(frame);
	return retval;
}
Esempio n. 6
0
static PyObject *py_creds_get_named_ccache(PyObject *self, PyObject *args)
{
	PyObject *py_lp_ctx = Py_None;
	char *ccache_name;
	struct loadparm_context *lp_ctx;
	struct ccache_container *ccc;
	struct tevent_context *event_ctx;
	int ret;
	const char *error_string;
	struct cli_credentials *creds;
	TALLOC_CTX *mem_ctx;

	creds = PyCredentials_AsCliCredentials(self);

	if (!PyArg_ParseTuple(args, "|Os", &py_lp_ctx, &ccache_name))
		return NULL;

	mem_ctx = talloc_new(NULL);
	if (mem_ctx == NULL) {
		PyErr_NoMemory();
		return NULL;
	}

	lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
	if (lp_ctx == NULL) {
		talloc_free(mem_ctx);
		return NULL;
	}

	event_ctx = samba_tevent_context_init(mem_ctx);

	ret = cli_credentials_get_named_ccache(creds, event_ctx, lp_ctx,
					       ccache_name, &ccc, &error_string);
	talloc_unlink(mem_ctx, lp_ctx);
	if (ret == 0) {
		talloc_steal(ccc, event_ctx);
		talloc_free(mem_ctx);
		return PyCredentialCacheContainer_from_ccache_container(ccc);
	}

	PyErr_SetString(PyExc_RuntimeError, error_string?error_string:"NULL");

	talloc_free(mem_ctx);
	return NULL;
}
struct tevent_context *winbind_event_context(void)
{
	static struct tevent_context *ev = NULL;

	if (ev != NULL) {
		return ev;
	}

	/*
	 * Note we MUST use the NULL context here, not the autofree context,
	 * to avoid side effects in forked children exiting.
	 */
	ev = samba_tevent_context_init(NULL);
	if (ev == NULL) {
		smb_panic("Could not init winbindd's messaging context.\n");
	}
	return ev;
}
Esempio n. 8
0
bool run_dbwrap_watch1(int dummy)
{
	struct tevent_context *ev = NULL;
	struct messaging_context *msg = NULL;
	struct db_context *backend = NULL;
	struct db_context *db = NULL;
	const char *keystr = "key";
	TDB_DATA key = string_term_tdb_data(keystr);
	struct db_record *rec = NULL;
	struct tevent_req *req = NULL;
	NTSTATUS status;
	bool ret = false;

	ev = samba_tevent_context_init(talloc_tos());
	if (ev == NULL) {
		fprintf(stderr, "tevent_context_init failed\n");
		goto fail;
	}
	msg = messaging_init(ev, ev);
	if (msg == NULL) {
		fprintf(stderr, "messaging_init failed\n");
		goto fail;
	}
	backend = db_open(msg, "test_watch.tdb", 0, TDB_DEFAULT,
			  O_CREAT|O_RDWR, 0644, DBWRAP_LOCK_ORDER_1,
			  DBWRAP_FLAG_NONE);
	if (backend == NULL) {
		fprintf(stderr, "db_open failed: %s\n", strerror(errno));
		goto fail;
	}

	db = db_open_watched(ev, backend, msg);

	rec = dbwrap_fetch_locked(db, db, key);
	if (rec == NULL) {
		fprintf(stderr, "dbwrap_fetch_locked failed\n");
		goto fail;
	}
	req = dbwrap_watched_watch_send(talloc_tos(), ev, rec,
					(struct server_id){0});
static bool fdpass2_child(int ready_fd)
{
	struct tevent_context *ev = NULL;
	struct messaging_context *msg_ctx = NULL;
	TALLOC_CTX *frame = talloc_stackframe();
	bool retval = false;
	uint8_t c = 1;
	struct tevent_req *subreq;
	int ret;
	ssize_t bytes;
	int up_fd, down_fd;
	struct messaging_rec *rec;
	bool ok;

	ev = samba_tevent_context_init(frame);
	if (ev == NULL) {
		fprintf(stderr, "child: tevent_context_init failed\n");
		goto done;
	}

	msg_ctx = messaging_init(ev, ev);
	if (msg_ctx == NULL) {
		fprintf(stderr, "child: messaging_init failed\n");
		goto done;
	}

	/* Tell the parent we are ready to receive mesages. */
	bytes = write(ready_fd, &c, 1);
	if (bytes != 1) {
		perror("child: failed to write to ready_fd");
		goto done;
	}

	subreq = messaging_filtered_read_send(frame, /* TALLOC_CTX */
					      ev, msg_ctx,
					      fdpass2_filter, NULL);
	if (subreq == NULL) {
		fprintf(stderr, "child: messaging_filtered_read_send failed\n");
		goto done;
	}

	ok = tevent_req_poll(subreq, ev);
	if (!ok) {
		fprintf(stderr, "child: tevent_req_poll failed\n");
		goto done;
	}

	ret = messaging_filtered_read_recv(subreq, frame, &rec);
	TALLOC_FREE(subreq);
	if (ret != 0) {
		fprintf(stderr, "child: messaging_filtered_read_recv failed\n");
		goto done;
	}

	SMB_ASSERT(rec->num_fds == 2);

	/* Tell the parent we are done. */
	bytes = write(ready_fd, &c, 1);
	if (bytes != 1) {
		perror("child: failed to write to ready_fd");
		goto done;
	}

	up_fd = rec->fds[0];
	down_fd = rec->fds[1];

	bytes = read(up_fd, &c, 1);
	if (bytes != 1) {
		perror("child: read from up_fd failed");
		goto done;
	}

	bytes = write(down_fd, &c, 1);
	if (bytes != 1) {
		perror("child: write to down_fd failed");
	}

	printf("child: done\n");

	retval = true;

done:
	TALLOC_FREE(frame);
	return retval;
}
Esempio n. 10
0
_PUBLIC_ NTSTATUS gensec_update_ev(struct gensec_security *gensec_security,
				   TALLOC_CTX *out_mem_ctx,
				   struct tevent_context *ev,
				   const DATA_BLOB in, DATA_BLOB *out)
{
	NTSTATUS status;
	const struct gensec_security_ops *ops = gensec_security->ops;
	TALLOC_CTX *frame = NULL;
	struct tevent_req *subreq = NULL;
	bool ok;

	if (ops->update_send == NULL) {

		if (ev == NULL) {
			frame = talloc_stackframe();

			ev = samba_tevent_context_init(frame);
			if (ev == NULL) {
				status = NT_STATUS_NO_MEMORY;
				goto fail;
			}

			/*
			 * TODO: remove this hack once the backends
			 * are fixed.
			 */
			tevent_loop_allow_nesting(ev);
		}

		status = ops->update(gensec_security, out_mem_ctx,
				     ev, in, out);
		TALLOC_FREE(frame);
		if (!NT_STATUS_IS_OK(status)) {
			return status;
		}

		/*
		 * Because callers using the
		 * gensec_start_mech_by_auth_type() never call
		 * gensec_want_feature(), it isn't sensible for them
		 * to have to call gensec_have_feature() manually, and
		 * these are not points of negotiation, but are
		 * asserted by the client
		 */
		switch (gensec_security->dcerpc_auth_level) {
		case DCERPC_AUTH_LEVEL_INTEGRITY:
			if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
				DEBUG(0,("Did not manage to negotiate mandetory feature "
					 "SIGN for dcerpc auth_level %u\n",
					 gensec_security->dcerpc_auth_level));
				return NT_STATUS_ACCESS_DENIED;
			}
			break;
		case DCERPC_AUTH_LEVEL_PRIVACY:
			if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
				DEBUG(0,("Did not manage to negotiate mandetory feature "
					 "SIGN for dcerpc auth_level %u\n",
					 gensec_security->dcerpc_auth_level));
				return NT_STATUS_ACCESS_DENIED;
			}
			if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
				DEBUG(0,("Did not manage to negotiate mandetory feature "
					 "SEAL for dcerpc auth_level %u\n",
					 gensec_security->dcerpc_auth_level));
				return NT_STATUS_ACCESS_DENIED;
			}
			break;
		default:
			break;
		}

		return NT_STATUS_OK;
	}

	frame = talloc_stackframe();

	if (ev == NULL) {
		ev = samba_tevent_context_init(frame);
		if (ev == NULL) {
			status = NT_STATUS_NO_MEMORY;
			goto fail;
		}

		/*
		 * TODO: remove this hack once the backends
		 * are fixed.
		 */
		tevent_loop_allow_nesting(ev);
	}

	subreq = ops->update_send(frame, ev, gensec_security, in);
	if (subreq == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto fail;
	}
	ok = tevent_req_poll_ntstatus(subreq, ev, &status);
	if (!ok) {
		goto fail;
	}
	status = ops->update_recv(subreq, out_mem_ctx, out);
 fail:
	TALLOC_FREE(frame);
	return status;
}
Esempio n. 11
0
int main(int argc, const char **argv)
{
	struct tevent_context *evt_ctx;
	struct messaging_context *msg_ctx;
	struct db_context *db;

	uint16_t count;

	const char *dbname;
	const char *opname;
	enum dbwrap_op op;
	const char *keyname = "";
	const char *keytype = "int32";
	enum dbwrap_type type;
	const char *valuestr = "0";
	int persistent = 0;
	int non_persistent = 0;
	int tdb_flags = TDB_DEFAULT;

	TALLOC_CTX *mem_ctx = talloc_stackframe();

	int ret = 1;

	struct poptOption popt_options[] = {
		POPT_AUTOHELP
		POPT_COMMON_SAMBA
		{ "non-persistent", 0, POPT_ARG_NONE, &non_persistent, 0,
		  "treat the database as non-persistent "
		  "(CAVEAT: This mode might wipe your database!)",
		  NULL },
		{ "persistent", 0, POPT_ARG_NONE, &persistent, 0,
		  "treat the database as persistent",
		  NULL },
		POPT_TABLEEND
	};
	int opt;
	const char **extra_argv;
	int extra_argc = 0;
	poptContext pc;

	smb_init_locale();
	lp_set_cmdline("log level", "0");
	setup_logging(argv[0], DEBUG_STDERR);

	pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);

	while ((opt = poptGetNextOpt(pc)) != -1) {
		switch (opt) {
		default:
			fprintf(stderr, "Invalid option %s: %s\n",
				poptBadOption(pc, 0), poptStrerror(opt));
			goto done;
		}
	}

	/* setup the remaining options for the main program to use */
	extra_argv = poptGetArgs(pc);
	if (extra_argv) {
		extra_argv++;
		while (extra_argv[extra_argc]) extra_argc++;
	}

	lp_load_global(get_dyn_CONFIGFILE());

	if ((extra_argc < 2) || (extra_argc > 5)) {
		d_fprintf(stderr,
			  "USAGE: %s [options] <database> <op> [<key> [<type> "
			  "[<value>]]]\n"
			  "       ops: fetch, store, delete, exists, "
			  "erase, listkeys, listwatchers\n"
			  "       types: int32, uint32, string, hex\n",
			 argv[0]);
		goto done;
	}

	if ((persistent == 0 && non_persistent == 0) ||
	    (persistent == 1 && non_persistent == 1))
	{
		d_fprintf(stderr, "ERROR: you must specify exactly one "
			  "of --persistent and --non-persistent\n");
		goto done;
	} else if (non_persistent == 1) {
		tdb_flags |= TDB_CLEAR_IF_FIRST;
	}

	dbname = extra_argv[0];
	opname = extra_argv[1];

	if (strcmp(opname, "store") == 0) {
		if (extra_argc != 5) {
			d_fprintf(stderr, "ERROR: operation 'store' requires "
				  "value argument\n");
			goto done;
		}
		valuestr = extra_argv[4];
		keytype = extra_argv[3];
		keyname = extra_argv[2];
		op = OP_STORE;
	} else if (strcmp(opname, "fetch") == 0) {
		if (extra_argc != 4) {
			d_fprintf(stderr, "ERROR: operation 'fetch' requires "
				  "type but not value argument\n");
			goto done;
		}
		op = OP_FETCH;
		keytype = extra_argv[3];
		keyname = extra_argv[2];
	} else if (strcmp(opname, "delete") == 0) {
		if (extra_argc != 3) {
			d_fprintf(stderr, "ERROR: operation 'delete' does "
				  "not allow type nor value argument\n");
			goto done;
		}
		keyname = extra_argv[2];
		op = OP_DELETE;
	} else if (strcmp(opname, "erase") == 0) {
		if (extra_argc != 2) {
			d_fprintf(stderr, "ERROR: operation 'erase' does "
				  "not take a key argument\n");
			goto done;
		}
		op = OP_ERASE;
	} else if (strcmp(opname, "listkeys") == 0) {
		if (extra_argc != 2) {
			d_fprintf(stderr, "ERROR: operation 'listkeys' does "
				  "not take a key argument\n");
			goto done;
		}
		op = OP_LISTKEYS;
	} else if (strcmp(opname, "exists") == 0) {
		if (extra_argc != 3) {
			d_fprintf(stderr, "ERROR: operation 'exists' does "
				  "not allow type nor value argument\n");
			goto done;
		}
		keyname = extra_argv[2];
		op = OP_EXISTS;
		keytype = "string";
	} else {
		d_fprintf(stderr,
			  "ERROR: invalid op '%s' specified\n"
			  "       supported ops: fetch, store, delete, exists, "
			  "erase, listkeys, listwatchers\n",
			  opname);
		goto done;
	}

	if (strcmp(keytype, "int32") == 0) {
		type = TYPE_INT32;
	} else if (strcmp(keytype, "uint32") == 0) {
		type = TYPE_UINT32;
	} else if (strcmp(keytype, "string") == 0) {
		type = TYPE_STRING;
	} else if (strcmp(keytype, "hex") == 0) {
		type = TYPE_HEX;
	} else if (strcmp(keytype, "none") == 0) {
		type = TYPE_NONE;
	} else {
		d_fprintf(stderr, "ERROR: invalid type '%s' specified.\n"
				  "       supported types: int32, uint32, "
				  "string, hex, none\n",
				  keytype);
		goto done;
	}

	evt_ctx = samba_tevent_context_init(mem_ctx);
	if (evt_ctx == NULL) {
		d_fprintf(stderr, "ERROR: could not init event context\n");
		goto done;
	}

	msg_ctx = messaging_init(mem_ctx, evt_ctx);
	if (msg_ctx == NULL) {
		d_fprintf(stderr, "ERROR: could not init messaging context\n");
		goto done;
	}

	switch (op) {
	case OP_FETCH:
	case OP_STORE:
	case OP_DELETE:
	case OP_ERASE:
	case OP_LISTKEYS:
	case OP_EXISTS:
		db = db_open(mem_ctx, dbname, 0, tdb_flags, O_RDWR | O_CREAT,
			     0644, DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
		if (db == NULL) {
			d_fprintf(stderr, "ERROR: could not open dbname\n");
			goto done;
		}
		break;
	default:
		db = NULL;
		break;
	}

	for (count = 0; dispatch_table[count].cmd != NULL; count++) {
		if ((op == dispatch_table[count].op) &&
		    (type == dispatch_table[count].type))
		{
			ret = dispatch_table[count].cmd(db, keyname, valuestr);
			break;
		}
	}

done:
	TALLOC_FREE(mem_ctx);
	return ret;
}
Esempio n. 12
0
int main(int argc, const char **argv)
{
	poptContext pc;
	int opt;
	struct tevent_context *evt_ctx;
	struct messaging_context *msg_ctx;

	static struct poptOption long_options[] = {
		/* POPT_AUTOHELP */
		{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, help_options,
		                        0, "Help options:", NULL },
		{ "timeout", 't', POPT_ARG_INT, &timeout, 't', 
		  "Set timeout value in seconds", "TIMEOUT" },

		POPT_COMMON_SAMBA
		POPT_TABLEEND
	};
	TALLOC_CTX *frame = talloc_stackframe();
	int ret = 0;

	smb_init_locale();

	setup_logging(argv[0], DEBUG_STDOUT);
	lp_set_cmdline("log level", "0");

	/* Parse command line arguments using popt */

	pc = poptGetContext(
		"smbcontrol", argc, (const char **)argv, long_options, 0);

	poptSetOtherOptionHelp(pc, "[OPTION...] <destination> <message-type> "
			       "<parameters>");

	if (argc == 1)
		usage(pc);

	while ((opt = poptGetNextOpt(pc)) != -1) {
		switch(opt) {
		case 't':	/* --timeout */
			break;
		default:
			fprintf(stderr, "Invalid option\n");
			poptPrintHelp(pc, stderr, 0);
			break;
		}
	}

	/* We should now have the remaining command line arguments in
           argv.  The argc parameter should have been decremented to the
           correct value in the above switch statement. */

	argv = (const char **)poptGetArgs(pc);
	argc = 0;
	if (argv != NULL) {
		while (argv[argc] != NULL) {
			argc++;
		}
	}

	if (argc <= 1)
		usage(pc);

	lp_load_global(get_dyn_CONFIGFILE());

	/* Need to invert sense of return code -- samba
         * routines mostly return True==1 for success, but
         * shell needs 0. */ 

	if (!(evt_ctx = samba_tevent_context_init(NULL)) ||
	    !(msg_ctx = messaging_init(NULL, evt_ctx))) {
		fprintf(stderr, "could not init messaging context\n");
		TALLOC_FREE(frame);
		exit(1);
	}

	ret = !do_command(evt_ctx, msg_ctx, argc, argv);
	TALLOC_FREE(msg_ctx);
	TALLOC_FREE(frame);
	return ret;
}
Esempio n. 13
0
NTSTATUS smb1cli_trans(TALLOC_CTX *mem_ctx, struct smbXcli_conn *conn,
		uint8_t trans_cmd,
		uint8_t additional_flags, uint8_t clear_flags,
		uint16_t additional_flags2, uint16_t clear_flags2,
		uint32_t timeout_msec,
		uint32_t pid,
		struct smbXcli_tcon *tcon,
		struct smbXcli_session *session,
		const char *pipe_name, uint16_t fid, uint16_t function,
		int flags,
		uint16_t *setup, uint8_t num_setup, uint8_t max_setup,
		uint8_t *param, uint32_t num_param, uint32_t max_param,
		uint8_t *data, uint32_t num_data, uint32_t max_data,
		uint16_t *recv_flags2,
		uint16_t **rsetup, uint8_t min_rsetup, uint8_t *num_rsetup,
		uint8_t **rparam, uint32_t min_rparam, uint32_t *num_rparam,
		uint8_t **rdata, uint32_t min_rdata, uint32_t *num_rdata)
{
	TALLOC_CTX *frame = talloc_stackframe();
	struct tevent_context *ev;
	struct tevent_req *req;
	NTSTATUS status = NT_STATUS_NO_MEMORY;

	if (smbXcli_conn_has_async_calls(conn)) {
		/*
		 * Can't use sync call while an async call is in flight
		 */
		status = NT_STATUS_INVALID_PARAMETER_MIX;
		goto fail;
	}

	ev = samba_tevent_context_init(frame);
	if (ev == NULL) {
		goto fail;
	}

	req = smb1cli_trans_send(frame, ev, conn, trans_cmd,
				 additional_flags, clear_flags,
				 additional_flags2, clear_flags2,
				 timeout_msec,
				 pid, tcon, session,
				 pipe_name, fid, function, flags,
				 setup, num_setup, max_setup,
				 param, num_param, max_param,
				 data, num_data, max_data);
	if (req == NULL) {
		goto fail;
	}

	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
		goto fail;
	}

	status = smb1cli_trans_recv(req, mem_ctx, recv_flags2,
				    rsetup, min_rsetup, num_rsetup,
				    rparam, min_rparam, num_rparam,
				    rdata, min_rdata, num_rdata);
 fail:
	TALLOC_FREE(frame);
	return status;
}
Esempio n. 14
0
int main(int argc, const char *argv[])
{
	int c;
	int profile_only = 0;
	bool show_processes, show_locks, show_shares;
	bool show_notify = false;
	poptContext pc;
	struct poptOption long_options[] = {
		POPT_AUTOHELP
		{"processes",	'p', POPT_ARG_NONE,	NULL, 'p', "Show processes only" },
		{"verbose",	'v', POPT_ARG_NONE, 	NULL, 'v', "Be verbose" },
		{"locks",	'L', POPT_ARG_NONE,	NULL, 'L', "Show locks only" },
		{"shares",	'S', POPT_ARG_NONE,	NULL, 'S', "Show shares only" },
		{"notify",	'N', POPT_ARG_NONE,	NULL, 'N', "Show notifies" },
		{"user", 	'u', POPT_ARG_STRING,	&username, 'u', "Switch to user" },
		{"brief",	'b', POPT_ARG_NONE, 	NULL, 'b', "Be brief" },
		{"profile",     'P', POPT_ARG_NONE, NULL, 'P', "Do profiling" },
		{"profile-rates", 'R', POPT_ARG_NONE, NULL, 'R', "Show call rates" },
		{"byterange",	'B', POPT_ARG_NONE,	NULL, 'B', "Include byte range locks"},
		{"numeric",	'n', POPT_ARG_NONE,	NULL, 'n', "Numeric uid/gid"},
		{"fast",	'f', POPT_ARG_NONE,	NULL, 'f', "Skip checks if processes still exist"},
		POPT_COMMON_SAMBA
		POPT_TABLEEND
	};
	TALLOC_CTX *frame = talloc_stackframe();
	int ret = 0;
	struct messaging_context *msg_ctx = NULL;
	char *db_path;
	bool ok;

	sec_init();
	smb_init_locale();

	setup_logging(argv[0], DEBUG_STDERR);
	lp_set_cmdline("log level", "0");

	if (getuid() != geteuid()) {
		d_printf("smbstatus should not be run setuid\n");
		ret = 1;
		goto done;
	}

	if (getuid() != 0) {
		d_printf("smbstatus only works as root!\n");
		ret = 1;
		goto done;
	}


	pc = poptGetContext(NULL, argc, argv, long_options,
			    POPT_CONTEXT_KEEP_FIRST);

	while ((c = poptGetNextOpt(pc)) != -1) {
		switch (c) {
		case 'p':
			processes_only = true;
			break;
		case 'v':
			verbose = true;
			break;
		case 'L':
			locks_only = true;
			break;
		case 'S':
			shares_only = true;
			break;
		case 'N':
			show_notify = true;
			break;
		case 'b':
			brief = true;
			break;
		case 'u':
			Ucrit_addUid(nametouid(poptGetOptArg(pc)));
			break;
		case 'P':
		case 'R':
			profile_only = c;
			break;
		case 'B':
			show_brl = true;
			break;
		case 'n':
			numeric_only = true;
			break;
		case 'f':
			do_checks = false;
			break;
		}
	}

	/* setup the flags based on the possible combincations */

	show_processes = !(shares_only || locks_only || profile_only) || processes_only;
	show_locks     = !(shares_only || processes_only || profile_only) || locks_only;
	show_shares    = !(processes_only || locks_only || profile_only) || shares_only;

	if ( username )
		Ucrit_addUid( nametouid(username) );

	if (verbose) {
		d_printf("using configfile = %s\n", get_dyn_CONFIGFILE());
	}

	if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
		fprintf(stderr, "Can't load %s - run testparm to debug it\n",
			get_dyn_CONFIGFILE());
		ret = -1;
		goto done;
	}


	/*
	 * This implicitly initializes the global ctdbd connection,
	 * usable by the db_open() calls further down.
	 */
	msg_ctx = messaging_init(NULL, samba_tevent_context_init(NULL));
	if (msg_ctx == NULL) {
		fprintf(stderr, "messaging_init failed\n");
		ret = -1;
		goto done;
	}

	if (!lp_load_global(get_dyn_CONFIGFILE())) {
		fprintf(stderr, "Can't load %s - run testparm to debug it\n",
			get_dyn_CONFIGFILE());
		ret = -1;
		goto done;
	}

	switch (profile_only) {
		case 'P':
			/* Dump profile data */
			ok = status_profile_dump(verbose);
			return ok ? 0 : 1;
		case 'R':
			/* Continuously display rate-converted data */
			ok = status_profile_rates(verbose);
			return ok ? 0 : 1;
		default:
			break;
	}

	if ( show_processes ) {
		d_printf("\nSamba version %s\n",samba_version_string());
		d_printf("%-7s %-12s %-12s %-41s %-17s %-20s %-21s\n", "PID", "Username", "Group", "Machine", "Protocol Version", "Encryption", "Signing");
		d_printf("----------------------------------------------------------------------------------------------------------------------------------------\n");

		sessionid_traverse_read(traverse_sessionid, frame);

		if (processes_only) {
			goto done;
		}
	}

	if ( show_shares ) {
		if (brief) {
			goto done;
		}

		d_printf("\n%-12s %-7s %-13s %-32s %-12s %-12s\n", "Service", "pid", "Machine", "Connected at", "Encryption", "Signing");
		d_printf("---------------------------------------------------------------------------------------------\n");

		connections_forall_read(traverse_connections, frame);

		d_printf("\n");

		if ( shares_only ) {
			goto done;
		}
	}

	if ( show_locks ) {
		int result;
		struct db_context *db;

		db_path = lock_path("locking.tdb");
		if (db_path == NULL) {
			d_printf("Out of memory - exiting\n");
			ret = -1;
			goto done;
		}

		db = db_open(NULL, db_path, 0,
			     TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, O_RDONLY, 0,
			     DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);

		if (!db) {
			d_printf("%s not initialised\n", db_path);
			d_printf("This is normal if an SMB client has never "
				 "connected to your server.\n");
			TALLOC_FREE(db_path);
			exit(0);
		} else {
			TALLOC_FREE(db);
			TALLOC_FREE(db_path);
		}

		if (!locking_init_readonly()) {
			d_printf("Can't initialise locking module - exiting\n");
			ret = 1;
			goto done;
		}

		result = share_entry_forall(print_share_mode, NULL);

		if (result == 0) {
			d_printf("No locked files\n");
		} else if (result < 0) {
			d_printf("locked file list truncated\n");
		}

		d_printf("\n");

		if (show_brl) {
			brl_forall(print_brl, NULL);
		}

		locking_end();
	}

	if (show_notify) {
		struct notify_context *n;

		n = notify_init(talloc_tos(), msg_ctx,
				messaging_tevent_context(msg_ctx));
		if (n == NULL) {
			goto done;
		}
		notify_walk(n, print_notify_rec, NULL);
		TALLOC_FREE(n);
	}

done:
	TALLOC_FREE(frame);
	return ret;
}
Esempio n. 15
0
File: net.c Progetto: hef/samba
/****************************************************************************
  main program
****************************************************************************/
int main(int argc, char **argv)
{
    int opt,i;
    char *p;
    int rc = 0;
    int argc_new = 0;
    const char ** argv_new;
    const char **argv_const = discard_const_p(const char *, argv);
    poptContext pc;
    TALLOC_CTX *frame = talloc_stackframe();
    struct net_context *c = talloc_zero(frame, struct net_context);

    struct poptOption long_options[] = {
        {"help",	'h', POPT_ARG_NONE,   0, 'h'},
        {"workgroup",	'w', POPT_ARG_STRING, &c->opt_target_workgroup},
        {"user",	'U', POPT_ARG_STRING, &c->opt_user_name, 'U'},
        {"ipaddress",	'I', POPT_ARG_STRING, 0,'I'},
        {"port",	'p', POPT_ARG_INT,    &c->opt_port},
        {"myname",	'n', POPT_ARG_STRING, &c->opt_requester_name},
        {"server",	'S', POPT_ARG_STRING, &c->opt_host},
        {"encrypt",	'e', POPT_ARG_NONE,   NULL, 'e', N_("Encrypt SMB transport (UNIX extended servers only)") },
        {"container",	'c', POPT_ARG_STRING, &c->opt_container},
        {"comment",	'C', POPT_ARG_STRING, &c->opt_comment},
        {"maxusers",	'M', POPT_ARG_INT,    &c->opt_maxusers},
        {"flags",	'F', POPT_ARG_INT,    &c->opt_flags},
        {"long",	'l', POPT_ARG_NONE,   &c->opt_long_list_entries},
        {"reboot",	'r', POPT_ARG_NONE,   &c->opt_reboot},
        {"force",	'f', POPT_ARG_NONE,   &c->opt_force},
        {"stdin",	'i', POPT_ARG_NONE,   &c->opt_stdin},
        {"timeout",	't', POPT_ARG_INT,    &c->opt_timeout},
        {"request-timeout",0,POPT_ARG_INT,    &c->opt_request_timeout},
        {"machine-pass",'P', POPT_ARG_NONE,   &c->opt_machine_pass},
        {"kerberos",    'k', POPT_ARG_NONE,   &c->opt_kerberos},
        {"myworkgroup", 'W', POPT_ARG_STRING, &c->opt_workgroup},
        {"use-ccache",    0, POPT_ARG_NONE,   &c->opt_ccache},
        {"verbose",	'v', POPT_ARG_NONE,   &c->opt_verbose},
        {"test",	'T', POPT_ARG_NONE,   &c->opt_testmode},
        /* Options for 'net groupmap set' */
        {"local",       'L', POPT_ARG_NONE,   &c->opt_localgroup},
        {"domain",      'D', POPT_ARG_NONE,   &c->opt_domaingroup},
        {"ntname",      'N', POPT_ARG_STRING, &c->opt_newntname},
        {"rid",         'R', POPT_ARG_INT,    &c->opt_rid},
        /* Options for 'net rpc share migrate' */
        {"acls",	0, POPT_ARG_NONE,     &c->opt_acls},
        {"attrs",	0, POPT_ARG_NONE,     &c->opt_attrs},
        {"timestamps",	0, POPT_ARG_NONE,     &c->opt_timestamps},
        {"exclude",	'X', POPT_ARG_STRING, &c->opt_exclude},
        {"destination",	0, POPT_ARG_STRING,   &c->opt_destination},
        {"tallocreport", 0, POPT_ARG_NONE,    &c->do_talloc_report},
        /* Options for 'net rpc vampire (keytab)' */
        {"force-full-repl", 0, POPT_ARG_NONE, &c->opt_force_full_repl},
        {"single-obj-repl", 0, POPT_ARG_NONE, &c->opt_single_obj_repl},
        {"clean-old-entries", 0, POPT_ARG_NONE, &c->opt_clean_old_entries},
        /* Options for 'net idmap'*/
        {"db", 0, POPT_ARG_STRING, &c->opt_db},
        {"lock", 0, POPT_ARG_NONE,   &c->opt_lock},
        {"auto", 'a', POPT_ARG_NONE,   &c->opt_auto},
        {"repair", 0, POPT_ARG_NONE,   &c->opt_repair},
        /* Options for 'net registry check'*/
        {"reg-version", 0, POPT_ARG_INT, &c->opt_reg_version},
        {"output", 'o', POPT_ARG_STRING, &c->opt_output},
        {"wipe", 0, POPT_ARG_NONE, &c->opt_wipe},
        /* Options for 'net registry import' */
        {"precheck", 0, POPT_ARG_STRING, &c->opt_precheck},
        POPT_COMMON_SAMBA
        { 0, 0, 0, 0}
    };

    zero_sockaddr(&c->opt_dest_ip);

    setup_logging(argv[0], DEBUG_STDERR);

    load_case_tables();

    setlocale(LC_ALL, "");
#if defined(HAVE_BINDTEXTDOMAIN)
    bindtextdomain(MODULE_NAME, get_dyn_LOCALEDIR());
#endif
#if defined(HAVE_TEXTDOMAIN)
    textdomain(MODULE_NAME);
#endif

    /* set default debug level to 0 regardless of what smb.conf sets */
    lp_set_cmdline("log level", "0");
    c->private_data = net_func;

    pc = poptGetContext(NULL, argc, argv_const, long_options,
                        POPT_CONTEXT_KEEP_FIRST);

    while((opt = poptGetNextOpt(pc)) != -1) {
        switch (opt) {
        case 'h':
            c->display_usage = true;
            break;
        case 'e':
            c->smb_encrypt = true;
            break;
        case 'I':
            if (!interpret_string_addr(&c->opt_dest_ip,
                                       poptGetOptArg(pc), 0)) {
                d_fprintf(stderr, _("\nInvalid ip address specified\n"));
            } else {
                c->opt_have_ip = true;
            }
            break;
        case 'U':
            c->opt_user_specified = true;
            c->opt_user_name = talloc_strdup(c, c->opt_user_name);
            p = strchr(c->opt_user_name,'%');
            if (p) {
                *p = 0;
                c->opt_password = p+1;
            }
            break;
        default:
            d_fprintf(stderr, _("\nInvalid option %s: %s\n"),
                      poptBadOption(pc, 0), poptStrerror(opt));
            net_help(c, argc, argv_const);
            exit(1);
        }
    }

    lp_load_global(get_dyn_CONFIGFILE());

#if defined(HAVE_BIND_TEXTDOMAIN_CODESET)
    /* Bind our gettext results to 'unix charset'

       This ensures that the translations and any embedded strings are in the
       same charset.  It won't be the one from the user's locale (we no
       longer auto-detect that), but it will be self-consistent.
    */
    bind_textdomain_codeset(MODULE_NAME, lp_unix_charset());
#endif

    argv_new = (const char **)poptGetArgs(pc);

    argc_new = argc;
    for (i=0; i<argc; i++) {
        if (argv_new[i] == NULL) {
            argc_new = i;
            break;
        }
    }

    if (c->do_talloc_report) {
        talloc_enable_leak_report();
    }

    if (c->opt_requester_name) {
        lp_set_cmdline("netbios name", c->opt_requester_name);
    }

    if (!c->opt_user_name && getenv("LOGNAME")) {
        c->opt_user_name = getenv("LOGNAME");
    }

    if (!c->opt_workgroup) {
        c->opt_workgroup = smb_xstrdup(lp_workgroup());
    }

    if (!c->opt_target_workgroup) {
        c->opt_target_workgroup = smb_xstrdup(lp_workgroup());
    }

    if (!init_names())
        exit(1);

    load_interfaces();

    /* this makes sure that when we do things like call scripts,
       that it won't assert because we are not root */
    sec_init();

    if (c->opt_machine_pass) {
        /* it is very useful to be able to make ads queries as the
           machine account for testing purposes and for domain leave */

        net_use_krb_machine_account(c);
    }

    if (!c->opt_password) {
        c->opt_password = getenv("PASSWD");
    }

    popt_burn_cmdline_password(argc, argv);

    /* Failing to init the msg_ctx isn't a fatal error. Only
       root-level things (joining/leaving domains etc.) will be denied. */

    c->msg_ctx = messaging_init(c, samba_tevent_context_init(c));

    rc = net_run_function(c, argc_new-1, argv_new+1, "net", net_func);

    DEBUG(2,("return code = %d\n", rc));

    gencache_stabilize();

    libnetapi_free(c->netapi_ctx);

    poptFreeContext(pc);

    TALLOC_FREE(frame);
    return rc;
}
krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
					    void *data,
					    krb5_krbhst_info *hi,
					    time_t timeout,
					    const krb5_data *send_buf,
					    krb5_data *recv_buf)
{
	krb5_error_code ret;
	NTSTATUS status;
	const char *name;
	struct addrinfo *ai, *a;
	struct smb_krb5_socket *smb_krb5;

	DATA_BLOB send_blob;

	struct tevent_context *ev;
	TALLOC_CTX *tmp_ctx = talloc_new(NULL);
	if (!tmp_ctx) {
		return ENOMEM;
	}

	if (!data) {
		/* If no event context was available, then create one for this loop */
		ev = samba_tevent_context_init(tmp_ctx);
		if (!ev) {
			talloc_free(tmp_ctx);
			return ENOMEM;
		}
	} else {
		ev = talloc_get_type_abort(data, struct tevent_context);
	}

	send_blob = data_blob_const(send_buf->data, send_buf->length);

	ret = krb5_krbhst_get_addrinfo(context, hi, &ai);
	if (ret) {
		talloc_free(tmp_ctx);
		return ret;
	}

	for (a = ai; a; a = a->ai_next) {
		struct socket_address *remote_addr;
		smb_krb5 = talloc(tmp_ctx, struct smb_krb5_socket);
		if (!smb_krb5) {
			talloc_free(tmp_ctx);
			return ENOMEM;
		}
		smb_krb5->hi = hi;

		switch (a->ai_family) {
		case PF_INET:
			name = "ipv4";
			break;
#ifdef HAVE_IPV6
		case PF_INET6:
			name = "ipv6";
			break;
#endif
		default:
			talloc_free(tmp_ctx);
			return EINVAL;
		}

		status = NT_STATUS_INVALID_PARAMETER;
		switch (hi->proto) {
		case KRB5_KRBHST_UDP:
			status = socket_create(name, SOCKET_TYPE_DGRAM, &smb_krb5->sock, 0);
			break;
		case KRB5_KRBHST_TCP:
			status = socket_create(name, SOCKET_TYPE_STREAM, &smb_krb5->sock, 0);
			break;
		case KRB5_KRBHST_HTTP:
			talloc_free(tmp_ctx);
			return EINVAL;
		}
		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(smb_krb5);
			continue;
		}

		talloc_steal(smb_krb5, smb_krb5->sock);

		remote_addr = socket_address_from_sockaddr(smb_krb5, a->ai_addr, a->ai_addrlen);
		if (!remote_addr) {
			talloc_free(smb_krb5);
			continue;
		}

		status = socket_connect_ev(smb_krb5->sock, NULL, remote_addr, 0, ev);
		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(smb_krb5);
			continue;
		}

		/* Setup the FDE, start listening for read events
		 * from the start (otherwise we may miss a socket
		 * drop) and mark as AUTOCLOSE along with the fde */

		/* Ths is equivilant to EVENT_FD_READABLE(smb_krb5->fde) */
		smb_krb5->fde = tevent_add_fd(ev, smb_krb5->sock,
					      socket_get_fd(smb_krb5->sock),
					      TEVENT_FD_READ,
					      smb_krb5_socket_handler, smb_krb5);
		/* its now the job of the event layer to close the socket */
		tevent_fd_set_close_fn(smb_krb5->fde, socket_tevent_fd_close_fn);
		socket_set_flags(smb_krb5->sock, SOCKET_FLAG_NOCLOSE);

		tevent_add_timer(ev, smb_krb5,
				 timeval_current_ofs(timeout, 0),
				 smb_krb5_request_timeout, smb_krb5);

		smb_krb5->status = NT_STATUS_OK;
		smb_krb5->reply = data_blob(NULL, 0);

		switch (hi->proto) {
		case KRB5_KRBHST_UDP:
			TEVENT_FD_WRITEABLE(smb_krb5->fde);
			smb_krb5->request = send_blob;
			break;
		case KRB5_KRBHST_TCP:

			smb_krb5->packet = packet_init(smb_krb5);
			if (smb_krb5->packet == NULL) {
				talloc_free(smb_krb5);
				return ENOMEM;
			}
			packet_set_private(smb_krb5->packet, smb_krb5);
			packet_set_socket(smb_krb5->packet, smb_krb5->sock);
			packet_set_callback(smb_krb5->packet, smb_krb5_full_packet);
			packet_set_full_request(smb_krb5->packet, packet_full_request_u32);
			packet_set_error_handler(smb_krb5->packet, smb_krb5_error_handler);
			packet_set_event_context(smb_krb5->packet, ev);
			packet_set_fde(smb_krb5->packet, smb_krb5->fde);

			smb_krb5->request = data_blob_talloc(smb_krb5, NULL, send_blob.length + 4);
			RSIVAL(smb_krb5->request.data, 0, send_blob.length);
			memcpy(smb_krb5->request.data+4, send_blob.data, send_blob.length);
			packet_send(smb_krb5->packet, smb_krb5->request);
			break;
		case KRB5_KRBHST_HTTP:
			talloc_free(tmp_ctx);
			return EINVAL;
		}
		while ((NT_STATUS_IS_OK(smb_krb5->status)) && !smb_krb5->reply.length) {
			if (tevent_loop_once(ev) != 0) {
				talloc_free(tmp_ctx);
				return EINVAL;
			}

			/* After each and every event loop, reset the
			 * send_to_kdc pointers to what they were when
			 * we entered this loop.  That way, if a
			 * nested event has invalidated them, we put
			 * it back before we return to the heimdal
			 * code */
			ret = krb5_set_send_to_kdc_func(context,
							smb_krb5_send_and_recv_func,
							data);
			if (ret != 0) {
				talloc_free(tmp_ctx);
				return ret;
			}
		}
		if (NT_STATUS_EQUAL(smb_krb5->status, NT_STATUS_IO_TIMEOUT)) {
			talloc_free(smb_krb5);
			continue;
		}

		if (!NT_STATUS_IS_OK(smb_krb5->status)) {
			struct tsocket_address *addr = socket_address_to_tsocket_address(smb_krb5, remote_addr);
			const char *addr_string = NULL;
			if (addr) {
				addr_string = tsocket_address_inet_addr_string(addr, smb_krb5);
			} else {
				addr_string = NULL;
			}
			DEBUG(2,("Error reading smb_krb5 reply packet: %s from %s\n", nt_errstr(smb_krb5->status),
				 addr_string));
			talloc_free(smb_krb5);
			continue;
		}

		ret = krb5_data_copy(recv_buf, smb_krb5->reply.data, smb_krb5->reply.length);
		if (ret) {
			talloc_free(tmp_ctx);
			return ret;
		}
		talloc_free(smb_krb5);

		break;
	}
	talloc_free(tmp_ctx);
	if (a) {
		return 0;
	}
	return KRB5_KDC_UNREACH;
}
 int main(int argc, char *argv[])
{
	struct tevent_context *evt_ctx;
	struct messaging_context *msg_ctx;
	pid_t pid;
	int i, n;
	char buf[12];
	int ret;
	TALLOC_CTX *frame = talloc_stackframe();

	load_case_tables();

	setup_logging(argv[0], DEBUG_STDOUT);

	lp_load_global(get_dyn_CONFIGFILE());

	if (!(evt_ctx = samba_tevent_context_init(NULL)) ||
	    !(msg_ctx = messaging_init(NULL, evt_ctx))) {
		fprintf(stderr, "could not init messaging context\n");
		TALLOC_FREE(frame);
		exit(1);
	}

	if (argc != 3) {
		fprintf(stderr, "%s: Usage - %s pid count\n", argv[0],
			argv[0]);
		TALLOC_FREE(frame);
		exit(1);
	}

	pid = atoi(argv[1]);
	n = atoi(argv[2]);

	messaging_register(msg_ctx, NULL, MSG_PONG, pong_message);

	for (i=0;i<n;i++) {
		messaging_send(msg_ctx, pid_to_procid(pid), MSG_PING,
			       &data_blob_null);
	}

	while (pong_count < i) {
		ret = tevent_loop_once(evt_ctx);
		if (ret != 0) {
			break;
		}
	}

	/* Ensure all messages get through to ourselves. */
	pong_count = 0;

	strlcpy(buf, "1234567890", sizeof(buf));

	for (i=0;i<n;i++) {
		messaging_send(msg_ctx, messaging_server_id(msg_ctx), MSG_PING,
			       &data_blob_null);
		messaging_send_buf(msg_ctx, messaging_server_id(msg_ctx),
				   MSG_PING,(uint8 *)buf, 11);
	}

	/*
	 * We have to loop at least 2 times for
	 * each message as local ping messages are
	 * handled by an immediate callback, that
	 * has to be dispatched, which sends a pong
	 * message, which also has to be dispatched.
	 * Above we sent 2*n messages, which means
	 * we have to dispatch 4*n times.
	 */

	while (pong_count < n*2) {
		ret = tevent_loop_once(evt_ctx);
		if (ret != 0) {
			break;
		}
	}

	if (pong_count != 2*n) {
		fprintf(stderr, "Message count failed (%d).\n", pong_count);
	}

	/* Speed testing */

	pong_count = 0;

	{
		struct timeval tv = timeval_current();
		size_t timelimit = n;
		size_t ping_count = 0;

		printf("Sending pings for %d seconds\n", (int)timelimit);
		while (timeval_elapsed(&tv) < timelimit) {		
			if(NT_STATUS_IS_OK(messaging_send_buf(
						   msg_ctx, pid_to_procid(pid),
						   MSG_PING,
						   (uint8 *)buf, 11)))
			   ping_count++;
			if(NT_STATUS_IS_OK(messaging_send(
						   msg_ctx, pid_to_procid(pid),
						   MSG_PING, &data_blob_null)))
			   ping_count++;

			while (ping_count > pong_count + 20) {
				ret = tevent_loop_once(evt_ctx);
				if (ret != 0) {
					break;
				}
			}
		}

		printf("waiting for %d remaining replies (done %d)\n", 
		       (int)(ping_count - pong_count), pong_count);
		while (timeval_elapsed(&tv) < 30 && pong_count < ping_count) {
			ret = tevent_loop_once(evt_ctx);
			if (ret != 0) {
				break;
			}
		}

		if (ping_count != pong_count) {
			fprintf(stderr, "ping test failed! received %d, sent "
				"%d\n", pong_count, (int)ping_count);
		}

		printf("ping rate of %.0f messages/sec\n", 
		       (ping_count+pong_count)/timeval_elapsed(&tv));
	}

	TALLOC_FREE(frame);
	return (0);
}
Esempio n. 18
0
_PUBLIC_ NTSTATUS gensec_update_ev(struct gensec_security *gensec_security,
				   TALLOC_CTX *out_mem_ctx,
				   struct tevent_context *ev,
				   const DATA_BLOB in, DATA_BLOB *out)
{
	NTSTATUS status;
	const struct gensec_security_ops *ops = gensec_security->ops;
	TALLOC_CTX *frame = NULL;
	struct tevent_req *subreq = NULL;
	bool ok;

	if (ops->update_send == NULL) {

		if (ev == NULL) {
			frame = talloc_stackframe();

			ev = samba_tevent_context_init(frame);
			if (ev == NULL) {
				status = NT_STATUS_NO_MEMORY;
				goto fail;
			}

			/*
			 * TODO: remove this hack once the backends
			 * are fixed.
			 */
			tevent_loop_allow_nesting(ev);
		}

		status = ops->update(gensec_security, out_mem_ctx,
				     ev, in, out);
		TALLOC_FREE(frame);
		if (!NT_STATUS_IS_OK(status)) {
			return status;
		}

		/*
		 * Because callers using the
		 * gensec_start_mech_by_auth_type() never call
		 * gensec_want_feature(), it isn't sensible for them
		 * to have to call gensec_have_feature() manually, and
		 * these are not points of negotiation, but are
		 * asserted by the client
		 */
		status = gensec_verify_dcerpc_auth_level(gensec_security);
		if (!NT_STATUS_IS_OK(status)) {
			return status;
		}

		return NT_STATUS_OK;
	}

	frame = talloc_stackframe();

	if (ev == NULL) {
		ev = samba_tevent_context_init(frame);
		if (ev == NULL) {
			status = NT_STATUS_NO_MEMORY;
			goto fail;
		}

		/*
		 * TODO: remove this hack once the backends
		 * are fixed.
		 */
		tevent_loop_allow_nesting(ev);
	}

	subreq = ops->update_send(frame, ev, gensec_security, in);
	if (subreq == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto fail;
	}
	ok = tevent_req_poll_ntstatus(subreq, ev, &status);
	if (!ok) {
		goto fail;
	}
	status = ops->update_recv(subreq, out_mem_ctx, out);
 fail:
	TALLOC_FREE(frame);
	return status;
}
static bool fdpass2_parent(pid_t child_pid, int ready_fd)
{
	struct tevent_context *ev = NULL;
	struct messaging_context *msg_ctx = NULL;
	bool retval = false;
	int up_pipe[2];
	int down_pipe[2];
	int pass_fds[2] = { 0 };
	int ret;
	NTSTATUS status;
	struct server_id dst;
	TALLOC_CTX *frame = talloc_stackframe();
	uint8_t c1 = 1, c2, c;
	ssize_t bytes;
	struct iovec iov;
	DATA_BLOB blob;
	struct tevent_fd *child_done_fde;
	struct child_done_state child_state;

	ev = samba_tevent_context_init(frame);
	if (ev == NULL) {
		fprintf(stderr, "parent: tevent_context_init failed\n");
		goto done;
	}

	msg_ctx = messaging_init(ev, ev);
	if (msg_ctx == NULL) {
		fprintf(stderr, "parent: messaging_init failed\n");
		goto done;
	}

	/* wait util the child is ready to receive messages */
	bytes = read(ready_fd, &c, 1);
	if (bytes != 1) {
		perror("parent: read from ready_fd failed");
		goto done;
	}

	ret = pipe(up_pipe);
	if (ret != 0) {
		perror("parent: pipe failed for up_pipe");
		goto done;
	}

	ret = pipe(down_pipe);
	if (ret != 0) {
		perror("parent: pipe failed for down_pipe");
		goto done;
	}

	child_state.fd = ready_fd;
	child_state.done = false;

	child_done_fde = tevent_add_fd(ev, ev, ready_fd, TEVENT_FD_READ,
				       child_done_cb, &child_state);
	if (child_done_fde == NULL) {
		fprintf(stderr,
			"parent: failed tevent_add_fd for child done\n");
		goto done;
	}

	pass_fds[0] = up_pipe[0];
	pass_fds[1] = down_pipe[1];

	dst = messaging_server_id(msg_ctx);
	dst.pid = child_pid;

	/*
	 * Send a certain payload with the fds, to test to test
	 * that fd-passing works when we have fragmentation and
	 * re-assembly of the datagrams.
	 */
	blob = data_blob_talloc_zero(frame, 1000*1000);
	iov.iov_base = blob.data;
	iov.iov_len  = blob.length;

	status = messaging_send_iov(msg_ctx, dst, MSG_TORTURE_FDPASS2, &iov, 1,
				    pass_fds, 2);
	if (!NT_STATUS_IS_OK(status)) {
		fprintf(stderr, "parent: messaging_send_iov failed: %s\n",
			nt_errstr(status));
		goto done;
	}

	printf("parent: waiting for child to confirm\n");

	while (!child_state.done) {
		ret = tevent_loop_once(ev);
		if (ret != 0) {
			fprintf(stderr, "parent: tevent_loop_once failed\n");
			goto done;
		}
	}

	printf("parent: child confirmed\n");

	close(up_pipe[0]);
	close(down_pipe[1]);

	bytes = write(up_pipe[1], &c1, 1);
	if (bytes != 1) {
		perror("parent: write to up pipe failed");
		goto done;
	}

	bytes = read(down_pipe[0], &c2, 1);
	if (bytes != 1) {
		perror("parent: read from down pipe failed");
		goto done;
	}

	if (c1 != c2) {
		fprintf(stderr, "parent: c1[%d] != c2[%d]\n", c1, c2);
		goto done;
	}

	ret = waitpid(child_pid, NULL, 0);
	if (ret == -1) {
		perror("parent: waitpid failed");
		goto done;
	}

	retval = true;

done:
	TALLOC_FREE(frame);
	return retval;
}
Esempio n. 20
0
/*
  main program
*/
int main(int argc, const char *argv[])
{
	TALLOC_CTX *mem_ctx;
	struct tevent_context *ev_ctx;
	struct messaging_context *msg_ctx;
	struct db_context *db;

	int unsafe_writes = 0;
	struct poptOption popt_options[] = {
		POPT_AUTOHELP
		POPT_COMMON_SAMBA
		{ "timelimit", 't', POPT_ARG_INT, &timelimit, 0, "timelimit", "INTEGER" },
		{ "delay", 'D', POPT_ARG_INT, &torture_delay, 0, "delay (in seconds) between operations", "INTEGER" },
		{ "verbose", 'v', POPT_ARG_NONE,  &verbose, 0, "switch on verbose mode", NULL },
		{ "db-name", 'N', POPT_ARG_STRING, &db_name, 0, "name of the test db", "NAME" },
		{ "no-trans", 'n', POPT_ARG_NONE, &no_trans, 0, "use fetch_lock/record store instead of transactions", NULL },
		{ "unsafe-writes", 'u', POPT_ARG_NONE, &unsafe_writes, 0, "do not use tdb transactions when writing", NULL },
		POPT_TABLEEND
	};
	int opt;
	const char **extra_argv;
	int extra_argc = 0;
	poptContext pc;
	int tdb_flags;

	int ret = 1;

	mem_ctx = talloc_stackframe();

	if (verbose) {
		setbuf(stdout, (char *)NULL); /* don't buffer */
	} else {
		setlinebuf(stdout);
	}

	load_case_tables();

	setup_logging(argv[0], DEBUG_STDERR);
	lp_set_cmdline("log level", "0");

	pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);

	while ((opt = poptGetNextOpt(pc)) != -1) {
		switch (opt) {
		default:
			fprintf(stderr, "Invalid option %s: %s\n",
				poptBadOption(pc, 0), poptStrerror(opt));
			goto done;
		}
	}

	/* setup the remaining options for the main program to use */
	extra_argv = poptGetArgs(pc);
	if (extra_argv) {
		extra_argv++;
		while (extra_argv[extra_argc]) extra_argc++;
	}

	lp_load_global(get_dyn_CONFIGFILE());

	ev_ctx = samba_tevent_context_init(mem_ctx);
	if (ev_ctx == NULL) {
		d_fprintf(stderr, "ERROR: could not init event context\n");
		goto done;
	}

	msg_ctx = messaging_init(mem_ctx, ev_ctx);
	if (msg_ctx == NULL) {
		d_fprintf(stderr, "ERROR: could not init messaging context\n");
		goto done;
	}

	if (unsafe_writes == 1) {
		tdb_flags = TDB_NOSYNC;
	} else {
		tdb_flags = TDB_DEFAULT;
	}

	if (no_trans) {
		tdb_flags |= TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH;
	}

	db = db_open(mem_ctx, db_name, 0, tdb_flags,  O_RDWR | O_CREAT, 0644,
		     DBWRAP_LOCK_ORDER_1);

	if (db == NULL) {
		d_fprintf(stderr, "failed to open db '%s': %s\n", db_name,
			  strerror(errno));
		goto done;
	}

	if (get_my_vnn() == NONCLUSTER_VNN) {
		set_my_vnn(0);
	}
	pnn = get_my_vnn();

	printf("Starting test on node %u. running for %u seconds. "
	       "sleep delay: %u seconds.\n", pnn, timelimit, torture_delay);

	if (!verbose && (pnn == 0)) {
		tevent_add_timer(ev_ctx, db, timeval_current_ofs(1, 0), each_second, db);
	}

	test_store_records(db, ev_ctx);

	if (verbose || (pnn == 0)) {
		if (success != true) {
			printf("The test FAILED\n");
			ret = 2;
		} else {
			printf("SUCCESS!\n");
			ret = 0;
		}
	}

done:
	talloc_free(mem_ctx);
	return ret;
}
Esempio n. 21
0
bool run_dbwrap_watch1(int dummy)
{
	struct tevent_context *ev = NULL;
	struct messaging_context *msg = NULL;
	struct db_context *db = NULL;
	const char *keystr = "key";
	TDB_DATA key = string_term_tdb_data(keystr);
	struct db_record *rec = NULL;
	struct tevent_req *req = NULL;
	NTSTATUS status;
	bool ret = false;

	ev = samba_tevent_context_init(talloc_tos());
	if (ev == NULL) {
		fprintf(stderr, "tevent_context_init failed\n");
		goto fail;
	}
	msg = messaging_init(ev, ev);
	if (msg == NULL) {
		fprintf(stderr, "messaging_init failed\n");
		goto fail;
	}
	db = db_open(msg, "test_watch.tdb", 0, TDB_DEFAULT,
		     O_CREAT|O_RDWR, 0644, DBWRAP_LOCK_ORDER_1,
		     DBWRAP_FLAG_NONE);
	if (db == NULL) {
		fprintf(stderr, "db_open failed: %s\n", strerror(errno));
		goto fail;
	}
	dbwrap_watch_db(db, msg);
	rec = dbwrap_fetch_locked(db, db, key);
	if (rec == NULL) {
		fprintf(stderr, "dbwrap_fetch_locked failed\n");
		goto fail;
	}
	req = dbwrap_record_watch_send(talloc_tos(), ev, rec, msg);
	if (req == NULL) {
		fprintf(stderr, "dbwrap_record_watch_send failed\n");
		goto fail;
	}
	TALLOC_FREE(rec);

	status = dbwrap_store_int32_bystring(db, "different_key", 1);
	if (!NT_STATUS_IS_OK(status)) {
		fprintf(stderr, "dbwrap_store_int32 failed: %s\n",
			nt_errstr(status));
		goto fail;
	}

	status = dbwrap_store_int32_bystring(db, keystr, 1);
	if (!NT_STATUS_IS_OK(status)) {
		fprintf(stderr, "dbwrap_store_int32 failed: %s\n",
			nt_errstr(status));
		goto fail;
	}

	if (!tevent_req_poll(req, ev)) {
		fprintf(stderr, "tevent_req_poll failed\n");
		goto fail;
	}

	status = dbwrap_record_watch_recv(req, talloc_tos(), &rec);
	if (!NT_STATUS_IS_OK(status)) {
		fprintf(stderr, "dbwrap_record_watch_recv failed: %s\n",
			nt_errstr(status));
		goto fail;
	}

	ret = true;
fail:
	TALLOC_FREE(req);
	TALLOC_FREE(rec);
	TALLOC_FREE(db);
	TALLOC_FREE(msg);
	TALLOC_FREE(ev);
	return ret;
}