X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source3%2Frpc_server%2Fspoolss%2Fsrv_spoolss_nt.c;h=c71eb911097f84292dd434ed73395943cd7e5f22;hb=89869e090c56a3f83b451b437f9c3f40a231dd24;hp=03c966b615e0e30328e23a9e30172f1ee150c097;hpb=002d1a44672c9b3247a68a86899ce6644b696a48;p=obnox%2Fsamba%2Fsamba-obnox.git diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c index 03c966b615e..c71eb911097 100644 --- a/source3/rpc_server/spoolss/srv_spoolss_nt.c +++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c @@ -138,6 +138,7 @@ struct notify_back_channel { /* print notify back-channel pipe handle*/ struct rpc_pipe_client *cli_pipe; + struct cli_state *cli; uint32_t active_connections; }; @@ -276,7 +277,7 @@ static void srv_spoolss_replycloseprinter(int snum, /* 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); @@ -374,7 +375,7 @@ static WERROR delete_printer_hook(TALLOC_CTX *ctx, struct security_token *token, const char *sharename, struct messaging_context *msg_ctx) { - char *cmd = lp_deleteprinter_cmd(talloc_tos()); + char *cmd = lp_deleteprinter_command(talloc_tos()); char *command = NULL; int ret; bool is_print_op = false; @@ -630,16 +631,17 @@ static WERROR set_printer_hnd_name(TALLOC_CTX *mem_ctx, 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 @@ -651,7 +653,7 @@ static WERROR set_printer_hnd_name(TALLOC_CTX *mem_ctx, 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; } @@ -844,14 +846,6 @@ static bool is_monitoring_event(struct printer_handle *p, uint16_t notify_type, #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, @@ -1513,6 +1507,7 @@ void srv_spoolss_cleanup(void) /********************************************************************** 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, @@ -1545,7 +1540,7 @@ 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; } @@ -1725,6 +1720,16 @@ WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p, 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 */ @@ -1732,7 +1737,7 @@ WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p, 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; @@ -1802,7 +1807,7 @@ WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p, 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; @@ -1886,7 +1891,7 @@ WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p, 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); @@ -1895,10 +1900,10 @@ WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p, 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); @@ -2439,11 +2444,10 @@ WERROR _spoolss_GetPrinterData(struct pipes_struct *p, 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]; @@ -2469,7 +2473,7 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, } /* 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 */ @@ -2482,9 +2486,9 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, return false; } - if ( smbXcli_conn_protocol(the_cli->conn) != 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; } @@ -2493,11 +2497,11 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, * 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; } @@ -2543,7 +2547,7 @@ static bool srv_spoolss_replyopenprinter(int snum, const char *printer, } 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; } @@ -2941,7 +2945,14 @@ static void spoolss_notify_security_desc(struct messaging_context *msg_ctx, 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); } /******************************************************************* @@ -3542,7 +3553,7 @@ static WERROR printserver_notify_info(struct pipes_struct *p, for (snum = 0; snum < n_services; snum++) { if (!lp_browseable(snum) || !lp_snum_ok(snum) || - !lp_print_ok(snum)) { + !lp_printable(snum)) { continue; /* skip */ } @@ -3611,6 +3622,7 @@ static WERROR printer_notify_info(struct pipes_struct *p, print_status_struct status; struct spoolss_PrinterInfo2 *pinfo2 = NULL; WERROR result; + struct tdb_print_db *pdb; DEBUG(4,("printer_notify_info\n")); @@ -3634,13 +3646,19 @@ static WERROR printer_notify_info(struct pipes_struct *p, 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(talloc_tos(), snum), &pinfo2); if (!W_ERROR_IS_OK(result)) { - return WERR_BADFID; + result = WERR_BADFID; + goto err_pdb_drop; } /* @@ -3649,10 +3667,11 @@ static WERROR printer_notify_info(struct pipes_struct *p, */ pinfo2->servername = talloc_strdup(pinfo2, Printer->servername); if (pinfo2->servername == NULL) { - return WERR_NOMEM; + result = WERR_NOMEM; + goto err_pdb_drop; } - for (i=0; icount; i++) { + for (i = 0; i < option->count; i++) { option_type = option->types[i]; switch (option_type.type) { @@ -3671,12 +3690,21 @@ static WERROR printer_notify_info(struct pipes_struct *p, count = print_queue_status(p->msg_ctx, snum, &queue, &status); - for (j=0; jmsg_ctx, &queue[j], info, pinfo2, snum, &option_type, - queue[j].sysjob, + jobid, mem_ctx); } @@ -3701,7 +3729,10 @@ static WERROR printer_notify_info(struct pipes_struct *p, */ talloc_free(pinfo2); - return WERR_OK; + result = WERR_OK; +err_pdb_drop: + release_print_db(pdb); + return result; } /**************************************************************** @@ -4055,7 +4086,10 @@ static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx, /* 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; @@ -4078,8 +4112,10 @@ static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx, /* 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; @@ -4263,15 +4299,6 @@ static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx, 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. ********************************************************************/ @@ -4286,7 +4313,7 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx, 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; @@ -4298,6 +4325,15 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx, 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; @@ -4866,7 +4902,8 @@ static WERROR string_array_from_driver_info(TALLOC_CTX *mem_ctx, 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) { @@ -5781,7 +5818,13 @@ WERROR _spoolss_StartDocPrinter(struct pipes_struct *p, */ 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; } @@ -6152,7 +6195,7 @@ static bool check_printer_ok(TALLOC_CTX *mem_ctx, static WERROR add_port_hook(TALLOC_CTX *ctx, struct security_token *token, const char *portname, const char *uri) { - char *cmd = lp_addport_cmd(talloc_tos()); + char *cmd = lp_addport_command(talloc_tos()); char *command = NULL; int ret; bool is_print_op = false; @@ -6213,7 +6256,7 @@ static bool add_printer_hook(TALLOC_CTX *ctx, struct security_token *token, const char *remote_machine, struct messaging_context *msg_ctx) { - char *cmd = lp_addprinter_cmd(talloc_tos()); + char *cmd = lp_addprinter_command(talloc_tos()); char **qlines; char *command = NULL; int numlines; @@ -6768,7 +6811,7 @@ static WERROR update_printer(struct pipes_struct *p, /* Call addprinter hook */ /* Check changes to see if this is really needed */ - if (*lp_addprinter_cmd(talloc_tos()) && + if (*lp_addprinter_command(talloc_tos()) && (!strequal(printer->drivername, old_printer->drivername) || !strequal(printer->comment, old_printer->comment) || !strequal(printer->portname, old_printer->portname) || @@ -7015,6 +7058,7 @@ fill_job_info1 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) { @@ -7022,7 +7066,7 @@ static WERROR fill_job_info1(TALLOC_CTX *mem_ctx, t = gmtime(&queue->time); - r->job_id = queue->sysjob; + r->job_id = jobid; r->printer_name = lp_servicename(mem_ctx, snum); W_ERROR_HAVE_NO_MEMORY(r->printer_name); @@ -7055,6 +7099,7 @@ fill_job_info2 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) @@ -7063,7 +7108,7 @@ static WERROR fill_job_info2(TALLOC_CTX *mem_ctx, t = gmtime(&queue->time); - r->job_id = queue->sysjob; + r->job_id = jobid; r->printer_name = lp_servicename(mem_ctx, snum); W_ERROR_HAVE_NO_MEMORY(r->printer_name); @@ -7105,27 +7150,6 @@ static WERROR fill_job_info2(TALLOC_CTX *mem_ctx, 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->sysjob; - r->next_job_id = 0; - if (next_queue) { - r->next_job_id = next_queue->sysjob; - } - r->reserved = 0; - - return WERR_OK; -} - /**************************************************************************** Enumjobs at level 1. ****************************************************************************/ @@ -7140,34 +7164,56 @@ static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx, 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; + } + + 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; } /**************************************************************************** @@ -7184,45 +7230,65 @@ static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx, 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; } /**************************************************************************** @@ -7239,41 +7305,51 @@ static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx, 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; } /**************************************************************** @@ -7296,6 +7372,11 @@ WERROR _spoolss_EnumJobs(struct pipes_struct *p, 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; @@ -7341,7 +7422,7 @@ WERROR _spoolss_EnumJobs(struct pipes_struct *p, pinfo2, r->out.info, r->out.count); break; default: - result = WERR_UNKNOWN_LEVEL; + SMB_ASSERT(false); /* level checked on entry */ break; } @@ -7842,7 +7923,7 @@ static WERROR fill_port_2(TALLOC_CTX *mem_ctx, static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines) { - char *cmd = lp_enumports_cmd(talloc_tos()); + char *cmd = lp_enumports_command(talloc_tos()); char **qlines = NULL; char *command = NULL; int numlines; @@ -8106,7 +8187,7 @@ static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p, /* FIXME!!! smbd should check to see if the driver is installed before trying to add a printer like this --jerry */ - if (*lp_addprinter_cmd(talloc_tos()) ) { + if (*lp_addprinter_command(talloc_tos()) ) { char *raddr; raddr = tsocket_address_inet_addr_string(p->remote_address, @@ -8132,10 +8213,10 @@ static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p, } /* 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; } @@ -9300,13 +9381,14 @@ static WERROR getjob_level_1(TALLOC_CTX *mem_ctx, 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; iin.buffer && (r->in.offered != 0)) { - return WERR_INVALID_PARAM; + result = WERR_INVALID_PARAM; + goto err_jinfo_free; } DEBUG(5,("_spoolss_GetJob\n")); @@ -9404,16 +9493,38 @@ WERROR _spoolss_GetJob(struct pipes_struct *p, *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); @@ -9425,12 +9536,14 @@ WERROR _spoolss_GetJob(struct pipes_struct *p, 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; @@ -9441,8 +9554,7 @@ WERROR _spoolss_GetJob(struct pipes_struct *p, 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, @@ -9450,6 +9562,12 @@ WERROR _spoolss_GetJob(struct pipes_struct *p, 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; } /****************************************************************