static void do_successful_login(struct LOCAL_request *lreq) { int ret; lreq->mod_attrs = sysdb_new_attrs(lreq); NULL_CHECK_OR_JUMP(lreq->mod_attrs, ("sysdb_new_attrs failed.\n"), lreq->error, ENOMEM, done); ret = sysdb_attrs_add_long(lreq->mod_attrs, SYSDB_LAST_LOGIN, (long)time(NULL)); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_attrs_add_long failed.\n"), lreq->error, ret, done); ret = sysdb_attrs_add_long(lreq->mod_attrs, SYSDB_FAILED_LOGIN_ATTEMPTS, 0L); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_attrs_add_long failed.\n"), lreq->error, ret, done); ret = sysdb_set_user_attr(lreq->dbctx, lreq->domain, lreq->preq->pd->user, lreq->mod_attrs, SYSDB_MOD_REP); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_set_user_attr failed.\n"), lreq->error, ret, done); done: return; }
static errno_t invalidate_entry(TALLOC_CTX *ctx, struct sss_domain_info *domain, const char *name, int entry_type) { struct sysdb_attrs *sys_attrs = NULL; errno_t ret; sys_attrs = sysdb_new_attrs(ctx); if (sys_attrs) { ret = sysdb_attrs_add_time_t(sys_attrs, SYSDB_CACHE_EXPIRE, 1); if (ret == EOK) { switch (entry_type) { case TYPE_USER: /* For users, we also need to reset the initgroups * cache expiry */ ret = sysdb_attrs_add_time_t(sys_attrs, SYSDB_INITGR_EXPIRE, 1); if (ret != EOK) return ret; ret = sysdb_set_user_attr(domain, name, sys_attrs, SYSDB_MOD_REP); break; case TYPE_GROUP: ret = sysdb_set_group_attr(domain, name, sys_attrs, SYSDB_MOD_REP); break; case TYPE_NETGROUP: ret = sysdb_set_netgroup_attr(domain, name, sys_attrs, SYSDB_MOD_REP); break; case TYPE_SERVICE: ret = sysdb_set_service_attr(domain, name, sys_attrs, SYSDB_MOD_REP); break; case TYPE_AUTOFSMAP: ret = sysdb_set_autofsmap_attr(domain, name, sys_attrs, SYSDB_MOD_REP); break; default: return EINVAL; } if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not set entry attributes\n"); } } else { DEBUG(SSSDBG_MINOR_FAILURE, "Could not add expiration time to attributes\n"); } talloc_zfree(sys_attrs); } else { DEBUG(SSSDBG_MINOR_FAILURE, "Could not create sysdb attributes\n"); ret = ENOMEM; } return ret; }
static void do_pam_chauthtok(struct LOCAL_request *lreq) { int ret; char *newauthtok; char *salt; char *new_hash; struct pam_data *pd; pd = lreq->preq->pd; newauthtok = talloc_strndup(lreq, (char *) pd->newauthtok, pd->newauthtok_size); NULL_CHECK_OR_JUMP(newauthtok, ("talloc_strndup failed.\n"), lreq->error, ENOMEM, done); memset(pd->newauthtok, 0, pd->newauthtok_size); if (strlen(newauthtok) == 0) { /* TODO: should we allow null passwords via a config option ? */ DEBUG(1, ("Empty passwords are not allowed!\n")); lreq->error = EINVAL; goto done; } ret = s3crypt_gen_salt(lreq, &salt); NEQ_CHECK_OR_JUMP(ret, EOK, ("Salt generation failed.\n"), lreq->error, ret, done); DEBUG(4, ("Using salt [%s]\n", salt)); ret = s3crypt_sha512(lreq, newauthtok, salt, &new_hash); NEQ_CHECK_OR_JUMP(ret, EOK, ("Hash generation failed.\n"), lreq->error, ret, done); DEBUG(4, ("New hash [%s]\n", new_hash)); memset(newauthtok, 0, pd->newauthtok_size); lreq->mod_attrs = sysdb_new_attrs(lreq); NULL_CHECK_OR_JUMP(lreq->mod_attrs, ("sysdb_new_attrs failed.\n"), lreq->error, ENOMEM, done); ret = sysdb_attrs_add_string(lreq->mod_attrs, SYSDB_PWD, new_hash); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_attrs_add_string failed.\n"), lreq->error, ret, done); ret = sysdb_attrs_add_long(lreq->mod_attrs, "lastPasswordChange", (long)time(NULL)); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_attrs_add_long failed.\n"), lreq->error, ret, done); ret = sysdb_set_user_attr(lreq->dbctx, lreq->preq->pd->user, lreq->mod_attrs, SYSDB_MOD_REP); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_set_user_attr failed.\n"), lreq->error, ret, done); done: return; }
/* * Public interface for modifying users */ int usermod(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct ops_ctx *data) { struct sysdb_attrs *attrs = NULL; struct ldb_dn *member_dn = NULL; int ret; if (data->addgroups || data->rmgroups) { member_dn = sysdb_user_dn(sysdb, mem_ctx, data->domain->name, data->name); if (!member_dn) { return ENOMEM; } } ret = usermod_build_attrs(mem_ctx, data->gecos, data->home, data->shell, data->uid, data->gid, data->lock, &attrs); if (ret != EOK) { return ret; } if (attrs->num != 0) { ret = sysdb_set_user_attr(sysdb, data->name, attrs, SYSDB_MOD_REP); if (ret) { return ret; } } if (data->rmgroups != NULL) { ret = remove_from_groups(mem_ctx, sysdb, data, member_dn); if (ret) { return ret; } } if (data->addgroups != NULL) { ret = add_to_groups(mem_ctx, sysdb, data, member_dn); if (ret) { return ret; } } flush_nscd_cache(mem_ctx, NSCD_DB_PASSWD); flush_nscd_cache(mem_ctx, NSCD_DB_GROUP); return EOK; }
static void do_pam_chauthtok(struct LOCAL_request *lreq) { int ret; const char *password; char *salt; char *new_hash; struct pam_data *pd; pd = lreq->preq->pd; ret = sss_authtok_get_password(pd->newauthtok, &password, NULL); if (ret) { /* TODO: should we allow null passwords via a config option ? */ if (ret == ENOENT) { DEBUG(1, ("Empty passwords are not allowed!\n")); } lreq->error = EINVAL; goto done; } ret = s3crypt_gen_salt(lreq, &salt); NEQ_CHECK_OR_JUMP(ret, EOK, ("Salt generation failed.\n"), lreq->error, ret, done); DEBUG(4, ("Using salt [%s]\n", salt)); ret = s3crypt_sha512(lreq, password, salt, &new_hash); NEQ_CHECK_OR_JUMP(ret, EOK, ("Hash generation failed.\n"), lreq->error, ret, done); DEBUG(4, ("New hash [%s]\n", new_hash)); lreq->mod_attrs = sysdb_new_attrs(lreq); NULL_CHECK_OR_JUMP(lreq->mod_attrs, ("sysdb_new_attrs failed.\n"), lreq->error, ENOMEM, done); ret = sysdb_attrs_add_string(lreq->mod_attrs, SYSDB_PWD, new_hash); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_attrs_add_string failed.\n"), lreq->error, ret, done); ret = sysdb_attrs_add_long(lreq->mod_attrs, "lastPasswordChange", (long)time(NULL)); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_attrs_add_long failed.\n"), lreq->error, ret, done); ret = sysdb_set_user_attr(lreq->dbctx, lreq->domain, lreq->preq->pd->user, lreq->mod_attrs, SYSDB_MOD_REP); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_set_user_attr failed.\n"), lreq->error, ret, done); done: sss_authtok_set_empty(pd->newauthtok); }
static int attr_op(struct ops_ctx *octx, const char *nameval, int op) { TALLOC_CTX *tmp_ctx; errno_t ret; struct sysdb_attrs *attrs; char *name; char **vals; int nvals; int i; switch(op) { case SYSDB_MOD_ADD: case SYSDB_MOD_DEL: case SYSDB_MOD_REP: break; default: return EINVAL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) return ENOMEM; attrs = sysdb_new_attrs(tmp_ctx); if (attrs == NULL) { ret = ENOMEM; goto done; } ret = attr_name_val_split(tmp_ctx, nameval, &name, &vals, &nvals); if (ret != EOK) { goto done; } for (i=0; i < nvals; i++) { ret = sysdb_attrs_add_string(attrs, name, vals[i]); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not add %s to %s\n", vals[i], name); continue; } } ret = sysdb_set_user_attr(octx->domain, octx->name, attrs, op); done: talloc_free(tmp_ctx); return ret; }
static void do_failed_login(struct LOCAL_request *lreq) { int ret; int failedLoginAttempts; struct pam_data *pd; pd = lreq->preq->pd; pd->pam_status = PAM_AUTH_ERR; /* TODO: maybe add more inteligent delay calculation */ pd->response_delay = 3; lreq->mod_attrs = sysdb_new_attrs(lreq); NULL_CHECK_OR_JUMP(lreq->mod_attrs, ("sysdb_new_attrs failed.\n"), lreq->error, ENOMEM, done); ret = sysdb_attrs_add_long(lreq->mod_attrs, SYSDB_LAST_FAILED_LOGIN, (long)time(NULL)); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_attrs_add_long failed.\n"), lreq->error, ret, done); failedLoginAttempts = ldb_msg_find_attr_as_int(lreq->res->msgs[0], SYSDB_FAILED_LOGIN_ATTEMPTS, 0); failedLoginAttempts++; ret = sysdb_attrs_add_long(lreq->mod_attrs, SYSDB_FAILED_LOGIN_ATTEMPTS, (long)failedLoginAttempts); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_attrs_add_long failed.\n"), lreq->error, ret, done); ret = sysdb_set_user_attr(lreq->dbctx, lreq->domain, lreq->preq->pd->user, lreq->mod_attrs, SYSDB_MOD_REP); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_set_user_attr failed.\n"), lreq->error, ret, done); done: return; }
static errno_t set_last_login(struct pam_auth_req *preq) { struct sysdb_attrs *attrs; errno_t ret; attrs = sysdb_new_attrs(preq); if (!attrs) { ret = ENOMEM; goto fail; } ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_ONLINE_AUTH, time(NULL)); if (ret != EOK) { goto fail; } ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_LOGIN, time(NULL)); if (ret != EOK) { goto fail; } ret = sysdb_set_user_attr(preq->domain, preq->pd->user, attrs, SYSDB_MOD_REP); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "set_last_login failed.\n"); preq->pd->pam_status = PAM_SYSTEM_ERR; goto fail; } else { preq->pd->last_auth_saved = true; } preq->callback(preq); return EOK; fail: return ret; }
static int krb5_mod_ccname(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, const char *name, const char *ccname, int mod_op) { TALLOC_CTX *tmpctx; struct sysdb_attrs *attrs; int ret; errno_t sret; bool in_transaction = false; if (name == NULL || ccname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing user or ccache name.\n"); return EINVAL; } if (mod_op != SYSDB_MOD_REP && mod_op != SYSDB_MOD_DEL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported operation [%d].\n", mod_op); return EINVAL; } DEBUG(SSSDBG_TRACE_ALL, "%s ccname [%s] for user [%s].\n", mod_op == SYSDB_MOD_REP ? "Save" : "Delete", ccname, name); tmpctx = talloc_new(mem_ctx); if (!tmpctx) { return ENOMEM; } attrs = sysdb_new_attrs(tmpctx); if (!attrs) { ret = ENOMEM; goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_CCACHE_FILE, ccname); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_add_string failed.\n"); goto done; } ret = sysdb_transaction_start(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error %d starting transaction (%s)\n", ret, strerror(ret)); goto done; } in_transaction = true; ret = sysdb_set_user_attr(domain, name, attrs, mod_op); if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); goto done; } ret = sysdb_transaction_commit(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction!\n"); goto done; } in_transaction = false; done: if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } talloc_zfree(tmpctx); return ret; }
static int krb5_mod_ccname(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, const char *name, const char *ccname, int mod_op) { TALLOC_CTX *tmpctx; struct sysdb_attrs *attrs; int ret; if (name == NULL || ccname == NULL) { DEBUG(1, ("Missing user or ccache name.\n")); return EINVAL; } if (mod_op != SYSDB_MOD_REP && mod_op != SYSDB_MOD_DEL) { DEBUG(1, ("Unsupported operation [%d].\n", mod_op)); return EINVAL; } DEBUG(9, ("%s ccname [%s] for user [%s].\n", mod_op == SYSDB_MOD_REP ? "Save" : "Delete", ccname, name)); tmpctx = talloc_new(mem_ctx); if (!tmpctx) { return ENOMEM; } attrs = sysdb_new_attrs(mem_ctx); if (!attrs) { ret = ENOMEM; goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_CCACHE_FILE, ccname); if (ret != EOK) { DEBUG(1, ("sysdb_attrs_add_string failed.\n")); goto done; } ret = sysdb_transaction_start(sysdb); if (ret != EOK) { DEBUG(6, ("Error %d starting transaction (%s)\n", ret, strerror(ret))); goto done; } ret = sysdb_set_user_attr(sysdb, name, attrs, mod_op); if (ret != EOK) { DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret))); sysdb_transaction_cancel(sysdb); goto done; } ret = sysdb_transaction_commit(sysdb); if (ret != EOK) { DEBUG(1, ("Failed to commit transaction!\n")); } done: talloc_zfree(tmpctx); return ret; }