mirror of
https://github.com/samba-team/samba.git
synced 2025-02-24 13:57:43 +03:00
added printer admin option
any user in that list can do anything to a printer
This commit is contained in:
parent
39d025693e
commit
7b5912be15
@ -1461,6 +1461,7 @@ char *lp_force_user(int );
|
||||
char *lp_force_group(int );
|
||||
char *lp_readlist(int );
|
||||
char *lp_writelist(int );
|
||||
char *lp_printer_admin(int );
|
||||
char *lp_fstype(int );
|
||||
char *lp_vfsobj(int );
|
||||
char *lp_mangled_map(int );
|
||||
@ -1734,6 +1735,7 @@ void print_fsp_end(files_struct *fsp);
|
||||
|
||||
/*The following definitions come from printing/printing.c */
|
||||
|
||||
#if OLD_NTDOMAIN
|
||||
BOOL print_backend_init(void);
|
||||
BOOL print_job_exists(int jobid);
|
||||
int print_job_snum(int jobid);
|
||||
@ -1754,6 +1756,7 @@ int print_queue_snum(char *qname);
|
||||
BOOL print_queue_pause(struct current_user *user, int snum);
|
||||
BOOL print_queue_resume(struct current_user *user, int snum);
|
||||
BOOL print_queue_purge(struct current_user *user, int snum);
|
||||
#endif
|
||||
|
||||
/*The following definitions come from profile/profile.c */
|
||||
|
||||
|
@ -308,6 +308,7 @@ typedef struct
|
||||
char *force_group;
|
||||
char *readlist;
|
||||
char *writelist;
|
||||
char *printer_admin;
|
||||
char *volume;
|
||||
char *fstype;
|
||||
char *szVfsObjectFile;
|
||||
@ -420,6 +421,7 @@ static service sDefault = {
|
||||
NULL, /* force group */
|
||||
NULL, /* readlist */
|
||||
NULL, /* writelist */
|
||||
NULL, /* printer admin */
|
||||
NULL, /* volume */
|
||||
NULL, /* fstype */
|
||||
NULL, /* vfs object */
|
||||
@ -669,6 +671,7 @@ static struct parm_struct parm_table[] = {
|
||||
{"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
|
||||
{"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
|
||||
{"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
|
||||
{"printer admin", P_STRING, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
|
||||
{"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_SHARE},
|
||||
{"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_SHARE},
|
||||
{"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
|
||||
@ -1495,6 +1498,7 @@ FN_LOCAL_STRING(lp_force_user, force_user)
|
||||
FN_LOCAL_STRING(lp_force_group, force_group)
|
||||
FN_LOCAL_STRING(lp_readlist, readlist)
|
||||
FN_LOCAL_STRING(lp_writelist, writelist)
|
||||
FN_LOCAL_STRING(lp_printer_admin, printer_admin)
|
||||
FN_LOCAL_STRING(lp_fstype, fstype)
|
||||
FN_LOCAL_STRING(lp_vfsobj, szVfsObjectFile)
|
||||
static FN_LOCAL_STRING(lp_volume, volume)
|
||||
|
@ -2122,8 +2122,11 @@ 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
|
||||
|
||||
if user is NULL then use the current_user structure
|
||||
****************************************************************************/
|
||||
BOOL print_access_check(struct current_user *user, int snum,
|
||||
uint32 required_access)
|
||||
{
|
||||
@ -2132,14 +2135,23 @@ BOOL print_access_check(struct current_user *user, int snum,
|
||||
BOOL result;
|
||||
char *pname;
|
||||
int i;
|
||||
extern struct current_user current_user;
|
||||
|
||||
/* Get printer name */
|
||||
if (!user) user = ¤t_user;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Get printer security descriptor */
|
||||
if (!pname || !*pname) return False;
|
||||
|
||||
/* Get printer security descriptor */
|
||||
nt_printing_getsec(pname, &secdesc);
|
||||
|
||||
/* The ACE for Full Control in a printer security descriptor
|
||||
@ -2173,7 +2185,6 @@ BOOL print_access_check(struct current_user *user, int snum,
|
||||
DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
|
||||
|
||||
/* Free mallocated memory */
|
||||
|
||||
free_sec_desc_buf(&secdesc);
|
||||
|
||||
return result;
|
||||
@ -2208,4 +2219,5 @@ BOOL print_time_access_check(int snum)
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
#undef OLD_NTDOMAIN
|
||||
|
@ -1,3 +1,4 @@
|
||||
#define OLD_NTDOMAIN 1
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 3.0
|
||||
@ -948,3 +949,4 @@ BOOL print_queue_purge(struct current_user *user, int snum)
|
||||
|
||||
return True;
|
||||
}
|
||||
#undef OLD_NTDOMAIN
|
||||
|
@ -3049,19 +3049,18 @@ static uint32 update_printer_sec(POLICY_HND *handle, uint32 level,
|
||||
const SPOOL_PRINTER_INFO_LEVEL *info,
|
||||
pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
|
||||
{
|
||||
SEC_DESC_BUF *old_secdesc_ctr = NULL;
|
||||
struct current_user user;
|
||||
uint32 acc_granted, status, result;
|
||||
uint32 result;
|
||||
int snum;
|
||||
|
||||
Printer_entry *Printer = find_printer_index_by_hnd(handle);
|
||||
|
||||
if (!OPEN_HANDLE(Printer)) {
|
||||
if (!OPEN_HANDLE(Printer) || !get_printer_snum(handle, &snum)) {
|
||||
DEBUG(0,("update_printer_sec: Invalid handle (%s)\n", OUR_HANDLE(handle)));
|
||||
return ERROR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
/* Work out which user is performing the operation */
|
||||
|
||||
if (p->ntlmssp_auth_validated) {
|
||||
memcpy(&user, &p->pipe_user, sizeof(user));
|
||||
} else {
|
||||
@ -3069,32 +3068,18 @@ static uint32 update_printer_sec(POLICY_HND *handle, uint32 level,
|
||||
memcpy(&user, ¤t_user, sizeof(user));
|
||||
}
|
||||
|
||||
/* Get old security descriptor */
|
||||
|
||||
if (!nt_printing_getsec(Printer->dev.handlename, &old_secdesc_ctr)) {
|
||||
DEBUG(3, ("could not get old security descriptor for "
|
||||
"printer %s", Printer->dev.handlename));
|
||||
return ERROR_INVALID_FUNCTION;
|
||||
}
|
||||
|
||||
/* Check the user has permissions to change the security
|
||||
descriptor. By experimentation with two NT machines, the user
|
||||
requires Full Access to the printer to change security
|
||||
information. */
|
||||
|
||||
if (!se_access_check(old_secdesc_ctr->sec, &user,
|
||||
PRINTER_ACE_FULL_CONTROL, &acc_granted,
|
||||
&status)) {
|
||||
DEBUG(3, ("security descriptor change denied by existing "
|
||||
"security descriptor\n"));
|
||||
result = status;
|
||||
if (!print_access_check(&user, snum, PRINTER_ACE_FULL_CONTROL)) {
|
||||
result = NT_STATUS_ACCESS_DENIED;
|
||||
goto done;
|
||||
}
|
||||
|
||||
result = nt_printing_setsec(Printer->dev.handlename, secdesc_ctr);
|
||||
|
||||
done:
|
||||
free_sec_desc_buf(&old_secdesc_ctr);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -3144,9 +3129,7 @@ static uint32 update_printer(POLICY_HND *handle, uint32 level,
|
||||
int snum;
|
||||
NT_PRINTER_INFO_LEVEL *printer = NULL;
|
||||
Printer_entry *Printer = find_printer_index_by_hnd(handle);
|
||||
SEC_DESC_BUF *sd = NULL;
|
||||
uint32 result, acc_granted;
|
||||
extern struct current_user current_user;
|
||||
uint32 result;
|
||||
|
||||
DEBUG(8,("update_printer\n"));
|
||||
|
||||
@ -3154,22 +3137,6 @@ static uint32 update_printer(POLICY_HND *handle, uint32 level,
|
||||
|
||||
/* Check calling user has permission to update printer description */
|
||||
|
||||
#if 0 /* JFMTEST */
|
||||
if (!nt_printing_getsec(Printer->dev.handlename, &sd)) {
|
||||
DEBUG(3, ("Could not get security descriptor for printer %s",
|
||||
Printer->dev.handlename));
|
||||
result = ERROR_INVALID_FUNCTION;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!se_access_check(sd->sec, ¤t_user,
|
||||
PRINTER_ACE_FULL_CONTROL, &acc_granted,
|
||||
&result)) {
|
||||
DEBUG(3, ("printer property change denied by security "
|
||||
"descriptor\n"));
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
if (level!=2) {
|
||||
DEBUG(0,("Send a mail to samba@samba.org\n"));
|
||||
DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
|
||||
@ -3186,6 +3153,13 @@ static uint32 update_printer(POLICY_HND *handle, uint32 level,
|
||||
result = ERROR_INVALID_HANDLE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!print_access_check(NULL, snum, PRINTER_ACE_FULL_CONTROL)) {
|
||||
DEBUG(3, ("printer property change denied by security "
|
||||
"descriptor\n"));
|
||||
result = NT_STATUS_ACCESS_DENIED;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0) {
|
||||
result = ERROR_INVALID_HANDLE;
|
||||
@ -3240,7 +3214,6 @@ static uint32 update_printer(POLICY_HND *handle, uint32 level,
|
||||
|
||||
done:
|
||||
free_a_printer(&printer, 2);
|
||||
free_sec_desc_buf(&sd);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -4251,6 +4224,12 @@ static uint32 spoolss_addprinterex_level_2( const UNISTR2 *uni_srv_name,
|
||||
free_a_printer(&printer,2);
|
||||
return ERROR_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/* you must be a printer admin to add a new printer */
|
||||
if (!print_access_check(NULL, snum, PRINTER_ACE_FULL_CONTROL)) {
|
||||
free_a_printer(&printer,2);
|
||||
return ERROR_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do sanity check on the requested changes for Samba.
|
||||
@ -4547,8 +4526,7 @@ uint32 _spoolss_setprinterdata( POLICY_HND *handle,
|
||||
uint32 numeric_data)
|
||||
{
|
||||
NT_PRINTER_INFO_LEVEL *printer = NULL;
|
||||
NT_PRINTER_PARAM *param = NULL;
|
||||
|
||||
NT_PRINTER_PARAM *param = NULL;
|
||||
int snum=0;
|
||||
uint32 status = 0x0;
|
||||
Printer_entry *Printer=find_printer_index_by_hnd(handle);
|
||||
@ -4564,6 +4542,12 @@ 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)) {
|
||||
DEBUG(3, ("security descriptor change denied by existing "
|
||||
"security descriptor\n"));
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
status = get_a_printer(&printer, 2, lp_servicename(snum));
|
||||
if (status != 0x0)
|
||||
return ERROR_INVALID_NAME;
|
||||
|
Loading…
x
Reference in New Issue
Block a user