1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-13 13:18:06 +03:00

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 8ab8113d2e)
This commit is contained in:
Gerald Carter 2005-01-18 19:51:36 +00:00 committed by Gerald (Jerry) Carter
parent d50816d59a
commit 10861a6160
2 changed files with 136 additions and 45 deletions

View File

@ -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;
}

View File

@ -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;