Herb's warning fixes. Also the POSIX locking fix.
[samba.git] / source / rpc_server / srv_spoolss_nt.c
index 2a25f615d8a2cdf0dc92f8920e10c4d09eb5c259..5a724d6ab6487fbd701f21203a5530eb3b645b8a 100644 (file)
@@ -191,11 +191,16 @@ static BOOL srv_spoolss_replycloseprinter(POLICY_HND *handle)
                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;
 }
 
 /****************************************************************************
@@ -280,7 +285,7 @@ static BOOL delete_printer_handle(POLICY_HND *hnd)
                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 ) {
@@ -313,10 +318,8 @@ static BOOL get_printer_snum(POLICY_HND *hnd, int *number)
                return (*number != -1);
        case PRINTER_HANDLE_IS_PRINTSERVER:
                return False;
-               break;
        default:
                return False;
-               break;
        }
 }
 
@@ -355,16 +358,14 @@ static BOOL set_printer_hnd_printertype(Printer_entry *Printer, char *handlename
        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;
 }
 
 /****************************************************************************
@@ -495,6 +496,7 @@ static BOOL open_printer_hnd(POLICY_HND *hnd, char *name)
 {
        Printer_entry *new_printer;
 
+       DEBUG(10,("open_printer_hnd: name [%s]\n", name));
        clear_handle(hnd);
        create_printer_hnd(hnd);
 
@@ -576,11 +578,22 @@ static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
 /***************************************************************************
  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. */
@@ -596,8 +609,7 @@ static BOOL srv_spoolss_receive_message(char *printer)
                                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);
 
        }
 }
@@ -621,7 +633,12 @@ static BOOL srv_spoolss_sendnotify(POLICY_HND *handle)
        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;
 }      
 
 /********************************************************************
@@ -663,6 +680,17 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
                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;
 }
 
@@ -993,14 +1021,19 @@ static BOOL srv_spoolss_replyopenprinter(char *printer, uint32 localprinter, uin
         * 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;
 }
 
 /********************************************************************
@@ -1422,7 +1455,6 @@ static uint32 size_of_notify_info_data(uint16 type, uint16 field)
                     (notify_info_data_table[i].field == field ) )
                {
                        return (notify_info_data_table[i].size);
-                       continue;
                }
                i++;
        }
@@ -1449,7 +1481,6 @@ static BOOL type_of_notify_info_data(uint16 type, uint16 field)
                        {
                                return (True);
                        }
-                       continue;
                }
                i++;
        }
@@ -1759,10 +1790,8 @@ uint32 _spoolss_rfnpcnex( POLICY_HND *handle, uint32 change,
        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;
@@ -2466,18 +2495,14 @@ uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 le
        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;
        }
 }
 
@@ -2642,7 +2667,6 @@ uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level,
                return getprinter_level_3(servername,snum, buffer, offered, needed);
        default:
                return ERROR_INVALID_LEVEL;
-               break;
        }
 }      
                
@@ -3059,7 +3083,7 @@ static uint32 getprinterdriver2_level6(fstring servername, fstring architecture,
        *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;
        }
 
@@ -3100,19 +3124,14 @@ uint32 _spoolss_getprinterdriver2(POLICY_HND *handle, const UNISTR2 *uni_arch, u
        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;
        }
 }
 
@@ -3154,10 +3173,10 @@ uint32 _spoolss_endpageprinter(POLICY_HND *handle)
 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, &current_user, sizeof(user));
+               memcpy(user, &current_user, sizeof(struct current_user));
        }
 
        return user;
@@ -3451,11 +3470,11 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
        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();
        }
@@ -3592,17 +3611,13 @@ uint32 _spoolss_setprinter(POLICY_HND *handle, uint32 level,
        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;
        }
 }
 
@@ -3856,15 +3871,12 @@ uint32 _spoolss_enumjobs( POLICY_HND *handle, uint32 firstjob, uint32 numofjobs,
        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;
        }
 }
 
@@ -4180,18 +4192,14 @@ uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32
        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;
        }
 }
 
@@ -4393,7 +4401,7 @@ static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
                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;
                }
 
@@ -4491,7 +4499,7 @@ static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
                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;
                }
 
@@ -4572,13 +4580,10 @@ uint32 _spoolss_enumports( UNISTR2 *name, uint32 level,
        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;
        }
 }
 
@@ -4666,15 +4671,12 @@ uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level,
                        /* 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;
        }
 }
 
@@ -4773,10 +4775,8 @@ uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environmen
        switch(level) {
        case 1:
                return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
-               break;
        default:
                return ERROR_INVALID_LEVEL;
-               break;
        }
 }
        
@@ -5161,10 +5161,8 @@ uint32 _spoolss_enumprintprocessors(UNISTR2 *name, UNISTR2 *environment, uint32
        switch (level) {
        case 1:
                return enumprintprocessors_level_1(buffer, offered, needed, returned);
-               break;
        default:
                return ERROR_INVALID_LEVEL;
-               break;
        }
 }
 
@@ -5213,10 +5211,8 @@ uint32 _spoolss_enumprintprocdatatypes(UNISTR2 *name, UNISTR2 *processor, uint32
        switch (level) {
        case 1:
                return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
-               break;
        default:
                return ERROR_INVALID_LEVEL;
-               break;
        }
 }
 
@@ -5305,13 +5301,10 @@ uint32 _spoolss_enumprintmonitors(UNISTR2 *name,uint32 level,
        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;
        }
 }
 
@@ -5442,14 +5435,11 @@ uint32 _spoolss_getjob( POLICY_HND *handle, uint32 jobid, uint32 level,
        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