• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: launchd daemon, spawning children?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: launchd daemon, spawning children?


  • Subject: Re: launchd daemon, spawning children?
  • From: Terry Lambert <email@hidden>
  • Date: Wed, 1 Oct 2008 12:21:19 -0700

On Oct 1, 2008, at 3:40 AM, Mario Emmenlauer wrote:
Hi Terry and List,
Terry Lambert wrote:
On Sep 26, 2008, at 2:37 AM, Mario Emmenlauer wrote:
Damien Sorresso wrote:
The rules of setuid(2) have evolved into a vastly complex morass with subtle variations on different platforms. Entire papers have been written about this behavior.

You name it. I will look for a good tutorial, though Terry's suggestion
contained a nice start.
The primary paper on UNIX setuid() is:
   Setuid Demystified
   Hao Chen, David Wagner, Drew Dean
   Proceedings of the 11th USENIX Security Symposium
   <www.cs.berkeley.edu/~daw/papers/setuid-usenix02.pdf>

Thanks a lot, the paper is great! I finally ended up with something like (pseudocode): fork(); if(pid == 0) { setgroups(); setgid();


You probably actually want:

	setgid();
	syscall(SYS_initgroups, int ngroups, const gid_t *gidset, uid_t gmuid)

If you do not set the group membership uid, and do it without any other modifications of the credential, save the final setuid(), then you will opt out of external group resolution. This means that if you have put a user into more than 16 groups in DirectoryServices, you wil only see 16 of them, and due to ordering ambiguity, you will only be guaranteed that the primary group ID for the user will be in that list of 16.

As I said, it gets complicated.

       setuid();
       close_nonstd_file_descriptors();
       execve("/path/to/worker");
       _exit();
   } else {
       while(1) { waitpid(WNONBLOCK); usleep(1000); }
   }

This works very well, and makes sure the worker process can not gain
higher permissions than it should have. Don't mind the while(1) above,
in practice I have a network connection open between worker and server
to get error-feedback, so the server won't get stuck.


In general, we do not want you to establish your own sessions, and would prefer that you use /bin/login to do session management and support the utmp/utmpx interfaces for process accounting and knowing who is logged into your system, etc.; otherwise, things get more complicated fast, in order to support those interfaces, since you have to (1) maintain privilege in order to access the files to write out the closure records on sessions started by you (login does this - it hangs around until its children go away), and (2) deal with PAM and all the other things login deals with for authenticating you to the system.

Your suggestion to use login seems reasonable. Can someone sketch an outline how an application (daemon) would use login to start a new process as a certain user? Is that what you meant: execve("/bin/login -f worker_user /path/to/worker")

Typically, it's not used for daemons. daemons are expected to be started by launchd, which will do the session establishing. Establishing your own session is intended to be limited to interactive sessions. If you have more questions about interactive sessions and the login program, you should look at the sources for sshd or ftpd.



One last question: If "worker_user" is the current GUI-user, all his
applications get killed on logout. Is there a way around this (or would
using 'login' also solve this issue?)

The logout operation for non-GUI applications sends either a SIGHUP (the correct signal), or a SIGTERM (not the correct signal). You can ignore or catch these signals with a signal handler, although if you ignore SIGTERM, you will delay shutdowns.


In general, daemons running as that user are not kiplled unless they are in the process group, or their parent is the per-session launchd. Otherwise, you would not be able to ssh into a machine and log out of a GUI and not have it kill your ssh (which it doesn't do).

-- Terry
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • daemon-child dies on user lougout
      • From: Mario Emmenlauer <email@hidden>
    • Re: launchd daemon, spawning children?
      • From: Kevin Van Vechten <email@hidden>
References: 
 >Re: launchd daemon, spawning children? (From: Mario Emmenlauer <email@hidden>)

  • Prev by Date: Re: locale and file functions
  • Next by Date: Re: Open Firmware on Pismo
  • Previous by thread: Re: launchd daemon, spawning children?
  • Next by thread: Re: launchd daemon, spawning children?
  • Index(es):
    • Date
    • Thread