Ticket #652: sge-peopen.patch

File sge-peopen.patch, 18.4 KB (added by opoplawski, 4 years ago)

Patch to drop sge_peopen()

  • doc/devel/style_guide.txt

    diff --git a/doc/devel/style_guide.txt b/doc/devel/style_guide.txt
    index 3edbef0..ca6a50a 100644
    a b DRAFT of a Coding Styleguide 
    133133               module specific prefix.
    134134               Examples:
    135135                  - cull_pack_descr()
    136                   - sge_peopen()
     136                  - sge_peopen_r()
    137137
    138138         (M)   All names (of datatypes, constants, functions ...) that can be
    139139               associated to an object begin with the objects name.
  • source/daemons/execd/sge_load_sensor.c

    diff --git a/source/daemons/execd/sge_load_sensor.c b/source/daemons/execd/sge_load_sensor.c
    index ea39344..49bc1bd 100644
    a b static int sge_ls_status(lListElem *this_ls) 
    223223*        LS_in, LS_out, LS_err are the FILE-streams for the
    224224*        communication with the ls-process     
    225225*        returns LS_OK
    226 *     If sge_peopen fails, returns LS_CANT_PEOPEN     
     226*     If sge_peopen_r fails, returns LS_CANT_PEOPEN     
    227227******************************************************************************/
    228228static int sge_ls_start_ls(const char *qualified_hostname, lListElem *this_ls)
    229229{
    static int sge_ls_start_ls(const char *qualified_hostname, lListElem *this_ls) 
    250250   }
    251251
    252252   /* we need fds for select() .. */
    253    pid = sge_peopen("/bin/sh", 0, lGetString(this_ls, LS_command), NULL, envp,
     253   pid = sge_peopen_r("/bin/sh", 0, lGetString(this_ls, LS_command), NULL, envp,
    254254                &fp_in, &fp_out, &fp_err, true);
    255255
    256256   if (envp) {
  • source/libs/gdi/sge_security.c

    diff --git a/source/libs/gdi/sge_security.c b/source/libs/gdi/sge_security.c
    index caef73e..3ac339c 100644
    a b int set_sec_cred(const char *sge_root, const char *mastername, lListElem *job, l 
    673673         DRETURN(-1);
    674674      }   
    675675     
    676       command_pid = sge_peopen("/bin/sh", 0, binary, NULL, NULL, &fp_in, &fp_out, &fp_err, false);
     676      command_pid = sge_peopen_r("/bin/sh", 0, binary, NULL, NULL, &fp_in, &fp_out, &fp_err, false);
    677677
    678678      if (command_pid == -1) {
    679679         answer_list_add_sprintf(alpp, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR,
    int set_sec_cred(const char *sge_root, const char *mastername, lListElem *job, l 
    704704
    705705      snprintf(cmd, sizeof(cmd), "%s %s%s%s", binary, "sge", "@", mastername);
    706706     
    707       command_pid = sge_peopen("/bin/sh", 0, cmd, NULL, NULL, &fp_in, &fp_out, &fp_err, false);
     707      command_pid = sge_peopen_r("/bin/sh", 0, cmd, NULL, NULL, &fp_in, &fp_out, &fp_err, false);
    708708
    709709      if (command_pid == -1) {
    710710         answer_list_add_sprintf(alpp, STATUS_EUNKNOWN, ANSWER_QUALITY_ERROR,
    bool cache_sec_cred(const char* sge_root, lListElem *jep, const char *rhost) 
    801801
    802802         snprintf(cmd, sizeof(cmd), "%s %s%s%s", binary, "sge", "@", rhost);
    803803
    804          command_pid = sge_peopen("/bin/sh", 0, cmd, NULL, env, &fp_in, &fp_out, &fp_err, false);
     804         command_pid = sge_peopen_r("/bin/sh", 0, cmd, NULL, env, &fp_in, &fp_out, &fp_err, false);
    805805
    806806         if (command_pid == -1) {
    807807            ERROR((SGE_EVENT, MSG_SEC_NOSTARTCMD4GETCRED_SU,
    void delete_credentials(const char *sge_root, lListElem *jep) 
    876876
    877877         snprintf(cmd, sizeof(cmd), "%s -s %s", binary, "sge");
    878878
    879          command_pid = sge_peopen("/bin/sh", 0, cmd, NULL, env, &fp_in, &fp_out, &fp_err, false);
     879         command_pid = sge_peopen_r("/bin/sh", 0, cmd, "root", env, &fp_in, &fp_out, &fp_err, false);
    880880
    881881         if (command_pid == -1) {
    882882            sge_strlcpy(tmpstr, SGE_EVENT, sizeof(tmpstr));
    int store_sec_cred(const char* sge_root, sge_gdi_packet_class_t *packet, lListEl 
    955955         snprintf(cmd, sizeof(cmd), "%s -s %s -u %s", binary, "sge",
    956956                  lGetString(jep, JB_owner));
    957957
    958          command_pid = sge_peopen("/bin/sh", 0, cmd, NULL, env, &fp_in, &fp_out, &fp_err, false);
     958         command_pid = sge_peopen_r("/bin/sh", 0, cmd, NULL, env, &fp_in, &fp_out, &fp_err, false);
    959959
    960960         if (command_pid == -1) {
    961961            ERROR((SGE_EVENT, MSG_SEC_NOSTARTCMD4GETCRED_SU,
    int store_sec_cred2(const char* sge_root, const char* unqualified_hostname, lLis 
    10801080         snprintf(cmd, sizeof(cmd), "%s -s %s -u %s -b %s", binary, "sge",
    10811081                  lGetString(jelem, JB_owner), lGetString(jelem, JB_owner));
    10821082
    1083          command_pid = sge_peopen("/bin/sh", 0, cmd, NULL, env, &fp_in, &fp_out, &fp_err, false);
     1083         command_pid = sge_peopen_r("/bin/sh", 0, cmd, "root", env, &fp_in, &fp_out, &fp_err, false);
    10841084
    10851085         if (command_pid == -1) {
    10861086            ERROR((SGE_EVENT, MSG_SEC_NOSTARTCMD4GETCRED_SU, binary, sge_u32c(lGetUlong(jelem, JB_job_number))));
  • source/libs/uti/sge_afsutil.c

    diff --git a/source/libs/uti/sge_afsutil.c b/source/libs/uti/sge_afsutil.c
    index 1cdaf89..46881ea 100644
    a b char *sge_read_token(const char *file) 
    130130*
    131131*  NOTES
    132132*     MT-NOTE: sge_afs_extend_token() is not MT safe because it uses MT unsafe
    133 *     MT-NOTE: sge_peopen()
    134133*
    135134*  RESULT
    136135*     int - error state
    int sge_afs_extend_token(const char *command, char *tokenbuf, const char *user, 
    152151      sge_strlcpy(err_str, cmdbuf, lstr);
    153152   }
    154153
    155    command_pid = sge_peopen("/bin/sh", 0, cmdbuf, NULL, NULL,
     154   command_pid = sge_peopen_r("/bin/sh", 0, cmdbuf, NULL, NULL,
    156155                        &fp_in, &fp_out, &fp_err, false);
    157156   if (command_pid == -1) {
    158157      if (err_str) {
  • source/libs/uti/sge_os.c

    diff --git a/source/libs/uti/sge_os.c b/source/libs/uti/sge_os.c
    index b13c9e1..3027401 100644
    a b int sge_get_pids(pid_t *pids, int max_pids, const char *name, 
    109109
    110110   DENTER(TOP_LAYER, "sge_get_pids");
    111111   
    112    command_pid = sge_peopen("/bin/sh", 0, pscommand, NULL, NULL,
     112   command_pid = sge_peopen_r("/bin/sh", 0, pscommand, NULL, NULL,
    113113                        &fp_in, &fp_out, &fp_err, false);
    114114
    115115   if (command_pid == -1) {
    int sge_contains_pid(pid_t pid, pid_t *pids, int npids) 
    213213*     int - result state
    214214*         0 - Process with "pid" has "name"
    215215*         1 - No such pid or pid has other name
    216 *        -1 - error occurred (mostly sge_peopen() failed)
     216*        -1 - error occurred (mostly sge_peopen_r() failed)
    217217*
    218218*  NOTES
    219219*     MT-NOTES: sge_checkprog() is not MT safe
    int sge_checkprog(pid_t pid, const char *name, const char *pscommand) 
    227227
    228228   DENTER(TOP_LAYER, "sge_checkprog");
    229229
    230    command_pid = sge_peopen("/bin/sh", 0, pscommand, NULL, NULL,
     230   command_pid = sge_peopen_r("/bin/sh", 0, pscommand, NULL, NULL,
    231231                        &fp_in, &fp_out, &fp_err, false);
    232232
    233233   if (command_pid == -1) {
  • source/libs/uti/sge_smf.c

    diff --git a/source/libs/uti/sge_smf.c b/source/libs/uti/sge_smf.c
    index 2932b4b..8e79169 100644
    a b static int contracts_pre_fork(void) 
    715715   /*   
    716716    * EB: IMPORTANT: Logging in this function is not allowed
    717717    *   
    718     * Reason: This function is used in sge_peopen().
     718    * Reason: This function is used in sge_peopen_r().
    719719    *
    720720    *         In multi threaded environments the child might run into a deadlock situation
    721721    *         if it tries to get a lock which was hold by one of the parent threads
    static int contracts_post_fork(int ctfd, int pid, char *err_str, int err_length) 
    789789   /*   
    790790    * EB: IMPORTANT: Logging in this function is not allowed
    791791    *   
    792     * Reason: This function is used in sge_peopen().
     792    * Reason: This function is used in sge_peopen_r().
    793793    *
    794794    *         In multi threaded environments the child might run into a deadlock situation
    795795    *         if it tries to get a lock which was hold by one of the parent threads
    int sge_smf_contract_fork(char *err_str, int err_length) 
    897897   /*   
    898898    * EB: IMPORTANT: Logging in this function is not allowed
    899899    *   
    900     * Reason: This function is used in sge_peopen().
     900    * Reason: This function is used in sge_peopen_r().
    901901    *
    902902    *         In multi threaded environments the child might run into a deadlock situation
    903903    *         if it tries to get a lock which was hold by one of the parent threads
  • source/libs/uti/sge_stdio.c

    diff --git a/source/libs/uti/sge_stdio.c b/source/libs/uti/sge_stdio.c
    index 7e615e2..e0379b8 100644
    a b  
    5151#include "uti/sge_os.h"
    5252#include "uti/msg_utilib.h"
    5353#include "uti/sge_time.h"
     54#include "uti/sge_bootstrap.h"
    5455
    5556#include "basis_types.h"
    5657
    static void addenv(char *key, char *value) 
    8586   return;
    8687}
    8788
    88 /*
    89  * TODO: CLEANUP
    90  *
    91  * This function is DEPRECATED and should be removed with the next
    92  * major release.
    93  *
    94  * This function can't be used in multi threaded environments because it
    95  * might cause a deadlock in the executing qmaster thread.
    96  * Use sge_peopen_r() instead.
    97  */
    98 pid_t sge_peopen(const char *shell, int login_shell, const char *command,
    99                  const char *user, char **env,  FILE **fp_in, FILE **fp_out,
    100                  FILE **fp_err, bool null_stderr)
    101 {
    102    pid_t pid;
    103    int pipefds[3][2];
    104    const char *could_not = MSG_SYSTEM_EXECBINSHFAILED;
    105    const char *not_root = MSG_SYSTEM_NOROOTRIGHTSTOSWITCHUSER;
    106    int i;
    107    char arg0[256];
    108    char err_str[256];
    109    uid_t myuid;
    110  
    111    DENTER(TOP_LAYER, "sge_peopen");
    112  
    113    /* open pipes - close on failure */
    114    for (i=0; i<3; i++) {
    115       if (pipe(pipefds[i]) != 0) {
    116          while (--i >= 0) {
    117             close(pipefds[i][0]);
    118             close(pipefds[i][1]);
    119          }
    120          ERROR((SGE_EVENT, MSG_SYSTEM_FAILOPENPIPES_SS,
    121                 command, strerror(errno)));
    122          DEXIT;
    123          return -1;
    124       }
    125    }
    126 
    127 #if __sun
    128    pid = sge_smf_contract_fork(err_str, 256);
    129 #else
    130    pid = fork();
    131 #endif
    132    if (pid == 0) {  /* child */
    133       int keep_open[6];
    134       keep_open[0] = 0;
    135       keep_open[1] = 1;
    136       keep_open[2] = 2;
    137       keep_open[3] = pipefds[0][0];
    138       keep_open[4] = pipefds[1][1];
    139       keep_open[5] = pipefds[2][1];
    140       sge_close_all_fds(keep_open, 6);
    141       /* shall we redirect stderr to /dev/null? */
    142       if (null_stderr) {
    143          /* open /dev/null */
    144          int fd = open("/dev/null", O_WRONLY);
    145          if (fd == -1) {
    146             sprintf(err_str, MSG_ERROROPENINGFILEFORWRITING_SS, "/dev/null", strerror(errno));
    147             sprintf(err_str, "\n");
    148             if (write(2, err_str, strlen(err_str)) != (int)strlen(err_str)) {
    149                /* nothing we can do here - we are anyway about to exit */
    150             }
    151             SGE_EXIT(NULL, 1);
    152          }
    153 
    154          /* set stderr to /dev/null */
    155          close(2);
    156          if (dup(fd) == -1) {
    157             /* we have a serious problem here - nothing we can do but exit */
    158             SGE_EXIT(NULL, 1);
    159          }
    160 
    161          /* we don't need the stderr the pipe - close it */
    162          close(pipefds[2][1]);
    163       } else {
    164          /* redirect stderr to the pipe */
    165          close(2);
    166          if (dup(pipefds[2][1]) == -1) {
    167             /* we have a serious problem here - nothing we can do but exit */
    168             SGE_EXIT(NULL, 1);
    169          }
    170       }
    171 
    172       /* redirect stdin and stdout to the pipes */
    173       close(0);
    174       close(1);
    175       if (dup(pipefds[0][0]) == -1 ||
    176           dup(pipefds[1][1]) == -1) {
    177          /* we have a serious problem here - nothing we can do but exit */
    178          SGE_EXIT(NULL, 1);
    179       }
    180 
    181       if (user) {
    182          struct passwd *pw;
    183          struct passwd pw_struct;
    184          char *buffer;
    185          int size;
    186 
    187          size = get_pw_buffer_size();
    188          buffer = sge_malloc(size);
    189          if (!(pw=sge_getpwnam_r(user, &pw_struct, buffer, size))) {
    190             sprintf(err_str, MSG_SYSTEM_NOUSERFOUND_SS , user, strerror(errno));
    191             sprintf(err_str, "\n");
    192             if (write(2, err_str, strlen(err_str)) != (int)strlen(err_str)) {
    193                /* nothing we can do here - we are anyway about to exit */
    194             }
    195             sge_free(&buffer);
    196             SGE_EXIT(NULL, 1);
    197          }
    198 
    199          myuid = geteuid();
    200          if (myuid != pw->pw_uid) {
    201             /* Only change user if we differ from the wanted user */
    202             if(myuid != SGE_SUPERUSER_UID) {
    203                if (write(2, not_root, sizeof(not_root)) != sizeof(not_root)) {
    204                   /* nothing we can do here - we are anyway about to exit */
    205                }
    206                sge_free(&buffer);
    207                SGE_EXIT(NULL, 1);
    208             }
    209             sprintf(err_str, "%s %d\n", pw->pw_name, (int)pw->pw_gid);
    210             if (write(2, err_str, strlen(err_str)) != (int)strlen(err_str)) {
    211                /* TODO: required protocol step? If sending fails, exit? */
    212             }
    213 #if !(defined(WIN32) || __INTERIX)  /* initgroups not called */
    214             if (initgroups(pw->pw_name, pw->pw_gid) != 0) {
    215                sprintf(err_str, MSG_SYSTEM_INITGROUPSFORUSERFAILED_ISS,
    216                        user, strerror(errno));
    217                sprintf(err_str, "\n");
    218                if (write(2, err_str, strlen(err_str)) != (int)strlen(err_str)) {
    219                   /* nothing we can do here - we are anyway about to exit */
    220                }
    221                sge_free(&buffer);
    222                SGE_EXIT(NULL, 1);
    223             }
    224 #endif /* WIN32 */
    225  
    226             if (sge_setuid(pw->pw_uid)) {
    227                sprintf(err_str, MSG_SYSTEM_SWITCHTOUSERFAILED_SS , user,
    228                      strerror(errno));
    229                sprintf(err_str, "\n");
    230                if (write(2, err_str, strlen(err_str)) != (int)strlen(err_str)) {
    231                   /* nothing we can do here - we are anyway about to exit */
    232                }
    233                sge_free(&buffer);
    234                SGE_EXIT(NULL, 1);
    235             }
    236          }
    237  
    238          addenv("HOME", pw->pw_dir);
    239          addenv("SHELL", pw->pw_shell);
    240          addenv("USER", pw->pw_name);
    241          addenv("LOGNAME", pw->pw_name);
    242          addenv("PATH", SGE_DEFAULT_PATH);
    243 
    244          sge_free(&buffer);
    245       }
    246  
    247       if (login_shell) {
    248          strcpy(arg0, "-");
    249       } else {
    250          strcpy(arg0, "");
    251       }
    252       strcat(arg0, shell);
    253  
    254       if (env) {
    255          for(; *env; env++) {
    256             putenv(*env);
    257          }
    258       }
    259  
    260       execlp(shell, arg0, "-c", command, (char *) NULL);
    261  
    262       if (write(2, could_not, sizeof(could_not)) != sizeof(could_not)) {
    263          /* nothing we can do here - we are anyway about to exit */
    264       }
    265       SGE_EXIT(NULL, 1);
    266    } /* end child */
    267  
    268    if (pid < 0) {
    269       for (i=0; i<3; i++) {
    270          close(pipefds[i][0]);
    271          close(pipefds[i][1]);
    272       }
    273 #if __sun
    274       if (pid < -1) {
    275           ERROR((SGE_EVENT, MSG_SMF_FORK_FAILED_SS, "sge_peopen()", err_str));
    276       }
    277 #endif
    278       /* fork could have failed, report it */
    279       ERROR((SGE_EVENT, MSG_SMF_FORK_FAILED_SS, "sge_peopen()", strerror(errno)));
    280       DRETURN(-1);
    281    }
    282  
    283    /* close the childs ends of the pipes */
    284    close(pipefds[0][0]);
    285    close(pipefds[1][1]);
    286    close(pipefds[2][1]);
    287  
    288    /* return filehandles for stdin and stdout */
    289    *fp_in  = fdopen(pipefds[0][1], "a");
    290    *fp_out = fdopen(pipefds[1][0], "r");
    291 
    292    /* is stderr redirected to /dev/null? */
    293    if (null_stderr) {
    294       /* close the pipe and return NULL as filehandle */
    295       close(pipefds[2][0]);
    296       *fp_err = NULL;
    297    } else {
    298       /* return filehandle for stderr */
    299       *fp_err = fdopen(pipefds[2][0], "r");
    300    }
    301 
    302    DRETURN(pid);
    303 }
    304 
    30589/****** uti/stdio/sge_peopen_r() ************************************************
    30690*  NAME
    30791*     sge_peopen_r() -- Advanced popen()
    pid_t sge_peopen_r(const char *shell, int login_shell, const char *command, 
    373157         DRETURN(-1);
    374158      }
    375159   }
    376    myuid = geteuid();
    377    tuid = myuid;
     160   myuid = getuid();
     161   tuid = geteuid;
    378162
    379163   /*
    380164    * open pipes - close on failure
    pid_t sge_peopen_r(const char *shell, int login_shell, const char *command, 
    409193   DPRINTF(("arg1 = -c\n"));
    410194   DPRINTF(("arg2 = %s\n", command));
    411195
     196   /*
     197    * if we do not specify a user, run as the admin user
     198    */
     199   if (sge_has_admin_user() && !user) {
     200      user = bootstrap_get_admin_user();
     201   }
    412202
    413203   /*
    414204    * prepare the change of the user which might be done after fork()
    pid_t sge_peopen_r(const char *shell, int login_shell, const char *command, 
    477267      }
    478268      DPRINTF(("user = %s\n", user));
    479269      DPRINTF(("myuid = %d\n", (int)myuid));
    480       if (pw != NULL) {
     270      if ((pw != NULL) && (tuid != myuid)) {
    481271         tuid = pw->pw_uid;
    482272         DPRINTF(("target uid = %d\n", (int)tuid));
    483273      }
    pid_t sge_peopen_r(const char *shell, int login_shell, const char *command, 
    578368      }
    579369#if __sun
    580370      if (pid < -1) {
    581           ERROR((SGE_EVENT, MSG_SMF_FORK_FAILED_SS, "sge_peopen()", err_str));
     371          ERROR((SGE_EVENT, MSG_SMF_FORK_FAILED_SS, "sge_peopen_r()", err_str));
    582372      }
    583373#endif
    584374      if (sge_has_admin_user()) {
    pid_t sge_peopen_r(const char *shell, int login_shell, const char *command, 
    618408 
    619409/****** uti/stdio/sge_peclose() ***********************************************
    620410*  NAME
    621 *     sge_peclose() -- pclose() call which is suitable for sge_peopen()
     411*     sge_peclose() -- pclose() call which is suitable for sge_peopen_r()
    622412*
    623413*  SYNOPSIS
    624414*     int sge_peclose(pid_t pid, FILE *fp_in, FILE *fp_out,
    pid_t sge_peopen_r(const char *shell, int login_shell, const char *command, 
    628418*     ???
    629419*
    630420*  INPUTS
    631 *     pid_t pid               - pid returned by peopen()
     421*     pid_t pid               - pid returned by peopen_r()
    632422*     FILE *fp_in
    633423*     FILE *fp_out
    634424*     FILE *fp_err
    pid_t sge_peopen_r(const char *shell, int login_shell, const char *command, 
    638428*     int - exit code of command or -1 in case of errors
    639429*
    640430*  SEE ALSO
    641 *     uti/stdio/peopen()
     431*     uti/stdio/sge_peopen_r()
    642432*
    643433*  NOTES
    644434*     MT-NOTE: sge_peclose() is MT safe
  • source/libs/uti/sge_stdio.h

    diff --git a/source/libs/uti/sge_stdio.h b/source/libs/uti/sge_stdio.h
    index f73b773..c885688 100644
    a b  
    193193
    194194#define CLOSE_IGNORE_ERROR(x) (void) close(x)
    195195
    196 pid_t sge_peopen(const char *shell, int login_shell, const char *command,
    197                  const char *user, char **env, FILE **fp_in, FILE **fp_out,
    198                  FILE **fp_err, bool null_stderr);
    199  
    200196int sge_peclose(pid_t pid, FILE *fp_in, FILE *fp_out, FILE *fp_err,
    201197                struct timeval *timeout);
    202198