First cut of fix for changenotify on a print server handle. Use the connections tdb
authorJeremy Allison <jra@samba.org>
Sun, 10 Nov 2002 22:24:10 +0000 (22:24 +0000)
committerJeremy Allison <jra@samba.org>
Sun, 10 Nov 2002 22:24:10 +0000 (22:24 +0000)
with an snum of -1 and a special printername.
Jeremy.
(This used to be commit 940b04ddfa87acc939911e3fe76496e3c4675632)

source3/printing/printing.c
source3/rpc_server/srv_spoolss_nt.c

index 9bc4606adaadf801a03e52a2d08950612314682f..cc4d588e2ddbb3e1d870ae109481825ee17ca19a 100644 (file)
@@ -1046,15 +1046,16 @@ static void print_queue_update(int snum)
 ****************************************************************************/
 
 #define NOTIFY_PID_LIST_KEY "NOTIFY_PID_LIST"
+#define PRINT_SERVER_ENTRY_NAME "___PRINT_SERVER_ENTRY___"
 
-static TDB_DATA get_printer_notify_pid_list(struct tdb_print_db *pdb, BOOL cleanlist)
+static TDB_DATA get_printer_notify_pid_list(TDB_CONTEXT *tdb, const char *printer_name, BOOL cleanlist)
 {
        TDB_DATA data;
        size_t i;
 
        ZERO_STRUCT(data);
 
-       data = tdb_fetch_by_string( pdb->tdb, NOTIFY_PID_LIST_KEY );
+       data = tdb_fetch_by_string( tdb, NOTIFY_PID_LIST_KEY );
 
        if (!data.dptr) {
                ZERO_STRUCT(data);
@@ -1062,9 +1063,8 @@ static TDB_DATA get_printer_notify_pid_list(struct tdb_print_db *pdb, BOOL clean
        }
 
        if (data.dsize % 8) {
-               DEBUG(0,("get_printer_notify_pid_list: Size of record for printer %s not a multiple of 8 !\n",
-                                       pdb->printer_name ));
-               tdb_delete_by_string(pdb->tdb, NOTIFY_PID_LIST_KEY );
+               DEBUG(0,("get_printer_notify_pid_list: Size of record for printer %s not a multiple of 8 !\n", printer_name ));
+               tdb_delete_by_string(tdb, NOTIFY_PID_LIST_KEY );
                ZERO_STRUCT(data);
                return data;
        }
@@ -1089,7 +1089,7 @@ static TDB_DATA get_printer_notify_pid_list(struct tdb_print_db *pdb, BOOL clean
                        /* Refcount == zero is a logic error and should never happen. */
                        if (IVAL(data.dptr, i + 4) == 0) {
                                DEBUG(0,("get_printer_notify_pid_list: Refcount == 0 for pid = %u printer %s !\n",
-                                                       (unsigned int)pid, pdb->printer_name ));
+                                                       (unsigned int)pid, printer_name ));
                        }
 
                        if (data.dsize - i > 8)
@@ -1108,7 +1108,8 @@ static TDB_DATA get_printer_notify_pid_list(struct tdb_print_db *pdb, BOOL clean
 
 BOOL print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t *p_num_pids, pid_t **pp_pid_list)
 {
-       struct tdb_print_db *pdb;
+       struct tdb_print_db *pdb = NULL;
+       TDB_CONTEXT *tdb = NULL;
        TDB_DATA data;
        BOOL ret = True;
        size_t i, num_pids, offset;
@@ -1117,17 +1118,25 @@ BOOL print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t
        *p_num_pids = 0;
        *pp_pid_list = NULL;
 
-       pdb = get_print_db_byname(printername);
-       if (!pdb)
-               return False;
+       if (strequal(printername, PRINT_SERVER_ENTRY_NAME)) {
+               pdb = NULL;
+               tdb = conn_tdb_ctx();
+       } else {
+               pdb = get_print_db_byname(printername);
+               if (!pdb)
+                       return False;
+               tdb = pdb->tdb;
+       }
 
-       if (tdb_read_lock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
-               DEBUG(0,("print_notify_pid_list: Failed to lock printer %s database\n", printername));
-               release_print_db(pdb);
+       if (tdb_read_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
+               DEBUG(0,("print_notify_pid_list: Failed to lock printer %s database\n",
+                                       printername));
+               if (pdb)
+                       release_print_db(pdb);
                return False;
        }
 
-       data = get_printer_notify_pid_list( pdb, True );
+       data = get_printer_notify_pid_list( tdb, printername, True );
 
        if (!data.dptr) {
                ret = True;
@@ -1151,8 +1160,9 @@ BOOL print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t
 
   done:
 
-       tdb_read_unlock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY);
-       release_print_db(pdb);
+       tdb_read_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
+       if (pdb)
+               release_print_db(pdb);
        SAFE_FREE(data.dptr);
        return ret;
 }
@@ -1165,23 +1175,34 @@ BOOL print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t
 BOOL print_notify_register_pid(int snum)
 {
        TDB_DATA data;
-       struct tdb_print_db *pdb;
-       const char *printername = lp_const_servicename(snum);
+       struct tdb_print_db *pdb = NULL;
+       TDB_CONTEXT *tdb = NULL;
+       const char *printername;
        uint32 mypid = (uint32)sys_getpid();
        BOOL ret = False;
        size_t i;
 
-       pdb = get_print_db_byname(printername);
-       if (!pdb)
-               return False;
+       if (snum != -1) {
+               printername = lp_const_servicename(snum);
+               pdb = get_print_db_byname(printername);
+               if (!pdb)
+                       return False;
+               tdb = pdb->tdb;
+       } else {
+               printername = PRINT_SERVER_ENTRY_NAME;
+               pdb = NULL;
+               tdb = conn_tdb_ctx();
+       }
 
-       if (tdb_lock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
-               DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n", printername));
-               release_print_db(pdb);
+       if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
+               DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
+                                       printername));
+               if (pdb)
+                       release_print_db(pdb);
                return False;
        }
 
-       data = get_printer_notify_pid_list( pdb, True );
+       data = get_printer_notify_pid_list( tdb, printername, True );
 
        /* Add ourselves and increase the refcount. */
 
@@ -1197,7 +1218,8 @@ BOOL print_notify_register_pid(int snum)
                /* We weren't in the list. Realloc. */
                data.dptr = Realloc(data.dptr, data.dsize + 8);
                if (!data.dptr) {
-                       DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n", printername));
+                       DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
+                                               printername));
                        goto done;
                }
                data.dsize += 8;
@@ -1206,8 +1228,9 @@ BOOL print_notify_register_pid(int snum)
        }
 
        /* Store back the record. */
-       if (tdb_store_by_string(pdb->tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
-               DEBUG(0,("print_notify_register_pid: Failed to update pid list for printer %s\n", printername));
+       if (tdb_store_by_string(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
+               DEBUG(0,("print_notify_register_pid: Failed to update pid \
+list for printer %s\n", printername));
                goto done;
        }
 
@@ -1215,8 +1238,9 @@ BOOL print_notify_register_pid(int snum)
 
  done:
 
-       tdb_unlock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY);
-       release_print_db(pdb);
+       tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
+       if (pdb)
+               release_print_db(pdb);
        SAFE_FREE(data.dptr);
        return ret;
 }
@@ -1229,23 +1253,34 @@ BOOL print_notify_register_pid(int snum)
 BOOL print_notify_deregister_pid(int snum)
 {
        TDB_DATA data;
-       struct tdb_print_db *pdb;
-       const char *printername = lp_const_servicename(snum);
+       struct tdb_print_db *pdb = NULL;
+       TDB_CONTEXT *tdb = NULL;
+       const char *printername;
        uint32 mypid = (uint32)sys_getpid();
        size_t i;
        BOOL ret = False;
 
-       pdb = get_print_db_byname(printername);
-       if (!pdb)
-               return False;
+       if (snum != -1) {
+               printername = lp_const_servicename(snum);
+               pdb = get_print_db_byname(printername);
+               if (!pdb)
+                       return False;
+               tdb = pdb->tdb;
+       } else {
+               printername = PRINT_SERVER_ENTRY_NAME;
+               pdb = NULL;
+               tdb = conn_tdb_ctx();
+       }
 
-       if (tdb_lock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
-               DEBUG(0,("print_notify_register_pid: Failed to lock printer %s database\n", printername));
-               release_print_db(pdb);
+       if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
+               DEBUG(0,("print_notify_register_pid: Failed to lock \
+printer %s database\n", printername));
+               if (pdb)
+                       release_print_db(pdb);
                return False;
        }
 
-       data = get_printer_notify_pid_list( pdb, True );
+       data = get_printer_notify_pid_list( tdb, printername, True );
 
        /* Reduce refcount. Remove ourselves if zero. */
 
@@ -1271,8 +1306,9 @@ BOOL print_notify_deregister_pid(int snum)
                SAFE_FREE(data.dptr);
 
        /* Store back the record. */
-       if (tdb_store_by_string(pdb->tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
-               DEBUG(0,("print_notify_register_pid: Failed to update pid list for printer %s\n", printername));
+       if (tdb_store_by_string(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
+               DEBUG(0,("print_notify_register_pid: Failed to update pid \
+list for printer %s\n", printername));
                goto done;
        }
 
@@ -1280,8 +1316,9 @@ BOOL print_notify_deregister_pid(int snum)
 
   done:
 
-       tdb_unlock_bystring(pdb->tdb, NOTIFY_PID_LIST_KEY);
-       release_print_db(pdb);
+       tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
+       if (pdb)
+               release_print_db(pdb);
        SAFE_FREE(data.dptr);
        return ret;
 }
index f8262110ce17641f4b92c290c7788c272d765612..2227d39f44c39c7d5f6c6ac56654098151d5d4b6 100644 (file)
@@ -226,9 +226,19 @@ static void free_printer_entry(void *ptr)
 {
        Printer_entry *Printer = (Printer_entry *)ptr;
 
-       if (Printer->notify.client_connected==True)
-               srv_spoolss_replycloseprinter(print_queue_snum(Printer->dev.handlename),
-                               &Printer->notify.client_hnd);
+       if (Printer->notify.client_connected==True) {
+               int snum = -1;
+
+               if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER) {
+                       snum = -1;
+                       srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
+               } else if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTER) {
+                       snum = print_queue_snum(Printer->dev.handlename);
+                       if (snum != -1)
+                               srv_spoolss_replycloseprinter(snum,
+                                               &Printer->notify.client_hnd);
+               }
+       }
 
        Printer->notify.flags=0;
        Printer->notify.options=0;
@@ -2471,7 +2481,7 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE
        uint32 options = q_u->options;
        UNISTR2 *localmachine = &q_u->localmachine;
        uint32 printerlocal = q_u->printerlocal;
-       int snum;
+       int snum = -1;
        SPOOL_NOTIFY_OPTION *option = q_u->option;
 
        /* store the notify value in the printer struct */
@@ -2483,9 +2493,6 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE
                return WERR_BADFID;
        }
 
-       if ( (Printer->printer_type == PRINTER_HANDLE_IS_PRINTER) && !get_printer_snum(p, handle, &snum) )
-               return WERR_BADFID;
-
        Printer->notify.flags=flags;
        Printer->notify.options=options;
        Printer->notify.printerlocal=printerlocal;
@@ -2500,6 +2507,12 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE
 
        /* Connect to the client machine and send a ReplyOpenPrinter */
 
+       if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
+               snum = -1;
+       else if ( (Printer->printer_type == PRINTER_HANDLE_IS_PRINTER) &&
+                       !get_printer_snum(p, handle, &snum) )
+               return WERR_BADFID;
+
        if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
                                        Printer->notify.printerlocal, 1,
                                        &Printer->notify.client_hnd))
@@ -5859,7 +5872,6 @@ WERROR _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SET
 WERROR _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u)
 {
        POLICY_HND *handle = &q_u->handle;
-       int snum;
        Printer_entry *Printer= find_printer_index_by_hnd(p, handle);
        
        if (!Printer) {
@@ -5867,11 +5879,17 @@ WERROR _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u)
                return WERR_BADFID;
        }
 
-       if (!get_printer_snum(p, handle, &snum))
-               return WERR_BADFID;
+       if (Printer->notify.client_connected==True) {
+               int snum = -1;
+
+               if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
+                       snum = -1;
+               else if ( (Printer->printer_type == PRINTER_HANDLE_IS_PRINTER) &&
+                               !get_printer_snum(p, handle, &snum) )
+                       return WERR_BADFID;
 
-       if (Printer->notify.client_connected==True)
                srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
+       }
 
        Printer->notify.flags=0;
        Printer->notify.options=0;