about summary refs log tree commit diff
path: root/doc/building.html
blob: ff25de1368ba1e4480779cc8227c1594e234b829 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta http-equiv="Content-Language" content="en" />
    <title>pamela: building an application</title>
    <meta name="Description" content="pamela: building an application" />
    <meta name="Keywords" content="pamela PAM Linux-PAM library" />
    <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
  </head>
<body>

<p>
<a href="index.html">pamela</a><br />
<a href="//skarnet.org/software/">Software</a><br />
<a href="//skarnet.org/">skarnet.org</a>
</p>

<h1> Building an application with pamela instead of Linux-PAM </h1>

<h2> Prerequisites </h2>

<ul>
 <li> The pamela package must have been properly built and installed;
in particular, the <a href="pamelad.html">pamelad</a> binary must
have been properly linked against Linux-PAM's <tt>libpam.so</tt>. </li>
 <li> The <tt>security/pam_appl.h</tt> header, usually installed in
<tt>/usr/include</tt>, must be a symlink to pamela's
<tt>pamela/pam.h</tt> header. This can be achieved by running
<tt>make install-symlink</tt> after <tt>make install</tt> when
building the pamela package. </li>
 <li> The application must strictly follow the
<a href="http://www.linux-pam.org/Linux-PAM-html/adg-interface-by-app-expected.html">Linux-PAM
specification</a>. Note that the page claims that the
<tt>pam_set_item()</tt> function is declared in <tt>security/pam_modules.h</tt>,
but it is a mistake: like every PAM function used by applications, it
is declared in <tt>security/pam_appl.h</tt>. </li>
 <li> The pamela headers and library must be installed, as well as the
<a href="//skarnet.org/software/skalibs/">skalibs</a> headers and library. </li>
</ul>

<h2> Compiling </h2>

<ul>
 <li> Make sure that the pamela headers and the skalibs headers
are visible in your header search path, and that the
Linux-PAM headers <em>are not</em>. </li>
 <li> If the compilation fails, please report the issue to the
skaware mailing-list. pamela is a work in progress, and there
may be compatibility issues that still need to be fixed. </li>
</ul>

<h2> Linking </h2>

<ul>
 <li> Make sure the pamela library, as well as the skalibs
library, are visible in your library search path. </li>
 <li> Do not add <tt>-lpam</tt> to your linking command line.
Instead, add <tt>-lpamela -lskarnet</tt>. Depending on the
libc you're using, you may have to add <tt>-lrt</tt> too. </li>
 <li> It is possible to statically link a binary using pamela:
the pamela and skalibs libraries do not use any dynamic loading,
and are suitable for static linking. Only the
<a href="pamelad.html">pamelad</a> binary uses dynamic module
loading and needs to be dynamically linked, and that is decided
at pamela build time, not at your application's build time. </li>
 <li> Check your application binary's dynamic library dependencies
after it has been built. If your binary depends on <tt>libpam</tt>,
it has been incorrectly made! Your binary should depend on
<tt>libpamela</tt> and <tt>libskarnet</tt>, but not <tt>libpam</tt>.
If you have chosen to link against the static version of pamela
and skalibs, you may not even see the <tt>libpamela</tt> and
<tt>libskarnet</tt> dependencies. </li>
</ul>

<h2> Programming </h2>

<ul>
 <li> pamela strictly implements the
<a href="http://www.linux-pam.org/Linux-PAM-html/adg-interface-by-app-expected.html">Linux-PAM
API</a> </li>
 <li> The <tt>pam_start()</tt> function will spawn a
<a href="pamelad.html">pamelad</a> binary running as a child of
the application, until <tt>pam_end()</tt> is called. At that point
the zombie is reaped. </li>
 <li> If the <a href="pamelad.html">pamelad</a> binary is killed
during the PAM session, all PAM calls will return PAM_ABORT.
The application should then just exit, or call <tt>pam_end()</tt>
to free resources: nothing more can be done with the session. </li>
</ul>

<h2> Running </h2>

<ul>
 <li> If your application runs as root, you can set the
PAMELA_UID and PAMELA_GID environment variables to a non-zero
numeric uid and a nonzero numeric gid prior to running it.
The <a href="pamelad.html">pamelad</a> binary will then drop
its privileges and run under this uid/gid. </li>
</ul>

<h2> My application is not working with pam_foobar.so! </h2>

<p>
  A pamela-type architecture can only work if modules do not try
to do anything fancy outside of the official PAM communication
channels. In particular, if it <strong>sets global state</strong>,
it will not work. PAM modules that
</p>

<ul>
 <li> modify their process' environment </li>
 <li> change their process' uid and gid </li>
 <li> change their process' namespace </li>
 <li> change the working directory </li>
 <li> or any similar action impacting global data of the process </li>
</ul>

<p>
 will not, and <em>cannot</em>, be supported by pamela. The only
solution is to rewrite these modules so they communicate the
change they wish to make via the official PAM API, and have the
application perform the change itself. PAM provides a way to
do this: the <em>conversation function</em>, which exchanges data
between PAM and the application. Currently, only four types of
messages are officially specified by PAM, but the mechanism is
easily extensible and was designed for this. pamela fully supports
customized conversation functions with any message type.
</p>

</body>
</html>