[Dev] Tizen 3.0 / multiuser: using PAM to maintain user environment inside AMD

Schaufler, Casey casey.schaufler at intel.com
Wed Oct 16 17:57:14 GMT 2013


> -----Original Message-----
> From: dev-bounces at lists.tizen.org [mailto:dev-bounces at lists.tizen.org] On
> Behalf Of Stéphane Desneux
> Sent: Wednesday, October 16, 2013 10:46 AM
> To: dev at lists.tizen.org
> Subject: [Dev] Tizen 3.0 / multiuser: using PAM to maintain user environment
> inside AMD
> 
> Hello,
> 
> Following the recent discussions on multiuser support in Tizen 3.0, I dug
> further on the steps involved in a user session creation.
> 
> NB: I used the latest IVI release 20131015.1 for investigation.
> 
> Actual situation
> ================
> 
> The default Systemd target is the graphical.target. In particular, this target
> will launch the following services in this order:
>    * ac.service (AMD daemon)
>    * launchpad-preload at app.service (launchpad for binary apps: OSP Apps,
> Core Apps and even usual apps like weston-terminal)
>    * wrt_launchpad_daemon at app.service (launchpad for web apps)
>    * user-session at 5000.service: opens the 'app' user session (starts systemd -
> -user)
> 
> So before the user-session start, we have AMD and its launchpads running as
> root (despite the name 'xxx at app.service' for launchpads).
> 
> The user-session at .service is particular, as it contains:
> - User=%I (i.e. User=app)
> - PAMName=login
> - ExecStart=-/usr/lib/systemd/systemd --user
> - Environment=.... (static env variables)
> 
> The PAMName=login setting makes that systemd will open a PAM session
> with the pam service 'login' before starting systemd --user as 'app'.
> Respectively, when the user session terminates, the PAM session is closed
> too.
> 
> In the actual pam configuration, opening a 'login' session will call the
> pam_systemd module (included in systemd). This modules sends a DBus
> message to systemd login manager (systemd-logind) and gets some
> information in the response. This information is used to initialize some
> important environment variables. When the session terminates, the
> pam_systemd module also tells systemd-logind that the user session ended
> (and depending on its configuration, systemd-logind could kill any remaining
> user processes).
> 
> The following diagram tries to show what happens when systemd starts the
> user-session (bold=run as root, other run as user)
> 
> ---------------------------- *systemd-logind*
> --------*systemd*                  |
>   |          |                      ^
>   |          |                      |
>   |          v                      |(un)register
>   |     *PAM session*               |
>   |     *pam_systemd*-<-(dbus msg)--
>   |          |
>   |          |
>   |          v
>   |       systemd --user -------------------
>   |                                |
>   |                                |
>   |                                -> ... services inside user session
>   |
>   |
>   |
>   ---> *amd & launchpads*
> ------------------------------------------------------
> 
> NB on IVI: actually, weston is started inside the user session using weston-
> launch. IMO this is not the right way to do things as weston-launch (setuid
> root) clears the actual environment, opens a new PAM session then forks a
> login shell which exec() weston (!). So there's a second PAM session opened
> but moreover, all the environment variables propagated from the top are
> erased: that's why we have to put workarounds for environment vars
> everywhere (in service files, in /etc/sysconfig, in /etc/profile.d and probably
> in some other places)...
> 
> Proposition for the future
> ==========================
> 
> As described previously on this list, we'll probably agree on having a global
> AMD daemon with its launchpads, running as root (or at least as a privileged
> user). The consequence is that we have to push information to AMD
> concerning the user sessions and appropriate environment within each
> session.
> 
>  From what I've seen in pam_systemd code (see here:
> https://review.tizen.org/gerrit/gitweb?p=platform/upstream/systemd.git;a
> =blob;f=src/login/pam-
> module.c;h=13290fd8ea6de3fcbb621e99dc7d92e7be50a030;hb=HEAD),
> we have the following vars initialized before running systemd --user:
> - coming from pam_env.so (/etc/environment)
>    * nothing (yet)
> - coming from systemd-logind:
>    * XDG_SESSION_ID
>    * XDG_RUNTIME_DIR
>    * XDG_SEAT
>    * XDG_VTNR
> - coming from user-session at .service (static vars in service):
>    * DISPLAY
>    * XDG_RUNTIME_DIR (useless...)
>    * DBUS_SESSION_BUS_ADDRESS
> - other usual variables set at login time:
>    * HOME
>    * USER
>    * LOGNAME
>    * LANG
>    * PATH
> 
> So, to initialize a user-session environment in AMD, we could have a
> pam_amd module started *after* pam_systemd and responsible for sending
> the "init" request to AMD with the current environment. AMD would record
> the appropriate environment for the given user/session (uid, sid). This env
> would then be pushed to launchpads every time an application must be
> started.
> 
> Later during the user session, when the environment is complete (ex:
> desktop is started and we have WAYLAND_DISPLAY set), we could then
> update the environment in AMD, with some update policies: for example, an
> environment variable that was already set at init() time can't be updated by
> update() (we keep the initial value).
> 
> We'd get something like this:
> 
> ---------------------------- *systemd-logind*
> ----------*systemd*                  |
>   |            |                      ^
>   |            |                      |
>   |            v                      |(un)register
>   |       *PAM session*               |
>   |       *pam_systemd*-<-(dbus msg)--
>   |    ---*pam_amd*
>   |    |       |
>   |    |       |
>   |    |       v
>   |    |    systemd --user -------------------
>   |    |                    |
>   |    |                    |
>   |    |                    -> ......  services inside user session
> ...........
>   |    |                         |                        |               ^
>   |    |                         |                        |               |
>   |    |init(uid,sid,[env])      |update(uid,sid,[env])   |launch(app)    |
>   |    |                         |                        |               |
>   |    V                         v                        V               |
>   -> *amd* -----------------------------------------------+------         |
>   |                                                       |               |
>   |                                                       |      apply env|
>   |                                  launch(app,uid,[env])|   & launch app|
>   |                                                       v               |
>   ------>
> *launchpads*---------------------------------------------------------
> 
> Remark 1: Wether we have one environment per user or one environment
> per session is actually discussed... Given the previous diagram, do we know
> that a launch request comes from a given session ? It seems that we can
> handle both cases by adding the origin session id to the launch request.
> But I'm a bit wary about handling uid+session id actually because of extra
> error handling and added complexity. Do we have use cases for this ?
> 
> Remark 2: I didn't draw user session termination. Of course, it's the
> opposite: pam_amd would send an exit(uid,sid) to AMD to block any future
> launch for this session.
> 
> 
> Discussion
> ==========
> 
> What do you think of this "pam_amd" module ?
> 
> Even later when some new mechanisms will be used to open a user session,
> I'm quite sure we'll still have a PAM session: this is just a standard behaviour
> on any linux distro. So using a PAM lib to propagate the session environment
> to AMD makes sense and would certainly allow a smoother transition to
> anything else in the future.
> 
> Hope you love ASCII art ;)

Great job of taking the design to the next level. The ASCII art goes a long way in making the description clear.


> --
> Stéphane Desneux
> Intel OTC - Vannes/FR
> _______________________________________________
> Dev mailing list
> Dev at lists.tizen.org
> https://lists.tizen.org/listinfo/dev


More information about the Dev mailing list