Bugfixes.

* pam_ldaphome/pam_ldaphome.c (argcv_free): Fix multiple free
(argcv_concat): Fix overly conservative size calculation and
concatenation loop.
(parse_ldap_uri): Fix URI reconstruction.
(dir_copy_loop): Remove unused variable.
(store_pubkey): Return meaningful error code.
(import_public_key): Propagate return code from store_pubkey.
(create_home_dir): Return meaningful error code.
(pam_sm_authenticate): Propagate return code from create_home_dir
and import_public_key to the caller.
* pam_log/Makefile.am: Remove BUILD_PAM_LOG substitution
(complements 1a80b647).
This commit is contained in:
Sergey Poznyakoff 2012-05-15 17:23:31 +03:00
parent 996f020583
commit 381fbf3365
2 changed files with 20 additions and 22 deletions

View file

@ -72,8 +72,8 @@ argcv_free(int wc, char **wv)
for (i = 0; i < wc; i++) { for (i = 0; i < wc; i++) {
free(wv[i]); free(wv[i]);
free(wv);
} }
free(wv);
} }
static int static int
@ -131,14 +131,13 @@ argcv_concat(int wc, char **wv)
for (i = 0; i < wc; i++) for (i = 0; i < wc; i++)
size += strlen(wv[i]) + 1; size += strlen(wv[i]) + 1;
size++;
res = malloc(size); res = malloc(size);
if (!res) if (!res)
return 0; return 0;
for (p = res, i = 0; ; i++) { for (p = res, i = 0;;) {
strcpy(p, wv[i]); strcpy(p, wv[i]);
p += strlen(wv[i]); p += strlen(wv[i]);
if (i < wc) if (++i < wc)
*p++ = ' '; *p++ = ' ';
else else
break; break;
@ -266,7 +265,7 @@ parse_ldap_uri(const char *uri)
return NULL; return NULL;
} else if (!urls) } else if (!urls)
return NULL; return NULL;
ldapuri = argcv_concat(wc, wv); ldapuri = argcv_concat(nurls, urls);
if (!ldapuri) if (!ldapuri)
_pam_log(LOG_ERR, "%s", strerror(errno)); _pam_log(LOG_ERR, "%s", strerror(errno));
ber_memvfree ((void **)urls); ber_memvfree ((void **)urls);
@ -882,7 +881,6 @@ dir_copy_loop(pam_handle_t *pamh, DIR *dir,
char *buffer, size_t bufsize, struct passwd *pw) char *buffer, size_t bufsize, struct passwd *pw)
{ {
struct dirent *ent; struct dirent *ent;
struct stat dir_st;
while ((ent = readdir(dir))) { while ((ent = readdir(dir))) {
char const *ename = ent->d_name; char const *ename = ent->d_name;
@ -1044,7 +1042,7 @@ populate_homedir(pam_handle_t *pamh, struct passwd *pw, struct gray_env *env)
return rc; return rc;
} }
static void static int
store_pubkey(const char *key, struct passwd *pw) store_pubkey(const char *key, struct passwd *pw)
{ {
FILE *fp; FILE *fp;
@ -1053,6 +1051,7 @@ store_pubkey(const char *key, struct passwd *pw)
int found = 0; int found = 0;
char *file_name; char *file_name;
size_t homelen, pathlen, len; size_t homelen, pathlen, len;
int retval;
homelen = strlen(pw->pw_dir); homelen = strlen(pw->pw_dir);
pathlen = strlen(authorized_keys_file); pathlen = strlen(authorized_keys_file);
@ -1072,7 +1071,7 @@ store_pubkey(const char *key, struct passwd *pw)
_pam_log(LOG_EMERG, "cannot open file %s: %s", _pam_log(LOG_EMERG, "cannot open file %s: %s",
file_name, strerror(errno)); file_name, strerror(errno));
free(file_name); free(file_name);
return; return PAM_SERVICE_ERR;
} }
free(file_name); free(file_name);
fchown(fileno(fp), pw->pw_uid, pw->pw_gid); fchown(fileno(fp), pw->pw_uid, pw->pw_gid);
@ -1103,8 +1102,11 @@ store_pubkey(const char *key, struct passwd *pw)
if (!found) { if (!found) {
fwrite(key, strlen(key), 1, fp); fwrite(key, strlen(key), 1, fp);
fputc('\n', fp); fputc('\n', fp);
} retval = PAM_TRY_AGAIN;
} else
retval = PAM_SUCCESS;
fclose(fp); fclose(fp);
return retval;
} }
static int static int
@ -1142,9 +1144,8 @@ import_public_key(pam_handle_t *pamh, struct passwd *pw, struct gray_env *env)
pubkey = ldap_search(ld, base, filter, attr); pubkey = ldap_search(ld, base, filter, attr);
gray_slist_free(&slist); gray_slist_free(&slist);
store_pubkey(pubkey, pw); retval = store_pubkey(pubkey, pw);
free(pubkey); free(pubkey);
retval = PAM_SUCCESS;
} }
ldap_unbind(ld); ldap_unbind(ld);
return retval; return retval;
@ -1159,24 +1160,23 @@ create_home_dir(pam_handle_t *pamh, struct passwd *pw, struct gray_env *env)
if (errno != ENOENT) { if (errno != ENOENT) {
_pam_log(LOG_ERR, "cannot stat home directory %s: %s", _pam_log(LOG_ERR, "cannot stat home directory %s: %s",
pw->pw_dir, strerror(errno)); pw->pw_dir, strerror(errno));
return 1; return PAM_SERVICE_ERR;
} }
/* FIXME: mode must be configurable */ /* FIXME: mode must be configurable */
if (mkdir(pw->pw_dir, 0775)) { if (mkdir(pw->pw_dir, 0775)) {
_pam_log(LOG_ERR, "cannot create %s: %s", _pam_log(LOG_ERR, "cannot create %s: %s",
pw->pw_dir, strerror(errno)); pw->pw_dir, strerror(errno));
return 1; return PAM_SERVICE_ERR;
} }
populate_homedir(pamh, pw, env); populate_homedir(pamh, pw, env);
chown(pw->pw_dir, pw->pw_uid, pw->pw_gid); chown(pw->pw_dir, pw->pw_uid, pw->pw_gid);
} else if (!S_ISDIR(st.st_mode)) { } else if (!S_ISDIR(st.st_mode)) {
_pam_log(LOG_ERR, "%s exists, but is not a directory", _pam_log(LOG_ERR, "%s exists, but is not a directory",
pw->pw_dir); pw->pw_dir);
return 1; return PAM_SERVICE_ERR;
} }
return PAM_SUCCESS;
return 0;
} }
PAM_EXTERN int PAM_EXTERN int
@ -1196,9 +1196,9 @@ pam_sm_authenticate(pam_handle_t *pamh,
struct passwd *pw; struct passwd *pw;
if (check_user_groups(pamh, env, &pw, &retval) == 0) { if (check_user_groups(pamh, env, &pw, &retval) == 0) {
if (create_home_dir(pamh, pw, env) == 0 && retval = create_home_dir(pamh, pw, env);
import_public_key(pamh, pw, env) == 0) if (retval == PAM_SUCCESS)
retval = PAM_TRY_AGAIN; retval = import_public_key(pamh, pw, env);
} }
gray_env_free(env); gray_env_free(env);
} }

View file

@ -14,9 +14,7 @@
# with this program. If not, see <http://www.gnu.org/licenses/>. # with this program. If not, see <http://www.gnu.org/licenses/>.
pamdir=@PAMDIR@ pamdir=@PAMDIR@
PAM_LOG = pam_log.la pam_LTLIBRARIES = pam_log.la
pam_LTLIBRARIES = @BUILD_PAM_LOG@
EXTRA_LTLIBRARIES = pam_log.la
pam_log_la_SOURCES = pam_log.c pam_log_la_SOURCES = pam_log.c
AM_CPPFLAGS=-DMODULE_NAME=\"pam_log\" -DSYSCONFDIR=\"${sysconfdir}\" AM_CPPFLAGS=-DMODULE_NAME=\"pam_log\" -DSYSCONFDIR=\"${sysconfdir}\"