2 Unix SMB/CIFS implementation.
3 test suite for RAP sam operations
5 Copyright (C) Guenther Deschner 2010-2011
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 3 of the License, or
10 (at your option) any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "libcli/libcli.h"
23 #include "torture/torture.h"
24 #include "torture/util.h"
25 #include "torture/smbtorture.h"
26 #include "torture/util.h"
27 #include "libcli/rap/rap.h"
28 #include "torture/rap/proto.h"
29 #include "../libcli/auth/libcli_auth.h"
30 #include "torture/rpc/torture_rpc.h"
32 #include <gnutls/gnutls.h>
33 #include <gnutls/crypto.h>
35 #define TEST_RAP_USER "torture_rap_user"
37 static char *samr_rand_pass(TALLOC_CTX
*mem_ctx
, int min_len
)
39 size_t len
= MAX(8, min_len
);
40 char *s
= generate_random_password(mem_ctx
, len
, len
+6);
41 printf("Generated password '%s'\n", s
);
45 static bool test_userpasswordset2_args(struct torture_context
*tctx
,
46 struct smbcli_state
*cli
,
48 const char **password
)
50 struct rap_NetUserPasswordSet2 r
;
51 char *newpass
= samr_rand_pass(tctx
, 8);
55 r
.in
.UserName
= username
;
57 memcpy(r
.in
.OldPassword
, *password
, MIN(strlen(*password
), 16));
58 memcpy(r
.in
.NewPassword
, newpass
, MIN(strlen(newpass
), 16));
59 r
.in
.EncryptedPassword
= 0;
60 r
.in
.RealPasswordLength
= strlen(newpass
);
62 torture_comment(tctx
, "Testing rap_NetUserPasswordSet2(%s)\n", r
.in
.UserName
);
64 torture_assert_ntstatus_ok(tctx
,
65 smbcli_rap_netuserpasswordset2(cli
->tree
, tctx
, &r
),
66 "smbcli_rap_netuserpasswordset2 failed");
67 if (!W_ERROR_IS_OK(W_ERROR(r
.out
.status
))) {
68 torture_warning(tctx
, "RAP NetUserPasswordSet2 gave: %s\n",
69 win_errstr(W_ERROR(r
.out
.status
)));
77 static bool test_userpasswordset2_crypt_args(struct torture_context
*tctx
,
78 struct smbcli_state
*cli
,
80 const char **password
)
82 struct rap_NetUserPasswordSet2 r
;
83 char *newpass
= samr_rand_pass(tctx
, 8);
85 r
.in
.UserName
= username
;
87 E_deshash(*password
, r
.in
.OldPassword
);
88 E_deshash(newpass
, r
.in
.NewPassword
);
90 r
.in
.RealPasswordLength
= strlen(newpass
);
91 r
.in
.EncryptedPassword
= 1;
93 torture_comment(tctx
, "Testing rap_NetUserPasswordSet2(%s)\n", r
.in
.UserName
);
95 torture_assert_ntstatus_ok(tctx
,
96 smbcli_rap_netuserpasswordset2(cli
->tree
, tctx
, &r
),
97 "smbcli_rap_netuserpasswordset2 failed");
98 if (!W_ERROR_IS_OK(W_ERROR(r
.out
.status
))) {
99 torture_warning(tctx
, "RAP NetUserPasswordSet2 gave: %s\n",
100 win_errstr(W_ERROR(r
.out
.status
)));
108 static bool test_userpasswordset2(struct torture_context
*tctx
,
109 struct smbcli_state
*cli
)
111 struct test_join
*join_ctx
;
112 const char *password
;
115 join_ctx
= torture_create_testuser_max_pwlen(tctx
, TEST_RAP_USER
,
116 torture_setting_string(tctx
, "workgroup", NULL
),
119 if (join_ctx
== NULL
) {
120 torture_fail(tctx
, "failed to create user\n");
123 ret
&= test_userpasswordset2_args(tctx
, cli
, TEST_RAP_USER
, &password
);
124 ret
&= test_userpasswordset2_crypt_args(tctx
, cli
, TEST_RAP_USER
, &password
);
126 torture_leave_domain(tctx
, join_ctx
);
131 static bool test_oemchangepassword_args(struct torture_context
*tctx
,
132 struct smbcli_state
*cli
,
133 const char *username
,
134 const char **password
)
136 struct rap_NetOEMChangePassword r
;
138 const char *oldpass
= *password
;
139 char *newpass
= samr_rand_pass(tctx
, 9);
140 uint8_t old_pw_hash
[16];
141 uint8_t new_pw_hash
[16];
142 gnutls_cipher_hd_t cipher_hnd
= NULL
;
143 gnutls_datum_t pw_key
= {
145 .size
= sizeof(old_pw_hash
),
148 r
.in
.UserName
= username
;
150 E_deshash(oldpass
, old_pw_hash
);
151 E_deshash(newpass
, new_pw_hash
);
153 encode_pw_buffer(r
.in
.crypt_password
, newpass
, STR_ASCII
);
155 gnutls_cipher_init(&cipher_hnd
,
156 GNUTLS_CIPHER_ARCFOUR_128
,
159 gnutls_cipher_encrypt(cipher_hnd
,
162 gnutls_cipher_deinit(cipher_hnd
);
163 E_old_pw_hash(new_pw_hash
, old_pw_hash
, r
.in
.password_hash
);
165 torture_comment(tctx
, "Testing rap_NetOEMChangePassword(%s)\n", r
.in
.UserName
);
167 torture_assert_ntstatus_ok(tctx
,
168 smbcli_rap_netoemchangepassword(cli
->tree
, tctx
, &r
),
169 "smbcli_rap_netoemchangepassword failed");
170 if (!W_ERROR_IS_OK(W_ERROR(r
.out
.status
))) {
171 torture_warning(tctx
, "RAP NetOEMChangePassword gave: %s\n",
172 win_errstr(W_ERROR(r
.out
.status
)));
180 static bool test_oemchangepassword(struct torture_context
*tctx
,
181 struct smbcli_state
*cli
)
184 struct test_join
*join_ctx
;
185 const char *password
;
188 join_ctx
= torture_create_testuser_max_pwlen(tctx
, TEST_RAP_USER
,
189 torture_setting_string(tctx
, "workgroup", NULL
),
192 if (join_ctx
== NULL
) {
193 torture_fail(tctx
, "failed to create user\n");
196 ret
= test_oemchangepassword_args(tctx
, cli
, TEST_RAP_USER
, &password
);
198 torture_leave_domain(tctx
, join_ctx
);
203 static bool test_usergetinfo_byname(struct torture_context
*tctx
,
204 struct smbcli_state
*cli
,
205 const char *UserName
)
207 struct rap_NetUserGetInfo r
;
209 uint16_t levels
[] = { 0, 1, 2, 10, 11 };
211 for (i
=0; i
< ARRAY_SIZE(levels
); i
++) {
213 r
.in
.UserName
= UserName
;
214 r
.in
.level
= levels
[i
];
217 torture_comment(tctx
,
218 "Testing rap_NetUserGetInfo(%s) level %d\n", r
.in
.UserName
, r
.in
.level
);
220 torture_assert_ntstatus_ok(tctx
,
221 smbcli_rap_netusergetinfo(cli
->tree
, tctx
, &r
),
222 "smbcli_rap_netusergetinfo failed");
223 torture_assert_werr_ok(tctx
, W_ERROR(r
.out
.status
),
224 "smbcli_rap_netusergetinfo failed");
230 static bool test_usergetinfo(struct torture_context
*tctx
,
231 struct smbcli_state
*cli
)
234 struct test_join
*join_ctx
;
235 const char *password
;
238 join_ctx
= torture_create_testuser_max_pwlen(tctx
, TEST_RAP_USER
,
239 torture_setting_string(tctx
, "workgroup", NULL
),
242 if (join_ctx
== NULL
) {
243 torture_fail(tctx
, "failed to create user\n");
246 ret
= test_usergetinfo_byname(tctx
, cli
, TEST_RAP_USER
);
248 torture_leave_domain(tctx
, join_ctx
);
253 static bool test_useradd(struct torture_context
*tctx
,
254 struct smbcli_state
*cli
)
257 struct rap_NetUserAdd r
;
258 struct rap_NetUserInfo1 info1
;
260 uint16_t levels
[] = { 1 };
261 const char *username
= TEST_RAP_USER
;
263 for (i
=0; i
< ARRAY_SIZE(levels
); i
++) {
267 pwd
= generate_random_password(tctx
, 9, 16);
269 r
.in
.level
= levels
[i
];
270 r
.in
.bufsize
= 0xffff;
271 r
.in
.pwdlength
= strlen(pwd
);
274 switch (r
.in
.level
) {
278 info1
.Name
= username
;
279 memcpy(info1
.Password
, pwd
, MIN(strlen(pwd
), 16));
280 info1
.Priv
= USER_PRIV_USER
;
282 info1
.HomeDir
= "home_dir";
283 info1
.Comment
= "comment";
284 info1
.ScriptPath
= "logon_script";
286 r
.in
.info
.info1
= info1
;
290 torture_comment(tctx
,
291 "Testing rap_NetUserAdd(%s) level %d\n", username
, r
.in
.level
);
293 torture_assert_ntstatus_ok(tctx
,
294 smbcli_rap_netuseradd(cli
->tree
, tctx
, &r
),
295 "smbcli_rap_netuseradd failed");
296 torture_assert_werr_ok(tctx
, W_ERROR(r
.out
.status
),
297 "smbcli_rap_netuseradd failed");
299 torture_assert_ntstatus_ok(tctx
,
300 smbcli_rap_netuseradd(cli
->tree
, tctx
, &r
),
301 "2nd smbcli_rap_netuseradd failed");
302 torture_assert_werr_equal(tctx
, W_ERROR(r
.out
.status
), WERR_NERR_USEREXISTS
,
303 "2nd smbcli_rap_netuseradd failed");
306 struct rap_NetUserDelete d
;
308 d
.in
.UserName
= username
;
310 smbcli_rap_netuserdelete(cli
->tree
, tctx
, &d
);
317 static bool test_userdelete(struct torture_context
*tctx
,
318 struct smbcli_state
*cli
)
321 struct rap_NetUserDelete r
;
324 struct rap_NetUserAdd a
;
327 ZERO_STRUCT(a
.in
.info
.info1
);
329 pwd
= generate_random_password(tctx
, 9, 16);
332 a
.in
.bufsize
= 0xffff;
333 a
.in
.pwdlength
= strlen(pwd
);
335 a
.in
.info
.info1
.Name
= TEST_RAP_USER
;
336 a
.in
.info
.info1
.Priv
= USER_PRIV_USER
;
338 memcpy(a
.in
.info
.info1
.Password
, pwd
, MIN(strlen(pwd
), 16));
340 torture_assert_ntstatus_ok(tctx
,
341 smbcli_rap_netuseradd(cli
->tree
, tctx
, &a
),
342 "smbcli_rap_netuseradd failed");
345 r
.in
.UserName
= TEST_RAP_USER
;
347 torture_comment(tctx
,
348 "Testing rap_NetUserDelete(%s)\n", r
.in
.UserName
);
350 torture_assert_ntstatus_ok(tctx
,
351 smbcli_rap_netuserdelete(cli
->tree
, tctx
, &r
),
352 "smbcli_rap_netuserdelete failed");
353 torture_assert_werr_ok(tctx
, W_ERROR(r
.out
.status
),
354 "smbcli_rap_netuserdelete failed");
356 torture_assert_ntstatus_ok(tctx
,
357 smbcli_rap_netuserdelete(cli
->tree
, tctx
, &r
),
358 "2nd smbcli_rap_netuserdelete failed");
359 torture_assert_werr_equal(tctx
, W_ERROR(r
.out
.status
), WERR_NERR_USERNOTFOUND
,
360 "2nd smbcli_rap_netuserdelete failed");
365 struct torture_suite
*torture_rap_sam(TALLOC_CTX
*mem_ctx
)
367 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "sam");
369 torture_suite_add_1smb_test(suite
, "userpasswordset2", test_userpasswordset2
);
370 torture_suite_add_1smb_test(suite
, "oemchangepassword", test_oemchangepassword
);
371 torture_suite_add_1smb_test(suite
, "usergetinfo", test_usergetinfo
);
372 torture_suite_add_1smb_test(suite
, "useradd", test_useradd
);
373 torture_suite_add_1smb_test(suite
, "userdelete", test_userdelete
);