Exemple #1
0
BOOL prs_werror(const char *name, prs_struct *ps, int depth, WERROR *status)
{
	char *q = prs_mem_get(ps, sizeof(uint32));
	if (q == NULL)
		return False;

	if (UNMARSHALLING(ps)) {
		if (ps->bigendian_data)
			*status = W_ERROR(RIVAL(q,0));
		else
			*status = W_ERROR(IVAL(q,0));
	} else {
		if (ps->bigendian_data)
			RSIVAL(q,0,W_ERROR_V(*status));
		else
			SIVAL(q,0,W_ERROR_V(*status));
	}

	DEBUG(5,("%s%04x %s: %s\n", tab_depth(depth), ps->data_offset, name, 
		 dos_errstr(*status)));

	ps->data_offset += sizeof(uint32);

	return True;
}
Exemple #2
0
static bool test_netprintqgetinfo(struct torture_context *tctx,
				  struct smbcli_state *cli)
{
	struct rap_NetPrintQGetInfo r;
	struct rap_NetPrintQEnum r_enum;
	int i, p;
	uint16_t levels[] = { 0, 1, 2, 3, 4, 5 };

	r.in.level = 0;
	r.in.bufsize = 0;
	r.in.PrintQueueName = "";

	torture_assert_ntstatus_ok(tctx,
		smbcli_rap_netprintqgetinfo(cli->tree, tctx, &r),
		"smbcli_rap_netprintqgetinfo failed");
	torture_assert_werr_equal(tctx,
				  W_ERROR(r.out.status),
				  WERR_INVALID_PARAMETER,
				  "smbcli_rap_netprintqgetinfo failed");

	r_enum.in.level = 5;
	r_enum.in.bufsize = 8192;

	torture_assert_ntstatus_ok(tctx,
		smbcli_rap_netprintqenum(cli->tree, tctx, &r_enum),
		"failed to enum printq");
	torture_assert_werr_ok(tctx, W_ERROR(r_enum.out.status),
		"failed to enum printq");

	for (p=0; p < r_enum.out.count; p++) {

		for (i=0; i < ARRAY_SIZE(levels); i++) {

			r.in.level = levels[i];
			r.in.bufsize = 8192;
			r.in.PrintQueueName = r_enum.out.info[p].info5.PrintQueueName;

			torture_comment(tctx, "Testing rap_NetPrintQGetInfo(%s) level %d\n",
				r.in.PrintQueueName, r.in.level);

			torture_assert_ntstatus_ok(tctx,
				smbcli_rap_netprintqgetinfo(cli->tree, tctx, &r),
				"smbcli_rap_netprintqgetinfo failed");
			torture_assert_werr_ok(tctx,
				W_ERROR(r.out.status),
				"smbcli_rap_netprintqgetinfo failed");

			switch (r.in.level) {
			case 0:
				printf("%s\n", r.out.info.info0.PrintQName);
				break;
			}
		}
	}

	return true;
}
Exemple #3
0
const char *cli_errstr(struct cli_state *cli)
{   
	fstring cli_error_message;
	char *result;

	if (!cli->initialised) {
		fstrcpy(cli_error_message, "[Programmer's error] cli_errstr called on unitialized cli_stat struct!\n");
		goto done;
	}

	/* Case #1: RAP error */
	if (cli->rap_error) {
		strlcpy(cli_error_message, win_errstr(W_ERROR(cli->rap_error)),
			sizeof(cli_error_message));
		goto done;
	}

	if (!cli_state_is_connected(cli) && NT_STATUS_IS_OK(cli->raw_status)) {
		return nt_errstr(NT_STATUS_CONNECTION_DISCONNECTED);
	}

	return nt_errstr(cli->raw_status);
 done:
	result = talloc_strdup(talloc_tos(), cli_error_message);
	SMB_ASSERT(result);
	return result;
}
Exemple #4
0
static bool test_netprintjobsetinfo(struct torture_context *tctx,
				    struct smbcli_state *cli)
{
	struct rap_NetPrintQEnum r;
	int i;

	r.in.level = 5;
	r.in.bufsize = 8192;

	torture_assert_ntstatus_ok(tctx,
		smbcli_rap_netprintqenum(cli->tree, tctx, &r),
		"failed to enum printq");
	torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
		"failed to enum printq");

	for (i=0; i < r.out.count; i++) {

		const char *printqname = r.out.info[i].info5.PrintQueueName;

		torture_assert(tctx,
			test_netprintjobsetinfo_byqueue(tctx, cli, printqname),
			"failed to set printjobs on print queue");
	}

	return true;
}
Exemple #5
0
static bool test_netprintqenum(struct torture_context *tctx,
			       struct smbcli_state *cli)
{
	struct rap_NetPrintQEnum r;
	int i, q;
	uint16_t levels[] = { 0, 1, 2, 3, 4, 5 };

	for (i=0; i < ARRAY_SIZE(levels); i++) {

		r.in.level = levels[i];
		r.in.bufsize = 8192;

		torture_comment(tctx,
			"Testing rap_NetPrintQEnum level %d\n", r.in.level);

		torture_assert_ntstatus_ok(tctx,
			smbcli_rap_netprintqenum(cli->tree, tctx, &r),
			"smbcli_rap_netprintqenum failed");
		torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
			"failed to enum printq");

		for (q=0; q<r.out.count; q++) {
			switch (r.in.level) {
			case 0:
				printf("%s\n", r.out.info[q].info0.PrintQName);
				break;
			}
		}
	}

	return true;
}
Exemple #6
0
static uint8_t client_connect(Client *client) {
	//printf("connecting...\n");
	start:

	if (-1 == connect(client->sock_watcher.fd, client->worker->config->saddr->ai_addr, client->worker->config->saddr->ai_addrlen)) {
		switch (errno) {
			case EINPROGRESS:
			case EALREADY:
				/* async connect now in progress */
				client->state = CLIENT_CONNECTING;
				return 1;
			case EISCONN:
				break;
			case EINTR:
				goto start;
			default:
			{
				strerror_r(errno, client->buffer, sizeof(client->buffer));
				W_ERROR("connect() failed: %s (%d)", client->buffer, errno);
				return 0;
			}
		}
	}

	/* successfully connected */
	client->state = CLIENT_WRITING;
	return 1;
}
Exemple #7
0
/*
  pull a WERROR
*/
_PUBLIC_ enum ndr_err_code ndr_pull_WERROR(struct ndr_pull *ndr, int ndr_flags, WERROR *status)
{
	uint32_t v;
	NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
	*status = W_ERROR(v);
	return NDR_ERR_SUCCESS;
}
Exemple #8
0
const char *libnetapi_errstr(NET_API_STATUS status)
{
	if (status & 0xc0000000) {
		return get_friendly_nt_error_msg(NT_STATUS(status));
	}

	return get_friendly_werror_msg(W_ERROR(status));
}
Exemple #9
0
/*
 * This takes an AD error message and splits it into the WERROR code
 * (WERR_DS_GENERIC if none found) and the reason (remaining string).
 */
static WERROR ad_error(const char *err_msg, char **reason)
{
	WERROR err = W_ERROR(strtol(err_msg, reason, 16));

	if ((reason != NULL) && (*reason[0] != ':')) {
		return WERR_DS_GENERIC_ERROR; /* not an AD std error message */
	}
		
	if (reason != NULL) {
		*reason += 2; /* skip ": " */
	}
	return err;
}
Exemple #10
0
_PUBLIC_ const char *dcerpc_errstr(TALLOC_CTX *mem_ctx, uint32_t fault_code)
{
	int idx = 0;
	WERROR werr = W_ERROR(fault_code);

	while (dcerpc_faults[idx].errstr != NULL) {
		if (dcerpc_faults[idx].faultcode == fault_code) {
			return dcerpc_faults[idx].errstr;
		}
		idx++;
	}

	return win_errstr(werr);
}
Exemple #11
0
char *libnetapi_errstr(NET_API_STATUS status)
{
	TALLOC_CTX *frame = talloc_stackframe();
	char *ret;
	if (status & 0xc0000000) {
		ret = talloc_strdup(NULL, 
				     get_friendly_nt_error_msg(NT_STATUS(status)));
	} else {
		ret = talloc_strdup(NULL,
				    get_friendly_werror_msg(W_ERROR(status)));
	}
	TALLOC_FREE(frame);
	return ret;
}
Exemple #12
0
_PUBLIC_ NTSTATUS dcerpc_fault_to_nt_status(uint32_t fault_code)
{
	int idx = 0;
	WERROR werr = W_ERROR(fault_code);

	if (fault_code == 0) {
		return NT_STATUS_RPC_PROTOCOL_ERROR;
	}

	while (dcerpc_faults[idx].errstr != NULL) {
		if (dcerpc_faults[idx].faultcode == fault_code) {
			return dcerpc_faults[idx].nt_status;
		}
		idx++;
	}

	return werror_to_ntstatus(werr);
}
Exemple #13
0
static bool test_netprintq_resume(struct torture_context *tctx,
				  struct smbcli_state *cli,
				  const char *PrintQueueName)
{
	struct rap_NetPrintQueueResume r;

	r.in.PrintQueueName = PrintQueueName;

	torture_comment(tctx, "Testing rap_NetPrintQueueResume(%s)\n", r.in.PrintQueueName);

	torture_assert_ntstatus_ok(tctx,
		smbcli_rap_netprintqueueresume(cli->tree, tctx, &r),
		"smbcli_rap_netprintqueueresume failed");
	torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
		"smbcli_rap_netprintqueueresume failed");

	return true;
}
Exemple #14
0
WERROR cli_srvsvc_net_remote_tod(struct cli_state *cli, TALLOC_CTX *mem_ctx,
				 char *server, TIME_OF_DAY_INFO *tod)
{
	prs_struct qbuf, rbuf;
	SRV_Q_NET_REMOTE_TOD q;
	SRV_R_NET_REMOTE_TOD r;
	WERROR result = W_ERROR(ERRgeneral);

	ZERO_STRUCT(q);
	ZERO_STRUCT(r);

	/* Initialise parse structures */

	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);

	/* Initialise input parameters */

	init_srv_q_net_remote_tod(&q, cli->srv_name_slash);

	/* Marshall data and send request */

	if (!srv_io_q_net_remote_tod("", &q, &qbuf, 0) ||
	    !rpc_api_pipe_req(cli, SRV_NET_REMOTE_TOD, &qbuf, &rbuf))
		goto done;

	/* Unmarshall response */

	r.tod = tod;

	if (!srv_io_r_net_remote_tod("", &r, &rbuf, 0))
		goto done;

	result = r.status;

	if (!W_ERROR_IS_OK(result))
		goto done;

 done:
	prs_mem_free(&qbuf);
	prs_mem_free(&rbuf);

	return result;	
}
Exemple #15
0
WERROR cli_srvsvc_net_srv_get_info(struct cli_state *cli, 
				   TALLOC_CTX *mem_ctx,
				   uint32 switch_value, SRV_INFO_CTR *ctr)
{
	prs_struct qbuf, rbuf;
	SRV_Q_NET_SRV_GET_INFO q;
	SRV_R_NET_SRV_GET_INFO r;
	WERROR result = W_ERROR(ERRgeneral);

	ZERO_STRUCT(q);
	ZERO_STRUCT(r);

	/* Initialise parse structures */

	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);

	/* Initialise input parameters */

	init_srv_q_net_srv_get_info(&q, cli->srv_name_slash, switch_value);

	/* Marshall data and send request */

	if (!srv_io_q_net_srv_get_info("", &q, &qbuf, 0) ||
	    !rpc_api_pipe_req(cli, SRV_NET_SRV_GET_INFO, &qbuf, &rbuf))
		goto done;

	/* Unmarshall response */

	r.ctr = ctr;

	if (!srv_io_r_net_srv_get_info("", &r, &rbuf, 0))
		goto done;

	result = r.status;

 done:
	prs_mem_free(&qbuf);
	prs_mem_free(&rbuf);

	return result;
}
Exemple #16
0
WERROR cli_srvsvc_net_share_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
				const char *netname, uint32 type, 
				const char *remark, uint32 perms, 
				uint32 max_uses, uint32 num_uses, 
				const char *path, const char *passwd)
{
	prs_struct qbuf, rbuf;
	SRV_Q_NET_SHARE_ADD q;
	SRV_R_NET_SHARE_ADD r;
	WERROR result = W_ERROR(ERRgeneral);

	ZERO_STRUCT(q);
	ZERO_STRUCT(r);

	/* Initialise parse structures */

	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);

	init_srv_q_net_share_add(&q,cli->srv_name_slash, netname, type, remark,
				 perms, max_uses, num_uses, path, passwd);

	/* Marshall data and send request */

	if (!srv_io_q_net_share_add("", &q, &qbuf, 0) ||
	    !rpc_api_pipe_req(cli, SRV_NET_SHARE_ADD, &qbuf, &rbuf))
		goto done;

	/* Unmarshall response */

	if (!srv_io_r_net_share_add("", &r, &rbuf, 0))
		goto done;

	result = r.status;

 done:
	prs_mem_free(&qbuf);
	prs_mem_free(&rbuf);

	return result;	
}
Exemple #17
0
WERROR cli_srvsvc_net_share_del(struct cli_state *cli, TALLOC_CTX *mem_ctx,
				const char *sharename)
{
	prs_struct qbuf, rbuf;
	SRV_Q_NET_SHARE_DEL q;
	SRV_R_NET_SHARE_DEL r;
	WERROR result = W_ERROR(ERRgeneral);

	ZERO_STRUCT(q);
	ZERO_STRUCT(r);

	/* Initialise parse structures */

	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);

	/* Initialise input parameters */

	init_srv_q_net_share_del(&q, cli->srv_name_slash, sharename);

	/* Marshall data and send request */

	if (!srv_io_q_net_share_del("", &q, &qbuf, 0) ||
	    !rpc_api_pipe_req(cli, SRV_NET_SHARE_DEL, &qbuf, &rbuf))
		goto done;

	/* Unmarshall response */

	if (!srv_io_r_net_share_del("", &r, &rbuf, 0))
		goto done;

	result = r.status;

 done:
	prs_mem_free(&qbuf);
	prs_mem_free(&rbuf);

	return result;
}
Exemple #18
0
void client_state_machine(Client *client) {
	int r;
	Config *config = client->worker->config;

	start:
	//printf("state: %d\n", client->state);
	switch (client->state) {
		case CLIENT_START:
			client->worker->stats.req_started++;

			do {
				r = socket(config->saddr->ai_family, config->saddr->ai_socktype, config->saddr->ai_protocol);
			} while (-1 == r && errno == EINTR);

			if (-1 == r) {
				client->state = CLIENT_ERROR;
				strerror_r(errno, client->buffer, sizeof(client->buffer));
				W_ERROR("socket() failed: %s (%d)", client->buffer, errno);
				goto start;
			}

			/* set non-blocking */
			fcntl(r, F_SETFL, O_NONBLOCK | O_RDWR);

			ev_init(&client->sock_watcher, client_io_cb);
			ev_io_set(&client->sock_watcher, r, EV_WRITE);
			ev_io_start(client->worker->loop, &client->sock_watcher);

			if (!client_connect(client)) {
				client->state = CLIENT_ERROR;
				goto start;
			} else {
				client_set_events(client, EV_WRITE);
				return;
			}
		case CLIENT_CONNECTING:
			if (!client_connect(client)) {
				client->state = CLIENT_ERROR;
				goto start;
			}
		case CLIENT_WRITING:
			while (1) {
				r = write(client->sock_watcher.fd, &config->request[client->request_offset], config->request_size - client->request_offset);
				//printf("write(%d - %d = %d): %d\n", config->request_size, client->request_offset, config->request_size - client->request_offset, r);
				if (r == -1) {
					/* error */
					if (errno == EINTR)
						continue;
					strerror_r(errno, client->buffer, sizeof(client->buffer));
					W_ERROR("write() failed: %s (%d)", client->buffer, errno);
					client->state = CLIENT_ERROR;
					goto start;
				} else if (r != 0) {
					/* success */
					client->request_offset += r;
					if (client->request_offset == config->request_size) {
						/* whole request was sent, start reading */
						client->state = CLIENT_READING;
						client_set_events(client, EV_READ);
					}

					return;
				} else {
					/* disconnect */
					client->state = CLIENT_END;
					goto start;
				}
			}
		case CLIENT_READING:
			while (1) {
				r = read(client->sock_watcher.fd, &client->buffer[client->buffer_offset], sizeof(client->buffer) - client->buffer_offset - 1);
				//printf("read(): %d, offset was: %d\n", r, client->buffer_offset);
				if (r == -1) {
					/* error */
					if (errno == EINTR)
						continue;
					strerror_r(errno, client->buffer, sizeof(client->buffer));
					W_ERROR("read() failed: %s (%d)", client->buffer, errno);
					client->state = CLIENT_ERROR;
				} else if (r != 0) {
					/* success */
					client->bytes_received += r;
					client->buffer_offset += r;
					client->worker->stats.bytes_total += r;

					if (client->buffer_offset >= sizeof(client->buffer)) {
						/* too big response header */
						client->state = CLIENT_ERROR;
						break;
					}
					client->buffer[client->buffer_offset] = '\0';
					//printf("buffer:\n==========\n%s\n==========\n", client->buffer);
					if (!client_parse(client, r)) {
						client->state = CLIENT_ERROR;
						//printf("parser failed\n");
						break;
					} else {
						if (client->state == CLIENT_END)
							goto start;
						else
							return;
					}
				} else {
					/* disconnect */
					if (client->parser_state == PARSER_BODY && !client->keepalive && client->status_success
						&& !client->chunked && client->content_length == -1) {
						client->success = 1;
						client->state = CLIENT_END;
					} else {
						client->state = CLIENT_ERROR;
					}

					goto start;
				}
			}

		case CLIENT_ERROR:
			//printf("client error\n");
			client->worker->stats.req_error++;
			client->keepalive = 0;
			client->success = 0;
			client->state = CLIENT_END;
		case CLIENT_END:
			/* update worker stats */
			client->worker->stats.req_done++;

			if (client->success) {
				client->worker->stats.req_success++;
				client->worker->stats.bytes_body += client->bytes_received - client->header_size;
			} else {
				client->worker->stats.req_failed++;
			}

			/* print progress every 10% done */
			if (client->worker->id == 1 && client->worker->stats.req_done % client->worker->progress_interval == 0) {
				printf("progress: %3d%% done\n",
					(int) (client->worker->stats.req_done * 100 / client->worker->stats.req_todo)
				);
			}

			if (client->worker->stats.req_started == client->worker->stats.req_todo) {
				/* this worker has started all requests */
				client->keepalive = 0;
				client_reset(client);

				if (client->worker->stats.req_done == client->worker->stats.req_todo) {
					/* this worker has finished all requests */
					ev_unref(client->worker->loop);
				}
			} else {
				client_reset(client);
				goto start;
			}
	}
}
Exemple #19
0
static bool test_rap_print(struct torture_context *tctx,
			   struct smbcli_state *cli)
{
	struct rap_NetPrintQEnum r;
	int i;

	r.in.level = 5;
	r.in.bufsize = 8192;

	torture_assert_ntstatus_ok(tctx,
		smbcli_rap_netprintqenum(cli->tree, tctx, &r),
		"failed to enum printq");
	torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
		"failed to enum printq");

	for (i=0; i < r.out.count; i++) {

		const char *printqname = r.out.info[i].info5.PrintQueueName;
		struct smbcli_tree *res_queue = NULL;
		uint16_t num_jobs;
		union rap_printj_info *job_info;
		int j;

		torture_assert(tctx,
			test_netprintq_pause(tctx, cli, printqname),
			"failed to set printjobs on print queue");

		torture_assert_ntstatus_ok(tctx,
			torture_second_tcon(tctx, cli->session, printqname, &res_queue),
			"failed to open 2nd connection");

		torture_assert(tctx,
			print_printjob(tctx, res_queue),
			"failed to print job on 2nd connection");

		talloc_free(res_queue);

		torture_assert(tctx,
			test_netprintjobenum_args(tctx, cli, printqname, 1,
			&num_jobs, &job_info),
			"failed to enum printjobs on print queue");

		for (j=0; j < num_jobs; j++) {

			uint16_t job_id = job_info[j].info1.JobID;

			torture_assert(tctx,
				test_netprintjobgetinfo_byid(tctx, cli, job_id),
				"failed to getinfo on new printjob");

			torture_assert(tctx,
				test_netprintjob_delete(tctx, cli, job_id),
				"failed to delete job");
		}

		torture_assert(tctx,
			test_netprintq_resume(tctx, cli, printqname),
			"failed to resume print queue");

	}

	return true;
}
Exemple #20
0
WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
				uint32 file_level, const char *user_name,
				SRV_FILE_INFO_CTR *ctr,	int preferred_len,
				ENUM_HND *hnd)
{
	prs_struct qbuf, rbuf;
	SRV_Q_NET_FILE_ENUM q;
	SRV_R_NET_FILE_ENUM r;
	WERROR result = W_ERROR(ERRgeneral);
	int i;

	ZERO_STRUCT(q);
	ZERO_STRUCT(r);

	/* Initialise parse structures */

	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);

	/* Initialise input parameters */

	init_srv_q_net_file_enum(&q, cli->srv_name_slash, NULL, user_name, 
				 file_level, ctr, preferred_len, hnd);

	/* Marshall data and send request */

	if (!srv_io_q_net_file_enum("", &q, &qbuf, 0) ||
	    !rpc_api_pipe_req(cli, SRV_NET_FILE_ENUM, &qbuf, &rbuf))
		goto done;

	/* Unmarshall response */

	if (!srv_io_r_net_file_enum("", &r, &rbuf, 0))
		goto done;

	result = r.status;

	if (!W_ERROR_IS_OK(result))
		goto done;

	/* copy the data over to the ctr */

	ZERO_STRUCTP(ctr);

	ctr->switch_value = file_level;

	ctr->num_entries = ctr->num_entries2 = r.ctr.num_entries;
	
	switch(file_level) {
	case 3:
		ctr->file.info3 = (SRV_FILE_INFO_3 *)talloc(
			mem_ctx, sizeof(SRV_FILE_INFO_3) * ctr->num_entries);

		memset(ctr->file.info3, 0, 
		       sizeof(SRV_FILE_INFO_3) * ctr->num_entries);

		for (i = 0; i < r.ctr.num_entries; i++) {
			SRV_FILE_INFO_3 *info3 = &ctr->file.info3[i];
			char *s;
			
			/* Copy pointer crap */

			memcpy(&info3->info_3, &r.ctr.file.info3[i].info_3, 
			       sizeof(FILE_INFO_3));

			/* Duplicate strings */

			s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_path_name);
			if (s)
				init_unistr2(&info3->info_3_str.uni_path_name, s, UNI_STR_TERMINATE);
		
			s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_user_name);
			if (s)
				init_unistr2(&info3->info_3_str.uni_user_name, s, UNI_STR_TERMINATE);

		}		

		break;
	}

 done:
	prs_mem_free(&qbuf);
	prs_mem_free(&rbuf);

	return result;
}
Exemple #21
0
WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
				 uint32 info_level, SRV_SHARE_INFO_CTR *ctr,
				 int preferred_len, ENUM_HND *hnd)
{
	prs_struct qbuf, rbuf;
	SRV_Q_NET_SHARE_ENUM q;
	SRV_R_NET_SHARE_ENUM r;
	WERROR result = W_ERROR(ERRgeneral);
	int i;

	ZERO_STRUCT(q);
	ZERO_STRUCT(r);

	/* Initialise parse structures */

	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);

	/* Initialise input parameters */

	init_srv_q_net_share_enum(
		&q, cli->srv_name_slash, info_level, preferred_len, hnd);

	/* Marshall data and send request */

	if (!srv_io_q_net_share_enum("", &q, &qbuf, 0) ||
	    !rpc_api_pipe_req(cli, SRV_NET_SHARE_ENUM_ALL, &qbuf, &rbuf))
		goto done;

	/* Unmarshall response */

	if (!srv_io_r_net_share_enum("", &r, &rbuf, 0))
		goto done;

	result = r.status;

	if (!W_ERROR_IS_OK(result))
		goto done;

	/* Oh yuck yuck yuck - we have to copy all the info out of the
	   SRV_SHARE_INFO_CTR in the SRV_R_NET_SHARE_ENUM as when we do a
	   prs_mem_free() it will all be invalidated.  The various share
	   info structures suck badly too.  This really is gross. */

	ZERO_STRUCTP(ctr);

	if (!r.ctr.num_entries)
		goto done;

	ctr->info_level = info_level;
	ctr->num_entries = r.ctr.num_entries;

	switch(info_level) {
	case 1:
		ctr->share.info1 = (SRV_SHARE_INFO_1 *)talloc(
			mem_ctx, sizeof(SRV_SHARE_INFO_1) * ctr->num_entries);
		
		memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1));

		for (i = 0; i < ctr->num_entries; i++) {
			SRV_SHARE_INFO_1 *info1 = &ctr->share.info1[i];
			char *s;
			
			/* Copy pointer crap */

			memcpy(&info1->info_1, &r.ctr.share.info1[i].info_1, 
			       sizeof(SH_INFO_1));

			/* Duplicate strings */

			s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_netname);
			if (s)
				init_unistr2(&info1->info_1_str.uni_netname, s, UNI_STR_TERMINATE);
		
			s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_remark);
			if (s)
				init_unistr2(&info1->info_1_str.uni_remark, s, UNI_STR_TERMINATE);

		}		

		break;
	case 2:
		ctr->share.info2 = (SRV_SHARE_INFO_2 *)talloc(
			mem_ctx, sizeof(SRV_SHARE_INFO_2) * ctr->num_entries);
		
		memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2));

		for (i = 0; i < ctr->num_entries; i++) {
			SRV_SHARE_INFO_2 *info2 = &ctr->share.info2[i];
			char *s;
			
			/* Copy pointer crap */

			memcpy(&info2->info_2, &r.ctr.share.info2[i].info_2, 
			       sizeof(SH_INFO_2));

			/* Duplicate strings */

			s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_netname);
			if (s)
				init_unistr2(&info2->info_2_str.uni_netname, s, UNI_STR_TERMINATE);

			s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_remark);
			if (s)
				init_unistr2(&info2->info_2_str.uni_remark, s, UNI_STR_TERMINATE);

			s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_path);
			if (s)
				init_unistr2(&info2->info_2_str.uni_path, s, UNI_STR_TERMINATE);

			s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_passwd);
			if (s)
				init_unistr2(&info2->info_2_str.uni_passwd, s, UNI_STR_TERMINATE);
		}
		break;
	}
 done:
	prs_mem_free(&qbuf);
	prs_mem_free(&rbuf);

	return result;
}
Exemple #22
0
	{ "WERR_INVALID_ENVIRONMENT", WERR_INVALID_ENVIRONMENT },
	{ "WERR_INVALID_FORM_NAME", WERR_INVALID_FORM_NAME },
	{ "WERR_INVALID_FORM_SIZE", WERR_INVALID_FORM_SIZE },
	{ "WERR_BUF_TOO_SMALL", WERR_BUF_TOO_SMALL },
	{ "WERR_JOB_NOT_FOUND", WERR_JOB_NOT_FOUND },
	{ "WERR_DEST_NOT_FOUND", WERR_DEST_NOT_FOUND },
	{ "WERR_NOT_LOCAL_DOMAIN", WERR_NOT_LOCAL_DOMAIN },
	{ "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE },
	{ "WERR_STATUS_MORE_ENTRIES  ", WERR_STATUS_MORE_ENTRIES },
	{ "WERR_DFS_NO_SUCH_VOL", WERR_DFS_NO_SUCH_VOL },
	{ "WERR_DFS_NO_SUCH_SHARE", WERR_DFS_NO_SUCH_SHARE },
	{ "WERR_DFS_NO_SUCH_SERVER", WERR_DFS_NO_SUCH_SERVER },
	{ "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR },
	{ "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT },
	{ "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR },
	{ NULL, W_ERROR(0) }
};

/*****************************************************************************
 returns a DOS error message.  not amazingly helpful, but better than a number.
 *****************************************************************************/

const char *dos_errstr(WERROR werror)
{
        static pstring msg;
        int idx = 0;

	slprintf(msg, sizeof(msg), "DOS code 0x%08x", W_ERROR_V(werror));

	while (dos_errs[idx].dos_errstr != NULL) {
		if (W_ERROR_V(dos_errs[idx].werror) ==