root/source4/winbind/wb_sid2domain.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. find_domain_from_sid
  2. wb_sid2domain_send
  3. sid2domain_recv_dom_info
  4. sid2domain_recv_name
  5. sid2domain_recv_trusted_dom_info
  6. sid2domain_recv_init
  7. wb_sid2domain_recv
  8. wb_sid2domain

   1 /* 
   2    Unix SMB/CIFS implementation.
   3 
   4    Find and init a domain struct for a SID
   5 
   6    Copyright (C) Volker Lendecke 2005
   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 "libcli/composite/composite.h"
  24 #include "winbind/wb_server.h"
  25 #include "smbd/service_task.h"
  26 #include "winbind/wb_async_helpers.h"
  27 #include "libcli/security/security.h"
  28 #include "../lib/util/dlinklist.h"
  29 #include "param/param.h"
  30 
  31 static struct wbsrv_domain *find_domain_from_sid(struct wbsrv_service *service,
     /* [<][>][^][v][top][bottom][index][help] */
  32                                                  const struct dom_sid *sid)
  33 {
  34         struct wbsrv_domain *domain;
  35 
  36         for (domain = service->domains; domain!=NULL; domain = domain->next) {
  37                 if (dom_sid_equal(domain->info->sid, sid)) {
  38                         break;
  39                 }
  40                 if (dom_sid_in_domain(domain->info->sid, sid)) {
  41                         break;
  42                 }
  43         }
  44         return domain;
  45 }
  46 
  47 struct sid2domain_state {
  48         struct composite_context *ctx;
  49         struct wbsrv_service *service;
  50         struct dom_sid *sid;
  51 
  52         struct wbsrv_domain *domain;
  53 };
  54 
  55 static void sid2domain_recv_dom_info(struct composite_context *ctx);
  56 static void sid2domain_recv_name(struct composite_context *ctx);
  57 static void sid2domain_recv_trusted_dom_info(struct composite_context *ctx);
  58 static void sid2domain_recv_init(struct composite_context *ctx);
  59 
  60 struct composite_context *wb_sid2domain_send(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  61                                              struct wbsrv_service *service,
  62                                              const struct dom_sid *sid)
  63 {
  64         struct composite_context *result, *ctx;
  65         struct sid2domain_state *state;
  66 
  67         result = composite_create(mem_ctx, service->task->event_ctx);
  68         if (result == NULL) goto failed;
  69 
  70         state = talloc(result, struct sid2domain_state);
  71         if (state == NULL) goto failed;
  72         state->ctx = result;
  73         result->private_data = state;
  74 
  75         state->service = service;
  76         state->sid = dom_sid_dup(state, sid);
  77         if (state->sid == NULL) goto failed;
  78 
  79         state->domain = find_domain_from_sid(service, sid);
  80         if (state->domain != NULL) {
  81                 result->status = NT_STATUS_OK;
  82                 composite_done(result);
  83                 return result;
  84         }
  85 
  86         if (dom_sid_equal(service->primary_sid, sid) ||
  87             dom_sid_in_domain(service->primary_sid, sid)) {
  88                 ctx = wb_get_dom_info_send(state, service, lp_workgroup(service->task->lp_ctx),
  89                                            service->primary_sid);
  90                 if (ctx == NULL) goto failed;
  91                 ctx->async.fn = sid2domain_recv_dom_info;
  92                 ctx->async.private_data = state;
  93                 return result;
  94         }
  95 
  96         ctx = wb_cmd_lookupsid_send(state, service, state->sid);
  97         if (ctx == NULL) goto failed;
  98         composite_continue(result, ctx, sid2domain_recv_name, state);
  99 
 100         return result;
 101 
 102  failed:
 103         talloc_free(result);
 104         return NULL;
 105 
 106 }
 107 
 108 static void sid2domain_recv_dom_info(struct composite_context *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 109 {
 110         struct sid2domain_state *state =
 111                 talloc_get_type(ctx->async.private_data,
 112                                 struct sid2domain_state);
 113         struct wb_dom_info *info;
 114 
 115         state->ctx->status = wb_get_dom_info_recv(ctx, state, &info);
 116         if (!composite_is_ok(state->ctx)) return;
 117 
 118         ctx = wb_init_domain_send(state, state->service, info);
 119 
 120         composite_continue(state->ctx, ctx, sid2domain_recv_init, state);
 121 }
 122 
 123 static void sid2domain_recv_name(struct composite_context *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 124 {
 125         struct sid2domain_state *state =
 126                 talloc_get_type(ctx->async.private_data,
 127                                 struct sid2domain_state);
 128         struct wb_sid_object *name;
 129 
 130         state->ctx->status = wb_cmd_lookupsid_recv(ctx, state, &name);
 131         if (!composite_is_ok(state->ctx)) return;
 132 
 133         if (name->type == SID_NAME_UNKNOWN) {
 134                 composite_error(state->ctx, NT_STATUS_NO_SUCH_DOMAIN);
 135                 return;
 136         }
 137 
 138         if (name->type != SID_NAME_DOMAIN) {
 139                 state->sid->num_auths -= 1;
 140         }
 141 
 142         ctx = wb_trusted_dom_info_send(state, state->service, name->domain,
 143                                        state->sid);
 144 
 145         composite_continue(state->ctx, ctx, sid2domain_recv_trusted_dom_info,
 146                            state);
 147 }
 148 
 149 static void sid2domain_recv_trusted_dom_info(struct composite_context *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 150 {
 151         struct sid2domain_state *state =
 152                 talloc_get_type(ctx->async.private_data,
 153                                 struct sid2domain_state);
 154         struct wb_dom_info *info;
 155 
 156         state->ctx->status = wb_trusted_dom_info_recv(ctx, state, &info);
 157         if (!composite_is_ok(state->ctx)) return;
 158 
 159         ctx = wb_init_domain_send(state, state->service, info);
 160 
 161         composite_continue(state->ctx, ctx, sid2domain_recv_init, state);
 162 }
 163 
 164 static void sid2domain_recv_init(struct composite_context *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 165 {
 166         struct sid2domain_state *state =
 167                 talloc_get_type(ctx->async.private_data,
 168                                 struct sid2domain_state);
 169         struct wbsrv_domain *existing;
 170 
 171         state->ctx->status = wb_init_domain_recv(ctx, state,
 172                                                  &state->domain);
 173         if (!composite_is_ok(state->ctx)) {
 174                 DEBUG(10, ("Could not init domain\n"));
 175                 return;
 176         }
 177 
 178         existing = find_domain_from_sid(state->service, state->sid);
 179         if (existing != NULL) {
 180                 DEBUG(5, ("Initialized domain twice, dropping second one\n"));
 181                 talloc_free(state->domain);
 182                 state->domain = existing;
 183         }
 184 
 185         talloc_steal(state->service, state->domain);
 186         DLIST_ADD(state->service->domains, state->domain);
 187 
 188         composite_done(state->ctx);
 189 }
 190 
 191 NTSTATUS wb_sid2domain_recv(struct composite_context *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 192                             struct wbsrv_domain **result)
 193 {
 194         NTSTATUS status = composite_wait(ctx);
 195         if (NT_STATUS_IS_OK(status)) {
 196                 struct sid2domain_state *state =
 197                         talloc_get_type(ctx->private_data,
 198                                         struct sid2domain_state);
 199                 *result = state->domain;
 200         }
 201         talloc_free(ctx);
 202         return status;
 203 }
 204 
 205 NTSTATUS wb_sid2domain(TALLOC_CTX *mem_ctx, struct wbsrv_service *service,
     /* [<][>][^][v][top][bottom][index][help] */
 206                        const struct dom_sid *sid,
 207                        struct wbsrv_domain **result)
 208 {
 209         struct composite_context *c = wb_sid2domain_send(mem_ctx, service,
 210                                                          sid);
 211         return wb_sid2domain_recv(c, result);
 212 }

/* [<][>][^][v][top][bottom][index][help] */