aboutsummaryrefslogtreecommitdiff
path: root/pam_ldaphome/pam_ldaphome.c
diff options
context:
space:
mode:
Diffstat (limited to 'pam_ldaphome/pam_ldaphome.c')
-rw-r--r--pam_ldaphome/pam_ldaphome.c262
1 files changed, 169 insertions, 93 deletions
diff --git a/pam_ldaphome/pam_ldaphome.c b/pam_ldaphome/pam_ldaphome.c
index dd3f9e3..0b492dd 100644
--- a/pam_ldaphome/pam_ldaphome.c
+++ b/pam_ldaphome/pam_ldaphome.c
@@ -179,3 +179,3 @@ get_intval(struct gray_env *env, const char *name, int base, unsigned long *pv)
-char *
+static char *
parse_ldap_uri(const char *uri)
@@ -724,9 +724,17 @@ check_groups(int gc, char **gv, const char *username, gid_t gid)
char *pgname;
+ int rc = 1;
gp = getgrgid(gid);
- pgname = gp ? gray_strdup(gp->gr_name) : NULL;
- for (i = 0; i < gc; i++) {
+ if (gp) {
+ pgname = strdup(gp->gr_name);
+ if (!pgname) {
+ errno_to_pam(errno);
+ return -1;
+ }
+ } else
+ gp = NULL;
+ for (i = 0; rc && i < gc; i++) {
if (strcmp(gv[i], pgname) == 0) {
- free(pgname);
- return 0;
+ rc = 0;
+ break;
}
@@ -735,6 +743,6 @@ check_groups(int gc, char **gv, const char *username, gid_t gid)
char **p;
- for (p = gp->gr_mem; *p; p++)
+ for (p = gp->gr_mem; *p; p++) {
if (strcmp(username, *p) == 0) {
- free(pgname);
- return 0;
+ rc = 0;
+ break;
}
@@ -742,3 +750,5 @@ check_groups(int gc, char **gv, const char *username, gid_t gid)
}
- return 1;
+ }
+ free(pgname);
+ return rc;
}
@@ -858,32 +868,20 @@ copy_file(pam_handle_t *pamh, const char *src, const char *dst,
-#define INITIAL_READLINK_SIZE 128
-
-int
-read_link_name(const char *name, char **pbuf, size_t *psize, size_t *plen)
+static int
+read_link_name(const char *name, char **pbuf)
{
int rc = 0;
- char *buf = *pbuf;
- size_t size = *psize;
- ssize_t linklen;
+ char *buf = NULL;
+ size_t size = 0;
+ ssize_t linklen = 0;
while (1) {
- if (!buf) {
- size = INITIAL_READLINK_SIZE;
- buf = malloc(size);
- } else {
- char *p;
- size_t newsize = size << 1;
- if (newsize < size) {
- rc = ENAMETOOLONG;
+ if (linklen == size) {
+ char *p = gray_2nrealloc(&buf, &size, 1);
+ if (!p) {
+ errno_to_pam(errno);
+ rc = 1;
break;
}
- size = newsize;
- p = realloc(buf, size);
- if (!p)
- free(buf);
buf = p;
- }
- if (!buf) {
- rc = 1;
- break;
+ linklen = size;
}
@@ -896,3 +894,3 @@ read_link_name(const char *name, char **pbuf, size_t *psize, size_t *plen)
- if ((size_t) linklen < size) {
+ if (linklen < size) {
buf[linklen++] = '\0';
@@ -908,8 +906,4 @@ read_link_name(const char *name, char **pbuf, size_t *psize, size_t *plen)
}
- size = 0;
}
*pbuf = buf;
- *psize = size;
- if (plen)
- *plen = linklen;
return rc;
@@ -922,7 +916,6 @@ copy_link(pam_handle_t *pamh, const char *src, const char *dst,
{
- char *lnkname = NULL;
- size_t lnklen = 0;
+ char *lnkname;
int rc;
- if (read_link_name(src, &lnkname, &lnklen, NULL)) {
+ if (read_link_name(src, &lnkname)) {
_pam_log(LOG_ERR, "error reading link %s: %s",
@@ -1001,3 +994,7 @@ create_interdir(const char *path, struct passwd *pw)
len = p - path;
- dir = gray_malloc(len + 1);
+ dir = malloc(len + 1);
+ if (!dir) {
+ errno_to_pam(errno);
+ return -1;
+ }
memcpy(dir, path, len);
@@ -1270,2 +1267,17 @@ struct pubkeyfile {
+/* Close the public key file */
+static void
+pubkeyfile_close(struct pubkeyfile *pkb)
+{
+ close(pkb->fd);
+ free(pkb->file_name);
+ free(pkb->base);
+ free(pkb->lnv);
+
+ pkb->fd = -1;
+ pkb->file_name = NULL;
+ pkb->base = NULL;
+ pkb->lnv = NULL;
+}
+
/* Open public key file NAME. Return 0 on success. On error, issue a
@@ -1282,3 +1294,9 @@ pubkeyfile_open(struct pubkeyfile *pkb, char *name)
}
- pkb->file_name = gray_strdup(name);
+ pkb->file_name = strdup(name);
+ if (!pkb->file_name) {
+ int rc = errno_to_pam(errno);
+ close(pkb->fd);
+ pkb->fd = -1;
+ return rc;
+ }
return 0;
@@ -1300,3 +1318,7 @@ pubkeyfile_read(struct pubkeyfile *pkb)
pkb->size = st.st_size;
- pkb->base = gray_malloc(st.st_size + 1);
+ pkb->base = malloc(st.st_size + 1);
+ if (!pkb->base) {
+ errno_to_pam(errno);
+ return -1;
+ }
if (full_read(pkb->fd, pkb->file_name, pkb->base, pkb->size)) {
@@ -1312,4 +1334,7 @@ pubkeyfile_read(struct pubkeyfile *pkb)
pkb->lnm = pkb->lnc + 1;
- pkb->lnv = gray_calloc(pkb->lnm, sizeof(pkb->lnv[0]));
-
+ pkb->lnv = calloc(pkb->lnm, sizeof(pkb->lnv[0]));
+ if (pkb->lnv) {
+ errno_to_pam(errno);
+ return -1;
+ }
i = 0;
@@ -1331,3 +1356,6 @@ pubkeyfile_init(struct pubkeyfile *pkb, char *name)
return -1;
- return pubkeyfile_read(pkb);
+ if (pubkeyfile_read(pkb) == 0)
+ return 0;
+ pubkeyfile_close(pkb);
+ return -1;
}
@@ -1390,3 +1418,3 @@ pubkeyfile_remove_lines(struct pubkeyfile *pkb, int pos, int count)
the existing data. */
-static void
+static int
pubkeyfile_alloc_lines(struct pubkeyfile *pkb, size_t pos, size_t count)
@@ -1396,8 +1424,12 @@ pubkeyfile_alloc_lines(struct pubkeyfile *pkb, size_t pos, size_t count)
__FILE__, __LINE__);
- abort();
+ return PAM_SERVICE_ERR;
}
if (pkb->lnc + count + 1 > pkb->lnm) {
- pkb->lnm += count;
- pkb->lnv = gray_realloc(pkb->lnv,
- pkb->lnm * sizeof(pkb->lnv[0]));
+ char **p;
+ size_t lnm = pkb->lnm + count;
+ p = realloc(pkb->lnv, lnm * sizeof(pkb->lnv[0]));
+ if (!p)
+ return errno_to_pam(errno);
+ pkb->lnv = p;
+ pkb->lnm = lnm;
}
@@ -1406,2 +1438,3 @@ pubkeyfile_alloc_lines(struct pubkeyfile *pkb, size_t pos, size_t count)
pkb->lnc += count;
+ return PAM_SUCCESS;
}
@@ -1410,3 +1443,3 @@ pubkeyfile_alloc_lines(struct pubkeyfile *pkb, size_t pos, size_t count)
existing lines as necessary. */
-void
+static int
pubkeyfile_insert_lines(struct pubkeyfile *pkb, size_t pos, char **lv)
@@ -1415,2 +1448,3 @@ pubkeyfile_insert_lines(struct pubkeyfile *pkb, size_t pos, char **lv)
size_t lc;
+ int rc;
@@ -1419,4 +1453,4 @@ pubkeyfile_insert_lines(struct pubkeyfile *pkb, size_t pos, char **lv)
- pubkeyfile_alloc_lines(pkb, pos, lc);
-
+ rc = pubkeyfile_alloc_lines(pkb, pos, lc);
+ if (rc == 0) {
for (i = 0; i < lc; i++)
@@ -1424,14 +1458,5 @@ pubkeyfile_insert_lines(struct pubkeyfile *pkb, size_t pos, char **lv)
}
-
-/* Close the public key file */
-void
-pubkeyfile_close(struct pubkeyfile *pkb)
-{
- close(pkb->fd);
- free(pkb->file_name);
- free(pkb->base);
- free(pkb->lnv);
+ return rc;
}
-
static int
@@ -1453,3 +1478,5 @@ store_pubkeys(char **keys, struct passwd *pw, struct gray_env *env)
len++;
- file_name = gray_malloc(len + 1);
+ file_name = malloc(len + 1);
+ if (!file_name)
+ return errno_to_pam(errno);
memcpy(file_name, pw->pw_dir, homelen);
@@ -1522,5 +1549,7 @@ store_pubkeys(char **keys, struct passwd *pw, struct gray_env *env)
pubkeyfile_remove_lines(&pkf, 0, i);
- pubkeyfile_insert_lines(&pkf, 0, keys);
+ retval = pubkeyfile_insert_lines(&pkf, 0, keys);
+ if (retval == PAM_SUCCESS) {
pubkeyfile_write(&pkf);
retval = PAM_TRY_AGAIN;
+ }
} else
@@ -1562,5 +1591,7 @@ import_public_key(pam_handle_t *pamh, struct passwd *pw, struct gray_env *env)
gray_slist_t slist;
- char **keys;
slist = gray_slist_create();
+ if (!slist)
+ retval = errno_to_pam(errno);
+ else {
gray_expand_string(pamh, filter_pat, slist);
@@ -1568,5 +1599,5 @@ import_public_key(pam_handle_t *pamh, struct passwd *pw, struct gray_env *env)
filter = gray_slist_finish(slist);
-
- keys = get_pubkeys(ld, base, filter, attr);
- gray_slist_free(&slist);
+ if (filter) {
+ char **keys = get_pubkeys(ld, base, filter,
+ attr);
if (keys) {
@@ -1576,2 +1607,7 @@ import_public_key(pam_handle_t *pamh, struct passwd *pw, struct gray_env *env)
retval = PAM_SUCCESS;
+ } else {
+ retval = errno_to_pam(gray_slist_err(slist));
+ }
+ gray_slist_free(&slist);
+ }
}
@@ -1696,2 +1732,8 @@ locate_unset(char **env, const char *name)
+/* Concatenate NAMELEN bytes from NAME, "=", A, and B. Allocate the
+ result using malloc.
+
+ On ENOMEM, log a diagnostic message and exit with code 127. This function
+ should be used from child process only.
+*/
static char *
@@ -1703,5 +1745,7 @@ env_concat(char *name, size_t namelen, char *a, char *b)
if (a && b) {
- res = gray_malloc(namelen + 1 + strlen(a) + strlen(b) + 1);
+ res = malloc(namelen + 1 + strlen(a) + strlen(b) + 1);
+ if (res) {
strcpy(res + namelen + 1, a);
strcat(res, b);
+ }
} else if (a) {
@@ -1710,5 +1754,7 @@ env_concat(char *name, size_t namelen, char *a, char *b)
len--;
- res = gray_malloc(namelen + 1 + len + 1);
+ res = malloc(namelen + 1 + len + 1);
+ if (res) {
memcpy(res + namelen + 1, a, len);
res[namelen + 1 + len] = 0;
+ }
} else /* if (a == NULL) */ {
@@ -1717,7 +1763,13 @@ env_concat(char *name, size_t namelen, char *a, char *b)
len = strlen(b);
- res = gray_malloc(namelen + 1 + len + 1);
+ res = malloc(namelen + 1 + len + 1);
+ if (res)
strcpy(res + namelen + 1, b);
}
+ if (res) {
memcpy(res, name, namelen);
res[namelen] = '=';
+ } else {
+ errno_to_pam(errno);
+ _exit(127);
+ }
return res;
@@ -1742,2 +1794,10 @@ parsenv(char *str)
+# define ASSERT_NOTNULL(p) do { \
+ if (!(p)) { \
+ errno_to_pam(errno); \
+ _exit(127); \
+ } \
+ } while (0)
+
+
if (!str)
@@ -1793,7 +1853,4 @@ parsenv(char *str)
if (wi == wc) {
- if (wc == 0)
- wc = 4;
- else
- wc *= 2;
- wv = gray_realloc(wv, wc * sizeof(wv[0]));
+ wv = gray_2nrealloc(wv, &wc, sizeof(wv[0]));
+ ASSERT_NOTNULL(wv);
}
@@ -1803,3 +1860,4 @@ parsenv(char *str)
len -= 2;
- wv[wi] = gray_malloc(len + 1);
+ wv[wi] = malloc(len + 1);
+ ASSERT_NOTNULL(wv[wi]);
for (q = wv[wi]; *kw; ) {
@@ -1814,3 +1872,4 @@ parsenv(char *str)
len -= 2;
- wv[wi] = gray_malloc(len + 1);
+ wv[wi] = malloc(len + 1);
+ ASSERT_NOTNULL(wv[wi]);
q = wv[wi];
@@ -1829,3 +1888,4 @@ parsenv(char *str)
default:
- wv[wi] = gray_malloc(len + 1);
+ wv[wi] = malloc(len + 1);
+ ASSERT_NOTNULL(wv[wi]);
memcpy(wv[wi], kw, len);
@@ -1840,10 +1900,14 @@ parsenv(char *str)
if (wc == wi) {
- ++wc;
- wv = gray_realloc(wv, (wc + 1) * sizeof(wv[0]));
+ wv = gray_2nrealloc(wv, &wc, sizeof(wv[0]));
+ ASSERT_NOTNULL(wv);
}
- wv[wi++] = gray_strdup(kw);
+ wv[wi] = strdup(kw);
+ ASSERT_NOTNULL(wv[wi]);
+ ++wi;
}
- if (wc == wi)
- wv = gray_realloc(wv, (wc + 1) * sizeof(wv[0]));
+ if (wc == wi) {
+ wv = gray_2nrealloc(wv, &wc, sizeof(wv[0]));
+ ASSERT_NOTNULL(wv);
+ }
wv[wi] = NULL;
@@ -1853,2 +1917,5 @@ parsenv(char *str)
+/* Setup environment for exec* family call. On ENOMEM, exit with code 127.
+ This function should be called from a child process.
+*/
static char **
@@ -1881,4 +1948,7 @@ env_setup(char *envstr)
/* Allocate the new environment. */
- new_env = gray_calloc(count + 1, sizeof new_env[0]);
-
+ new_env = calloc(count + 1, sizeof new_env[0]);
+ if (!new_env) {
+ errno_to_pam(errno);
+ _exit(127);
+ }
/* Populate the environment. */
@@ -1940,5 +2010,12 @@ runas(struct passwd *pw)
if (strcmp (*p, pw->pw_name) == 0) {
- if (sgc == sgm)
- sgv = gray_2nrealloc(sgv, &sgm,
+ if (sgc == sgm) {
+ gid_t *p;
+ p = gray_2nrealloc(sgv, &sgm,
sizeof(sgv[0]));
+ if (!p) {
+ errno_to_pam(errno);
+ return 1; //FIXME: proper error code
+ }
+ sgv = p;
+ }
sgv[sgc++] = gr->gr_gid;
@@ -2145,3 +2222,2 @@ ldaphome_main(pam_handle_t *pamh, int flags, int argc, const char **argv,
DEBUG(90,("enter %s", func));
- gray_pam_init(PAM_AUTHINFO_UNAVAIL);
if (gray_env_read(config_file_name, &env) == 0) {
@@ -2150,3 +2226,3 @@ ldaphome_main(pam_handle_t *pamh, int flags, int argc, const char **argv,
- if (val = gray_env_get(env, "ldap-config")) {
+ if ((val = gray_env_get(env, "ldap-config"))) {
if (strcmp(val, "none") == 0)
@@ -2164,3 +2240,3 @@ ldaphome_main(pam_handle_t *pamh, int flags, int argc, const char **argv,
- if (val = gray_env_get(env, "authorized_keys"))
+ if ((val = gray_env_get(env, "authorized_keys")))
authorized_keys_file = val;

Return to:

Send suggestions and report system problems to the System administrator.