1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

Changes from APPLIANCE_HEAD (per Tim Potter):

- 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 commit is contained in:
David O'Neill 0001-01-01 00:00:00 +00:00
parent 8317d70a35
commit 74af3e2cae
10 changed files with 222 additions and 64 deletions

View 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_unistr.o lib/util_file.o \
lib/util.o lib/util_sock.o lib/util_sec.o smbd/ssl.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/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) $(TDB_OBJ)
UBIQX_OBJ = ubiqx/ubi_BinTree.o ubiqx/ubi_Cache.o ubiqx/ubi_SplayTree.o \ UBIQX_OBJ = ubiqx/ubi_BinTree.o ubiqx/ubi_Cache.o ubiqx/ubi_SplayTree.o \

View File

@ -93,6 +93,10 @@ SMB_OFF_T dos_file_size(char *file_name);
int dos_ChDir(char *path); int dos_ChDir(char *path);
char *dos_GetWd(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 */ /*The following definitions come from lib/fault.c */
void fault_setup(void (*fn)(void *)); 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); fstring value, uint8 **data, uint32 *type, uint32 *len);
uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr); uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr);
BOOL nt_printing_getsec(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, BOOL print_access_check(struct current_user *user, int snum, int access_type);
uint32 required_access);
BOOL print_time_access_check(int snum); BOOL print_time_access_check(int snum);
#endif #endif

View File

@ -145,13 +145,18 @@
#define PRINTER_STATUS_POWER_SAVE 0x01000000 #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_FULL_CONTROL GENERIC_ALL_ACCESS
#define PRINTER_ACE_MANAGE_DOCUMENTS READ_CONTROL_ACCESS #define PRINTER_ACE_MANAGE_DOCUMENTS READ_CONTROL_ACCESS
#define PRINTER_ACE_PRINT \ #define PRINTER_ACE_PRINT \
(GENERIC_READ_ACCESS | GENERIC_WRITE_ACCESS | GENERIC_EXECUTE_ACCESS) (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_ADMINISTER 0x00000001
#define SERVER_ACCESS_ENUMERATE 0x00000002 #define SERVER_ACCESS_ENUMERATE 0x00000002
#define PRINTER_ACCESS_ADMINISTER 0x00000004 #define PRINTER_ACCESS_ADMINISTER 0x00000004

75
source/lib/error.c Normal file
View File

@ -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;
}

View 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, BOOL print_access_check(struct current_user *user, int snum, int access_type)
uint32 required_access)
{ {
SEC_DESC_BUF *secdesc = NULL; SEC_DESC_BUF *secdesc = NULL;
uint32 access_granted, status; uint32 access_granted, status, required_access = 0;
BOOL result; BOOL result;
char *pname; char *pname;
int i; int i;
extern struct current_user current_user; extern struct current_user current_user;
/* If user is NULL then use the current_user structure */
if (!user) user = &current_user; if (!user) user = &current_user;
/* always allow root or printer admins to do anything */ /* Always allow root or printer admins to do anything */
if (user->uid==0 ||
if (user->uid == 0 ||
user_in_list(uidtoname(user->uid), lp_printer_admin(snum))) { user_in_list(uidtoname(user->uid), lp_printer_admin(snum))) {
return True; return True;
} }
/* Get printer name */ /* Get printer name */
pname = PRINTERNAME(snum); pname = PRINTERNAME(snum);
if (!pname || !*pname) if (!pname || !*pname)
pname = SERVICE(snum); pname = SERVICE(snum);
@ -2236,8 +2253,34 @@ BOOL print_access_check(struct current_user *user, int snum,
} }
/* Get printer security descriptor */ /* Get printer security descriptor */
nt_printing_getsec(pname, &secdesc); 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 /* The ACE for Full Control in a printer security descriptor
doesn't seem to map properly to the access checking model. For 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 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 performing the access check. I'm sure there is a better way to
do this! */ 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 && if (secdesc && secdesc->sec && secdesc->sec->dacl &&
secdesc->sec->dacl->ace) { secdesc->sec->dacl->ace) {
for(i = 0; i < secdesc->sec->dacl->num_aces; i++) { 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, result = se_access_check(secdesc->sec, user, required_access,
&access_granted, &status); &access_granted, &status);
/* Check access */
done:
DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE")); DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
/* Free mallocated memory */ /* Free mallocated memory */
free_sec_desc_buf(&secdesc); free_sec_desc_buf(&secdesc);
if (!result) if (!result)

View File

@ -507,7 +507,7 @@ BOOL print_job_delete(struct current_user *user, int jobid)
owns their job. */ owns their job. */
if (!owner && 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")); DEBUG(3, ("delete denied by security descriptor\n"));
return False; return False;
} }
@ -542,7 +542,7 @@ BOOL print_job_pause(struct current_user *user, int jobid)
owner = is_owner(user->uid, jobid); owner = is_owner(user->uid, jobid);
if (!owner && 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")); DEBUG(3, ("pause denied by security descriptor\n"));
return False; return False;
} }
@ -579,7 +579,7 @@ BOOL print_job_resume(struct current_user *user, int jobid)
owner = is_owner(user->uid, jobid); owner = is_owner(user->uid, jobid);
if (!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")); DEBUG(3, ("resume denied by security descriptor\n"));
return False; return False;
} }
@ -624,9 +624,9 @@ int print_job_start(struct current_user *user, int snum, char *jobname)
errno = 0; 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")); DEBUG(3, ("job start denied by security descriptor\n"));
return False; return -1;
} }
path = lp_pathname(snum); path = lp_pathname(snum);
@ -665,6 +665,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname)
/* lock the database */ /* lock the database */
tdb_writelock(tdb); tdb_writelock(tdb);
next_jobnum:
next_jobid = tdb_fetch_int(tdb, "INFO/nextjob"); next_jobid = tdb_fetch_int(tdb, "INFO/nextjob");
if (next_jobid == -1) next_jobid = 1; 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 we unlink first to cope with old spool files and also to beat
a symlink security hole - it allows us to use O_EXCL 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", slprintf(pjob.filename, sizeof(pjob.filename), "%s/%s%d",
path, PRINT_SPOOL_PREFIX, jobid); path, PRINT_SPOOL_PREFIX, jobid);
if (unlink(pjob.filename) == -1 && errno != ENOENT) { 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); pjob.fd = sys_open(pjob.filename,O_WRONLY|O_CREAT|O_EXCL,0600);
if (pjob.fd == -1) goto fail; if (pjob.fd == -1) goto fail;
print_job_store(jobid, &pjob); print_job_store(jobid, &pjob);
tdb_writeunlock(tdb);
/* /*
* If the printer is marked as postscript output a leading * If the printer is marked as postscript output a leading
* file identifier to ensure the file is treated as a raw * 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); print_job_write(jobid, "%!\n",3);
} }
tdb_writeunlock(tdb);
return jobid; return jobid;
fail: fail:
@ -896,7 +899,7 @@ BOOL print_queue_pause(struct current_user *user, int snum, int *errcode)
if (!user) return False; 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; *errcode = ERROR_ACCESS_DENIED;
return False; return False;
} }
@ -917,7 +920,7 @@ BOOL print_queue_resume(struct current_user *user, int snum, int *errcode)
{ {
int ret; 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; *errcode = ERROR_ACCESS_DENIED;
return False; return False;
} }
@ -940,14 +943,11 @@ BOOL print_queue_purge(struct current_user *user, int snum, int *errcode)
print_status_struct status; print_status_struct status;
int njobs, i; 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); njobs = print_queue_status(snum, &queue, &status);
for (i=0;i<njobs;i++) { 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); print_cache_flush(snum);

View File

@ -219,7 +219,7 @@ static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2,
pstring full_name; pstring full_name;
fstring dom_name; fstring dom_name;
fstring user; 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])); 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; uint32 rid = 0xffffffff;
int dom_idx = -1; int dom_idx = -1;
fstring name, dom_name; fstring name, dom_name;
uint8 sid_name_use = 0; enum SID_NAME_USE sid_name_use = 0;
/* Lookup sid from winbindd */ /* Lookup sid from winbindd */

View File

@ -22,7 +22,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include "includes.h" #include "includes.h"
extern int DEBUGLEVEL; extern int DEBUGLEVEL;
@ -2936,10 +2935,11 @@ uint32 _spoolss_startdocprinter(POLICY_HND *handle, uint32 level,
Printer->jobid = print_job_start(&user, snum, jobname); Printer->jobid = print_job_start(&user, snum, jobname);
/* need to map error codes properly - for now give out of /* An error occured in print_job_start() so return an appropriate
memory as I don't know the correct codes (tridge) */ NT error code. */
if (Printer->jobid == -1) { if (Printer->jobid == -1) {
return ERROR_NOT_ENOUGH_MEMORY; return map_nt_error_from_unix(errno);
} }
Printer->document_started=True; 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 descriptor. By experimentation with two NT machines, the user
requires Full Access to the printer to change security requires Full Access to the printer to change security
information. */ information. */
if (!print_access_check(&user, snum, PRINTER_ACE_FULL_CONTROL)) { if (!print_access_check(&user, snum, PRINTER_ACCESS_ADMINISTER)) {
result = ERROR_ACCESS_DENIED; result = ERROR_ACCESS_DENIED;
goto done; goto done;
} }
@ -3172,13 +3172,13 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
numlines = 0; numlines = 0;
qlines = file_lines_load(tmp_file, &numlines); qlines = file_lines_load(tmp_file, &numlines);
DEBUGADD(10,("Lines returned = [%d]\n", 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)); DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
unlink(tmp_file); unlink(tmp_file);
if(numlines) { 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)); 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); kill(0, SIGHUP);
@ -3226,7 +3226,7 @@ static uint32 update_printer(POLICY_HND *handle, uint32 level,
goto done; 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 " DEBUG(3, ("printer property change denied by security "
"descriptor\n")); "descriptor\n"));
result = ERROR_ACCESS_DENIED; result = ERROR_ACCESS_DENIED;
@ -4028,7 +4028,6 @@ static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
numlines = 0; numlines = 0;
qlines = file_lines_load(tmp_file, &numlines); qlines = file_lines_load(tmp_file, &numlines);
DEBUGADD(10,("Lines returned = [%d]\n", 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)); DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
unlink(tmp_file); unlink(tmp_file);
@ -4127,7 +4126,6 @@ static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
numlines = 0; numlines = 0;
qlines = file_lines_load(tmp_file, &numlines); qlines = file_lines_load(tmp_file, &numlines);
DEBUGADD(10,("Lines returned = [%d]\n", 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)); DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file));
unlink(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 */ /* 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); free_a_printer(&printer,2);
return ERROR_ACCESS_DENIED; return ERROR_ACCESS_DENIED;
} }
@ -4564,7 +4562,7 @@ uint32 _spoolss_setprinterdata( POLICY_HND *handle,
if (!get_printer_snum(handle, &snum)) if (!get_printer_snum(handle, &snum))
return ERROR_INVALID_HANDLE; 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 " DEBUG(3, ("security descriptor change denied by existing "
"security descriptor\n")); "security descriptor\n"));
return ERROR_ACCESS_DENIED; return ERROR_ACCESS_DENIED;

View 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), DEBUG(3,("Can't open %s - %s\n", lp_driverfile(snum),
strerror(errno))); strerror(errno)));
desc->errcode=NERR_notsupported; desc->errcode=NERR_notsupported;
return; goto done;
} }
/* lookup the long printer driver name in the file description */ /* 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)); SERVICE(snum),count));
desc->errcode=NERR_Success; desc->errcode=NERR_Success;
file_lines_free(lines); goto done;
return;
} }
err: err:
DEBUG(3,("fill_printq_info: Can't supply driver files\n")); DEBUG(3,("fill_printq_info: Can't supply driver files\n"));
desc->errcode=NERR_notsupported; desc->errcode=NERR_notsupported;
done:
safe_free(info);
file_lines_free(lines); 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 */ /* This function returns the number of files for a given driver */
static int get_printerdrivernumber(int snum) static int get_printerdrivernumber(int snum)
{ {
int i; int i, result = 0;
BOOL ok = False; BOOL ok = False;
pstring tok; pstring tok;
char *p; char *p;
@ -777,7 +779,7 @@ static int get_printerdrivernumber(int snum)
if (!lines) if (!lines)
{ {
DEBUG(3,("Can't open %s - %s\n", lp_driverfile(snum),strerror(errno))); 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 */ /* lookup the long printer driver name in the file description */
@ -800,22 +802,24 @@ static int get_printerdrivernumber(int snum)
while (*p && i) { while (*p && i) {
if (*p++ == ':') i--; if (*p++ == ':') i--;
} }
if (!*p || i) if (!*p || i) {
goto err; DEBUG(3,("Can't determine number of printer driver files\n"));
goto done;
}
/* count the number of files */ /* count the number of files */
while (next_token(&p,tok,",",sizeof(tok))) while (next_token(&p,tok,",",sizeof(tok)))
i++; i++;
file_lines_free(lines); result = i;
return(i);
} }
err: done:
DEBUG(3,("Can't determine number of printer driver files\n")); safe_free(info);
file_lines_free(lines); file_lines_free(lines);
return (0);
return result;
} }
static BOOL api_DosPrintQGetInfo(connection_struct *conn, static BOOL api_DosPrintQGetInfo(connection_struct *conn,

View File

@ -165,6 +165,8 @@ int psec_getsec(char *printer)
prs_struct ps; prs_struct ps;
int result = 0, i; int result = 0, i;
ZERO_STRUCT(ps);
/* Open tdb for reading */ /* Open tdb for reading */
slprintf(tdb_path, sizeof(tdb_path) - 1, "%s/ntdrivers.tdb", LOCKDIR); 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 (tdb) tdb_close(tdb);
if (mem_ctx) talloc_destroy(mem_ctx); if (mem_ctx) talloc_destroy(mem_ctx);
if (secdesc_ctr) free_sec_desc_buf(&secdesc_ctr); if (secdesc_ctr) free_sec_desc_buf(&secdesc_ctr);
prs_mem_free(&ps);
return result; return result;
} }
@ -252,7 +255,7 @@ int psec_setsec(char *printer)
{ {
DOM_SID user_sid, group_sid; DOM_SID user_sid, group_sid;
SEC_ACE *ace_list = NULL; SEC_ACE *ace_list = NULL;
SEC_ACL *dacl; SEC_ACL *dacl = NULL;
SEC_DESC *sd; SEC_DESC *sd;
SEC_DESC_BUF *sdb = NULL; SEC_DESC_BUF *sdb = NULL;
int result = 0, num_aces = 0; int result = 0, num_aces = 0;
@ -262,6 +265,8 @@ int psec_setsec(char *printer)
TALLOC_CTX *mem_ctx = NULL; TALLOC_CTX *mem_ctx = NULL;
BOOL has_user_sid = False, has_group_sid = False; BOOL has_user_sid = False, has_group_sid = False;
ZERO_STRUCT(ps);
/* Open tdb for reading */ /* Open tdb for reading */
slprintf(tdb_path, sizeof(tdb_path) - 1, "%s/ntdrivers.tdb", LOCKDIR); slprintf(tdb_path, sizeof(tdb_path) - 1, "%s/ntdrivers.tdb", LOCKDIR);
@ -327,6 +332,8 @@ int psec_setsec(char *printer)
dacl, /* Discretionary ACL */ dacl, /* Discretionary ACL */
&size); &size);
free_sec_acl(&dacl);
sdb = make_sec_desc_buf(size, sd); sdb = make_sec_desc_buf(size, sd);
free_sec_desc(&sd); free_sec_desc(&sd);
@ -360,6 +367,7 @@ int psec_setsec(char *printer)
if (tdb) tdb_close(tdb); if (tdb) tdb_close(tdb);
if (sdb) free_sec_desc_buf(&sdb); if (sdb) free_sec_desc_buf(&sdb);
if (mem_ctx) talloc_destroy(mem_ctx); if (mem_ctx) talloc_destroy(mem_ctx);
prs_mem_free(&ps);
return result; return result;
} }