X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fuams%2Fuams_passwd.c;h=e94539c83c6dc99ff09aa408d05d00c264125f95;hb=ecfc96169ab669b578e53fa8e13592934fe37788;hp=e423b674a9786ee86fda6d31f8de62129b4d70e2;hpb=eaf59ab61214a746387fd0b1deb4b0f587069780;p=netatalk.git diff --git a/etc/uams/uams_passwd.c b/etc/uams/uams_passwd.c index e423b674..e94539c8 100644 --- a/etc/uams/uams_passwd.c +++ b/etc/uams/uams_passwd.c @@ -1,5 +1,5 @@ /* - * $Id: uams_passwd.c,v 1.16 2002-02-13 16:44:59 srittau Exp $ + * $Id: uams_passwd.c,v 1.23 2005-04-28 20:49:50 bfernhomberg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu) @@ -7,12 +7,20 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include #endif /* HAVE_CONFIG_H */ +#include +/* crypt needs _XOPEN_SOURCE (500) at least on BSD, but that breaks Solaris compile */ +#ifdef NETBSD +#define _XOPEN_SOURCE 500 /* for crypt() */ +#endif +#ifdef FREEBSD +#define _XOPEN_SOURCE /* for crypt() */ +#endif + #include #include - /* STDC check */ #if STDC_HEADERS #include @@ -27,29 +35,35 @@ char *strchr (), *strrchr (); #define memmove(d,s,n) bcopy ((s), (d), (n)) #endif /* ! HAVE_MEMCPY */ #endif /* STDC_HEADERS */ - #ifdef HAVE_UNISTD_H #include #endif /* HAVE_UNISTD_H */ -#ifndef NO_CRYPT_H +#ifdef HAVE_CRYPT_H #include -#endif /* ! NO_CRYPT_H */ +#endif /* ! HAVE_CRYPT_H */ #include -#include - -#ifdef SOLARIS -#define SHADOWPW -#endif /* SOLARIS */ - +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_TIME_H +#include +#endif #ifdef SHADOWPW #include #endif /* SHADOWPW */ #include +#include #include +#include #define PASSWDLEN 8 +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif /* MIN */ + + #ifdef TRU64 #include #include @@ -57,23 +71,18 @@ char *strchr (), *strrchr (); static char *clientname; #endif /* TRU64 */ -/* cleartxt login */ -static int passwd_login(void *obj, struct passwd **uam_pwd, +extern void append(void *, const char *, int); + +static int pwd_login(void *obj, char *username, int ulen, struct passwd **uam_pwd, char *ibuf, int ibuflen, - char *rbuf, int *rbuflen) + char *rbuf _U_, int *rbuflen _U_) { + char *p; struct passwd *pwd; + int err = AFP_OK; #ifdef SHADOWPW struct spwd *sp; #endif /* SHADOWPW */ - char *username, *p; - int len, ulen; - - *rbuflen = 0; - - if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, - (void *) &username, &ulen) < 0) - return AFPERR_MISC; #ifdef TRU64 if( uam_afpserver_option( obj, UAM_OPTION_CLIENTNAME, @@ -81,46 +90,37 @@ static int passwd_login(void *obj, struct passwd **uam_pwd, return AFPERR_MISC; #endif /* TRU64 */ - if (ibuflen <= 1) { - 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--; - } if (ibuflen < PASSWDLEN) { return( AFPERR_PARAM ); } ibuf[ PASSWDLEN ] = '\0'; - if (( pwd = uam_getname(username, ulen)) == NULL ) { + if (( pwd = uam_getname(obj, username, ulen)) == NULL ) { return AFPERR_PARAM; } - LOG(log_info, logtype_default, "cleartext login: %s", username); + LOG(log_info, logtype_uams, "cleartext login: %s", username); + if (uam_checkuser(pwd) < 0) { - LOG(log_info, logtype_default, "not a valid user"); + LOG(log_info, logtype_uams, "not a valid user"); return AFPERR_NOTAUTH; } #ifdef SHADOWPW if (( sp = getspnam( pwd->pw_name )) == NULL ) { - LOG(log_info, logtype_default, "no shadow passwd entry for %s", username); + LOG(log_info, logtype_uams, "no shadow passwd entry for %s", username); return AFPERR_NOTAUTH; } pwd->pw_passwd = sp->sp_pwdp; + + 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", username); + err = AFPERR_PWDEXPR; + } + } #endif /* SHADOWPW */ if (!pwd->pw_passwd) { @@ -138,21 +138,91 @@ static int passwd_login(void *obj, struct passwd **uam_pwd, uam_afp_getcmdline( &ac, &av ); sprintf( hostname, "%s@%s", username, clientname ); - if( uams_sia_validate_user( NULL, ac, av, hostname, username, - NULL, FALSE, NULL, ibuf ) != SIASUCCESS ) + if( uam_sia_validate_user( NULL, ac, av, hostname, username, + NULL, FALSE, NULL, ibuf ) != SIASUCCESS ) return AFPERR_NOTAUTH; - return AFP_OK; + return err; } #else /* TRU64 */ p = crypt( ibuf, pwd->pw_passwd ); if ( strcmp( p, pwd->pw_passwd ) == 0 ) - return AFP_OK; + return err; #endif /* TRU64 */ return AFPERR_NOTAUTH; + +} + +/* cleartxt login */ +static int passwd_login(void *obj, struct passwd **uam_pwd, + char *ibuf, int ibuflen, + char *rbuf, int *rbuflen) +{ + char *username; + int len, ulen; + + *rbuflen = 0; + + if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, + (void *) &username, &ulen) < 0) + return AFPERR_MISC; + + if (ibuflen <= 1) { + 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 unicode name +*/ +static int passwd_login_ext(void *obj, char *uname, struct passwd **uam_pwd, + char *ibuf, int ibuflen, + char *rbuf, int *rbuflen) +{ + char *username; + int 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)); +} + #if 0 /* change passwd */ @@ -176,7 +246,7 @@ static int passwd_changepw(void *obj, char *username, #ifdef SHADOWPW if (( sp = getspnam( pwd->pw_name )) == NULL ) { - LOG(log_info, logtype_default, "no shadow passwd entry for %s", username); + LOG(log_info, logtype_uams, "no shadow passwd entry for %s", username); return AFPERR_PARAM; } pwd->pw_passwd = sp->sp_pwdp; @@ -215,7 +285,11 @@ struct papfile *out; int ulen; data = (char *)malloc(stop - start + 1); - strncpy(data, start, stop - start + 1); + if (!data) { + LOG(log_info, logtype_uams,"Bad Login ClearTxtUAM: malloc"); + return(-1); + } + strlcpy(data, start, stop - start + 1); /* We are looking for the following format in data: * (username) (password) @@ -225,34 +299,34 @@ struct papfile *out; /* Parse input for username in () */ if ((p = strchr(data, '(' )) == NULL) { - LOG(log_info, logtype_default,"Bad Login ClearTxtUAM: username not found in string"); + LOG(log_info, logtype_uams,"Bad Login ClearTxtUAM: username not found in string"); free(data); return(-1); } p++; - if ((q = strstr(data, ") (" )) == NULL) { - LOG(log_info, logtype_default,"Bad Login ClearTxtUAM: username not found in string"); + if ((q = strstr(p, ") (" )) == NULL) { + LOG(log_info, logtype_uams,"Bad Login ClearTxtUAM: username not found in string"); free(data); return(-1); } - strncpy(username, p, q - p); + memcpy(username, p, MIN( UAM_USERNAMELEN, q - p )); /* Parse input for password in next () */ p = q + 3; - if ((q = strrchr(data, ')' )) == NULL) { - LOG(log_info, logtype_default,"Bad Login ClearTxtUAM: password not found in string"); + if ((q = strrchr(p , ')' )) == NULL) { + LOG(log_info, logtype_uams,"Bad Login ClearTxtUAM: password not found in string"); free(data); return(-1); } - strncpy(password, p, q - p); + memcpy(password, p, MIN(PASSWDLEN, q - p) ); /* Done copying username and password, clean up */ free(data); ulen = strlen(username); - if (( pwd = uam_getname(username, ulen)) == NULL ) { - LOG(log_info, logtype_default, "Bad Login ClearTxtUAM: ( %s ) not found ", + if (( pwd = uam_getname(NULL, username, ulen)) == NULL ) { + LOG(log_info, logtype_uams, "Bad Login ClearTxtUAM: ( %s ) not found ", username); return(-1); } @@ -264,15 +338,25 @@ struct papfile *out; #ifdef SHADOWPW if (( sp = getspnam( pwd->pw_name )) == NULL ) { - LOG(log_info, logtype_default, "Bad Login ClearTxtUAM: no shadow passwd entry for %s", + LOG(log_info, logtype_uams, "Bad Login ClearTxtUAM: no shadow passwd entry for %s", username); return(-1); } pwd->pw_passwd = sp->sp_pwdp; + + 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", username); + return (-1); + } + } + #endif /* SHADOWPW */ if (!pwd->pw_passwd) { - LOG(log_info, logtype_default, "Bad Login ClearTxtUAM: no password for %s", + LOG(log_info, logtype_uams, "Bad Login ClearTxtUAM: no password for %s", username); return(-1); } @@ -284,21 +368,33 @@ struct papfile *out; p = crypt(password, pwd->pw_passwd); if (strcmp(p, pwd->pw_passwd) != 0) { - LOG(log_info, logtype_default, "Bad Login ClearTxtUAM: %s: bad password", username); + LOG(log_info, logtype_uams, "Bad Login ClearTxtUAM: %s: bad password", username); return(-1); } /* Login successful */ append(out, loginok, strlen(loginok)); - LOG(log_info, logtype_default, "Login ClearTxtUAM: %s", username); + LOG(log_info, logtype_uams, "Login ClearTxtUAM: %s", username); return(0); } +#ifdef ATACC +int uam_setup(const char *path) +{ + if (uam_register_fn(UAM_SERVER_LOGIN_EXT, path, "Cleartxt Passwrd", + passwd_login, NULL, NULL, passwd_login_ext) < 0) + return -1; + if (uam_register_fn(UAM_SERVER_PRINTAUTH, path, "ClearTxtUAM", + passwd_printer) < 0) + return -1; + return 0; +} +#else static int uam_setup(const char *path) { - if (uam_register(UAM_SERVER_LOGIN, path, "Cleartxt Passwrd", - passwd_login, NULL, NULL) < 0) + if (uam_register(UAM_SERVER_LOGIN_EXT, path, "Cleartxt Passwrd", + passwd_login, NULL, NULL, passwd_login_ext) < 0) return -1; if (uam_register(UAM_SERVER_PRINTAUTH, path, "ClearTxtUAM", passwd_printer) < 0) @@ -307,6 +403,8 @@ static int uam_setup(const char *path) return 0; } +#endif + static void uam_cleanup(void) { uam_unregister(UAM_SERVER_LOGIN, "Cleartxt Passwrd");