/* shadow.c - shadow entry lookup routines Parts of this file were part of the nss_ldap library (as ldap-spwd.c) which has been forked into the nss-pam-ldapd library. Copyright (C) 1997-2005 Luke Howard Copyright (C) 2006 West Consulting Copyright (C) 2006-2014 Arthur de Jong This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include "common.h" #include "log.h" struct shadow { /* for the integers: a value < 0 means empty */ char *name; /* the account name */ char *hash; /* a crypt(3) formatted password hash */ int32_t lastchange_date; /* days since Jan 1, 1970 */ int32_t min_days; /* minimum number of days between changes */ int32_t max_days; /* maximum number of days between changes */ int32_t warn_days; /* how long before max_days is up to warn the user */ int32_t inact_days; /* how long after max_days to accept the pw */ int32_t expire_date; /* days since Jarn 1, 1970 */ int32_t flag; /* unused on Linux/Glibc */ }; static void passwd2shadow(struct passwd *p, struct shadow *s) { s->name = p->pw_name; s->hash = p->pw_passwd; s->lastchange_date = -1; s->min_days = -1; s->max_days = -1; s->warn_days = -1; s->inact_days = -1; s->expire_date = -1; s->flag = -1; } static int write_shadow(TFILE *fp, struct shadow *entry) { WRITE_STRING(fp, entry->name); WRITE_STRING(fp, entry->hash ? entry->hash : "!"); WRITE_INT32( fp, entry->lastchange_date); WRITE_INT32( fp, entry->min_days); WRITE_INT32( fp, entry->max_days); WRITE_INT32( fp, entry->warn_days); WRITE_INT32( fp, entry->inact_days); WRITE_INT32( fp, entry->expire_date); WRITE_INT32( fp, entry->flag); return 0; } NSLCD_HANDLE_UID(SHADOW, BYNAME ,/* request data */ struct { char name[BUFLEN_NAME]; } ,/* search data */ struct { int cnt; struct shadow ret; } ,/* entry type */ struct shadow ,/* int read(TFILE *fp, *req) */ READ_STRING(fp, req->name); log_setrequest("shadow=\"%s\"", req->name); return 0; ,/* check */ if (!isvalidname(req->name)) { log_log(LOG_WARNING, "request denied by validnames option"); return -1; } return 0; ,/* search(*session, *req, *searchdat, *entry) */ *entry = NULL; if (calleruid != 0 || searchdat->cnt++ != 0) return 0; for (size_t i = 0; i < session->cnt; i++) { if (session->users[i].pw_uid != UID_INVALID && STR_CMP(req->name, session->users[i].pw_name)==0) { if (session->users[i].pw_uid < nslcd_cfg->nss_min_uid) return -1; passwd2shadow(&(session->users[i]), &(searchdat->ret)); *entry = &(searchdat->ret); break; } } return 0; ,/* int write(TFILE *fp, tentry *entry) */ return write_shadow(fp, entry); ,/* cleanup */ ) NSLCD_HANDLE_UID(SHADOW, ALL ,/* request data */ int ,/* search data */ struct { size_t i; struct shadow ret; } ,/* entry type */ struct shadow ,/* int read(TFILE *fp, *req) */ log_setrequest("shadow(all)"); return 0; ,/* check */ return 0; ,/* search(*session, *req, *searchdat, *entry) */ *entry = NULL; for (; searchdat->i < session->cnt; searchdat->i++) { if (session->users[searchdat->i].pw_uid != UID_INVALID && session->users[searchdat->i].pw_uid >= nslcd_cfg->nss_min_uid) { passwd2shadow(&(session->users[searchdat->i]), &(searchdat->ret)); *entry = &(searchdat->ret); searchdat->i++; break; } } return 0; ,/* write */ return write_shadow(fp, entry); ,/* cleanup */ )