Hello, I'm trying to implement setting of user limits (ulimit) in sshd. I'm not using PAM so I need it in the sshd itself. The task is very simple - just to put one line calling setup_limits(pw); and link with -lshadow. But the problem is, where to put this line. I did it in session.c, in do_child(), like this: #ifdef HAVE_OSF_SIA session_setup_sia(pw, s->ttyfd == -1 ? NULL : s->tty); if (!check_quietlogin(s, command)) do_motd(); #else /* HAVE_OSF_SIA */ /* When PAM is enabled we rely on it to do the nologin check */ if (!options.use_pam) { do_nologin(pw); setup_limits(pw); /* Setting up user limits */ } do_setusercontext(pw); /* * PAM session modules in do_setusercontext may have * generated messages, so if this in an interactive * login then display them too. */ if (!check_quietlogin(s, command)) display_loginmsg(); But I found a problem - in this place the code is already running with the user privileges, so the limits file (/etc/limits) is unreadable for it (normaly it's owned by root with privs 600). If I chmod to 644 or chown to the user trying to log in, it can be read and the limits are set. To be honest I don't understand, why it's happening before calling do_setusercontext(pw), but it is. I would need a better place, where to put this call, already in the child process but still running with root privs. With regards, Pavel
On Thu, 29 Nov 2018, Pavel Troller wrote:> Hello, > I'm trying to implement setting of user limits (ulimit) in sshd. I'm > not using PAM so I need it in the sshd itself. The task is very simple - > just to put one line calling setup_limits(pw); and link with -lshadow. > But the problem is, where to put this line. I did it in session.c, > in do_child(), like this: > > #ifdef HAVE_OSF_SIA > session_setup_sia(pw, s->ttyfd == -1 ? NULL : s->tty); > if (!check_quietlogin(s, command)) > do_motd(); > #else /* HAVE_OSF_SIA */ > /* When PAM is enabled we rely on it to do the nologin check */ > if (!options.use_pam) { > do_nologin(pw); > setup_limits(pw); /* Setting up user limits */ > } > do_setusercontext(pw); > /* > * PAM session modules in do_setusercontext may have > * generated messages, so if this in an interactive > * login then display them too. > */ > if (!check_quietlogin(s, command)) > display_loginmsg(); > > But I found a problem - in this place the code is already running with > the user privileges, so the limits file (/etc/limits) is unreadable for > it (normaly it's owned by root with privs 600). If I chmod to 644 > or chown to the user trying to log in, it can be read and the limits are > set. To be honest I don't understand, why it's happening before calling > do_setusercontext(pw), but it is. > I would need a better place, where to put this call, already in the child > process but still running with root privs.You should read the file in ssh.c:privsep_postauth() just after the /* child */ comment (sshd still has root privs there) but actually apply the limits where you have them in do_child(). -d
Hello Damien, thank you for your advice! Do you think that something is explicitly wrong with putting all the setup_lmits() call to the place you pointed out ? I tried it and it seems to be perfectly working. I believe that there is nothing which requires unmodified limits between this place and the one where the call has been placed originally. Following your advice exactly would require a lot of work with reimplementing the libshadow call by splitting it into two parts, one reading the file and second applying the limits, including a mechanism for handing the read limits over (so probably extending struct authctxt with the limit values or so), which seems to me too expensive for such a simple task. So, I'll do it only if there is something really wrong with the unsplitted variant (a security problem, possibility of crash etc).... which I cannot see from my perspective of a foreigner in the Land of OpenSSH :-). With regards, Pavel On Thu, 29 Nov 2018 at 09:32, Damien Miller <djm at mindrot.org> wrote:> On Thu, 29 Nov 2018, Pavel Troller wrote: > > > Hello, > > I'm trying to implement setting of user limits (ulimit) in sshd. I'm > > not using PAM so I need it in the sshd itself. The task is very simple - > > just to put one line calling setup_limits(pw); and link with -lshadow. > > But the problem is, where to put this line. I did it in session.c, > > in do_child(), like this: > > > > #ifdef HAVE_OSF_SIA > > session_setup_sia(pw, s->ttyfd == -1 ? NULL : s->tty); > > if (!check_quietlogin(s, command)) > > do_motd(); > > #else /* HAVE_OSF_SIA */ > > /* When PAM is enabled we rely on it to do the nologin check */ > > if (!options.use_pam) { > > do_nologin(pw); > > setup_limits(pw); /* Setting up user limits */ > > } > > do_setusercontext(pw); > > /* > > * PAM session modules in do_setusercontext may have > > * generated messages, so if this in an interactive > > * login then display them too. > > */ > > if (!check_quietlogin(s, command)) > > display_loginmsg(); > > > > But I found a problem - in this place the code is already running with > > the user privileges, so the limits file (/etc/limits) is unreadable for > > it (normaly it's owned by root with privs 600). If I chmod to 644 > > or chown to the user trying to log in, it can be read and the limits are > > set. To be honest I don't understand, why it's happening before calling > > do_setusercontext(pw), but it is. > > I would need a better place, where to put this call, already in the > child > > process but still running with root privs. > > You should read the file in ssh.c:privsep_postauth() just after > the /* child */ comment (sshd still has root privs there) but > actually apply the limits where you have them in do_child(). > > -d >