summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/providers/ldap/ldap_auth.c48
-rw-r--r--server/providers/ldap/ldap_id.c80
-rw-r--r--server/providers/ldap/sdap.c254
-rw-r--r--server/providers/ldap/sdap.h141
-rw-r--r--server/providers/ldap/sdap_async.c45
-rw-r--r--server/providers/ldap/sdap_async.h2
6 files changed, 376 insertions, 194 deletions
diff --git a/server/providers/ldap/ldap_auth.c b/server/providers/ldap/ldap_auth.c
index 51afee36..a64a27f7 100644
--- a/server/providers/ldap/ldap_auth.c
+++ b/server/providers/ldap/ldap_auth.c
@@ -126,7 +126,8 @@ static void get_user_dn_done(void *pvt, int err, struct ldb_result *res)
dn = talloc_asprintf(state, "%s=%s,%s",
state->ctx->opts->user_map[SDAP_AT_USER_NAME].name,
state->name,
- state->ctx->opts->basic[SDAP_USER_SEARCH_BASE].value);
+ sdap_go_get_string(state->ctx->opts->basic,
+ SDAP_USER_SEARCH_BASE));
if (!dn) {
tevent_req_error(req, ENOMEM);
break;
@@ -173,7 +174,7 @@ struct auth_state {
struct tevent_context *ev;
struct sdap_auth_ctx *ctx;
const char *username;
- const char *password;
+ struct sdap_blob password;
struct sdap_handle *sh;
@@ -185,11 +186,11 @@ static void auth_connect_done(struct tevent_req *subreq);
static void auth_get_user_dn_done(struct tevent_req *subreq);
static void auth_bind_user_done(struct tevent_req *subreq);
-struct tevent_req *auth_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_auth_ctx *ctx,
- const char *username,
- const char *password)
+static struct tevent_req *auth_send(TALLOC_CTX *memctx,
+ struct tevent_context *ev,
+ struct sdap_auth_ctx *ctx,
+ const char *username,
+ struct sdap_blob password)
{
struct tevent_req *req, *subreq;
struct auth_state *state;
@@ -333,6 +334,7 @@ static void sdap_pam_chpass_send(struct be_req *breq)
struct sdap_auth_ctx *ctx;
struct tevent_req *subreq;
struct pam_data *pd;
+ struct sdap_blob authtok;
ctx = talloc_get_type(breq->be_ctx->bet_info[BET_CHPASS].pvt_bet_data,
struct sdap_auth_ctx);
@@ -371,8 +373,10 @@ static void sdap_pam_chpass_send(struct be_req *breq)
talloc_set_destructor((TALLOC_CTX *)state->new_password,
password_destructor);
+ authtok.data = (uint8_t *)state->password;
+ authtok.length = strlen(state->password);
subreq = auth_send(breq, breq->be_ctx->ev,
- ctx, state->username, state->password);
+ ctx, state->username, authtok);
if (!subreq) goto done;
tevent_req_set_callback(subreq, sdap_auth4chpass_done, state);
@@ -454,7 +458,7 @@ struct sdap_pam_auth_state {
struct be_req *breq;
struct pam_data *pd;
const char *username;
- char *password;
+ struct sdap_blob password;
};
static void sdap_pam_auth_done(struct tevent_req *req);
@@ -489,14 +493,11 @@ static void sdap_pam_auth_send(struct be_req *breq)
state->breq = breq;
state->pd = pd;
state->username = pd->user;
- state->password = talloc_strndup(state,
- (char *)pd->authtok, pd->authtok_size);
- if (!state->password) goto done;
- talloc_set_destructor((TALLOC_CTX *)state->password,
- password_destructor);
-
- subreq = auth_send(breq, breq->be_ctx->ev,
- ctx, state->username, state->password);
+ state->password.data = pd->authtok;
+ state->password.length = pd->authtok_size;
+
+ subreq = auth_send(breq, breq->be_ctx->ev, ctx,
+ state->username, state->password);
if (!subreq) goto done;
tevent_req_set_callback(subreq, sdap_pam_auth_done, state);
@@ -551,12 +552,21 @@ static void sdap_pam_auth_done(struct tevent_req *req)
if (result == SDAP_AUTH_SUCCESS &&
state->breq->be_ctx->domain->cache_credentials) {
+ char *password = talloc_strndup(state, (char *)
+ state->password.data,
+ state->password.length);
+ if (!password) {
+ DEBUG(2, ("Failed to cache password for %s\n", state->username));
+ goto done;
+ }
+ talloc_set_destructor((TALLOC_CTX *)password, password_destructor);
+
subreq = sysdb_cache_password_send(state,
state->breq->be_ctx->ev,
state->breq->be_ctx->sysdb,
NULL,
state->breq->be_ctx->domain,
- state->username, state->password);
+ state->username, password);
/* password caching failures are not fatal errors */
if (!subreq) {
@@ -633,7 +643,7 @@ int sssm_ldap_auth_init(struct be_ctx *bectx,
&ctx->opts);
if (ret != EOK) goto done;
- tls_reqcert = ctx->opts->basic[SDAP_TLS_REQCERT].value;
+ tls_reqcert = sdap_go_get_string(ctx->opts->basic, SDAP_TLS_REQCERT);
if (tls_reqcert) {
if (strcasecmp(tls_reqcert, "never") == 0) {
ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_NEVER;
diff --git a/server/providers/ldap/ldap_id.c b/server/providers/ldap/ldap_id.c
index 1984582d..72caf966 100644
--- a/server/providers/ldap/ldap_id.c
+++ b/server/providers/ldap/ldap_id.c
@@ -98,7 +98,7 @@ struct sdap_id_connect_state {
bool use_start_tls;
char *defaultBindDn;
char *defaultAuthtokType;
- char *defaultAuthtok;
+ struct sdap_blob defaultAuthtok;
struct sdap_handle *sh;
};
@@ -106,13 +106,13 @@ struct sdap_id_connect_state {
static void sdap_id_connect_done(struct tevent_req *subreq);
static void sdap_id_bind_done(struct tevent_req *subreq);
-struct tevent_req *sdap_id_connect_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx,
- bool use_start_tls,
- char *defaultBindDn,
- char *defaultAuthtokType,
- char *defaultAuthtok)
+static struct tevent_req *sdap_id_connect_send(TALLOC_CTX *memctx,
+ struct tevent_context *ev,
+ struct sdap_id_ctx *ctx,
+ bool use_start_tls,
+ char *defaultBindDn,
+ char *defaultAuthtokType,
+ struct sdap_blob defaultAuthtok)
{
struct tevent_req *req, *subreq;
struct sdap_id_connect_state *state;
@@ -268,9 +268,12 @@ static struct tevent_req *users_get_send(TALLOC_CTX *memctx,
/* FIXME: add option to decide if tls should be used
* or SASL/GSSAPI, etc ... */
subreq = sdap_id_connect_send(state, ev, ctx, false,
- ctx->opts->basic[SDAP_DEFAULT_BIND_DN].value,
- ctx->opts->basic[SDAP_DEFAULT_AUTHTOK_TYPE].value,
- ctx->opts->basic[SDAP_DEFAULT_AUTHTOK].value);
+ sdap_go_get_string(ctx->opts->basic,
+ SDAP_DEFAULT_BIND_DN),
+ sdap_go_get_string(ctx->opts->basic,
+ SDAP_DEFAULT_AUTHTOK_TYPE),
+ sdap_go_get_blob(ctx->opts->basic,
+ SDAP_DEFAULT_AUTHTOK));
if (!subreq) {
ret = ENOMEM;
goto fail;
@@ -434,9 +437,12 @@ static struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
/* FIXME: add option to decide if tls should be used
* or SASL/GSSAPI, etc ... */
subreq = sdap_id_connect_send(state, ev, ctx, false,
- ctx->opts->basic[SDAP_DEFAULT_BIND_DN].value,
- ctx->opts->basic[SDAP_DEFAULT_AUTHTOK_TYPE].value,
- ctx->opts->basic[SDAP_DEFAULT_AUTHTOK].value);
+ sdap_go_get_string(ctx->opts->basic,
+ SDAP_DEFAULT_BIND_DN),
+ sdap_go_get_string(ctx->opts->basic,
+ SDAP_DEFAULT_AUTHTOK_TYPE),
+ sdap_go_get_blob(ctx->opts->basic,
+ SDAP_DEFAULT_AUTHTOK));
if (!subreq) {
ret = ENOMEM;
goto fail;
@@ -574,9 +580,12 @@ static struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx,
/* FIXME: add option to decide if tls should be used
* or SASL/GSSAPI, etc ... */
subreq = sdap_id_connect_send(state, ev, ctx, false,
- ctx->opts->basic[SDAP_DEFAULT_BIND_DN].value,
- ctx->opts->basic[SDAP_DEFAULT_AUTHTOK_TYPE].value,
- ctx->opts->basic[SDAP_DEFAULT_AUTHTOK].value);
+ sdap_go_get_string(ctx->opts->basic,
+ SDAP_DEFAULT_BIND_DN),
+ sdap_go_get_string(ctx->opts->basic,
+ SDAP_DEFAULT_AUTHTOK_TYPE),
+ sdap_go_get_blob(ctx->opts->basic,
+ SDAP_DEFAULT_AUTHTOK));
if (!subreq) {
ret = ENOMEM;
goto fail;
@@ -789,6 +798,7 @@ static void ldap_id_enumerate(struct tevent_context *ev,
struct sdap_id_ctx *ctx = talloc_get_type(pvt, struct sdap_id_ctx);
struct tevent_timer *timeout;
struct tevent_req *req;
+ int ert;
if (be_is_offline(ctx->be)) {
DEBUG(4, ("Backend is marked offline, retry later!\n"));
@@ -811,7 +821,8 @@ static void ldap_id_enumerate(struct tevent_context *ev,
/* if enumeration takes so long, either we try to enumerate too
* frequently, or something went seriously wrong */
tv = tevent_timeval_current();
- tv = tevent_timeval_add(&tv, ctx->opts->enum_refresh_timeout, 0);
+ ert = sdap_go_get_int(ctx->opts->basic, SDAP_ENUM_REFRESH_TIMEOUT);
+ tv = tevent_timeval_add(&tv, ert, 0);
timeout = tevent_add_timer(ctx->be->ev, req, tv,
ldap_id_enumerate_timeout, req);
return;
@@ -824,9 +835,10 @@ static void ldap_id_enumerate_timeout(struct tevent_context *ev,
struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
struct sdap_id_ctx *ctx = tevent_req_callback_data(req,
struct sdap_id_ctx);
+ int ert;
- DEBUG(1, ("Enumeration timed out! Timeout too small? (%ds)!\n",
- ctx->opts->enum_refresh_timeout));
+ ert = sdap_go_get_int(ctx->opts->basic, SDAP_ENUM_REFRESH_TIMEOUT);
+ DEBUG(1, ("Enumeration timed out! Timeout too small? (%ds)!\n", ert));
ldap_id_enumerate_set_timer(ctx, tevent_timeval_current());
talloc_zfree(req);
@@ -855,8 +867,10 @@ static void ldap_id_enumerate_set_timer(struct sdap_id_ctx *ctx,
struct timeval tv)
{
struct tevent_timer *enum_task;
+ int ert;
- tv = tevent_timeval_add(&tv, ctx->opts->enum_refresh_timeout, 0);
+ ert = sdap_go_get_int(ctx->opts->basic, SDAP_ENUM_REFRESH_TIMEOUT);
+ tv = tevent_timeval_add(&tv, ert, 0);
enum_task = tevent_add_timer(ctx->be->ev, ctx, tv, ldap_id_enumerate, ctx);
if (!enum_task) {
DEBUG(0, ("FATAL: failed to setup enumeration task!\n"));
@@ -965,6 +979,7 @@ fail:
tevent_req_done(req);
}
+
/* ==User-Enumeration===================================================== */
struct enum_users_state {
@@ -1025,9 +1040,12 @@ static struct tevent_req *enum_users_send(TALLOC_CTX *memctx,
/* FIXME: add option to decide if tls should be used
* or SASL/GSSAPI, etc ... */
subreq = sdap_id_connect_send(state, ev, ctx, false,
- ctx->opts->basic[SDAP_DEFAULT_BIND_DN].value,
- ctx->opts->basic[SDAP_DEFAULT_AUTHTOK_TYPE].value,
- ctx->opts->basic[SDAP_DEFAULT_AUTHTOK].value);
+ sdap_go_get_string(ctx->opts->basic,
+ SDAP_DEFAULT_BIND_DN),
+ sdap_go_get_string(ctx->opts->basic,
+ SDAP_DEFAULT_AUTHTOK_TYPE),
+ sdap_go_get_blob(ctx->opts->basic,
+ SDAP_DEFAULT_AUTHTOK));
if (!subreq) {
ret = ENOMEM;
goto fail;
@@ -1175,9 +1193,12 @@ static struct tevent_req *enum_groups_send(TALLOC_CTX *memctx,
/* FIXME: add option to decide if tls should be used
* or SASL/GSSAPI, etc ... */
subreq = sdap_id_connect_send(state, ev, ctx, false,
- ctx->opts->basic[SDAP_DEFAULT_BIND_DN].value,
- ctx->opts->basic[SDAP_DEFAULT_AUTHTOK_TYPE].value,
- ctx->opts->basic[SDAP_DEFAULT_AUTHTOK].value);
+ sdap_go_get_string(ctx->opts->basic,
+ SDAP_DEFAULT_BIND_DN),
+ sdap_go_get_string(ctx->opts->basic,
+ SDAP_DEFAULT_AUTHTOK_TYPE),
+ sdap_go_get_blob(ctx->opts->basic,
+ SDAP_DEFAULT_AUTHTOK));
if (!subreq) {
ret = ENOMEM;
goto fail;
@@ -1291,10 +1312,9 @@ int sssm_ldap_init(struct be_ctx *bectx,
ctx->be = bectx;
- ret = sdap_get_options(ctx, bectx->cdb, bectx->conf_path,
- &ctx->opts);
+ ret = sdap_get_options(ctx, bectx->cdb, bectx->conf_path, &ctx->opts);
- tls_reqcert = ctx->opts->basic[SDAP_TLS_REQCERT].value;
+ tls_reqcert = sdap_go_get_string(ctx->opts->basic, SDAP_TLS_REQCERT);
if (tls_reqcert) {
if (strcasecmp(tls_reqcert, "never") == 0) {
ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_NEVER;
diff --git a/server/providers/ldap/sdap.c b/server/providers/ldap/sdap.c
index 616e4a37..22d238e6 100644
--- a/server/providers/ldap/sdap.c
+++ b/server/providers/ldap/sdap.c
@@ -25,24 +25,31 @@
#include "confdb/confdb.h"
#include "providers/ldap/sdap.h"
+#define NULL_STRING { .string = NULL }
+#define NULL_BLOB { .blob = { NULL, 0 } }
+#define NULL_NUMBER { .number = 0 }
+#define BOOL_FALSE { .boolean = false }
+#define BOOL_TRUE { .boolean = true }
+
struct sdap_gen_opts default_basic_opts[] = {
- { "ldapUri", "ldap://localhost", NULL },
- { "defaultBindDn", NULL, NULL },
- { "defaultAuthtokType", NULL, NULL },
- { "defaultAuthtok", NULL, NULL },
- { "network_timeout", "5", NULL },
- { "opt_timeout", "5", NULL },
- { "tls_reqcert", "hard", NULL },
- { "userSearchBase", "ou=People,dc=example,dc=com", NULL },
- { "userSearchScope", "sub", NULL },
- { "userSearchFilter", NULL, NULL },
- { "groupSearchBase", "ou=Group,dc=example,dc=com", NULL },
- { "groupSearchScope", "sub", NULL },
- { "groupSearchFilter", NULL, NULL },
- { "ldapSchema", "rfc2307", NULL },
- { "offline_timeout", "60", NULL },
- { "force_upper_case_realm", "0", NULL },
- { "enumeration_refresh_timeout", "300", NULL }
+ { "ldapUri", SDAP_STRING, { "ldap://localhost" }, NULL_STRING },
+ { "defaultBindDn", SDAP_STRING, NULL_STRING, NULL_STRING },
+ { "defaultAuthtokType", SDAP_STRING, NULL_STRING, NULL_STRING},
+ { "defaultAuthtok", SDAP_BLOB, NULL_BLOB, NULL_BLOB },
+ { "network_timeout", SDAP_NUMBER, { .number = 5 }, NULL_NUMBER },
+ { "opt_timeout", SDAP_NUMBER, { .number = 5 }, NULL_NUMBER },
+ { "tls_reqcert", SDAP_STRING, { "hard" }, NULL_STRING },
+ { "userSearchBase", SDAP_STRING, { "ou=People,dc=example,dc=com" }, NULL_STRING },
+ { "userSearchScope", SDAP_STRING, { "sub" }, NULL_STRING },
+ { "userSearchFilter", SDAP_STRING, NULL_STRING, NULL_STRING },
+ { "groupSearchBase", SDAP_STRING, { "ou=Group,dc=example,dc=com" }, NULL_STRING },
+ { "groupSearchScope", SDAP_STRING, { "sub" }, NULL_STRING },
+ { "groupSearchFilter", SDAP_STRING, NULL_STRING, NULL_STRING },
+ { "ldapSchema", SDAP_STRING, { "rfc2307" }, NULL_STRING },
+ { "offline_timeout", SDAP_NUMBER, { .number = 60 }, NULL_NUMBER },
+ { "force_upper_case_realm", SDAP_BOOL, BOOL_FALSE, BOOL_FALSE },
+ { "enumeration_refresh_timeout", SDAP_NUMBER, { .number = 300 }, NULL_NUMBER },
+ { "stale_time", SDAP_NUMBER, { .number = 1800 }, NULL_NUMBER }
};
struct sdap_id_map rfc2307_user_map[] = {
@@ -109,6 +116,7 @@ int sdap_get_options(TALLOC_CTX *memctx,
struct sdap_id_map *default_user_map;
struct sdap_id_map *default_group_map;
struct sdap_options *opts;
+ char *schema;
int i, ret;
opts = talloc_zero(memctx, struct sdap_options);
@@ -124,76 +132,98 @@ int sdap_get_options(TALLOC_CTX *memctx,
if (!opts) return ENOMEM;
for (i = 0; i < SDAP_OPTS_BASIC; i++) {
+ char *tmp;
opts->basic[i].opt_name = default_basic_opts[i].opt_name;
- opts->basic[i].def_value = default_basic_opts[i].def_value;
-
- ret = confdb_get_string(cdb, opts, conf_path,
- opts->basic[i].opt_name,
- opts->basic[i].def_value,
- &opts->basic[i].value);
- if (ret != EOK ||
- (opts->basic[i].def_value && !opts->basic[i].value)) {
- DEBUG(0, ("Failed to retrieve a value (%s)\n",
- opts->basic[i].opt_name));
- if (ret != EOK) ret = EINVAL;
- goto done;
- }
-
- DEBUG(5, ("Option %s has value %s\n",
- opts->basic[i].opt_name, opts->basic[i].value));
- }
-
- /* re-read special options that are easier to be consumed after they are
- * transformed */
-
-/* TODO: better to have a blob object than a string here */
- ret = confdb_get_string(cdb, opts, conf_path,
- "defaultAuthtok", NULL,
- &opts->default_authtok);
- if (ret != EOK) goto done;
- if (opts->default_authtok) {
- opts->default_authtok_size = strlen(opts->default_authtok);
- }
+ opts->basic[i].type = default_basic_opts[i].type;
+ opts->basic[i].def_val = default_basic_opts[i].def_val;
+ ret = EOK;
+
+ switch (default_basic_opts[i].type) {
+ case SDAP_STRING:
+ ret = confdb_get_string(cdb, opts, conf_path,
+ opts->basic[i].opt_name,
+ opts->basic[i].def_val.cstring,
+ &opts->basic[i].val.string);
+ if (ret != EOK ||
+ ((opts->basic[i].def_val.string != NULL) &&
+ (opts->basic[i].val.string == NULL))) {
+ DEBUG(0, ("Failed to retrieve value for option (%s)\n",
+ opts->basic[i].opt_name));
+ if (ret == EOK) ret = EINVAL;
+ goto done;
+ }
+ DEBUG(6, ("Option %s has value %s\n",
+ opts->basic[i].opt_name, opts->basic[i].val.cstring));
+ break;
- ret = confdb_get_int(cdb, opts, conf_path,
- "network_timeout", 5,
- &opts->network_timeout);
- if (ret != EOK) goto done;
+ case SDAP_BLOB:
+ ret = confdb_get_string(cdb, opts, conf_path,
+ opts->basic[i].opt_name,
+ NULL, &tmp);
+ if (ret != EOK) {
+ DEBUG(0, ("Failed to retrieve value for option (%s)\n",
+ opts->basic[i].opt_name));
+ goto done;
+ }
- ret = confdb_get_int(cdb, opts, conf_path,
- "opt_timeout", 5,
- &opts->opt_timeout);
- if (ret != EOK) goto done;
+ if (tmp) {
+ opts->basic[i].val.blob.data = (uint8_t *)tmp;
+ opts->basic[i].val.blob.length = strlen(tmp);
+ } else {
+ opts->basic[i].val.blob.data = NULL;
+ opts->basic[i].val.blob.length = 0;
+ }
- ret = confdb_get_int(cdb, opts, conf_path,
- "offline_timeout", 60,
- &opts->offline_timeout);
- if (ret != EOK) goto done;
+ DEBUG(6, ("Option %s has %s value\n",
+ opts->basic[i].opt_name,
+ opts->basic[i].val.blob.length?"a":"no"));
+ break;
- ret = confdb_get_bool(cdb, opts, conf_path,
- "force_upper_case_realm", false,
- &opts->force_upper_case_realm);
- if (ret != EOK) goto done;
+ case SDAP_NUMBER:
+ ret = confdb_get_int(cdb, opts, conf_path,
+ opts->basic[i].opt_name,
+ opts->basic[i].def_val.number,
+ &opts->basic[i].val.number);
+ if (ret != EOK) {
+ DEBUG(0, ("Failed to retrieve value for option (%s)\n",
+ opts->basic[i].opt_name));
+ goto done;
+ }
+ DEBUG(6, ("Option %s has value %d\n",
+ opts->basic[i].opt_name, opts->basic[i].val.number));
+ break;
- ret = confdb_get_int(cdb, opts, conf_path,
- "enumeration_refresh_timeout", 300,
- &opts->enum_refresh_timeout);
- if (ret != EOK) goto done;
+ case SDAP_BOOL:
+ ret = confdb_get_bool(cdb, opts, conf_path,
+ opts->basic[i].opt_name,
+ opts->basic[i].def_val.boolean,
+ &opts->basic[i].val.boolean);
+ if (ret != EOK) {
+ DEBUG(0, ("Failed to retrieve value for option (%s)\n",
+ opts->basic[i].opt_name));
+ goto done;
+ }
+ DEBUG(6, ("Option %s is %s\n",
+ opts->basic[i].opt_name,
+ opts->basic[i].val.boolean?"TRUE":"FALSE"));
+ break;
+ }
+ }
/* schema type */
- if (strcasecmp(opts->basic[SDAP_SCHEMA].value, "rfc2307") == 0) {
+ schema = sdap_go_get_string(opts->basic, SDAP_SCHEMA);
+ if (strcasecmp(schema, "rfc2307") == 0) {
opts->schema_type = SDAP_SCHEMA_RFC2307;
default_user_map = rfc2307_user_map;
default_group_map = rfc2307_group_map;
} else
- if (strcasecmp(opts->basic[SDAP_SCHEMA].value, "rfc2307bis") == 0) {
+ if (strcasecmp(schema, "rfc2307bis") == 0) {
opts->schema_type = SDAP_SCHEMA_RFC2307BIS;
default_user_map = rfc2307bis_user_map;
default_group_map = rfc2307bis_group_map;
} else {
- DEBUG(0, ("Unrecognized schema type: %s\n",
- opts->basic[SDAP_SCHEMA].value));
+ DEBUG(0, ("Unrecognized schema type: %s\n", schema));
ret = EINVAL;
goto done;
}
@@ -250,6 +280,90 @@ done:
return ret;
}
+/* =Basic-Option-Helpers================================================== */
+
+static const char *sdap_type_to_string(enum sdap_type type)
+{
+ switch (type) {
+ case SDAP_STRING:
+ return "String";
+ case SDAP_BLOB:
+ return "Blob";
+ case SDAP_NUMBER:
+ return "Number";
+ case SDAP_BOOL:
+ return "Boolean";
+ }
+ return NULL;
+}
+
+const char *_sdap_go_get_cstring(struct sdap_gen_opts *opts,
+ int id, const char *location)
+{
+ if (opts[id].type != SDAP_STRING) {
+ DEBUG(0, ("[%s] Requested type 'String' for option '%s'"
+ " but value is of type '%s'!\n",
+ location, opts[id].opt_name,
+ sdap_type_to_string(opts[id].type)));
+ return NULL;
+ }
+ return opts[id].val.cstring;
+}
+
+char *_sdap_go_get_string(struct sdap_gen_opts *opts,
+ int id, const char *location)
+{
+ if (opts[id].type != SDAP_STRING) {
+ DEBUG(0, ("[%s] Requested type 'String' for option '%s'"
+ " but value is of type '%s'!\n",
+ location, opts[id].opt_name,
+ sdap_type_to_string(opts[id].type)));
+ return NULL;
+ }
+ return opts[id].val.string;
+}
+
+struct sdap_blob _sdap_go_get_blob(struct sdap_gen_opts *opts,
+ int id, const char *location)
+{
+ struct sdap_blob null_blob = { NULL, 0 };
+ if (opts[id].type != SDAP_BLOB) {
+ DEBUG(0, ("[%s] Requested type 'Blob' for option '%s'"
+ " but value is of type '%s'!\n",
+ location, opts[id].opt_name,
+ sdap_type_to_string(opts[id].type)));
+ return null_blob;
+ }
+ return opts[id].val.blob;
+}
+
+int _sdap_go_get_int(struct sdap_gen_opts *opts,
+ int id, const char *location)
+{
+ if (opts[id].type != SDAP_NUMBER) {
+ DEBUG(0, ("[%s] Requested type 'Number' for option '%s'"
+ " but value is of type '%s'!\n",
+ location, opts[id].opt_name,
+ sdap_type_to_string(opts[id].type)));
+ return 0;
+ }
+ return opts[id].val.number;
+}
+
+bool _sdap_go_get_bool(struct sdap_gen_opts *opts,
+ int id, const char *location)
+{
+ if (opts[id].type != SDAP_BOOL) {
+ DEBUG(0, ("[%s] Requested type 'Boolean' for option '%s'"
+ " but value is of type '%s'!\n",
+ location, opts[id].opt_name,
+ sdap_type_to_string(opts[id].type)));
+ return false;
+ }
+ return opts[id].val.boolean;
+}
+
+
/* =Parse-msg============================================================= */
static int sdap_parse_entry(TALLOC_CTX *memctx,
diff --git a/server/providers/ldap/sdap.h b/server/providers/ldap/sdap.h
index a39eef51..7168a5a0 100644
--- a/server/providers/ldap/sdap.h
+++ b/server/providers/ldap/sdap.h
@@ -69,60 +69,88 @@ enum sdap_result {
SDAP_AUTH_FAILED
};
-#define SDAP_URI 0
-#define SDAP_DEFAULT_BIND_DN 1
-#define SDAP_DEFAULT_AUTHTOK_TYPE 2
-#define SDAP_DEFAULT_AUTHTOK 3
-#define SDAP_NETWROK_TIMEOUT 4
-#define SDAP_OPT_TIMEOUT 5
-#define SDAP_TLS_REQCERT 6
-#define SDAP_USER_SEARCH_BASE 7
-#define SDAP_USER_SEARCH_SCOPE 8
-#define SDAP_USER_SEARCH_FILTER 9
-#define SDAP_GROUP_SEARCH_BASE 10
-#define SDAP_GROUP_SEARCH_SCOPE 11
-#define SDAP_GROUP_SEARCH_FILTER 12
-#define SDAP_SCHEMA 13
-#define SDAP_OFFLINE_TIMEOUT 14
-#define SDAP_FORCE_UPPER_CASE_REALM 15
-#define SDAP_ENUM_REFRESH_TIMEOUT 16
-
-#define SDAP_OPTS_BASIC 17 /* opts counter */
+enum sdap_basic_opt {
+ SDAP_URI = 0,
+ SDAP_DEFAULT_BIND_DN,
+ SDAP_DEFAULT_AUTHTOK_TYPE,
+ SDAP_DEFAULT_AUTHTOK,
+ SDAP_NETWORK_TIMEOUT,
+ SDAP_OPT_TIMEOUT,
+ SDAP_TLS_REQCERT,
+ SDAP_USER_SEARCH_BASE,
+ SDAP_USER_SEARCH_SCOPE,
+ SDAP_USER_SEARCH_FILTER,
+ SDAP_GROUP_SEARCH_BASE,
+ SDAP_GROUP_SEARCH_SCOPE,
+ SDAP_GROUP_SEARCH_FILTER,
+ SDAP_SCHEMA,
+ SDAP_OFFLINE_TIMEOUT,
+ SDAP_FORCE_UPPER_CASE_REALM,
+ SDAP_ENUM_REFRESH_TIMEOUT,
+ SDAP_STALE_TIME,
+
+ SDAP_OPTS_BASIC /* opts counter */
+};
/* the objectclass must be the first attribute.
* Functions depend on this */
-#define SDAP_OC_USER 0
-#define SDAP_AT_USER_NAME 1
-#define SDAP_AT_USER_PWD 2
-#define SDAP_AT_USER_UID 3
-#define SDAP_AT_USER_GID 4
-#define SDAP_AT_USER_GECOS 5
-#define SDAP_AT_USER_HOME 6
-#define SDAP_AT_USER_SHELL 7
-#define SDAP_AT_USER_PRINC 8
-#define SDAP_AT_USER_FULLNAME 9
-#define SDAP_AT_USER_MEMBEROF 10
-#define SDAP_AT_USER_UUID 11
-#define SDAP_AT_USER_MODSTAMP 12
-
-#define SDAP_OPTS_USER 13 /* attrs counter */
+enum sdap_user_opt {
+ SDAP_OC_USER = 0,
+ SDAP_AT_USER_NAME,
+ SDAP_AT_USER_PWD,
+ SDAP_AT_USER_UID,
+ SDAP_AT_USER_GID,
+ SDAP_AT_USER_GECOS,
+ SDAP_AT_USER_HOME,
+ SDAP_AT_USER_SHELL,
+ SDAP_AT_USER_PRINC,
+ SDAP_AT_USER_FULLNAME,
+ SDAP_AT_USER_MEMBEROF,
+ SDAP_AT_USER_UUID,
+ SDAP_AT_USER_MODSTAMP,
+
+ SDAP_OPTS_USER /* attrs counter */
+};
/* the objectclass must be the first attribute.
* Functions depend on this */
-#define SDAP_OC_GROUP 0
-#define SDAP_AT_GROUP_NAME 1
-#define SDAP_AT_GROUP_PWD 2
-#define SDAP_AT_GROUP_GID 3
-#define SDAP_AT_GROUP_MEMBER 4
-#define SDAP_AT_GROUP_UUID 5
-#define SDAP_AT_GROUP_MODSTAMP 6
+enum sdap_group_opt {
+ SDAP_OC_GROUP = 0,
+ SDAP_AT_GROUP_NAME,
+ SDAP_AT_GROUP_PWD,
+ SDAP_AT_GROUP_GID,
+ SDAP_AT_GROUP_MEMBER,
+ SDAP_AT_GROUP_UUID,
+ SDAP_AT_GROUP_MODSTAMP,
+
+ SDAP_OPTS_GROUP /* attrs counter */
+};
+
+enum sdap_type {
+ SDAP_STRING,
+ SDAP_BLOB,
+ SDAP_NUMBER,
+ SDAP_BOOL
+};
-#define SDAP_OPTS_GROUP 7 /* attrs counter */
+struct sdap_blob {
+ uint8_t *data;
+ size_t length;
+};
+
+union sdap_value {
+ const char *cstring;
+ char *string;
+ struct sdap_blob blob;
+ int number;
+ bool boolean;
+};
struct sdap_gen_opts {
const char *opt_name;
- const char *def_value;
- char *value;
+ enum sdap_type type;
+ union sdap_value def_val;
+ union sdap_value val;
};
struct sdap_id_map {
@@ -137,15 +165,6 @@ struct sdap_options {
struct sdap_id_map *user_map;
struct sdap_id_map *group_map;
- /* transformed for easier consumption */
- uint32_t default_authtok_size;
- char *default_authtok; /* todo: turn into uint8_t */
- int network_timeout;
- int opt_timeout;
- int offline_timeout;
- int enum_refresh_timeout;
- bool force_upper_case_realm;
-
/* supported schema types */
enum schema_type {
SDAP_SCHEMA_RFC2307 = 1, /* memberUid = uid */
@@ -162,6 +181,22 @@ int sdap_get_options(TALLOC_CTX *memctx,
const char *conf_path,
struct sdap_options **_opts);
+const char *_sdap_go_get_cstring(struct sdap_gen_opts *opts,
+ int id, const char *location);
+char *_sdap_go_get_string(struct sdap_gen_opts *opts,
+ int id, const char *location);
+struct sdap_blob _sdap_go_get_blob(struct sdap_gen_opts *opts,
+ int id, const char *location);
+int _sdap_go_get_int(struct sdap_gen_opts *opts,
+ int id, const char *location);
+bool _sdap_go_get_bool(struct sdap_gen_opts *opts,
+ int id, const char *location);
+#define sdap_go_get_cstring(o, i) _sdap_go_get_cstring(o, i, __FUNCTION__)
+#define sdap_go_get_string(o, i) _sdap_go_get_string(o, i, __FUNCTION__)
+#define sdap_go_get_blob(o, i) _sdap_go_get_blob(o, i, __FUNCTION__)
+#define sdap_go_get_int(o, i) _sdap_go_get_int(o, i, __FUNCTION__)
+#define sdap_go_get_bool(o, i) _sdap_go_get_bool(o, i, __FUNCTION__)
+
int sdap_parse_user(TALLOC_CTX *memctx, struct sdap_options *opts,
struct sdap_handle *sh, struct sdap_msg *sm,
struct sysdb_attrs **_attrs, char **_dn);
diff --git a/server/providers/ldap/sdap_async.c b/server/providers/ldap/sdap_async.c
index bcdf22a0..1a0faf4e 100644
--- a/server/providers/ldap/sdap_async.c
+++ b/server/providers/ldap/sdap_async.c
@@ -472,7 +472,8 @@ struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx,
return NULL;
}
/* Initialize LDAP handler */
- lret = ldap_initialize(&state->sh->ldap, opts->basic[SDAP_URI].value);
+ lret = ldap_initialize(&state->sh->ldap,
+ sdap_go_get_string(opts->basic, SDAP_URI));
if (lret != LDAP_SUCCESS) {
DEBUG(1, ("ldap_initialize failed: %s\n", ldap_err2string(ret)));
goto fail;
@@ -487,22 +488,22 @@ struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx,
}
/* Set Network Timeout */
- tv.tv_sec = opts->network_timeout;
+ tv.tv_sec = sdap_go_get_int(opts->basic, SDAP_NETWORK_TIMEOUT);
tv.tv_usec = 0;
lret = ldap_set_option(state->sh->ldap, LDAP_OPT_NETWORK_TIMEOUT, &tv);
if (lret != LDAP_OPT_SUCCESS) {
DEBUG(1, ("Failed to set network timeout to %d\n",
- opts->network_timeout));
+ sdap_go_get_int(opts->basic, SDAP_NETWORK_TIMEOUT)));
goto fail;
}
/* Set Default Timeout */
- tv.tv_sec = opts->opt_timeout;
+ tv.tv_sec = sdap_go_get_int(opts->basic, SDAP_OPT_TIMEOUT);
tv.tv_usec = 0;
lret = ldap_set_option(state->sh->ldap, LDAP_OPT_TIMEOUT, &tv);
if (lret != LDAP_OPT_SUCCESS) {
DEBUG(1, ("Failed to set default timeout to %d\n",
- opts->opt_timeout));
+ sdap_go_get_int(opts->basic, SDAP_OPT_TIMEOUT)));
goto fail;
}
@@ -766,7 +767,7 @@ struct tevent_req *sdap_auth_send(TALLOC_CTX *memctx,
struct sdap_handle *sh,
const char *user_dn,
const char *authtok_type,
- const char *password)
+ struct sdap_blob authtok)
{
struct tevent_req *req, *subreq;
struct sdap_auth_state *state;
@@ -780,13 +781,8 @@ struct tevent_req *sdap_auth_send(TALLOC_CTX *memctx,
if (!req) return NULL;
state->user_dn = user_dn;
- if (password) {
- state->pw.bv_val = discard_const(password);
- state->pw.bv_len = strlen(password);
- } else {
- state->pw.bv_val = NULL;
- state->pw.bv_len = 0;
- }
+ state->pw.bv_val = (char *)authtok.data;
+ state->pw.bv_len = authtok.length;
subreq = simple_bind_send(state, ev, sh, user_dn, &state->pw);
if (!subreq) {
@@ -1020,7 +1016,7 @@ static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
ret = ENOMEM;
goto fail;
}
- if (opts->force_upper_case_realm) {
+ if (sdap_go_get_bool(opts->basic, SDAP_FORCE_UPPER_CASE_REALM)) {
make_realm_upper_case(upn);
}
DEBUG(7, ("Adding user principle [%s] to attributes of [%s].\n",
@@ -1234,10 +1230,12 @@ static struct tevent_req *sdap_save_group_send(TALLOC_CTX *memctx,
if (!opts->users_base) {
opts->users_base = ldb_dn_new_fmt(opts,
sysdb_handle_get_ldb(state->handle), "%s",
- opts->basic[SDAP_USER_SEARCH_BASE].value);
+ sdap_go_get_string(opts->basic,
+ SDAP_USER_SEARCH_BASE));
if (!opts->users_base) {
DEBUG(1, ("Unable to get casefold Users Base DN from [%s]\n",
- opts->basic[SDAP_USER_SEARCH_BASE].value));
+ sdap_go_get_string(opts->basic,
+ SDAP_USER_SEARCH_BASE)));
DEBUG(1, ("Out of memory?!\n"));
ret = ENOMEM;
goto fail;
@@ -1246,10 +1244,12 @@ static struct tevent_req *sdap_save_group_send(TALLOC_CTX *memctx,
if (!opts->groups_base) {
opts->groups_base = ldb_dn_new_fmt(state->handle,
sysdb_handle_get_ldb(state->handle), "%s",
- opts->basic[SDAP_GROUP_SEARCH_BASE].value);
+ sdap_go_get_string(opts->basic,
+ SDAP_GROUP_SEARCH_BASE));
if (!opts->users_base) {
DEBUG(1, ("Unable to get casefold Users Base DN from [%s]\n",
- opts->basic[SDAP_USER_SEARCH_BASE].value));
+ sdap_go_get_string(opts->basic,
+ SDAP_GROUP_SEARCH_BASE)));
DEBUG(1, ("Out of memory?!\n"));
ret = ENOMEM;
goto fail;
@@ -1500,7 +1500,8 @@ static void sdap_get_users_transaction(struct tevent_req *subreq)
DEBUG(5, ("calling ldap_search_ext with [%s].\n", state->filter));
lret = ldap_search_ext(state->sh->ldap,
- state->opts->basic[SDAP_USER_SEARCH_BASE].value,
+ sdap_go_get_string(state->opts->basic,
+ SDAP_USER_SEARCH_BASE),
LDAP_SCOPE_SUBTREE, state->filter,
discard_const(state->attrs),
false, NULL, NULL, NULL, 0, &msgid);
@@ -1723,7 +1724,8 @@ static void sdap_get_groups_transaction(struct tevent_req *subreq)
}
lret = ldap_search_ext(state->sh->ldap,
- state->opts->basic[SDAP_GROUP_SEARCH_BASE].value,
+ sdap_go_get_string(state->opts->basic,
+ SDAP_GROUP_SEARCH_BASE),
LDAP_SCOPE_SUBTREE, state->filter,
discard_const(state->attrs),
false, NULL, NULL, NULL, 0, &msgid);
@@ -2053,7 +2055,8 @@ static void sdap_get_initgr_transaction(struct tevent_req *subreq)
DEBUG(5, ("calling ldap_search_ext with filter:[%s].\n", state->filter));
lret = ldap_search_ext(state->sh->ldap,
- state->opts->basic[SDAP_GROUP_SEARCH_BASE].value,
+ sdap_go_get_string(state->opts->basic,
+ SDAP_GROUP_SEARCH_BASE),
LDAP_SCOPE_SUBTREE, state->filter,
discard_const(state->grp_attrs),
false, NULL, NULL, NULL, 0, &msgid);
diff --git a/server/providers/ldap/sdap_async.h b/server/providers/ldap/sdap_async.h
index c9af750b..08b84d8b 100644
--- a/server/providers/ldap/sdap_async.h
+++ b/server/providers/ldap/sdap_async.h
@@ -59,7 +59,7 @@ struct tevent_req *sdap_auth_send(TALLOC_CTX *memctx,
struct sdap_handle *sh,
const char *user_dn,
const char *authtok_type,
- const char *password);
+ struct sdap_blob authtok);
int sdap_auth_recv(struct tevent_req *req, enum sdap_result *result);
struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,