summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2005-01-18 19:51:36 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:53:56 -0500
commit10861a6160fb1ead19e23ff58f3590813600fc7b (patch)
tree379bbbbc80271f203d303013fa4d09f5c06a88a5
parentd50816d59a830ab1ecea271063fe0b2fade9683d (diff)
downloadsamba-10861a6160fb1ead19e23ff58f3590813600fc7b.tar.gz
samba-10861a6160fb1ead19e23ff58f3590813600fc7b.tar.bz2
samba-10861a6160fb1ead19e23ff58f3590813600fc7b.zip
r4825: Printing changes
---------------- * bracket the add/delete/set printer scripts with checks for se_print_op * slight change to the add/set printer script semantics. smbd no longer relies on output from the script (on stdout) to re-read smb.conf * remove SIGHUP from set/add/delete printin script code and now just use MSG_SMB_CONF_UPDATED * bracket the add/delete/set share scripts with checks for se_print_op (this includes setting share ACLs) (This used to be commit 8ab8113d2e1bec6a1dbf464882ad724c7c591be4)
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c74
-rw-r--r--source3/rpc_server/srv_srvsvc_nt.c107
2 files changed, 136 insertions, 45 deletions
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 12611c4ee5..31e1e4a3bf 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -379,29 +379,50 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
return WERR_ACCESS_DENIED;
}
#endif
-
+
+ /* this does not need a become root since the access check has been
+ done on the handle already */
+
if (del_a_printer( Printer->sharename ) != 0) {
DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
return WERR_BADFID;
}
+ /* the delete printer script shoudl be run as root if the user has perms */
+
if (*lp_deleteprinter_cmd()) {
char *cmd = lp_deleteprinter_cmd();
pstring command;
int ret;
-
+ SE_PRIV se_printop = SE_PRINT_OPERATOR;
+ BOOL is_print_op;
+
pstr_sprintf(command, "%s \"%s\"", cmd, Printer->sharename);
+ is_print_op = user_has_privileges( p->pipe_user.nt_user_token, &se_printop );
+
DEBUG(10,("Running [%s]\n", command));
+
+ /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
+
+ if ( is_print_op )
+ become_root();
+
ret = smbrun(command, NULL);
- if (ret != 0) {
- return WERR_BADFID; /* What to return here? */
- }
+
+ if ( is_print_op )
+ unbecome_root();
+
+ /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
+
DEBUGADD(10,("returned [%d]\n", ret));
- /* Send SIGHUP to process group... is there a better way? */
- kill(0, SIGHUP);
+ if (ret != 0)
+ return WERR_BADFID; /* What to return here? */
+
+ /* Tell everyone we updated smb.conf. */
+ message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
/* go ahead and re-read the services immediately */
reload_services( False );
@@ -5984,7 +6005,7 @@ static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
/****************************************************************************
****************************************************************************/
-static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
+static BOOL add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
{
extern userdom_struct current_user_info;
char *cmd = lp_addprinter_cmd();
@@ -5994,6 +6015,8 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
int ret;
int fd;
fstring remote_machine = "%m";
+ SE_PRIV se_printop = SE_PRINT_OPERATOR;
+ BOOL is_print_op;
standard_sub_basic(current_user_info.smb_name, remote_machine,sizeof(remote_machine));
@@ -6002,8 +6025,22 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
printer->info_2->portname, printer->info_2->drivername,
printer->info_2->location, printer->info_2->comment, remote_machine);
+ is_print_op = user_has_privileges( token, &se_printop );
+
DEBUG(10,("Running [%s]\n", command));
+
+ /********* BEGIN SePrintOperatorPrivilege **********/
+
+ if ( is_print_op )
+ become_root();
+
ret = smbrun(command, &fd);
+
+ if ( is_print_op )
+ unbecome_root();
+
+ /********* END SePrintOperatorPrivilege **********/
+
DEBUGADD(10,("returned [%d]\n", ret));
if ( ret != 0 ) {
@@ -6012,22 +6049,25 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
return False;
}
+ /* Tell everyone we updated smb.conf. */
+ message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
+
+ /* reload our services immediately */
+ reload_services( False );
+
numlines = 0;
/* Get lines and convert them back to dos-codepage */
qlines = fd_lines_load(fd, &numlines);
DEBUGADD(10,("Lines returned = [%d]\n", numlines));
close(fd);
- if(numlines) {
+ /* Set the portname to what the script says the portname should be. */
+ /* but don't require anything to be return from the script exit a good error code */
+
+ 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);
-
- /* reload our services immediately */
- reload_services( False );
}
file_lines_free(qlines);
@@ -6122,7 +6162,7 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
|| !strequal(printer->info_2->portname, old_printer->info_2->portname)
|| !strequal(printer->info_2->location, old_printer->info_2->location)) )
{
- if ( !add_printer_hook(printer) ) {
+ if ( !add_printer_hook(p->pipe_user.nt_user_token, printer) ) {
result = WERR_ACCESS_DENIED;
goto done;
}
@@ -7416,7 +7456,7 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
trying to add a printer like this --jerry */
if (*lp_addprinter_cmd() ) {
- if ( !add_printer_hook(printer) ) {
+ if ( !add_printer_hook(p->pipe_user.nt_user_token, printer) ) {
free_a_printer(&printer,2);
return WERR_ACCESS_DENIED;
}
diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c
index af4c94800a..382941d361 100644
--- a/source3/rpc_server/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srv_srvsvc_nt.c
@@ -1470,6 +1470,8 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
int ret;
char *ptr;
SEC_DESC *psd = NULL;
+ SE_PRIV se_diskop = SE_DISK_OPERATOR;
+ BOOL is_disk_op;
DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
@@ -1492,7 +1494,11 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
get_current_user(&user,p);
- if (user.uid != sec_initial_uid())
+ is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
+
+ /* fail out now if you are not root and not a disk op */
+
+ if ( user.uid != sec_initial_uid() && !is_disk_op )
return WERR_ACCESS_DENIED;
switch (q_u->info_level) {
@@ -1575,23 +1581,36 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
/* Only call modify function if something changed. */
-
- if (strcmp(ptr, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) {
- if (!lp_change_share_cmd() || !*lp_change_share_cmd())
+
+ if (strcmp(ptr, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) )
+ {
+ if (!lp_change_share_cmd() || !*lp_change_share_cmd())
return WERR_ACCESS_DENIED;
slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
lp_change_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
- if ((ret = smbrun(command, NULL)) != 0) {
- DEBUG(0,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
+
+ /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
+
+ if ( is_disk_op )
+ become_root();
+
+ ret = smbrun(command, NULL);
+
+ if ( is_disk_op )
+ unbecome_root();
+
+ /********* END SeDiskOperatorPrivilege BLOCK *********/
+
+ DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
+
+ if ( ret != 0 )
return WERR_ACCESS_DENIED;
- }
/* Tell everyone we updated smb.conf. */
message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
-
} else {
DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
}
@@ -1609,7 +1628,7 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
share_name ));
}
}
-
+
DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
return WERR_OK;
@@ -1631,6 +1650,8 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
int ret;
char *ptr;
SEC_DESC *psd = NULL;
+ SE_PRIV se_diskop = SE_DISK_OPERATOR;
+ BOOL is_disk_op;
DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
@@ -1638,16 +1659,16 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
get_current_user(&user,p);
- if (user.uid != sec_initial_uid()) {
- DEBUG(10,("_srv_net_share_add: uid != sec_initial_uid(). Access denied.\n"));
+ is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
+
+ if (user.uid != sec_initial_uid() && !is_disk_op )
return WERR_ACCESS_DENIED;
- }
if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
DEBUG(10,("_srv_net_share_add: No add share command\n"));
return WERR_ACCESS_DENIED;
}
-
+
switch (q_u->info_level) {
case 0:
/* No path. Not enough info in a level 0 to do anything. */
@@ -1713,12 +1734,28 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
lp_add_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
-
+
DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
- if ((ret = smbrun(command, NULL)) != 0) {
- DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
+
+ /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
+
+ if ( is_disk_op )
+ become_root();
+
+ ret = smbrun(command, NULL);
+
+ if ( is_disk_op )
+ unbecome_root();
+
+ /********* END SeDiskOperatorPrivilege BLOCK *********/
+
+ DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
+
+ if ( ret != 0 )
return WERR_ACCESS_DENIED;
- }
+
+ /* Tell everyone we updated smb.conf. */
+ message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
if (psd) {
if (!set_share_security(p->mem_ctx, share_name, psd))
@@ -1726,9 +1763,6 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
share_name ));
}
- /* Tell everyone we updated smb.conf. */
- message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
-
/*
* We don't call reload_services() here, the message will
* cause this to be done before the next packet is read
@@ -1752,6 +1786,8 @@ WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_S
fstring share_name;
int ret;
int snum;
+ SE_PRIV se_diskop = SE_DISK_OPERATOR;
+ BOOL is_disk_op;
DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
@@ -1771,27 +1807,42 @@ WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_S
get_current_user(&user,p);
- if (user.uid != sec_initial_uid())
+ is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
+
+ if (user.uid != sec_initial_uid() && !is_disk_op )
return WERR_ACCESS_DENIED;
if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
return WERR_ACCESS_DENIED;
-
+
slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
- if ((ret = smbrun(command, NULL)) != 0) {
- DEBUG(0,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
- return WERR_ACCESS_DENIED;
- }
- /* Delete the SD in the database. */
- delete_share_security(snum);
+ /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
+
+ if ( is_disk_op )
+ become_root();
+
+ ret = smbrun(command, NULL);
+
+ if ( is_disk_op )
+ unbecome_root();
+
+ /********* END SeDiskOperatorPrivilege BLOCK *********/
+
+ DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
+
+ if ( ret != 0 )
+ return WERR_ACCESS_DENIED;
/* Tell everyone we updated smb.conf. */
message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
+ /* Delete the SD in the database. */
+ delete_share_security(snum);
+
lp_killservice(snum);
return WERR_OK;