X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Fuam.c;h=74340565b4da5dc26fe9a91195b7ad260e25fc4a;hb=f758a8c097b044293fa2fe58f8a7fcc2d8909b55;hp=7e18ee2025d344a54e0dda709a97d8a013cbe717;hpb=16c71250cf94fb7b4369df930b701a3c236311b0;p=netatalk.git diff --git a/etc/afpd/uam.c b/etc/afpd/uam.c index 7e18ee20..74340565 100644 --- a/etc/afpd/uam.c +++ b/etc/afpd/uam.c @@ -1,5 +1,5 @@ /* - * $Id: uam.c,v 1.23 2002-10-17 18:01:54 didg Exp $ + * $Id: uam.c,v 1.30 2009-10-22 12:35:38 franklahm Exp $ * * Copyright (c) 1999 Adrian Sun (asun@zoology.washington.edu) * All Rights Reserved. See COPYRIGHT. @@ -56,6 +56,12 @@ char *strchr (), *strrchr (); #include "auth.h" #include "uam_auth.h" +#ifdef AFP3x +#define utf8_encoding() (afp_version >= 30) +#else +#define utf8_encoding() (0) +#endif + #ifdef TRU64 #include #include @@ -87,8 +93,7 @@ struct uam_mod *uam_load(const char *path, const char *name) goto uam_load_fail; } - strncpy(buf, name, sizeof(buf)); - buf[sizeof(buf) - 1] = '\0'; + strlcpy(buf, name, sizeof(buf)); if ((p = strchr(buf, '.'))) *p = '\0'; @@ -142,12 +147,12 @@ void uam_unload(struct uam_mod *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, ...) { va_list ap; struct uam_obj *uam; + int ret; if (!name) return -1; @@ -197,77 +202,14 @@ int uam_register(const int type, const char *path, const char *name, ...) va_end(ap); /* attach to other uams */ - if (auth_register(type, uam) < 0) { - free(uam->uam_path); - free(uam); - return -1; - } - - 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) { + ret = auth_register(type, uam); + if ( ret) { free(uam->uam_path); free(uam); - return -1; } - return 0; + return ret; } -#endif void uam_unregister(const int type, const char *name) { @@ -285,33 +227,71 @@ void uam_unregister(const int type, const char *name) free(uam); } -/* --- helper functions for plugin uams --- */ +/* --- helper functions for plugin uams --- + * name: user name + * len: size of name buffer. +*/ -struct passwd *uam_getname(char *name, const int len) +struct passwd *uam_getname(void *private, char *name, const int len) { + AFPObj *obj = private; struct passwd *pwent; - char *user; - int i; + static char username[256]; + static char user[256]; + static char pwname[256]; + char *p; + size_t namelen, gecoslen = 0, pwnamelen = 0; if ((pwent = getpwnam(name))) return pwent; - + + /* if we have a NT domain name try with it */ + if (obj->options.ntdomain && obj->options.ntseparator) { + /* FIXME What about charset ? */ + size_t ulen = strlen(obj->options.ntdomain) + strlen(obj->options.ntseparator) + strlen(name); + if ((p = malloc(ulen +1))) { + strcpy(p, obj->options.ntdomain); + strcat(p, obj->options.ntseparator); + strcat(p, name); + pwent = getpwnam(p); + free(p); + if (pwent) { + int len = strlen(pwent->pw_name); + if (len < MAXUSERLEN) { + strncpy(name,pwent->pw_name, MAXUSERLEN); + }else{ + LOG(log_error, logtype_uams, "MAJOR:The name %s is longer than %d",pwent->pw_name,MAXUSERLEN); + } + + return pwent; + } + } + } #ifndef NO_REAL_USER_NAME - for (i = 0; i < len; i++) - name[i] = tolower(name[i]); + + if ( (size_t) -1 == (namelen = convert_string((utf8_encoding())?CH_UTF8_MAC:obj->options.maccharset, + CH_UCS2, name, strlen(name), username, sizeof(username)))) + return NULL; setpwent(); while ((pwent = getpwent())) { - if ((user = strchr(pwent->pw_gecos, ','))) - *user = '\0'; - user = pwent->pw_gecos; + if ((p = strchr(pwent->pw_gecos, ','))) + *p = '\0'; + + if ((size_t)-1 == ( gecoslen = convert_string(obj->options.unixcharset, CH_UCS2, + pwent->pw_gecos, strlen(pwent->pw_gecos), user, sizeof(username))) ) + continue; + if ((size_t)-1 == ( pwnamelen = convert_string(obj->options.unixcharset, CH_UCS2, + pwent->pw_name, strlen(pwent->pw_name), pwname, sizeof(username))) ) + continue; + /* check against both the gecos and the name fields. the user * might have just used a different capitalization. */ - if ((strncasecmp(user, name, len) == 0) || - (strncasecmp(pwent->pw_name, name, len) == 0)) { - strncpy(name, pwent->pw_name, len); - name[len - 1] = '\0'; + + if ( (namelen == gecoslen && strncasecmp_w((ucs2_t*)user, (ucs2_t*)username, len) == 0) || + ( namelen == pwnamelen && strncasecmp_w ( (ucs2_t*) pwname, (ucs2_t*) username, len) == 0)) { + strlcpy(name, pwent->pw_name, len); break; } } @@ -334,7 +314,6 @@ int uam_checkuser(const struct passwd *pwd) LOG(log_info, logtype_afpd, "uam_checkuser: User %s does not have a shell", pwd->pw_name); return -1; } -#endif while ((p = getusershell())) { if ( strcmp( p, pwd->pw_shell ) == 0 ) @@ -342,7 +321,6 @@ int uam_checkuser(const struct passwd *pwd) } endusershell(); -#ifndef DISABLE_SHELLCHECK if (!p) { LOG(log_info, logtype_afpd, "illegal shell %s for %s", pwd->pw_shell, pwd->pw_name); return -1; @@ -352,27 +330,57 @@ int uam_checkuser(const struct passwd *pwd) return 0; } +int uam_random_string (AFPObj *obj, char *buf, int len) +{ + u_int32_t result; + int ret; + int fd; + + if ( (len <= 0) || (len % sizeof(result))) + return -1; + + /* construct a random number */ + if ((fd = open("/dev/urandom", O_RDONLY)) < 0) { + struct timeval tv; + struct timezone tz; + int i; + + if (gettimeofday(&tv, &tz) < 0) + return -1; + srandom(tv.tv_sec + (unsigned long) obj + (unsigned long) obj->handle); + for (i = 0; i < len; i += sizeof(result)) { + result = random(); + memcpy(buf + i, &result, sizeof(result)); + } + } else { + ret = read(fd, buf, len); + close(fd); + if (ret <= 0) + return -1; + } + return 0; +} + /* afp-specific functions */ int uam_afpserver_option(void *private, const int what, void *option, - int *len) + size_t *len) { AFPObj *obj = private; char **buf = (char **) option; /* most of the options are this */ - int32_t result; - int fd; + struct session_info **sinfo = (struct session_info **) option; if (!obj || !option) return -1; switch (what) { case UAM_OPTION_USERNAME: - *buf = (void *) obj->username; + *buf = obj->username; if (len) *len = sizeof(obj->username) - 1; break; case UAM_OPTION_GUEST: - *buf = (void *) obj->options.guest; + *buf = obj->options.guest; if (len) *len = strlen(obj->options.guest); break; @@ -383,7 +391,7 @@ AFPObj *obj = private; switch (*len) { case UAM_PASSWD_FILENAME: - *buf = (void *) obj->options.passwdfile; + *buf = obj->options.passwdfile; *len = strlen(obj->options.passwdfile); break; @@ -411,40 +419,22 @@ AFPObj *obj = private; break; case UAM_OPTION_RANDNUM: /* returns a random number in 4-byte units. */ - if (!len || (*len < 0) || (*len % sizeof(result))) + if (!len) return -1; - /* construct a random number */ - if ((fd = open("/dev/urandom", O_RDONLY)) < 0) { - struct timeval tv; - struct timezone tz; - char *randnum = (char *) option; - int i; - - if (gettimeofday(&tv, &tz) < 0) - return -1; - srandom(tv.tv_sec + (unsigned long) obj + (unsigned long) obj->handle); - for (i = 0; i < *len; i += sizeof(result)) { - result = random(); - memcpy(randnum + i, &result, sizeof(result)); - } - } else { - result = read(fd, option, *len); - close(fd); - if (result < 0) - return -1; - } + return uam_random_string(obj, option, *len); break; case UAM_OPTION_HOSTNAME: - *buf = (void *) obj->options.hostname; + *buf = obj->options.hostname; if (len) *len = strlen(obj->options.hostname); break; case UAM_OPTION_PROTOCOL: - *buf = (void *) obj->proto; + *((int *) option) = obj->proto; break; + case UAM_OPTION_CLIENTNAME: { struct DSI *dsi = obj->handle; @@ -454,9 +444,9 @@ AFPObj *obj = private; sizeof( struct in_addr ), dsi->client.sin_family ); if( hp ) - *buf = (void *) hp->h_name; + *buf = hp->h_name; else - *buf = (void *) inet_ntoa( dsi->client.sin_addr ); + *buf = inet_ntoa( dsi->client.sin_addr ); } break; case UAM_OPTION_COOKIE: @@ -466,7 +456,32 @@ AFPObj *obj = private; * the cookie. */ *buf = (void *) &obj->uam_cookie; break; - + case UAM_OPTION_KRB5SERVICE: + *buf = obj->options.k5service; + if (len) + *len = (*buf)?strlen(*buf):0; + break; + case UAM_OPTION_KRB5REALM: + *buf = obj->options.k5realm; + if (len) + *len = (*buf)?strlen(*buf):0; + break; + case UAM_OPTION_FQDN: + *buf = obj->options.fqdn; + if (len) + *len = (*buf)?strlen(*buf):0; + break; + case UAM_OPTION_MACCHARSET: + *((int *) option) = obj->options.maccharset; + *len = sizeof(obj->options.maccharset); + break; + case UAM_OPTION_UNIXCHARSET: + *((int *) option) = obj->options.unixcharset; + *len = sizeof(obj->options.unixcharset); + break; + case UAM_OPTION_SESSIONINFO: + *sinfo = &(obj->sinfo); + break; default: return -1; break; @@ -478,7 +493,7 @@ AFPObj *obj = private; /* if we need to maintain a connection, this is how we do it. * because an action pointer gets passed in, we can stream * DSI connections */ -int uam_afp_read(void *handle, char *buf, int *buflen, +int uam_afp_read(void *handle, char *buf, size_t *buflen, int (*action)(void *, void *, const int)) { AFPObj *obj = handle; @@ -568,7 +583,7 @@ int uam_sia_validate_user(sia_collect_func_t * collect, int argc, char **argv, #endif /* TRU64 */ /* --- papd-specific functions (just placeholders) --- */ -void append(void *pf, char *data, int len) +void append(void *pf _U_, char *data _U_, int len _U_) { return; }