aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2012-08-01 21:07:27 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2012-08-01 21:14:22 +0300
commitd211d9ec0cf708b047a0fb0d4019a16a806bbf4c (patch)
treeecffe1e8c9939e794ca7fbfc066e28c0e2aff2aa
parentf6cde78d9891ad9b07daf6f1b8a822a2a26a250c (diff)
downloadpam-modules-d211d9ec0cf708b047a0fb0d4019a16a806bbf4c.tar.gz
pam-modules-d211d9ec0cf708b047a0fb0d4019a16a806bbf4c.tar.bz2
Improve pam_ldaphome
New keywords: bindpwfile and keyfile-mode. * doc/pam-modules.texi: Document bindpwfile and keyfile-mode. * pam_ldaphome/pam_ldaphome.c (ldap_bind): Read password from file, if bindpwfile is given. (store_pubkeys): Optionally enforce file mode, given by the keyfile-mode configuration statement. * pamck/pamck.c (main): Fix a typo.
-rw-r--r--doc/pam-modules.texi8
-rw-r--r--pam_ldaphome/pam_ldaphome.c124
-rw-r--r--pamck/pamck.c2
3 files changed, 116 insertions, 18 deletions
diff --git a/doc/pam-modules.texi b/doc/pam-modules.texi
index d263d57..e7b460f 100644
--- a/doc/pam-modules.texi
+++ b/doc/pam-modules.texi
@@ -1213,6 +1213,10 @@ If @code{binddn} statement is used, this statement supplies the
1213password for simple authentication. 1213password for simple authentication.
1214@end deffn 1214@end deffn
1215 1215
1216@deffn {pam_ldaphome config} bindpwfile file
1217Read password for simple authentication from @var{file}.
1218@end deffn
1219
1216@deffn {pam_ldaphome config} tls val 1220@deffn {pam_ldaphome config} tls val
1217Controls whether TLS is desired or required. If @var{val} is 1221Controls whether TLS is desired or required. If @var{val} is
1218@samp{no} (the default), TLS will not be used. If it is @samp{yes}, 1222@samp{no} (the default), TLS will not be used. If it is @samp{yes},
@@ -1259,6 +1263,10 @@ directory to the newly created home. The default size is 16384 bytes.
1259Sets the mode (octal) for the created user directories. 1263Sets the mode (octal) for the created user directories.
1260@end deffn 1264@end deffn
1261 1265
1266@deffn {pam_ldaphome config} keyfile-mode mode
1267Sets the mode (octal) for the created authorized keys file.
1268@end deffn
1269
1262@deffn {pam_ldaphome config} authorized_keys name 1270@deffn {pam_ldaphome config} authorized_keys name
1263Sets the pathname (relative to the home directory) for the authorized 1271Sets the pathname (relative to the home directory) for the authorized
1264keys file. The default is @samp{.ssh/authorized_keys}. For normal 1272keys file. The default is @samp{.ssh/authorized_keys}. For normal
diff --git a/pam_ldaphome/pam_ldaphome.c b/pam_ldaphome/pam_ldaphome.c
index 9e5b440..83c10c1 100644
--- a/pam_ldaphome/pam_ldaphome.c
+++ b/pam_ldaphome/pam_ldaphome.c
@@ -202,7 +202,7 @@ parse_ldap_uri(const char *uri)
202 char *domain = NULL, *hostlist = NULL; 202 char *domain = NULL, *hostlist = NULL;
203 size_t i; 203 size_t i;
204 204
205 if (ldap_dn2domain (lud->lud_dn, &domain) || 205 if (ldap_dn2domain(lud->lud_dn, &domain) ||
206 !domain) { 206 !domain) {
207 _pam_log(LOG_ERR, 207 _pam_log(LOG_ERR,
208 "DNS SRV: cannot convert " 208 "DNS SRV: cannot convert "
@@ -288,14 +288,14 @@ parse_ldap_uri(const char *uri)
288 } 288 }
289 289
290 if (ludlist) { 290 if (ludlist) {
291 ldap_free_urldesc (ludlist); 291 ldap_free_urldesc(ludlist);
292 return NULL; 292 return NULL;
293 } else if (!urls) 293 } else if (!urls)
294 return NULL; 294 return NULL;
295 ldapuri = argcv_concat(nurls, urls); 295 ldapuri = argcv_concat(nurls, urls);
296 if (!ldapuri) 296 if (!ldapuri)
297 _pam_log(LOG_ERR, "%s", strerror(errno)); 297 _pam_log(LOG_ERR, "%s", strerror(errno));
298 ber_memvfree ((void **)urls); 298 ber_memvfree((void **)urls);
299 return ldapuri; 299 return ldapuri;
300} 300}
301 301
@@ -312,14 +312,14 @@ ldap_connect(struct gray_env *env)
312 unsigned long lval; 312 unsigned long lval;
313 313
314 if (ldap_debug_level) { 314 if (ldap_debug_level) {
315 if (ber_set_option (NULL, LBER_OPT_DEBUG_LEVEL, 315 if (ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL,
316 &ldap_debug_level) 316 &ldap_debug_level)
317 != LBER_OPT_SUCCESS ) 317 != LBER_OPT_SUCCESS )
318 _pam_log(LOG_ERR, 318 _pam_log(LOG_ERR,
319 "cannot set LBER_OPT_DEBUG_LEVEL %d", 319 "cannot set LBER_OPT_DEBUG_LEVEL %d",
320 ldap_debug_level); 320 ldap_debug_level);
321 321
322 if (ldap_set_option (NULL, LDAP_OPT_DEBUG_LEVEL, 322 if (ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL,
323 &ldap_debug_level) 323 &ldap_debug_level)
324 != LDAP_OPT_SUCCESS ) 324 != LDAP_OPT_SUCCESS )
325 _pam_log(LOG_ERR, 325 _pam_log(LOG_ERR,
@@ -411,7 +411,77 @@ ldap_connect(struct gray_env *env)
411} 411}
412 412
413static int 413static int
414ldap_bind (LDAP *ld, struct gray_env *env) 414full_read(int fd, char *file, char *buf, size_t size)
415{
416 while (size) {
417 ssize_t n;
418
419 n = read(fd, buf, size);
420 if (n == -1) {
421 if (errno == EAGAIN || errno == EINTR)
422 continue;
423 _pam_log(LOG_ERR, "error reading from %s: %s",
424 file, strerror(errno));
425 return -1;
426 } else if (n == 0) {
427 _pam_log(LOG_ERR, "short read from %s", file);
428 return -1;
429 }
430
431 buf += n;
432 size -= n;
433 }
434 return 0;
435}
436
437static int
438get_passwd(struct gray_env *env, struct berval *pwd, char **palloc)
439{
440 char *file;
441
442 file = gray_env_get(env, "bindpwfile");
443 if (file) {
444 struct stat st;
445 int fd, rc;
446 char *mem, *p;
447
448 fd = open(file, O_RDONLY);
449 if (fd == -1) {
450 _pam_log(LOG_ERR, "can't open password file %s: %s",
451 file, strerror(errno));
452 return -1;
453 }
454 if (fstat(fd, &st)) {
455 _pam_log(LOG_ERR, "can't stat password file %s: %s",
456 file, strerror(errno));
457 close(fd);
458 return -1;
459 }
460 mem = malloc(st.st_size + 1);
461 if (!mem) {
462 _pam_log(LOG_ERR, "can't allocate memory (%lu bytes)",
463 (unsigned long) st.st_size+1);
464 close(fd);
465 return -1;
466 }
467 rc = full_read(fd, file, mem, st.st_size);
468 close(fd);
469 if (rc)
470 return rc;
471 mem[st.st_size] = 0;
472 p = strchr(mem, '\n');
473 if (p)
474 *p = 0;
475 *palloc = mem;
476 pwd->bv_val = mem;
477 } else
478 pwd->bv_val = gray_env_get(env, "bindpw");
479 pwd->bv_len = pwd->bv_val ? strlen(pwd->bv_val) : 0;
480 return 0;
481}
482
483static int
484ldap_bind(LDAP *ld, struct gray_env *env)
415{ 485{
416 int msgid, err, rc; 486 int msgid, err, rc;
417 LDAPMessage *result; 487 LDAPMessage *result;
@@ -420,12 +490,14 @@ ldap_bind (LDAP *ld, struct gray_env *env)
420 char *matched = NULL; 490 char *matched = NULL;
421 char *info = NULL; 491 char *info = NULL;
422 char **refs = NULL; 492 char **refs = NULL;
423 static struct berval passwd; 493 struct berval passwd;
424 char *binddn; 494 char *binddn;
495 char *alloc_ptr = NULL;
425 496
426 binddn = gray_env_get(env, "binddn"); 497 binddn = gray_env_get(env, "binddn");
427 passwd.bv_val = gray_env_get(env, "bindpw"); 498
428 passwd.bv_len = passwd.bv_val ? strlen(passwd.bv_val) : 0; 499 if (get_passwd(env, &passwd, &alloc_ptr))
500 return 1;
429 501
430 msgbuf[0] = 0; 502 msgbuf[0] = 0;
431 503
@@ -435,11 +507,13 @@ ldap_bind (LDAP *ld, struct gray_env *env)
435 _pam_log(LOG_ERR, 507 _pam_log(LOG_ERR,
436 "ldap_sasl_bind(SIMPLE) failed: %s", 508 "ldap_sasl_bind(SIMPLE) failed: %s",
437 ldap_err2string(rc)); 509 ldap_err2string(rc));
510 free(alloc_ptr);
438 return 1; 511 return 1;
439 } 512 }
440 513
441 if (ldap_result(ld, msgid, LDAP_MSG_ALL, NULL, &result ) == -1) { 514 if (ldap_result(ld, msgid, LDAP_MSG_ALL, NULL, &result ) == -1) {
442 _pam_log(LOG_ERR, "ldap_result failed"); 515 _pam_log(LOG_ERR, "ldap_result failed");
516 free(alloc_ptr);
443 return 1; 517 return 1;
444 } 518 }
445 519
@@ -447,7 +521,8 @@ ldap_bind (LDAP *ld, struct gray_env *env)
447 &ctrls, 1); 521 &ctrls, 1);
448 if (rc != LDAP_SUCCESS) { 522 if (rc != LDAP_SUCCESS) {
449 _pam_log(LOG_ERR, "ldap_parse_result failed: %s", 523 _pam_log(LOG_ERR, "ldap_parse_result failed: %s",
450 ldap_err2string (rc));