diff options
Diffstat (limited to 'source4/libnet')
-rw-r--r-- | source4/libnet/config.mk | 3 | ||||
-rw-r--r-- | source4/libnet/libnet.c | 3 | ||||
-rw-r--r-- | source4/libnet/libnet.h | 2 | ||||
-rw-r--r-- | source4/libnet/libnet_group.c | 250 | ||||
-rw-r--r-- | source4/libnet/libnet_group.h | 20 | ||||
-rw-r--r-- | source4/libnet/libnet_join.c | 2 | ||||
-rw-r--r-- | source4/libnet/libnet_lookup.c | 17 | ||||
-rw-r--r-- | source4/libnet/libnet_lookup.h | 2 | ||||
-rw-r--r-- | source4/libnet/libnet_samdump.c | 2 | ||||
-rw-r--r-- | source4/libnet/libnet_samdump_keytab.c | 8 | ||||
-rw-r--r-- | source4/libnet/libnet_site.c | 8 | ||||
-rw-r--r-- | source4/libnet/libnet_site.h | 1 | ||||
-rw-r--r-- | source4/libnet/libnet_vampire.c | 2 |
13 files changed, 298 insertions, 22 deletions
diff --git a/source4/libnet/config.mk b/source4/libnet/config.mk index ef0c7ff6ca..93d6a7251e 100644 --- a/source4/libnet/config.mk +++ b/source4/libnet/config.mk @@ -30,5 +30,4 @@ OBJ_FILES = \ userman.o \ groupman.o \ prereq_domain.o -PUBLIC_DEPENDENCIES = CREDENTIALS dcerpc dcerpc_samr RPC_NDR_LSA RPC_NDR_SRVSVC RPC_NDR_DRSUAPI LIBCLI_COMPOSITE LIBCLI_RESOLVE LIBCLI_FINDDCS LIBSAMBA3 LIBCLI_CLDAP LIBCLI_FINDDCS gensec_schannel -PRIVATE_DEPENDENCIES = CREDENTIALS_KRB5 +PUBLIC_DEPENDENCIES = CREDENTIALS dcerpc dcerpc_samr RPC_NDR_LSA RPC_NDR_SRVSVC RPC_NDR_DRSUAPI LIBCLI_COMPOSITE LIBCLI_RESOLVE LIBCLI_FINDDCS LIBSAMBA3 LIBCLI_CLDAP LIBCLI_FINDDCS gensec_schannel LIBCLI_AUTH LIBNDR diff --git a/source4/libnet/libnet.c b/source4/libnet/libnet.c index 5c483a757c..d1605bc17d 100644 --- a/source4/libnet/libnet.c +++ b/source4/libnet/libnet.c @@ -21,6 +21,7 @@ #include "libnet/libnet.h" #include "lib/events/events.h" #include "param/param.h" +#include "libcli/resolve/resolve.h" struct libnet_context *libnet_context_init(struct event_context *ev, struct loadparm_context *lp_ctx) @@ -45,7 +46,7 @@ struct libnet_context *libnet_context_init(struct event_context *ev, ctx->lp_ctx = lp_ctx; /* name resolution methods */ - ctx->name_res_methods = str_list_copy(ctx, lp_name_resolve_order(lp_ctx)); + ctx->resolve_ctx = lp_resolve_context(lp_ctx); /* connected services' params */ ZERO_STRUCT(ctx->samr); diff --git a/source4/libnet/libnet.h b/source4/libnet/libnet.h index 4f3acc6010..71ee8ef8e4 100644 --- a/source4/libnet/libnet.h +++ b/source4/libnet/libnet.h @@ -47,7 +47,7 @@ struct libnet_context { } lsa; /* name resolution methods */ - const char **name_res_methods; + struct resolve_context *resolve_ctx; struct event_context *event_ctx; diff --git a/source4/libnet/libnet_group.c b/source4/libnet/libnet_group.c index 39e5e7a4f9..c4d44eefe8 100644 --- a/source4/libnet/libnet_group.c +++ b/source4/libnet/libnet_group.c @@ -22,6 +22,10 @@ #include "libnet/libnet.h" #include "libcli/composite/composite.h" #include "librpc/gen_ndr/lsa.h" +#include "librpc/gen_ndr/ndr_lsa_c.h" +#include "librpc/gen_ndr/samr.h" +#include "librpc/gen_ndr/ndr_samr_c.h" +#include "libcli/security/security.h" struct group_info_state { @@ -230,3 +234,249 @@ NTSTATUS libnet_GroupInfo(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, io, NULL); return libnet_GroupInfo_recv(c, mem_ctx, io); } + + +struct grouplist_state { + struct libnet_context *ctx; + const char *domain_name; + struct lsa_DomainInfo dominfo; + int page_size; + uint32_t resume_index; + struct grouplist *groups; + uint32_t count; + + struct libnet_DomainOpen domain_open; + struct lsa_QueryInfoPolicy query_domain; + struct samr_EnumDomainGroups group_list; + + void (*monitor_fn)(struct monitor_msg*); +}; + + +static void continue_lsa_domain_opened(struct composite_context *ctx); +static void continue_domain_queried(struct rpc_request *req); +static void continue_samr_domain_opened(struct composite_context *ctx); +static void continue_domain_queried(struct rpc_request *req); +static void continue_groups_enumerated(struct rpc_request *req); + + +struct composite_context *libnet_GroupList_send(struct libnet_context *ctx, + TALLOC_CTX *mem_ctx, + struct libnet_GroupList *io, + void (*monitor)(struct monitor_msg*)) +{ + struct composite_context *c; + struct grouplist_state *s; + struct rpc_request *query_req; + bool prereq_met = false; + + c = composite_create(mem_ctx, ctx->event_ctx); + if (c == NULL) return NULL; + + s = talloc_zero(c, struct grouplist_state); + if (composite_nomem(s, c)) return c; + + c->private_data = s; + + s->ctx = ctx; + s->page_size = io->in.page_size; + s->resume_index = (uint32_t)io->in.resume_index; + s->domain_name = talloc_strdup(c, io->in.domain_name); + s->monitor_fn = monitor; + + prereq_met = lsa_domain_opened(ctx, s->domain_name, &c, &s->domain_open, + continue_lsa_domain_opened, monitor); + if (!prereq_met) return c; + + s->query_domain.in.handle = &ctx->lsa.handle; + s->query_domain.in.level = LSA_POLICY_INFO_DOMAIN; + + query_req = dcerpc_lsa_QueryInfoPolicy_send(ctx->lsa.pipe, c, &s->query_domain); + if (composite_nomem(query_req, c)) return c; + + composite_continue_rpc(c, query_req, continue_domain_queried, c); + return c; +} + + +static void continue_lsa_domain_opened(struct composite_context *ctx) +{ + struct composite_context *c; + struct grouplist_state *s; + struct rpc_request *query_req; + + c = talloc_get_type(ctx->async.private_data, struct composite_context); + s = talloc_get_type(c->private_data, struct grouplist_state); + + c->status = libnet_DomainOpen_recv(ctx, s->ctx, c, &s->domain_open); + if (!composite_is_ok(c)) return; + + s->query_domain.in.handle = &s->ctx->lsa.handle; + s->query_domain.in.level = LSA_POLICY_INFO_DOMAIN; + + query_req = dcerpc_lsa_QueryInfoPolicy_send(s->ctx->lsa.pipe, c, &s->query_domain); + if (composite_nomem(query_req, c)) return; + + composite_continue_rpc(c, query_req, continue_domain_queried, c); +} + + +static void continue_domain_queried(struct rpc_request *req) +{ + struct composite_context *c; + struct grouplist_state *s; + struct rpc_request *enum_req; + bool prereq_met = false; + + c = talloc_get_type(req->async.private_data, struct composite_context); + s = talloc_get_type(c->private_data, struct grouplist_state); + + /* receive result of rpc request */ + c->status = dcerpc_ndr_request_recv(req); + if (!composite_is_ok(c)) return; + + /* get the returned domain info */ + s->dominfo = s->query_domain.out.info->domain; + + /* make sure we have samr domain handle before continuing */ + prereq_met = samr_domain_opened(s->ctx, s->domain_name, &c, &s->domain_open, + continue_samr_domain_opened, s->monitor_fn); + if (!prereq_met) return; + + /* prepare arguments od EnumDomainGroups call */ + s->group_list.in.domain_handle = &s->ctx->samr.handle; + s->group_list.in.max_size = s->page_size; + s->group_list.in.resume_handle = &s->resume_index; + s->group_list.out.resume_handle = &s->resume_index; + + /* send the request */ + enum_req = dcerpc_samr_EnumDomainGroups_send(s->ctx->samr.pipe, c, &s->group_list); + if (composite_nomem(enum_req, c)) return; + + composite_continue_rpc(c, enum_req, continue_groups_enumerated, c); +} + + +static void continue_samr_domain_opened(struct composite_context *ctx) +{ + struct composite_context *c; + struct grouplist_state *s; + struct rpc_request *enum_req; + + c = talloc_get_type(ctx->async.private_data, struct composite_context); + s = talloc_get_type(c->private_data, struct grouplist_state); + + /* receive samr domain handle */ + c->status = libnet_DomainOpen_recv(ctx, s->ctx, c, &s->domain_open); + if (!composite_is_ok(c)) return; + + s->group_list.in.domain_handle = &s->ctx->samr.handle; + s->group_list.in.max_size = s->page_size; + s->group_list.in.resume_handle = &s->resume_index; + s->group_list.out.resume_handle = &s->resume_index; + + enum_req = dcerpc_samr_EnumDomainGroups_send(s->ctx->samr.pipe, c, &s->group_list); + if (composite_nomem(enum_req, c)) return; + + composite_continue_rpc(c, enum_req, continue_groups_enumerated, c); +} + + +static void continue_groups_enumerated(struct rpc_request *req) +{ + struct composite_context *c; + struct grouplist_state *s; + int i; + + c = talloc_get_type(req->async.private_data, struct composite_context); + s = talloc_get_type(c->private_data, struct grouplist_state); + + c->status = dcerpc_ndr_request_recv(req); + if (!composite_is_ok(c)) return; + + c->status = s->group_list.out.result; + + if (NT_STATUS_IS_OK(c->status) || + NT_STATUS_EQUAL(c->status, STATUS_MORE_ENTRIES) || + NT_STATUS_EQUAL(c->status, NT_STATUS_NO_MORE_ENTRIES)) { + + s->resume_index = *s->group_list.out.resume_handle; + s->count = s->group_list.out.num_entries; + + s->groups = talloc_array(c, struct grouplist, s->group_list.out.sam->count); + if (composite_nomem(s->groups, c)) return; + + for (i = 0; i < s->group_list.out.sam->count; i++) { + struct dom_sid *group_sid; + struct samr_SamEntry *entry = &s->group_list.out.sam->entries[i]; + struct dom_sid *domain_sid = s->query_domain.out.info->domain.sid; + + group_sid = dom_sid_add_rid(c, domain_sid, entry->idx); + if (composite_nomem(group_sid, c)) return; + + s->groups[i].groupname = talloc_strdup(c, entry->name.string); + if (composite_nomem(s->groups[i].groupname, c)) return; + + s->groups[i].sid = dom_sid_string(c, group_sid); + if (composite_nomem(s->groups[i].sid, c)) return; + } + + composite_done(c); + + } else { + composite_error(c, c->status); + } +} + + +NTSTATUS libnet_GroupList_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, + struct libnet_GroupList *io) +{ + NTSTATUS status; + struct grouplist_state *s; + + if (c == NULL || mem_ctx == NULL || io == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + status = composite_wait(c); + if (NT_STATUS_IS_OK(status) || + NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) || + NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) { + + s = talloc_get_type(c->private_data, struct grouplist_state); + + io->out.count = s->count; + io->out.resume_index = s->resume_index; + io->out.groups = talloc_steal(mem_ctx, s->groups); + + if (NT_STATUS_IS_OK(status)) { + io->out.error_string = talloc_asprintf(mem_ctx, "Success"); + } else { + io->out.error_string = talloc_asprintf(mem_ctx, "Success (status: %s)", + nt_errstr(status)); + } + + } else { + io->out.error_string = talloc_asprintf(mem_ctx, "Error: %s", nt_errstr(status)); + } + + return status; +} + + +/** + * Gets list of groups + * + * @param ctx initialised libnet context + * @param mem_ctx memory context of this call + * @param r pointer to a structure containing arguments and result of this call + * @return nt status + */ +NTSTATUS libnet_GroupList(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, + struct libnet_GroupList *io) +{ + struct composite_context *c = libnet_GroupList_send(ctx, mem_ctx, + io, NULL); + return libnet_GroupList_recv(c, mem_ctx, io); +} diff --git a/source4/libnet/libnet_group.h b/source4/libnet/libnet_group.h index 7cab1c90e6..aa414a6667 100644 --- a/source4/libnet/libnet_group.h +++ b/source4/libnet/libnet_group.h @@ -32,3 +32,23 @@ struct libnet_GroupInfo { const char *error_string; } out; }; + + +struct libnet_GroupList { + struct { + const char *domain_name; + int page_size; + uint resume_index; + } in; + struct { + int count; + uint resume_index; + + struct grouplist { + const char *sid; + const char *groupname; + } *groups; + + const char *error_string; + } out; +}; diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 6d7fcd09ad..8297172a58 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -390,7 +390,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J r->out.account_guid = samdb_result_guid(res->msgs[0], "objectGUID"); if (r->in.acct_type == ACB_SVRTRUST) { - status = libnet_JoinSite(remote_ldb, r); + status = libnet_JoinSite(ctx, remote_ldb, r); } talloc_free(tmp_ctx); diff --git a/source4/libnet/libnet_lookup.c b/source4/libnet/libnet_lookup.c index fcb24601e4..409cc7575b 100644 --- a/source4/libnet/libnet_lookup.c +++ b/source4/libnet/libnet_lookup.c @@ -57,7 +57,7 @@ struct composite_context *libnet_Lookup_send(struct libnet_context *ctx, struct composite_context *c; struct lookup_state *s; struct composite_context *cresolve_req; - const char** methods; + struct resolve_context *resolve_ctx; /* allocate context and state structures */ c = composite_create(ctx, ctx->event_ctx); @@ -81,14 +81,14 @@ struct composite_context *libnet_Lookup_send(struct libnet_context *ctx, s->hostname.scope = NULL; /* name resolution methods */ - if (io->in.methods) { - methods = io->in.methods; + if (io->in.resolve_ctx) { + resolve_ctx = io->in.resolve_ctx; } else { - methods = ctx->name_res_methods; + resolve_ctx = ctx->resolve_ctx; } /* send resolve request */ - cresolve_req = resolve_name_send(&s->hostname, c->event_ctx, methods); + cresolve_req = resolve_name_send(resolve_ctx, &s->hostname, c->event_ctx); if (composite_nomem(cresolve_req, c)) return c; composite_continue(c, cresolve_req, continue_name_resolved, c); @@ -192,11 +192,12 @@ struct composite_context* libnet_LookupDCs_send(struct libnet_context *ctx, { struct composite_context *c; struct messaging_context *msg_ctx = - messaging_client_init(mem_ctx, lp_messaging_path(mem_ctx, ctx->lp_ctx), ctx->event_ctx); + messaging_client_init(mem_ctx, lp_messaging_path(mem_ctx, ctx->lp_ctx), + lp_iconv_convenience(ctx->lp_ctx), ctx->event_ctx); - c = finddcs_send(mem_ctx, lp_netbios_name(ctx->lp_ctx), + c = finddcs_send(mem_ctx, lp_netbios_name(ctx->lp_ctx), lp_nbt_port(ctx->lp_ctx), io->in.domain_name, io->in.name_type, - NULL, ctx->name_res_methods, ctx->event_ctx, msg_ctx); + NULL, ctx->resolve_ctx, ctx->event_ctx, msg_ctx); return c; } diff --git a/source4/libnet/libnet_lookup.h b/source4/libnet/libnet_lookup.h index 69cc0b5ade..189ae58b39 100644 --- a/source4/libnet/libnet_lookup.h +++ b/source4/libnet/libnet_lookup.h @@ -22,7 +22,7 @@ struct libnet_Lookup { struct { const char *hostname; int type; - const char **methods; + struct resolve_context *resolve_ctx; } in; struct { const char **address; diff --git a/source4/libnet/libnet_samdump.c b/source4/libnet/libnet_samdump.c index 93e25aa428..9d417d280d 100644 --- a/source4/libnet/libnet_samdump.c +++ b/source4/libnet/libnet_samdump.c @@ -185,7 +185,7 @@ NTSTATUS libnet_SamDump(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, if (strcasecmp_m(s->name, secret_name) != 0) { continue; } - if (convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UTF16, CH_UNIX, + if (convert_string_talloc(mem_ctx, lp_iconv_convenience(ctx->lp_ctx), CH_UTF16, CH_UNIX, s->secret.data, s->secret.length, (void **)&secret_string) == -1) { r->out.error_string = talloc_asprintf(mem_ctx, diff --git a/source4/libnet/libnet_samdump_keytab.c b/source4/libnet/libnet_samdump_keytab.c index c235df6d25..c25cb4d9c5 100644 --- a/source4/libnet/libnet_samdump_keytab.c +++ b/source4/libnet/libnet_samdump_keytab.c @@ -28,6 +28,7 @@ #include "param/param.h" static NTSTATUS samdump_keytab_handle_user(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, const char *keytab_name, struct netr_DELTA_ENUM *delta) { @@ -45,19 +46,19 @@ static NTSTATUS samdump_keytab_handle_user(TALLOC_CTX *mem_ctx, if (!credentials) { return NT_STATUS_NO_MEMORY; } - cli_credentials_set_conf(credentials, global_loadparm); + cli_credentials_set_conf(credentials, lp_ctx); cli_credentials_set_username(credentials, username, CRED_SPECIFIED); /* We really should consult ldap in the main SamSync code, and * pass a value in here */ cli_credentials_set_kvno(credentials, 0); cli_credentials_set_nt_hash(credentials, &user->ntpassword, CRED_SPECIFIED); - ret = cli_credentials_set_keytab_name(credentials, keytab_name, CRED_SPECIFIED); + ret = cli_credentials_set_keytab_name(credentials, lp_ctx, keytab_name, CRED_SPECIFIED); if (ret) { return NT_STATUS_UNSUCCESSFUL; } - ret = cli_credentials_update_keytab(credentials); + ret = cli_credentials_update_keytab(credentials, lp_ctx); if (ret) { return NT_STATUS_UNSUCCESSFUL; } @@ -81,6 +82,7 @@ static NTSTATUS libnet_samdump_keytab_fn(TALLOC_CTX *mem_ctx, /* not interested in builtin users */ if (database == SAM_DATABASE_DOMAIN) { nt_status = samdump_keytab_handle_user(mem_ctx, + global_loadparm, keytab_name, delta); break; diff --git a/source4/libnet/libnet_site.c b/source4/libnet/libnet_site.c index 9351aef634..9db9494865 100644 --- a/source4/libnet/libnet_site.c +++ b/source4/libnet/libnet_site.c @@ -51,7 +51,7 @@ NTSTATUS libnet_FindSite(TALLOC_CTX *ctx, struct libnet_JoinSite *r) /* Resolve the site name. */ ZERO_STRUCT(search); search.in.dest_address = r->in.dest_address; - search.in.dest_port = lp_cldap_port(global_loadparm); + search.in.dest_port = r->in.cldap_port; search.in.acct_control = -1; search.in.version = 6; @@ -116,7 +116,8 @@ NTSTATUS libnet_FindSite(TALLOC_CTX *ctx, struct libnet_JoinSite *r) * 2. Add entry CN=<netbios name>,CN=Servers,CN=<site name>,CN=Sites,CN=Configuration,<domain dn>. * TODO: 3.) use DsAddEntry() to create CN=NTDS Settings,CN=<netbios name>,CN=Servers,CN=<site name>,... */ -NTSTATUS libnet_JoinSite(struct ldb_context *remote_ldb, +NTSTATUS libnet_JoinSite(struct libnet_context *ctx, + struct ldb_context *remote_ldb, struct libnet_JoinDomain *libnet_r) { NTSTATUS status; @@ -147,7 +148,7 @@ NTSTATUS libnet_JoinSite(struct ldb_context *remote_ldb, } make_nbt_name_client(&name, libnet_r->out.samr_binding->host); - status = resolve_name(&name, r, &dest_addr, NULL, lp_name_resolve_order(global_loadparm)); + status = resolve_name(lp_resolve_context(ctx->lp_ctx), &name, r, &dest_addr, NULL); if (!NT_STATUS_IS_OK(status)) { libnet_r->out.error_string = NULL; talloc_free(tmp_ctx); @@ -158,6 +159,7 @@ NTSTATUS libnet_JoinSite(struct ldb_context *remote_ldb, r->in.dest_address = dest_addr; r->in.netbios_name = libnet_r->in.netbios_name; r->in.domain_dn_str = libnet_r->out.domain_dn_str; + r->in.cldap_port = lp_cldap_port(ctx->lp_ctx); status = libnet_FindSite(tmp_ctx, r); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/libnet/libnet_site.h b/source4/libnet/libnet_site.h index 9a0484c2a9..8e607c5b6a 100644 --- a/source4/libnet/libnet_site.h +++ b/source4/libnet/libnet_site.h @@ -22,6 +22,7 @@ struct libnet_JoinSite { const char *dest_address; const char *netbios_name; const char *domain_dn_str; + uint16_t cldap_port; } in; struct { diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 574b34c246..df4cb4d657 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -186,7 +186,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx return NT_STATUS_NO_MEMORY; } cli_credentials_set_conf(machine_account, ctx->lp_ctx); - nt_status = cli_credentials_set_machine_account(machine_account); + nt_status = cli_credentials_set_machine_account(machine_account, ctx->lp_ctx); if (!NT_STATUS_IS_OK(nt_status)) { r->out.error_string = talloc_strdup(mem_ctx, "Could not obtain machine account password - are we joined to the domain?"); talloc_free(samsync_ctx); |