Merge branch 'master' of ssh://git.samba.org/data/git/samba into displaysec
[sfrench/samba-autobuild/.git] / source3 / rpc_client / cli_samr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    RPC pipe client
4    Copyright (C) Tim Potter                        2000-2001,
5    Copyright (C) Andrew Tridgell              1992-1997,2000,
6    Copyright (C) Rafal Szczesniak                       2002.
7    Copyright (C) Jeremy Allison                         2005.
8    Copyright (C) Guenther Deschner                      2008.
9    
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25
26 /* User change password */
27
28 NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli,
29                                     TALLOC_CTX *mem_ctx,
30                                     struct policy_handle *user_handle,
31                                     const char *newpassword,
32                                     const char *oldpassword)
33 {
34         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
35         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
36
37         uchar old_nt_hash[16];
38         uchar old_lm_hash[16];
39         uchar new_nt_hash[16];
40         uchar new_lm_hash[16];
41
42         ZERO_STRUCT(old_nt_hash);
43         ZERO_STRUCT(old_lm_hash);
44         ZERO_STRUCT(new_nt_hash);
45         ZERO_STRUCT(new_lm_hash);
46
47         DEBUG(10,("rpccli_samr_chgpasswd_user\n"));
48
49         E_md4hash(oldpassword, old_nt_hash);
50         E_md4hash(newpassword, new_nt_hash);
51
52         E_deshash(oldpassword, old_lm_hash);
53         E_deshash(newpassword, new_lm_hash);
54
55         E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
56         E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
57         E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
58         E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
59         E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
60         E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
61
62         result = rpccli_samr_ChangePasswordUser(cli, mem_ctx,
63                                                 user_handle,
64                                                 true,
65                                                 &hash1,
66                                                 &hash2,
67                                                 true,
68                                                 &hash3,
69                                                 &hash4,
70                                                 true,
71                                                 &hash5,
72                                                 true,
73                                                 &hash6);
74
75         return result;
76 }
77
78
79 /* User change password */
80
81 NTSTATUS rpccli_samr_chgpasswd_user2(struct rpc_pipe_client *cli,
82                                      TALLOC_CTX *mem_ctx,
83                                      const char *username,
84                                      const char *newpassword,
85                                      const char *oldpassword)
86 {
87         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
88         struct samr_CryptPassword new_nt_password;
89         struct samr_CryptPassword new_lm_password;
90         struct samr_Password old_nt_hash_enc;
91         struct samr_Password old_lanman_hash_enc;
92
93         uchar old_nt_hash[16];
94         uchar old_lanman_hash[16];
95         uchar new_nt_hash[16];
96         uchar new_lanman_hash[16];
97         struct lsa_String server, account;
98
99         DEBUG(10,("rpccli_samr_chgpasswd_user2\n"));
100
101         init_lsa_String(&server, cli->srv_name_slash);
102         init_lsa_String(&account, username);
103
104         /* Calculate the MD4 hash (NT compatible) of the password */
105         E_md4hash(oldpassword, old_nt_hash);
106         E_md4hash(newpassword, new_nt_hash);
107
108         if (lp_client_lanman_auth() &&
109             E_deshash(newpassword, new_lanman_hash) &&
110             E_deshash(oldpassword, old_lanman_hash)) {
111                 /* E_deshash returns false for 'long' passwords (> 14
112                    DOS chars).  This allows us to match Win2k, which
113                    does not store a LM hash for these passwords (which
114                    would reduce the effective password length to 14) */
115
116                 encode_pw_buffer(new_lm_password.data, newpassword, STR_UNICODE);
117
118                 SamOEMhash(new_lm_password.data, old_nt_hash, 516);
119                 E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash);
120         } else {
121                 ZERO_STRUCT(new_lm_password);
122                 ZERO_STRUCT(old_lanman_hash_enc);
123         }
124
125         encode_pw_buffer(new_nt_password.data, newpassword, STR_UNICODE);
126
127         SamOEMhash(new_nt_password.data, old_nt_hash, 516);
128         E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
129
130         result = rpccli_samr_ChangePasswordUser2(cli, mem_ctx,
131                                                  &server,
132                                                  &account,
133                                                  &new_nt_password,
134                                                  &old_nt_hash_enc,
135                                                  true,
136                                                  &new_lm_password,
137                                                  &old_lanman_hash_enc);
138
139         return result;
140 }
141
142 /* User change password given blobs */
143
144 NTSTATUS rpccli_samr_chng_pswd_auth_crap(struct rpc_pipe_client *cli,
145                                          TALLOC_CTX *mem_ctx,
146                                          const char *username,
147                                          DATA_BLOB new_nt_password_blob,
148                                          DATA_BLOB old_nt_hash_enc_blob,
149                                          DATA_BLOB new_lm_password_blob,
150                                          DATA_BLOB old_lm_hash_enc_blob)
151 {
152         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
153         struct samr_CryptPassword new_nt_password;
154         struct samr_CryptPassword new_lm_password;
155         struct samr_Password old_nt_hash_enc;
156         struct samr_Password old_lm_hash_enc;
157         struct lsa_String server, account;
158
159         DEBUG(10,("rpccli_samr_chng_pswd_auth_crap\n"));
160
161         init_lsa_String(&server, cli->srv_name_slash);
162         init_lsa_String(&account, username);
163
164         memcpy(&new_nt_password.data, new_nt_password_blob.data, 516);
165         memcpy(&new_lm_password.data, new_lm_password_blob.data, 516);
166         memcpy(&old_nt_hash_enc.hash, old_nt_hash_enc_blob.data, 16);
167         memcpy(&old_lm_hash_enc.hash, old_lm_hash_enc_blob.data, 16);
168
169         result = rpccli_samr_ChangePasswordUser2(cli, mem_ctx,
170                                                  &server,
171                                                  &account,
172                                                  &new_nt_password,
173                                                  &old_nt_hash_enc,
174                                                  true,
175                                                  &new_lm_password,
176                                                  &old_lm_hash_enc);
177         return result;
178 }
179
180
181 /* change password 3 */
182
183 NTSTATUS rpccli_samr_chgpasswd_user3(struct rpc_pipe_client *cli,
184                                      TALLOC_CTX *mem_ctx,
185                                      const char *username,
186                                      const char *newpassword,
187                                      const char *oldpassword,
188                                      struct samr_DomInfo1 **dominfo1,
189                                      struct samr_ChangeReject **reject)
190 {
191         NTSTATUS status;
192
193         struct samr_CryptPassword new_nt_password;
194         struct samr_CryptPassword new_lm_password;
195         struct samr_Password old_nt_hash_enc;
196         struct samr_Password old_lanman_hash_enc;
197
198         uchar old_nt_hash[16];
199         uchar old_lanman_hash[16];
200         uchar new_nt_hash[16];
201         uchar new_lanman_hash[16];
202
203         struct lsa_String server, account;
204
205         DEBUG(10,("rpccli_samr_chgpasswd_user3\n"));
206
207         init_lsa_String(&server, cli->srv_name_slash);
208         init_lsa_String(&account, username);
209
210         /* Calculate the MD4 hash (NT compatible) of the password */
211         E_md4hash(oldpassword, old_nt_hash);
212         E_md4hash(newpassword, new_nt_hash);
213
214         if (lp_client_lanman_auth() &&
215             E_deshash(newpassword, new_lanman_hash) &&
216             E_deshash(oldpassword, old_lanman_hash)) {
217                 /* E_deshash returns false for 'long' passwords (> 14
218                    DOS chars).  This allows us to match Win2k, which
219                    does not store a LM hash for these passwords (which
220                    would reduce the effective password length to 14) */
221
222                 encode_pw_buffer(new_lm_password.data, newpassword, STR_UNICODE);
223
224                 SamOEMhash(new_lm_password.data, old_nt_hash, 516);
225                 E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash);
226         } else {
227                 ZERO_STRUCT(new_lm_password);
228                 ZERO_STRUCT(old_lanman_hash_enc);
229         }
230
231         encode_pw_buffer(new_nt_password.data, newpassword, STR_UNICODE);
232
233         SamOEMhash(new_nt_password.data, old_nt_hash, 516);
234         E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
235
236         status = rpccli_samr_ChangePasswordUser3(cli, mem_ctx,
237                                                  &server,
238                                                  &account,
239                                                  &new_nt_password,
240                                                  &old_nt_hash_enc,
241                                                  true,
242                                                  &new_lm_password,
243                                                  &old_lanman_hash_enc,
244                                                  NULL,
245                                                  dominfo1,
246                                                  reject);
247         return status;
248 }
249
250 /* This function returns the bizzare set of (max_entries, max_size) required
251    for the QueryDisplayInfo RPC to actually work against a domain controller
252    with large (10k and higher) numbers of users.  These values were 
253    obtained by inspection using ethereal and NT4 running User Manager. */
254
255 void get_query_dispinfo_params(int loop_count, uint32 *max_entries,
256                                uint32 *max_size)
257 {
258         switch(loop_count) {
259         case 0:
260                 *max_entries = 512;
261                 *max_size = 16383;
262                 break;
263         case 1:
264                 *max_entries = 1024;
265                 *max_size = 32766;
266                 break;
267         case 2:
268                 *max_entries = 2048;
269                 *max_size = 65532;
270                 break;
271         case 3:
272                 *max_entries = 4096;
273                 *max_size = 131064;
274                 break;
275         default:              /* loop_count >= 4 */
276                 *max_entries = 4096;
277                 *max_size = 131071;
278                 break;
279         }
280 }
281
282 NTSTATUS rpccli_try_samr_connects(struct rpc_pipe_client *cli,
283                                   TALLOC_CTX *mem_ctx,
284                                   uint32_t access_mask,
285                                   struct policy_handle *connect_pol)
286 {
287         NTSTATUS status;
288         union samr_ConnectInfo info_in, info_out;
289         struct samr_ConnectInfo1 info1;
290         uint32_t lvl_out = 0;
291
292         ZERO_STRUCT(info1);
293
294         info1.client_version = SAMR_CONNECT_W2K;
295         info_in.info1 = info1;
296
297         status = rpccli_samr_Connect5(cli, mem_ctx,
298                                       cli->srv_name_slash,
299                                       access_mask,
300                                       1,
301                                       &info_in,
302                                       &lvl_out,
303                                       &info_out,
304                                       connect_pol);
305         if (NT_STATUS_IS_OK(status)) {
306                 return status;
307         }
308
309         status = rpccli_samr_Connect4(cli, mem_ctx,
310                                       cli->srv_name_slash,
311                                       SAMR_CONNECT_W2K,
312                                       access_mask,
313                                       connect_pol);
314         if (NT_STATUS_IS_OK(status)) {
315                 return status;
316         }
317
318         status = rpccli_samr_Connect2(cli, mem_ctx,
319                                       cli->srv_name_slash,
320                                       access_mask,
321                                       connect_pol);
322         return status;
323 }
324