X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=blobdiff_plain;f=etc%2Fuams%2Fuams_dhx_passwd.c;h=6abbab0a88e3c4d9337e3e1af5c56fab366f9529;hp=b8076cfb8b82a14963eb89350755563c965a6616;hb=75fe310224dffb96868d7f2cb1ec9125a84f2a08;hpb=5268a18e175c883c0f62bb3bd0bde8a3e17d254c diff --git a/etc/uams/uams_dhx_passwd.c b/etc/uams/uams_dhx_passwd.c index b8076cfb..6abbab0a 100644 --- a/etc/uams/uams_dhx_passwd.c +++ b/etc/uams/uams_dhx_passwd.c @@ -1,5 +1,5 @@ /* - * $Id: uams_dhx_passwd.c,v 1.6 2001-02-27 17:07:43 rufustfirefly Exp $ + * $Id: uams_dhx_passwd.c,v 1.27 2009-11-05 14:38:07 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu) @@ -8,37 +8,47 @@ #ifdef HAVE_CONFIG_H #include "config.h" +#endif /* HAVE_CONFIG_H */ + +#ifdef NETBSD +#define _XOPEN_SOURCE 500 /* for crypt() */ +#endif +#ifdef FREEBSD +#define _XOPEN_SOURCE /* for crypt() */ #endif -#ifdef UAM_DHX #include #include #include +#ifdef HAVE_UNISTD_H #include -#ifndef NO_CRYPT_H +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_CRYPT_H #include +#endif /* ! HAVE_CRYPT_H */ +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_TIME_H +#include #endif #include -#include - -#ifdef SOLARIS -#define SHADOWPW -#endif SOLARIS - #ifdef SHADOWPW #include #endif /* SHADOWPW */ - -#ifdef OPENSSL_DHX +#if defined(GNUTLS_DHX) +#include +#elif defined(OPENSSL_DHX) #include #include #include -#else +#else /* OPENSSL_DHX */ #include #include #include #endif /* OPENSSL_DHX */ +#include #include #include @@ -56,10 +66,17 @@ static CAST_KEY castkey; static struct passwd *dhxpwd; static u_int8_t randbuf[16]; +#ifdef TRU64 +#include +#include + +static const char *clientname; +#endif /* TRU64 */ + /* dhx passwd */ -static int passwd_login(void *obj, struct passwd **uam_pwd, - char *ibuf, int ibuflen, - char *rbuf, int *rbuflen) +static int pwd_login(void *obj, char *username, int ulen, struct passwd **uam_pwd _U_, + char *ibuf, size_t ibuflen _U_, + char *rbuf, size_t *rbuflen) { unsigned char iv[] = "CJalbert"; u_int8_t p[] = {0xBA, 0x28, 0x73, 0xDF, 0xB0, 0x60, 0x57, 0xD4, @@ -67,50 +84,48 @@ static int passwd_login(void *obj, struct passwd **uam_pwd, u_int8_t g = 0x07; #ifdef SHADOWPW struct spwd *sp; -#endif +#endif /* SHADOWPW */ BIGNUM *bn, *gbn, *pbn; u_int16_t sessid; - int len, i; - char *name; + size_t i; DH *dh; - *rbuflen = 0; - - if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, (void *) &name, &i) < 0) - return AFPERR_PARAM; +#ifdef TRU64 + int rnd_seed[256]; + for (i = 0; i < 256; i++) + rnd_seed[i] = random(); + RAND_seed(rnd_seed, sizeof(rnd_seed)); +#endif /* TRU64 */ - len = (unsigned char) *ibuf++; - if ( len > i ) { - return( AFPERR_PARAM ); - } + *rbuflen = 0; - memcpy(name, ibuf, len ); - ibuf += len; - name[ len ] = '\0'; - if ((unsigned long) ibuf & 1) /* padding */ - ++ibuf; +#ifdef TRU64 + if( uam_afpserver_option( obj, UAM_OPTION_CLIENTNAME, + (void *) &clientname, NULL ) < 0 ) + return AFPERR_PARAM; +#endif /* TRU64 */ - if (( dhxpwd = uam_getname(name, i)) == NULL ) { - return AFPERR_PARAM; + if (( dhxpwd = uam_getname(obj, username, ulen)) == NULL ) { + return AFPERR_PARAM; } - - syslog( LOG_INFO, "dhx login: %s", name); + + LOG(log_info, logtype_uams, "dhx login: %s", username); if (uam_checkuser(dhxpwd) < 0) return AFPERR_NOTAUTH; #ifdef SHADOWPW if (( sp = getspnam( dhxpwd->pw_name )) == NULL ) { - syslog( LOG_INFO, "no shadow passwd entry for %s", name); + LOG(log_info, logtype_uams, "no shadow passwd entry for %s", username); return AFPERR_NOTAUTH; } dhxpwd->pw_passwd = sp->sp_pwdp; -#endif SHADOWPW +#endif /* SHADOWPW */ if (!dhxpwd->pw_passwd) return AFPERR_NOTAUTH; /* get the client's public key */ - if (!(bn = BN_bin2bn(ibuf, KEYSIZE, NULL))) { + if (!(bn = BN_bin2bn((unsigned char *)ibuf, KEYSIZE, NULL))) { return AFPERR_PARAM; } @@ -142,10 +157,10 @@ static int passwd_login(void *obj, struct passwd **uam_pwd, } /* figure out the key. use rbuf as a temporary buffer. */ - i = DH_compute_key(rbuf, bn, dh); + i = DH_compute_key((unsigned char *)rbuf, bn, dh); /* set the key */ - CAST_set_key(&castkey, i, rbuf); + CAST_set_key(&castkey, i, (unsigned char *)rbuf); /* session id. it's just a hashed version of the object pointer. */ sessid = dhxhash(obj); @@ -154,7 +169,7 @@ static int passwd_login(void *obj, struct passwd **uam_pwd, *rbuflen += sizeof(sessid); /* send our public key */ - BN_bn2bin(dh->pub_key, rbuf); + BN_bn2bin(dh->pub_key, (unsigned char *)rbuf); rbuf += KEYSIZE; *rbuflen += KEYSIZE; @@ -175,12 +190,12 @@ static int passwd_login(void *obj, struct passwd **uam_pwd, goto passwd_fail; } memcpy(rbuf + KEYSIZE, name, KEYSIZE); -#else +#else /* 0 */ memset(rbuf + KEYSIZE, 0, KEYSIZE); -#endif +#endif /* 0 */ /* encrypt using cast */ - CAST_cbc_encrypt(rbuf, rbuf, CRYPTBUFLEN, &castkey, iv, CAST_ENCRYPT); + CAST_cbc_encrypt((unsigned char *)rbuf, (unsigned char *)rbuf, CRYPTBUFLEN, &castkey, iv, CAST_ENCRYPT); *rbuflen += CRYPTBUFLEN; BN_free(bn); DH_free(dh); @@ -192,14 +207,87 @@ passwd_fail: return AFPERR_PARAM; } +/* cleartxt login */ +static int passwd_login(void *obj, struct passwd **uam_pwd, + char *ibuf, size_t ibuflen, + char *rbuf, size_t *rbuflen) +{ + char *username; + size_t len, ulen; + + *rbuflen = 0; + + if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, + (void *) &username, &ulen) < 0) + return AFPERR_MISC; + + if (ibuflen < 2) { + return( AFPERR_PARAM ); + } + + len = (unsigned char) *ibuf++; + ibuflen--; + if (!len || len > ibuflen || len > ulen ) { + return( AFPERR_PARAM ); + } + memcpy(username, ibuf, len ); + ibuf += len; + ibuflen -=len; + username[ len ] = '\0'; + + if ((unsigned long) ibuf & 1) { /* pad character */ + ++ibuf; + ibuflen--; + } + return (pwd_login(obj, username, ulen, uam_pwd, ibuf, ibuflen, rbuf, rbuflen)); + +} + +/* cleartxt login ext + * uname format : + byte 3 + 2 bytes len (network order) + len bytes utf8 name +*/ +static int passwd_login_ext(void *obj, char *uname, struct passwd **uam_pwd, + char *ibuf, size_t ibuflen, + char *rbuf, size_t *rbuflen) +{ + char *username; + size_t len, ulen; + u_int16_t temp16; + + *rbuflen = 0; + + if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, + (void *) &username, &ulen) < 0) + return AFPERR_MISC; + + if (*uname != 3) + return AFPERR_PARAM; + uname++; + memcpy(&temp16, uname, sizeof(temp16)); + len = ntohs(temp16); + if (!len || len > ulen ) { + return( AFPERR_PARAM ); + } + memcpy(username, uname +2, len ); + username[ len ] = '\0'; + return (pwd_login(obj, username, ulen, uam_pwd, ibuf, ibuflen, rbuf, rbuflen)); +} + static int passwd_logincont(void *obj, struct passwd **uam_pwd, - char *ibuf, int ibuflen, - char *rbuf, int *rbuflen) + char *ibuf, size_t ibuflen _U_, + char *rbuf, size_t *rbuflen) { +#ifdef SHADOWPW + struct spwd *sp; +#endif /* SHADOWPW */ unsigned char iv[] = "LWallace"; BIGNUM *bn1, *bn2, *bn3; u_int16_t sessid; char *p; + int err = AFPERR_NOTAUTH; *rbuflen = 0; @@ -210,12 +298,12 @@ static int passwd_logincont(void *obj, struct passwd **uam_pwd, ibuf += sizeof(sessid); /* use rbuf as scratch space */ - CAST_cbc_encrypt(ibuf, rbuf, CRYPT2BUFLEN, &castkey, + CAST_cbc_encrypt((unsigned char *)ibuf, (unsigned char *)rbuf, CRYPT2BUFLEN, &castkey, iv, CAST_DECRYPT); /* check to make sure that the random number is the same. we * get sent back an incremented random number. */ - if (!(bn1 = BN_bin2bn(rbuf, KEYSIZE, NULL))) + if (!(bn1 = BN_bin2bn((unsigned char *)rbuf, KEYSIZE, NULL))) return AFPERR_PARAM; if (!(bn2 = BN_bin2bn(randbuf, sizeof(randbuf), NULL))) { @@ -246,12 +334,48 @@ static int passwd_logincont(void *obj, struct passwd **uam_pwd, BN_free(bn3); rbuf[PASSWDLEN] = '\0'; +#ifdef TRU64 + { + int ac; + char **av; + char hostname[256]; + + uam_afp_getcmdline( &ac, &av ); + sprintf( hostname, "%s@%s", dhxpwd->pw_name, clientname ); + + if( uam_sia_validate_user( NULL, ac, av, hostname, dhxpwd->pw_name, + NULL, FALSE, NULL, rbuf ) != SIASUCCESS ) + return AFPERR_NOTAUTH; + + memset( rbuf, 0, PASSWDLEN ); + *uam_pwd = dhxpwd; + return AFP_OK; + } +#else /* TRU64 */ p = crypt( rbuf, dhxpwd->pw_passwd ); memset(rbuf, 0, PASSWDLEN); if ( strcmp( p, dhxpwd->pw_passwd ) == 0 ) { *uam_pwd = dhxpwd; - return AFP_OK; + err = AFP_OK; + } +#ifdef SHADOWPW + if (( sp = getspnam( dhxpwd->pw_name )) == NULL ) { + LOG(log_info, logtype_uams, "no shadow passwd entry for %s", dhxpwd->pw_name); + return (AFPERR_NOTAUTH); + } + + /* check for expired password */ + if (sp && sp->sp_max != -1 && sp->sp_lstchg) { + time_t now = time(NULL) / (60*60*24); + int32_t expire_days = sp->sp_lstchg - now + sp->sp_max; + if ( expire_days < 0 ) { + LOG(log_info, logtype_uams, "password for user %s expired", dhxpwd->pw_name); + err = AFPERR_PWDEXPR; + } } +#endif /* SHADOWPW */ + return err; +#endif /* TRU64 */ return AFPERR_NOTAUTH; } @@ -259,8 +383,8 @@ static int passwd_logincont(void *obj, struct passwd **uam_pwd, static int uam_setup(const char *path) { - if (uam_register(UAM_SERVER_LOGIN, path, "DHCAST128", - passwd_login, passwd_logincont, NULL) < 0) + if (uam_register(UAM_SERVER_LOGIN_EXT, path, "DHCAST128", + passwd_login, passwd_logincont, NULL, passwd_login_ext) < 0) return -1; /*uam_register(UAM_SERVER_PRINTAUTH, path, "DHCAST128", passwd_printer);*/ @@ -279,4 +403,9 @@ UAM_MODULE_EXPORT struct uam_export uams_dhx = { UAM_MODULE_VERSION, uam_setup, uam_cleanup }; -#endif + +UAM_MODULE_EXPORT struct uam_export uams_dhx_passwd = { + UAM_MODULE_SERVER, + UAM_MODULE_VERSION, + uam_setup, uam_cleanup +};