X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=blobdiff_plain;f=etc%2Fuams%2Fuams_pam.c;h=25ee5814b3ae440231bea067e65025fba1fe1f4e;hp=473e5e5c6e1ea6a6822e5b9f9823cb7abf8d13a4;hb=75fe310224dffb96868d7f2cb1ec9125a84f2a08;hpb=458fcac4e6aee7eb54ba744f57169f70cce12505 diff --git a/etc/uams/uams_pam.c b/etc/uams/uams_pam.c index 473e5e5c..25ee5814 100644 --- a/etc/uams/uams_pam.c +++ b/etc/uams/uams_pam.c @@ -1,4 +1,6 @@ /* + * $Id: uams_pam.c,v 1.22 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) * All Rights Reserved. See COPYRIGHT. @@ -6,30 +8,61 @@ #ifdef HAVE_CONFIG_H #include "config.h" -#endif +#endif /* HAVE_CONFIG_H */ -#ifdef USE_PAM #include #include +#ifdef HAVE_UNISTD_H #include -#include -#include +#endif /* HAVE_UNISTD_H */ +/* STDC check */ +#if STDC_HEADERS +#include +#else /* STDC_HEADERS */ +#ifndef HAVE_STRCHR +#define strchr index +#define strrchr index +#endif /* HAVE_STRCHR */ +char *strchr (), *strrchr (); +#ifndef HAVE_MEMCPY +#define memcpy(d,s,n) bcopy ((s), (d), (n)) +#define memmove(d,s,n) bcopy ((s), (d), (n)) +#endif /* ! HAVE_MEMCPY */ +#endif /* STDC_HEADERS */ + +#include + +#ifdef HAVE_SECURITY_PAM_APPL_H #include +#endif +#ifdef HAVE_PAM_PAM_APPL_H +#include +#endif #include #include +#include #define PASSWDLEN 8 +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif /* MIN */ + + /* Static variables used to communicate between the conversation function * and the server_login function */ static pam_handle_t *pamh = NULL; -static char *hostname; +static const char *hostname; static char *PAM_username; static char *PAM_password; +/*XXX in etc/papd/file.h */ +struct papfile; +extern void append(struct papfile *, const char *, int); + /* PAM conversation function * Here we assume (for now, at least) that echo on means login name, and * echo off means password. @@ -37,7 +70,7 @@ static char *PAM_password; static int PAM_conv (int num_msg, const struct pam_message **msg, struct pam_response **resp, - void *appdata_ptr) + void *appdata_ptr _U_) { struct pam_response *reply; int count; @@ -68,7 +101,7 @@ static int PAM_conv (int num_msg, case PAM_TEXT_INFO: #ifdef PAM_BINARY_PROMPT case PAM_BINARY_PROMPT: -#endif +#endif /* PAM_BINARY_PROMPT */ /* ignore it... */ break; case PAM_ERROR_MSG: @@ -106,43 +139,27 @@ static struct pam_conv PAM_conversation = { NULL }; - -/* cleartxt login */ -static int pam_login(void *obj, struct passwd **uam_pwd, - char *ibuf, int ibuflen, - char *rbuf, int *rbuflen) +static int login(void *obj, char *username, int ulen, struct passwd **uam_pwd, + char *ibuf, size_t ibuflen _U_, + char *rbuf _U_, size_t *rbuflen _U_) { 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_HOSTNAME, + if (uam_afpserver_option(obj, UAM_OPTION_CLIENTNAME, (void *) &hostname, NULL) < 0) - return AFPERR_MISC; - - len = (unsigned char) *ibuf++; - if ( len > ulen ) { - return( AFPERR_PARAM ); + { + LOG(log_info, logtype_uams, "uams_pam.c :PAM: unable to retrieve client hostname"); + hostname = NULL; } - - 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 ) { + if (( pwd = uam_getname(obj, username, ulen)) == NULL ) { return AFPERR_PARAM; } - syslog(LOG_INFO, "cleartext login: %s", username); + LOG(log_info, logtype_uams, "cleartext login: %s", username); PAM_username = username; PAM_password = ibuf; /* Set these things up for the conv function */ @@ -164,18 +181,19 @@ static int pam_login(void *obj, struct passwd **uam_pwd, PAM_error = pam_acct_mgmt(pamh, 0); if (PAM_error != PAM_SUCCESS) { - if (PAM_error == PAM_ACCT_EXPIRED) + if (PAM_error == PAM_NEW_AUTHTOK_REQD) /* Password change required */ err = AFPERR_PWDEXPR; #ifdef PAM_AUTHTOKEN_REQD else if (PAM_error == PAM_AUTHTOKEN_REQD) err = AFPERR_PWDCHNG; -#endif - goto login_err; +#endif /* PAM_AUTHTOKEN_REQD */ + else + goto login_err; } #ifndef PAM_CRED_ESTABLISH #define PAM_CRED_ESTABLISH PAM_ESTABLISH_CRED -#endif +#endif /* PAM_CRED_ESTABLISH */ PAM_error = pam_setcred(pamh, PAM_CRED_ESTABLISH); if (PAM_error != PAM_SUCCESS) goto login_err; @@ -185,6 +203,10 @@ static int pam_login(void *obj, struct passwd **uam_pwd, goto login_err; *uam_pwd = pwd; + + if (err == AFPERR_PWDEXPR) + return err; + return AFP_OK; login_err: @@ -193,17 +215,77 @@ login_err: return err; } +/* -------------------------- + cleartxt login +*/ +static int pam_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; + } + + 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, 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 (login(obj, username, ulen, uam_pwd, ibuf, ibuflen, rbuf, rbuflen)); +} + /* logout */ -static void pam_logout() { +static void pam_logout(void) { pam_close_session(pamh, 0); pam_end(pamh, 0); pamh = NULL; } /* change passwd */ -static int pam_changepw(void *obj, char *username, - struct passwd *pwd, char *ibuf, int ibuflen, - char *rbuf, int *rbuflen) +static int pam_changepw(void *obj _U_, char *username, + struct passwd *pwd _U_, char *ibuf, size_t ibuflen _U_, + char *rbuf _U_, size_t *rbuflen _U_) { char pw[PASSWDLEN + 1]; pam_handle_t *lpamh; @@ -261,17 +343,21 @@ static int pam_changepw(void *obj, char *username, /* Printer ClearTxtUAM login */ -int pam_printer(start, stop, username, out) - char *start, *stop, *username; - struct papfile *out; +static int pam_printer(char *start, char *stop, char *username, struct papfile *out) { int PAM_error; char *data, *p, *q; char password[PASSWDLEN + 1] = "\0"; static const char *loginok = "0\r"; + struct passwd *pwd; 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) @@ -281,37 +367,48 @@ int pam_printer(start, stop, username, out) /* Parse input for username in () */ if ((p = strchr(data, '(' )) == NULL) { - syslog(LOG_INFO,"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) { - syslog(LOG_INFO,"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) { - syslog(LOG_INFO,"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); + if (( pwd = uam_getname(NULL, username, strlen(username))) == NULL ) { + LOG(log_info, logtype_uams, "Bad Login ClearTxtUAM: ( %s ) not found ", + username); + return(-1); + } + + if (uam_checkuser(pwd) < 0) { + /* syslog of error happens in uam_checkuser */ + return(-1); + } + PAM_username = username; PAM_password = password; PAM_error = pam_start("netatalk", username, &PAM_conversation, &pamh); if (PAM_error != PAM_SUCCESS) { - syslog(LOG_INFO, "Bad Login ClearTxtUAM: %s: %s", + LOG(log_info, logtype_uams, "Bad Login ClearTxtUAM: %s: %s", username, pam_strerror(pamh, PAM_error)); pam_end(pamh, PAM_error); pamh = NULL; @@ -322,7 +419,7 @@ int pam_printer(start, stop, username, out) pam_set_item(pamh, PAM_RHOST, hostname); PAM_error = pam_authenticate(pamh,0); if (PAM_error != PAM_SUCCESS) { - syslog(LOG_INFO, "Bad Login ClearTxtUAM: %s: %s", + LOG(log_info, logtype_uams, "Bad Login ClearTxtUAM: %s: %s", username, pam_strerror(pamh, PAM_error)); pam_end(pamh, PAM_error); pamh = NULL; @@ -331,7 +428,7 @@ int pam_printer(start, stop, username, out) PAM_error = pam_acct_mgmt(pamh, 0); if (PAM_error != PAM_SUCCESS) { - syslog(LOG_INFO, "Bad Login ClearTxtUAM: %s: %s", + LOG(log_info, logtype_uams, "Bad Login ClearTxtUAM: %s: %s", username, pam_strerror(pamh, PAM_error)); pam_end(pamh, PAM_error); pamh = NULL; @@ -340,7 +437,7 @@ int pam_printer(start, stop, username, out) PAM_error = pam_open_session(pamh, 0); if (PAM_error != PAM_SUCCESS) { - syslog(LOG_INFO, "Bad Login ClearTxtUAM: %s: %s", + LOG(log_info, logtype_uams, "Bad Login ClearTxtUAM: %s: %s", username, pam_strerror(pamh, PAM_error)); pam_end(pamh, PAM_error); pamh = NULL; @@ -350,7 +447,7 @@ int pam_printer(start, stop, username, out) /* Login successful, but no need to hang onto it, so logout immediately */ append(out, loginok, strlen(loginok)); - syslog(LOG_INFO, "Login ClearTxtUAM: %s", username); + LOG(log_info, logtype_uams, "Login ClearTxtUAM: %s", username); pam_close_session(pamh, 0); pam_end(pamh, 0); pamh = NULL; @@ -361,8 +458,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", @@ -392,4 +489,8 @@ UAM_MODULE_EXPORT struct uam_export uams_clrtxt = { uam_setup, uam_cleanup }; -#endif /* USE_PAM */ +UAM_MODULE_EXPORT struct uam_export uams_pam = { + UAM_MODULE_SERVER, + UAM_MODULE_VERSION, + uam_setup, uam_cleanup +};