/* * reset the failed count. * returns the number of failed logins before the reset, or an error (< 0) */ int __rst_failed_count(char *username, char *repname) { int ret; void *buf; attrlist items[1]; int repnum = name_to_int(repname); repops_t *ops; /* account locking only defined for files and ldap */ if ((repnum != REP_FILES) && (repnum != REP_LDAP)) { return (PWU_SUCCESS); } ops = rops[repnum]; if ((ops->lock != NULL) && (ret = ops->lock()) != PWU_SUCCESS) { return (ret); } items[0].type = ATTR_RST_FAILED_LOGINS; items[0].next = NULL; if ((ret = ops->getpwnam(username, items, NULL, &buf)) != PWU_SUCCESS) goto out; if ((ret = ops->update(items, NULL, buf)) != PWU_SUCCESS) goto out; ret = ops->putpwnam(username, NULL, NULL, buf); out: if (ops->unlock != NULL) { ops->unlock(); } return (ret != PWU_SUCCESS ? ret : items[0].data.val_i); }
int __incr_failed_count(char *username, char *repname, int max_failures) { int ret; void *buf; attrlist items[1]; int repnum = name_to_int(repname); repops_t *ops; /* account locking only defined for files and ldap */ if ((repnum != REP_FILES) && (repnum != REP_LDAP)) { return (PWU_SUCCESS); } ops = rops[repnum]; if ((ops->lock != NULL) && (ret = ops->lock()) != PWU_SUCCESS) { return (ret); } items[0].type = ATTR_INCR_FAILED_LOGINS; items[0].next = NULL; if ((ret = ops->getpwnam(username, items, NULL, &buf)) != PWU_SUCCESS) { goto out; } /* We increment the failed count by one */ if ((ret = ops->update(items, NULL, buf)) != PWU_SUCCESS) { goto out; } /* Did we just exceed "max_failures" ? */ if (items[0].data.val_i >= max_failures) { syslog(LOG_AUTH|LOG_NOTICE, "Excessive (%d) login failures for %s: locking account.", max_failures, username); items[0].type = ATTR_LOCK_ACCOUNT; if ((ret = ops->update(items, NULL, buf)) != PWU_SUCCESS) goto out; } if (((ret = ops->putpwnam(username, NULL, NULL, buf)) == PWU_SUCCESS) && (items[0].type == ATTR_LOCK_ACCOUNT)) ret = PWU_ACCOUNT_LOCKED; out: if (ops->unlock != NULL) { ops->unlock(); } return (ret); }
static struct dentry *proc_lookupfd_common(struct inode *dir, struct dentry *dentry, instantiate_t instantiate) { struct task_struct *task = get_proc_task(dir); struct dentry *result = ERR_PTR(-ENOENT); unsigned fd = name_to_int(dentry); if (!task) goto out_no_task; if (fd == ~0U) goto out; result = instantiate(dir, dentry, task, (void *)(unsigned long)fd); out: put_task_struct(task); out_no_task: return result; }
constexpr unsigned name_to_int(const char *str, int off = 0) { return !str[off] ? 5381 : (name_to_int(str, off + 1) * 33) ^ static_cast<unsigned>(str[off]); }
/* * get_ns(rep, accesstype) * * returns a bitmask of repositories to use based on either * 1. the repository that is given as argument * 2. the nsswitch.conf file * 3. the type of access requested * * "accesstype" indicates whether we are reading from or writing to the * repository. We need to know this since "compat" will translate into * REP_NSS (the nss-switch) for READ access (needed to decode * the black-magic '+' entries) but it translates into a bitmask * on WRITE access. * * If we detect read-access in compat mode, we augment the result * with one of REP_COMPAT_{NIS,LDAP}. We need this in order to * implement ATTR_REP_NAME in nss_getpwnam. * * A return value of REP_NOREP indicates an error. */ int get_ns(pwu_repository_t *rep, int accesstype) { struct __nsw_switchconfig *conf = NULL; enum __nsw_parse_err pserr; struct __nsw_lookup *lkp; struct __nsw_lookup *lkp2; struct __nsw_lookup *lkp3; struct __nsw_lookup *lkpn; int result = REP_NOREP; if (rep != PWU_DEFAULT_REP) { result = name_to_int(rep->type); return (result); } conf = __nsw_getconfig("passwd", &pserr); if (conf == NULL) { /* * No config found. The user didn't supply a repository, * so we try to change the password in the default * repositories (files and nis) even though we cannot * find the name service switch entry. (Backward compat) */ syslog(LOG_ERR, "passwdutil.so: nameservice switch entry for " "passwd not found."); result = REP_FILES | REP_NIS; return (result); } lkp = conf->lookups; /* * Supported nsswitch.conf can have a maximum of 3 repositories. * If we encounter an unsupported nsswitch.conf, we return REP_NSS * to fall back to the nsswitch backend. * * Note that specifying 'ad' in the configuration is acceptable * though changing AD users' passwords through passwd(1) is not. * Therefore "ad" will be silently ignored. */ if (conf->num_lookups == 1) { /* files or compat */ if (strcmp(lkp->service_name, "files") == 0) { result = name_to_int(lkp->service_name); } else if (strcmp(lkp->service_name, "compat") == 0) { if (accesstype == PWU_READ) result = REP_NSS | get_compat_mode(); else result = name_to_int(lkp->service_name); } else result = REP_NSS; } else if (conf->num_lookups == 2) { lkp2 = lkp->next; if (strcmp(lkp->service_name, "files") == 0) { result = REP_FILES; if (strcmp(lkp2->service_name, "ldap") == 0) result |= REP_LDAP; else if (strcmp(lkp2->service_name, "nis") == 0) result |= REP_NIS; else if (strcmp(lkp2->service_name, "ad") != 0) result = REP_NSS; /* AD is ignored */ } else { result = REP_NSS; } } else if (conf->num_lookups == 3) { /* * Valid configurations with 3 repositories are: * files ad [nis | ldap ] OR * files [nis | ldap ] ad */ lkp2 = lkp->next; lkp3 = lkp2->next; if (strcmp(lkp2->service_name, "ad") == 0) lkpn = lkp3; else if (strcmp(lkp3->service_name, "ad") == 0) lkpn = lkp2; else lkpn = NULL; if (strcmp(lkp->service_name, "files") == 0 && lkpn != NULL) { result = REP_FILES; if (strcmp(lkpn->service_name, "ldap") == 0) result |= REP_LDAP; else if (strcmp(lkpn->service_name, "nis") == 0) result |= REP_NIS; else result = REP_NSS; } else { result = REP_NSS; } } else { result = REP_NSS; } (void) __nsw_freeconfig(conf); return (result); }