diff options
Diffstat (limited to 'nslcd/db_shadow.c')
-rw-r--r-- | nslcd/db_shadow.c | 222 |
1 files changed, 58 insertions, 164 deletions
diff --git a/nslcd/db_shadow.c b/nslcd/db_shadow.c index 081738b..3764873 100644 --- a/nslcd/db_shadow.c +++ b/nslcd/db_shadow.c @@ -25,16 +25,8 @@ #include "config.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - #include "common.h" #include "log.h" -#include "myldap.h" -#include "cfg.h" -#include "attmap.h" struct shadow { /* for the integers: a value < 0 means empty */ @@ -49,127 +41,24 @@ struct shadow { int32_t flag; /* unused on Linux/Glibc */ }; -static long to_date(const char *dn, const char *date, const char *attr) -{ - char buffer[32]; - long value; - char *tmp; - size_t l; - /* do some special handling for date values on AD */ - if (strcasecmp(attr, "pwdLastSet") == 0) - { - /* we expect an AD 64-bit datetime value; - we should do date=date/864000000000-134774 - but that causes problems on 32-bit platforms, - first we devide by 1000000000 by stripping the - last 9 digits from the string and going from there */ - l = strlen(date) - 9; - if (l > (sizeof(buffer) - 1)) - return -1; /* error */ - strncpy(buffer, date, l); - buffer[l] = '\0'; - errno = 0; - value = strtol(buffer, &tmp, 10); - if ((*date == '\0') || (*tmp != '\0')) - { - log_log(LOG_WARNING, "%s: %s: non-numeric", dn, attr); - return -1; - } - else if (errno != 0) - { - log_log(LOG_WARNING, "%s: %s: out of range", dn, attr); - return -1; - } - return value / 864 - 134774; - /* note that AD does not have expiry dates but a lastchangeddate - and some value that needs to be added */ - } - errno = 0; - value = strtol(date, &tmp, 10); - if ((*date == '\0') || (*tmp != '\0')) - { - log_log(LOG_WARNING, "%s: %s: non-numeric", dn, attr); - return -1; - } - else if (errno != 0) - { - log_log(LOG_WARNING, "%s: %s: out of range", dn, attr); - return -1; - } - return value; -} - -#ifndef UF_DONT_EXPIRE_PASSWD -#define UF_DONT_EXPIRE_PASSWD 0x10000 -#endif - -#define GET_OPTIONAL_LONG(var, att, fallback) \ - tmpvalue = attmap_get_value(entry, attmap_shadow_##att, \ - buffer, sizeof(buffer)); \ - if (tmpvalue == NULL) \ - tmpvalue = ""; \ - errno = 0; \ - var = strtol(tmpvalue, &tmp, 10); \ - if ((*(tmpvalue) == '\0') || (*tmp != '\0')) \ - { \ - log_log(LOG_WARNING, "%s: %s: non-numeric", \ - myldap_get_dn(entry), attmap_shadow_##att); \ - var = fallback; \ - } \ - else if (errno != 0) \ - { \ - log_log(LOG_WARNING, "%s: %s: out of range", \ - myldap_get_dn(entry), attmap_shadow_##att); \ - var = fallback; \ - } - -void get_shadow_properties(MYLDAP_ENTRY *entry, long *lastchangedate, - long *mindays, long *maxdays, long *warndays, - long *inactdays, long *expiredate, - unsigned long *flag) +static void passwd2shadow(struct passwd *p, struct shadow *s) { - char buffer[64]; - const char *tmpvalue; - char *tmp; - /* get lastchange date */ - tmpvalue = attmap_get_value(entry, attmap_shadow_shadowLastChange, - buffer, sizeof(buffer)); - if (tmpvalue == NULL) - tmpvalue = ""; - *lastchangedate = to_date(myldap_get_dn(entry), tmpvalue, attmap_shadow_shadowLastChange); - /* get other shadow properties */ - GET_OPTIONAL_LONG(*mindays, shadowMin, -1); - GET_OPTIONAL_LONG(*maxdays, shadowMax, -1); - GET_OPTIONAL_LONG(*warndays, shadowWarning, -1); - GET_OPTIONAL_LONG(*inactdays, shadowInactive, -1); - GET_OPTIONAL_LONG(*expiredate, shadowExpire, -1); - GET_OPTIONAL_LONG(*flag, shadowFlag, 0); - /* if we're using AD handle the flag specially */ - if (strcasecmp(attmap_shadow_shadowLastChange, "pwdLastSet") == 0) - { - if (*flag & UF_DONT_EXPIRE_PASSWD) - *maxdays = -1; - *flag = 0; - } -} + 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, uid_t calleruid) { int32_t tmpint32; - struct shadow _entry = { - .name = pentry->pw_name; - .hash = pentry->pw_passwd; - .lastchange_date = -1; - .min_days = -1; - .max_days = -1; - .warn_days = -1; - .inact_days = -1; - .expire_date = -1; - .flag = -1; - }; - struct shadow *entry = &_entry; - if (caller_uid == 0) + if (calleruid == 0) { WRITE_INT32(fp, NSLCD_RESULT_BEGIN); WRITE_STRING(fp, entry->name); @@ -185,55 +74,60 @@ static int write_shadow(TFILE *fp, struct shadow *entry, uid_t calleruid) return 0; } -MYLDAP_ENTRY *shadow_uid2entry(MYLDAP_SESSION *session, const char *username, - int *rcp) -{ - MYLDAP_SEARCH *search = NULL; - MYLDAP_ENTRY *entry = NULL; - const char *base; - char filter[BUFLEN_FILTER]; - int i; - /* if it isn't a valid username, just bail out now */ - if (!isvalidname(username)) +NSLCD_HANDLE_UID( + shadow, byname, NSLCD_ACTION_SHADOW_BYNAME + ,/* decls */ + char name[BUFLEN_NAME]; + struct shadow ret; + ,/* read */ + READ_STRING(fp, name); + log_setrequest("shadow=\"%s\"", name); + ,/* check */ + if (!isvalidname(name)) { - if (rcp != NULL) - *rcp = LDAP_INVALID_SYNTAX; - return NULL; + log_log(LOG_WARNING, "request denied by validnames option"); + return -1; } - /* we have to look up the entry */ - mkfilter_shadow_byname(username, filter, sizeof(filter)); - for (i = 0; (i < NSS_LDAP_CONFIG_MAX_BASES) && ((base = shadow_bases[i]) != NULL); i++) + ,/* search */ + struct shadow, + static size_t i = 0; + for (; i < session->cnt; i++) { - search = myldap_search(session, base, shadow_scope, filter, shadow_attrs, rcp); - if (search == NULL) + if (session->users[i].pw_uid > 0 && + STR_CMP(name, session->users[i].pw_name)==0) { - if ((rcp != NULL) && (*rcp == LDAP_SUCCESS)) - *rcp = LDAP_NO_SUCH_OBJECT; - return NULL; + *rcp = 0; + i = session->cnt; + passwd2shadow(&(session->users[i]), &ret); + return &ret; } - entry = myldap_get_entry(search, rcp); - if (entry != NULL) - return entry; } - if ((rcp != NULL) && (*rcp == LDAP_SUCCESS)) - *rcp = LDAP_NO_SUCH_OBJECT; return NULL; -} - -NSLCD_HANDLE_UID( - shadow, byname, NSLCD_ACTION_SHADOW_BYNAME, - char name[BUFLEN_NAME]; - char filter[BUFLEN_FILTER]; - READ_STRING(fp, name); - log_setrequest("shadow=\"%s\"", name);, - mkfilter_shadow_byname(name, filter, sizeof(filter)), - write_shadow(fp, entry, name, calleruid) + ,/* write */ + write_shadow(fp, entry, calleruid); + ,/* cleanup */ ) NSLCD_HANDLE_UID( - shadow, all, NSLCD_ACTION_SHADOW_ALL, - const char *filter; - log_setrequest("shadow(all)");, - (filter = shadow_filter, 0), - write_shadow(fp, entry, NULL, calleruid) + shadow, all, NSLCD_ACTION_SHADOW_ALL + ,/* decls */ + struct shadow ret; + ,/* read */ + log_setrequest("shadow(all)"); + ,/* check */ + ,/* search */ + struct shadow, + static size_t i = 0; + for (; i < session->cnt; i++) + { + if (session->users[i].pw_uid > 0) { + *rcp = 0; + passwd2shadow(&(session->users[i]), &ret); + return &ret; + } + } + return NULL; + ,/* write */ + write_shadow(fp, entry, calleruid); + ,/* cleanup */ ) |