From 50e78a9ac8cf0949c2471fafde844c674f97d73d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 13 Apr 2001 00:37:00 +0000 Subject: As Andrew suggested, make smbrun return a fd for a deleted file which can then be read. Jeremy. (This used to be commit e7d59d6de89a5fdd201e4b5c6072dab08b1519db) --- source3/include/proto.h | 13 +++- source3/lib/smbrun.c | 116 ++++++++++++++++-------------------- source3/lib/util.c | 5 +- source3/lib/util_file.c | 52 ++++++++++++---- source3/nmbd/nmbd_winsserver.c | 2 +- source3/printing/print_generic.c | 31 ++++++---- source3/rpc_server/srv_spoolss_nt.c | 58 +++++++----------- source3/rpc_server/srv_srvsvc_nt.c | 6 +- source3/smbd/close.c | 26 +++++++- source3/smbd/message.c | 2 +- source3/smbd/reply.c | 4 +- source3/smbd/service.c | 8 +-- 12 files changed, 186 insertions(+), 137 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 78fae3705a..ff83fc103e 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -219,7 +219,7 @@ int vslprintf(char *str, int n, char *format, va_list ap); /*The following definitions come from lib/smbrun.c */ -int smbrun(char *cmd,char *outfile,BOOL shared); +int smbrun(char *cmd, int *outfd, char *template); /*The following definitions come from lib/snprintf.c */ @@ -529,8 +529,10 @@ BOOL setfilepwpos(void *vp, SMB_BIG_UINT tok); int getfileline(void *vp, char *linebuf, int linebuf_size); char *fgets_slash(char *s2,int maxlen,FILE *f); char *file_pload(char *syscmd, size_t *size); +char *fd_load(int fd, size_t *size); char *file_load(char *fname, size_t *size); char **file_lines_load(char *fname, int *numlines, BOOL convert); +char **fd_lines_load(int fd, int *numlines, BOOL convert); char **file_lines_pload(char *syscmd, int *numlines, BOOL convert); void file_lines_free(char **lines); void file_lines_slashcont(char **lines); @@ -4383,6 +4385,15 @@ int smbw_dup(int fd); int smbw_dup2(int fd, int fd2); int smbw_fork(void); +/*The following definitions come from smbwrapper/smbw_cache.c */ + +BOOL smbw_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, + void (*fn)(const char *, uint32, const char *, void *), + void *state); +int smbw_RNetShareEnum(struct cli_state *cli, + void (*fn)(const char *, uint32, const char *, void *), + void *state); + /*The following definitions come from smbwrapper/smbw_dir.c */ struct smbw_dir *smbw_dir(int fd); diff --git a/source3/lib/smbrun.c b/source3/lib/smbrun.c index e039f222fc..a543ff5eee 100644 --- a/source3/lib/smbrun.c +++ b/source3/lib/smbrun.c @@ -27,54 +27,41 @@ struct current_user current_user; extern int DEBUGLEVEL; /**************************************************************************** -This is a utility function of smbrun(). It must be called only from -the child as it may leave the caller in a privileged state. +This is a utility function of smbrun(). ****************************************************************************/ -static BOOL setup_stdout_file(char *outfile,BOOL shared) -{ - int fd; - mode_t mode = S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH; - int flags = O_RDWR|O_CREAT|O_EXCL; - close(1); +static BOOL setup_out_fd(char *template) +{ + int fd; + pstring path; - if (shared) { - /* become root - unprivileged users can't delete these files */ - gain_root_privilege(); - gain_root_group_privilege(); - } + pstrcpy( path, template); + pstrcat( path, generate_random_str(17)); + pstrcat( path, ".XXXXXX"); - unlink(outfile); + /* now create the file */ + fd = smb_mkstemp(path); - /* now create the file */ - fd = sys_open(outfile,flags,mode); + if (fd == -1) { + DEBUG(0,("setup_out_fd: Failed to create file %s. (%s)\n", + path, strerror(errno) )); + return -1; + } - if (fd == -1) return False; + DEBUG(10,("setup_out_fd: Created tmp file %s\n", path )); - if (fd != 1) { - if (dup2(fd,1) != 1) { - DEBUG(2,("Failed to create stdout file descriptor\n")); - close(fd); - return False; - } - close(fd); - } - return True; + /* Ensure file only kept around by open fd. */ + unlink(path); + return fd; } - /**************************************************************************** run a command being careful about uid/gid handling and putting the output in -outfile (or discard it if outfile is NULL). - -if shared is True then ensure the file will be writeable by all users -but created such that its owned by root. This overcomes a security hole. - -if shared is not set then open the file with O_EXCL set +outfd (or discard it if outfd is NULL). ****************************************************************************/ -int smbrun(char *cmd,char *outfile,BOOL shared) + +int smbrun(char *cmd, int *outfd, char *template) { - int fd; pid_t pid; uid_t uid = current_user.uid; gid_t gid = current_user.gid; @@ -84,32 +71,13 @@ int smbrun(char *cmd,char *outfile,BOOL shared) */ oplock_set_capability(False, False); -#ifndef HAVE_EXECL - { - int ret; - pstring syscmd; - char *path = lp_smbrun(); - - /* in the old method we use system() to execute smbrun which then - executes the command (using system() again!). This involves lots - of shell launches and is very slow. It also suffers from a - potential security hole */ - if (!file_exist(path,NULL)) { - DEBUG(0,("SMBRUN ERROR: Can't find %s. Installation problem?\n",path)); - return(1); - } + /* point our stdout at the file we want output to go into */ - slprintf(syscmd,sizeof(syscmd)-1,"%s %d %d \"(%s 2>&1) > %s\"", - path,(int)uid,(int)gid,cmd, - outfile?outfile:"/dev/null"); - - DEBUG(5,("smbrun - running %s ",syscmd)); - ret = system(syscmd); - DEBUG(5,("gave %d\n",ret)); - return(ret); + if (outfd && ((*outfd = setup_out_fd(template)) == -1)) { + return -1; } -#else - /* in this newer method we will exec /bin/sh with the correct + + /* in this method we will exec /bin/sh with the correct arguments, after first setting stdout to point at the file */ /* @@ -122,6 +90,10 @@ int smbrun(char *cmd,char *outfile,BOOL shared) if ((pid=sys_fork()) < 0) { DEBUG(0,("smbrun: fork failed with error %s\n", strerror(errno) )); CatchChild(); + if (outfd) { + close(*outfd); + *outfd = -1; + } return errno; } @@ -146,13 +118,24 @@ int smbrun(char *cmd,char *outfile,BOOL shared) if (wpid != pid) { DEBUG(2,("waitpid(%d) : %s\n",(int)pid,strerror(errno))); + if (outfd) { + close(*outfd); + *outfd = -1; + } return -1; } + + /* Reset the seek pointer. */ + if (outfd) { + sys_lseek(*outfd, 0, SEEK_SET); + } + #if defined(WIFEXITED) && defined(WEXITSTATUS) if (WIFEXITED(status)) { return WEXITSTATUS(status); } #endif + return status; } @@ -163,10 +146,15 @@ int smbrun(char *cmd,char *outfile,BOOL shared) pipeline or anything else the config file specifies */ /* point our stdout at the file we want output to go into */ - if (outfile && !setup_stdout_file(outfile,shared)) { - exit(80); + if (outfd) { + close(1); + if (dup2(*outfd,1) != 1) { + DEBUG(2,("Failed to create stdout file descriptor\n")); + close(*outfd); + exit(80); + } } - + /* now completely lose our privileges. This is a fairly paranoid way of doing it, but it does work on all systems that I know of */ @@ -183,13 +171,15 @@ int smbrun(char *cmd,char *outfile,BOOL shared) #ifndef __INSURE__ /* close all other file descriptors, leaving only 0, 1 and 2. 0 and 2 point to /dev/null from the startup code */ + { + int fd; for (fd=3;fd<256;fd++) close(fd); + } #endif execl("/bin/sh","sh","-c",cmd,NULL); /* not reached */ exit(82); -#endif return 1; } diff --git a/source3/lib/util.c b/source3/lib/util.c index 42a9617077..506a0334d1 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -1752,8 +1752,9 @@ int smb_mkstemp(char *template) #else /* have a reasonable go at emulating it. Hope that the system mktemp() isn't completly hopeless */ - if (!mktemp(template)) return -1; - return open(template, O_CREAT|O_EXCL|O_RDWR, 0600); + char *p = smbd_mktemp(template); + if (!p) return -1; + return open(p, O_CREAT|O_EXCL|O_RDWR, 0600); #endif } diff --git a/source3/lib/util_file.c b/source3/lib/util_file.c index 023f3e131c..4e2adc97bc 100644 --- a/source3/lib/util_file.c +++ b/source3/lib/util_file.c @@ -368,21 +368,15 @@ char *file_pload(char *syscmd, size_t *size) return p; } - /**************************************************************************** -load a file into memory -****************************************************************************/ -char *file_load(char *fname, size_t *size) +load a file into memory from a fd. +****************************************************************************/ + +char *fd_load(int fd, size_t *size) { - int fd; SMB_STRUCT_STAT sbuf; char *p; - if (!fname || !*fname) return NULL; - - fd = open(fname,O_RDONLY); - if (fd == -1) return NULL; - if (sys_fstat(fd, &sbuf) != 0) return NULL; p = (char *)malloc(sbuf.st_size+1); @@ -394,13 +388,31 @@ char *file_load(char *fname, size_t *size) } p[sbuf.st_size] = 0; - close(fd); - if (size) *size = sbuf.st_size; return p; } +/**************************************************************************** +load a file into memory +****************************************************************************/ +char *file_load(char *fname, size_t *size) +{ + int fd; + char *p; + + if (!fname || !*fname) return NULL; + + fd = open(fname,O_RDONLY); + if (fd == -1) return NULL; + + p = fd_load(fd, size); + + close(fd); + + return p; +} + /**************************************************************************** parse a buffer into lines @@ -459,6 +471,22 @@ char **file_lines_load(char *fname, int *numlines, BOOL convert) return file_lines_parse(p, size, numlines, convert); } +/**************************************************************************** +load a fd into memory and return an array of pointers to lines in the file +must be freed with file_lines_free(). If convert is true calls unix_to_dos on +the list. +****************************************************************************/ +char **fd_lines_load(int fd, int *numlines, BOOL convert) +{ + char *p; + size_t size; + + p = fd_load(fd, &size); + if (!p) return NULL; + + return file_lines_parse(p, size, numlines, convert); +} + /**************************************************************************** load a pipe into memory and return an array of pointers to lines in the data diff --git a/source3/nmbd/nmbd_winsserver.c b/source3/nmbd/nmbd_winsserver.c index 454b2170aa..7836f0570c 100644 --- a/source3/nmbd/nmbd_winsserver.c +++ b/source3/nmbd/nmbd_winsserver.c @@ -62,7 +62,7 @@ static void wins_hook(char *operation, struct name_record *namerec, int ttl) } DEBUG(3,("calling wins hook for %s\n", nmb_namestr(&namerec->name))); - smbrun(command, NULL, False); + smbrun(command, NULL, NULL); } diff --git a/source3/printing/print_generic.c b/source3/printing/print_generic.c index af73088d1f..45c9d445e8 100644 --- a/source3/printing/print_generic.c +++ b/source3/printing/print_generic.c @@ -56,13 +56,14 @@ for local substitution strings ****************************************************************************/ #ifdef HAVE_STDARG_H -static int print_run_command(int snum,char *command, char *outfile, ...) +static int print_run_command(int snum,char *command, int *outfd, char *outfile, ...) { #else /* HAVE_STDARG_H */ static int print_run_command(va_alist) va_dcl { int snum; + int *outfd; char *command, *outfile; #endif /* HAVE_STDARG_H */ @@ -76,6 +77,7 @@ va_dcl #else /* HAVE_STDARG_H */ va_start(ap); snum = va_arg(ap,int); + fd = va_arg(ap, int *); command = va_arg(ap,char *); outfile = va_arg(ap,char *); #endif /* HAVE_STDARG_H */ @@ -102,7 +104,7 @@ va_dcl /* Convert script args to unix-codepage */ dos_to_unix(syscmd, True); - ret = smbrun(syscmd,outfile,False); + ret = smbrun(syscmd,outfd,outfile); DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret)); @@ -121,7 +123,7 @@ static int generic_job_delete(int snum, struct printjob *pjob) slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob); return print_run_command( snum, - lp_lprmcommand(snum), NULL, + lp_lprmcommand(snum), NULL, NULL, "%j", jobstr, "%T", http_timestring(pjob->starttime), NULL); @@ -137,7 +139,7 @@ static int generic_job_pause(int snum, struct printjob *pjob) /* need to pause the spooled entry */ slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob); return print_run_command(snum, - lp_lppausecommand(snum), NULL, + lp_lppausecommand(snum), NULL, NULL, "%j", jobstr, NULL); } @@ -152,7 +154,7 @@ static int generic_job_resume(int snum, struct printjob *pjob) /* need to pause the spooled entry */ slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob); return print_run_command(snum, - lp_lpresumecommand(snum), NULL, + lp_lpresumecommand(snum), NULL, NULL, "%j", jobstr, NULL); } @@ -189,7 +191,7 @@ static int generic_job_submit(int snum, struct printjob *pjob) /* send it to the system spooler */ ret = print_run_command(snum, - lp_printcommand(snum), NULL, + lp_printcommand(snum), NULL, NULL, "%s", p, "%J", jobname, "%f", p, @@ -209,6 +211,7 @@ static int generic_queue_get(int snum, print_queue_struct **q, print_status_stru char *path = lp_pathname(snum); char *cmd = lp_lpqcommand(snum); char **qlines; + int fd; pstring tmp_file; int numlines, i, qcount; print_queue_struct *queue; @@ -221,11 +224,17 @@ static int generic_queue_get(int snum, print_queue_struct **q, print_status_stru slprintf(tmp_file, sizeof(tmp_file)-1, "%s/smblpq.%d", path, sys_getpid()); unlink(tmp_file); - print_run_command(snum, cmd, tmp_file, NULL); + print_run_command(snum, cmd, &fd, tmp_file, NULL); + if (fd == -1) { + DEBUG(5,("generic_queue_get: Can't read print queue status for printer %s\n", + printer_name )); + return 0; + } + numlines = 0; - qlines = file_lines_load(tmp_file, &numlines, True); - unlink(tmp_file); + qlines = fd_lines_load(fd, &numlines, True); + close(fd); /* turn the lpq output into a series of job structures */ qcount = 0; @@ -253,7 +262,7 @@ static int generic_queue_get(int snum, print_queue_struct **q, print_status_stru ****************************************************************************/ static int generic_queue_pause(int snum) { - return print_run_command(snum, lp_queuepausecommand(snum), NULL, + return print_run_command(snum, lp_queuepausecommand(snum), NULL, NULL, NULL); } @@ -262,6 +271,6 @@ static int generic_queue_pause(int snum) ****************************************************************************/ static int generic_queue_resume(int snum) { - return print_run_command(snum, lp_queueresumecommand(snum), NULL, + return print_run_command(snum, lp_queueresumecommand(snum), NULL, NULL, NULL); } diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index f91168d3e4..3bf44cd041 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -286,33 +286,21 @@ static uint32 delete_printer_handle(pipes_struct *p, POLICY_HND *hnd) if (*lp_deleteprinter_cmd()) { char *cmd = lp_deleteprinter_cmd(); - char *path; - pstring tmp_file; pstring command; int ret; int i; - if (*lp_pathname(lp_servicenumber(PRINTERS_NAME))) - path = lp_pathname(lp_servicenumber(PRINTERS_NAME)); - else - path = lp_lockdir(); - /* Printer->dev.handlename equals portname equals sharename */ slprintf(command, sizeof(command)-1, "%s \"%s\"", cmd, Printer->dev.handlename); dos_to_unix(command, True); /* Convert printername to unix-codepage */ - slprintf(tmp_file, sizeof(tmp_file)-1, "%s/smbcmd.%s", path, generate_random_str(16)); - unlink(tmp_file); - DEBUG(10,("Running [%s > %s]\n", command,tmp_file)); - ret = smbrun(command, tmp_file, False); + DEBUG(10,("Running [%s]\n", command)); + ret = smbrun(command, NULL, NULL); if (ret != 0) { - unlink(tmp_file); return ERROR_INVALID_HANDLE; /* What to return here? */ } DEBUGADD(10,("returned [%d]\n", ret)); - DEBUGADD(10,("Unlinking output file [%s]\n", tmp_file)); - unlink(tmp_file); /* Send SIGHUP to process group... is there a better way? */ kill(0, SIGHUP); @@ -4140,6 +4128,7 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer) pstring driverlocation; int numlines; int ret; + int fd; if (*lp_pathname(lp_servicenumber(PRINTERS_NAME))) path = lp_pathname(lp_servicenumber(PRINTERS_NAME)); @@ -4152,31 +4141,29 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer) /* change \ to \\ for the shell */ all_string_sub(driverlocation,"\\","\\\\",sizeof(pstring)); - slprintf(tmp_file, sizeof(tmp_file)-1, "%s/smbcmd.%s", path, generate_random_str(16)); + slprintf(tmp_file, sizeof(tmp_file)-1, "%s/smbcmd.%d.", path, sys_getpid()); slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"", cmd, printer->info_2->printername, printer->info_2->sharename, printer->info_2->portname, printer->info_2->drivername, printer->info_2->location, driverlocation); - unlink(tmp_file); - /* Convert script args to unix-codepage */ dos_to_unix(command, True); DEBUG(10,("Running [%s > %s]\n", command,tmp_file)); - ret = smbrun(command, tmp_file, False); + ret = smbrun(command, &fd, tmp_file); DEBUGADD(10,("returned [%d]\n", ret)); if ( ret != 0 ) { - unlink(tmp_file); + if (fd != -1) + close(fd); return False; } numlines = 0; /* Get lines and convert them back to dos-codepage */ - qlines = file_lines_load(tmp_file, &numlines, True); + qlines = fd_lines_load(fd, &numlines, True); DEBUGADD(10,("Lines returned = [%d]\n", numlines)); - DEBUGADD(10,("Unlinking script output file [%s]\n", tmp_file)); - unlink(tmp_file); + close(fd); if(numlines) { /* Set the portname to what the script says the portname should be. */ @@ -5423,30 +5410,30 @@ static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need pstring command; int numlines; int ret; + int fd; if (*lp_pathname(lp_servicenumber(PRINTERS_NAME))) path = lp_pathname(lp_servicenumber(PRINTERS_NAME)); else path = lp_lockdir(); - slprintf(tmp_file, sizeof(tmp_file)-1, "%s/smbcmd.%s", path, generate_random_str(16)); + slprintf(tmp_file, sizeof(tmp_file)-1, "%s/smbcmd.%d.", path, sys_getpid()); slprintf(command, sizeof(command)-1, "%s \"%d\"", cmd, 1); - unlink(tmp_file); DEBUG(10,("Running [%s > %s]\n", command,tmp_file)); - ret = smbrun(command, tmp_file, False); + ret = smbrun(command, &fd, tmp_file); DEBUG(10,("Returned [%d]\n", ret)); if (ret != 0) { - unlink(tmp_file); + if (fd != -1) + close(fd); /* Is this the best error to return here? */ return ERROR_ACCESS_DENIED; } numlines = 0; - qlines = file_lines_load(tmp_file, &numlines,True); + qlines = fd_lines_load(fd, &numlines,True); DEBUGADD(10,("Lines returned = [%d]\n", numlines)); - DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file)); - unlink(tmp_file); + close(fd); if(numlines) { if((ports=(PORT_INFO_1 *)malloc( numlines * sizeof(PORT_INFO_1) )) == NULL) { @@ -5520,30 +5507,31 @@ static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need pstring command; int numlines; int ret; + int fd; if (*lp_pathname(lp_servicenumber(PRINTERS_NAME))) path = lp_pathname(lp_servicenumber(PRINTERS_NAME)); else path = lp_lockdir(); - slprintf(tmp_file, sizeof(tmp_file)-1, "%s/smbcmd.%s", path, generate_random_str(16)); + slprintf(tmp_file, sizeof(tmp_file)-1, "%s/smbcmd.%d.", path, sys_getpid()); slprintf(command, sizeof(command)-1, "%s \"%d\"", cmd, 2); unlink(tmp_file); DEBUG(10,("Running [%s > %s]\n", command,tmp_file)); - ret = smbrun(command, tmp_file, False); + ret = smbrun(command, &fd, tmp_file); DEBUGADD(10,("returned [%d]\n", ret)); if (ret != 0) { - unlink(tmp_file); + if (fd != -1) + close(fd); /* Is this the best error to return here? */ return ERROR_ACCESS_DENIED; } numlines = 0; - qlines = file_lines_load(tmp_file, &numlines,True); + qlines = fd_lines_load(fd, &numlines,True); DEBUGADD(10,("Lines returned = [%d]\n", numlines)); - DEBUGADD(10,("Unlinking port file [%s]\n", tmp_file)); - unlink(tmp_file); + close(fd); if(numlines) { if((ports=(PORT_INFO_2 *)malloc( numlines * sizeof(PORT_INFO_2) )) == NULL) { diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index 0c165bf9fa..e5d93b8b3d 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -1303,7 +1303,7 @@ uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S dos_to_unix(command, True); /* Convert to unix-codepage */ DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command )); - if ((ret = smbrun(command, NULL, False)) != 0) { + if ((ret = smbrun(command, NULL, NULL)) != 0) { DEBUG(0,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret )); return ERROR_ACCESS_DENIED; } @@ -1420,7 +1420,7 @@ uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S dos_to_unix(command, True); /* Convert to unix-codepage */ DEBUG(10,("_srv_net_share_add: Running [%s]\n", command )); - if ((ret = smbrun(command, NULL, False)) != 0) { + if ((ret = smbrun(command, NULL, NULL)) != 0) { DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret )); return ERROR_ACCESS_DENIED; } @@ -1487,7 +1487,7 @@ uint32 _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_S dos_to_unix(command, True); /* Convert to unix-codepage */ DEBUG(10,("_srv_net_share_del: Running [%s]\n", command )); - if ((ret = smbrun(command, NULL, False)) != 0) { + if ((ret = smbrun(command, NULL, NULL)) != 0) { DEBUG(0,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret )); return ERROR_ACCESS_DENIED; } diff --git a/source3/smbd/close.c b/source3/smbd/close.c index c290ee6f89..10c9539834 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -48,17 +48,39 @@ static void check_magic(files_struct *fsp,connection_struct *conn) int ret; pstring magic_output; pstring fname; - pstrcpy(fname,fsp->fsp_name); + SMB_STRUCT_STAT st; + int tmp_fd, outfd; + pstrcpy(fname,fsp->fsp_name); if (*lp_magicoutput(SNUM(conn))) pstrcpy(magic_output,lp_magicoutput(SNUM(conn))); else slprintf(magic_output,sizeof(fname)-1, "%s.out",fname); chmod(fname,0755); - ret = smbrun(fname,magic_output,False); + ret = smbrun(fname,&tmp_fd,magic_output); DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret)); unlink(fname); + if (ret != 0 || tmp_fd == -1) { + if (tmp_fd != -1) + close(tmp_fd); + return; + } + outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600); + if (outfd == -1) { + close(tmp_fd); + return; + } + + if (sys_fstat(tmp_fd,&st) == -1) { + close(tmp_fd); + close(outfd); + return; + } + + transfer_file(tmp_fd,outfd,st.st_size, NULL,0,0); + close(tmp_fd); + close(outfd); } } diff --git a/source3/smbd/message.c b/source3/smbd/message.c index 9206442b94..01b5f51acc 100644 --- a/source3/smbd/message.c +++ b/source3/smbd/message.c @@ -91,7 +91,7 @@ static void msg_deliver(void) pstring_sub(s,"%t",alpha_strcpy(alpha_msgto,msgto,sizeof(alpha_msgto))); standard_sub_basic(s); pstring_sub(s,"%s",name); - smbrun(s,NULL,False); + smbrun(s,NULL,NULL); } msgpos = 0; diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 4176dd0104..b4e0d490ab 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -493,7 +493,7 @@ int smb_create_user(char *unix_user, char *homedir) all_string_sub(add_script, "%u", unix_user, sizeof(pstring)); if (homedir) all_string_sub(add_script, "%H", homedir, sizeof(pstring)); - ret = smbrun(add_script,NULL,False); + ret = smbrun(add_script,NULL,NULL); DEBUG(3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret)); return ret; } @@ -510,7 +510,7 @@ static int smb_delete_user(char *unix_user) pstrcpy(del_script, lp_deluser_script()); if (! *del_script) return -1; all_string_sub(del_script, "%u", unix_user, sizeof(pstring)); - ret = smbrun(del_script,NULL,False); + ret = smbrun(del_script,NULL,NULL); DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret)); return ret; } diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 507d07cc42..375587b539 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -559,7 +559,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int pstrcpy(cmd,lp_rootpreexec(SNUM(conn))); standard_sub_conn(conn,cmd); DEBUG(5,("cmd=%s\n",cmd)); - ret = smbrun(cmd,NULL,False); + ret = smbrun(cmd,NULL,NULL); if (ret != 0 && lp_rootpreexec_close(SNUM(conn))) { DEBUG(1,("preexec gave %d - failing connection\n", ret)); conn_free(conn); @@ -611,7 +611,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int pstring cmd; pstrcpy(cmd,lp_preexec(SNUM(conn))); standard_sub_conn(conn,cmd); - ret = smbrun(cmd,NULL,False); + ret = smbrun(cmd,NULL,NULL); if (ret != 0 && lp_preexec_close(SNUM(conn))) { DEBUG(1,("preexec gave %d - failing connection\n", ret)); conn_free(conn); @@ -688,7 +688,7 @@ void close_cnum(connection_struct *conn, uint16 vuid) pstring cmd; pstrcpy(cmd,lp_postexec(SNUM(conn))); standard_sub_conn(conn,cmd); - smbrun(cmd,NULL,False); + smbrun(cmd,NULL,NULL); unbecome_user(); } @@ -698,7 +698,7 @@ void close_cnum(connection_struct *conn, uint16 vuid) pstring cmd; pstrcpy(cmd,lp_rootpostexec(SNUM(conn))); standard_sub_conn(conn,cmd); - smbrun(cmd,NULL,False); + smbrun(cmd,NULL,NULL); } conn_free(conn); } -- cgit