procmail
[Top] [All Lists]

Re: Replacing /bin/sh in procmail

1997-02-06 22:58:57
"Tony Zamora" <zamora(_at_)VNET(_dot_)IBM(_dot_)COM> writes:
...
If we put

SHELL=/usr/afsws/bin/pagsh

in /etc/procmailrc, the user can override this by putting

SHELL=/bin/sh

in their .procmailrc

What we want is for them either not to be able to override this or
(better) guarantee that /usr/afsws/bin/pagsh runs first.  Procmail is
running with an AFS token that lets it write to the user's mailbox.
We want to make sure that procmail loses its token whenever the user
starts a program from .procmailrc.  Running pagsh guarantees that
the shell command will run without a token.  But this is no good if
the user can reset things so pagsh doesn't run.

What do we need to do?

Assuming that pagsh takes the -c argument like normal shells (or passes
it on to a real shell), I think that only two changes are necessary:

1) In misc.c, change metaparse() to read:

void metaparse(p)const char*p;                              /* result in buf */
{ sh=1; strcpy(buf,p);                   /* copy literally, shell will parse */
}

2) In goodies.c, line 105, inside readparse(), remove the if statement:

                       if(!(sh=!!strpbrk(startb,shellmetas)))
                        { const char*save=sgetcp,*sAll_args;
                          sgetcp=p=tstrdup(startb);sAll_args=All_args;
                          readparse(startb,sgetc,0);All_args=sAll_args;
#ifndef GOT_bin_test
                          if(!strcmp(test,startb))
                             strcpy(startb,p),sh=1;    /* oops, `test' found */
#endif
                          free(p);sgetcp=save;                 /* chopped up */
                        }           /* drop source buffer, read from program */


3) In pipes.c, change callnewprog() to read:

static void callnewprog(newname)const char*const newname;
{ if(1)                                          /* should we start a shell? */
   { const char*newargv[4];
     yell(executing,newname);newargv[3]=0;newargv[2]=newname;
     newargv[1]=shellflags;*newargv="/usr/afsws/bin/pagsh";shexec(newargv);
   }
}


The first two changes make procmail ignore the SHELLMETAS variable
and always invoke a real shell, while the third makes it ignore the
SHELL variable and always invoke
        /usr/afsws/bin/pagsh "$SHELLFLAGS" 'command with args'
The SHELL and SHELLMETAS environment variables will still be passed in the
environment to pagsh, so pagsh should, after disinheriting the AFS token,
just say (in C):

        argv[0] = getenv("SHELL");
        if (argv[0] == NULL)
            argv[0] = "/bin/sh";
        execv(argv[0], argv);
        /* choke...  I think POSIX reserves 127 and/or 126 for
         * "unable to locate/execute command".  Check the docs on
         * "find" in the POSIX.2 (or whatever the number is now) spec. */
        exit(127);

It should otherwise ignore "argv", as it has no reason to care.

NOTE: this should be documented somewhere obvious so your users don't get
confused when the otherwise valid recipe:

        :0:
        * some conditions...
        | some program that plays with mail messages >>$DEFAULT

fails.  This'll have to be rewritten as a filter:

        :0 f
        * some conditions...
        | some program that plays with mail messages
        :0 A:
        $DEFAULT

which is more memory and CPU intensive and harder to modify.


BTW: why do you want to do this?


Philip Guenther

<Prev in Thread] Current Thread [Next in Thread>