~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to source/libsmb/trusts_util.c

  • Committer: jerry
  • Date: 2006-07-14 21:48:39 UTC
  • Revision ID: vcs-imports@canonical.com-20060714214839-586d8c489a8fcead
gutting trunk to move to svn:externals

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  Unix SMB/CIFS implementation.
3
 
 *  Routines to operate on various trust relationships
4
 
 *  Copyright (C) Andrew Bartlett                   2001
5
 
 *  Copyright (C) Rafal Szczesniak                  2003
6
 
 *
7
 
 *  This program is free software; you can redistribute it and/or modify
8
 
 *  it under the terms of the GNU General Public License as published by
9
 
 *  the Free Software Foundation; either version 2 of the License, or
10
 
 *  (at your option) any later version.
11
 
 *  
12
 
 *  This program is distributed in the hope that it will be useful,
13
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
 *  GNU General Public License for more details.
16
 
 *  
17
 
 *  You should have received a copy of the GNU General Public License
18
 
 *  along with this program; if not, write to the Free Software
19
 
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
 
 */
21
 
 
22
 
#include "includes.h"
23
 
 
24
 
/*********************************************************
25
 
 Change the domain password on the PDC.
26
 
 
27
 
 Just changes the password betwen the two values specified.
28
 
 
29
 
 Caller must have the cli connected to the netlogon pipe
30
 
 already.
31
 
**********************************************************/
32
 
 
33
 
static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, 
34
 
                                         const unsigned char orig_trust_passwd_hash[16],
35
 
                                         const unsigned char new_trust_passwd_hash[16],
36
 
                                         uint32 sec_channel_type)
37
 
{
38
 
        NTSTATUS result;
39
 
 
40
 
        /* Check if the netlogon pipe is open using schannel. If so we
41
 
           already have valid creds. If not we must set them up. */
42
 
 
43
 
        if (cli->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
44
 
                uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
45
 
 
46
 
                result = rpccli_netlogon_setup_creds(cli, 
47
 
                                        cli->cli->desthost, /* server name */
48
 
                                        lp_workgroup(), /* domain */
49
 
                                        global_myname(), /* client name */
50
 
                                        global_myname(), /* machine account name */
51
 
                                        orig_trust_passwd_hash,
52
 
                                        sec_channel_type,
53
 
                                        &neg_flags);
54
 
 
55
 
                if (!NT_STATUS_IS_OK(result)) {
56
 
                        DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n",
57
 
                                 nt_errstr(result)));
58
 
                        return result;
59
 
                }
60
 
        }
61
 
 
62
 
        result = rpccli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash);
63
 
 
64
 
        if (!NT_STATUS_IS_OK(result)) {
65
 
                DEBUG(0,("just_change_the_password: unable to change password (%s)!\n",
66
 
                         nt_errstr(result)));
67
 
        }
68
 
        return result;
69
 
}
70
 
 
71
 
/*********************************************************
72
 
 Change the domain password on the PDC.
73
 
 Store the password ourselves, but use the supplied password
74
 
 Caller must have already setup the connection to the NETLOGON pipe
75
 
**********************************************************/
76
 
 
77
 
NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, 
78
 
                                      const char *domain,
79
 
                                      unsigned char orig_trust_passwd_hash[16],
80
 
                                      uint32 sec_channel_type)
81
 
{
82
 
        unsigned char new_trust_passwd_hash[16];
83
 
        char *new_trust_passwd;
84
 
        char *str;
85
 
        NTSTATUS nt_status;
86
 
                
87
 
        /* Create a random machine account password */
88
 
        str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
89
 
 
90
 
        if ((new_trust_passwd = talloc_strdup(mem_ctx, str)) == NULL) {
91
 
                DEBUG(0, ("talloc_strdup failed\n"));
92
 
                return NT_STATUS_NO_MEMORY;
93
 
        }
94
 
        
95
 
        E_md4hash(new_trust_passwd, new_trust_passwd_hash);
96
 
 
97
 
        nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash,
98
 
                                             new_trust_passwd_hash, sec_channel_type);
99
 
        
100
 
        if (NT_STATUS_IS_OK(nt_status)) {
101
 
                DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n", 
102
 
                         current_timestring(False)));
103
 
                /*
104
 
                 * Return the result of trying to write the new password
105
 
                 * back into the trust account file.
106
 
                 */
107
 
                if (!secrets_store_machine_password(new_trust_passwd, domain, sec_channel_type)) {
108
 
                        nt_status = NT_STATUS_UNSUCCESSFUL;
109
 
                }
110
 
        }
111
 
 
112
 
        return nt_status;
113
 
}
114
 
 
115
 
/*********************************************************
116
 
 Change the domain password on the PDC.
117
 
 Do most of the legwork ourselfs.  Caller must have
118
 
 already setup the connection to the NETLOGON pipe
119
 
**********************************************************/
120
 
 
121
 
NTSTATUS trust_pw_find_change_and_store_it(struct rpc_pipe_client *cli, 
122
 
                                           TALLOC_CTX *mem_ctx, 
123
 
                                           const char *domain) 
124
 
{
125
 
        unsigned char old_trust_passwd_hash[16];
126
 
        uint32 sec_channel_type = 0;
127
 
 
128
 
        if (!secrets_fetch_trust_account_password(domain,
129
 
                                                  old_trust_passwd_hash, 
130
 
                                                  NULL, &sec_channel_type)) {
131
 
                DEBUG(0, ("could not fetch domain secrets for domain %s!\n", domain));
132
 
                return NT_STATUS_UNSUCCESSFUL;
133
 
        }
134
 
        
135
 
        return trust_pw_change_and_store_it(cli, mem_ctx, domain,
136
 
                                            old_trust_passwd_hash,
137
 
                                            sec_channel_type);
138
 
}
139
 
 
140
 
/*********************************************************************
141
 
 Enumerate the list of trusted domains from a DC
142
 
*********************************************************************/
143
 
 
144
 
BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain,
145
 
                                     char ***domain_names, uint32 *num_domains,
146
 
                                     DOM_SID **sids )
147
 
{
148
 
        POLICY_HND      pol;
149
 
        NTSTATUS        result = NT_STATUS_UNSUCCESSFUL;
150
 
        fstring         dc_name;
151
 
        struct in_addr  dc_ip;
152
 
        uint32          enum_ctx = 0;
153
 
        struct cli_state *cli = NULL;
154
 
        struct rpc_pipe_client *lsa_pipe;
155
 
        BOOL            retry;
156
 
 
157
 
        *domain_names = NULL;
158
 
        *num_domains = 0;
159
 
        *sids = NULL;
160
 
 
161
 
        /* lookup a DC first */
162
 
 
163
 
        if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) {
164
 
                DEBUG(3,("enumerate_domain_trusts: can't locate a DC for domain %s\n",
165
 
                        domain));
166
 
                return False;
167
 
        }
168
 
 
169
 
        /* setup the anonymous connection */
170
 
 
171
 
        result = cli_full_connection( &cli, global_myname(), dc_name, &dc_ip, 0, "IPC$", "IPC",
172
 
                "", "", "", 0, Undefined, &retry);
173
 
        if ( !NT_STATUS_IS_OK(result) )
174
 
                goto done;
175
 
 
176
 
        /* open the LSARPC_PIPE */
177
 
 
178
 
        lsa_pipe = cli_rpc_pipe_open_noauth( cli, PI_LSARPC, &result );
179
 
        if ( !lsa_pipe) {
180
 
                goto done;
181
 
        }
182
 
 
183
 
        /* get a handle */
184
 
 
185
 
        result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True,
186
 
                POLICY_VIEW_LOCAL_INFORMATION, &pol);
187
 
        if ( !NT_STATUS_IS_OK(result) )
188
 
                goto done;
189
 
 
190
 
        /* Lookup list of trusted domains */
191
 
 
192
 
        result = rpccli_lsa_enum_trust_dom(lsa_pipe, mem_ctx, &pol, &enum_ctx,
193
 
                num_domains, domain_names, sids);
194
 
        if ( !NT_STATUS_IS_OK(result) )
195
 
                goto done;
196
 
 
197
 
done:
198
 
        /* cleanup */
199
 
        if (cli) {
200
 
                DEBUG(10,("enumerate_domain_trusts: shutting down connection...\n"));
201
 
                cli_shutdown( cli );
202
 
        }
203
 
 
204
 
        return NT_STATUS_IS_OK(result);
205
 
}