1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-24 13:57:43 +03:00

Sync 3.0 branch with HEAD

This commit is contained in:
Jelmer Vernooij -
parent bcb7d928af
commit 3823a2ff5a
7 changed files with 4651 additions and 3615 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,260 +1,119 @@
/* /*
* Unix SMB/CIFS implementation. Unix SMB/CIFS implementation.
* RPC Pipe client / server routines RPC pipe client
* Copyright (C) Andrew Tridgell 1992-2000,
* Copyright (C) Jean Francois Micouleau 1998-2000, Copyright (C) Gerald Carter 2001-2002,
* Copyright (C) Tim Potter 2000-2002,
* This program is free software; you can redistribute it and/or modify Copyright (C) Andrew Tridgell 1994-2000,
* it under the terms of the GNU General Public License as published by Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
* the Free Software Foundation; either version 2 of the License, or Copyright (C) Jean-Francois Micouleau 1999-2000.
* (at your option) any later version.
* This program is free software; you can redistribute it and/or modify
* This program is distributed in the hope that it will be useful, it under the terms of the GNU General Public License as published by
* but WITHOUT ANY WARRANTY; without even the implied warranty of the Free Software Foundation; either version 2 of the License, or
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the (at your option) any later version.
* GNU General Public License for more details.
* This program is distributed in the hope that it will be useful,
* You should have received a copy of the GNU General Public License but WITHOUT ANY WARRANTY; without even the implied warranty of
* along with this program; if not, write to the Free Software MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. GNU General Public License for more details.
*/
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h" #include "includes.h"
#if 0
#include "rpc_parse.h"
#include "nterr.h"
#endif
extern pstring global_myname;
struct msg_info_table {
uint32 msg;
uint32 field;
char* name;
void (*construct_fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
print_queue_struct *queue,
NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
};
struct msg_info_table msg_table[] = {
{ PRINTER_MESSAGE_DRIVER, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_MESSAGE_DRIVER", spoolss_notify_driver_name },
{ PRINTER_MESSAGE_ATTRIBUTES, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_MESSAGE_ATTRIBUTES", spoolss_notify_attributes },
{ PRINTER_MESSAGE_COMMENT, PRINTER_NOTIFY_COMMENT, "PRINTER_MESSAGE_COMMENT", spoolss_notify_comment },
{ PRINTER_MESSAGE_LOCATION, PRINTER_NOTIFY_LOCATION, "PRINTER_MESSAGE_LOCATION", spoolss_notify_location },
{ PRINTER_MESSAGE_PRINTERNAME, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_MESSAGE_PRINTERNAME", spoolss_notify_printer_name },
{ PRINTER_MESSAGE_SHARENAME, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_MESSAGE_SHARENAME", spoolss_notify_share_name },
{ PRINTER_MESSAGE_PORT, PRINTER_NOTIFY_PORT_NAME, "PRINTER_MESSAGE_PORT", spoolss_notify_port_name },
{ PRINTER_MESSAGE_CJOBS, PRINTER_NOTIFY_CJOBS, "PRINTER_MESSAGE_CJOBS", spoolss_notify_cjobs },
{ PRINTER_MESSAGE_SEPFILE, PRINTER_NOTIFY_SEPFILE, "PRINTER_MESSAGE_SEPFILE", spoolss_notify_sepfile },
{ PRINTER_MESSAGE_PARAMS, PRINTER_NOTIFY_PARAMETERS, "PRINTER_MESSAGE_PARAMETERS", spoolss_notify_parameters },
{ PRINTER_MESSAGE_DATATYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_MESSAGE_DATATYPE", spoolss_notify_datatype },
{ PRINTER_MESSAGE_NULL, 0x0, "", NULL },
};
/*********************************************************
Disconnect from the client machine.
**********************************************************/
BOOL spoolss_disconnect_from_client( struct cli_state *cli)
{
cli_nt_session_close(cli);
cli_ulogoff(cli);
cli_shutdown(cli);
return True;
}
/*********************************************************
Connect to the client machine.
**********************************************************/
BOOL spoolss_connect_to_client( struct cli_state *cli, char *remote_machine)
{
ZERO_STRUCTP(cli);
if(cli_initialise(cli) == NULL) {
DEBUG(0,("connect_to_client: unable to initialize client connection.\n"));
return False;
}
if(!resolve_name( remote_machine, &cli->dest_ip, 0x20)) {
DEBUG(0,("connect_to_client: Can't resolve address for %s\n", remote_machine));
cli_shutdown(cli);
return False;
}
if (ismyip(cli->dest_ip)) {
DEBUG(0,("connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
cli_shutdown(cli);
return False;
}
if (!cli_connect(cli, remote_machine, &cli->dest_ip)) {
DEBUG(0,("connect_to_client: unable to connect to SMB server on machine %s. Error was : %s.\n", remote_machine, cli_errstr(cli) ));
cli_shutdown(cli);
return False;
}
if (!attempt_netbios_session_request(cli, global_myname, remote_machine, &cli->dest_ip)) {
DEBUG(0,("connect_to_client: machine %s rejected the NetBIOS session request.\n",
remote_machine));
return False;
}
cli->protocol = PROTOCOL_NT1;
if (!cli_negprot(cli)) {
DEBUG(0,("connect_to_client: machine %s rejected the negotiate protocol. Error was : %s.\n", remote_machine, cli_errstr(cli) ));
cli_shutdown(cli);
return False;
}
if (cli->protocol != PROTOCOL_NT1) {
DEBUG(0,("connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
cli_shutdown(cli);
return False;
}
/*
* Do an anonymous session setup.
*/
if (!cli_session_setup(cli, "", "", 0, "", 0, "")) {
DEBUG(0,("connect_to_client: machine %s rejected the session setup. Error was : %s.\n", remote_machine, cli_errstr(cli) ));
cli_shutdown(cli);
return False;
}
if (!(cli->sec_mode & 1)) {
DEBUG(0,("connect_to_client: machine %s isn't in user level security mode\n", remote_machine));
cli_shutdown(cli);
return False;
}
if (!cli_send_tconX(cli, "IPC$", "IPC", "", 1)) {
DEBUG(0,("connect_to_client: machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", remote_machine, cli_errstr(cli) ));
cli_shutdown(cli);
return False;
}
/*
* Ok - we have an anonymous connection to the IPC$ share.
* Now start the NT Domain stuff :-).
*/
if(cli_nt_session_open(cli, PIPE_SPOOLSS) == False) {
DEBUG(0,("connect_to_client: unable to open the domain client session to machine %s. Error was : %s.\n", remote_machine, cli_errstr(cli)));
cli_nt_session_close(cli);
cli_ulogoff(cli);
cli_shutdown(cli);
return False;
}
return True;
}
/* /*
* SPOOLSS Client RPC's used by servers as the notification * SPOOLSS Client RPC's used by servers as the notification
* back channel * back channel.
*/ */
/*************************************************************************** /* Send a ReplyOpenPrinter request. This rpc is made by the printer
do a reply open printer server to the printer client in response to a rffpcnex request.
****************************************************************************/ The rrfpcnex request names a printer and a handle (the printerlocal
value) and this rpc establishes a back-channel over which printer
notifications are performed. */
WERROR cli_spoolss_reply_open_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, WERROR cli_spoolss_reply_open_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
char *printer, uint32 localprinter, uint32 type, char *printer, uint32 printerlocal, uint32 type,
POLICY_HND *handle) POLICY_HND *handle)
{ {
prs_struct qbuf, rbuf;
SPOOL_Q_REPLYOPENPRINTER q;
SPOOL_R_REPLYOPENPRINTER r;
WERROR result = W_ERROR(ERRgeneral); WERROR result = W_ERROR(ERRgeneral);
prs_struct rbuf; /* Initialise input parameters */
prs_struct buf;
SPOOL_Q_REPLYOPENPRINTER q_s; prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
SPOOL_R_REPLYOPENPRINTER r_s; prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
prs_init(&buf, 1024, mem_ctx, MARSHALL); make_spoolss_q_replyopenprinter(&q, printer, printerlocal, type);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL );
/* create and send a MSRPC command with api SPOOLSS_REPLYOPENPRINTER */ /* Marshall data and send request */
if (!spoolss_io_q_replyopenprinter("", &q, &qbuf, 0) ||
!rpc_api_pipe_req (cli, SPOOLSS_REPLYOPENPRINTER, &qbuf, &rbuf))
goto done;
/* store the parameters */ /* Unmarshall response */
make_spoolss_q_replyopenprinter(&q_s, printer, localprinter, type);
/* turn parameters into data stream */
if(!spoolss_io_q_replyopenprinter("", &q_s, &buf, 0)) {
DEBUG(0,("cli_spoolss_reply_open_printer: Error : failed to marshall SPOOL_Q_REPLYOPENPRINTER struct.\n"));
goto done;
}
/* send the data on \PIPE\ */
if (!rpc_api_pipe_req(cli, SPOOLSS_REPLYOPENPRINTER, &buf, &rbuf))
goto done;
/* turn data stream into parameters*/
if(!spoolss_io_r_replyopenprinter("", &r_s, &rbuf, 0)) {
DEBUG(0,("cli_spoolss_reply_open_printer: Error : failed to unmarshall SPOOL_R_REPLYOPENPRINTER struct.\n"));
goto done;
}
memcpy(handle, &r_s.handle, sizeof(r_s.handle)); if (!spoolss_io_r_replyopenprinter("", &r, &rbuf, 0))
result = r_s.status; goto done;
/* Return result */
memcpy(handle, &r.handle, sizeof(r.handle));
result = r.status;
done: done:
prs_mem_free(&buf); prs_mem_free(&qbuf);
prs_mem_free(&rbuf); prs_mem_free(&rbuf);
return result; return result;
} }
/*************************************************************************** /* Close a back-channel notification connection */
do a reply open printer
****************************************************************************/
WERROR cli_spoolss_reply_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, WERROR cli_spoolss_reply_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *handle) POLICY_HND *handle)
{ {
prs_struct qbuf, rbuf;
SPOOL_Q_REPLYCLOSEPRINTER q;
SPOOL_R_REPLYCLOSEPRINTER r;
WERROR result = W_ERROR(ERRgeneral); WERROR result = W_ERROR(ERRgeneral);
prs_struct rbuf;
prs_struct buf;
SPOOL_Q_REPLYCLOSEPRINTER q_s; /* Initialise input parameters */
SPOOL_R_REPLYCLOSEPRINTER r_s;
prs_init(&buf, 1024, cli->mem_ctx, MARSHALL); prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL ); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
/* create and send a MSRPC command with api */ make_spoolss_q_reply_closeprinter(&q, handle);
/* Marshall data and send request */
if (!spoolss_io_q_replycloseprinter("", &q, &qbuf, 0) ||
!rpc_api_pipe_req (cli, SPOOLSS_REPLYCLOSEPRINTER, &qbuf, &rbuf))
goto done;
/* store the parameters */ /* Unmarshall response */
make_spoolss_q_reply_closeprinter(&q_s, handle);
/* turn parameters into data stream */
if(!spoolss_io_q_replycloseprinter("", &q_s, &buf, 0)) {
DEBUG(0,("cli_spoolss_reply_close_printer: Error : failed to marshall SPOOL_Q_REPLY_CLOSEPRINTER struct.\n"));
goto done;
}
/* send the data on \PIPE\ */
if (!rpc_api_pipe_req(cli, SPOOLSS_REPLYCLOSEPRINTER, &buf, &rbuf))
goto done;
/* turn data stream into parameters*/
if(!spoolss_io_r_replycloseprinter("", &r_s, &rbuf, 0)) {
DEBUG(0,("cli_spoolss_reply_close_printer: Error : failed to marshall SPOOL_R_REPLY_CLOSEPRINTER struct.\n"));
goto done;
}
if (!spoolss_io_r_replycloseprinter("", &r, &rbuf, 0))
goto done;
/* Return result */
result = r_s.status; result = r.status;
done: done:
prs_mem_free(&buf); prs_mem_free(&qbuf);
prs_mem_free(&rbuf); prs_mem_free(&rbuf);
return result; return result;
} }
/********************************************************************* /*********************************************************************
This SPOOLSS_ROUTERREPLYPRINTER function is used to send a change This SPOOLSS_ROUTERREPLYPRINTER function is used to send a change
notification event when the registration **did not** use notification event when the registration **did not** use
@ -262,186 +121,147 @@ done:
Also see cli_spolss_reply_rrpcn() Also see cli_spolss_reply_rrpcn()
*********************************************************************/ *********************************************************************/
WERROR cli_spoolss_routerreplyprinter (struct cli_state *cli, TALLOC_CTX *mem_ctx, WERROR cli_spoolss_routerreplyprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, uint32 condition, uint32 changd_id) POLICY_HND *pol, uint32 condition, uint32 change_id)
{ {
prs_struct qbuf, rbuf; prs_struct qbuf, rbuf;
SPOOL_Q_ROUTERREPLYPRINTER q; SPOOL_Q_ROUTERREPLYPRINTER q;
SPOOL_R_ROUTERREPLYPRINTER r; SPOOL_R_ROUTERREPLYPRINTER r;
WERROR result = W_ERROR(ERRgeneral); WERROR result = W_ERROR(ERRgeneral);
ZERO_STRUCT(q);
ZERO_STRUCT(r);
/* Initialise input parameters */ /* Initialise input parameters */
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
make_spoolss_q_routerreplyprinter(&q, pol, condition, change_id);
/* write the request */
make_spoolss_q_routerreplyprinter(&q, pol, condition, changd_id);
/* Marshall data and send request */ /* Marshall data and send request */
if (!spoolss_io_q_routerreplyprinter ("", &q, &qbuf, 0)) {
DEBUG(0,("cli_spoolss_routerreplyprinter: Unable to marshall SPOOL_Q_ROUTERREPLYPRINTER!\n"));
goto done;
}
if (!rpc_api_pipe_req (cli, SPOOLSS_ROUTERREPLYPRINTER, &qbuf, &rbuf))
goto done;
/* Unmarshall response */ if (!spoolss_io_q_routerreplyprinter("", &q, &qbuf, 0) ||
if (!spoolss_io_r_routerreplyprinter ("", &r, &rbuf, 0)) { !rpc_api_pipe_req (cli, SPOOLSS_ROUTERREPLYPRINTER, &qbuf, &rbuf))
DEBUG(0,("cli_spoolss_routerreplyprinter: Unable to unmarshall SPOOL_R_ROUTERREPLYPRINTER!\n")); goto done;
/* Unmarshall response */
if (!spoolss_io_r_routerreplyprinter("", &r, &rbuf, 0))
goto done; goto done;
}
/* Return output parameters */ /* Return output parameters */
result = r.status; result = r.status;
done: done:
prs_mem_free(&qbuf); prs_mem_free(&qbuf);
prs_mem_free(&rbuf); prs_mem_free(&rbuf);
return result; return result;
} }
/**********************************************************************************
Build the SPOOL_NOTIFY_INFO_DATA entries based upon the flags which have been set
*********************************************************************************/
static int build_notify_data (TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printer, uint32 flags,
SPOOL_NOTIFY_INFO_DATA **notify_data)
{
SPOOL_NOTIFY_INFO_DATA *data;
uint32 idx = 0;
int i = 0;
while ((msg_table[i].msg != PRINTER_MESSAGE_NULL) && flags)
{
if (flags & msg_table[i].msg)
{
DEBUG(10,("build_notify_data: %s set on [%s][%d]\n", msg_table[i].name,
printer->info_2->printername, idx));
if ((data=Realloc(*notify_data, (idx+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
DEBUG(0,("build_notify_data: Realloc() failed with size [%d]!\n",
(idx+1)*sizeof(SPOOL_NOTIFY_INFO_DATA)));
return -1;
}
*notify_data = data;
/* clear memory */
memset(*notify_data+idx, 0x0, sizeof(SPOOL_NOTIFY_INFO_DATA));
/*
* 'id' (last param here) is undefined when type == PRINTER_NOTIFY_TYPE
* See PRINTER_NOTIFY_INFO_DATA entries in MSDN
* --jerry
*/
construct_info_data(*notify_data+idx, PRINTER_NOTIFY_TYPE, msg_table[i].field, 0x00);
msg_table[i].construct_fn(-1, *notify_data+idx, NULL, printer, ctx);
idx++;
}
i++;
}
return idx;
}
/********************************************************************* /*********************************************************************
This SPOOLSS_ROUTERREPLYPRINTER function is used to send a change This SPOOLSS_REPLY_RRPCN function is used to send a change
notification event when the registration **did** use notification event when the registration **did** use
SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor
Also see cli_spoolss_routereplyprinter() Also see cli_spoolss_routereplyprinter()
*********************************************************************/ *********************************************************************/
WERROR cli_spoolss_reply_rrpcn(struct cli_state *cli, TALLOC_CTX *mem_ctx, WERROR cli_spoolss_rrpcn(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *handle, PRINTER_MESSAGE_INFO *info, POLICY_HND *pol, uint32 notify_data_len,
NT_PRINTER_INFO_LEVEL *printer) SPOOL_NOTIFY_INFO_DATA *notify_data,
uint32 change_low, uint32 change_high)
{ {
prs_struct rbuf; prs_struct qbuf, rbuf;
prs_struct buf; SPOOL_Q_REPLY_RRPCN q;
SPOOL_R_REPLY_RRPCN r;
SPOOL_NOTIFY_INFO notify_info;
SPOOL_NOTIFY_INFO_DATA *notify_data = NULL;
uint32 data_len;
WERROR result = W_ERROR(ERRgeneral); WERROR result = W_ERROR(ERRgeneral);
SPOOL_NOTIFY_INFO notify_info;
SPOOL_Q_REPLY_RRPCN q_s; ZERO_STRUCT(q);
SPOOL_R_REPLY_RRPCN r_s; ZERO_STRUCT(r);
if (!info) { /* Initialise parse structures */
DEBUG(5,("cli_spoolss_reply_rrpcn: NULL printer message info pointer!\n"));
goto done; prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
} prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
prs_init(&buf, 1024, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL );
ZERO_STRUCT(notify_info); ZERO_STRUCT(notify_info);
/* /* Initialise input parameters */
* See comments in _spoolss_setprinter() about PRINTER_CHANGE_XXX
* events. --jerry
*/
DEBUG(10,("cli_spoolss_reply_rrpcn: PRINTER_MESSAGE flags = 0x%8x\n", info->flags));
data_len = build_notify_data(mem_ctx, printer, info->flags, &notify_data);
if (info->flags && (data_len == -1)) {
DEBUG(0,("cli_spoolss_reply_rrpcn: Failed to build SPOOL_NOTIFY_INFO_DATA [flags == 0x%x] for printer [%s]\n",
info->flags, info->printer_name));
result = WERR_NOMEM;
goto done;
}
notify_info.version = 0x2; notify_info.version = 0x2;
notify_info.flags = 0x00020000; /* ?? */ notify_info.flags = 0x00020000; /* ?? */
notify_info.count = data_len; notify_info.count = notify_data_len;
notify_info.data = notify_data; notify_info.data = notify_data;
/* create and send a MSRPC command with api */ /* create and send a MSRPC command with api */
/* store the parameters */ /* store the parameters */
make_spoolss_q_reply_rrpcn(&q_s, handle, info->low, info->high, &notify_info); make_spoolss_q_reply_rrpcn(&q, pol, change_low, change_high,
&notify_info);
/* turn parameters into data stream */ /* Marshall data and send request */
if(!spoolss_io_q_reply_rrpcn("", &q_s, &buf, 0)) {
DEBUG(0,("cli_spoolss_reply_rrpcn: Error : failed to marshall SPOOL_Q_REPLY_RRPCN struct.\n"));
goto done;
}
/* send the data on \PIPE\ */ if(!spoolss_io_q_reply_rrpcn("", &q, &qbuf, 0) ||
if (!rpc_api_pipe_req(cli, SPOOLSS_RRPCN, &buf, &rbuf)) !rpc_api_pipe_req(cli, SPOOLSS_RRPCN, &qbuf, &rbuf))
goto done; goto done;
/* Unmarshall response */
/* turn data stream into parameters*/ if(!spoolss_io_r_reply_rrpcn("", &r, &rbuf, 0))
if(!spoolss_io_r_reply_rrpcn("", &r_s, &rbuf, 0)) {
DEBUG(0,("cli_spoolss_reply_rrpcn: Error : failed to unmarshall SPOOL_R_REPLY_RRPCN struct.\n"));
goto done; goto done;
}
if (r_s.unknown0 == 0x00080000) { if (r.unknown0 == 0x00080000)
DEBUG(8,("cli_spoolss_reply_rrpcn: I think the spooler resonded that the notification was ignored.\n")); DEBUG(8,("cli_spoolss_reply_rrpcn: I think the spooler resonded that the notification was ignored.\n"));
}
result = r_s.status; result = r.status;
done: done:
prs_mem_free(&buf); prs_mem_free(&qbuf);
prs_mem_free(&rbuf); prs_mem_free(&rbuf);
/*
* The memory allocated in this array is talloc'd so we only need
* free the array here. JRA.
*/
SAFE_FREE(notify_data);
return result; return result;
} }
WERROR cli_spoolss_rffpcnex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, uint32 flags, uint32 options,
char *localmachine, uint32 printerlocal,
SPOOL_NOTIFY_OPTION *option)
{
prs_struct qbuf, rbuf;
SPOOL_Q_RFFPCNEX q;
SPOOL_R_RFFPCNEX 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 */
make_spoolss_q_rffpcnex(
&q, pol, flags, options, localmachine, printerlocal,
option);
/* Marshall data and send request */
if(!spoolss_io_q_rffpcnex("", &q, &qbuf, 0) ||
!rpc_api_pipe_req(cli, SPOOLSS_RFFPCNEX, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
if(!spoolss_io_r_rffpcnex("", &r, &rbuf, 0))
goto done;
result = r.status;
done:
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
return result;
}

View File

@ -1,404 +1,445 @@
/* /*
* Unix SMB/CIFS implementation. Unix SMB/CIFS implementation.
* RPC Pipe client / server routines NT Domain Authentication SMB / MSRPC client
* Copyright (C) Andrew Tridgell 1992-1997, Copyright (C) Andrew Tridgell 1994-2000
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997, Copyright (C) Luke Kenneth Casson Leighton 1996-2000
* Copyright (C) Paul Ashton 1997. Copyright (C) Tim Potter 2001
* Copyright (C) Jeremy Allison 1999. Copyright (C) Jim McDonough 2002
*
* This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include "includes.h" #include "includes.h"
#undef DBGC_CLASS NTSTATUS cli_srvsvc_net_srv_get_info(struct cli_state *cli,
#define DBGC_CLASS DBGC_RPC_CLI TALLOC_CTX *mem_ctx,
uint32 switch_value, SRV_INFO_CTR *ctr)
/****************************************************************************
do a server net conn enum
****************************************************************************/
BOOL do_srv_net_srv_conn_enum(struct cli_state *cli,
char *server_name, char *qual_name,
uint32 switch_value, SRV_CONN_INFO_CTR *ctr,
uint32 preferred_len,
ENUM_HND *hnd)
{ {
prs_struct data; prs_struct qbuf, rbuf;
prs_struct rdata; SRV_Q_NET_SRV_GET_INFO q;
SRV_Q_NET_CONN_ENUM q_o; SRV_R_NET_SRV_GET_INFO r;
SRV_R_NET_CONN_ENUM r_o; NTSTATUS result;
if (server_name == NULL || ctr == NULL || preferred_len == 0) ZERO_STRUCT(q);
return False; ZERO_STRUCT(r);
prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); /* Initialise parse structures */
prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
/* create and send a MSRPC command with api SRV_NET_CONN_ENUM */ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
DEBUG(4,("SRV Net Server Connection Enum(%s, %s), level %d, enum:%8x\n", /* Initialise input parameters */
server_name, qual_name, switch_value, get_enum_hnd(hnd)));
ctr->switch_value = switch_value;
ctr->ptr_conn_ctr = 1;
ctr->conn.info0.num_entries_read = 0;
ctr->conn.info0.ptr_conn_info = 1;
/* store the parameters */ init_srv_q_net_srv_get_info(&q, cli->srv_name_slash, switch_value);
init_srv_q_net_conn_enum(&q_o, server_name, qual_name,
switch_value, ctr,
preferred_len,
hnd);
/* turn parameters into data stream */ /* Marshall data and send request */
if(!srv_io_q_net_conn_enum("", &q_o, &data, 0)) {
prs_mem_free(&data); if (!srv_io_q_net_srv_get_info("", &q, &qbuf, 0) ||
prs_mem_free(&rdata); !rpc_api_pipe_req(cli, SRV_NET_SRV_GET_INFO, &qbuf, &rbuf)) {
return False; result = NT_STATUS_UNSUCCESSFUL;
goto done;
} }
/* send the data on \PIPE\ */ /* Unmarshall response */
if(!rpc_api_pipe_req(cli, SRV_NET_CONN_ENUM, &data, &rdata)) {
prs_mem_free(&data); r.ctr = ctr;
prs_mem_free(&rdata);
return False; if (!srv_io_r_net_srv_get_info("", &r, &rbuf, 0)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
} }
prs_mem_free(&data); result = werror_to_ntstatus(r.status);
r_o.ctr = ctr; done:
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
if(!srv_io_r_net_conn_enum("", &r_o, &rdata, 0)) { return result;
prs_mem_free(&rdata);
return False;
}
if (r_o.status != 0) {
/* report error code */
DEBUG(0,("SRV_R_NET_SRV_CONN_ENUM: %s\n", nt_errstr(r_o.status)));
prs_mem_free(&rdata);
return False;
}
if (r_o.ctr->switch_value != switch_value) {
/* different switch levels. oops. */
DEBUG(0,("SRV_R_NET_SRV_CONN_ENUM: info class %d does not match request %d\n",
r_o.ctr->switch_value, switch_value));
prs_mem_free(&rdata);
return False;
}
prs_mem_free(&rdata);
return True;
} }
/**************************************************************************** WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
do a server net sess enum uint32 info_level, SRV_SHARE_INFO_CTR *ctr,
****************************************************************************/ int preferred_len, ENUM_HND *hnd)
BOOL do_srv_net_srv_sess_enum(struct cli_state *cli,
char *server_name, char *qual_name,
char *user_name,
uint32 switch_value, SRV_SESS_INFO_CTR *ctr,
uint32 preferred_len,
ENUM_HND *hnd)
{ {
prs_struct data; prs_struct qbuf, rbuf;
prs_struct rdata; SRV_Q_NET_SHARE_ENUM q;
SRV_Q_NET_SESS_ENUM q_o; SRV_R_NET_SHARE_ENUM r;
SRV_R_NET_SESS_ENUM r_o; WERROR result = W_ERROR(ERRgeneral);
int i;
if (server_name == NULL || ctr == NULL || preferred_len == 0) ZERO_STRUCT(q);
return False; ZERO_STRUCT(r);
prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); /* Initialise parse structures */
prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
/* create and send a MSRPC command with api SRV_NET_SESS_ENUM */ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
DEBUG(4,("SRV Net Session Enum (%s), level %d, enum:%8x\n", /* Initialise input parameters */
server_name, switch_value, get_enum_hnd(hnd)));
ctr->switch_value = switch_value;
ctr->ptr_sess_ctr = 1;
ctr->sess.info0.num_entries_read = 0;
ctr->sess.info0.ptr_sess_info = 1;
/* store the parameters */ init_srv_q_net_share_enum(
init_srv_q_net_sess_enum(&q_o, server_name, qual_name, user_name, &q, cli->srv_name_slash, info_level, preferred_len, hnd);
switch_value, ctr,
preferred_len,
hnd);
/* turn parameters into data stream */ /* Marshall data and send request */
if(!srv_io_q_net_sess_enum("", &q_o, &data, 0)) {
prs_mem_free(&data);
prs_mem_free(&rdata);
return False;
}
/* send the data on \PIPE\ */ if (!srv_io_q_net_share_enum("", &q, &qbuf, 0) ||
if (!rpc_api_pipe_req(cli, SRV_NET_SESS_ENUM, &data, &rdata)) { !rpc_api_pipe_req(cli, SRV_NET_SHARE_ENUM_ALL, &qbuf, &rbuf))
prs_mem_free(&data); goto done;
prs_mem_free(&rdata);
return False;
}
prs_mem_free(&data); /* Unmarshall response */
r_o.ctr = ctr; if (!srv_io_r_net_share_enum("", &r, &rbuf, 0))
goto done;
if(!srv_io_r_net_sess_enum("", &r_o, &rdata, 0)) { result = r.status;
prs_mem_free(&rdata);
return False; 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);
if (r_o.status != 0) { memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1));
/* report error code */
DEBUG(0,("SRV_R_NET_SRV_SESS_ENUM: %s\n", nt_errstr(r_o.status)));
prs_mem_free(&rdata);
return False;
}
if (r_o.ctr->switch_value != switch_value) { for (i = 0; i < ctr->num_entries; i++) {
/* different switch levels. oops. */ SRV_SHARE_INFO_1 *info1 = &ctr->share.info1[i];
DEBUG(0,("SRV_R_NET_SRV_SESS_ENUM: info class %d does not match request %d\n", char *s;
r_o.ctr->switch_value, switch_value));
prs_mem_free(&rdata); /* Copy pointer crap */
return False;
}
prs_mem_free(&rdata); memcpy(&info1->info_1, &r.ctr.share.info1[i].info_1,
sizeof(SH_INFO_1));
return True;
}
/**************************************************************************** /* Duplicate strings */
do a server net share enum
****************************************************************************/
BOOL do_srv_net_srv_share_enum(struct cli_state *cli,
char *server_name,
uint32 switch_value, SRV_R_NET_SHARE_ENUM *r_o,
uint32 preferred_len, ENUM_HND *hnd)
{
prs_struct data;
prs_struct rdata;
SRV_Q_NET_SHARE_ENUM q_o;
if (server_name == NULL || preferred_len == 0) s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_netname);
return False; if (s)
init_unistr2(&info1->info_1_str.uni_netname, s, strlen(s) + 1);
prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
/* create and send a MSRPC command with api SRV_NET_SHARE_ENUM */
DEBUG(4,("SRV Get Share Info (%s), level %d, enum:%8x\n",
server_name, switch_value, get_enum_hnd(hnd)));
/* store the parameters */
init_srv_q_net_share_enum(&q_o, server_name, switch_value,
preferred_len, hnd);
/* turn parameters into data stream */
if(!srv_io_q_net_share_enum("", &q_o, &data, 0)) {
prs_mem_free(&data);
prs_mem_free(&rdata);
return False;
}
/* send the data on \PIPE\ */
if (!rpc_api_pipe_req(cli, SRV_NET_SHARE_ENUM, &data, &rdata)) {
prs_mem_free(&data);
prs_mem_free(&rdata);
return False;
}
prs_mem_free(&data);
if(!srv_io_r_net_share_enum("", r_o, &rdata, 0)) {
prs_mem_free(&rdata);
return False;
}
if (r_o->status != 0) { s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_remark);
/* report error code */ if (s)
DEBUG(0,("SRV_R_NET_SHARE_ENUM: %s\n", nt_errstr(r_o->status))); init_unistr2(&info1->info_1_str.uni_remark, s, strlen(s) + 1);
prs_mem_free(&rdata);
return False;
}
if (r_o->ctr.switch_value != switch_value) { }
/* different switch levels. oops. */
DEBUG(0,("SRV_R_NET_SHARE_ENUM: info class %d does not match request %d\n",
r_o->ctr.switch_value, switch_value));
prs_mem_free(&rdata);
return False;
}
prs_mem_free(&rdata); break;
case 2:
return True; ctr->share.info2 = (SRV_SHARE_INFO_2 *)talloc(
} mem_ctx, sizeof(SRV_SHARE_INFO_2) * ctr->num_entries);
/****************************************************************************
do a server net file enum
****************************************************************************/
BOOL do_srv_net_srv_file_enum(struct cli_state *cli,
char *server_name, char *qual_name,
uint32 switch_value, SRV_FILE_INFO_CTR *ctr,
uint32 preferred_len,
ENUM_HND *hnd)
{
prs_struct data;
prs_struct rdata;
SRV_Q_NET_FILE_ENUM q_o;
SRV_R_NET_FILE_ENUM r_o;
if (server_name == NULL || ctr == NULL || preferred_len == 0)
return False;
prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
/* create and send a MSRPC command with api SRV_NET_FILE_ENUM */
DEBUG(4,("SRV Get File Info (%s), level %d, enum:%8x\n",
server_name, switch_value, get_enum_hnd(hnd)));
q_o.file_level = switch_value;
ctr->switch_value = switch_value;
ctr->ptr_file_ctr = 1;
ctr->file.info3.num_entries_read = 0;
ctr->file.info3.ptr_file_info = 1;
/* store the parameters */
init_srv_q_net_file_enum(&q_o, server_name, qual_name,
switch_value, ctr,
preferred_len,
hnd);
/* turn parameters into data stream */
if(!srv_io_q_net_file_enum("", &q_o, &data, 0)) {
prs_mem_free(&data);
prs_mem_free(&rdata);
return False;
}
/* send the data on \PIPE\ */
if (!rpc_api_pipe_req(cli, SRV_NET_FILE_ENUM, &data, &rdata)) {
prs_mem_free(&data);
prs_mem_free(&rdata);
return False;
}
prs_mem_free(&data);
r_o.ctr = ctr;
if(!srv_io_r_net_file_enum("", &r_o, &rdata, 0)) {
prs_mem_free(&rdata);
return False;
}
if (r_o.status != 0) { memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2));
/* report error code */
DEBUG(0,("SRV_R_NET_FILE_ENUM: %s\n", nt_errstr(r_o.status)));
prs_mem_free(&rdata);
return False;
}
if (r_o.ctr->switch_value != switch_value) { for (i = 0; i < ctr->num_entries; i++) {
/* different switch levels. oops. */ SRV_SHARE_INFO_2 *info2 = &ctr->share.info2[i];
DEBUG(0,("SRV_R_NET_FILE_ENUM: info class %d does not match request %d\n", char *s;
r_o.ctr->switch_value, switch_value));
prs_mem_free(&rdata); /* Copy pointer crap */
return False;
}
prs_mem_free(&rdata); memcpy(&info2->info_2, &r.ctr.share.info2[i].info_2,
sizeof(SH_INFO_2));
return True;
/* 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, strlen(s) + 1);
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, strlen(s) + 1);
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, strlen(s) + 1);
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, strlen(s) + 1);
}
break;
}
done:
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
return result;
} }
/**************************************************************************** WERROR cli_srvsvc_net_share_del(struct cli_state *cli, TALLOC_CTX *mem_ctx,
do a server get info const char *sharename)
****************************************************************************/
BOOL do_srv_net_srv_get_info(struct cli_state *cli,
char *server_name, uint32 switch_value, SRV_INFO_CTR *ctr)
{ {
prs_struct data; prs_struct qbuf, rbuf;
prs_struct rdata; SRV_Q_NET_SHARE_DEL q;
SRV_Q_NET_SRV_GET_INFO q_o; SRV_R_NET_SHARE_DEL r;
SRV_R_NET_SRV_GET_INFO r_o; WERROR result = W_ERROR(ERRgeneral);
if (server_name == NULL || switch_value == 0 || ctr == NULL) ZERO_STRUCT(q);
return False; ZERO_STRUCT(r);
prs_init(&data, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); /* Initialise parse structures */
prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
/* create and send a MSRPC command with api SRV_NET_SRV_GET_INFO */ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
DEBUG(4,("SRV Get Server Info (%s), level %d\n", server_name, switch_value)); /* Initialise input parameters */
/* store the parameters */ init_srv_q_net_share_del(&q, cli->srv_name_slash, sharename);
init_srv_q_net_srv_get_info(&q_o, server_name, switch_value);
/* turn parameters into data stream */ /* Marshall data and send request */
if(!srv_io_q_net_srv_get_info("", &q_o, &data, 0)) {
prs_mem_free(&data);
prs_mem_free(&rdata);
return False;
}
/* send the data on \PIPE\ */ if (!srv_io_q_net_share_del("", &q, &qbuf, 0) ||
if (!rpc_api_pipe_req(cli, SRV_NET_SRV_GET_INFO, &data, &rdata)) { !rpc_api_pipe_req(cli, SRV_NET_SHARE_DEL, &qbuf, &rbuf))
prs_mem_free(&data); goto done;
prs_mem_free(&rdata);
return False;
}
prs_mem_free(&data); /* Unmarshall response */
r_o.ctr = ctr; if (!srv_io_r_net_share_del("", &r, &rbuf, 0))
goto done;
if(!srv_io_r_net_srv_get_info("", &r_o, &rdata, 0)) { result = r.status;
prs_mem_free(&rdata);
return False;
}
if (r_o.status != 0) { done:
/* report error code */ prs_mem_free(&qbuf);
DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", nt_errstr(r_o.status))); prs_mem_free(&rbuf);
prs_mem_free(&rdata);
return False;
}
if (r_o.ctr->switch_value != q_o.switch_value) { return result;
/* different switch levels. oops. */ }
DEBUG(0,("SRV_R_NET_SRV_GET_INFO: info class %d does not match request %d\n",
r_o.ctr->switch_value, q_o.switch_value)); WERROR cli_srvsvc_net_share_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
prs_mem_free(&rdata); char *netname, uint32 type, char *remark,
return False; uint32 perms, uint32 max_uses, uint32 num_uses,
} char *path, char *passwd)
{
prs_mem_free(&rdata); prs_struct qbuf, rbuf;
SRV_Q_NET_SHARE_ADD q;
return True; 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;
}
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;
}
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, strlen(s) + 1);
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, strlen(s) + 1);
}
break;
}
done:
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
return result;
}
WERROR cli_srvsvc_net_file_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
uint32 file_id)
{
prs_struct qbuf, rbuf;
SRV_Q_NET_FILE_CLOSE q;
SRV_R_NET_FILE_CLOSE 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_file_close(&q, cli->srv_name_slash, file_id);
/* Marshall data and send request */
if (!srv_io_q_net_file_close("", &q, &qbuf, 0) ||
!rpc_api_pipe_req(cli, SRV_NET_FILE_CLOSE, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
if (!srv_io_r_net_file_close("", &r, &rbuf, 0))
goto done;
result = r.status;
done:
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
return result;
} }

View File

@ -1,87 +1,93 @@
/* /*
* Unix SMB/CIFS implementation. Unix SMB/CIFS implementation.
* RPC Pipe client / server routines NT Domain Authentication SMB / MSRPC client
* Copyright (C) Andrew Tridgell 1992-1997, Copyright (C) Andrew Tridgell 1994-2000
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997, Copyright (C) Luke Kenneth Casson Leighton 1996-2000
* Copyright (C) Paul Ashton 1997. Copyright (C) Tim Potter 2001
* Copyright (C) Jeremy Allison 1999. Copytight (C) Rafal Szczesniak 2002
*
* This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include "includes.h" #include "includes.h"
#undef DBGC_CLASS /**
#define DBGC_CLASS DBGC_RPC_CLI * WksQueryInfo rpc call (like query for server's capabilities)
*
/**************************************************************************** * @param initialised client structure with \PIPE\wkssvc opened
do a WKS Open Policy * @param mem_ctx memory context assigned to this rpc binding
****************************************************************************/ * @param wks100 WksQueryInfo structure
BOOL do_wks_query_info(struct cli_state *cli, *
char *server_name, uint32 switch_value, * @return NTSTATUS of rpc call
WKS_INFO_100 *wks100) */
NTSTATUS cli_wks_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
WKS_INFO_100 *wks100)
{ {
prs_struct buf;
prs_struct rbuf; prs_struct rbuf;
prs_struct buf;
WKS_Q_QUERY_INFO q_o; WKS_Q_QUERY_INFO q_o;
WKS_R_QUERY_INFO r_o; WKS_R_QUERY_INFO r_o;
if (server_name == 0 || wks100 == NULL) if (cli == NULL || wks100 == NULL)
return False; return NT_STATUS_UNSUCCESSFUL;
prs_init(&buf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); /* init rpc parse structures */
prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL ); prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
/* create and send a MSRPC command with api WKS_QUERY_INFO */ DEBUG(4, ("WksQueryInfo\n"));
DEBUG(4,("WKS Query Info\n")); /* init query structure with rpc call arguments */
init_wks_q_query_info(&q_o, cli->desthost, 100);
/* store the parameters */
init_wks_q_query_info(&q_o, server_name, switch_value); /* marshall data */
if (!wks_io_q_query_info("", &q_o, &buf, 0)) {
/* turn parameters into data stream */
if(!wks_io_q_query_info("", &q_o, &buf, 0)) {
prs_mem_free(&buf); prs_mem_free(&buf);
prs_mem_free(&rbuf); prs_mem_free(&rbuf);
return False; return NT_STATUS_UNSUCCESSFUL;
} }
/* send the data on \PIPE\ */ /* actual rpc call over \PIPE\wkssvc */
if (!rpc_api_pipe_req(cli, WKS_QUERY_INFO, &buf, &rbuf)) { if (!rpc_api_pipe_req(cli, WKS_QUERY_INFO, &buf, &rbuf)) {
prs_mem_free(&buf); prs_mem_free(&buf);
prs_mem_free(&rbuf); prs_mem_free(&rbuf);
return False; return NT_STATUS_UNSUCCESSFUL;
} }
prs_mem_free(&buf); prs_mem_free(&buf);
r_o.wks100 = wks100; r_o.wks100 = wks100;
if(!wks_io_r_query_info("", &r_o, &rbuf, 0)) { /* get call results from response buffer */
if (!wks_io_r_query_info("", &r_o, &rbuf, 0)) {
prs_mem_free(&rbuf); prs_mem_free(&rbuf);
return False; return NT_STATUS_UNSUCCESSFUL;
} }
if (r_o.status != 0) { /* check returnet status code */
/* report error code */ if (NT_STATUS_IS_ERR(r_o.status)) {
/* report the error */
DEBUG(0,("WKS_R_QUERY_INFO: %s\n", nt_errstr(r_o.status))); DEBUG(0,("WKS_R_QUERY_INFO: %s\n", nt_errstr(r_o.status)));
prs_mem_free(&rbuf); prs_mem_free(&rbuf);
return False; return r_o.status;
} }
/* do clean up */
prs_mem_free(&rbuf); prs_mem_free(&rbuf);
return True; return NT_STATUS_OK;
} }