From 3fe27b7f9df7d2bb2f7799fd46b79928f0e614b0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 17 May 2002 13:49:01 +0000 Subject: A few more trusted domains updates from mimir. I think we may still need to look at our server enumeration code, but other than that, its much better in the tree than out. Andrew Bartlett (This used to be commit d57a1b4629d12a0374cc6d74dfc6f5d4793fcef8) --- source3/include/nterr.h | 2 +- source3/libsmb/cli_lsarpc.c | 31 +++++++++++++++++++-------- source3/libsmb/nterr.c | 1 + source3/nsswitch/winbindd_rpc.c | 5 +++-- source3/passdb/secrets.c | 47 +++++++++++++++++++++++++++++------------ source3/rpc_parse/parse_lsa.c | 25 ++++++---------------- source3/rpc_server/srv_lsa_nt.c | 22 +++++++++++++------ source3/rpcclient/cmd_lsarpc.c | 43 +++++++++++++++++++++++++------------ 8 files changed, 113 insertions(+), 63 deletions(-) diff --git a/source3/include/nterr.h b/source3/include/nterr.h index a869e19738..dcc26d9884 100644 --- a/source3/include/nterr.h +++ b/source3/include/nterr.h @@ -29,7 +29,7 @@ #define STATUS_BUFFER_OVERFLOW NT_STATUS(0x80000005) #define NT_STATUS_NO_MORE_ENTRIES NT_STATUS(0x8000001a) -#define STATUS_MORE_ENTRIES NT_STATUS(0x0105) +#define STATUS_MORE_ENTRIES NT_STATUS(0x0105) #define STATUS_SOME_UNMAPPED NT_STATUS(0x0107) #define ERROR_INVALID_PARAMETER NT_STATUS(0x0057) #define ERROR_INSUFFICIENT_BUFFER NT_STATUS(0x007a) diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 1989169fd7..8eaf6da2ec 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -5,7 +5,8 @@ Copyright (C) Andrew Tridgell 1992-1997,2000, Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000, Copyright (C) Paul Ashton 1997,2000, - Copyright (C) Elrond 2000. + Copyright (C) Elrond 2000, + Copyright (C) Rafal Szczesniak 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -537,12 +538,25 @@ NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/** Enumerate list of trusted domains */ +/** + * Enumerate list of trusted domains + * + * @param cli client state (cli_state) structure of the connection + * @param mem_ctx memory context + * @param pol opened lsa policy handle + * @param enum_ctx enumeration context ie. index of first returned domain entry + * @param pref_num_domains preferred max number of entries returned in one response + * @param num_domains total number of trusted domains returned by response + * @param domain_names returned trusted domain names + * @param domain_sids returned trusted domain sids + * + * @return nt status code of response + **/ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 *enum_ctx, - uint32 *num_domains, char ***domain_names, - DOM_SID **domain_sids) + uint32 *pref_num_domains, uint32 *num_domains, + char ***domain_names, DOM_SID **domain_sids) { prs_struct qbuf, rbuf; LSA_Q_ENUM_TRUST_DOM q; @@ -560,7 +574,7 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Marshall data and send request */ - init_q_enum_trust_dom(&q, pol, *enum_ctx, 0xffffffff); + init_q_enum_trust_dom(&q, pol, *enum_ctx, *pref_num_domains); if (!lsa_io_q_enum_trust_dom("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_ENUMTRUSTDOM, &qbuf, &rbuf)) { @@ -577,16 +591,15 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_NO_MORE_ENTRIES)) { + if (!NT_STATUS_IS_OK(result) && + !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) && + !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { /* An actual error ocured */ goto done; } - result = NT_STATUS_OK; - /* Return output parameters */ if (r.num_domains) { diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index faf5147fe2..e2da6318e1 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -534,6 +534,7 @@ nt_err_code_struct nt_errs[] = { "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT }, { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE }, { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES }, + { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, { NULL, NT_STATUS(0) } }; diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c index 39433419b0..9388675525 100644 --- a/source3/nsswitch/winbindd_rpc.c +++ b/source3/nsswitch/winbindd_rpc.c @@ -558,6 +558,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, CLI_POLICY_HND *hnd; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 enum_ctx = 0; + uint32 pref_num_domains = 5; *num_domains = 0; @@ -565,8 +566,8 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, goto done; result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx, - &hnd->pol, &enum_ctx, num_domains, - names, dom_sids); + &hnd->pol, &enum_ctx, &pref_num_domains, + num_domains, names, dom_sids); done: return result; } diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c index 073317824b..32d4b42611 100644 --- a/source3/passdb/secrets.c +++ b/source3/passdb/secrets.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. Copyright (C) Andrew Tridgell 1992-2001 Copyright (C) Andrew Bartlett 2002 + Copyright (C) Rafal Szczesniak 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -383,25 +384,31 @@ BOOL secrets_store_ldap_pw(char* dn, char* pw) * The linked list is allocated on the supplied talloc context, caller gets to destory * when done. * - * @param start_idx starting index, eg. we can start fetching - * at third or sixth trusted domain entry - * @param num_domains number of domain entries to fetch at one call + * @param ctx Allocation context + * @param enum_ctx Starting index, eg. we can start fetching at third + * or sixth trusted domain entry. Zero is the first index. + * Value it is set to is the enum context for the next enumeration. + * @param num_domains Number of domain entries to fetch at one call + * @param domains Pointer to array of trusted domain structs to be filled up * - * @return list of trusted domains structs (unicode name, sid and password) + * @return nt status code of rpc response **/ -NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int start_idx, int max_num_domains, int *num_domains, TRUSTDOM ***domains) +NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num_domains, int *num_domains, TRUSTDOM ***domains) { TDB_LIST_NODE *keys, *k; TRUSTDOM *dom = NULL; char *pattern; + int start_idx; uint32 idx = 0; size_t size; struct trusted_dom_pass *pass; + NTSTATUS status; secrets_init(); *num_domains = 0; + start_idx = *enum_ctx; /* generate searching pattern */ if (!(pattern = talloc_asprintf(ctx, "%s/*", SECRETS_DOMTRUST_ACCT_PASS))) { @@ -410,13 +417,19 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int start_idx, int max_num } DEBUG(5, ("secrets_get_trusted_domains: looking for %d domains, starting at index %d\n", - max_num_domains, start_idx)); + max_num_domains, *enum_ctx)); *domains = talloc_zero(ctx, sizeof(**domains)*max_num_domains); /* fetching trusted domains' data and collecting them in a list */ keys = tdb_search_keys(tdb, pattern); + /* + * if there's no keys returned ie. no trusted domain, + * return "no more entries" code + */ + status = NT_STATUS_NO_MORE_ENTRIES; + /* searching for keys in sectrets db -- way to go ... */ for (k = keys; k; k = k->next) { char *secrets_key; @@ -447,17 +460,26 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int start_idx, int max_num return NT_STATUS_NO_MEMORY; } - /* copy domain sid */ + /* copy domain sid */ SMB_ASSERT(sizeof(dom->sid) == sizeof(pass->domain_sid)); memcpy(&(dom->sid), &(pass->domain_sid), sizeof(dom->sid)); - /* copy unicode domain name */ + /* copy unicode domain name */ dom->name = talloc_strdup_w(ctx, pass->uni_name); - (*domains)[*num_domains] = dom; + (*domains)[idx - start_idx] = dom; + *enum_ctx = idx + 1; (*num_domains)++; - + + /* set proper status code to return */ + if (k->next) { + /* there are yet some entries to enumerate */ + status = STATUS_MORE_ENTRIES; + } else { + /* this is the last entry in the whole enumeration */ + status = NT_STATUS_OK; + } } idx++; @@ -466,12 +488,11 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int start_idx, int max_num SAFE_FREE(pass); } - DEBUG(5, ("secrets_get_trusted_domains: got %d of %d domains\n", - *num_domains, max_num_domains)); + DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n", *num_domains)); /* free the results of searching the keys */ tdb_search_list_free(keys); - return NT_STATUS_OK; + return status; } diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c index 415737ebfb..e2f3abc910 100644 --- a/source3/rpc_parse/parse_lsa.c +++ b/source3/rpc_parse/parse_lsa.c @@ -525,21 +525,19 @@ BOOL lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM *q_e, ********************************************************************/ void init_r_enum_trust_dom(TALLOC_CTX *ctx, LSA_R_ENUM_TRUST_DOM *r_e, uint32 enum_context, - uint32 requested_num_domains, uint32 num_domains, TRUSTDOM **td) + uint32 req_num_domains, uint32 num_domains, TRUSTDOM **td) { int i; DEBUG(5, ("init_r_enum_trust_dom\n")); r_e->enum_context = enum_context; - r_e->num_domains = 0; + r_e->num_domains = num_domains; r_e->ptr_enum_domains = 0; - r_e->num_domains2 = 0; - - if (num_domains == 0) { - r_e->status = NT_STATUS_NO_MORE_ENTRIES; - - } else { + r_e->num_domains2 = num_domains; + + if (num_domains != 0) { + /* * allocating empty arrays of unicode headers, strings * and sids of enumerated trusted domains @@ -558,10 +556,7 @@ void init_r_enum_trust_dom(TALLOC_CTX *ctx, LSA_R_ENUM_TRUST_DOM *r_e, uint32 en r_e->status = NT_STATUS_NO_MEMORY; return; } - - r_e->num_domains = num_domains; - r_e->num_domains2 = num_domains; - + for (i = 0; i < num_domains; i++) { /* don't know what actually is this for */ @@ -573,12 +568,6 @@ void init_r_enum_trust_dom(TALLOC_CTX *ctx, LSA_R_ENUM_TRUST_DOM *r_e, uint32 en init_unistr2_w(ctx, &r_e->uni_domain_name[i], (td[i])->name); }; - - if (num_domains < requested_num_domains) { - r_e->status = NT_STATUS_NO_MORE_ENTRIES; - } else { - r_e->status = NT_STATUS_OK; - } } } diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index c564323803..c4adc26360 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -3,8 +3,9 @@ * RPC Pipe client / server routines * Copyright (C) Andrew Tridgell 1992-1997, * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, - * Copyright (C) Paul Ashton 1997. - * Copyright (C) Jeremy Allison 2001. + * Copyright (C) Paul Ashton 1997, + * Copyright (C) Jeremy Allison 2001, + * Copyright (C) Rafal Szczesniak 2002. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -423,8 +424,12 @@ NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_E { struct lsa_info *info; uint32 enum_context = q_u->enum_context; - /* it's set to 10 as a "our" preferred length */ - uint32 max_num_domains = q_u->preferred_len < 10 ? q_u->preferred_len : 10; + + /* + * preferred length is set to 5 as a "our" preferred length + * nt sets this parameter to 2 + */ + uint32 max_num_domains = q_u->preferred_len < 5 ? q_u->preferred_len : 10; TRUSTDOM **trust_doms; uint32 num_domains; NTSTATUS nt_status; @@ -436,9 +441,14 @@ NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_E if (!(info->access & POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; - nt_status = secrets_get_trusted_domains(p->mem_ctx, enum_context, max_num_domains, &num_domains, &trust_doms); - if (!NT_STATUS_IS_OK(nt_status)) { + nt_status = secrets_get_trusted_domains(p->mem_ctx, &enum_context, max_num_domains, &num_domains, &trust_doms); + + if (!NT_STATUS_IS_OK(nt_status) && + !NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES) && + !NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_MORE_ENTRIES)) { return nt_status; + } else { + r_u->status = nt_status; } /* set up the lsa_enum_trust_dom response */ diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index 1f8b14ae04..511f5643c7 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -2,7 +2,8 @@ Unix SMB/CIFS implementation. RPC pipe client - Copyright (C) Tim Potter 2000 + Copyright (C) Tim Potter 2000 + Copyright (C) Rafal Szczesniak 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -188,17 +189,31 @@ static NTSTATUS cmd_lsa_enum_trust_dom(struct cli_state *cli, NTSTATUS result = NT_STATUS_UNSUCCESSFUL; DOM_SID *domain_sids; char **domain_names; + + /* defaults, but may be changed using params */ uint32 enum_ctx = 0; - uint32 num_domains; + uint32 preferred_maxnum = 5; + uint32 num_domains = 0; int i; - if (argc != 1) { - printf("Usage: %s\n", argv[0]); + if (argc > 3) { + printf("Usage: %s [preferred max number (%d)] [enum context (0)]\n", + argv[0], preferred_maxnum); return NT_STATUS_OK; } + /* enumeration context */ + if (argc >= 2 && argv[1]) { + preferred_maxnum = atoi(argv[1]); + } + + /* preferred maximum number */ + if (argc == 3 && argv[2]) { + enum_ctx = atoi(argv[2]); + } + result = cli_lsa_open_policy(cli, mem_ctx, True, - SEC_RIGHTS_MAXIMUM_ALLOWED, + POLICY_VIEW_LOCAL_INFORMATION, &pol); if (!NT_STATUS_IS_OK(result)) @@ -207,14 +222,14 @@ static NTSTATUS cmd_lsa_enum_trust_dom(struct cli_state *cli, /* Lookup list of trusted domains */ result = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx, - &num_domains, &domain_names, - &domain_sids); - - if (!NT_STATUS_IS_OK(result)) - goto done; - - /* Print results */ - + &preferred_maxnum, &num_domains, + &domain_names, &domain_sids); + if (!NT_STATUS_IS_OK(result) && + !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) && + !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) + goto done; + + /* Print results: list of names and sids returned in this response. */ for (i = 0; i < num_domains; i++) { fstring sid_str; @@ -503,7 +518,7 @@ struct cmd_set lsarpc_commands[] = { { "lsaquery", cmd_lsa_query_info_policy, PIPE_LSARPC, "Query info policy", "" }, { "lookupsids", cmd_lsa_lookup_sids, PIPE_LSARPC, "Convert SIDs to names", "" }, { "lookupnames", cmd_lsa_lookup_names, PIPE_LSARPC, "Convert names to SIDs", "" }, - { "enumtrust", cmd_lsa_enum_trust_dom, PIPE_LSARPC, "Enumerate trusted domains", "" }, + { "enumtrust", cmd_lsa_enum_trust_dom, PIPE_LSARPC, "Enumerate trusted domains", "Usage: [preferred max number] [enum context (0)]" }, { "enumprivs", cmd_lsa_enum_privilege, PIPE_LSARPC, "Enumerate privileges", "" }, { "getdispname", cmd_lsa_get_dispname, PIPE_LSARPC, "Get the privilege name", "" }, { "lsaenumsid", cmd_lsa_enum_sids, PIPE_LSARPC, "Enumerate the LSA SIDS", "" }, -- cgit