The branch, master has been updated via a5cd278f6fa8f9d79d727b978ab8b6b78956dc4c (commit) via bfd82e49791a91c20e581dacd6ba8fa43b9efce6 (commit) via 5742ed128df90db400ff825bba7a939dadac8c30 (commit) via f6ce7e062547a788425d683e75a517a32c235bd0 (commit) via 98fb2a18f9d805a16514f24a5a0d87aa4a3573ff (commit) via bc1e93cc80874dd89ade863e38effda80a99fd47 (commit) via f169772d9398218d7ef2d9586f254fa4c59fbff0 (commit) via 8666e79f8fc3fd05fabefeeadc2bd6a2a6f1c18a (commit) via b8322ec2b23f60379cbecaf68c0ce8f254611d41 (commit) via 1c778aa19a345a813942e1502539b1503b2085bd (commit) from 077808f91610e70c2105b837a2704842191d1e3c (commit)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit a5cd278f6fa8f9d79d727b978ab8b6b78956dc4c Author: Volker Lendecke <v...@samba.org> Date: Sat Jul 4 12:26:08 2009 +0200 pdb_ads: For cached samu entries, priv is NULL We have to recreate the priv entry on demand. This needs fixing in passdb... :-) commit bfd82e49791a91c20e581dacd6ba8fa43b9efce6 Author: Volker Lendecke <v...@samba.org> Date: Sat Jul 4 11:09:42 2009 +0200 Add pdb_ads_get_domain_info commit 5742ed128df90db400ff825bba7a939dadac8c30 Author: Volker Lendecke <v...@samba.org> Date: Sat Jul 4 10:35:21 2009 +0200 Fix some warnings commit f6ce7e062547a788425d683e75a517a32c235bd0 Author: Volker Lendecke <v...@samba.org> Date: Tue Jun 30 10:39:04 2009 +0200 pdb_ads: Use tldap_fetch_rootdse in pdb_ads_connect commit 98fb2a18f9d805a16514f24a5a0d87aa4a3573ff Author: Volker Lendecke <v...@samba.org> Date: Mon Jun 29 22:28:19 2009 +0200 pdb_ads: Fetch the domain GUID commit bc1e93cc80874dd89ade863e38effda80a99fd47 Author: Volker Lendecke <v...@samba.org> Date: Mon Jun 29 22:11:23 2009 +0200 Add tldap_pull_guid commit f169772d9398218d7ef2d9586f254fa4c59fbff0 Author: Volker Lendecke <v...@samba.org> Date: Sun Jun 28 23:07:00 2009 +0200 Handle LSA_POLICY_INFO_DNS commit 8666e79f8fc3fd05fabefeeadc2bd6a2a6f1c18a Author: Volker Lendecke <v...@samba.org> Date: Sun Jun 28 22:29:06 2009 +0200 Implement QueryInfoPolicy2 similar to s4: Make it the same as QueryInfoPolicy Don't reply to it for non-pdb-ads to keep up our old behaviour commit b8322ec2b23f60379cbecaf68c0ce8f254611d41 Author: Volker Lendecke <v...@samba.org> Date: Sat Jul 4 11:12:33 2009 +0200 Add pdb_get_domain_info commit 1c778aa19a345a813942e1502539b1503b2085bd Author: Volker Lendecke <v...@samba.org> Date: Sun Jun 28 17:43:48 2009 +0200 Make pdb_ads return an additional flag ----------------------------------------------------------------------- Summary of changes: lib/talloc/talloc.c | 5 +- source3/include/passdb.h | 12 ++ source3/include/proto.h | 1 + source3/include/tldap_util.h | 2 + source3/lib/tldap_util.c | 11 ++ source3/passdb/pdb_ads.c | 229 +++++++++++++++++++++++++-------------- source3/passdb/pdb_interface.c | 13 +++ source3/rpc_server/srv_lsa_nt.c | 44 +++++++- 8 files changed, 233 insertions(+), 84 deletions(-) Changeset truncated at 500 lines: diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c index 8ccebe2..0126567 100644 --- a/lib/talloc/talloc.c +++ b/lib/talloc/talloc.c @@ -723,7 +723,7 @@ void *talloc_reparent(const void *old_parent, const void *new_parent, const void if (_talloc_steal_internal(new_parent, h) != h) { return NULL; } - return ptr; + return (void *)ptr; } } @@ -1183,7 +1183,7 @@ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *n void *_talloc_move(const void *new_ctx, const void *_pptr) { const void **pptr = discard_const_p(const void *,_pptr); - void *ret = talloc_steal(new_ctx, *pptr); + void *ret = talloc_steal(new_ctx, (void *)*pptr); (*pptr) = NULL; return ret; } @@ -1905,6 +1905,7 @@ void *_talloc_steal(const void *new_ctx, const void *ptr) } #undef talloc_free +int talloc_free(void *ptr); int talloc_free(void *ptr) { return _talloc_free_internal(ptr); diff --git a/source3/include/passdb.h b/source3/include/passdb.h index dadb227..c288015 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -197,7 +197,16 @@ struct pdb_search { void (*search_end)(struct pdb_search *search); }; +struct pdb_domain_info { + char *name; + char *dns_domain; + char *dns_forest; + struct dom_sid sid; + struct GUID guid; +}; + #define PDB_CAP_STORE_RIDS 0x0001 +#define PDB_CAP_ADS 0x0002 /***************************************************************** Functions to be implemented by the new (v2) passdb API @@ -223,6 +232,9 @@ struct pdb_methods { const char *name; /* What name got this module */ + struct pdb_domain_info *(*get_domain_info)(struct pdb_methods *, + TALLOC_CTX *mem_ctx); + NTSTATUS (*getsampwnam)(struct pdb_methods *, struct samu *sam_acct, const char *username); NTSTATUS (*getsampwsid)(struct pdb_methods *, struct samu *sam_acct, const DOM_SID *sid); diff --git a/source3/include/proto.h b/source3/include/proto.h index 7f4907c..955a5a0 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -4531,6 +4531,7 @@ NTSTATUS smb_register_passdb(int version, const char *name, pdb_init_function in struct pdb_init_function_entry *pdb_find_backend_entry(const char *name); struct event_context *pdb_get_event_context(void); NTSTATUS make_pdb_method_name(struct pdb_methods **methods, const char *selected); +struct pdb_domain_info *pdb_get_domain_info(TALLOC_CTX *mem_ctx); bool pdb_getsampwnam(struct samu *sam_acct, const char *username) ; bool guest_user_info( struct samu *user ); bool pdb_getsampwsid(struct samu *sam_acct, const DOM_SID *sid) ; diff --git a/source3/include/tldap_util.h b/source3/include/tldap_util.h index f257afc..2e0da85 100644 --- a/source3/include/tldap_util.h +++ b/source3/include/tldap_util.h @@ -31,6 +31,8 @@ char *tldap_talloc_single_attribute(struct tldap_message *msg, TALLOC_CTX *mem_ctx); bool tldap_pull_binsid(struct tldap_message *msg, const char *attribute, struct dom_sid *sid); +bool tldap_pull_guid(struct tldap_message *msg, const char *attribute, + struct GUID *guid); bool tldap_add_mod_blobs(TALLOC_CTX *mem_ctx, struct tldap_mod **pmods, int mod_op, const char *attrib, int num_values, DATA_BLOB *values); diff --git a/source3/lib/tldap_util.c b/source3/lib/tldap_util.c index 73ce854..f9f54aa 100644 --- a/source3/lib/tldap_util.c +++ b/source3/lib/tldap_util.c @@ -91,6 +91,17 @@ bool tldap_pull_binsid(struct tldap_message *msg, const char *attribute, return sid_parse((char *)val.data, val.length, sid); } +bool tldap_pull_guid(struct tldap_message *msg, const char *attribute, + struct GUID *guid) +{ + DATA_BLOB val; + + if (!tldap_get_single_valueblob(msg, attribute, &val)) { + return false; + } + return NT_STATUS_IS_OK(GUID_from_data_blob(&val, guid)); +} + static bool tldap_add_blob_vals(TALLOC_CTX *mem_ctx, struct tldap_mod *mod, int num_newvals, DATA_BLOB *newvals) { diff --git a/source3/passdb/pdb_ads.c b/source3/passdb/pdb_ads.c index be4b4b2..eec6372 100644 --- a/source3/passdb/pdb_ads.c +++ b/source3/passdb/pdb_ads.c @@ -23,11 +23,17 @@ struct pdb_ads_state { struct sockaddr_un socket_address; struct tldap_context *ld; struct dom_sid domainsid; + struct GUID domainguid; char *domaindn; char *configdn; char *netbiosname; }; +struct pdb_ads_samu_private { + char *dn; + struct tldap_message *ldapmsg; +}; + static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m, struct samu *sam_acct, const DOM_SID *sid); @@ -44,6 +50,10 @@ static int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base, int attrsonly, TALLOC_CTX *mem_ctx, struct tldap_message ***res, const char *fmt, ...); +static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state, + const char *filter, + TALLOC_CTX *mem_ctx, + struct pdb_ads_samu_private **presult); static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr, time_t *ptime) @@ -64,42 +74,73 @@ static gid_t pdb_ads_sid2gid(const struct dom_sid *sid) return rid; } -struct pdb_ads_samu_private { - char *dn; - struct tldap_message *ldapmsg; -}; +static char *pdb_ads_domaindn2dns(TALLOC_CTX *mem_ctx, char *dn) +{ + char *result, *p; + + result = talloc_string_sub2(mem_ctx, dn, "DC=", "", false, false, + true); + if (result == NULL) { + return NULL; + } + + while ((p = strchr_m(result, ',')) != NULL) { + *p = '.'; + } + + return result; +} -static struct samu *pdb_ads_init_guest(TALLOC_CTX *mem_ctx, - struct pdb_methods *m) +static struct pdb_domain_info *pdb_ads_get_domain_info( + struct pdb_methods *m, TALLOC_CTX *mem_ctx) { struct pdb_ads_state *state = talloc_get_type_abort( m->private_data, struct pdb_ads_state); - struct dom_sid guest_sid; - struct samu *guest; - NTSTATUS status; + struct pdb_domain_info *info; + struct tldap_message *rootdse; + char *tmp; - sid_compose(&guest_sid, &state->domainsid, DOMAIN_USER_RID_GUEST); - - guest = samu_new(mem_ctx); - if (guest == NULL) { + info = talloc(mem_ctx, struct pdb_domain_info); + if (info == NULL) { return NULL; } + info->name = talloc_strdup(info, state->netbiosname); + if (info->name == NULL) { + goto fail; + } + info->dns_domain = pdb_ads_domaindn2dns(info, state->domaindn); + if (info->dns_domain == NULL) { + goto fail; + } - status = pdb_ads_getsampwsid(m, guest, &guest_sid); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("Could not init guest account: %s\n", - nt_errstr(status))); - TALLOC_FREE(guest); - return NULL; + rootdse = tldap_rootdse(state->ld); + tmp = tldap_talloc_single_attribute(rootdse, "rootDomainNamingContext", + talloc_tos()); + if (tmp == NULL) { + goto fail; } - return guest; + info->dns_forest = pdb_ads_domaindn2dns(info, tmp); + TALLOC_FREE(tmp); + if (info->dns_forest == NULL) { + goto fail; + } + info->sid = state->domainsid; + info->guid = state->domainguid; + return info; + +fail: + TALLOC_FREE(info); + return NULL; } static struct pdb_ads_samu_private *pdb_ads_get_samu_private( struct pdb_methods *m, struct samu *sam) { + struct pdb_ads_state *state = talloc_get_type_abort( + m->private_data, struct pdb_ads_state); struct pdb_ads_samu_private *result; - uint32_t rid; + char *sidstr, *filter; + NTSTATUS status; result = (struct pdb_ads_samu_private *) pdb_get_backend_private_data(sam, m); @@ -109,56 +150,42 @@ static struct pdb_ads_samu_private *pdb_ads_get_samu_private( result, struct pdb_ads_samu_private); } - /* - * This is now a weirdness of the passdb API. For the guest user we - * are not asked first. - */ - sid_peek_rid(pdb_get_user_sid(sam), &rid); + sidstr = sid_binstring(talloc_tos(), pdb_get_user_sid(sam)); + if (sidstr == NULL) { + return NULL; + } - if (rid == DOMAIN_USER_RID_GUEST) { - struct samu *guest = pdb_ads_init_guest(talloc_tos(), m); + filter = talloc_asprintf( + talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr); + TALLOC_FREE(sidstr); + if (filter == NULL) { + return NULL; + } - if (guest == NULL) { - return NULL; - } - result = talloc_get_type_abort( - pdb_get_backend_private_data(guest, m), - struct pdb_ads_samu_private); - pdb_set_backend_private_data( - sam, talloc_move(sam, &result), NULL, m, PDB_SET); - TALLOC_FREE(guest); - return talloc_get_type_abort( - pdb_get_backend_private_data(sam, m), - struct pdb_ads_samu_private); + status = pdb_ads_getsamupriv(state, filter, sam, &result); + TALLOC_FREE(filter); + if (!NT_STATUS_IS_OK(status)) { + return NULL; } - return NULL; + return result; } -static NTSTATUS pdb_ads_init_sam_from_ads(struct pdb_methods *m, - struct samu *sam, - struct tldap_message *entry) +static NTSTATUS pdb_ads_init_sam_from_priv(struct pdb_methods *m, + struct samu *sam, + struct pdb_ads_samu_private *priv) { struct pdb_ads_state *state = talloc_get_type_abort( m->private_data, struct pdb_ads_state); TALLOC_CTX *frame = talloc_stackframe(); - struct pdb_ads_samu_private *priv; NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION; + struct tldap_message *entry = priv->ldapmsg; char *str; time_t tmp_time; struct dom_sid sid; uint64_t n; DATA_BLOB blob; - priv = talloc(sam, struct pdb_ads_samu_private); - if (priv == NULL) { - return NT_STATUS_NO_MEMORY; - } - if (!tldap_entry_dn(entry, &priv->dn)) { - TALLOC_FREE(priv); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - str = tldap_talloc_single_attribute(entry, "samAccountName", sam); if (str == NULL) { DEBUG(10, ("no samAccountName\n")); @@ -248,10 +275,6 @@ static NTSTATUS pdb_ads_init_sam_from_ads(struct pdb_methods *m, pdb_set_group_sid(sam, &sid, PDB_SET); } - - priv->ldapmsg = talloc_move(priv, &entry); - pdb_set_backend_private_data(sam, priv, NULL, m, PDB_SET); - status = NT_STATUS_OK; fail: TALLOC_FREE(frame); @@ -308,10 +331,10 @@ static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state, return ret; } -static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m, - struct pdb_ads_state *state, - struct samu *sam_acct, - const char *filter) +static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state, + const char *filter, + TALLOC_CTX *mem_ctx, + struct pdb_ads_samu_private **presult) { const char * attrs[] = { "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires", @@ -323,23 +346,66 @@ static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m, "unicodePwd", "dBCSPwd" }; struct tldap_message **users; int rc, count; + struct pdb_ads_samu_private *result; + + result = talloc(mem_ctx, struct pdb_ads_samu_private); + if (result == NULL) { + return NT_STATUS_NO_MEMORY; + } rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB, - attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), + attrs, ARRAY_SIZE(attrs), 0, result, &users, "%s", filter); if (rc != TLDAP_SUCCESS) { DEBUG(10, ("ldap_search failed %s\n", tldap_errstr(debug_ctx(), state->ld, rc))); + TALLOC_FREE(result); return NT_STATUS_LDAP(rc); } count = talloc_array_length(users); if (count != 1) { DEBUG(10, ("Expected 1 user, got %d\n", count)); + TALLOC_FREE(result); return NT_STATUS_INTERNAL_DB_CORRUPTION; } - return pdb_ads_init_sam_from_ads(m, sam_acct, users[0]); + result->ldapmsg = users[0]; + if (!tldap_entry_dn(result->ldapmsg, &result->dn)) { + DEBUG(10, ("Could not extract dn\n")); + TALLOC_FREE(result); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + *presult = result; + return NT_STATUS_OK; +} + +static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m, + struct pdb_ads_state *state, + struct samu *sam_acct, + const char *filter) +{ + struct pdb_ads_samu_private *priv; + NTSTATUS status; + + status = pdb_ads_getsamupriv(state, filter, sam_acct, &priv); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("pdb_ads_getsamupriv failed: %s\n", + nt_errstr(status))); + return status; + } + + status = pdb_ads_init_sam_from_priv(m, sam_acct, priv); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("pdb_ads_init_sam_from_priv failed: %s\n", + nt_errstr(status))); + TALLOC_FREE(priv); + return status; + } + + pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET); + return NT_STATUS_OK; } static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m, @@ -1922,7 +1988,7 @@ static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid, static uint32_t pdb_ads_capabilities(struct pdb_methods *m) { - return PDB_CAP_STORE_RIDS; + return PDB_CAP_STORE_RIDS | PDB_CAP_ADS; } static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid) @@ -1962,6 +2028,7 @@ static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m, static void pdb_ads_init_methods(struct pdb_methods *m) { m->name = "ads"; + m->get_domain_info = pdb_ads_get_domain_info; m->getsampwnam = pdb_ads_getsampwnam; m->getsampwsid = pdb_ads_getsampwsid; m->create_user = pdb_ads_create_user; @@ -2126,11 +2193,10 @@ int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base, static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state, const char *location) { - const char *rootdse_attrs[2] = { - "defaultNamingContext", "configurationNamingContext" }; - const char *domain_attrs[1] = { "objectSid" }; + const char *domain_attrs[2] = { "objectSid", "objectGUID" }; const char *ncname_attrs[1] = { "netbiosname" }; - struct tldap_message **rootdse, **domain, **ncname; + struct tldap_context *ld; + struct tldap_message *rootdse, **domain, **ncname; TALLOC_CTX *frame = talloc_stackframe(); NTSTATUS status; int num_domains; @@ -2141,23 +2207,23 @@ static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state, strncpy(state->socket_address.sun_path, location, sizeof(state->socket_address.sun_path) - 1); - rc = pdb_ads_search_fmt( - state, "", TLDAP_SCOPE_BASE, - rootdse_attrs, ARRAY_SIZE(rootdse_attrs), 0, - talloc_tos(), &rootdse, "(objectclass=*)"); + ld = pdb_ads_ld(state); + if (ld == NULL) { + status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + goto done; + } + + rc = tldap_fetch_rootdse(ld); if (rc != TLDAP_SUCCESS) { DEBUG(10, ("Could not retrieve rootdse: %s\n", tldap_errstr(debug_ctx(), state->ld, rc))); status = NT_STATUS_LDAP(rc); goto done; } - if (talloc_array_length(rootdse) != 1) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto done; - } + rootdse = tldap_rootdse(state->ld); state->domaindn = tldap_talloc_single_attribute( - rootdse[0], "defaultNamingContext", state); + rootdse, "defaultNamingContext", state); if (state->domaindn == NULL) { DEBUG(10, ("Could not get defaultNamingContext\n")); status = NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -2166,7 +2232,7 @@ static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state, DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn)); state->configdn = tldap_talloc_single_attribute( - rootdse[0], "configurationNamingContext", state); + rootdse, "configurationNamingContext", state); if (state->domaindn == NULL) { DEBUG(10, ("Could not get configurationNamingContext\n")); status = NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -2199,6 +2265,11 @@ static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state, status = NT_STATUS_INTERNAL_DB_CORRUPTION; goto done; } + if (!tldap_pull_guid(domain[0], "objectGUID", &state->domainguid)) { + DEBUG(10, ("Could not retrieve domain GUID\n")); + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto done; + } DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid))); /* diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index a72409e..465a6bf 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -210,6 +210,12 @@ static struct pdb_methods *pdb_get_methods(void) return pdb_get_methods_reload(False); } -- Samba Shared Repository