-/*
+/*
Unix SMB/CIFS implementation.
run a command as a specified user
Copyright (C) Andrew Tridgell 1992-1998
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
****************************************************************************/
static int setup_out_fd(void)
-{
+{
int fd;
- pstring path;
-
- slprintf(path, sizeof(path)-1, "%s/smb.XXXXXX", tmpdir());
+ TALLOC_CTX *ctx = talloc_stackframe();
+ char *path = NULL;
+
+ path = talloc_asprintf(ctx,
+ "%s/smb.XXXXXX",
+ tmpdir());
+ if (!path) {
+ TALLOC_FREE(ctx);
+ errno = ENOMEM;
+ return -1;
+ }
/* now create the file */
- fd = smb_mkstemp(path);
+ fd = mkstemp(path);
if (fd == -1) {
DEBUG(0,("setup_out_fd: Failed to create file %s. (%s)\n",
path, strerror(errno) ));
+ TALLOC_FREE(ctx);
return -1;
}
/* Ensure file only kept around by open fd. */
unlink(path);
+ TALLOC_FREE(ctx);
return fd;
}
outfd (or discard it if outfd is NULL).
****************************************************************************/
-static int smbrun_internal(const char *cmd, int *outfd, BOOL sanitize)
+static int smbrun_internal(const char *cmd, int *outfd, bool sanitize)
{
pid_t pid;
uid_t uid = current_user.ut.uid;
gid_t gid = current_user.ut.gid;
-
+
/*
* Lose any elevated privileges.
*/
/* point our stdout at the file we want output to go into */
if (outfd) {
close(1);
- if (sys_dup2(*outfd,1) != 1) {
+ if (dup2(*outfd,1) != 1) {
DEBUG(2,("Failed to create stdout file descriptor\n"));
close(*outfd);
exit(80);
become_user_permanently(uid, gid);
- if (getuid() != uid || geteuid() != uid ||
- getgid() != gid || getegid() != gid) {
- /* we failed to lose our privileges - do not execute
- the command */
- exit(81); /* we can't print stuff at this stage,
- instead use exit codes for debugging */
+ if (!non_root_mode()) {
+ if (getuid() != uid || geteuid() != uid ||
+ getgid() != gid || getegid() != gid) {
+ /* we failed to lose our privileges - do not execute
+ the command */
+ exit(81); /* we can't print stuff at this stage,
+ instead use exit codes for debugging */
+ }
}
-
+
#ifndef __INSURE__
/* close all other file descriptors, leaving only 0, 1 and 2. 0 and
2 point to /dev/null from the startup code */
#endif
{
- const char *newcmd = sanitize ? escape_shell_string(cmd) : cmd;
- if (!newcmd) {
- exit(82);
+ char *newcmd = NULL;
+ if (sanitize) {
+ newcmd = escape_shell_string(cmd);
+ if (!newcmd)
+ exit(82);
}
- execl("/bin/sh","sh","-c",newcmd,NULL);
+
+ execl("/bin/sh","sh","-c",
+ newcmd ? (const char *)newcmd : cmd, NULL);
+
+ SAFE_FREE(newcmd);
}
/* not reached */
close(ifd[1]);
close(0);
- if (sys_dup2(ifd[0], 0) != 0) {
+ if (dup2(ifd[0], 0) != 0) {
DEBUG(2,("Failed to create stdin file descriptor\n"));
close(ifd[0]);
exit(80);
become_user_permanently(uid, gid);
- if (getuid() != uid || geteuid() != uid ||
- getgid() != gid || getegid() != gid) {
- /* we failed to lose our privileges - do not execute
- the command */
- exit(81); /* we can't print stuff at this stage,
- instead use exit codes for debugging */
+ if (!non_root_mode()) {
+ if (getuid() != uid || geteuid() != uid ||
+ getgid() != gid || getegid() != gid) {
+ /* we failed to lose our privileges - do not execute
+ the command */
+ exit(81); /* we can't print stuff at this stage,
+ instead use exit codes for debugging */
+ }
}
-
+
#ifndef __INSURE__
/* close all other file descriptors, leaving only 0, 1 and 2. 0 and
2 point to /dev/null from the startup code */