Darren J Moffat wrote:
> Scott Rotondo wrote:
>>
>> Do you get the same result from "pfexec /u01/apps/bin/logLvl" after
>> fixing the previous typo in the profile name? If so, that indicates that
>> pfexec is checking for execute permission before setting the attributes
>> in the profile. If it happens, that's arguably a bug.
> 
> Which is. In patchsearch() there is even a comment that indicates why it 
> is doing this:
> 
>                  if (stat(buf, &stbuf) < 0)
>                          continue;
>                  /*
>                   * Shells typically call access() with E_OK flag
>                   * to determine if the effective uid can execute
>                   * the file. We don't know what the eventual euid
>                   * will be; it is determined by the exec_attr
>                   * attributes which depend on the full pathname of
>                   * the command. Therefore, we match the first regular
>                   * file we find that is executable by someone.
>                   */
>                  if (S_ISREG(stbuf.st_mode) && S_ISEXEC(stbuf.st_mode)) {
>                          result = strdup(buf);
>                          break;
>                  }
> 
> Which BTW you wrote Scott :-) as part of implementing:
> 
> 6723298 pfexec should do a better job searching PATH and reporting errors
> 

Yes, I did write that. However, this code is not involved in Prasad's 
situation for two reasons:

1. The S_ISEXEC() macro above checks that the file is executable by one 
of {user,group,other}, which it is in Prasad's case.

2. This block of code is only used for PATH searching, not when a full 
pathname is supplied for the command, as in Prasad's case.

After a little investigation, I now know what's actually causing the 
problem (and how to fix it). The basic algorithm for pfexec is as follows:

1. Locate the file to be executed by searching PATH if necessary. 
[Nothing to do in this case because we're given a full pathname.]

2. Use getrealpath() to determine the canonical pathname for the file.

3. Look up the canonical pathname in the user's profiles to find the 
attributes (user/group ids and privileges).

4. Apply the attributes to this process.

5. Execute the program.

If you have a mode 500 executable and someone other than the owner tries 
to execute it using a rights profile specifying "privs=all" it won't 
work. On the other hand, if the profile specifies "uid=<owner>" it will 
work.

The reason for the difference is the way that step 4 above is 
implemented. User and group id attributes are set by modifying the 
relevant id's of the process *before* calling exec(). Privileges are set 
using the process's inheritable privilege set, which becomes the new 
effective set *during* the exec() call. Since the privileges are not in 
effect when exec() is called, they can't be used to override file 
permissions.

If it's important to restrict execute permissions on the program, then 
the best solution I see for Prasad is to have the profile entry specify 
the necessary uid either instead of or in addition to privileges.

        Scott

Reply via email to