----- Original Message ----- 
From: "Darren J Moffat" <[EMAIL PROTECTED]>
To: "Markus Moeller" <[EMAIL PROTECTED]>
Cc: <[email protected]>
Sent: Wednesday, January 09, 2008 10:30 AM
Subject: Re: [osol-code] Question about getspnam and LDAP


> Markus Moeller wrote:
>> I know that other methods are better and  Kerberos is my preferred 
>> option. Unfortunately I still need to support applications for which I 
>> don't have the source and I can't get the vendor to change it. I addition 
>> I am bound to Microsoft's AD use of unixuserpassword which is 
>> synchronized with the Kerberos password.
>>
>> I appreciate that you check for ldap RFC compliance (which is not really 
>> the case as it is now) but I still would prefer the ability to overwrite 
>> the behavior and let the application decide if it is OK or not. Also as 
>> there are many possible encryption algorithm why does the code require 
>> {crypt} ?
>
> Exactly because there are many possible password hashing algorithms. Only 
> those that are prefixed {crypt} are dealt with on the client side by using 
> the crypt(3C) library call.  All others are dealt with on the LDAP server.
>

Sorry I don't understand why the other algorithms are dealt with on the ldap 
server (I probably misunderstand how it should work.)  ? I thought 
getspnam/getpwnam will request the password hash from either a file, NIS 
server or LDAP server and then the application compares the hash (or what 
ever encryption used) with its own calculated hash from the users password. 
If it is a newer application it will know how to deal with the different 
prefixes and if it is an old application it will use the default crypt as 
described for the shadow file.


>> Markus
>>
>> BTW it works fine on other platforms (e.g. Linux)
>
> I assuming using OpenLDAP right ?
>
> Please give an example of one of these hashes that "works fine".
>

OK. Here is a user in AD called mm accessed from Opensuse 10.3 (using 
nss_ldap from PADL with openldap). I can successfully do a kinit to that 
account (as I mentioned my preferred method).

[EMAIL PROTECTED]:~/mysources/test_shadow> kinit [EMAIL PROTECTED]
Password for [EMAIL PROTECTED]:
[EMAIL PROTECTED]:~/mysources/test_shadow> klist -e
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: [EMAIL PROTECTED]

Valid starting     Expires            Service principal
01/09/08 11:59:03  01/09/08 21:58:57  krbtgt/[EMAIL PROTECTED]
        renew until 01/10/08 11:59:03, Etype (skey, tkt): ArcFour with 
HMAC/md5, ArcFour with HMAC/md5

I have ldap setup to use AD with the appropriate mappings.  My test tool 
(see source below) gives me the password hash from the unixuserpassword 
entry in AD.

[EMAIL PROTECTED]:~/mysources/test_shadow> ./test_shadow mm
passwd: name=mm
passwd: passwd=8cEU.o85XPLaU
passwd: uid=500
passwd: gid=10000
passwd: gecos=Markus Moeller
passwd: homedir=/export/home/mm
passwd: shell=/bin/ksh


shadow: name=mm
shadow: passwd=8cEU.o85XPLaU
shadow: lastchg=13887(Wed Jan  9 00:00:00 2008)
shadow: min=-1
shadow: max=-1
shadow: warn=-1
shadow: inactive=-1
shadow: expire=-1(Wed Dec 31 01:00:00 1969)

And I can do a successful password against it (See source below).

[EMAIL PROTECTED]:~/mysources/test_shadow> ./check_pass mm
Enter password:
Passwords match.

Test sources:

test_shadow.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <pwd.h>
#include <shadow.h>

int main(int argc, char ** argv) {
    char *user=NULL;
    char *date=NULL,*dp;
    time_t time;
    struct passwd *pw=NULL;
    struct spwd *spw=NULL;

    if ( argc > 1 ) {
        user = argv[1];
    } else {
        exit(99);
    }

    pw = getpwnam(user);
    spw = getspnam(user);

    if ( pw ) {
        printf("passwd: name=%s\n",pw->pw_name);
        printf("passwd: passwd=%s\n",pw->pw_passwd);
        printf("passwd: uid=%d\n",pw->pw_uid);
        printf("passwd: gid=%d\n",pw->pw_gid);
        printf("passwd: gecos=%s\n",pw->pw_gecos);
        printf("passwd: homedir=%s\n",pw->pw_dir);
        printf("passwd: shell=%s\n",pw->pw_shell);
        printf("\n\n");
    }
    if ( spw ) {
        printf("shadow: name=%s\n",spw->sp_namp);
        printf("shadow: passwd=%s\n",spw->sp_pwdp);
        time=spw->sp_lstchg*3600*24;
        date=ctime(&time);
        if ((dp=strchr(date,'\n')) != NULL ) {
            *dp = '\0';
        }
        printf("shadow: lastchg=%ld(%s)\n",spw->sp_lstchg,date);
        printf("shadow: min=%d\n",spw->sp_min);
        printf("shadow: max=%d\n",spw->sp_max);
        printf("shadow: warn=%d\n",spw->sp_warn);
        printf("shadow: inactive=%d\n",spw->sp_inact);
        time=spw->sp_expire*3600*24;
        date=ctime(&time);
        if ((dp=strchr(date,'\n')) != NULL ) {
            *dp = '\0';
        }
        printf("shadow: expire=%d(%s)\n",spw->sp_expire,date);
    }

}

checkpass.c:

#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <shadow.h>
#include <crypt.h>
#include <string.h>

int main (int argc,char **argv)
{
    struct passwd *pwd_info;
    struct spwd *spwd_info;
    char *ct_passwd;
    char *enc_passwd;
    char *password;
    int i;

    if ( argc < 2) {
            exit(1);
    } else {
            if ((pwd_info = getpwnam(argv[1])) == NULL )  {
                  fprintf (stderr, "Call to getpwuid failed\n");
                  exit (1);
            }
    }

    for (i=0;i<3;i++) {
        ct_passwd = getpass("Enter password: ");

        if ((spwd_info = getspnam (pwd_info -> pw_name)) == NULL) {
            fprintf (stderr, "Call to getspnam failed. Try password field 
from getpwnam\n");
            password=pwd_info->pw_passwd;
        } else {
            password=spwd_info->sp_pwdp;
        }
        enc_passwd = crypt (ct_passwd, password);

        if (strcmp (enc_passwd, password) == 0) {
            printf ("Passwords match.\n");
            break;
        } else
            printf ("Passwords don't match.\n");
    }

    return (0);
}



> -- 
> Darren J Moffat 

_______________________________________________
opensolaris-code mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/opensolaris-code

Reply via email to