summaryrefslogtreecommitdiffstats
path: root/source/rpc_server/srv_srvsvc_nt.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/rpc_server/srv_srvsvc_nt.c')
-rw-r--r--source/rpc_server/srv_srvsvc_nt.c152
1 files changed, 93 insertions, 59 deletions
diff --git a/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c
index af4c94800a5..13e1971925a 100644
--- a/source/rpc_server/srv_srvsvc_nt.c
+++ b/source/rpc_server/srv_srvsvc_nt.c
@@ -1419,10 +1419,7 @@ WERROR _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, S
static char *valid_share_pathname(char *dos_pathname)
{
- pstring saved_pathname;
- pstring unix_pathname;
char *ptr;
- int ret;
/* Convert any '\' paths to '/' */
unix_format(dos_pathname);
@@ -1437,21 +1434,7 @@ static char *valid_share_pathname(char *dos_pathname)
if (*ptr != '/')
return NULL;
- /* Can we cd to it ? */
-
- /* First save our current directory. */
- if (getcwd(saved_pathname, sizeof(saved_pathname)) == NULL)
- return False;
-
- pstrcpy(unix_pathname, ptr);
-
- ret = chdir(unix_pathname);
-
- /* We *MUST* be able to chdir back. Abort if we can't. */
- if (chdir(saved_pathname) == -1)
- smb_panic("valid_share_pathname: Unable to restore current directory.\n");
-
- return (ret != -1) ? ptr : NULL;
+ return ptr;
}
/*******************************************************************
@@ -1468,8 +1451,10 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
int type;
int snum;
int ret;
- char *ptr;
+ char *path;
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 +1477,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) {
@@ -1563,35 +1552,48 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
return WERR_ACCESS_DENIED;
/* Check if the pathname is valid. */
- if (!(ptr = valid_share_pathname( pathname )))
+ if (!(path = valid_share_pathname( pathname )))
return WERR_OBJECT_PATH_INVALID;
/* Ensure share name, pathname and comment don't contain '"' characters. */
string_replace(share_name, '"', ' ');
- string_replace(ptr, '"', ' ');
+ string_replace(path, '"', ' ');
string_replace(comment, '"', ' ');
DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
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(path, 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);
+ lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, 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 ));
- return WERR_ACCESS_DENIED;
+
+ /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
+
+ if ( is_disk_op )
+ become_root();
+
+ if ( (ret = smbrun(command, NULL)) == 0 ) {
+ /* Tell everyone we updated smb.conf. */
+ message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
}
+
+ if ( is_disk_op )
+ unbecome_root();
+
+ /********* END SeDiskOperatorPrivilege BLOCK *********/
- /* Tell everyone we updated smb.conf. */
- message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
-
+ DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
+
+ if ( ret != 0 )
+ return WERR_ACCESS_DENIED;
} else {
DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
}
@@ -1609,7 +1611,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;
@@ -1629,8 +1631,10 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
int type;
int snum;
int ret;
- char *ptr;
+ char *path;
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 +1642,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. */
@@ -1703,32 +1707,45 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
return WERR_ACCESS_DENIED;
/* Check if the pathname is valid. */
- if (!(ptr = valid_share_pathname( pathname )))
+ if (!(path = valid_share_pathname( pathname )))
return WERR_OBJECT_PATH_INVALID;
/* Ensure share name, pathname and comment don't contain '"' characters. */
string_replace(share_name, '"', ' ');
- string_replace(ptr, '"', ' ');
+ string_replace(path, '"', ' ');
string_replace(comment, '"', ' ');
slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
- lp_add_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
-
+ lp_add_share_cmd(), dyn_CONFIGFILE, share_name, path, 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 ));
- return WERR_ACCESS_DENIED;
+
+ /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
+
+ if ( is_disk_op )
+ become_root();
+
+ if ( (ret = smbrun(command, NULL)) == 0 ) {
+ /* Tell everyone we updated smb.conf. */
+ message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, 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;
+
if (psd) {
- if (!set_share_security(p->mem_ctx, share_name, psd))
- DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n",
- share_name ));
+ if (!set_share_security(p->mem_ctx, share_name, psd)) {
+ DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", 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 +1769,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 +1790,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;
+
+ /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
+
+ if ( is_disk_op )
+ become_root();
+
+ if ( (ret = smbrun(command, NULL)) == 0 ) {
+ /* Tell everyone we updated smb.conf. */
+ message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, 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;
+
/* Delete the SD in the database. */
delete_share_security(snum);
- /* Tell everyone we updated smb.conf. */
- message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
-
lp_killservice(snum);
return WERR_OK;