summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h2
-rwxr-xr-xsource3/rpc_server/srv_spoolss.c2
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c116
3 files changed, 67 insertions, 53 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index b452d1c9f1..8b90552956 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -3355,7 +3355,7 @@ BOOL api_spoolss_rpc(pipes_struct *p);
#if OLD_NTDOMAIN
void init_printer_hnd(void);
void srv_spoolss_receive_message(int msg_type, pid_t src, void *buf, size_t len);
-uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
+uint32 _spoolss_open_printer_ex( const UNISTR2 *printername, pipes_struct *p,
const PRINTER_DEFAULT *printer_default,
uint32 user_switch, SPOOL_USER_CTR user_ctr,
POLICY_HND *handle);
diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c
index 8d7d238ad0..8c06f16290 100755
--- a/source3/rpc_server/srv_spoolss.c
+++ b/source3/rpc_server/srv_spoolss.c
@@ -48,7 +48,7 @@ static BOOL api_spoolss_open_printer_ex(pipes_struct *p)
if (q_u.printername_ptr != 0)
printername = &q_u.printername;
- r_u.status = _spoolss_open_printer_ex( printername,
+ r_u.status = _spoolss_open_printer_ex( printername, p,
&q_u.printer_default,
q_u.user_switch, q_u.user_ctr,
&r_u.handle);
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index dabaca5d66..ff9dfabe69 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -658,12 +658,28 @@ static BOOL srv_spoolss_sendnotify(POLICY_HND *handle)
return True;
}
+/****************************************************************************
+ Return a user struct for a pipe user.
+****************************************************************************/
+
+static struct current_user *get_current_user(struct current_user *user, pipes_struct *p)
+{
+ if (p->ntlmssp_auth_validated) {
+ memcpy(user, &p->pipe_user, sizeof(struct current_user));
+ } else {
+ extern struct current_user current_user;
+ memcpy(user, &current_user, sizeof(struct current_user));
+ }
+
+ return user;
+}
+
/********************************************************************
* spoolss_open_printer
*
* called from the spoolss dispatcher
********************************************************************/
-uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
+uint32 _spoolss_open_printer_ex( const UNISTR2 *printername, pipes_struct *p,
const PRINTER_DEFAULT *printer_default,
uint32 user_switch, SPOOL_USER_CTR user_ctr,
POLICY_HND *handle)
@@ -671,11 +687,10 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
uint32 result = NT_STATUS_NO_PROBLEMO;
fstring name;
int snum;
+ struct current_user user;
- if (printername == NULL) {
- result = ERROR_INVALID_PRINTER_NAME;
- goto done;
- }
+ if (printername == NULL)
+ return ERROR_INVALID_PRINTER_NAME;
/* some sanity check because you can open a printer or a print server */
/* aka: \\server\printer or \\server */
@@ -683,10 +698,8 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
DEBUGADD(3,("checking name: %s\n",name));
- if (!open_printer_hnd(handle, name)) {
- result = ERROR_INVALID_PRINTER_NAME;
- goto done;
- }
+ if (!open_printer_hnd(handle, name))
+ return ERROR_INVALID_PRINTER_NAME;
/*
if (printer_default->datatype_ptr != NULL)
@@ -700,45 +713,62 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
if (!set_printer_hnd_accesstype(handle, printer_default->access_required)) {
close_printer_handle(handle);
- result = ERROR_ACCESS_DENIED;
- goto done;
+ return ERROR_ACCESS_DENIED;
}
- /* Disallow MS AddPrinterWizard if parameter disables it. A Win2k
+ /*
+ First case: the user is opening the print server:
+
+ Disallow MS AddPrinterWizard if parameter disables it. A Win2k
client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
+
Then both Win2k and WinNT clients try an OpenPrinterEx with
- SERVER_ALL_ACCESS, which we force to fail. Then they try
- OpenPrinterEx with SERVER_READ which we allow. This lets the
+ SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
+ or if the user is listed in the smb.conf printer admin parameter.
+
+ Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
client view printer folder, but does not show the MSAPW.
Note: this test needs code to check access rights here too. Jeremy
- could you look at this? */
+ could you look at this?
+
+
+ Second case: the user is opening a printer:
+ NT doesn't let us connect to a printer if the connecting user
+ doesn't have print permission.
- if (handle_is_printserver(handle) &&
- !lp_ms_add_printer_wizard()) {
+ */
+
+ get_current_user(&user, p);
+
+ if (handle_is_printserver(handle) ) {
if (printer_default->access_required == 0) {
- goto done;
- }
- else if (printer_default->access_required != (SERVER_READ)) {
- close_printer_handle(handle);
- result = ERROR_ACCESS_DENIED;
- goto done;
+ return NT_STATUS_NO_PROBLEMO;
}
- }
-
- /* NT doesn't let us connect to a printer if the connecting user
- doesn't have print permission. */
-
- if (!handle_is_printserver(handle)) {
+ else if ( (printer_default->access_required & SERVER_ACCESS_ADMINISTER ) == SERVER_ACCESS_ADMINISTER) {
+ if (lp_ms_add_printer_wizard()) {
+ close_printer_handle(handle);
+ return ERROR_ACCESS_DENIED;
+ }
+ else if (user.uid == 0 || user_in_list(uidtoname(user.uid), lp_printer_admin(snum))) {
+ return NT_STATUS_NO_PROBLEMO;
+ } else {
+ close_printer_handle(handle);
+ return ERROR_ACCESS_DENIED;
+ }
+ }
+ else
+ return NT_STATUS_NO_PROBLEMO;
+ } else {
+
if (!get_printer_snum(handle, &snum))
return ERROR_INVALID_HANDLE;
- if (!print_access_check(NULL, snum, PRINTER_ACCESS_USE)) {
+ if (!print_access_check(&user, snum, printer_default->access_required)) {
DEBUG(3, ("access DENIED for printer open\n"));
close_printer_handle(handle);
- result = ERROR_ACCESS_DENIED;
- goto done;
+ return ERROR_ACCESS_DENIED;
}
/*
@@ -753,13 +783,13 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
result = printer_write_default_dev( snum, printer_default);
if (result != 0) {
close_printer_handle(handle);
- goto done;
+ return result;
}
}
+
+ return NT_STATUS_NO_PROBLEMO;
}
- done:
- return result;
}
/****************************************************************************
@@ -3615,22 +3645,6 @@ uint32 _spoolss_endpageprinter(POLICY_HND *handle)
return NT_STATUS_NO_PROBLEMO;
}
-/****************************************************************************
- Return a user struct for a pipe user.
-****************************************************************************/
-
-static struct current_user *get_current_user(struct current_user *user, pipes_struct *p)
-{
- if (p->ntlmssp_auth_validated) {
- memcpy(user, &p->pipe_user, sizeof(struct current_user));
- } else {
- extern struct current_user current_user;
- memcpy(user, &current_user, sizeof(struct current_user));
- }
-
- return user;
-}
-
/********************************************************************
* api_spoolss_getprinter
* called from the spoolss dispatcher