Bug 2276 - Password change through pam_winbind.so does not work on Solaris.
Summary: Password change through pam_winbind.so does not work on Solaris.
Alias: None
Product: Samba 3.0
Classification: Unclassified
Component: winbind (show other bugs)
Version: 3.0.11
Hardware: All Solaris
: P3 normal
Target Milestone: none
Assignee: Samba Bugzilla Account
QA Contact: Samba QA Contact
Depends on:
Reported: 2005-01-23 10:30 UTC by Miroslav Spousta
Modified: 2005-09-29 09:07 UTC (History)
0 users

See Also:

Patch to fix pam_winbind on Solaris (754 bytes, patch)
2005-01-23 10:33 UTC, Miroslav Spousta
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Miroslav Spousta 2005-01-23 10:30:39 UTC
Problem description:

Solaris: SunOS sun 5.9 Generic_117171-15 sun4u sparc SUNW,Ultra-4
Samba: 3.0.11pre1 (LDAP)

Everything works fine except password change when using the passwd command
on the Solaris machine. Password changes are configured through pam.conf:

passwd  password required       pam_winbind.so debug

After hours of digging into winbind & smbd code I found what does this message

[2005/01/23 15:21:20, 0] libsmb/smbencrypt.c:decode_pw_buffer(544)
  decode_pw_buffer: incorrect password length (1244404949).
[2005/01/23 15:21:20, 0] libsmb/smbencrypt.c:decode_pw_buffer(545)
  decode_pw_buffer: check that 'encrypt passwords = yes'

The oldpass argument of winbind_chauthtok_request() was always set to ""
in the pam_winbind and so samba server could not decrypt new password
in smbd :-).

The cause of all troubles seems to be the Solaris PAM library which fails
to work in the following scenario:

char *token;
pam_get_item(pamh, PAM_OLDAUTHTOK, &token);
pam_set_item(pamh, PAM_OLDAUTHTOK, token);

In other words, it fails to work if you set item with pointer acquired
with previous pam_get_item() (maybe the free Solaris 9 sources would show
up more). Unfortunately this is exactly what pam_winbind.c does in

PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
                                int argc, const char **argv)
char *pass_old;
if (flags & PAM_PRELIM_CHECK) {
        retval = _winbind_read_password(pamh, lctrl,Announce
                                        ,"(current) NT password: "
                                        ,NULL,(const char **) &pass_old);
        if (retval != PAM_SUCCESS)
                return retval;
        retval = pam_set_item(pamh, PAM_OLDAUTHTOK, (const void *) pass_old);
} }

and _winbind_read_password() returns PAM_SUCCESS with pass_old set to item
acquired from pam_get_item():

int _winbind_read_password(pam_handle_t * pamh, ..., const char **pass)
const char *item;
pam_get_item(pamh, authtok_flag,(const void **) &item));
*pass = item;
item = NULL;

Proposed solution:

I think the last pam_set_item() is not necessary as pass_old is filled
by pam_get_item() so there is no need to store it again (and it breaks Solaris
compatibility as pointed out above). The patch attached possibly makes it
more clear :-). I tested it on Samba 3.0.10 (FC3, i686) and Samba 3.0.11pre2
(SunOS 5.9, sparc), password change works fine on both ones.
Comment 1 Miroslav Spousta 2005-01-23 10:33:36 UTC
Created attachment 911 [details]
Patch to fix pam_winbind on Solaris
Comment 2 Gerald (Jerry) Carter (dead mail address) 2005-02-07 07:29:39 UTC
resetting version
Comment 3 Gerald (Jerry) Carter (dead mail address) 2005-09-29 09:07:07 UTC
please retest against 3.0.20a (the current SAMBA_3_0_RELEASE branch) which will
publically be availebl next week.