* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
#include "includes.h"
extern int DEBUGLEVEL;
return False;
}
+ if (*lp_deleteprinter_cmd()) {
+
+ pid_t local_pid = sys_getpid();
+ char *cmd = lp_deleteprinter_cmd();
+ char *path;
+ pstring tmp_file;
+ pstring command;
+ int ret;
+ int i;
+
+ if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
+ path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
+ else
+ path = tmpdir();
+
+ /* Printer->dev.handlename equals portname equals sharename */
+ slprintf(command, sizeof(command), "%s \"%s\"", cmd,
+ Printer->dev.handlename);
+ slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
+
+ unlink(tmp_file);
+ DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
+ ret = smbrun(command, tmp_file, False);
+ if (ret != 0) {
+ unlink(tmp_file);
+ return False;
+ }
+ DEBUGADD(10,("returned [%d]\n", ret));
+ DEBUGADD(10,("Unlinking output file [%s]\n", tmp_file));
+ unlink(tmp_file);
+
+ if ( ( i = lp_servicenumber( Printer->dev.handlename ) ) >= 0 ) {
+ lp_remove_service( i );
+ lp_killservice( i );
+ return True;
+ } else
+ return False;
+ }
+
return True;
}
init_unistr(&printer->servername, chaine); /* servername*/
init_unistr(&printer->printername, chaine2); /* printername*/
init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
-#if 1 /* JRATEST */
- /* We need to determine the correct model for this..... */
- init_unistr(&printer->portname, lp_printername(snum)); /* port */
-#else
- init_unistr(&printer->portname, lp_servicename(snum)); /* port */
-#endif
+ init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */
init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
if (*ntprinter->info_2->comment == '\0')
if((printer->devmode = construct_dev_mode(snum, servername)) == NULL) {
DEBUG(8, ("Returning NULL Devicemode!\n"));
-#if 0 /* JFMTEST */
- goto err;
-#endif
}
if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
free_a_printer(&ntprinter, 2);
safe_free(queue);
return True;
-
- err:
-
- if (ntprinter)
- free_a_printer(&ntprinter, 2);
- safe_free(queue);
- return False;
}
/********************************************************************
* server-side code. *nnnnnggggh!*
*/
- if (info_1->p_datatype != 0)
- {
- unistr2_to_ascii(datatype, &(info_1->docname), sizeof(datatype));
- if (strcmp(datatype, "RAW") != 0)
- {
+ if (info_1->p_datatype != 0) {
+ unistr2_to_ascii(datatype, &info_1->docname, sizeof(datatype));
+ if (strcmp(datatype, "RAW") != 0) {
(*jobid)=0;
return ERROR_INVALID_DATATYPE;
}
}
/* get the share number of the printer */
- if (!get_printer_snum(handle, &snum))
- {
+ if (!get_printer_snum(handle, &snum)) {
return ERROR_INVALID_HANDLE;
}
Printer->jobid = print_job_start(&user, snum, jobname);
- /* need to map error codes properly - for now give out of
- memory as I don't know the correct codes (tridge) */
+ /* An error occured in print_job_start() so return an appropriate
+ NT error code. */
+
if (Printer->jobid == -1) {
- return ERROR_NOT_ENOUGH_MEMORY;
+ return map_nt_error_from_unix(errno);
}
Printer->document_started=True;
{
struct current_user user;
int snum;
+ int errcode = 0;
Printer_entry *Printer = find_printer_index_by_hnd(handle);
if (p->ntlmssp_auth_validated) {
switch (command) {
case PRINTER_CONTROL_PAUSE:
- if (print_queue_pause(&user, snum)) {
+ if (print_queue_pause(&user, snum, &errcode)) {
return 0;
}
break;
case PRINTER_CONTROL_RESUME:
case PRINTER_CONTROL_UNPAUSE:
- if (print_queue_resume(&user, snum)) {
+ if (print_queue_resume(&user, snum, &errcode)) {
return 0;
}
break;
case PRINTER_CONTROL_PURGE:
- if (print_queue_purge(&user, snum)) {
+ if (print_queue_purge(&user, snum, &errcode)) {
return 0;
}
break;
}
+ if (errcode)
+ return (uint32)errcode;
+
return ERROR_INVALID_FUNCTION;
}
+/********************************************************************
+ * api_spoolss_abortprinter
+ ********************************************************************/
+
+uint32 _spoolss_abortprinter(POLICY_HND *handle, pipes_struct *p)
+{
+ return control_printer(handle, PRINTER_CONTROL_PURGE, p);
+}
+
/********************************************************************
* called by spoolss_api_setprinter
* when updating a printer description
const SPOOL_PRINTER_INFO_LEVEL *info,
pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
{
- SEC_DESC_BUF *old_secdesc_ctr = NULL;
struct current_user user;
- uint32 acc_granted, status, result;
+ uint32 result;
+ int snum;
Printer_entry *Printer = find_printer_index_by_hnd(handle);
- if (!OPEN_HANDLE(Printer)) {
+ if (!OPEN_HANDLE(Printer) || !get_printer_snum(handle, &snum)) {
DEBUG(0,("update_printer_sec: Invalid handle (%s)\n", OUR_HANDLE(handle)));
return ERROR_INVALID_HANDLE;
}
/* Work out which user is performing the operation */
-
if (p->ntlmssp_auth_validated) {
memcpy(&user, &p->pipe_user, sizeof(user));
} else {
memcpy(&user, ¤t_user, sizeof(user));
}
- /* Get old security descriptor */
-
- if (!nt_printing_getsec(Printer->dev.handlename, &old_secdesc_ctr)) {
- DEBUG(3, ("could not get old security descriptor for "
- "printer %s", Printer->dev.handlename));
- return ERROR_INVALID_FUNCTION;
- }
-
/* Check the user has permissions to change the security
descriptor. By experimentation with two NT machines, the user
requires Full Access to the printer to change security
information. */
-
- if (!se_access_check(old_secdesc_ctr->sec, &user,
- PRINTER_ACE_FULL_CONTROL, &acc_granted,
- &status)) {
- DEBUG(3, ("security descriptor change denied by existing "
- "security descriptor\n"));
- result = status;
+ if (!print_access_check(&user, snum, PRINTER_ACCESS_ADMINISTER)) {
+ result = ERROR_ACCESS_DENIED;
goto done;
}
result = nt_printing_setsec(Printer->dev.handlename, secdesc_ctr);
done:
- free_sec_desc_buf(&old_secdesc_ctr);
return result;
}
return True;
}
+/****************************************************************************
+****************************************************************************/
+static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
+{
+ pid_t local_pid = sys_getpid();
+ char *cmd = lp_addprinter_cmd();
+ char *path;
+ char **qlines;
+ pstring tmp_file;
+ pstring command;
+ pstring driverlocation;
+ int numlines;
+ int ret;
+
+ if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
+ path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
+ else
+ path = tmpdir();
+
+ /* build driver path... only 9X architecture is needed for legacy reasons */
+ slprintf(driverlocation, sizeof(driverlocation)-1, "\\\\%s\\print$\\WIN40\\0",
+ global_myname);
+ /* change \ to \\ for the shell */
+ all_string_sub(driverlocation,"\\","\\\\",sizeof(pstring));
+
+ slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
+ slprintf(command, sizeof(command), "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
+ cmd, printer->info_2->printername, printer->info_2->sharename,
+ printer->info_2->portname, printer->info_2->drivername,
+ printer->info_2->location, driverlocation);
+
+ unlink(tmp_file);
+ DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
+ ret = smbrun(command, tmp_file, False);
+ DEBUGADD(10,("returned [%d]\n", ret));
+
+ if ( ret != 0 ) {
+ unlink(tmp_file);
+ return False;
+ }
+
+ numlines = 0;
+ qlines = file_lines_load(tmp_file, &numlines);
+ DEBUGADD(10,("Lines returned = [%d]\n", numlines));
+ DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
+ unlink(tmp_file);
+
+ if(numlines) {
+ // Set the portname to what the script says the portname should be
+ strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
+ DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
+
+ // Send SIGHUP to process group... is there a better way?
+ kill(0, SIGHUP);
+ add_all_printers();
+ }
+
+ file_lines_free(qlines);
+ return True;
+}
+
/********************************************************************
* called by spoolss_api_setprinter
* when updating a printer description
int snum;
NT_PRINTER_INFO_LEVEL *printer = NULL;
Printer_entry *Printer = find_printer_index_by_hnd(handle);
- SEC_DESC_BUF *sd = NULL;
- uint32 result, acc_granted;
- extern struct current_user current_user;
+ uint32 result;
DEBUG(8,("update_printer\n"));
/* Check calling user has permission to update printer description */
-#if 0 /* JFMTEST */
- if (!nt_printing_getsec(Printer->dev.handlename, &sd)) {
- DEBUG(3, ("Could not get security descriptor for printer %s",
- Printer->dev.handlename));
- result = ERROR_INVALID_FUNCTION;
- goto done;
- }
-
- if (!se_access_check(sd->sec, ¤t_user,
- PRINTER_ACE_FULL_CONTROL, &acc_granted,
- &result)) {
- DEBUG(3, ("printer property change denied by security "
- "descriptor\n"));
- goto done;
- }
-#endif
if (level!=2) {
DEBUG(0,("Send a mail to samba@samba.org\n"));
DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
result = ERROR_INVALID_HANDLE;
goto done;
}
+
+ if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
+ DEBUG(3, ("printer property change denied by security "
+ "descriptor\n"));
+ result = ERROR_ACCESS_DENIED;
+ goto done;
+ }
if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0) {
result = ERROR_INVALID_HANDLE;
*/
if (!check_printer_ok(printer->info_2, snum)) {
- result = ERROR_ACCESS_DENIED;
+ result = ERROR_INVALID_PARAMETER;
goto done;
}
+ if (*lp_addprinter_cmd() )
+ if ( !add_printer_hook(printer) ) {
+ result = ERROR_ACCESS_DENIED;
+ goto done;
+ }
+
if (add_a_printer(*printer, 2)!=0) {
/* I don't really know what to return here !!! */
result = ERROR_ACCESS_DENIED;
done:
free_a_printer(&printer, 2);
- free_sec_desc_buf(&sd);
return result;
}
/****************************************************************************
****************************************************************************/
uint32 _spoolss_addjob(POLICY_HND *handle, uint32 level,
- NEW_BUFFER *buffer, uint32 offered)
+ NEW_BUFFER *buffer, uint32 offered,
+ uint32 *needed)
{
- return NT_STATUS_NO_PROBLEMO;
+ *needed = 0;
+ return ERROR_INVALID_PARAMETER; /* this is what a NT server
+ returns for AddJob. AddJob
+ must fail on non-local
+ printers */
}
/****************************************************************************
job_info->totalpages=0;
job_info->pagesprinted=0;
- make_systemtime(&(job_info->submitted), t);
+ make_systemtime(&job_info->submitted, t);
}
/****************************************************************************
/****************************************************************************
****************************************************************************/
-static void fill_form_1(FORM_1 *form, nt_forms_struct *list, int position)
+static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
{
form->flag=list->flag;
init_unistr(&form->name, list->name);
/* construct the list of form structures */
for (i=0; i<*numofforms; i++) {
DEBUGADD(6,("Filling form number [%d]\n",i));
- fill_form_1(&forms_1[i], &list[i], i);
+ fill_form_1(&forms_1[i], &list[i]);
}
safe_free(list);
}
+/****************************************************************************
+****************************************************************************/
+uint32 _spoolss_getform( POLICY_HND *handle, uint32 level, UNISTR2 *uni_formname, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+{
+ nt_forms_struct *list=NULL;
+ FORM_1 form_1;
+ fstring form_name;
+ int buffer_size=0;
+ int numofforms, i;
+
+ unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
+
+ DEBUG(4,("_spoolss_getform\n"));
+ DEBUGADD(5,("Offered buffer size [%d]\n", offered));
+ DEBUGADD(5,("Info level [%d]\n", level));
+
+ numofforms = get_ntforms(&list);
+ DEBUGADD(5,("Number of forms [%d]\n", numofforms));
+
+ if (numofforms == 0)
+ return ERROR_NO_MORE_ITEMS;
+
+ switch (level) {
+ case 1:
+
+ /* Check if the requested name is in the list of form structures */
+ for (i=0; i<numofforms; i++) {
+
+ DEBUG(4,("_spoolss_getform: checking form %s (want %s)\n", list[i].name, form_name));
+
+ if (strequal(form_name, list[i].name)) {
+ DEBUGADD(6,("Found form %s number [%d]\n", form_name, i));
+ fill_form_1(&form_1, &list[i]);
+ break;
+ }
+ }
+
+ safe_free(list);
+
+ /* check the required size. */
+
+ *needed=spoolss_size_form_1(&form_1);
+
+ if (!alloc_buffer_size(buffer, buffer_size)){
+ return ERROR_INSUFFICIENT_BUFFER;
+ }
+
+ if (*needed > offered) {
+ return ERROR_INSUFFICIENT_BUFFER;
+ }
+
+ /* fill the buffer with the form structures */
+ DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name, i));
+ new_smb_io_form_1("", buffer, &form_1, 0);
+
+ return NT_STATUS_NO_PROBLEMO;
+
+ default:
+ safe_free(list);
+ return ERROR_INVALID_LEVEL;
+ }
+}
+
/****************************************************************************
****************************************************************************/
static void fill_port_1(PORT_INFO_1 *port, char *name)
****************************************************************************/
static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
- int n_services=lp_numservices();
- int snum;
- int i=0;
-
PORT_INFO_1 *ports=NULL;
+ int i=0;
- for (snum=0; snum<n_services; snum++)
- if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
- (*returned)++;
-
- if((ports=(PORT_INFO_1 *)malloc( (*returned+1) * sizeof(PORT_INFO_1) )) == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- for (snum=0; snum<n_services; snum++) {
- if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
- /*
- * Ensure this port name is unique.
- */
- int j;
-
- DEBUG(10,("enumports_level_1: port name %s\n", PRINTERNAME(snum)));
+ if (*lp_enumports_cmd()) {
+ pid_t local_pid = sys_getpid();
+ char *cmd = lp_enumports_cmd();
+ char *path;
+ char **qlines;
+ pstring tmp_file;
+ pstring command;
+ int numlines;
+ int ret;
+
+ if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
+ path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
+ else
+ path = tmpdir();
+
+ slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
+ slprintf(command, sizeof(command), "%s \"%d\"", cmd, 1);
+
+ unlink(tmp_file);
+ DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
+ ret = smbrun(command, tmp_file, False);
+ DEBUG(10,("Returned [%d]\n", ret));
+ if (ret != 0) {
+ unlink(tmp_file);
+ // Is this the best error to return here?
+ return ERROR_ACCESS_DENIED;
+ }
- for(j = 0; j < i; j++) {
- fstring port_name;
- unistr_to_dos(port_name, (const char *)&ports[j].port_name.buffer[0], sizeof(port_name));
+ numlines = 0;
+ qlines = file_lines_load(tmp_file, &numlines);
+ DEBUGADD(10,("Lines returned = [%d]\n", numlines));
+ DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
+ unlink(tmp_file);
- if (strequal(port_name, PRINTERNAME(snum)))
- break;
+ if(numlines) {
+ if((ports=(PORT_INFO_1 *)malloc( numlines * sizeof(PORT_INFO_1) )) == NULL) {
+ DEBUG(10,("Returning ERROR_NOT_ENOUGH_MEMORY [%x]\n", ERROR_NOT_ENOUGH_MEMORY));
+ file_lines_free(qlines);
+ return ERROR_NOT_ENOUGH_MEMORY;
}
- if (j < i)
- continue;
+ for (i=0; i<numlines; i++) {
+ DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
+ fill_port_1(&ports[i], qlines[i]);
+ }
- DEBUGADD(6,("Filling port number [%d]\n", i));
- fill_port_1(&ports[i], PRINTERNAME(snum));
- i++;
+ file_lines_free(qlines);
}
- }
- *returned = i;
+ *returned = numlines;
+
+ } else {
+ *returned = 1; /* Sole Samba port returned. */
+
+ if((ports=(PORT_INFO_1 *)malloc( sizeof(PORT_INFO_1) )) == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ DEBUG(10,("enumports_level_1: port name %s\n", SAMBA_PRINTER_PORT_NAME));
+
+ fill_port_1(&ports[0], SAMBA_PRINTER_PORT_NAME);
+ }
/* check the required size. */
for (i=0; i<*returned; i++) {
static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
- int n_services=lp_numservices();
- int snum;
- int i=0;
-
PORT_INFO_2 *ports=NULL;
+ int i=0;
- for (snum=0; snum<n_services; snum++)
- if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
- (*returned)++;
-
- if((ports=(PORT_INFO_2 *)malloc( (*returned+1) * sizeof(PORT_INFO_2) )) == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- for (snum=0; snum<n_services; snum++) {
- if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
- /*
- * Ensure this port name is unique.
- */
- int j;
-
- DEBUG(10,("enumports_level_2: port name %s\n", PRINTERNAME(snum)));
+ if (*lp_enumports_cmd()) {
+ pid_t local_pid = sys_getpid();
+ char *cmd = lp_enumports_cmd();
+ char *path;
+ char **qlines;
+ pstring tmp_file;
+ pstring command;
+ int numlines;
+ int ret;
+
+ if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
+ path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
+ else
+ path = tmpdir();
+
+ slprintf(tmp_file, sizeof(tmp_file), "%s/smbcmd.%d", path, local_pid);
+ slprintf(command, sizeof(command), "%s \"%d\"", cmd, 2);
+
+ unlink(tmp_file);
+ DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
+ ret = smbrun(command, tmp_file, False);
+ DEBUGADD(10,("returned [%d]\n", ret));
+ if (ret != 0) {
+ unlink(tmp_file);
+ // Is this the best error to return here?
+ return ERROR_ACCESS_DENIED;
+ }
- for(j = 0; j < i; j++) {
- fstring port_name;
- unistr_to_dos(port_name, (const char *)&ports[j].port_name.buffer[0], sizeof(port_name));
+ numlines = 0;
+ qlines = file_lines_load(tmp_file, &numlines);
+ DEBUGADD(10,("Lines returned = [%d]\n", numlines));
+ DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
+ unlink(tmp_file);
- if (strequal(port_name, PRINTERNAME(snum)))
- break;
+ if(numlines) {
+ if((ports=(PORT_INFO_2 *)malloc( numlines * sizeof(PORT_INFO_2) )) == NULL) {
+ DEBUG(10,("Returning ERROR_NOT_ENOUGH_MEMORY [%x]\n", ERROR_NOT_ENOUGH_MEMORY));
+ file_lines_free(qlines);
+ return ERROR_NOT_ENOUGH_MEMORY;
}
- if (j < i)
- continue;
+ for (i=0; i<numlines; i++) {
+ DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
+ fill_port_2(&(ports[i]), qlines[i]);
+ }
- DEBUGADD(6,("Filling port number [%d]\n", i));
- fill_port_2(&ports[i], PRINTERNAME(snum));
- i++;
+ file_lines_free(qlines);
}
- }
- *returned = i;
+ *returned = numlines;
+
+ } else {
+
+ *returned = 1;
+
+ if((ports=(PORT_INFO_2 *)malloc( sizeof(PORT_INFO_2) )) == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ DEBUG(10,("enumports_level_2: port name %s\n", SAMBA_PRINTER_PORT_NAME));
+
+ fill_port_2(&ports[0], SAMBA_PRINTER_PORT_NAME);
+ }
/* check the required size. */
for (i=0; i<*returned; i++) {
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
fstring name;
- fstring share_name;
int snum;
if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
/* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
convert_printer_info(info, printer, 2);
- unistr2_to_ascii(share_name, &info->info_2->sharename, sizeof(share_name)-1);
-
- slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname, share_name);
+ if (*lp_addprinter_cmd() )
+ if ( !add_printer_hook(printer) ) {
+ free_a_printer(&printer,2);
+ return ERROR_ACCESS_DENIED;
+ }
+
+ slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname,
+ printer->info_2->sharename);
- if ((snum = print_queue_snum(share_name)) == -1) {
+ if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
free_a_printer(&printer,2);
return ERROR_ACCESS_DENIED;
}
+
+ /* you must be a printer admin to add a new printer */
+ if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
+ free_a_printer(&printer,2);
+ return ERROR_ACCESS_DENIED;
+ }
/*
* Do sanity check on the requested changes for Samba.
if (!check_printer_ok(printer->info_2, snum)) {
free_a_printer(&printer,2);
- return ERROR_ACCESS_DENIED;
+ return ERROR_INVALID_PARAMETER;
}
/* write the ASCII on disk */
if (!open_printer_hnd(handle, name)) {
/* Handle open failed - remove addition. */
- del_a_printer(share_name);
+ del_a_printer(printer->info_2->sharename);
free_a_printer(&printer,2);
return ERROR_ACCESS_DENIED;
}
clean_up_driver_struct(driver, level);
DEBUG(5,("Moving driver to final destination\n"));
- if(!move_driver_to_download_area(driver, level, &user)) {
- err = ERROR_ACCESS_DENIED;
+ if(!move_driver_to_download_area(driver, level, &user, &err)) {
+ if (err == 0)
+ err = ERROR_ACCESS_DENIED;
goto done;
}
*/
if ( (in_value_len==0) && (in_data_len==0) ) {
DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
-
+
+ /*
+ * NT can ask for a specific parameter size - we need to return NO_MORE_ITEMS
+ * if this parameter size doesn't exist.
+ * Ok - my opinion here is that the client is not asking for the greatest
+ * possible size of all the parameters, but is asking specifically for the size needed
+ * for this specific parameter. In that case we can remove the loop below and
+ * simplify this lookup code considerably. JF - comments welcome. JRA.
+ */
+
+ if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
+ safe_free(data);
+ free_a_printer(&printer, 2);
+ return ERROR_NO_MORE_ITEMS;
+ }
+
+ safe_free(data);
+ data = NULL;
+
param_index=0;
biggest_valuesize=0;
biggest_datasize=0;
DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize, biggest_datasize));
safe_free(data);
+ data = NULL;
param_index++;
}
+ /*
+ * I think this is correct, it doesn't break APW and
+ * allows Gerald's Win32 test programs to work correctly,
+ * but may need altering.... JRA.
+ */
+
+ if (param_index == 0) {
+ /* No parameters found. */
+ free_a_printer(&printer, 2);
+ return ERROR_NO_MORE_ITEMS;
+ }
+
/* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
*out_value_len=2*(1+biggest_valuesize);
*out_data_len=biggest_datasize;
uint32 numeric_data)
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
- NT_PRINTER_PARAM *param = NULL;
-
+ NT_PRINTER_PARAM *param = NULL;
int snum=0;
uint32 status = 0x0;
Printer_entry *Printer=find_printer_index_by_hnd(handle);
if (!get_printer_snum(handle, &snum))
return ERROR_INVALID_HANDLE;
+ if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
+ DEBUG(3, ("security descriptor change denied by existing "
+ "security descriptor\n"));
+ return ERROR_ACCESS_DENIED;
+ }
+
status = get_a_printer(&printer, 2, lp_servicename(snum));
if (status != 0x0)
return ERROR_INVALID_NAME;
return 0x0;
}
+/****************************************************************************
+****************************************************************************/
+uint32 _spoolss_deleteform( POLICY_HND *handle, UNISTR2 *form_name)
+{
+ int count=0;
+ uint32 ret = 0;
+ nt_forms_struct *list=NULL;
+ Printer_entry *Printer = find_printer_index_by_hnd(handle);
+
+ DEBUG(5,("spoolss_deleteform\n"));
+
+ if (!OPEN_HANDLE(Printer)) {
+ DEBUG(0,("_spoolss_deleteform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
+ return ERROR_INVALID_HANDLE;
+ }
+
+ count = get_ntforms(&list);
+ if(!delete_a_form(&list, form_name, &count, &ret))
+ return ERROR_INVALID_PARAMETER;
+
+ safe_free(list);
+
+ return ret;
+}
+
/****************************************************************************
****************************************************************************/
uint32 _spoolss_setform( POLICY_HND *handle,