00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "includes.h"
00022
00023
00024 struct current_user current_user;
00025
00026
00027
00028
00029
00030 static int setup_out_fd(void)
00031 {
00032 int fd;
00033 pstring path;
00034
00035 slprintf(path, sizeof(path)-1, "%s/smb.XXXXXX", tmpdir());
00036
00037
00038 fd = smb_mkstemp(path);
00039
00040 if (fd == -1) {
00041 DEBUG(0,("setup_out_fd: Failed to create file %s. (%s)\n",
00042 path, strerror(errno) ));
00043 return -1;
00044 }
00045
00046 DEBUG(10,("setup_out_fd: Created tmp file %s\n", path ));
00047
00048
00049 unlink(path);
00050 return fd;
00051 }
00052
00053
00054
00055
00056
00057
00058 static int smbrun_internal(const char *cmd, int *outfd, BOOL sanitize)
00059 {
00060 pid_t pid;
00061 uid_t uid = current_user.ut.uid;
00062 gid_t gid = current_user.ut.gid;
00063
00064
00065
00066
00067 drop_effective_capability(KERNEL_OPLOCK_CAPABILITY);
00068 drop_effective_capability(DMAPI_ACCESS_CAPABILITY);
00069
00070
00071
00072 if (outfd && ((*outfd = setup_out_fd()) == -1)) {
00073 return -1;
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 CatchChildLeaveStatus();
00085
00086 if ((pid=sys_fork()) < 0) {
00087 DEBUG(0,("smbrun: fork failed with error %s\n", strerror(errno) ));
00088 CatchChild();
00089 if (outfd) {
00090 close(*outfd);
00091 *outfd = -1;
00092 }
00093 return errno;
00094 }
00095
00096 if (pid) {
00097
00098
00099
00100 int status=0;
00101 pid_t wpid;
00102
00103
00104
00105 while((wpid = sys_waitpid(pid,&status,0)) < 0) {
00106 if(errno == EINTR) {
00107 errno = 0;
00108 continue;
00109 }
00110 break;
00111 }
00112
00113 CatchChild();
00114
00115 if (wpid != pid) {
00116 DEBUG(2,("waitpid(%d) : %s\n",(int)pid,strerror(errno)));
00117 if (outfd) {
00118 close(*outfd);
00119 *outfd = -1;
00120 }
00121 return -1;
00122 }
00123
00124
00125 if (outfd) {
00126 sys_lseek(*outfd, 0, SEEK_SET);
00127 }
00128
00129 #if defined(WIFEXITED) && defined(WEXITSTATUS)
00130 if (WIFEXITED(status)) {
00131 return WEXITSTATUS(status);
00132 }
00133 #endif
00134
00135 return status;
00136 }
00137
00138 CatchChild();
00139
00140
00141
00142
00143
00144
00145 if (outfd) {
00146 close(1);
00147 if (sys_dup2(*outfd,1) != 1) {
00148 DEBUG(2,("Failed to create stdout file descriptor\n"));
00149 close(*outfd);
00150 exit(80);
00151 }
00152 }
00153
00154
00155
00156
00157 become_user_permanently(uid, gid);
00158
00159 if (getuid() != uid || geteuid() != uid ||
00160 getgid() != gid || getegid() != gid) {
00161
00162
00163 exit(81);
00164
00165 }
00166
00167 #ifndef __INSURE__
00168
00169
00170 {
00171 int fd;
00172 for (fd=3;fd<256;fd++) close(fd);
00173 }
00174 #endif
00175
00176 {
00177 const char *newcmd = sanitize ? escape_shell_string(cmd) : cmd;
00178 if (!newcmd) {
00179 exit(82);
00180 }
00181 execl("/bin/sh","sh","-c",newcmd,NULL);
00182 }
00183
00184
00185 exit(83);
00186 return 1;
00187 }
00188
00189
00190
00191
00192
00193 int smbrun_no_sanitize(const char *cmd, int *outfd)
00194 {
00195 return smbrun_internal(cmd, outfd, False);
00196 }
00197
00198
00199
00200
00201
00202 int smbrun(const char *cmd, int *outfd)
00203 {
00204 return smbrun_internal(cmd, outfd, True);
00205 }
00206
00207
00208
00209
00210
00211
00212
00213 int smbrunsecret(const char *cmd, const char *secret)
00214 {
00215 pid_t pid;
00216 uid_t uid = current_user.ut.uid;
00217 gid_t gid = current_user.ut.gid;
00218 int ifd[2];
00219
00220
00221
00222
00223 drop_effective_capability(KERNEL_OPLOCK_CAPABILITY);
00224 drop_effective_capability(DMAPI_ACCESS_CAPABILITY);
00225
00226
00227 if(pipe(ifd)) {
00228 return -1;
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 CatchChildLeaveStatus();
00240
00241 if ((pid=sys_fork()) < 0) {
00242 DEBUG(0, ("smbrunsecret: fork failed with error %s\n", strerror(errno)));
00243 CatchChild();
00244 return errno;
00245 }
00246
00247 if (pid) {
00248
00249
00250
00251 int status = 0;
00252 pid_t wpid;
00253 size_t towrite;
00254 ssize_t wrote;
00255
00256 close(ifd[0]);
00257
00258 towrite = strlen(secret);
00259 wrote = write(ifd[1], secret, towrite);
00260 if ( wrote != towrite ) {
00261 DEBUG(0,("smbrunsecret: wrote %ld of %lu bytes\n",(long)wrote,(unsigned long)towrite));
00262 }
00263 fsync(ifd[1]);
00264 close(ifd[1]);
00265
00266
00267 while((wpid = sys_waitpid(pid, &status, 0)) < 0) {
00268 if(errno == EINTR) {
00269 errno = 0;
00270 continue;
00271 }
00272 break;
00273 }
00274
00275 CatchChild();
00276
00277 if (wpid != pid) {
00278 DEBUG(2, ("waitpid(%d) : %s\n", (int)pid, strerror(errno)));
00279 return -1;
00280 }
00281
00282 #if defined(WIFEXITED) && defined(WEXITSTATUS)
00283 if (WIFEXITED(status)) {
00284 return WEXITSTATUS(status);
00285 }
00286 #endif
00287
00288 return status;
00289 }
00290
00291 CatchChild();
00292
00293
00294
00295
00296
00297 close(ifd[1]);
00298 close(0);
00299 if (sys_dup2(ifd[0], 0) != 0) {
00300 DEBUG(2,("Failed to create stdin file descriptor\n"));
00301 close(ifd[0]);
00302 exit(80);
00303 }
00304
00305
00306
00307
00308 become_user_permanently(uid, gid);
00309
00310 if (getuid() != uid || geteuid() != uid ||
00311 getgid() != gid || getegid() != gid) {
00312
00313
00314 exit(81);
00315
00316 }
00317
00318 #ifndef __INSURE__
00319
00320
00321 {
00322 int fd;
00323 for (fd = 3; fd < 256; fd++) close(fd);
00324 }
00325 #endif
00326
00327 execl("/bin/sh", "sh", "-c", cmd, NULL);
00328
00329
00330 exit(82);
00331 return 1;
00332 }