1/* 2 Unix SMB/CIFS implementation. 3 4 async seqnums, update the seqnums in winbindd_cache.c 5 6 Copyright (C) Volker Lendecke 2009 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20*/ 21 22#include "includes.h" 23#include "winbindd.h" 24#include "librpc/gen_ndr/cli_wbint.h" 25 26struct wb_seqnums_state { 27 int num_domains; 28 int num_received; 29 30 struct tevent_req **subreqs; 31 struct winbindd_domain **domains; 32 NTSTATUS *stati; 33 uint32_t *seqnums; 34}; 35 36static void wb_seqnums_done(struct tevent_req *subreq); 37 38struct tevent_req *wb_seqnums_send(TALLOC_CTX *mem_ctx, 39 struct tevent_context *ev) 40{ 41 struct tevent_req *req; 42 struct wb_seqnums_state *state; 43 struct winbindd_domain *domain; 44 int i; 45 46 req = tevent_req_create(mem_ctx, &state, struct wb_seqnums_state); 47 if (req == NULL) { 48 return NULL; 49 } 50 state->num_received = 0; 51 state->num_domains = 0; 52 53 for (domain = domain_list(); domain != NULL; domain = domain->next) { 54 state->num_domains += 1; 55 } 56 57 state->subreqs = talloc_array(state, struct tevent_req *, 58 state->num_domains); 59 state->domains = talloc_array(state, struct winbindd_domain *, 60 state->num_domains); 61 state->stati = talloc_array(state, NTSTATUS, state->num_domains); 62 state->seqnums = talloc_array(state, uint32_t, state->num_domains); 63 64 if ((state->subreqs == NULL) || (state->domains == NULL) || 65 (state->stati == NULL) || (state->seqnums == NULL)) { 66 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 67 return tevent_req_post(req, ev); 68 } 69 70 i = 0; 71 72 for (domain = domain_list(); domain != NULL; domain = domain->next) { 73 state->domains[i] = domain; 74 state->subreqs[i] = wb_seqnum_send(state->subreqs, ev, domain); 75 if (tevent_req_nomem(state->subreqs[i], req)) { 76 /* Don't even start all the other requests */ 77 TALLOC_FREE(state->subreqs); 78 return tevent_req_post(req, ev); 79 } 80 tevent_req_set_callback(state->subreqs[i], wb_seqnums_done, 81 req); 82 i += 1; 83 } 84 return req; 85} 86 87static void wb_seqnums_done(struct tevent_req *subreq) 88{ 89 struct tevent_req *req = tevent_req_callback_data( 90 subreq, struct tevent_req); 91 struct wb_seqnums_state *state = tevent_req_data( 92 req, struct wb_seqnums_state); 93 NTSTATUS status; 94 uint32_t seqnum; 95 int i; 96 97 status = wb_seqnum_recv(subreq, &seqnum); 98 99 for (i=0; i<state->num_domains; i++) { 100 if (subreq == state->subreqs[i]) { 101 break; 102 } 103 } 104 if (i < state->num_domains) { 105 /* found one */ 106 107 state->subreqs[i] = NULL; 108 state->stati[i] = status; 109 if (NT_STATUS_IS_OK(status)) { 110 state->seqnums[i] = seqnum; 111 112 /* 113 * This first assignment might be removed 114 * later 115 */ 116 state->domains[i]->sequence_number = seqnum; 117 118 if (!wcache_store_seqnum(state->domains[i]->name, 119 state->seqnums[i], 120 time(NULL))) { 121 DEBUG(1, ("wcache_store_seqnum failed for " 122 "domain %s\n", 123 state->domains[i]->name)); 124 } 125 } 126 } 127 128 TALLOC_FREE(subreq); 129 130 state->num_received += 1; 131 132 if (state->num_received >= state->num_domains) { 133 tevent_req_done(req); 134 } 135} 136 137NTSTATUS wb_seqnums_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 138 int *num_domains, struct winbindd_domain ***domains, 139 NTSTATUS **stati, uint32_t **seqnums) 140{ 141 struct wb_seqnums_state *state = tevent_req_data( 142 req, struct wb_seqnums_state); 143 NTSTATUS status; 144 145 if (tevent_req_is_nterror(req, &status)) { 146 return status; 147 } 148 *num_domains = state->num_domains; 149 *domains = talloc_move(mem_ctx, &state->domains); 150 *stati = talloc_move(mem_ctx, &state->stati); 151 *seqnums = talloc_move(mem_ctx, &state->seqnums); 152 return NT_STATUS_OK; 153} 154