From 16c71250cf94fb7b4369df930b701a3c236311b0 Mon Sep 17 00:00:00 2001 From: didg Date: Thu, 17 Oct 2002 18:01:54 +0000 Subject: [PATCH] AFP 3 fixes ofr cleartxt login and 31 char filename size limit --- etc/afpd/auth.c | 13 ++++- etc/afpd/enumerate.c | 4 +- etc/afpd/mangle.c | 4 +- etc/afpd/mangle.h | 4 +- etc/afpd/uam.c | 88 ++++++++++++++++++++++++++++- etc/afpd/uam_auth.h | 4 +- etc/afpd/volume.c | 8 ++- etc/afpd/volume.h | 8 ++- etc/uams/uams_pam.c | 99 ++++++++++++++++++++++++--------- etc/uams/uams_passwd.c | 122 ++++++++++++++++++++++++++++++----------- include/atalk/uam.h | 1 + 11 files changed, 281 insertions(+), 74 deletions(-) diff --git a/etc/afpd/auth.c b/etc/afpd/auth.c index 093cf46d..3f6afafb 100644 --- a/etc/afpd/auth.c +++ b/etc/afpd/auth.c @@ -1,5 +1,5 @@ /* - * $Id: auth.c,v 1.35 2002-10-16 02:20:41 didg Exp $ + * $Id: auth.c,v 1.36 2002-10-17 18:01:54 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -497,6 +497,8 @@ unsigned int ibuflen, *rbuflen; int i; char type; u_int16_t len16; + char *username; + *rbuflen = 0; if ( nologin & 1) @@ -535,10 +537,15 @@ unsigned int ibuflen, *rbuflen; ibuf += len; ibuflen -= len; + if (!afp_uam->u.uam_login.login_ext) { + LOG(log_error, logtype_afpd, "login_ext: uam %s not AFP 3 ready!", afp_uam->uam_name ); + return send_reply(obj, AFPERR_BADUAM); + } /* user name */ if (len <= 1 +sizeof(len16)) return send_reply(obj, AFPERR_PARAM); type = *ibuf; + username = ibuf; ibuf++; ibuflen--; if (type != 3) @@ -596,7 +603,7 @@ unsigned int ibuflen, *rbuflen; ibuflen--; /* FIXME user name are in unicode */ - i = afp_uam->u.uam_login.login(obj, &pwd, ibuf, ibuflen, rbuf, rbuflen); + i = afp_uam->u.uam_login.login_ext(obj, username, &pwd, ibuf, ibuflen, rbuf, rbuflen); if (i || !pwd) return send_reply(obj, i); @@ -741,7 +748,7 @@ int ibuflen, *rbuflen; return AFP_OK; } -#define UAM_LIST(type) (((type) == UAM_SERVER_LOGIN) ? &uam_login : \ +#define UAM_LIST(type) (((type) == UAM_SERVER_LOGIN || (type) == UAM_SERVER_LOGIN_EXT) ? &uam_login : \ (((type) == UAM_SERVER_CHANGEPW) ? \ &uam_changepw : NULL)) diff --git a/etc/afpd/enumerate.c b/etc/afpd/enumerate.c index 5a39943a..7cb9def0 100644 --- a/etc/afpd/enumerate.c +++ b/etc/afpd/enumerate.c @@ -1,5 +1,5 @@ /* - * $Id: enumerate.c,v 1.25 2002-10-15 19:34:34 didg Exp $ + * $Id: enumerate.c,v 1.26 2002-10-17 18:01:54 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -165,7 +165,7 @@ char *check_dirent(const struct vol *vol, char *name) return NULL; /* now check against too big a file */ - if (strlen(m_name = utompath(vol, name)) > MACFILELEN) + if (strlen(m_name = utompath(vol, name)) > vol->max_filename) return NULL; return m_name; diff --git a/etc/afpd/mangle.c b/etc/afpd/mangle.c index 1f146560..9491d878 100644 --- a/etc/afpd/mangle.c +++ b/etc/afpd/mangle.c @@ -1,5 +1,5 @@ /* - * $Id: mangle.c,v 1.11 2002-10-05 20:13:31 jmarcus Exp $ + * $Id: mangle.c,v 1.12 2002-10-17 18:01:54 didg Exp $ * * Copyright (c) 2002. Joe Marcus Clarke (marcus@marcuscom.com) * All Rights Reserved. See COPYRIGHT. @@ -59,7 +59,7 @@ mangle(const struct vol *vol, char *filename) { int mangle_suffix_int = 0; /* Do we really need to mangle this filename? */ - if (strlen(filename) <= MAX_LENGTH) { + if (strlen(filename) <= vol->max_filename) { return filename; } diff --git a/etc/afpd/mangle.h b/etc/afpd/mangle.h index 55b8d88d..2d80c8a3 100644 --- a/etc/afpd/mangle.h +++ b/etc/afpd/mangle.h @@ -1,5 +1,5 @@ /* - * $Id: mangle.h,v 1.2 2002-07-04 18:14:38 jmarcus Exp $ + * $Id: mangle.h,v 1.3 2002-10-17 18:01:54 didg Exp $ * */ @@ -22,7 +22,7 @@ #define MANGLE_LENGTH 3 /* XXX This really can't be changed. */ #define MAX_MANGLE_SUFFIX_LENGTH 999 #define MAX_EXT_LENGTH 4 /* XXX This cannot be greater than 27 */ -#define MAX_LENGTH 31 +#define MAX_LENGTH MACFILELEN extern char *mangle __P((const struct vol *, char *)); extern char *demangle __P((const struct vol *, char *)); diff --git a/etc/afpd/uam.c b/etc/afpd/uam.c index 05037dcf..7e18ee20 100644 --- a/etc/afpd/uam.c +++ b/etc/afpd/uam.c @@ -1,5 +1,5 @@ /* - * $Id: uam.c,v 1.22 2002-03-24 01:23:41 sibaz Exp $ + * $Id: uam.c,v 1.23 2002-10-17 18:01:54 didg Exp $ * * Copyright (c) 1999 Adrian Sun (asun@zoology.washington.edu) * All Rights Reserved. See COPYRIGHT. @@ -64,6 +64,9 @@ char *strchr (), *strrchr (); #endif /* TRU64 */ /* --- server uam functions -- */ +#ifndef NO_LOAD_UAM +extern int uam_setup(const char *path); +#endif /* uam_load. uams must have a uam_setup function. */ struct uam_mod *uam_load(const char *path, const char *name) @@ -72,10 +75,12 @@ struct uam_mod *uam_load(const char *path, const char *name) struct uam_mod *mod; void *module; +#ifndef NO_LOAD_UAM if ((module = mod_open(path)) == NULL) { LOG(log_error, logtype_afpd, "uam_load(%s): failed to load: %s", name, mod_error()); return NULL; } +#endif if ((mod = (struct uam_mod *) malloc(sizeof(struct uam_mod))) == NULL) { LOG(log_error, logtype_afpd, "uam_load(%s): malloc failed", name); @@ -86,6 +91,8 @@ struct uam_mod *uam_load(const char *path, const char *name) buf[sizeof(buf) - 1] = '\0'; if ((p = strchr(buf, '.'))) *p = '\0'; + +#ifndef NO_LOAD_UAM if ((mod->uam_fcn = mod_symbol(module, buf)) == NULL) { LOG(log_error, logtype_afpd, "uam_load(%s): mod_symbol error for symbol %s", name, @@ -106,6 +113,9 @@ struct uam_mod *uam_load(const char *path, const char *name) LOG(log_error, logtype_afpd, "uam_load(%s): uam_setup failed", name); goto uam_load_err; } +#else + uam_setup(name); +#endif mod->uam_module = module; return mod; @@ -124,12 +134,15 @@ void uam_unload(struct uam_mod *mod) { if (mod->uam_fcn->uam_cleanup) (*mod->uam_fcn->uam_cleanup)(); + +#ifndef NO_LOAD_UAM mod_close(mod->uam_module); +#endif free(mod); } /* -- client-side uam functions -- */ - +#ifndef ATACC /* set up stuff for this uam. */ int uam_register(const int type, const char *path, const char *name, ...) { @@ -161,7 +174,15 @@ int uam_register(const int type, const char *path, const char *name, ...) va_start(ap, name); switch (type) { + case UAM_SERVER_LOGIN_EXT: /* expect four arguments */ + uam->u.uam_login.login = va_arg(ap, void *); + uam->u.uam_login.logincont = va_arg(ap, void *); + uam->u.uam_login.logout = va_arg(ap, void *); + uam->u.uam_login.login_ext = va_arg(ap, void *); + break; + case UAM_SERVER_LOGIN: /* expect three arguments */ + uam->u.uam_login.login_ext = NULL; uam->u.uam_login.login = va_arg(ap, void *); uam->u.uam_login.logincont = va_arg(ap, void *); uam->u.uam_login.logout = va_arg(ap, void *); @@ -184,6 +205,69 @@ int uam_register(const int type, const char *path, const char *name, ...) return 0; } +#endif + +#ifdef ATACC +int uam_register_fn(const int type, const char *path, const char *name, void *fn1, void *fn2, + void *fn3, void *fn4) +{ + va_list ap; + struct uam_obj *uam; + + if (!name) + return -1; + + /* see if it already exists. */ + if ((uam = auth_uamfind(type, name, strlen(name)))) { + if (strcmp(uam->uam_path, path)) { + /* it exists, but it's not the same module. */ + LOG(log_error, logtype_afpd, "uam_register: \"%s\" already loaded by %s", + name, path); + return -1; + } + uam->uam_count++; + return 0; + } + + /* allocate space for uam */ + if ((uam = calloc(1, sizeof(struct uam_obj))) == NULL) + return -1; + + uam->uam_name = name; + uam->uam_path = strdup(path); + uam->uam_count++; + + switch (type) { + case UAM_SERVER_LOGIN_EXT: /* expect four arguments */ + uam->u.uam_login.login_ext = fn4; + uam->u.uam_login.login = fn1; + uam->u.uam_login.logincont = fn2; + uam->u.uam_login.logout = fn3; + break; + case UAM_SERVER_LOGIN: /* expect three arguments */ + uam->u.uam_login.login_ext = NULL; + uam->u.uam_login.login = fn1; + uam->u.uam_login.logincont = fn2; + uam->u.uam_login.logout = fn3; + break; + case UAM_SERVER_CHANGEPW: /* one argument */ + uam->u.uam_changepw = fn1; + break; + case UAM_SERVER_PRINTAUTH: /* x arguments */ + default: + break; + } + + /* attach to other uams */ + if (auth_register(type, uam) < 0) { + free(uam->uam_path); + free(uam); + return -1; + } + + return 0; +} +#endif void uam_unregister(const int type, const char *name) { diff --git a/etc/afpd/uam_auth.h b/etc/afpd/uam_auth.h index c2069adb..fe9fe08d 100644 --- a/etc/afpd/uam_auth.h +++ b/etc/afpd/uam_auth.h @@ -1,5 +1,5 @@ /* - * $Id: uam_auth.h,v 1.3 2001-12-03 05:03:38 jmarcus Exp $ + * $Id: uam_auth.h,v 1.4 2002-10-17 18:01:54 didg Exp $ * * Copyright (c) 1999 Adrian Sun (asun@zoology.washington.edu) * All Rights Reserved. See COPYRIGHT. @@ -33,6 +33,8 @@ struct uam_obj { int (*logincont) __P((void *, struct passwd **, char *, int, char *, int *)); void (*logout) __P((void)); + int (*login_ext) __P((void *, char *, struct passwd **, + char *, int, char *, int *)); } uam_login; int (*uam_changepw) __P((void *, char *, struct passwd *, char *, int, char *, int *)); diff --git a/etc/afpd/volume.c b/etc/afpd/volume.c index 280f71b0..806229ae 100644 --- a/etc/afpd/volume.c +++ b/etc/afpd/volume.c @@ -1,5 +1,5 @@ /* - * $Id: volume.c,v 1.40 2002-10-16 16:19:34 jmarcus Exp $ + * $Id: volume.c,v 1.41 2002-10-17 18:01:54 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -1220,6 +1220,12 @@ int ibuflen, *rbuflen; ret = AFPERR_ACCESS; goto openvol_err; } + /* FIXME + */ + if (afp_version >= 30) + volume->max_filename = 255; + else + volume->max_filename = MACFILELEN; if (( volume->v_flags & AFPVOL_OPEN ) == 0 ) { /* FIXME unix name != mac name */ diff --git a/etc/afpd/volume.h b/etc/afpd/volume.h index ea666c9b..19950047 100644 --- a/etc/afpd/volume.h +++ b/etc/afpd/volume.h @@ -1,5 +1,5 @@ /* - * $Id: volume.h,v 1.15 2002-10-09 18:46:32 didg Exp $ + * $Id: volume.h,v 1.16 2002-10-17 18:01:54 didg Exp $ * * Copyright (c) 1990,1994 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -46,8 +46,12 @@ struct vol { int v_lastdid; u_int16_t v_vid; void *v_nfsclient; - int v_nfs, v_casefold; + int v_nfs; + + int v_casefold; struct codepage *v_mtoupage, *v_utompage, *v_badumap; + int max_filename; + char *v_password; char *v_veto; #ifdef CNID_DB diff --git a/etc/uams/uams_pam.c b/etc/uams/uams_pam.c index b56fbffd..461ac0ef 100644 --- a/etc/uams/uams_pam.c +++ b/etc/uams/uams_pam.c @@ -1,5 +1,5 @@ /* - * $Id: uams_pam.c,v 1.13 2002-10-13 06:18:14 didg Exp $ + * $Id: uams_pam.c,v 1.14 2002-10-17 18:01:54 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu) @@ -125,40 +125,20 @@ static struct pam_conv PAM_conversation = { NULL }; - -/* cleartxt login */ -static int pam_login(void *obj, struct passwd **uam_pwd, +static int login(void *obj, char *username, int ulen, struct passwd **uam_pwd, char *ibuf, int ibuflen, char *rbuf, int *rbuflen) { struct passwd *pwd; - char *username; - int err, len, ulen, PAM_error; - - *rbuflen = 0; - - if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, - (void *) &username, &ulen) < 0) - return AFPERR_MISC; + int err, PAM_error; if (uam_afpserver_option(obj, UAM_OPTION_CLIENTNAME, (void *) &hostname, NULL) < 0) - { + { LOG(log_info, logtype_uams, "uams_pam.c :PAM: unable to retrieve client hostname"); hostname = NULL; - } - - - len = (unsigned char) *ibuf++; - if ( len > ulen ) { - return( AFPERR_PARAM ); } - - memcpy(username, ibuf, len ); - ibuf += len; - username[ len ] = '\0'; - if ((unsigned long) ibuf & 1) /* pad character */ - ++ibuf; + ibuf[ PASSWDLEN ] = '\0'; if (( pwd = uam_getname(username, ulen)) == NULL ) { @@ -214,6 +194,71 @@ login_err: pam_end(pamh, PAM_error); pamh = NULL; return err; + +} + +/* -------------------------- + cleartxt login +*/ +static int pam_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; + + + len = (unsigned char) *ibuf++; + if ( len > ulen ) { + return( AFPERR_PARAM ); + } + + memcpy(username, ibuf, len ); + ibuf += len; + + username[ len ] = '\0'; + if ((unsigned long) ibuf & 1) /* pad character */ + ++ibuf; + return (login(obj, username, ulen, uam_pwd, ibuf, ibuflen, rbuf, rbuflen)); +} + +static int pam_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'; +#if 0 + if ((unsigned long) ibuf & 1) { /* pad character */ + ++ibuf; + } +#endif + return (login(obj, username, ulen, uam_pwd, ibuf, ibuflen, rbuf, rbuflen)); } /* logout */ @@ -384,8 +429,8 @@ int pam_printer(start, stop, username, out) static int uam_setup(const char *path) { - if (uam_register(UAM_SERVER_LOGIN, path, "Cleartxt Passwrd", - pam_login, NULL, pam_logout) < 0) + if (uam_register(UAM_SERVER_LOGIN_EXT, path, "Cleartxt Passwrd", + pam_login, NULL, pam_logout, pam_login_ext) < 0) return -1; if (uam_register(UAM_SERVER_CHANGEPW, path, "Cleartxt Passwrd", diff --git a/etc/uams/uams_passwd.c b/etc/uams/uams_passwd.c index 5b90d495..027d6c85 100644 --- a/etc/uams/uams_passwd.c +++ b/etc/uams/uams_passwd.c @@ -1,5 +1,5 @@ /* - * $Id: uams_passwd.c,v 1.18 2002-09-29 23:30:20 sibaz Exp $ + * $Id: uams_passwd.c,v 1.19 2002-10-17 18:01:55 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu) @@ -57,23 +57,15 @@ char *strchr (), *strrchr (); static char *clientname; #endif /* TRU64 */ -/* cleartxt login */ -static int passwd_login(void *obj, struct passwd **uam_pwd, +static int pwd_login(void *obj, char *username, int ulen, struct passwd **uam_pwd, char *ibuf, int ibuflen, char *rbuf, int *rbuflen) { + char *p; struct passwd *pwd; #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,25 +73,6 @@ 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 ); } @@ -110,6 +83,7 @@ static int passwd_login(void *obj, struct passwd **uam_pwd, } LOG(log_info, logtype_uams, "cleartext login: %s", username); + if (uam_checkuser(pwd) < 0) { LOG(log_info, logtype_uams, "not a valid user"); return AFPERR_NOTAUTH; @@ -151,8 +125,78 @@ static int passwd_login(void *obj, struct passwd **uam_pwd, #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 */ @@ -294,11 +338,23 @@ struct papfile *out; 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 +363,8 @@ static int uam_setup(const char *path) return 0; } +#endif + static void uam_cleanup(void) { uam_unregister(UAM_SERVER_LOGIN, "Cleartxt Passwrd"); diff --git a/include/atalk/uam.h b/include/atalk/uam.h index 5bf6b69f..d7e5048f 100644 --- a/include/atalk/uam.h +++ b/include/atalk/uam.h @@ -28,6 +28,7 @@ #define UAM_SERVER_LOGIN (1 << 0) #define UAM_SERVER_CHANGEPW (1 << 1) #define UAM_SERVER_PRINTAUTH (1 << 2) +#define UAM_SERVER_LOGIN_EXT (1 << 3) /* options */ #define UAM_OPTION_USERNAME (1 << 0) /* get space for username */ -- 2.39.2