return False;
/* if it's the last connection, deconnect the IPC$ share */
- if (smb_connections==1)
+ if (smb_connections==1) {
if(!spoolss_disconnect_from_client(&cli))
return False;
+ message_deregister(MSG_PRINTER_NOTIFY);
+ }
+
smb_connections--;
+
+ return True;
}
/****************************************************************************
DEBUGADD(10,("Unlinking output file [%s]\n", tmp_file));
unlink(tmp_file);
- // Send SIGHUP to process group... is there a better way?
+ /* Send SIGHUP to process group... is there a better way? */
kill(0, SIGHUP);
if ( ( i = lp_servicenumber( Printer->dev.handlename ) ) >= 0 ) {
return (*number != -1);
case PRINTER_HANDLE_IS_PRINTSERVER:
return False;
- break;
default:
return False;
- break;
}
}
if (!strchr(handlename+2, '\\')) {
DEBUGADD(4,("Printer is a print server\n"));
Printer->printer_type = PRINTER_HANDLE_IS_PRINTSERVER;
- return True;
}
/* it's a printer */
else {
DEBUGADD(4,("Printer is a printer\n"));
Printer->printer_type = PRINTER_HANDLE_IS_PRINTER;
- return True;
}
- return False;
+ return True;
}
/****************************************************************************
{
Printer_entry *new_printer;
+ DEBUG(10,("open_printer_hnd: name [%s]\n", name));
clear_handle(hnd);
create_printer_hnd(hnd);
/***************************************************************************
receive the notify message
****************************************************************************/
-static BOOL srv_spoolss_receive_message(char *printer)
+void srv_spoolss_receive_message(int msg_type, pid_t src, void *buf, size_t len)
{
+ fstring printer;
uint32 status;
Printer_entry *find_printer;
+ *printer = '\0';
+ fstrcpy(printer,buf);
+
+ if (len == 0) {
+ DEBUG(0,("srv_spoolss_receive_message: got null message !\n"));
+ return;
+ }
+
+ DEBUG(10,("srv_spoolss_receive_message: Got message about printer %s\n", printer ));
+
find_printer = (Printer_entry *)ubi_dlFirst(&Printer_list);
/* Iterate the printer list. */
continue;
if (find_printer->notify.client_connected==True)
- if( !cli_spoolss_reply_rrpcn(&cli, &find_printer->notify.client_hnd, PRINTER_CHANGE_ALL, 0x0, &status))
- return False;
+ cli_spoolss_reply_rrpcn(&cli, &find_printer->notify.client_hnd, PRINTER_CHANGE_ALL, 0x0, &status);
}
}
else
fstrcpy(printer, "");
- srv_spoolss_receive_message(printer);
+ /*srv_spoolss_receive_message(printer);*/
+ DEBUG(10,("srv_spoolss_sendnotify: Sending message about printer %s\n", printer ));
+
+ message_send_all(MSG_PRINTER_NOTIFY, printer, strlen(printer) + 1); /* Null terminate... */
+
+ return True;
}
/********************************************************************
return ERROR_ACCESS_DENIED;
}
+ /* Disallow MS AddPrinterWizard if access rights are insufficient OR
+ if parameter disables it. The client tries an OpenPrinterEx with
+ SERVER_ALL_ACCESS(0xf0003), which we force to fail. It then tries
+ OpenPrinterEx with SERVER_READ(0x20002) which we allow. This lets
+ it see any printers there, but does not show the MSAPW */
+ if (handle_is_printserver(handle) &&
+ printer_default->access_required != (SERVER_READ) &&
+ !lp_ms_add_printer_wizard() ) {
+ return ERROR_ACCESS_DENIED;
+ }
+
return NT_STATUS_NO_PROBLEMO;
}
* If it's the first connection, contact the client
* and connect to the IPC$ share anonumously
*/
- if (smb_connections==0)
+ if (smb_connections==0) {
if(!spoolss_connect_to_client(&cli, printer+2)) /* the +2 is to strip the leading 2 backslashs */
return False;
+ message_register(MSG_PRINTER_NOTIFY, srv_spoolss_receive_message);
+
+ }
smb_connections++;
if(!cli_spoolss_reply_open_printer(&cli, printer, localprinter, type, &status, handle))
return False;
+
+ return True;
}
/********************************************************************
(notify_info_data_table[i].field == field ) )
{
return (notify_info_data_table[i].size);
- continue;
}
i++;
}
{
return (True);
}
- continue;
}
i++;
}
switch (Printer->printer_type) {
case PRINTER_HANDLE_IS_PRINTSERVER:
return printserver_notify_info(handle, info);
- break;
case PRINTER_HANDLE_IS_PRINTER:
return printer_notify_info(handle, info);
- break;
}
return ERROR_INVALID_HANDLE;
switch (level) {
case 1:
return enumprinters_level1(flags, name, buffer, offered, needed, returned);
- break;
case 2:
return enumprinters_level2(flags, name, buffer, offered, needed, returned);
- break;
case 5:
return enumprinters_level5(flags, name, buffer, offered, needed, returned);
- break;
case 3:
case 4:
default:
return ERROR_INVALID_LEVEL;
- break;
}
}
return getprinter_level_3(servername,snum, buffer, offered, needed);
default:
return ERROR_INVALID_LEVEL;
- break;
}
}
*needed += spoolss_size_printer_driver_info_6(&info);
if (!alloc_buffer_size(buffer, *needed)) {
- free_printer_driver_info_3(&info);
+ free_printer_driver_info_6(&info);
return ERROR_INSUFFICIENT_BUFFER;
}
switch (level) {
case 1:
return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
- break;
case 2:
return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
- break;
case 3:
return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
- break;
case 6:
return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
- break;
default:
return ERROR_INVALID_LEVEL;
- break;
}
}
static struct current_user *get_current_user(struct current_user *user, pipes_struct *p)
{
if (p->ntlmssp_auth_validated) {
- memcpy(user, &p->pipe_user, sizeof(user));
+ memcpy(user, &p->pipe_user, sizeof(struct current_user));
} else {
extern struct current_user current_user;
- memcpy(user, ¤t_user, sizeof(user));
+ memcpy(user, ¤t_user, sizeof(struct current_user));
}
return user;
unlink(tmp_file);
if(numlines) {
- // Set the portname to what the script says the portname should be
+ /* 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?
+ /* Send SIGHUP to process group... is there a better way? */
kill(0, SIGHUP);
add_all_printers();
}
switch (level) {
case 0:
return control_printer(handle, command, p);
- break;
case 2:
return update_printer(handle, level, info, devmode_ctr.devmode);
- break;
case 3:
return update_printer_sec(handle, level, info, p,
secdesc_ctr);
- break;
default:
return ERROR_INVALID_LEVEL;
- break;
}
}
switch (level) {
case 1:
return enumjobs_level1(queue, snum, buffer, offered, needed, returned);
- break;
case 2:
return enumjobs_level2(queue, snum, buffer, offered, needed, returned);
- break;
default:
safe_free(queue);
*returned=0;
return ERROR_INVALID_LEVEL;
- break;
}
}
switch (level) {
case 1:
return enumprinterdrivers_level1(servername, architecture, buffer, offered, needed, returned);
- break;
case 2:
return enumprinterdrivers_level2(servername, architecture, buffer, offered, needed, returned);
- break;
case 3:
return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned);
- break;
default:
*returned=0;
safe_free(list);
return ERROR_INVALID_LEVEL;
- break;
}
}
DEBUG(10,("Returned [%d]\n", ret));
if (ret != 0) {
unlink(tmp_file);
- // Is this the best error to return here?
+ /* Is this the best error to return here? */
return ERROR_ACCESS_DENIED;
}
DEBUGADD(10,("returned [%d]\n", ret));
if (ret != 0) {
unlink(tmp_file);
- // Is this the best error to return here?
+ /* Is this the best error to return here? */
return ERROR_ACCESS_DENIED;
}
switch (level) {
case 1:
return enumports_level_1(buffer, offered, needed, returned);
- break;
case 2:
return enumports_level_2(buffer, offered, needed, returned);
- break;
default:
return ERROR_INVALID_LEVEL;
- break;
}
}
/* we don't handle yet */
/* but I know what to do ... */
return ERROR_INVALID_LEVEL;
- break;
case 2:
return spoolss_addprinterex_level_2(uni_srv_name, info,
unk0, unk1, unk2, unk3,
user_switch, user, handle);
- break;
default:
return ERROR_INVALID_LEVEL;
- break;
}
}
switch(level) {
case 1:
return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
- break;
default:
return ERROR_INVALID_LEVEL;
- break;
}
}
switch (level) {
case 1:
return enumprintprocessors_level_1(buffer, offered, needed, returned);
- break;
default:
return ERROR_INVALID_LEVEL;
- break;
}
}
switch (level) {
case 1:
return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
- break;
default:
return ERROR_INVALID_LEVEL;
- break;
}
}
switch (level) {
case 1:
return enumprintmonitors_level_1(buffer, offered, needed, returned);
- break;
case 2:
return enumprintmonitors_level_2(buffer, offered, needed, returned);
- break;
default:
return ERROR_INVALID_LEVEL;
- break;
}
}
switch (level) {
case 1:
return getjob_level_1(queue, count, snum, jobid, buffer, offered, needed);
- break;
case 2:
return getjob_level_2(queue, count, snum, jobid, buffer, offered, needed);
- break;
default:
safe_free(queue);
return ERROR_INVALID_LEVEL;
- break;
}
}
#undef OLD_NTDOMAIN