diff options
Diffstat (limited to 'source/rpc_server/srv_srvsvc_nt.c')
-rw-r--r-- | source/rpc_server/srv_srvsvc_nt.c | 152 |
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; |