#include "printing/printer_list.h"
#include "../lib/tsocket/tsocket.h"
#include "rpc_client/cli_winreg_spoolss.h"
+#include "../libcli/smb/smbXcli_base.h"
/* macros stolen from s4 spoolss server */
#define SPOOLSS_BUFFER_UNION(fn,info,level) \
/* print notify back-channel pipe handle*/
struct rpc_pipe_client *cli_pipe;
+ struct cli_state *cli;
uint32_t active_connections;
};
/* if it's the last connection, deconnect the IPC$ share */
if (prn_hnd->notify.cli_chan->active_connections == 1) {
- cli_shutdown(rpc_pipe_np_smb_conn(prn_hnd->notify.cli_chan->cli_pipe));
+ cli_shutdown(prn_hnd->notify.cli_chan->cli);
DLIST_REMOVE(back_channels, prn_hnd->notify.cli_chan);
TALLOC_FREE(prn_hnd->notify.cli_chan);
const char *sharename,
struct messaging_context *msg_ctx)
{
- char *cmd = lp_deleteprinter_cmd();
+ char *cmd = lp_deleteprinter_command(talloc_tos());
char *command = NULL;
int ret;
bool is_print_op = false;
cache_key = talloc_asprintf(talloc_tos(), "PRINTERNAME/%s",
aprinter);
- if ((cache_key != NULL) && gencache_get(cache_key, &tmp, NULL)) {
+ if ((cache_key != NULL) &&
+ gencache_get(cache_key, talloc_tos(), &tmp, NULL)) {
found = (strcmp(tmp, printer_not_found) != 0);
if (!found) {
DEBUG(4, ("Printer %s not found\n", aprinter));
- SAFE_FREE(tmp);
+ TALLOC_FREE(tmp);
return WERR_INVALID_PRINTER_NAME;
}
fstrcpy(sname, tmp);
- SAFE_FREE(tmp);
+ TALLOC_FREE(tmp);
}
/* Search all sharenames first as this is easier than pulling
const char *printer = lp_const_servicename(snum);
/* no point going on if this is not a printer */
- if (!(lp_snum_ok(snum) && lp_print_ok(snum))) {
+ if (!(lp_snum_ok(snum) && lp_printable(snum))) {
continue;
}
#define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
_data->data.devmode.devmode = _devmode;
-#define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _sd) \
- _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
- if (!_data->data.sd.sd) { \
- _data->data.sd.sd_size = 0; \
- } \
- _data->data.sd.sd_size = \
- ndr_size_security_descriptor(_data->data.sd.sd, 0);
-
static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
struct tm *t,
const char **pp,
/**********************************************************************
callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
over all printers, upgrading ones as necessary
+ This is now *ONLY* called inside the background lpq updater. JRA.
**********************************************************************/
void do_drv_upgrade_printer(struct messaging_context *msg,
/* Iterate the printer list */
for (snum = 0; snum < n_services; snum++) {
- if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
+ if (!lp_snum_ok(snum) || !lp_printable(snum)) {
continue;
}
struct spoolss_OpenPrinter *r)
{
struct spoolss_OpenPrinterEx e;
+ struct spoolss_UserLevel1 level1;
WERROR werr;
- ZERO_STRUCT(e.in.userlevel);
+ ZERO_STRUCT(level1);
e.in.printername = r->in.printername;
e.in.datatype = r->in.datatype;
e.in.devmode_ctr = r->in.devmode_ctr;
e.in.access_mask = r->in.access_mask;
- e.in.level = 0;
+ e.in.userlevel_ctr.level = 1;
+ e.in.userlevel_ctr.user_info.level1 = &level1;
e.out.handle = r->out.handle;
return WERR_INVALID_PARAM;
}
- if (r->in.level > 3) {
+ if (r->in.userlevel_ctr.level > 3) {
return WERR_INVALID_PARAM;
}
- if ((r->in.level == 1 && !r->in.userlevel.level1) ||
- (r->in.level == 2 && !r->in.userlevel.level2) ||
- (r->in.level == 3 && !r->in.userlevel.level3)) {
+ if ((r->in.userlevel_ctr.level == 1 && !r->in.userlevel_ctr.user_info.level1) ||
+ (r->in.userlevel_ctr.level == 2 && !r->in.userlevel_ctr.user_info.level2) ||
+ (r->in.userlevel_ctr.level == 3 && !r->in.userlevel_ctr.user_info.level3)) {
return WERR_INVALID_PARAM;
}
+ /*
+ * The printcap printer share inventory is updated on client
+ * enumeration. For clients that do not perform enumeration prior to
+ * access, such as cupssmbadd, we reinitialise the printer share
+ * inventory on open as well.
+ */
+ become_root();
+ delete_and_reload_printers(server_event_context(), p->msg_ctx);
+ unbecome_root();
+
/* some sanity check because you can open a printer or a print server */
/* aka: \\server\printer or \\server */
result = open_printer_hnd(p, r->out.handle, r->in.printername, 0);
if (!W_ERROR_IS_OK(result)) {
- DEBUG(0,("_spoolss_OpenPrinterEx: Cannot open a printer handle "
+ DEBUG(3,("_spoolss_OpenPrinterEx: Cannot open a printer handle "
"for printer %s\n", r->in.printername));
ZERO_STRUCTP(r->out.handle);
return result;
if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
{
- if (!lp_ms_add_printer_wizard()) {
+ if (!lp_show_add_printer_wizard()) {
close_printer_handle(p, r->out.handle);
ZERO_STRUCTP(r->out.handle);
return WERR_ACCESS_DENIED;
if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
!security_token_has_privilege(p->session_info->security_token, SEC_PRIV_PRINT_OPERATOR) &&
- !nt_token_check_sid(&global_sid_Builtin_Print_Operators, p->session_info->security_token) &&
- !token_contains_name_in_list(
- uidtoname(p->session_info->unix_token->uid),
- p->session_info->info->domain_name,
- NULL,
- p->session_info->security_token,
- lp_printer_admin(snum))) {
+ !nt_token_check_sid(&global_sid_Builtin_Print_Operators,
+ p->session_info->security_token)) {
close_printer_handle(p, r->out.handle);
ZERO_STRUCTP(r->out.handle);
DEBUG(3,("access DENIED as user is not root, "
rhost = raddr;
}
- if (!allow_access(lp_hostsdeny(snum), lp_hostsallow(snum),
+ if (!allow_access(lp_hosts_deny(snum), lp_hosts_allow(snum),
rhost, raddr)) {
DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
ZERO_STRUCTP(r->out.handle);
if (!user_ok_token(uidtoname(p->session_info->unix_token->uid), NULL,
p->session_info->security_token, snum) ||
- !print_access_check(p->session_info,
- p->msg_ctx,
- snum,
- r->in.access_mask)) {
+ !W_ERROR_IS_OK(print_access_check(p->session_info,
+ p->msg_ctx,
+ snum,
+ r->in.access_mask))) {
DEBUG(3, ("access DENIED for printer open\n"));
close_printer_handle(p, r->out.handle);
ZERO_STRUCTP(r->out.handle);
* save it here in case we get a job submission on this handle
*/
- if ((Printer->printer_type != SPLHND_SERVER) &&
- r->in.devmode_ctr.devmode) {
+ if ((Printer->printer_type != SPLHND_SERVER)
+ && (r->in.devmode_ctr.devmode != NULL)) {
copy_devicemode(NULL, r->in.devmode_ctr.devmode,
&Printer->devmode);
}
-#if 0 /* JERRY -- I'm doubtful this is really effective */
- /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
- optimization in Windows 2000 clients --jerry */
-
- if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
- && (RA_WIN2K == get_remote_arch()) )
- {
- DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
- usleep( 500000 );
- }
-#endif
-
return WERR_OK;
}
/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
and not a printer admin, then fail */
- if ( (p->session_info->unix_token->uid != sec_initial_uid())
- && !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_PRINT_OPERATOR)
- && !token_contains_name_in_list(
- uidtoname(p->session_info->unix_token->uid),
- p->session_info->info->domain_name,
- NULL,
- p->session_info->security_token,
- lp_printer_admin(-1)) )
- {
+ if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
+ !security_token_has_privilege(p->session_info->security_token,
+ SEC_PRIV_PRINT_OPERATOR)) {
return WERR_ACCESS_DENIED;
}
* because the driver doesn not exist any more
*/
if (delete_files) {
- delete_driver_files(get_session_info_system(), info);
+ delete_driver_files(p->session_info, info);
}
done:
/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
and not a printer admin, then fail */
- if ( (p->session_info->unix_token->uid != sec_initial_uid())
- && !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_PRINT_OPERATOR)
- && !token_contains_name_in_list(
- uidtoname(p->session_info->unix_token->uid),
- p->session_info->info->domain_name,
- NULL,
- p->session_info->security_token, lp_printer_admin(-1)) )
- {
+ if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
+ !security_token_has_privilege(p->session_info->security_token,
+ SEC_PRIV_PRINT_OPERATOR)) {
return WERR_ACCESS_DENIED;
}
if (!strcasecmp_m(value, "W3SvcInstalled")) {
*type = REG_DWORD;
- data->value = 0x00;
+ SIVAL(&data->value, 0, 0x00);
return WERR_OK;
}
if (!strcasecmp_m(value, "BeepEnabled")) {
*type = REG_DWORD;
- data->value = 0x00;
+ SIVAL(&data->value, 0, 0x00);
return WERR_OK;
}
if (!strcasecmp_m(value, "EventLog")) {
*type = REG_DWORD;
/* formally was 0x1b */
- data->value = 0x00;
+ SIVAL(&data->value, 0, 0x00);
return WERR_OK;
}
if (!strcasecmp_m(value, "NetPopup")) {
*type = REG_DWORD;
- data->value = 0x00;
+ SIVAL(&data->value, 0, 0x00);
return WERR_OK;
}
-- jerry */
if (RA_WINNT == get_remote_arch()) {
- data->value = 0x02;
+ SIVAL(&data->value, 0, 0x02);
} else {
- data->value = 0x03;
+ SIVAL(&data->value, 0, 0x03);
}
return WERR_OK;
if (!strcasecmp_m(value, "MinorVersion")) {
*type = REG_DWORD;
- data->value = 0x00;
+ SIVAL(&data->value, 0, 0x00);
return WERR_OK;
}
enum ndr_err_code ndr_err;
struct spoolss_OSVersion os;
- os.major = 5; /* Windows 2000 == 5.0 */
- os.minor = 0;
- os.build = 2195; /* build */
+ os.major = lp_parm_int(GLOBAL_SECTION_SNUM,
+ "spoolss", "os_major", 5);
+ /* Windows 2000 == 5.0 */
+ os.minor = lp_parm_int(GLOBAL_SECTION_SNUM,
+ "spoolss", "os_minor", 0);
+ os.build = lp_parm_int(GLOBAL_SECTION_SNUM,
+ "spoolss", "os_build", 2195);
os.extra_string = ""; /* leave extra string empty */
ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os,
return WERR_GENERAL_FAILURE;
}
+ if (DEBUGLEVEL >= 10) {
+ NDR_PRINT_DEBUG(spoolss_OSVersion, &os);
+ }
+
*type = REG_BINARY;
data->binary = blob;
member of a AD domain */
if (lp_security() == SEC_ADS) {
- data->value = 0x01;
+ SIVAL(&data->value, 0, 0x01);
} else {
- data->value = 0x00;
+ SIVAL(&data->value, 0, 0x00);
}
return WERR_OK;
}
Connect to the client machine.
**********************************************************/
-static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
- struct sockaddr_storage *client_ss, const char *remote_machine)
+static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, struct cli_state **pp_cli,
+ struct sockaddr_storage *client_ss, const char *remote_machine)
{
NTSTATUS ret;
- struct cli_state *the_cli;
struct sockaddr_storage rm_addr;
char addr[INET6_ADDRSTRLEN];
}
/* setup the connection */
- ret = cli_full_connection( &the_cli, lp_netbios_name(), remote_machine,
+ ret = cli_full_connection( pp_cli, lp_netbios_name(), remote_machine,
&rm_addr, 0, "IPC$", "IPC",
"", /* username */
"", /* domain */
return false;
}
- if ( cli_state_protocol(the_cli) != PROTOCOL_NT1 ) {
+ if ( smbXcli_conn_protocol((*pp_cli)->conn) != PROTOCOL_NT1 ) {
DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
- cli_shutdown(the_cli);
+ cli_shutdown(*pp_cli);
return false;
}
* Now start the NT Domain stuff :-).
*/
- ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
+ ret = cli_rpc_pipe_open_noauth(*pp_cli, &ndr_table_spoolss, pp_pipe);
if (!NT_STATUS_IS_OK(ret)) {
DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
remote_machine, nt_errstr(ret)));
- cli_shutdown(the_cli);
+ cli_shutdown(*pp_cli);
return false;
}
}
chan->client_address = *client_ss;
- if (!spoolss_connect_to_client(&chan->cli_pipe, client_ss, unix_printer)) {
+ if (!spoolss_connect_to_client(&chan->cli_pipe, &chan->cli, client_ss, unix_printer)) {
TALLOC_FREE(chan);
return false;
}
struct spoolss_PrinterInfo2 *pinfo2,
TALLOC_CTX *mem_ctx)
{
- SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
+ SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(talloc_tos(), snum));
}
/*******************************************************************
const char *p;
if (*pinfo2->comment == '\0') {
- p = lp_comment(snum);
+ p = lp_comment(talloc_tos(), snum);
} else {
p = pinfo2->comment;
}
struct spoolss_PrinterInfo2 *pinfo2,
TALLOC_CTX *mem_ctx)
{
- SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data, pinfo2->secdesc);
+ if (pinfo2->secdesc == NULL) {
+ data->data.sd.sd = NULL;
+ } else {
+ data->data.sd.sd = security_descriptor_copy(mem_ctx,
+ pinfo2->secdesc);
+ }
+ data->data.sd.sd_size = ndr_size_security_descriptor(data->data.sd.sd,
+ 0);
}
/*******************************************************************
struct spoolss_PrinterInfo2 *pinfo2,
TALLOC_CTX *mem_ctx)
{
- SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
+ SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->sysjob);
}
/*******************************************************************
DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
(type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
- option_type->count, lp_servicename(snum)));
+ option_type->count, lp_servicename(talloc_tos(), snum)));
for(field_num=0; field_num < option_type->count; field_num++) {
field = option_type->fields[field_num].field;
for (snum = 0; snum < n_services; snum++) {
if (!lp_browseable(snum) ||
!lp_snum_ok(snum) ||
- !lp_print_ok(snum)) {
+ !lp_printable(snum)) {
continue; /* skip */
}
result = winreg_get_printer_internal(mem_ctx,
get_session_info_system(),
p->msg_ctx,
- lp_servicename(snum),
+ lp_servicename(talloc_tos(), snum),
&pinfo2);
if (!W_ERROR_IS_OK(result)) {
DEBUG(4, ("printserver_notify_info: "
"Failed to get printer [%s]\n",
- lp_servicename(snum)));
+ lp_servicename(talloc_tos(), snum)));
continue;
}
print_status_struct status;
struct spoolss_PrinterInfo2 *pinfo2 = NULL;
WERROR result;
+ struct tdb_print_db *pdb;
DEBUG(4,("printer_notify_info\n"));
return WERR_BADFID;
}
+ pdb = get_print_db_byname(Printer->sharename);
+ if (pdb == NULL) {
+ return WERR_BADFID;
+ }
+
/* Maybe we should use the SYSTEM session_info here... */
result = winreg_get_printer_internal(mem_ctx,
get_session_info_system(),
p->msg_ctx,
- lp_servicename(snum), &pinfo2);
+ lp_servicename(talloc_tos(), snum), &pinfo2);
if (!W_ERROR_IS_OK(result)) {
- return WERR_BADFID;
+ result = WERR_BADFID;
+ goto err_pdb_drop;
}
/*
*/
pinfo2->servername = talloc_strdup(pinfo2, Printer->servername);
if (pinfo2->servername == NULL) {
- return WERR_NOMEM;
+ result = WERR_NOMEM;
+ goto err_pdb_drop;
}
- for (i=0; i<option->count; i++) {
+ for (i = 0; i < option->count; i++) {
option_type = option->types[i];
switch (option_type.type) {
count = print_queue_status(p->msg_ctx, snum, &queue,
&status);
- for (j=0; j<count; j++) {
+ for (j = 0; j < count; j++) {
+ uint32_t jobid;
+ jobid = sysjob_to_jobid_pdb(pdb,
+ queue[j].sysjob);
+ if (jobid == (uint32_t)-1) {
+ DEBUG(2, ("ignoring untracked job %d\n",
+ queue[j].sysjob));
+ continue;
+ }
+ /* FIXME check return value */
construct_notify_jobs_info(p->msg_ctx,
&queue[j], info,
pinfo2, snum,
&option_type,
- queue[j].job,
+ jobid,
mem_ctx);
}
*/
talloc_free(pinfo2);
- return WERR_OK;
+ result = WERR_OK;
+err_pdb_drop:
+ release_print_db(pdb);
+ return result;
}
/****************************************************************
r->flags = flags;
if (info2->comment == NULL || info2->comment[0] == '\0') {
- r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
+ r->comment = lp_comment(mem_ctx, snum);
} else {
r->comment = talloc_strdup(mem_ctx, info2->comment); /* saved comment */
}
return result;
}
- r->sharename = talloc_strdup(mem_ctx, lp_servicename(snum));
+ r->sharename = lp_servicename(mem_ctx, snum);
W_ERROR_HAVE_NO_MEMORY(r->sharename);
r->portname = talloc_strdup(mem_ctx, info2->portname);
W_ERROR_HAVE_NO_MEMORY(r->portname);
W_ERROR_HAVE_NO_MEMORY(r->drivername);
if (info2->comment[0] == '\0') {
- r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
+ r->comment = lp_comment(mem_ctx, snum);
} else {
r->comment = talloc_strdup(mem_ctx, info2->comment);
}
r->cjobs = count;
r->averageppm = info2->averageppm;
- copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
- if (!r->devmode) {
+ if (info2->devmode != NULL) {
+ result = copy_devicemode(mem_ctx,
+ info2->devmode,
+ &r->devmode);
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
+ } else if (lp_default_devmode(snum)) {
+ result = spoolss_create_default_devmode(mem_ctx,
+ info2->printername,
+ &r->devmode);
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
+ } else {
+ r->devmode = NULL;
DEBUG(8,("Returning NULL Devicemode!\n"));
}
/* don't use talloc_steal() here unless you do a deep steal of all
the SEC_DESC members */
- r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
+ r->secdesc = security_descriptor_copy(mem_ctx, info2->secdesc);
+ if (r->secdesc == NULL) {
+ return WERR_NOMEM;
+ }
}
return WERR_OK;
/* don't use talloc_steal() here unless you do a deep steal of all
the SEC_DESC members */
- r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
- W_ERROR_HAVE_NO_MEMORY(r->secdesc);
+ r->secdesc = security_descriptor_copy(mem_ctx, info2->secdesc);
+ if (r->secdesc == NULL) {
+ return WERR_NOMEM;
+ }
}
return WERR_OK;
struct spoolss_PrinterInfo7 *r,
int snum)
{
- const struct auth_session_info *session_info = get_session_info_system();
- struct GUID guid;
+ const struct auth_session_info *session_info;
+ char *printer;
+ WERROR werr;
+ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+ if (tmp_ctx == NULL) {
+ return WERR_NOMEM;
+ }
+
+ session_info = get_session_info_system();
+ SMB_ASSERT(session_info != NULL);
+
+ printer = lp_servicename(tmp_ctx, snum);
+ if (printer == NULL) {
+ DEBUG(0, ("invalid printer snum %d\n", snum));
+ werr = WERR_INVALID_PARAM;
+ goto out_tmp_free;
+ }
- if (is_printer_published(mem_ctx, session_info, msg_ctx,
- servername,
- lp_servicename(snum), &guid, NULL)) {
+ if (is_printer_published(tmp_ctx, session_info, msg_ctx,
+ servername, printer, NULL)) {
+ struct GUID guid;
+ werr = nt_printer_guid_get(tmp_ctx, session_info, msg_ctx,
+ printer, &guid);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto out_tmp_free;
+ }
r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
r->action = DSPRINT_PUBLISH;
} else {
r->guid = talloc_strdup(mem_ctx, "");
r->action = DSPRINT_UNPUBLISH;
}
- W_ERROR_HAVE_NO_MEMORY(r->guid);
+ if (r->guid == NULL) {
+ werr = WERR_NOMEM;
+ goto out_tmp_free;
+ }
- return WERR_OK;
+ werr = WERR_OK;
+out_tmp_free:
+ talloc_free(tmp_ctx);
+ return werr;
}
/********************************************************************
return result;
}
- copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
- if (!r->devmode) {
+ if (info2->devmode != NULL) {
+ result = copy_devicemode(mem_ctx,
+ info2->devmode,
+ &r->devmode);
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
+ } else if (lp_default_devmode(snum)) {
+ result = spoolss_create_default_devmode(mem_ctx,
+ info2->printername,
+ &r->devmode);
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
+ } else {
+ r->devmode = NULL;
DEBUG(8,("Returning NULL Devicemode!\n"));
}
return WERR_OK;
}
-
-/********************************************************************
-********************************************************************/
-
-static bool snum_is_shared_printer(int snum)
-{
- return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
-}
-
/********************************************************************
Spoolss_enumprinters.
********************************************************************/
uint32_t *count_p)
{
int snum;
- int n_services = lp_numservices();
+ int n_services;
union spoolss_PrinterInfo *info = NULL;
uint32_t count = 0;
WERROR result = WERR_OK;
return WERR_NOMEM;
}
+ /*
+ * printer shares are updated on client enumeration. The background
+ * printer process updates printer_list.tdb at regular intervals.
+ */
+ become_root();
+ delete_and_reload_printers(server_event_context(), msg_ctx);
+ unbecome_root();
+
+ n_services = lp_numservices();
*count_p = 0;
*info_p = NULL;
DEBUG(4,("enum_all_printers_info_1_name\n"));
- if ((servername[0] == '\\') && (servername[1] == '\\')) {
+ if (servername != NULL &&
+ (servername[0] == '\\') && (servername[1] == '\\')) {
s = servername + 2;
}
listed. Windows responds to this call with a
WERR_CAN_NOT_COMPLETE so we should do the same. */
- if (servername[0] == '\\' && servername[1] == '\\') {
+ if (servername != NULL &&
+ (servername[0] == '\\') && (servername[1] == '\\')) {
s = servername + 2;
}
const char *arch,
int version)
{
- int i, num_strings = 0;
+ int i;
+ size_t num_strings = 0;
const char **array = NULL;
if (string_array == NULL) {
&array, &num_strings);
}
- if (presult) {
+ if (presult != NULL) {
*presult = array;
+ } else {
+ talloc_free(array);
}
return WERR_OK;
{
struct printer_handle *printer;
WERROR result;
+ uint32_t version = r->in.client_major_version;
int snum;
/* that's an [in out] buffer */
if (!r->in.buffer && (r->in.offered != 0)) {
- return WERR_INVALID_PARAM;
+ result = WERR_INVALID_PARAM;
+ goto err_info_free;
}
DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
- return WERR_INVALID_PRINTER_NAME;
+ result = WERR_INVALID_PRINTER_NAME;
+ goto err_info_free;
}
*r->out.needed = 0;
*r->out.server_minor_version = 0;
if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
- return WERR_BADFID;
+ result = WERR_BADFID;
+ goto err_info_free;
+ }
+
+ if (r->in.client_major_version == SPOOLSS_DRIVER_VERSION_2012) {
+ DEBUG(3,("_spoolss_GetPrinterDriver2: v4 driver requested, "
+ "downgrading to v3\n"));
+ version = SPOOLSS_DRIVER_VERSION_200X;
}
result = construct_printer_driver_info_level(p->mem_ctx,
r->in.level, r->out.info,
snum, printer->servername,
r->in.architecture,
- r->in.client_major_version);
+ version);
if (!W_ERROR_IS_OK(result)) {
- TALLOC_FREE(r->out.info);
- return result;
+ goto err_info_free;
}
*r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo,
r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
+
+err_info_free:
+ TALLOC_FREE(r->out.info);
+ return result;
}
return WERR_INVALID_HANDLE;
}
- if (r->in.level != 1) {
+ if (r->in.info_ctr->level != 1) {
return WERR_UNKNOWN_LEVEL;
}
- info_1 = r->in.info.info1;
+ info_1 = r->in.info_ctr->info.info1;
/*
* a nice thing with NT is it doesn't listen to what you tell it.
*/
if (info_1->datatype) {
- if (strcmp(info_1->datatype, "RAW") != 0) {
+ /*
+ * The v4 driver model used in Windows 8 declares print jobs
+ * intended to bypass the XPS processing layer by setting
+ * datatype to "XPS_PASS" instead of "RAW".
+ */
+ if ((strcmp(info_1->datatype, "RAW") != 0)
+ && (strcmp(info_1->datatype, "XPS_PASS") != 0)) {
*r->out.job_id = 0;
return WERR_INVALID_DATATYPE;
}
static WERROR add_port_hook(TALLOC_CTX *ctx, struct security_token *token, const char *portname, const char *uri)
{
- char *cmd = lp_addport_cmd();
+ char *cmd = lp_addport_command(talloc_tos());
char *command = NULL;
int ret;
bool is_print_op = false;
const char *remote_machine,
struct messaging_context *msg_ctx)
{
- char *cmd = lp_addprinter_cmd();
+ char *cmd = lp_addprinter_command(talloc_tos());
char **qlines;
char *command = NULL;
int numlines;
/* Call addprinter hook */
/* Check changes to see if this is really needed */
- if (*lp_addprinter_cmd() &&
+ if (*lp_addprinter_command(talloc_tos()) &&
(!strequal(printer->drivername, old_printer->drivername) ||
!strequal(printer->comment, old_printer->comment) ||
!strequal(printer->portname, old_printer->portname) ||
result = winreg_get_printer_internal(p->mem_ctx,
get_session_info_system(),
p->msg_ctx,
- lp_servicename(snum),
+ lp_servicename(talloc_tos(), snum),
&pinfo2);
if (!W_ERROR_IS_OK(result)) {
return WERR_BADFID;
static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
struct spoolss_JobInfo1 *r,
const print_queue_struct *queue,
+ uint32_t jobid,
int position, int snum,
struct spoolss_PrinterInfo2 *pinfo2)
{
t = gmtime(&queue->time);
- r->job_id = queue->job;
+ r->job_id = jobid;
- r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
+ r->printer_name = lp_servicename(mem_ctx, snum);
W_ERROR_HAVE_NO_MEMORY(r->printer_name);
r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
W_ERROR_HAVE_NO_MEMORY(r->server_name);
static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
struct spoolss_JobInfo2 *r,
const print_queue_struct *queue,
+ uint32_t jobid,
int position, int snum,
struct spoolss_PrinterInfo2 *pinfo2,
struct spoolss_DeviceMode *devmode)
t = gmtime(&queue->time);
- r->job_id = queue->job;
+ r->job_id = jobid;
- r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
+ r->printer_name = lp_servicename(mem_ctx, snum);
W_ERROR_HAVE_NO_MEMORY(r->printer_name);
r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
W_ERROR_HAVE_NO_MEMORY(r->server_name);
return WERR_OK;
}
-/****************************************************************************
-fill_job_info3
-****************************************************************************/
-
-static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
- struct spoolss_JobInfo3 *r,
- const print_queue_struct *queue,
- const print_queue_struct *next_queue,
- int position, int snum,
- struct spoolss_PrinterInfo2 *pinfo2)
-{
- r->job_id = queue->job;
- r->next_job_id = 0;
- if (next_queue) {
- r->next_job_id = next_queue->job;
- }
- r->reserved = 0;
-
- return WERR_OK;
-}
-
/****************************************************************************
Enumjobs at level 1.
****************************************************************************/
union spoolss_JobInfo *info;
int i;
WERROR result = WERR_OK;
+ uint32_t num_filled;
+ struct tdb_print_db *pdb;
info = talloc_array(mem_ctx, union spoolss_JobInfo, num_queues);
- W_ERROR_HAVE_NO_MEMORY(info);
+ if (info == NULL) {
+ result = WERR_NOMEM;
+ goto err_out;
+ }
+
+ pdb = get_print_db_byname(pinfo2->sharename);
+ if (pdb == NULL) {
+ result = WERR_INVALID_PARAM;
+ goto err_info_free;
+ }
- *count = num_queues;
+ num_filled = 0;
+ for (i = 0; i < num_queues; i++) {
+ uint32_t jobid = sysjob_to_jobid_pdb(pdb, queue[i].sysjob);
+ if (jobid == (uint32_t)-1) {
+ DEBUG(4, ("skipping sysjob %d\n", queue[i].sysjob));
+ continue;
+ }
- for (i=0; i<*count; i++) {
result = fill_job_info1(info,
- &info[i].info1,
+ &info[num_filled].info1,
&queue[i],
+ jobid,
i,
snum,
pinfo2);
if (!W_ERROR_IS_OK(result)) {
- goto out;
+ goto err_pdb_drop;
}
- }
- out:
- if (!W_ERROR_IS_OK(result)) {
- TALLOC_FREE(info);
- *count = 0;
- return result;
+ num_filled++;
}
+ release_print_db(pdb);
*info_p = info;
+ *count = num_filled;
return WERR_OK;
+
+err_pdb_drop:
+ release_print_db(pdb);
+err_info_free:
+ TALLOC_FREE(info);
+err_out:
+ *count = 0;
+ return result;
}
/****************************************************************************
union spoolss_JobInfo *info;
int i;
WERROR result = WERR_OK;
+ uint32_t num_filled;
+ struct tdb_print_db *pdb;
info = talloc_array(mem_ctx, union spoolss_JobInfo, num_queues);
- W_ERROR_HAVE_NO_MEMORY(info);
+ if (info == NULL) {
+ result = WERR_NOMEM;
+ goto err_out;
+ }
- *count = num_queues;
+ pdb = get_print_db_byname(pinfo2->sharename);
+ if (pdb == NULL) {
+ result = WERR_INVALID_PARAM;
+ goto err_info_free;
+ }
- for (i=0; i<*count; i++) {
+ num_filled = 0;
+ for (i = 0; i< num_queues; i++) {
struct spoolss_DeviceMode *devmode;
+ uint32_t jobid = sysjob_to_jobid_pdb(pdb, queue[i].sysjob);
+ if (jobid == (uint32_t)-1) {
+ DEBUG(4, ("skipping sysjob %d\n", queue[i].sysjob));
+ continue;
+ }
result = spoolss_create_default_devmode(info,
pinfo2->printername,
&devmode);
if (!W_ERROR_IS_OK(result)) {
DEBUG(3, ("Can't proceed w/o a devmode!"));
- goto out;
+ goto err_pdb_drop;
}
result = fill_job_info2(info,
- &info[i].info2,
+ &info[num_filled].info2,
&queue[i],
+ jobid,
i,
snum,
pinfo2,
devmode);
if (!W_ERROR_IS_OK(result)) {
- goto out;
+ goto err_pdb_drop;
}
+ num_filled++;
}
- out:
- if (!W_ERROR_IS_OK(result)) {
- TALLOC_FREE(info);
- *count = 0;
- return result;
- }
-
+ release_print_db(pdb);
*info_p = info;
+ *count = num_filled;
return WERR_OK;
+
+err_pdb_drop:
+ release_print_db(pdb);
+err_info_free:
+ TALLOC_FREE(info);
+err_out:
+ *count = 0;
+ return result;
}
/****************************************************************************
union spoolss_JobInfo *info;
int i;
WERROR result = WERR_OK;
+ uint32_t num_filled;
+ struct tdb_print_db *pdb;
info = talloc_array(mem_ctx, union spoolss_JobInfo, num_queues);
- W_ERROR_HAVE_NO_MEMORY(info);
-
- *count = num_queues;
+ if (info == NULL) {
+ result = WERR_NOMEM;
+ goto err_out;
+ }
- for (i=0; i<*count; i++) {
- const print_queue_struct *next_queue = NULL;
+ pdb = get_print_db_byname(pinfo2->sharename);
+ if (pdb == NULL) {
+ result = WERR_INVALID_PARAM;
+ goto err_info_free;
+ }
- if (i+1 < *count) {
- next_queue = &queue[i+1];
+ num_filled = 0;
+ for (i = 0; i < num_queues; i++) {
+ uint32_t jobid = sysjob_to_jobid_pdb(pdb, queue[i].sysjob);
+ if (jobid == (uint32_t)-1) {
+ DEBUG(4, ("skipping sysjob %d\n", queue[i].sysjob));
+ continue;
}
- result = fill_job_info3(info,
- &info[i].info3,
- &queue[i],
- next_queue,
- i,
- snum,
- pinfo2);
- if (!W_ERROR_IS_OK(result)) {
- goto out;
- }
- }
+ info[num_filled].info3.job_id = jobid;
+ /* next_job_id is overwritten on next iteration */
+ info[num_filled].info3.next_job_id = 0;
+ info[num_filled].info3.reserved = 0;
- out:
- if (!W_ERROR_IS_OK(result)) {
- TALLOC_FREE(info);
- *count = 0;
- return result;
+ if (num_filled > 0) {
+ info[num_filled - 1].info3.next_job_id = jobid;
+ }
+ num_filled++;
}
+ release_print_db(pdb);
*info_p = info;
+ *count = num_filled;
return WERR_OK;
+
+err_info_free:
+ TALLOC_FREE(info);
+err_out:
+ *count = 0;
+ return result;
}
/****************************************************************
return WERR_INVALID_PARAM;
}
+ if ((r->in.level != 1) && (r->in.level != 2) && (r->in.level != 3)) {
+ DEBUG(4, ("EnumJobs level %d not supported\n", r->in.level));
+ return WERR_UNKNOWN_LEVEL;
+ }
+
DEBUG(4,("_spoolss_EnumJobs\n"));
*r->out.needed = 0;
pinfo2, r->out.info, r->out.count);
break;
default:
- result = WERR_UNKNOWN_LEVEL;
+ SMB_ASSERT(false); /* level checked on entry */
break;
}
}
break;
case SPOOLSS_JOB_CONTROL_PAUSE:
- if (print_job_pause(session_info, p->msg_ctx,
- snum, r->in.job_id, &errcode)) {
- errcode = WERR_OK;
- }
+ errcode = print_job_pause(session_info, p->msg_ctx,
+ snum, r->in.job_id);
break;
case SPOOLSS_JOB_CONTROL_RESTART:
case SPOOLSS_JOB_CONTROL_RESUME:
- if (print_job_resume(session_info, p->msg_ctx,
- snum, r->in.job_id, &errcode)) {
- errcode = WERR_OK;
- }
+ errcode = print_job_resume(session_info, p->msg_ctx,
+ snum, r->in.job_id);
break;
case 0:
errcode = WERR_OK;
/* that's an [in out] buffer */
if (!r->in.buffer && (r->in.offered != 0)) {
+ TALLOC_FREE(r->out.info);
return WERR_INVALID_PARAM;
}
static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
{
- char *cmd = lp_enumports_cmd();
+ char *cmd = lp_enumports_command(talloc_tos());
char **qlines = NULL;
char *command = NULL;
int numlines;
/* FIXME!!! smbd should check to see if the driver is installed before
trying to add a printer like this --jerry */
- if (*lp_addprinter_cmd() ) {
+ if (*lp_addprinter_command(talloc_tos()) ) {
char *raddr;
raddr = tsocket_address_inet_addr_string(p->remote_address,
}
/* you must be a printer admin to add a new printer */
- if (!print_access_check(p->session_info,
- p->msg_ctx,
- snum,
- PRINTER_ACCESS_ADMINISTER)) {
+ if (!W_ERROR_IS_OK(print_access_check(p->session_info,
+ p->msg_ctx,
+ snum,
+ PRINTER_ACCESS_ADMINISTER))) {
return WERR_ACCESS_DENIED;
}
char **path)
{
const char *pservername = NULL;
- const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
+ const char *long_archi;
const char *short_archi;
*path = NULL;
/* environment may be empty */
if (environment && strlen(environment)) {
long_archi = environment;
+ } else {
+ long_archi = lp_parm_const_string(GLOBAL_SECTION_SNUM,
+ "spoolss", "architecture",
+ SPOOLSS_ARCHITECTURE_NT_X86);
}
/* servername may be empty */
/* that's an [in out] buffer */
if (!r->in.buffer && (r->in.offered != 0)) {
+ TALLOC_FREE(r->out.info);
return WERR_INVALID_PARAM;
}
WERROR _spoolss_AddForm(struct pipes_struct *p,
struct spoolss_AddForm *r)
{
- struct spoolss_AddFormInfo1 *form = r->in.info.info1;
+ struct spoolss_AddFormInfo1 *form;
int snum = -1;
WERROR status = WERR_OK;
struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
and not a printer admin, then fail */
if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
- !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_PRINT_OPERATOR) &&
- !token_contains_name_in_list(uidtoname(p->session_info->unix_token->uid),
- p->session_info->info->domain_name,
- NULL,
- p->session_info->security_token,
- lp_printer_admin(snum))) {
+ !security_token_has_privilege(p->session_info->security_token,
+ SEC_PRIV_PRINT_OPERATOR)) {
DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
return WERR_ACCESS_DENIED;
}
+ if (r->in.info_ctr->level != 1) {
+ return WERR_INVALID_LEVEL;
+ }
+
+ form = r->in.info_ctr->info.info1;
+ if (!form) {
+ return WERR_INVALID_PARAM;
+ }
+
switch (form->flags) {
case SPOOLSS_FORM_USER:
case SPOOLSS_FORM_BUILTIN:
}
if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
- !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_PRINT_OPERATOR) &&
- !token_contains_name_in_list(uidtoname(p->session_info->unix_token->uid),
- p->session_info->info->domain_name,
- NULL,
- p->session_info->security_token,
- lp_printer_admin(snum))) {
+ !security_token_has_privilege(p->session_info->security_token,
+ SEC_PRIV_PRINT_OPERATOR)) {
DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
return WERR_ACCESS_DENIED;
}
WERROR _spoolss_SetForm(struct pipes_struct *p,
struct spoolss_SetForm *r)
{
- struct spoolss_AddFormInfo1 *form = r->in.info.info1;
+ struct spoolss_AddFormInfo1 *form;
const char *form_name = r->in.form_name;
int snum = -1;
WERROR status = WERR_OK;
and not a printer admin, then fail */
if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
- !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_PRINT_OPERATOR) &&
- !token_contains_name_in_list(uidtoname(p->session_info->unix_token->uid),
- p->session_info->info->domain_name,
- NULL,
- p->session_info->security_token,
- lp_printer_admin(snum))) {
+ !security_token_has_privilege(p->session_info->security_token,
+ SEC_PRIV_PRINT_OPERATOR)) {
DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
return WERR_ACCESS_DENIED;
}
+ if (r->in.info_ctr->level != 1) {
+ return WERR_INVALID_LEVEL;
+ }
+
+ form = r->in.info_ctr->info.info1;
+ if (!form) {
+ return WERR_INVALID_PARAM;
+ }
+
tmp_ctx = talloc_new(p->mem_ctx);
if (!tmp_ctx) {
return WERR_NOMEM;
int count, int snum,
struct spoolss_PrinterInfo2 *pinfo2,
uint32_t jobid,
+ int sysjob,
struct spoolss_JobInfo1 *r)
{
int i = 0;
bool found = false;
for (i=0; i<count; i++) {
- if (queue[i].job == (int)jobid) {
+ if (queue[i].sysjob == sysjob) {
found = true;
break;
}
return fill_job_info1(mem_ctx,
r,
&queue[i],
+ jobid,
i,
snum,
pinfo2);
int count, int snum,
struct spoolss_PrinterInfo2 *pinfo2,
uint32_t jobid,
+ int sysjob,
struct spoolss_JobInfo2 *r)
{
int i = 0;
WERROR result;
for (i=0; i<count; i++) {
- if (queue[i].job == (int)jobid) {
+ if (queue[i].sysjob == sysjob) {
found = true;
break;
}
* a failure condition
*/
- devmode = print_job_devmode(lp_const_servicename(snum), jobid);
+ devmode = print_job_devmode(mem_ctx, lp_const_servicename(snum), jobid);
if (!devmode) {
result = spoolss_create_default_devmode(mem_ctx,
pinfo2->printername,
return fill_job_info2(mem_ctx,
r,
&queue[i],
+ jobid,
i,
snum,
pinfo2,
{
WERROR result = WERR_OK;
struct spoolss_PrinterInfo2 *pinfo2 = NULL;
+ const char *svc_name;
+ int sysjob;
int snum;
int count;
+ struct tdb_print_db *pdb;
print_queue_struct *queue = NULL;
print_status_struct prt_status;
/* that's an [in out] buffer */
if (!r->in.buffer && (r->in.offered != 0)) {
- return WERR_INVALID_PARAM;
+ result = WERR_INVALID_PARAM;
+ goto err_jinfo_free;
}
DEBUG(5,("_spoolss_GetJob\n"));
*r->out.needed = 0;
if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
- return WERR_BADFID;
+ result = WERR_BADFID;
+ goto err_jinfo_free;
+ }
+
+ svc_name = lp_const_servicename(snum);
+ if (svc_name == NULL) {
+ result = WERR_INVALID_PARAM;
+ goto err_jinfo_free;
}
result = winreg_get_printer_internal(p->mem_ctx,
get_session_info_system(),
p->msg_ctx,
- lp_const_servicename(snum),
+ svc_name,
&pinfo2);
if (!W_ERROR_IS_OK(result)) {
- return result;
+ goto err_jinfo_free;
+ }
+
+ pdb = get_print_db_byname(svc_name);
+ if (pdb == NULL) {
+ DEBUG(3, ("failed to get print db for svc %s\n", svc_name));
+ result = WERR_INVALID_PARAM;
+ goto err_pinfo_free;
+ }
+
+ sysjob = jobid_to_sysjob_pdb(pdb, r->in.job_id);
+ release_print_db(pdb);
+ if (sysjob == -1) {
+ DEBUG(3, ("no sysjob for spoolss jobid %u\n", r->in.job_id));
+ result = WERR_INVALID_PARAM;
+ goto err_pinfo_free;
}
count = print_queue_status(p->msg_ctx, snum, &queue, &prt_status);
case 1:
result = getjob_level_1(p->mem_ctx,
queue, count, snum, pinfo2,
- r->in.job_id, &r->out.info->info1);
+ r->in.job_id, sysjob,
+ &r->out.info->info1);
break;
case 2:
result = getjob_level_2(p->mem_ctx,
queue, count, snum, pinfo2,
- r->in.job_id, &r->out.info->info2);
+ r->in.job_id, sysjob,
+ &r->out.info->info2);
break;
default:
result = WERR_UNKNOWN_LEVEL;
TALLOC_FREE(pinfo2);
if (!W_ERROR_IS_OK(result)) {
- TALLOC_FREE(r->out.info);
- return result;
+ goto err_jinfo_free;
}
*r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
+
+err_pinfo_free:
+ TALLOC_FREE(pinfo2);
+err_jinfo_free:
+ TALLOC_FREE(r->out.info);
+ return result;
}
/****************************************************************
}
result = winreg_get_printer(tmp_ctx, b,
- lp_servicename(snum),
+ lp_servicename(talloc_tos(), snum),
&pinfo2);
if (!W_ERROR_IS_OK(result)) {
goto done;
/* that's an [in out] buffer */
if (!r->in.buffer && (r->in.offered != 0)) {
- return WERR_INVALID_PARAM;
+ result = WERR_INVALID_PARAM;
+ goto err_info_free;
}
DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
snum = find_service(talloc_tos(), "prnproc$", &prnproc_share);
if (!prnproc_share) {
- return WERR_NOMEM;
+ result = WERR_NOMEM;
+ goto err_info_free;
}
if (snum != -1) {
prnproc_share_exists = true;
r->in.environment,
&r->out.info->info1);
if (!W_ERROR_IS_OK(result)) {
- TALLOC_FREE(r->out.info);
- return result;
+ goto err_info_free;
}
*r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
+
+err_info_free:
+ TALLOC_FREE(r->out.info);
+ return result;
}
/*******************************************************************
WERROR _spoolss_GetPrinterDriver(struct pipes_struct *p,
struct spoolss_GetPrinterDriver *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_ReadPrinter(struct pipes_struct *p,
struct spoolss_ReadPrinter *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_WaitForPrinterChange(struct pipes_struct *p,
struct spoolss_WaitForPrinterChange *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_ConfigurePort(struct pipes_struct *p,
struct spoolss_ConfigurePort *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_DeletePort(struct pipes_struct *p,
struct spoolss_DeletePort *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_CreatePrinterIC(struct pipes_struct *p,
struct spoolss_CreatePrinterIC *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct *p,
struct spoolss_PlayGDIScriptOnPrinterIC *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_DeletePrinterIC(struct pipes_struct *p,
struct spoolss_DeletePrinterIC *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_AddPrinterConnection(struct pipes_struct *p,
struct spoolss_AddPrinterConnection *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_DeletePrinterConnection(struct pipes_struct *p,
struct spoolss_DeletePrinterConnection *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_PrinterMessageBox(struct pipes_struct *p,
struct spoolss_PrinterMessageBox *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_AddMonitor(struct pipes_struct *p,
struct spoolss_AddMonitor *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_DeleteMonitor(struct pipes_struct *p,
struct spoolss_DeleteMonitor *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_DeletePrintProcessor(struct pipes_struct *p,
struct spoolss_DeletePrintProcessor *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_AddPrintProvidor(struct pipes_struct *p,
struct spoolss_AddPrintProvidor *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_DeletePrintProvidor(struct pipes_struct *p,
struct spoolss_DeletePrintProvidor *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_FindFirstPrinterChangeNotification(struct pipes_struct *p,
struct spoolss_FindFirstPrinterChangeNotification *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_FindNextPrinterChangeNotification(struct pipes_struct *p,
struct spoolss_FindNextPrinterChangeNotification *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct *p,
struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_ReplyOpenPrinter(struct pipes_struct *p,
struct spoolss_ReplyOpenPrinter *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_RouterReplyPrinter(struct pipes_struct *p,
struct spoolss_RouterReplyPrinter *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_ReplyClosePrinter(struct pipes_struct *p,
struct spoolss_ReplyClosePrinter *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_AddPortEx(struct pipes_struct *p,
struct spoolss_AddPortEx *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct *p,
struct spoolss_RouterFindFirstPrinterChangeNotification *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_SpoolerInit(struct pipes_struct *p,
struct spoolss_SpoolerInit *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_ResetPrinterEx(struct pipes_struct *p,
struct spoolss_ResetPrinterEx *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_RouterReplyPrinterEx(struct pipes_struct *p,
struct spoolss_RouterReplyPrinterEx *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_44(struct pipes_struct *p,
struct spoolss_44 *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_SetPort(struct pipes_struct *p,
struct spoolss_SetPort *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_4a(struct pipes_struct *p,
struct spoolss_4a *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_4b(struct pipes_struct *p,
struct spoolss_4b *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_4c(struct pipes_struct *p,
struct spoolss_4c *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_53(struct pipes_struct *p,
struct spoolss_53 *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_AddPerMachineConnection(struct pipes_struct *p,
struct spoolss_AddPerMachineConnection *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_DeletePerMachineConnection(struct pipes_struct *p,
struct spoolss_DeletePerMachineConnection *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_EnumPerMachineConnections(struct pipes_struct *p,
struct spoolss_EnumPerMachineConnections *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_5a(struct pipes_struct *p,
struct spoolss_5a *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_5b(struct pipes_struct *p,
struct spoolss_5b *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_5c(struct pipes_struct *p,
struct spoolss_5c *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_5d(struct pipes_struct *p,
struct spoolss_5d *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_5e(struct pipes_struct *p,
struct spoolss_5e *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_5f(struct pipes_struct *p,
struct spoolss_5f *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_60(struct pipes_struct *p,
struct spoolss_60 *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
/****************************************************************
- _spoolss_61
+ _spoolss_RpcSendRecvBidiData
****************************************************************/
-WERROR _spoolss_61(struct pipes_struct *p,
- struct spoolss_61 *r)
+WERROR _spoolss_RpcSendRecvBidiData(struct pipes_struct *p,
+ struct spoolss_RpcSendRecvBidiData *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_62(struct pipes_struct *p,
struct spoolss_62 *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_63(struct pipes_struct *p,
struct spoolss_63 *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_64(struct pipes_struct *p,
struct spoolss_64 *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_65(struct pipes_struct *p,
struct spoolss_65 *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_GetCorePrinterDrivers(struct pipes_struct *p,
struct spoolss_GetCorePrinterDrivers *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_67(struct pipes_struct *p,
struct spoolss_67 *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_GetPrinterDriverPackagePath(struct pipes_struct *p,
struct spoolss_GetPrinterDriverPackagePath *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_69(struct pipes_struct *p,
struct spoolss_69 *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_6a(struct pipes_struct *p,
struct spoolss_6a *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_6b(struct pipes_struct *p,
struct spoolss_6b *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_6c(struct pipes_struct *p,
struct spoolss_6c *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}
WERROR _spoolss_6d(struct pipes_struct *p,
struct spoolss_6d *r)
{
- p->rng_fault_state = true;
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ return WERR_NOT_SUPPORTED;
+}
+
+/****************************************************************
+ _spoolss_RpcGetJobNamedPropertyValue
+****************************************************************/
+
+WERROR _spoolss_RpcGetJobNamedPropertyValue(struct pipes_struct *p,
+ struct spoolss_RpcGetJobNamedPropertyValue *r)
+{
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ return WERR_NOT_SUPPORTED;
+}
+
+/****************************************************************
+ _spoolss_RpcSetJobNamedProperty
+****************************************************************/
+
+WERROR _spoolss_RpcSetJobNamedProperty(struct pipes_struct *p,
+ struct spoolss_RpcSetJobNamedProperty *r)
+{
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ return WERR_NOT_SUPPORTED;
+}
+
+/****************************************************************
+ _spoolss_RpcDeleteJobNamedProperty
+****************************************************************/
+
+WERROR _spoolss_RpcDeleteJobNamedProperty(struct pipes_struct *p,
+ struct spoolss_RpcDeleteJobNamedProperty *r)
+{
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ return WERR_NOT_SUPPORTED;
+}
+
+/****************************************************************
+ _spoolss_RpcEnumJobNamedProperties
+****************************************************************/
+
+WERROR _spoolss_RpcEnumJobNamedProperties(struct pipes_struct *p,
+ struct spoolss_RpcEnumJobNamedProperties *r)
+{
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
return WERR_NOT_SUPPORTED;
}