~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/winbind/wb_connect_sam.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
   Unix SMB/CIFS implementation.
 
3
 
 
4
   Connect to the SAMR pipe, and return connection and domain handles.
 
5
 
 
6
   Copyright (C) Volker Lendecke 2005
 
7
   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2007
 
8
   
 
9
   This program is free software; you can redistribute it and/or modify
 
10
   it under the terms of the GNU General Public License as published by
 
11
   the Free Software Foundation; either version 3 of the License, or
 
12
   (at your option) any later version.
 
13
   
 
14
   This program is distributed in the hope that it will be useful,
 
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
   GNU General Public License for more details.
 
18
   
 
19
   You should have received a copy of the GNU General Public License
 
20
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
21
*/
 
22
 
 
23
#include "includes.h"
 
24
#include "libcli/composite/composite.h"
 
25
 
 
26
#include "libcli/raw/libcliraw.h"
 
27
#include "libcli/security/security.h"
 
28
#include "librpc/gen_ndr/ndr_samr_c.h"
 
29
#include "winbind/wb_server.h"
 
30
 
 
31
 
 
32
/* Helper to initialize SAMR with a specific auth methods. Verify by opening
 
33
 * the SAM handle */
 
34
 
 
35
struct connect_samr_state {
 
36
        struct composite_context *ctx;
 
37
        struct dom_sid *sid;
 
38
 
 
39
        struct dcerpc_pipe *samr_pipe;
 
40
        struct policy_handle *connect_handle;
 
41
        struct policy_handle *domain_handle;
 
42
 
 
43
        struct samr_Connect2 c;
 
44
        struct samr_OpenDomain o;
 
45
};
 
46
 
 
47
static void connect_samr_recv_pipe(struct composite_context *ctx);
 
48
static void connect_samr_recv_conn(struct rpc_request *req);
 
49
static void connect_samr_recv_open(struct rpc_request *req);
 
50
 
 
51
struct composite_context *wb_connect_samr_send(TALLOC_CTX *mem_ctx,
 
52
                                           struct wbsrv_domain *domain)
 
53
{
 
54
        struct composite_context *result, *ctx;
 
55
        struct connect_samr_state *state;
 
56
 
 
57
        result = composite_create(mem_ctx, domain->netlogon_pipe->conn->event_ctx);
 
58
        if (result == NULL) goto failed;
 
59
 
 
60
        state = talloc(result, struct connect_samr_state);
 
61
        if (state == NULL) goto failed;
 
62
        state->ctx = result;
 
63
        result->private_data = state;
 
64
 
 
65
        state->sid = dom_sid_dup(state, domain->info->sid);
 
66
        if (state->sid == NULL) goto failed;
 
67
 
 
68
        /* this will make the secondary connection on the same IPC$ share, 
 
69
           secured with SPNEGO, NTLMSSP or SCHANNEL */
 
70
        ctx = dcerpc_secondary_auth_connection_send(domain->netlogon_pipe,
 
71
                                                    domain->samr_binding,
 
72
                                                    &ndr_table_samr,
 
73
                                                    domain->libnet_ctx->cred,
 
74
                                                    domain->libnet_ctx->lp_ctx);
 
75
        composite_continue(state->ctx, ctx, connect_samr_recv_pipe, state);
 
76
        return result;
 
77
        
 
78
 failed:
 
79
        talloc_free(result);
 
80
        return NULL;
 
81
}
 
82
 
 
83
static void connect_samr_recv_pipe(struct composite_context *ctx)
 
84
{
 
85
        struct rpc_request *req;
 
86
        struct connect_samr_state *state =
 
87
                talloc_get_type(ctx->async.private_data,
 
88
                                struct connect_samr_state);
 
89
 
 
90
        state->ctx->status = dcerpc_secondary_auth_connection_recv(ctx, state, 
 
91
                                                                   &state->samr_pipe);
 
92
        if (!composite_is_ok(state->ctx)) return;
 
93
                        
 
94
        state->connect_handle = talloc(state, struct policy_handle);
 
95
        if (composite_nomem(state->connect_handle, state->ctx)) return;
 
96
 
 
97
        state->c.in.system_name =
 
98
                talloc_asprintf(state, "\\\\%s",
 
99
                                dcerpc_server_name(state->samr_pipe));
 
100
        state->c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 
101
        state->c.out.connect_handle = state->connect_handle;
 
102
 
 
103
        req = dcerpc_samr_Connect2_send(state->samr_pipe, state, &state->c);
 
104
        composite_continue_rpc(state->ctx, req, connect_samr_recv_conn, state);
 
105
        return;
 
106
}
 
107
 
 
108
static void connect_samr_recv_conn(struct rpc_request *req)
 
109
{
 
110
        struct connect_samr_state *state =
 
111
                talloc_get_type(req->async.private_data,
 
112
                                struct connect_samr_state);
 
113
 
 
114
        state->ctx->status = dcerpc_ndr_request_recv(req);
 
115
        if (!composite_is_ok(state->ctx)) return;
 
116
        state->ctx->status = state->c.out.result;
 
117
        if (!composite_is_ok(state->ctx)) return;
 
118
 
 
119
        state->domain_handle = talloc(state, struct policy_handle);
 
120
        if (composite_nomem(state->domain_handle, state->ctx)) return;
 
121
 
 
122
        state->o.in.connect_handle = state->connect_handle;
 
123
        state->o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 
124
        state->o.in.sid = state->sid;
 
125
        state->o.out.domain_handle = state->domain_handle;
 
126
 
 
127
        req = dcerpc_samr_OpenDomain_send(state->samr_pipe, state, &state->o);
 
128
        composite_continue_rpc(state->ctx, req,
 
129
                               connect_samr_recv_open, state);
 
130
}
 
131
 
 
132
static void connect_samr_recv_open(struct rpc_request *req)
 
133
{
 
134
        struct connect_samr_state *state =
 
135
                talloc_get_type(req->async.private_data,
 
136
                                struct connect_samr_state);
 
137
 
 
138
        state->ctx->status = dcerpc_ndr_request_recv(req);
 
139
        if (!composite_is_ok(state->ctx)) return;
 
140
        state->ctx->status = state->o.out.result;
 
141
        if (!composite_is_ok(state->ctx)) return;
 
142
 
 
143
        composite_done(state->ctx);
 
144
}
 
145
 
 
146
NTSTATUS wb_connect_samr_recv(struct composite_context *c,
 
147
                             TALLOC_CTX *mem_ctx,
 
148
                             struct dcerpc_pipe **samr_pipe,
 
149
                             struct policy_handle *connect_handle,
 
150
                             struct policy_handle *domain_handle)
 
151
{
 
152
        NTSTATUS status = composite_wait(c);
 
153
        if (NT_STATUS_IS_OK(status)) {
 
154
                struct connect_samr_state *state =
 
155
                        talloc_get_type(c->private_data,
 
156
                                        struct connect_samr_state);
 
157
                *samr_pipe = talloc_steal(mem_ctx, state->samr_pipe);
 
158
                *connect_handle = *state->connect_handle;
 
159
                *domain_handle = *state->domain_handle;
 
160
        }
 
161
        talloc_free(c);
 
162
        return status;
 
163
}
 
164