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:
parent
8317d70a35
commit
74af3e2cae
@ -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 \
|
||||
|
@ -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
|
||||
|
||||
|
@ -145,13 +145,18 @@
|
||||
|
||||
#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
|
||||
|
75
source/lib/error.c
Normal file
75
source/lib/error.c
Normal 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;
|
||||
}
|
@ -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 = ¤t_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)
|
||||
|
@ -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,15 +943,12 @@ 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++) {
|
||||
if (print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
|
||||
print_job_delete1(queue[i].job);
|
||||
}
|
||||
}
|
||||
|
||||
print_cache_flush(snum);
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user