ldap_auth.c revision 71cd2f7ce705561d8d8f3cb7f385a57bedad1ef1
/*
SSSD
LDAP Backend Module
Authors:
Sumit Bose <sbose@redhat.com>
Copyright (C) 2008 Red Hat
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef WITH_MOZLDAP
#define LDAP_OPT_SUCCESS LDAP_SUCCESS
#endif
#include <time.h>
#include <errno.h>
#include <strings.h>
#include <shadow.h>
#include <security/pam_modules.h>
#include "util/user_info_msg.h"
#include "providers/ldap/ldap_common.h"
#include "providers/ldap/sdap_async.h"
enum pwexpire {
PWEXPIRE_NONE = 0,
};
enum sdap_result *result)
{
char *end;
return EINVAL;
}
if (*end != '\0') {
expire_date));
return EINVAL;
}
if (expire_time == -1) {
return EINVAL;
}
tzset();
expire_time -= timezone;
"daylight [%d] now [%d] expire_time [%d].\n", tzname[0],
} else {
}
return EOK;
}
enum sdap_result *result)
{
long today;
long password_age;
return EOK;
}
if (password_age < 0) {
return EOK;
}
{
return EOK;
}
return EOK;
}
/* TODO: evaluate spwd->min and spwd->warn */
return EOK;
}
static errno_t string_to_shadowpw_days(const char *s, long *d)
{
long l;
char *endptr;
if (s == NULL || *s == '\0') {
*d = -1;
return EOK;
}
errno = 0;
if (errno != 0) {
return errno;
}
if (*endptr != '\0') {
return EINVAL;
}
if (*d < -1) {
*d));
return EINVAL;
}
*d = l;
return EOK;
}
const struct ldb_message *msg,
{
const char *mark;
const char *val;
const char *pwd_policy;
int ret;
*type = PWEXPIRE_NONE;
if (pwd_policy == NULL) {
return EINVAL;
}
"assuming LDAP password policies are active.\n"));
return EOK;
}
return EOK;
NULL);
return ENOMEM;
}
return EOK;
}
} else {
"but MIT Kerberos password policy was requested.\n"));
return EINVAL;
}
return ENOMEM;
}
*type = PWEXPIRE_SHADOW;
return EOK;
} else {
"but shadow password policy was requested.\n"));
return EINVAL;
}
}
return EOK;
return ret;
}
/* ==Get-User-DN========================================================== */
struct get_user_dn_state {
struct tevent_context *ev;
struct sdap_auth_ctx *ctx;
struct sdap_handle *sh;
const char **attrs;
const char *name;
char *dn;
enum pwexpire pw_expire_type;
void *pw_expire_data;
};
struct tevent_context *ev,
struct sdap_auth_ctx *ctx,
struct sdap_handle *sh,
const char *username)
{
struct tevent_req *req;
struct get_user_dn_state *state;
int ret;
return NULL;
}
/* this sysdb call uses a sysdn operation, which means it will be
* schedule only after we return, no timer hack needed */
if (ret) {
}
return req;
}
{
struct get_user_dn_state);
const char *dn;
int ret;
if (err != LDB_SUCCESS) {
return;
}
case 0:
/* FIXME: not in cache, needs a true search */
break;
case 1:
if (!dn) {
/* TODO: try to search ldap server ? */
/* FIXME: remove once we store originalDN on every call
* NOTE: this is wrong, works only with some DITs */
if (!dn) {
break;
}
}
break;
}
&state->pw_expire_data);
break;
}
break;
default:
break;
}
}
enum pwexpire *pw_expire_type,
void **pw_expire_data)
{
struct get_user_dn_state);
/* state->pw_expire_data may be NULL */
return EOK;
}
/* ==Authenticate-User==================================================== */
struct auth_state {
struct tevent_context *ev;
struct sdap_auth_ctx *ctx;
const char *username;
struct dp_opt_blob password;
struct sdap_handle *sh;
enum sdap_result result;
char *dn;
enum pwexpire pw_expire_type;
void *pw_expire_data;
};
struct tevent_context *ev,
struct sdap_auth_ctx *ctx,
const char *username,
struct dp_opt_blob password)
{
struct auth_state *state;
return req;
fail:
return NULL;
}
{
struct tevent_req);
struct auth_state);
int ret;
if (ret) {
return;
}
if (!subreq) {
return;
}
}
{
struct tevent_req);
struct auth_state);
int ret;
if (ret) {
/* mark this server as bad if connection failed */
}
return;
}
if (!subreq) {
return;
}
}
{
struct tevent_req);
struct auth_state);
int ret;
&state->pw_expire_data);
if (ret) {
return;
}
if (!subreq) {
return;
}
}
{
struct tevent_req);
struct auth_state);
int ret;
if (ret) {
return;
}
}
struct sdap_handle **sh,
{
enum tevent_req_state tstate;
switch (tstate) {
case TEVENT_REQ_USER_ERROR:
else *result = SDAP_ERROR;
return err;
default:
*result = SDAP_ERROR;
return EIO;
}
}
}
}
if (pw_expire_data != NULL) {
}
return EOK;
}
/* ==Perform-Password-Change===================== */
struct sdap_pam_chpass_state {
const char *username;
char *dn;
char *password;
char *new_password;
struct sdap_handle *sh;
};
{
struct sdap_pam_chpass_state *state;
struct sdap_auth_ctx *ctx;
struct tevent_req *subreq;
struct dp_opt_blob authtok;
int dp_err = DP_ERR_FATAL;
struct sdap_auth_ctx);
goto done;
}
goto done;
}
(char *)pd->newauthtok,
}
return;
done:
}
{
struct sdap_pam_chpass_state *state =
struct tevent_req *subreq;
enum sdap_result result;
enum pwexpire pw_expire_type;
void *pw_expire_data;
int dp_err = DP_ERR_FATAL;
int ret;
if (ret) {
goto done;
}
if (result == SDAP_AUTH_SUCCESS &&
"successful.\n"));
goto done;
}
if (result == SDAP_AUTH_SUCCESS) {
switch (pw_expire_type) {
case PWEXPIRE_SHADOW:
&result);
goto done;
}
break;
case PWEXPIRE_KERBEROS:
&result);
goto done;
}
if (result == SDAP_AUTH_PW_EXPIRED) {
"passwords.\n"));
goto done;
}
break;
case PWEXPIRE_NONE:
break;
default:
goto done;
}
}
switch (result) {
case SDAP_AUTH_SUCCESS:
case SDAP_AUTH_PW_EXPIRED:
if (pw_expire_type == PWEXPIRE_SHADOW) {
/* TODO: implement async ldap modify request */
goto done;
} else {
if (!subreq) {
goto done;
}
return;
}
break;
case SDAP_AUTH_FAILED:
break;
default:
}
done:
}
{
struct sdap_pam_chpass_state *state =
enum sdap_result result;
int dp_err = DP_ERR_FATAL;
int ret;
char *user_error_message = NULL;
if (ret) {
goto done;
}
switch (result) {
case SDAP_SUCCESS:
break;
default:
if (user_error_message != NULL) {
} else {
msg);
}
}
}
}
done:
}
/* ==Perform-User-Authentication-and-Password-Caching===================== */
struct sdap_pam_auth_state {
const char *username;
struct dp_opt_blob password;
};
{
struct sdap_pam_auth_state *state;
struct sdap_auth_ctx *ctx;
struct tevent_req *subreq;
int dp_err = DP_ERR_FATAL;
struct sdap_auth_ctx);
goto done;
}
case SSS_PAM_AUTHENTICATE:
case SSS_PAM_CHAUTHTOK_PRELIM:
return;
case SSS_PAM_CHAUTHTOK:
break;
case SSS_PAM_ACCT_MGMT:
case SSS_PAM_SETCRED:
case SSS_PAM_OPEN_SESSION:
case SSS_PAM_CLOSE_SESSION:
break;
default:
}
done:
}
{
struct sdap_pam_auth_state *state =
struct tevent_req *subreq;
enum sdap_result result;
enum pwexpire pw_expire_type;
void *pw_expire_data;
int ret;
if (ret) {
goto done;
}
if (result == SDAP_AUTH_SUCCESS) {
switch (pw_expire_type) {
case PWEXPIRE_SHADOW:
&result);
goto done;
}
break;
case PWEXPIRE_KERBEROS:
&result);
goto done;
}
break;
case PWEXPIRE_NONE:
break;
default:
goto done;
}
}
switch (result) {
case SDAP_AUTH_SUCCESS:
break;
case SDAP_AUTH_FAILED:
break;
case SDAP_UNAVAIL:
break;
case SDAP_ACCT_EXPIRED:
break;
case SDAP_AUTH_PW_EXPIRED:
break;
default:
}
if (result == SDAP_UNAVAIL) {
goto done;
}
if (result == SDAP_AUTH_SUCCESS &&
/* password caching failures are not fatal errors */
if (!password) {
goto done;
}
NULL,
/* password caching failures are not fatal errors */
if (!subreq) {
goto done;
}
return;
}
done:
}
{
struct sdap_pam_auth_state);
int ret;
if (ret) {
/* password caching failures are not fatal errors */
} else {
}
}
{
}