Changes from APPLIANCE_HEAD (per Tim Potter):
authorDavid O'Neill <dmo@samba.org>
Fri, 1 Sep 2000 18:49:26 +0000 (18:49 +0000)
committerDavid O'Neill <dmo@samba.org>
Fri, 1 Sep 2000 18:49:26 +0000 (18:49 +0000)
- make proto
- addition of function to convert from errno values to NT status codes
  (source/lib/error.c)
- purge queue done without full access permission will purge only the
  jobs owned by that user, rather than failing.
- unlock job database tdb before sending job to printer
- in print_job_start(), ensure that we don't pick a jobid with an existing
  temporary file that may be owned by another user, as it causes silent
  failures.
- fixes for printer permission checking for NT5 clients
  (source/include/rpc_spoolss.h, source/printing/nt_printing.c,
   source/printing/printing.c, source/rpc_server/srv_spoolss_nt.c)
- change from uint8 to 'enum SID_NAME_USE' (source/rpc_server/srv_lsa.c)
- fixed memory leaks for win95 driver download process
  (source/smbd/lanman.c)
- properly free prs_structs and dacl in testsuite/printing/psec.c
(This used to be commit 74af3e2caec7197e5d1ca389e2f78054a4197502)

source3/Makefile.in
source3/include/proto.h
source3/include/rpc_spoolss.h
source3/lib/error.c [new file with mode: 0644]
source3/printing/nt_printing.c
source3/printing/printing.c
source3/rpc_server/srv_lsa.c
source3/rpc_server/srv_spoolss_nt.c
source3/smbd/lanman.c
testsuite/printing/psec.c

index 4e9475ea94dc703f9ab163a36c5ee83d4f23294d..018086b40b23f84d75777f7624b40f347db05954 100644 (file)
@@ -108,7 +108,7 @@ LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \
          lib/util_unistr.o lib/util_file.o \
          lib/util.o lib/util_sock.o lib/util_sec.o smbd/ssl.o \
          lib/talloc.o lib/hash.o lib/substitute.o lib/fsusage.o \
-         lib/ms_fnmatch.o lib/select.o \
+         lib/ms_fnmatch.o lib/select.o lib/error.o \
          $(TDB_OBJ)
 
 UBIQX_OBJ = ubiqx/ubi_BinTree.o ubiqx/ubi_Cache.o ubiqx/ubi_SplayTree.o \
index 38393e3de8c3c57038daac1e4614dc5fcc9038ba..9d239d38fda140f356499d96d0f159fb053125f3 100644 (file)
@@ -93,6 +93,10 @@ SMB_OFF_T dos_file_size(char *file_name);
 int dos_ChDir(char *path);
 char *dos_GetWd(char *path);
 
+/*The following definitions come from  lib/error.c  */
+
+uint32 map_nt_error_from_unix(int unix_error);
+
 /*The following definitions come from  lib/fault.c  */
 
 void fault_setup(void (*fn)(void *));
@@ -1709,8 +1713,7 @@ BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
                         fstring value, uint8 **data, uint32 *type, uint32 *len);
 uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr);
 BOOL nt_printing_getsec(char *printername, SEC_DESC_BUF **secdesc_ctr);
-BOOL print_access_check(struct current_user *user, int snum,
-                       uint32 required_access);
+BOOL print_access_check(struct current_user *user, int snum, int access_type);
 BOOL print_time_access_check(int snum);
 #endif
 
index a77ce55063c6a598635f85f9a56761bcc0b995e0..eb521a5b9472e5faa2dfa9348192fcf038aa163e 100755 (executable)
 
 #define PRINTER_STATUS_POWER_SAVE      0x01000000
 
-/* Printer permissions ACE settings */
+/* Printer permissions ACE settings.  NT4 uses generic and standard access
+   rights whereas NT5 converts them all to object specific access rights. */
 
 #define PRINTER_ACE_FULL_CONTROL      GENERIC_ALL_ACCESS
 #define PRINTER_ACE_MANAGE_DOCUMENTS  READ_CONTROL_ACCESS
 #define PRINTER_ACE_PRINT             \
     (GENERIC_READ_ACCESS | GENERIC_WRITE_ACCESS | GENERIC_EXECUTE_ACCESS)
 
+#define PRINTER_ACE_NT5_FULL_CONTROL     0x000f000c
+#define PRINTER_ACE_NT5_PRINT            0x00020000
+#define PRINTER_ACE_NT5_MANAGE_DOCUMENTS 0x00020008
+
 #define SERVER_ACCESS_ADMINISTER       0x00000001
 #define SERVER_ACCESS_ENUMERATE                0x00000002
 #define PRINTER_ACCESS_ADMINISTER      0x00000004
diff --git a/source3/lib/error.c b/source3/lib/error.c
new file mode 100644 (file)
index 0000000..880eba5
--- /dev/null
@@ -0,0 +1,75 @@
+/* 
+ *  Unix SMB/Netbios implementation.
+ *  Version 1.9
+ *  Unix/DOS/NT error code conversions
+ *  Copyright (C) Tim Potter 2000
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+
+/* Mapping between Unix, DOS and NT error numbers */
+
+struct {
+       int unix_error;
+       int dos_error;
+       uint32 nt_error;
+} unix_dos_nt_errmap[] = {
+       { EPERM, ERRnoaccess, NT_STATUS_ACCESS_DENIED },
+       { EACCES, ERRnoaccess, NT_STATUS_ACCESS_DENIED },
+       { ENOENT, ERRbadfile, NT_STATUS_NO_SUCH_FILE },
+       { ENOTDIR, ERRbadpath, NT_STATUS_NOT_A_DIRECTORY },
+       { EIO, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR },
+       { EBADF, ERRsrverror, NT_STATUS_INVALID_HANDLE },
+       { EINVAL, ERRsrverror, NT_STATUS_INVALID_HANDLE },
+       { EEXIST, ERRfilexists, NT_STATUS_ACCESS_DENIED},
+       { ENFILE, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES },
+       { EMFILE, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES },
+       { ENOSPC, ERRdiskfull, NT_STATUS_DISK_FULL },
+#ifdef EDQUOT
+       { EDQUOT, ERRdiskfull, NT_STATUS_DISK_FULL },
+#endif
+#ifdef ENOTEMPTY
+       { ENOTEMPTY, ERRnoaccess, NT_STATUS_DIRECTORY_NOT_EMPTY },
+#endif
+#ifdef EXDEV
+       { EXDEV, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE },
+#endif
+       { EROFS, ERRnowrite, NT_STATUS_ACCESS_DENIED },
+
+       { 0, 0, 0 }
+};
+
+/* Map an NT error code from a Unix error code */
+
+uint32 map_nt_error_from_unix(int unix_error)
+{
+       int i = 0;
+
+       /* Look through list */
+
+       while(unix_dos_nt_errmap[i].unix_error != 0) {
+               if (unix_dos_nt_errmap[i].unix_error == unix_error) {
+                       return unix_dos_nt_errmap[i].nt_error;
+               }
+
+               i++;
+       }
+
+       /* Default return */
+
+       return NT_STATUS_ACCESS_DENIED;
+}
index 05ab71d178c4cb74799caabc895d5e5fb5849c11..0ad50a227763db0ccc9c763232c9f7d9ef44f9e6 100644 (file)
@@ -2203,30 +2203,47 @@ jfm: I should use this comment for the text file to explain
 */
 
 /****************************************************************************
- Check a user has permissions to perform the given operation 
+ Check a user has permissions to perform the given operation.  We use some
+ constants defined in include/rpc_spoolss.h that look relevant to check
+ the various actions we perform when checking printer access.
+
+   PRINTER_ACCESS_ADMINISTER:
+       print_queue_pause, print_queue_resume, update_printer_sec,
+       update_printer, spoolss_addprinterex_level_2,
+       _spoolss_setprinterdata
+        
+   PRINTER_ACCESS_USE:
+       print_job_start
+
+   JOB_ACCESS_ADMINISTER:
+       print_job_delete, print_job_pause, print_job_resume,
+       print_queue_purge
 
-   if user is NULL then use the current_user structure
  ****************************************************************************/
-BOOL print_access_check(struct current_user *user, int snum,
-                       uint32 required_access)
+BOOL print_access_check(struct current_user *user, int snum, int access_type)
 {
        SEC_DESC_BUF *secdesc = NULL;
-       uint32 access_granted, status;
+       uint32 access_granted, status, required_access = 0;
        BOOL result;
        char *pname;
        int i;
        extern struct current_user current_user;
        
+       /* If user is NULL then use the current_user structure */
+
        if (!user) user = &current_user;
 
-       /* always allow root or printer admins to do anything */
-       if (user->uid==0 ||
+       /* Always allow root or printer admins to do anything */
+
+       if (user->uid == 0 ||
            user_in_list(uidtoname(user->uid), lp_printer_admin(snum))) {
                return True;
        }
 
        /* Get printer name */
+
        pname = PRINTERNAME(snum);
+
        if (!pname || !*pname)
                pname = SERVICE(snum);
 
@@ -2236,8 +2253,34 @@ BOOL print_access_check(struct current_user *user, int snum,
        }
 
        /* Get printer security descriptor */
+
        nt_printing_getsec(pname, &secdesc);
 
+       /* Check against NT4 ACE mask values.  From observation these
+          values are:
+
+              Access Type       ACE Mask    Constant
+              -------------------------------------
+              Full Control      0x10000000  PRINTER_ACE_FULL_CONTROL
+              Print             0xe0000000  PRINTER_ACE_PRINT
+              Manage Documents  0x00020000  PRINTER_ACE_MANAGE_DOCUMENTS
+       */
+
+       switch (access_type) {
+       case PRINTER_ACCESS_USE:
+               required_access = PRINTER_ACE_PRINT;
+               break;
+       case PRINTER_ACCESS_ADMINISTER:
+               required_access = PRINTER_ACE_MANAGE_DOCUMENTS | 
+                       PRINTER_ACE_PRINT;
+               break;
+       case JOB_ACCESS_ADMINISTER:
+               required_access = PRINTER_ACE_MANAGE_DOCUMENTS;
+       default:
+               DEBUG(0, ("invalid value passed to print_access_check()\n"));
+               return False;
+       }       
+
        /* The ACE for Full Control in a printer security descriptor
           doesn't seem to map properly to the access checking model.  For
           it to work properly it should be the logical OR of all the other
@@ -2249,16 +2292,6 @@ BOOL print_access_check(struct current_user *user, int snum,
           performing the access check.  I'm sure there is a better way to
           do this! */
 
-       /* You forgot to also change the *required access* from PRINTER_ACE_FULL_CONTROL
-               to PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT before doing the check.
-               This took me 3 hours to find !!!!! JRA.
-       */
-
-       if (required_access & PRINTER_ACE_FULL_CONTROL) {
-               required_access |= (PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT);
-               required_access &= ~PRINTER_ACE_FULL_CONTROL;
-       }
-
        if (secdesc && secdesc->sec && secdesc->sec->dacl &&
            secdesc->sec->dacl->ace) {
                for(i = 0; i < secdesc->sec->dacl->num_aces; i++) {
@@ -2271,14 +2304,46 @@ BOOL print_access_check(struct current_user *user, int snum,
                }
        }
 
-       /* Check access */
+       if ((result = se_access_check(secdesc->sec, user, required_access, 
+                                     &access_granted, &status))) {
+               goto done;
+       }
+
+       /* Check against NT5 ACE mask values.  From observation these
+          values are:
+
+              Access Type       ACE Mask    Constant
+              -------------------------------------
+              Full Control      0x000f000c  PRINTER_ACE_NT5_FULL_CONTROL
+              Print             0x00020008  PRINTER_ACE_NT5_PRINT
+              Manage Documents  0x00020000  PRINTER_ACE_NT5_MANAGE_DOCUMENTS
+
+          NT5 likes to rewrite the security descriptor and change the ACE
+          masks from NT4 format to NT5 format making them unreadable by
+          NT4 clients. */
+
+       switch (access_type) {
+       case PRINTER_ACCESS_USE:
+               required_access = PRINTER_ACE_NT5_PRINT;
+               break;
+       case PRINTER_ACCESS_ADMINISTER:
+               required_access = PRINTER_ACE_NT5_FULL_CONTROL;
+               break;
+       case JOB_ACCESS_ADMINISTER:
+               required_access = PRINTER_ACE_NT5_MANAGE_DOCUMENTS;
+               break;
+       }       
 
        result = se_access_check(secdesc->sec, user, required_access, 
                                 &access_granted, &status);
 
+       /* Check access */
+       
+ done:
        DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
-
+       
        /* Free mallocated memory */
+
        free_sec_desc_buf(&secdesc);
 
        if (!result)
index cf3748ed161efa90396bc1ef6fa8fd26f1033a51..406cbf2c8009d6ebe579c111102c4cce25a24857 100644 (file)
@@ -507,7 +507,7 @@ BOOL print_job_delete(struct current_user *user, int jobid)
           owns their job. */
 
        if (!owner && 
-           !print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) {
+           !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
                DEBUG(3, ("delete denied by security descriptor\n"));
                return False;
        }
@@ -542,7 +542,7 @@ BOOL print_job_pause(struct current_user *user, int jobid)
        owner = is_owner(user->uid, jobid);
 
        if (!owner &&
-           !print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) {
+           !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
                DEBUG(3, ("pause denied by security descriptor\n"));
                return False;
        }
@@ -579,7 +579,7 @@ BOOL print_job_resume(struct current_user *user, int jobid)
        owner = is_owner(user->uid, jobid);
 
        if (!is_owner(user->uid, jobid) &&
-           !print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) {
+           !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
                DEBUG(3, ("resume denied by security descriptor\n"));
                return False;
        }
@@ -624,9 +624,9 @@ int print_job_start(struct current_user *user, int snum, char *jobname)
 
        errno = 0;
 
-       if (!print_access_check(user, snum, PRINTER_ACE_PRINT)) {
+       if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
                DEBUG(3, ("job start denied by security descriptor\n"));
-               return False;
+               return -1;
        }
 
        path = lp_pathname(snum);
@@ -665,6 +665,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname)
        /* lock the database */
        tdb_writelock(tdb);
 
+ next_jobnum:
        next_jobid = tdb_fetch_int(tdb, "INFO/nextjob");
        if (next_jobid == -1) next_jobid = 1;
 
@@ -684,17 +685,20 @@ int print_job_start(struct current_user *user, int snum, char *jobname)
 
           we unlink first to cope with old spool files and also to beat
           a symlink security hole - it allows us to use O_EXCL 
+          There may be old spool files owned by other users lying around.
        */
        slprintf(pjob.filename, sizeof(pjob.filename), "%s/%s%d", 
                 path, PRINT_SPOOL_PREFIX, jobid);
        if (unlink(pjob.filename) == -1 && errno != ENOENT) {
-               goto fail;
+               goto next_jobnum;
        }
        pjob.fd = sys_open(pjob.filename,O_WRONLY|O_CREAT|O_EXCL,0600);
        if (pjob.fd == -1) goto fail;
 
        print_job_store(jobid, &pjob);
 
+       tdb_writeunlock(tdb);
+
        /*
         * If the printer is marked as postscript output a leading
         * file identifier to ensure the file is treated as a raw
@@ -706,7 +710,6 @@ int print_job_start(struct current_user *user, int snum, char *jobname)
                print_job_write(jobid, "%!\n",3);
        }
 
-       tdb_writeunlock(tdb);
        return jobid;
 
  fail:
@@ -896,7 +899,7 @@ BOOL print_queue_pause(struct current_user *user, int snum, int *errcode)
        
        if (!user) return False;
        
-       if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) {
+       if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
                *errcode = ERROR_ACCESS_DENIED;
                return False;
        }
@@ -917,7 +920,7 @@ BOOL print_queue_resume(struct current_user *user, int snum, int *errcode)
 {
        int ret;
 
-       if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) {
+       if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
                *errcode = ERROR_ACCESS_DENIED;
                return False;
        }
@@ -940,14 +943,11 @@ BOOL print_queue_purge(struct current_user *user, int snum, int *errcode)
        print_status_struct status;
        int njobs, i;
 
-       if (!print_access_check(user, snum, PRINTER_ACE_MANAGE_DOCUMENTS)) {
-               *errcode = ERROR_ACCESS_DENIED;
-               return False;
-       }
-
        njobs = print_queue_status(snum, &queue, &status);
        for (i=0;i<njobs;i++) {
-               print_job_delete1(queue[i].job);
+               if (print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
+                       print_job_delete1(queue[i].job);
+               }
        }
 
        print_cache_flush(snum);
index f37bb249ba4fb1ba448a77d6394805f0d2735b49..a7abc614e37cb158c6ab5c4acd05871aa932e970 100644 (file)
@@ -219,7 +219,7 @@ static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2,
                pstring full_name;
                fstring dom_name;
                fstring user;
-               uint8 sid_name_use = SID_NAME_UNKNOWN;
+               enum SID_NAME_USE sid_name_use = SID_NAME_UNKNOWN;
 
                pstrcpy(full_name, dos_unistr2_to_str(&name[i]));
 
@@ -298,7 +298,7 @@ static void init_lsa_trans_names(DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *trn,
                uint32 rid = 0xffffffff;
                int dom_idx = -1;
                fstring name, dom_name;
-               uint8 sid_name_use = 0;
+               enum SID_NAME_USE sid_name_use = 0;
 
                /* Lookup sid from winbindd */
 
index 0938b37ab340e205bfa6054e8bdb27a0225fadac..1f19be1188d3538215cd84be05e52fac7fc266f1 100644 (file)
@@ -22,7 +22,6 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-
 #include "includes.h"
 
 extern int DEBUGLEVEL;
@@ -2936,10 +2935,11 @@ uint32 _spoolss_startdocprinter(POLICY_HND *handle, uint32 level,
        
        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;
@@ -3082,7 +3082,7 @@ static uint32 update_printer_sec(POLICY_HND *handle, uint32 level,
           descriptor.  By experimentation with two NT machines, the user
           requires Full Access to the printer to change security
           information. */ 
-       if (!print_access_check(&user, snum, PRINTER_ACE_FULL_CONTROL)) {
+       if (!print_access_check(&user, snum, PRINTER_ACCESS_ADMINISTER)) {
                result = ERROR_ACCESS_DENIED;
                goto done;
        }
@@ -3172,13 +3172,13 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
        numlines = 0;
        qlines = file_lines_load(tmp_file, &numlines);
        DEBUGADD(10,("Lines returned = [%d]\n", numlines));
-       DEBUGADD(10,("Line[0] = [%s]\n", qlines[0]));
        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);
@@ -3226,7 +3226,7 @@ static uint32 update_printer(POLICY_HND *handle, uint32 level,
                goto done;
        }
 
-       if (!print_access_check(NULL, snum, PRINTER_ACE_FULL_CONTROL)) {
+       if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
                DEBUG(3, ("printer property change denied by security "
                          "descriptor\n"));
                result = ERROR_ACCESS_DENIED;
@@ -4028,7 +4028,6 @@ static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
                numlines = 0;
                qlines = file_lines_load(tmp_file, &numlines);
                DEBUGADD(10,("Lines returned = [%d]\n", numlines));
-               DEBUGADD(10,("Line[0] = [%s]\n", qlines[0]));
                DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
                unlink(tmp_file);
 
@@ -4127,7 +4126,6 @@ static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
                numlines = 0;
                qlines = file_lines_load(tmp_file, &numlines);
                DEBUGADD(10,("Lines returned = [%d]\n", numlines));
-               DEBUGADD(10,("Line[0] = [%s]\n", qlines[0]));
                DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
                unlink(tmp_file);
 
@@ -4247,7 +4245,7 @@ static uint32 spoolss_addprinterex_level_2( const UNISTR2 *uni_srv_name,
        }
 
        /* you must be a printer admin to add a new printer */
-       if (!print_access_check(NULL, snum, PRINTER_ACE_FULL_CONTROL)) {
+       if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
                free_a_printer(&printer,2);
                return ERROR_ACCESS_DENIED;             
        }
@@ -4564,7 +4562,7 @@ uint32 _spoolss_setprinterdata( POLICY_HND *handle,
        if (!get_printer_snum(handle, &snum))
                return ERROR_INVALID_HANDLE;
 
-       if (!print_access_check(NULL, snum, PRINTER_ACE_FULL_CONTROL)) {
+       if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
                DEBUG(3, ("security descriptor change denied by existing "
                          "security descriptor\n"));
                return ERROR_ACCESS_DENIED;
index 6595163ba9e7a28323ff0028014f28b51cbdbc79..54bfa3155b75fbb7892fe08267d467f16786cb49 100644 (file)
@@ -540,7 +540,7 @@ static void fill_printq_info_52(connection_struct *conn, int snum, int uLevel,
                        DEBUG(3,("Can't open %s - %s\n", lp_driverfile(snum),
                                  strerror(errno)));
                        desc->errcode=NERR_notsupported;
-                       return;
+                       goto done;
                } 
 
                /* lookup the long printer driver name in the file description */
@@ -651,14 +651,16 @@ static void fill_printq_info_52(connection_struct *conn, int snum, int uLevel,
                          SERVICE(snum),count));
 
                desc->errcode=NERR_Success;
-               file_lines_free(lines);
-               return;
+               goto done;
        }
 
   err:
 
        DEBUG(3,("fill_printq_info: Can't supply driver files\n"));
        desc->errcode=NERR_notsupported;
+
+ done:
+       safe_free(info);
        file_lines_free(lines); 
 }
 
@@ -741,7 +743,7 @@ static void fill_printq_info(connection_struct *conn, int snum, int uLevel,
 /* This function returns the number of files for a given driver */
 static int get_printerdrivernumber(int snum)
 {
-       int i;
+       int i, result = 0;
        BOOL ok = False;
        pstring tok;
        char *p;
@@ -777,7 +779,7 @@ static int get_printerdrivernumber(int snum)
                if (!lines) 
                {
                        DEBUG(3,("Can't open %s - %s\n", lp_driverfile(snum),strerror(errno)));
-                       return 0;
+                       goto done;
                } 
 
                /* lookup the long printer driver name in the file description */
@@ -800,22 +802,24 @@ static int get_printerdrivernumber(int snum)
                while (*p && i) {
                        if (*p++ == ':') i--;
                }
-               if (!*p || i)
-                       goto err;
+               if (!*p || i) {
+                       DEBUG(3,("Can't determine number of printer driver files\n"));
+                       goto done;
+               }
                
                /* count the number of files */
                while (next_token(&p,tok,",",sizeof(tok)))
                        i++;
        
-               file_lines_free(lines);
-               return(i);
+               result = i;
        }
 
 err:
done:
 
-       DEBUG(3,("Can't determine number of printer driver files\n"));
+       safe_free(info);
        file_lines_free(lines);
-       return (0);
+
+       return result;
 }
 
 static BOOL api_DosPrintQGetInfo(connection_struct *conn,
index 28c4ee0ca51709f45c9a152598bb9d82382a383a..9b1fc7c46c471ae8e1ba1cf7fa4048fe0d4cde3d 100644 (file)
@@ -165,6 +165,8 @@ int psec_getsec(char *printer)
        prs_struct ps;
        int result = 0, i;
 
+       ZERO_STRUCT(ps);
+
        /* Open tdb for reading */
 
        slprintf(tdb_path, sizeof(tdb_path) - 1, "%s/ntdrivers.tdb", LOCKDIR);
@@ -242,6 +244,7 @@ int psec_getsec(char *printer)
        if (tdb) tdb_close(tdb);
        if (mem_ctx) talloc_destroy(mem_ctx);
        if (secdesc_ctr) free_sec_desc_buf(&secdesc_ctr);
+       prs_mem_free(&ps);
 
        return result;
 }
@@ -252,7 +255,7 @@ int psec_setsec(char *printer)
 {
        DOM_SID user_sid, group_sid;
        SEC_ACE *ace_list = NULL;
-       SEC_ACL *dacl;
+       SEC_ACL *dacl = NULL;
        SEC_DESC *sd;
        SEC_DESC_BUF *sdb = NULL;
        int result = 0, num_aces = 0;
@@ -262,6 +265,8 @@ int psec_setsec(char *printer)
        TALLOC_CTX *mem_ctx = NULL;
        BOOL has_user_sid = False, has_group_sid = False;
 
+       ZERO_STRUCT(ps);
+
        /* Open tdb for reading */
 
        slprintf(tdb_path, sizeof(tdb_path) - 1, "%s/ntdrivers.tdb", LOCKDIR);
@@ -327,6 +332,8 @@ int psec_setsec(char *printer)
                           dacl, /* Discretionary ACL */
                           &size);
 
+       free_sec_acl(&dacl);
+
        sdb = make_sec_desc_buf(size, sd);
 
        free_sec_desc(&sd);
@@ -360,6 +367,7 @@ int psec_setsec(char *printer)
        if (tdb) tdb_close(tdb);
        if (sdb) free_sec_desc_buf(&sdb);
        if (mem_ctx) talloc_destroy(mem_ctx);
+       prs_mem_free(&ps);
 
        return result;
 }