Re: launchd daemon, spawning children?
site_archiver@lists.apple.com Delivered-To: Darwin-dev@lists.apple.com Hi Terry and List, Terry Lambert wrote: 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) 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. 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") -- Terry _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-dev mailing list (Darwin-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-dev/site_archiver%40lists.appl... On Oct 1, 2008, at 3:40 AM, Mario Emmenlauer 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. 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. 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. 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). This email sent to site_archiver@lists.apple.com
participants (1)
-
Terry Lambert