From a1827a1deba04e0b4b2a508dc4e4e66603a46d16 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 14 Dec 2005 07:22:25 +0000 Subject: r12227: I realised that I wasn't yet seeing authenticated LDAP for the ldb backend. The idea is that every time we open an LDB, we can provide a session_info and/or credentials. This would allow any ldb to be remote to LDAP. We should also support provisioning to a authenticated ldap server. (They are separate so we can say authenticate as foo for remote, but here we just want a token of SYSTEM). Andrew Bartlett (This used to be commit ae2f3a64ee0b07575624120db45299c65204210b) --- source4/auth/auth_util.c | 2 -- source4/auth/credentials/credentials.c | 4 +++ source4/auth/credentials/credentials_files.c | 39 +++++++++++++++++++++++----- source4/auth/gensec/schannel_state.c | 3 ++- source4/dsdb/samdb/samdb.c | 8 +++--- source4/ldap_server/ldap_simple_ldb.c | 7 ++--- source4/lib/db_wrap.c | 13 ++++++++++ source4/lib/ldb/ldb_ildap/ldb_ildap.c | 6 ++--- source4/lib/registry/reg_backend_ldb.c | 3 ++- source4/libnet/libnet_join.c | 7 ++--- source4/nbt_server/wins/winsdb.c | 3 ++- source4/ntptr/simple_ldb/ntptr_simple_ldb.c | 3 ++- source4/passdb/secrets.c | 6 +++-- source4/scripting/ejs/smbcalls_auth.c | 20 +++++++++++--- source4/scripting/ejs/smbcalls_ldb.c | 14 +++++++++- source4/scripting/libjs/provision.js | 18 ++++++------- 16 files changed, 113 insertions(+), 43 deletions(-) diff --git a/source4/auth/auth_util.c b/source4/auth/auth_util.c index 5a5e779bf1..dbedde9190 100644 --- a/source4/auth/auth_util.c +++ b/source4/auth/auth_util.c @@ -604,8 +604,6 @@ NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx, } cli_credentials_set_conf(session_info->credentials); - /* set anonymous as the fallback, if the machine account won't work */ - cli_credentials_set_anonymous(session_info->credentials); cli_credentials_set_machine_account_pending(session_info->credentials); *_session_info = session_info; diff --git a/source4/auth/credentials/credentials.c b/source4/auth/credentials/credentials.c index 22b7772182..0e37fdc4a6 100644 --- a/source4/auth/credentials/credentials.c +++ b/source4/auth/credentials/credentials.c @@ -171,6 +171,10 @@ BOOL cli_credentials_set_principal_callback(struct cli_credentials *cred, BOOL cli_credentials_authentication_requested(struct cli_credentials *cred) { + if (cred->machine_account_pending) { + cli_credentials_set_machine_account(cred); + } + if (cred->principal_obtained >= CRED_SPECIFIED) { return True; } diff --git a/source4/auth/credentials/credentials_files.c b/source4/auth/credentials/credentials_files.c index 6b3c77c4e3..1f7a7cf435 100644 --- a/source4/auth/credentials/credentials_files.c +++ b/source4/auth/credentials/credentials_files.c @@ -208,6 +208,8 @@ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred, /* Local secrets are stored in secrets.ldb */ ldb = secrets_db_connect(mem_ctx); if (!ldb) { + /* set anonymous as the fallback, if the machine account won't work */ + cli_credentials_set_anonymous(cred); DEBUG(1, ("Could not open secrets.ldb\n")); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } @@ -220,11 +222,15 @@ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred, if (ldb_ret == 0) { DEBUG(1, ("Could not find entry to match filter: %s\n", filter)); + /* set anonymous as the fallback, if the machine account won't work */ + cli_credentials_set_anonymous(cred); talloc_free(mem_ctx); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } else if (ldb_ret != 1) { DEBUG(1, ("Found more than one (%d) entry to match filter: %s\n", ldb_ret, filter)); + /* set anonymous as the fallback, if the machine account won't work */ + cli_credentials_set_anonymous(cred); talloc_free(mem_ctx); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } @@ -237,6 +243,8 @@ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred, if (!machine_account) { DEBUG(1, ("Could not find 'samAccountName' in join record to domain: %s\n", cli_credentials_get_domain(cred))); + /* set anonymous as the fallback, if the machine account won't work */ + cli_credentials_set_anonymous(cred); talloc_free(mem_ctx); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } @@ -262,6 +270,10 @@ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred, DEBUG(1, ("Could not find 'secret' in join record to domain: %s\n", cli_credentials_get_domain(cred))); + + /* set anonymous as the fallback, if the machine account won't work */ + cli_credentials_set_anonymous(cred); + talloc_free(mem_ctx); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } @@ -312,7 +324,12 @@ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred, */ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred) { - char *filter = talloc_asprintf(cred, SECRETS_PRIMARY_DOMAIN_FILTER, + char *filter; + /* Bleh, nasty recursion issues: We are setting a machine + * account here, so we don't want the 'pending' flag around + * any more */ + cred->machine_account_pending = False; + filter = talloc_asprintf(cred, SECRETS_PRIMARY_DOMAIN_FILTER, cli_credentials_get_domain(cred)); return cli_credentials_set_secrets(cred, SECRETS_PRIMARY_DOMAIN_DN, filter); @@ -326,7 +343,12 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred) */ NTSTATUS cli_credentials_set_krbtgt(struct cli_credentials *cred) { - char *filter = talloc_asprintf(cred, SECRETS_KRBTGT_SEARCH, + char *filter; + /* Bleh, nasty recursion issues: We are setting a machine + * account here, so we don't want the 'pending' flag around + * any more */ + cred->machine_account_pending = False; + filter = talloc_asprintf(cred, SECRETS_KRBTGT_SEARCH, cli_credentials_get_realm(cred), cli_credentials_get_domain(cred)); return cli_credentials_set_secrets(cred, SECRETS_PRINCIPALS_DN, @@ -342,10 +364,15 @@ NTSTATUS cli_credentials_set_krbtgt(struct cli_credentials *cred) NTSTATUS cli_credentials_set_stored_principal(struct cli_credentials *cred, const char *serviceprincipal) { - char *filter = talloc_asprintf(cred, SECRETS_PRINCIPAL_SEARCH, - cli_credentials_get_realm(cred), - cli_credentials_get_domain(cred), - serviceprincipal); + char *filter; + /* Bleh, nasty recursion issues: We are setting a machine + * account here, so we don't want the 'pending' flag around + * any more */ + cred->machine_account_pending = False; + filter = talloc_asprintf(cred, SECRETS_PRINCIPAL_SEARCH, + cli_credentials_get_realm(cred), + cli_credentials_get_domain(cred), + serviceprincipal); return cli_credentials_set_secrets(cred, SECRETS_PRINCIPALS_DN, filter); } diff --git a/source4/auth/gensec/schannel_state.c b/source4/auth/gensec/schannel_state.c index 83776c4187..8f9a8ef6b5 100644 --- a/source4/auth/gensec/schannel_state.c +++ b/source4/auth/gensec/schannel_state.c @@ -47,7 +47,8 @@ static struct ldb_context *schannel_db_connect(TALLOC_CTX *mem_ctx) existed = file_exists(path); - ldb = ldb_wrap_connect(mem_ctx, path, LDB_FLG_NOSYNC, NULL); + ldb = ldb_wrap_connect(mem_ctx, path, system_session(mem_ctx), + NULL, LDB_FLG_NOSYNC, NULL); talloc_free(path); if (!ldb) { return NULL; diff --git a/source4/dsdb/samdb/samdb.c b/source4/dsdb/samdb/samdb.c index 18e482c9d3..c5eba8ae84 100644 --- a/source4/dsdb/samdb/samdb.c +++ b/source4/dsdb/samdb/samdb.c @@ -33,11 +33,13 @@ connect to the SAM database return an opaque context pointer on success, or NULL on failure */ -struct ldb_context *samdb_connect(TALLOC_CTX *mem_ctx, struct auth_session_info *session_info) +struct ldb_context *samdb_connect(TALLOC_CTX *mem_ctx, + struct auth_session_info *session_info) { struct ldb_context *ldb; - ldb = ldb_wrap_connect(mem_ctx, lp_sam_url(), 0, NULL); - if (ldb_set_opaque(ldb, "sessionInfo", session_info)) { + ldb = ldb_wrap_connect(mem_ctx, lp_sam_url(), session_info, + NULL, 0, NULL); + if (!ldb) { return NULL; } return ldb; diff --git a/source4/ldap_server/ldap_simple_ldb.c b/source4/ldap_server/ldap_simple_ldb.c index b9ef085002..07d85f634f 100644 --- a/source4/ldap_server/ldap_simple_ldb.c +++ b/source4/ldap_server/ldap_simple_ldb.c @@ -62,15 +62,12 @@ NTSTATUS sldb_Init(struct ldapsrv_partition *partition, struct ldapsrv_connectio url = lp_parm_string(-1, "ldapsrv", "samdb"); if (url) { - ldb = ldb_wrap_connect(mem_ctx, url, 0, NULL); + ldb = ldb_wrap_connect(mem_ctx, url, conn->session_info, + NULL, 0, NULL); if (ldb == NULL) { talloc_free(mem_ctx); return NT_STATUS_INTERNAL_DB_CORRUPTION; } - if (ldb_set_opaque(ldb, "sessionInfo", conn->session_info)) { - talloc_free(mem_ctx); - return NT_STATUS_NO_MEMORY; - } talloc_steal(partition, ldb); partition->private = ldb; talloc_free(mem_ctx); diff --git a/source4/lib/db_wrap.c b/source4/lib/db_wrap.c index 974490f8b2..e070d4eb14 100644 --- a/source4/lib/db_wrap.c +++ b/source4/lib/db_wrap.c @@ -61,6 +61,8 @@ static void ldb_wrap_debug(void *context, enum ldb_debug_level level, */ struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx, const char *url, + struct auth_session_info *session_info, + struct cli_credentials *credentials, unsigned int flags, const char *options[]) { @@ -80,6 +82,17 @@ struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx, ev = event_context_find(ldb); if (ldb_set_opaque(ldb, "EventContext", ev)) { + talloc_free(ldb); + return NULL; + } + + if (ldb_set_opaque(ldb, "sessionInfo", session_info)) { + talloc_free(ldb); + return NULL; + } + + if (ldb_set_opaque(ldb, "credentials", credentials)) { + talloc_free(ldb); return NULL; } diff --git a/source4/lib/ldb/ldb_ildap/ldb_ildap.c b/source4/lib/ldb/ldb_ildap/ldb_ildap.c index e195ec24aa..582513df6f 100644 --- a/source4/lib/ldb/ldb_ildap/ldb_ildap.c +++ b/source4/lib/ldb/ldb_ildap/ldb_ildap.c @@ -224,7 +224,7 @@ static int ildb_search_bytree(struct ldb_module *module, const struct ldb_dn *ba msg = ldapres[i]; search = &msg->r.SearchResultEntry; - (*res)->msgs[i] = talloc(*res, struct ldb_message); + (*res)->msgs[i] = talloc((*res)->msgs, struct ldb_message); if (!(*res)->msgs[i]) { goto failed; } @@ -504,10 +504,8 @@ int ildb_connect(struct ldb_context *ldb, const char *url, creds = talloc_get_type(ldb_get_opaque(ldb, "credentials"), struct cli_credentials); if (creds == NULL) { struct auth_session_info *session_info = talloc_get_type(ldb_get_opaque(ldb, "sessionInfo"), struct auth_session_info); - if (session_info && session_info->credentials) { + if (session_info) { creds = session_info->credentials; - } else { - creds = cmdline_credentials; } } diff --git a/source4/lib/registry/reg_backend_ldb.c b/source4/lib/registry/reg_backend_ldb.c index f1c3187aa5..6c668d7b48 100644 --- a/source4/lib/registry/reg_backend_ldb.c +++ b/source4/lib/registry/reg_backend_ldb.c @@ -262,7 +262,8 @@ static WERROR ldb_open_hive(struct registry_hive *hive, struct registry_key **k) struct ldb_context *wrap; if (!hive->location) return WERR_INVALID_PARAM; - wrap = ldb_wrap_connect(hive, hive->location, 0, NULL); + /* TODO: Support remoting with credentials and ACLs with session tokens */ + wrap = ldb_wrap_connect(hive, hive->location, NULL, NULL, 0, NULL); if(!wrap) { DEBUG(1, ("ldb_open_hive: unable to connect\n")); diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 1530a9f6a8..08bd9aa680 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -396,7 +396,8 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J return NT_STATUS_NO_MEMORY; } - remote_ldb = ldb_wrap_connect(tmp_ctx, remote_ldb_url, 0, NULL); + remote_ldb = ldb_wrap_connect(tmp_ctx, remote_ldb_url, + NULL, ctx->cred, 0, NULL); if (!remote_ldb) { r->out.error_string = NULL; talloc_free(tmp_ctx); @@ -1131,7 +1132,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, } } - account_name = talloc_asprintf(tmp_mem, "%s$", netbios_name); + account_name = talloc_asprintf(tmp_mem, "%s$", netbios_name); if (!account_name) { r->out.error_string = NULL; talloc_free(tmp_mem); @@ -1142,7 +1143,7 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, * Local secrets are stored in secrets.ldb * open it to make sure we can write the info into it after the join */ - ldb = secrets_db_connect(tmp_mem); + ldb = secrets_db_connect(tmp_mem); if (!ldb) { r->out.error_string = talloc_asprintf(mem_ctx, diff --git a/source4/nbt_server/wins/winsdb.c b/source4/nbt_server/wins/winsdb.c index e33c0747c9..3a73b9897c 100644 --- a/source4/nbt_server/wins/winsdb.c +++ b/source4/nbt_server/wins/winsdb.c @@ -677,5 +677,6 @@ failed: struct ldb_context *winsdb_connect(TALLOC_CTX *mem_ctx) { - return ldb_wrap_connect(mem_ctx, lp_wins_url(), 0, NULL); + return ldb_wrap_connect(mem_ctx, lp_wins_url(), system_session(mem_ctx), + NULL, 0, NULL); } diff --git a/source4/ntptr/simple_ldb/ntptr_simple_ldb.c b/source4/ntptr/simple_ldb/ntptr_simple_ldb.c index 78280e294b..ebd6eb4f46 100644 --- a/source4/ntptr/simple_ldb/ntptr_simple_ldb.c +++ b/source4/ntptr/simple_ldb/ntptr_simple_ldb.c @@ -40,7 +40,8 @@ */ static struct ldb_context *sptr_db_connect(TALLOC_CTX *mem_ctx) { - return ldb_wrap_connect(mem_ctx, lp_spoolss_url(), 0, NULL); + return ldb_wrap_connect(mem_ctx, lp_spoolss_url(), system_session(mem_ctx), + NULL, 0, NULL); } static int sptr_db_search(struct ldb_context *ldb, diff --git a/source4/passdb/secrets.c b/source4/passdb/secrets.c index 5797007975..9673b89d2c 100644 --- a/source4/passdb/secrets.c +++ b/source4/passdb/secrets.c @@ -106,8 +106,10 @@ struct ldb_context *secrets_db_connect(TALLOC_CTX *mem_ctx) } existed = file_exists(path); - - ldb = ldb_wrap_connect(mem_ctx, path, 0, NULL); + + /* Secrets.ldb *must* always be local. If we call for a + * system_session() we will recurse */ + ldb = ldb_wrap_connect(mem_ctx, path, NULL, NULL, 0, NULL); talloc_free(path); if (!ldb) { return NULL; diff --git a/source4/scripting/ejs/smbcalls_auth.c b/source4/scripting/ejs/smbcalls_auth.c index ba20332aaa..80089f75a7 100644 --- a/source4/scripting/ejs/smbcalls_auth.c +++ b/source4/scripting/ejs/smbcalls_auth.c @@ -26,12 +26,14 @@ #include "auth/auth.h" #include "scripting/ejs/smbcalls.h" -static int ejs_doauth(TALLOC_CTX *tmp_ctx, struct MprVar *auth, const char *username, +static int ejs_doauth(MprVarHandle eid, + TALLOC_CTX *tmp_ctx, struct MprVar *auth, const char *username, const char *password, const char *domain, const char *remote_host, const char *authtype) { struct auth_usersupplied_info *user_info = NULL; struct auth_serversupplied_info *server_info = NULL; + struct auth_session_info *session_info = NULL; struct auth_context *auth_context; const char *auth_types[] = { authtype, NULL }; NTSTATUS nt_status; @@ -76,11 +78,21 @@ static int ejs_doauth(TALLOC_CTX *tmp_ctx, struct MprVar *auth, const char *user nt_status = auth_check_password(auth_context, tmp_ctx, user_info, &server_info); if (!NT_STATUS_IS_OK(nt_status)) { - mprSetPropertyValue(auth, "result", mprCreateBoolVar(False)); mprSetPropertyValue(auth, "report", mprString("Login Failed")); + mprSetPropertyValue(auth, "result", mprCreateBoolVar(False)); + goto done; + } + + nt_status = auth_generate_session_info(tmp_ctx, server_info, &session_info); + if (!NT_STATUS_IS_OK(nt_status)) { + mprSetPropertyValue(auth, "report", mprString("Session Info generation failed")); + mprSetPropertyValue(auth, "result", mprCreateBoolVar(False)); goto done; } + talloc_steal(mprMemCtx(), session_info); + mprSetThisPtr(eid, "session_info", session_info); + mprSetPropertyValue(auth, "result", mprCreateBoolVar(server_info->authenticated)); mprSetPropertyValue(auth, "username", mprString(server_info->account_name)); mprSetPropertyValue(auth, "domain", mprString(server_info->domain_name)); @@ -138,9 +150,9 @@ static int ejs_userAuth(MprVarHandle eid, int argc, struct MprVar **argv) auth = mprObject("auth"); if (domain && (strcmp("System User", domain) == 0)) { - ejs_doauth(tmp_ctx, &auth, username, password, domain, remote_host, "unix"); + ejs_doauth(eid, tmp_ctx, &auth, username, password, domain, remote_host, "unix"); } else { - ejs_doauth(tmp_ctx, &auth, username, password, domain, remote_host, "sam"); + ejs_doauth(eid, tmp_ctx, &auth, username, password, domain, remote_host, "sam"); } mpr_Return(eid, auth); diff --git a/source4/scripting/ejs/smbcalls_ldb.c b/source4/scripting/ejs/smbcalls_ldb.c index d3db85db86..709ed27e5e 100644 --- a/source4/scripting/ejs/smbcalls_ldb.c +++ b/source4/scripting/ejs/smbcalls_ldb.c @@ -350,10 +350,16 @@ static int ejs_ldbModify(MprVarHandle eid, int argc, struct MprVar **argv) usage: ok = ldb.connect(dbfile); ok = ldb.connect(dbfile, "modules:modlist"); + + ldb.credentials or ldb.session_info may be setup first + */ static int ejs_ldbConnect(MprVarHandle eid, int argc, char **argv) { struct ldb_context *ldb; + struct auth_session_info *session_info; + struct cli_credentials *creds; + const char *dbfile; if (argc < 1) { @@ -361,9 +367,15 @@ static int ejs_ldbConnect(MprVarHandle eid, int argc, char **argv) return -1; } + session_info = mprGetThisPtr(eid, "session_info"); + + creds = mprGetThisPtr(eid, "credentials"); + dbfile = argv[0]; - ldb = ldb_wrap_connect(mprMemCtx(), dbfile, 0, (const char **)(argv+1)); + ldb = ldb_wrap_connect(mprMemCtx(), dbfile, + session_info, creds, + 0, (const char **)(argv+1)); if (ldb == NULL) { ejsSetErrorMsg(eid, "ldb.connect failed to open %s", dbfile); } diff --git a/source4/scripting/libjs/provision.js b/source4/scripting/libjs/provision.js index 0b6a31ae4f..aa4ea5bff8 100644 --- a/source4/scripting/libjs/provision.js +++ b/source4/scripting/libjs/provision.js @@ -280,6 +280,15 @@ function provision(subobj, message, blank, paths) setup_file("provision.smb.conf", paths.smbconf, subobj); lp.reload(); } + message("Setting up secrets.ldb\n"); + setup_ldb("secrets.ldif", paths.secrets, subobj); + message("Setting up DNS zone file\n"); + setup_file("provision.zone", + paths.dns, + subobj); + message("Setting up keytabs\n"); + var keytab_ok = credentials_update_all_keytabs(); + assert(keytab_ok); message("Setting up hklm.ldb\n"); setup_ldb("hklm.ldif", paths.hklm, subobj); message("Setting up sam.ldb attributes\n"); @@ -296,15 +305,6 @@ function provision(subobj, message, blank, paths) message("Setting up sam.ldb users and groups\n"); setup_ldb("provision_users.ldif", paths.samdb, subobj, data, false); } - message("Setting up secrets.ldb\n"); - setup_ldb("secrets.ldif", paths.secrets, subobj); - message("Setting up DNS zone file\n"); - setup_file("provision.zone", - paths.dns, - subobj); - message("Setting up keytabs\n"); - var keytab_ok = credentials_update_all_keytabs(); - assert(keytab_ok); } /* -- cgit