[Pkg-netatalk-devel] Bug#1111652: netatalk: Unable to using PAM in centralized authentication scenario
Hector Rulot
Hector.Rulot at uv.es
Wed Sep 3 16:30:51 BST 2025
> Aug 20 16:53:04 netatalkdbg afpd[41840]: DHX2: unknown username
I have downgraded to netatalk Version: 4.1.2~ds-4 for
this same reason.
After recompile and intensive debugging I found the bug,
but patching it correctly is too complex for me, so
I downgraded.
The problem is in the uam_getname() function of
etc/afpd/uam.c module when calling getpwnam() to get
the user data.
The old/classic/working getpwnam() call has been changed
to its reentrant version getpwnam_r(), even when
(I think) there is not need as afpd is not threaded.
But the call to getpwnam_r() has some grave errors;
using a simplified version we have:
struct passwd pwent_buf;
char *buffer = malloc(bufsize);
getpwnam_r(name, &pwent_buf, buffer, sizeof(buffer), &pwent);
free(buffer);
Problems:
1) sizeof(buffer) is always 2, because buffer is a
pointer (char *).
2) The return value of getpwnam_r is not checked, it always
return "OUT OF RANGE" (insufficient buffer size).
3) As getpwnam_r returns error, the uam_getname() function
proceeds to a classic scan to all users using
"while ((pwent = getpwent()))". This works in the simple
case of local users, but fails when when the users (as
in our case) are 350.000 PAM/LDAP entries. The scan last
minutes and the user generally is not found because
the download of all users is limited :-(((
4) Even when a working buffer (using "bufsize" instead
of "sizeof(buffer)") is used, uam_getname() returns invalid
data and potentially can break badly, as it returns data that
is stored in -locally- declared variables that are destroyed
on function exit,
getpwnam_r stores its data pointers in "pwent_buf" and
pwent_buf is -not- static.
Also, data returned by uam_getname() is stored in "buffer"
that is dinamically allocated and -freed- on function exit (!).
5) if "buffer" is not freed, there is a potential memory leak.
Then correcting the bug is no trivial because uam_getname()
has to return not only "pwent" but also "buffer" and the calling
function must free it after use. Also, to be reentrant uam_getname()
must receive pwent_buf, not declare it itself.
Hope this helps.
More information about the pkg-netatalk-devel
mailing list