Changes from APPLIANCE_HEAD:
[ira/wip.git] / source3 / rpc_server / srv_spoolss_nt.c
index 69cb79156b31cdae5636157221193d2b0283a336..23f8ab15efb1ddfa9fc5a805a113aa3253def429 100644 (file)
@@ -640,7 +640,7 @@ static BOOL srv_spoolss_sendnotify(POLICY_HND *handle)
        /*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, False); /* Null terminate... */
+       message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer, strlen(printer) + 1, False); /* Null terminate... */
 
        return True;
 }      
@@ -655,10 +655,16 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
                                 uint32  user_switch, SPOOL_USER_CTR user_ctr,
                                 POLICY_HND *handle)
 {
+       uint32 result = NT_STATUS_NO_PROBLEMO;
+       SEC_DESC_BUF *sec_desc = NULL;
+       uint32 acc_granted, status;
        fstring name;
+       extern struct current_user current_user;
        
-       if (printername == NULL)
-               return ERROR_INVALID_PRINTER_NAME;
+       if (printername == NULL) {
+               result = ERROR_INVALID_PRINTER_NAME;
+               goto done;
+       }
 
        /* some sanity check because you can open a printer or a print server */
        /* aka: \\server\printer or \\server */
@@ -666,8 +672,10 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
 
        DEBUGADD(3,("checking name: %s\n",name));
 
-       if (!open_printer_hnd(handle, name))
-               return ERROR_INVALID_PRINTER_NAME;
+       if (!open_printer_hnd(handle, name)) {
+               result = ERROR_INVALID_PRINTER_NAME;
+               goto done;
+       }
        
 /*
        if (printer_default->datatype_ptr != NULL)
@@ -681,7 +689,8 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
        
        if (!set_printer_hnd_accesstype(handle, printer_default->access_required)) {
                close_printer_handle(handle);
-               return ERROR_ACCESS_DENIED;
+               result = ERROR_ACCESS_DENIED;
+               goto done;
        }
                
        /* Disallow MS AddPrinterWizard if parameter disables it. A Win2k
@@ -696,13 +705,41 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
 
        if (handle_is_printserver(handle) &&
            !lp_ms_add_printer_wizard()) {
-               if (printer_default->access_required == 0)
-                       return NT_STATUS_NO_PROBLEMO;
-               else if (printer_default->access_required != (SERVER_READ))
-               return ERROR_ACCESS_DENIED;
+               if (printer_default->access_required == 0) {
+                       goto done;
+               }
+               else if (printer_default->access_required != (SERVER_READ)) {
+                       close_printer_handle(handle);
+                       result = ERROR_ACCESS_DENIED;
+                       goto done;
+               }
        }
 
-       return NT_STATUS_NO_PROBLEMO;
+       /* NT doesn't let us connect to a printer if the connecting user
+          doesn't have print permission.  If no security descriptor just
+          return OK. */
+
+       if (!nt_printing_getsec(name, &sec_desc)) {
+               goto done;
+       }
+       
+       /* Yuck - we should use the pipe_user rather than current_user but
+          it doesn't seem to be filled in correctly. )-: */
+
+       map_printer_permissions(sec_desc->sec);
+
+       if (!se_access_check(sec_desc->sec, &current_user, PRINTER_ACCESS_USE,
+                            &acc_granted, &status)) {
+               DEBUG(3, ("access DENIED for printer open\n"));
+               close_printer_handle(handle);
+               result = ERROR_ACCESS_DENIED;
+               goto done;
+       }
+
+ done:
+       free_sec_desc_buf(&sec_desc);
+
+       return result;
 }
 
 /****************************************************************************
@@ -779,13 +816,16 @@ static BOOL convert_devicemode(const DEVICEMODE *devmode, NT_DEVICEMODE *nt_devm
        nt_devmode->panningwidth=devmode->panningwidth;
        nt_devmode->panningheight=devmode->panningheight;
 
+       safe_free(nt_devmode->private);
        if (nt_devmode->driverextra != 0) {
                /* if we had a previous private delete it and make a new one */
-               safe_free(nt_devmode->private);
                if((nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra * sizeof(uint8))) == NULL)
                        return False;
                memcpy(nt_devmode->private, devmode->private, nt_devmode->driverextra);
        }
+       else {
+               nt_devmode->private = NULL;
+       }
 
        return True;
 }
@@ -2021,7 +2061,7 @@ static DEVICEMODE *construct_dev_mode(int snum)
 
        DEBUGADD(8,("loading DEVICEMODE\n"));
 
-       safe_strcpy(adevice, printer->info_2->printername, sizeof(adevice));
+       snprintf(adevice, sizeof(adevice), printer->info_2->printername);
        init_unistr(&devmode->devicename, adevice);
 
        snprintf(aform, sizeof(aform), ntdevmode->formname);
@@ -2700,23 +2740,31 @@ static uint32 construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fst
  ********************************************************************/
 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
 {
-       pstring temp_driverpath;
-       pstring temp_datafile;
-       pstring temp_configfile;
+       pstring temp;
 
        info->version=driver.info_3->cversion;
 
        init_unistr( &info->name, driver.info_3->name );
        init_unistr( &info->architecture, driver.info_3->environment );
 
-       snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
-       init_unistr( &info->driverpath, temp_driverpath );
 
-       snprintf(temp_datafile, sizeof(temp_datafile)-1, "\\\\%s%s", servername, driver.info_3->datafile);
-       init_unistr( &info->datafile, temp_datafile );
+    if (strlen(driver.info_3->driverpath)) {
+               snprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
+               init_unistr( &info->driverpath, temp );
+    } else
+        init_unistr( &info->driverpath, "" );
 
-       snprintf(temp_configfile, sizeof(temp_configfile)-1, "\\\\%s%s", servername, driver.info_3->configfile);
-       init_unistr( &info->configfile, temp_configfile );      
+       if (strlen(driver.info_3->datafile)) {
+               snprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile);
+               init_unistr( &info->datafile, temp );
+       } else
+               init_unistr( &info->datafile, "" );
+       
+       if (strlen(driver.info_3->configfile)) {
+               snprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile);
+               init_unistr( &info->configfile, temp ); 
+       } else
+               init_unistr( &info->configfile, "" );
 }
 
 /********************************************************************
@@ -2790,10 +2838,7 @@ static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *ser
  ********************************************************************/
 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
 {
-       pstring temp_driverpath;
-       pstring temp_datafile;
-       pstring temp_configfile;
-       pstring temp_helpfile;
+       pstring temp;
 
        ZERO_STRUCTP(info);
 
@@ -2802,17 +2847,29 @@ static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_IN
        init_unistr( &info->name, driver.info_3->name );        
        init_unistr( &info->architecture, driver.info_3->environment );
 
-       snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "\\\\%s%s", servername, driver.info_3->driverpath);                
-       init_unistr( &info->driverpath, temp_driverpath );
-
-       snprintf(temp_datafile, sizeof(temp_datafile)-1, "\\\\%s%s", servername, driver.info_3->datafile);
-       init_unistr( &info->datafile, temp_datafile );
-
-       snprintf(temp_configfile, sizeof(temp_configfile)-1, "\\\\%s%s", servername, driver.info_3->configfile);
-       init_unistr( &info->configfile, temp_configfile );      
-
-       snprintf(temp_helpfile, sizeof(temp_helpfile)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
-       init_unistr( &info->helpfile, temp_helpfile );
+    if (strlen(driver.info_3->driverpath)) {
+        snprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath);             
+        init_unistr( &info->driverpath, temp );
+    } else
+        init_unistr( &info->driverpath, "" );
+    
+    if (strlen(driver.info_3->datafile)) {
+        snprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile);
+        init_unistr( &info->datafile, temp );
+    } else
+        init_unistr( &info->datafile, "" );
+
+    if (strlen(driver.info_3->configfile)) {
+        snprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile);
+        init_unistr( &info->configfile, temp );        
+    } else
+        init_unistr( &info->configfile, "" );
+
+    if (strlen(driver.info_3->helpfile)) {
+        snprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
+        init_unistr( &info->helpfile, temp );
+    } else
+        init_unistr( &info->helpfile, "" );
 
        init_unistr( &info->monitorname, driver.info_3->monitorname );
        init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
@@ -2858,10 +2915,7 @@ static uint32 construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fst
 
 static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
 {
-       pstring temp_driverpath;
-       pstring temp_datafile;
-       pstring temp_configfile;
-       pstring temp_helpfile;
+       pstring temp;
        fstring nullstr;
 
        ZERO_STRUCTP(info);
@@ -2872,18 +2926,30 @@ static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_IN
        init_unistr( &info->name, driver.info_3->name );        
        init_unistr( &info->architecture, driver.info_3->environment );
 
-       snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "\\\\%s%s", servername, driver.info_3->driverpath);                
-       init_unistr( &info->driverpath, temp_driverpath );
-
-       snprintf(temp_datafile, sizeof(temp_datafile)-1, "\\\\%s%s", servername, driver.info_3->datafile);
-       init_unistr( &info->datafile, temp_datafile );
-
-       snprintf(temp_configfile, sizeof(temp_configfile)-1, "\\\\%s%s", servername, driver.info_3->configfile);
-       init_unistr( &info->configfile, temp_configfile );      
-
-       snprintf(temp_helpfile, sizeof(temp_helpfile)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
-       init_unistr( &info->helpfile, temp_helpfile );
-
+       if (strlen(driver.info_3->driverpath)) {
+               snprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath);              
+               init_unistr( &info->driverpath, temp );
+       } else
+               init_unistr( &info->driverpath, "" );
+
+       if (strlen(driver.info_3->datafile)) {
+               snprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile);
+               init_unistr( &info->datafile, temp );
+       } else
+               init_unistr( &info->datafile, "" );
+
+       if (strlen(driver.info_3->configfile)) {
+               snprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile);
+               init_unistr( &info->configfile, temp ); 
+       } else
+               init_unistr( &info->configfile, "" );
+
+       if (strlen(driver.info_3->helpfile)) {
+               snprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
+               init_unistr( &info->helpfile, temp );
+       } else
+               init_unistr( &info->helpfile, "" );
+       
        init_unistr( &info->monitorname, driver.info_3->monitorname );
        init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
 
@@ -3384,6 +3450,42 @@ static uint32 update_printer_sec(POLICY_HND *handle, uint32 level,
 
        nt_printing_getsec(Printer->dev.handlename, &old_secdesc_ctr);
 
+       if (DEBUGLEVEL >= 10) {
+               SEC_ACL *acl;
+               int i;
+
+               acl = old_secdesc_ctr->sec->dacl;
+               DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n", 
+                          PRINTERNAME(snum), acl->num_aces));
+
+               for (i = 0; i < acl->num_aces; i++) {
+                       fstring sid_str;
+
+                       sid_to_string(sid_str, &acl->ace[i].sid);
+
+                       DEBUG(10, ("%s 0x%08x\n", sid_str, 
+                                 acl->ace[i].info.mask));
+               }
+
+               acl = secdesc_ctr->sec->dacl;
+
+               if (acl) {
+                       DEBUG(10, ("secdesc_ctr for %s has %d aces:\n", 
+                                  PRINTERNAME(snum), acl->num_aces));
+
+                       for (i = 0; i < acl->num_aces; i++) {
+                               fstring sid_str;
+                               
+                               sid_to_string(sid_str, &acl->ace[i].sid);
+                               
+                               DEBUG(10, ("%s 0x%08x\n", sid_str, 
+                                          acl->ace[i].info.mask));
+                       }
+               } else {
+                       DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
+               }
+       }
+
        new_secdesc_ctr = sec_desc_merge(secdesc_ctr, old_secdesc_ctr);
 
        if (sec_desc_equal(new_secdesc_ctr->sec, old_secdesc_ctr->sec)) {
@@ -3470,6 +3572,9 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
                        printer->info_2->location, driverlocation);
 
        unlink(tmp_file);
+
+    /* Convert script args to unix-codepage */
+    dos_to_unix(command, True);
        DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
        ret = smbrun(command, tmp_file, False);
        DEBUGADD(10,("returned [%d]\n", ret));
@@ -3480,9 +3585,10 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
        }
 
        numlines = 0;
+    /* Get lines and convert them back to dos-codepage */
        qlines = file_lines_load(tmp_file, &numlines, True);
        DEBUGADD(10,("Lines returned = [%d]\n", numlines));
-       DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
+       DEBUGADD(10,("Unlinking script output file [%s]\n", tmp_file));
        unlink(tmp_file);
 
        if(numlines) {
@@ -3501,59 +3607,74 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
 
 /* Return true if two devicemodes are equal */
 
+#define DEVMODE_CHECK_INT(field) \
+    if (d1->field != d2->field) { \
+        DEBUG(10, ("nt_devicemode_equal(): " #field " not equal (%d != %d)\n", \
+            d1->field, d2->field)); \
+        return False; \
+    }
+
 static BOOL nt_devicemode_equal(NT_DEVICEMODE *d1, NT_DEVICEMODE *d2)
 {
-       if (!d1 && !d2) return True;  /* if both are NULL they are equal */
-       if (!d1 ^  !d2) return False; /* if either is exclusively NULL are not equal */
+       if (!d1 && !d2) goto equal;  /* if both are NULL they are equal */
+
+       if (!d1 ^ !d2) {
+               DEBUG(10, ("nt_devicemode_equal(): pointers not equal\n"));
+               return False; /* if either is exclusively NULL are not equal */
+       }
 
        if (!strequal(d1->devicename, d2->devicename) ||
            !strequal(d1->formname, d2->formname)) {
+               DEBUG(10, ("nt_devicemode_equal(): device,form not equal\n"));
                return False;
        }
 
-       if (d1->specversion != d2->specversion ||
-           d1->driverversion != d2->driverversion ||
-           d1->size != d2->size ||
-           d1->driverextra != d2->driverextra ||
-           d1->orientation != d2->orientation ||
-           d1->papersize != d2->papersize ||
-           d1->paperlength != d2->paperlength ||
-           d1->paperwidth != d2->paperwidth ||
-           d1->scale != d2->scale ||
-           d1->copies != d2->copies ||
-           d1->defaultsource != d2->defaultsource ||
-           d1->printquality != d2->printquality ||
-           d1->color != d2->color ||
-           d1->duplex != d2->duplex ||
-           d1->yresolution != d2->yresolution ||
-           d1->ttoption != d2->ttoption ||
-           d1->collate != d2->collate ||
-           d1->logpixels != d2->logpixels) {
-               return False;
-       }
+       DEVMODE_CHECK_INT(specversion);
+       DEVMODE_CHECK_INT(driverversion);
+       DEVMODE_CHECK_INT(driverextra);
+       DEVMODE_CHECK_INT(orientation);
+       DEVMODE_CHECK_INT(papersize);
+       DEVMODE_CHECK_INT(paperlength);
+       DEVMODE_CHECK_INT(paperwidth);
+       DEVMODE_CHECK_INT(scale);
+       DEVMODE_CHECK_INT(copies);
+       DEVMODE_CHECK_INT(defaultsource);
+       DEVMODE_CHECK_INT(printquality);
+       DEVMODE_CHECK_INT(color);
+       DEVMODE_CHECK_INT(duplex);
+       DEVMODE_CHECK_INT(yresolution);
+       DEVMODE_CHECK_INT(ttoption);
+       DEVMODE_CHECK_INT(collate);
+       DEVMODE_CHECK_INT(logpixels);
+
+       DEVMODE_CHECK_INT(fields);
+       DEVMODE_CHECK_INT(bitsperpel);
+       DEVMODE_CHECK_INT(pelswidth);
+       DEVMODE_CHECK_INT(pelsheight);
+       DEVMODE_CHECK_INT(displayflags);
+       DEVMODE_CHECK_INT(displayfrequency);
+       DEVMODE_CHECK_INT(icmmethod);
+       DEVMODE_CHECK_INT(icmintent);
+       DEVMODE_CHECK_INT(mediatype);
+       DEVMODE_CHECK_INT(dithertype);
+       DEVMODE_CHECK_INT(reserved1);
+       DEVMODE_CHECK_INT(reserved2);
+       DEVMODE_CHECK_INT(panningwidth);
+       DEVMODE_CHECK_INT(panningheight);
+
+       /* compare the private data if it exists */
+       if (!d1->driverextra && !d2->driverextra) goto equal;
+
+
+       DEVMODE_CHECK_INT(driverextra);
 
-       if (d1->fields != d2->fields ||
-           d1->bitsperpel != d2->bitsperpel ||
-           d1->pelswidth != d2->pelswidth ||
-           d1->pelsheight != d2->pelsheight ||
-           d1->displayflags != d2->displayflags ||
-           d1->displayfrequency != d2->displayfrequency ||
-           d1->icmmethod != d2->icmmethod ||
-           d1->icmintent != d2->icmintent ||
-           d1->mediatype != d2->mediatype ||
-           d1->dithertype != d2->dithertype ||
-           d1->reserved1 != d2->reserved1 ||
-           d1->reserved2 != d2->reserved2 ||
-           d1->panningwidth != d2->panningwidth ||
-           d1->panningheight != d2->panningheight) {
+       if (memcmp(d1->private, d2->private, d1->driverextra)) {
+               DEBUG(10, ("nt_devicemode_equal(): private data not equal\n"));
                return False;
        }
 
-       /* compare the private data if it exists */
-       if (!d1->driverextra && !d2->driverextra) return True;
-       if ( d1->driverextra !=  d2->driverextra) return False;
-       if (memcmp(d1->private, d2->private, d1->driverextra)) return False;
-
+ equal:
+       DEBUG(10, ("nt_devicemode_equal(): devicemodes identical\n"));
        return True;
 }
 
@@ -3562,9 +3683,12 @@ static BOOL nt_devicemode_equal(NT_DEVICEMODE *d1, NT_DEVICEMODE *d2)
 static BOOL nt_printer_param_equal(NT_PRINTER_PARAM *p1,
                                   NT_PRINTER_PARAM *p2)
 {
-       if (!p1 && !p2) return True;
+       if (!p1 && !p2) goto equal;
 
-       if ((!p1 && p2) || (p1 && !p2)) return False;
+       if ((!p1 && p2) || (p1 && !p2)) {
+               DEBUG(10, ("nt_printer_param_equal(): pointers differ\n"));
+               return False;
+       }
 
        /* Compare lists of printer parameters */
 
@@ -3576,25 +3700,49 @@ static BOOL nt_printer_param_equal(NT_PRINTER_PARAM *p1,
 
                while(q) {
 
-                       if (strequal(p1->value, q->value) &&
-                           p1->type == q->type &&
-                           p1->data_len == q->data_len &&
-                           memcmp(p1->data, q->data, p1->data_len) == 0) {
-                               found = True;
-                               goto found_it;
+                       if (strequal(p1->value, q->value)) {
+
+                               if (p1->type != q->type) {
+                                       DEBUG(10, ("nt_printer_param_equal():"
+                                                  "types for %s differ (%d != %d)\n",
+                                                  p1->value, p1->type,
+                                                  q->type));
+                                       break;
+                               }
+
+                               if (p1->data_len != q->data_len) {
+                                       DEBUG(10, ("nt_printer_param_equal():"
+                                                  "len for %s differs (%d != %d)\n",
+                                                  p1->value, p1->data_len,
+                                                  q->data_len));
+                                       break;
+                               }
+
+                               if (memcmp(p1->data, q->data, p1->data_len) == 0) {
+                                       found = True;
+                               } else {
+                                       DEBUG(10, ("nt_printer_param_equal():"
+                                                  "data for %s differs\n", p1->value));
+                               }
+
+                               break;
                        }
 
                        q = q->next;
                }
 
-       found_it:
                if (!found) {
+                       DEBUG(10, ("nt_printer_param_equal(): param %s "
+                                  "does not exist\n", p1->value));
                        return False;
                }
 
                p1 = p1->next;
        }
 
+       equal:
+
+       DEBUG(10, ("nt_printer_param_equal(): printer params identical\n"));
        return True;
 }
 
@@ -3603,6 +3751,20 @@ static BOOL nt_printer_param_equal(NT_PRINTER_PARAM *p1,
  * actually update printer info.
  ********************************************************************/
 
+#define PI_CHECK_INT(field) \
+    if (pi1->field != pi2->field) { \
+        DEBUG(10, ("nt_printer_info_level_equal(): " #field " not equal (%d != %d)\n", \
+            pi1->field, pi2->field)); \
+        return False; \
+    }
+
+#define PI_CHECK_STR(field) \
+    if (!strequal(pi1->field, pi2->field)) { \
+        DEBUG(10, ("nt_printer_info_level_equal(): " #field " not equal (%s != %s)\n", \
+            pi1->field, pi2->field)); \
+        return False; \
+    }
+
 static BOOL nt_printer_info_level_equal(NT_PRINTER_INFO_LEVEL *p1,
                                        NT_PRINTER_INFO_LEVEL *p2)
 {
@@ -3611,12 +3773,14 @@ static BOOL nt_printer_info_level_equal(NT_PRINTER_INFO_LEVEL *p1,
        /* Trivial conditions */
 
        if ((!p1 && !p2) || (!p1->info_2 && !p2->info_2)) {
-               return True;
+               goto equal;
        }
 
        if ((!p1 && p2) || (p1 && !p2) ||
            (!p1->info_2 && p2->info_2) ||
            (p1->info_2 && !p2->info_2)) {
+               DEBUG(10, ("nt_printer_info_level_equal(): info levels "
+                          "differ\n"));
                return False;
        }
 
@@ -3627,38 +3791,32 @@ static BOOL nt_printer_info_level_equal(NT_PRINTER_INFO_LEVEL *p1,
        pi1 = p1->info_2;
        pi2 = p2->info_2;
 
-       if (pi1->attributes != pi2->attributes ||
-           pi1->priority != pi2->priority ||
-           pi1->default_priority != pi2->default_priority ||
-           pi1->starttime != pi2->starttime ||
-           pi1->untiltime != pi2->untiltime ||
-           pi1->averageppm != pi2->averageppm) {
-               return False;
-       }
+       PI_CHECK_INT(attributes);
+       PI_CHECK_INT(priority);
+       PI_CHECK_INT(default_priority);
+       PI_CHECK_INT(starttime);
+       PI_CHECK_INT(untiltime);
+       PI_CHECK_INT(averageppm);
 
        /* Yuck - don't check the printername or servername as the
           add_a_printer() code plays games with them.  You can't
           change the printername or the sharename through this interface
           in Samba. */
 
-       if (!strequal(pi1->sharename, pi2->sharename) ||
-           !strequal(pi1->portname, pi2->portname) ||
-           !strequal(pi1->drivername, pi2->drivername) ||
-           !strequal(pi1->comment, pi2->comment) ||
-           !strequal(pi1->location, pi2->location)) {
-               return False;
-       }
+       PI_CHECK_STR(sharename);
+       PI_CHECK_STR(portname);
+       PI_CHECK_STR(drivername);
+       PI_CHECK_STR(comment);
+       PI_CHECK_STR(location);
 
        if (!nt_devicemode_equal(pi1->devmode, pi2->devmode)) {
                return False;
        }
 
-       if (!strequal(pi1->sepfile, pi2->sepfile) ||
-           !strequal(pi1->printprocessor, pi2->printprocessor) ||
-           !strequal(pi1->datatype, pi2->datatype) ||
-           !strequal(pi1->parameters, pi2->parameters)) {
-               return False;
-       }
+       PI_CHECK_STR(sepfile);
+       PI_CHECK_STR(printprocessor);
+       PI_CHECK_STR(datatype);
+       PI_CHECK_STR(parameters);
 
        if (!nt_printer_param_equal(pi1->specific, pi2->specific)) {
                return False;
@@ -3668,12 +3826,12 @@ static BOOL nt_printer_info_level_equal(NT_PRINTER_INFO_LEVEL *p1,
                return False;
        }
 
-       if (pi1->changeid != pi2->changeid ||
-           pi1->c_setprinter != pi2->c_setprinter ||
-           pi1->setuptime != pi2->setuptime) {
-               return False;
-       }
+       PI_CHECK_INT(changeid);
+       PI_CHECK_INT(c_setprinter);
+       PI_CHECK_INT(setuptime);
 
+ equal:
+       DEBUG(10, ("nt_printer_info_level_equal(): infos are identical\n"));
        return True;
 }
 
@@ -4034,7 +4192,7 @@ static uint32 enumjobs_level2(print_queue_struct *queue, int snum,
                new_smb_io_job_info_2("", buffer, &info[i], 0); 
 
        /* clear memory */
-       safe_free(info);
+       free_job_info_2(info);
 
        if (*needed > offered) {
                *returned=0;
@@ -5622,8 +5780,7 @@ static uint32 getjob_level_2(print_queue_struct *queue, int count, int snum, uin
 
        new_smb_io_job_info_2("", buffer, info_2, 0);
 
-       free_dev_mode(info_2->devmode);
-       safe_free(info_2);
+       free_job_info_2(info_2);
 
        if (*needed > offered)
                return ERROR_INSUFFICIENT_BUFFER;