diff options
| -rw-r--r-- | source3/include/proto.h | 3 | ||||
| -rw-r--r-- | source3/param/loadparm.c | 4 | ||||
| -rw-r--r-- | source3/printing/nt_printing.c | 20 | ||||
| -rw-r--r-- | source3/printing/printing.c | 2 | ||||
| -rw-r--r-- | source3/rpc_server/srv_spoolss_nt.c | 68 | 
5 files changed, 51 insertions, 46 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 604af93272..f458bd7e7f 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -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  */ diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 318c1ea534..17a109dd06 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.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) diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 0265cf5593..11c8e80276 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -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 diff --git a/source3/printing/printing.c b/source3/printing/printing.c index c6252b8fb1..a6dc81b172 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -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 diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 4774375db4..d6c39fa022 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -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;  | 
