2 Unix SMB/CIFS implementation.
5 Copyright (C) Wilco Baan Hofman 2006
6 Copyright (C) Jelmer Vernooij 2006
7 Copyright (C) Andrew Bartlett 2012
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.
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.
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/>.
25 #include "lib/cmdline/cmdline.h"
28 #include "../librpc/gen_ndr/drsblobs.h"
29 #include "../librpc/gen_ndr/ndr_drsblobs.h"
30 #include "../libcli/security/dom_sid.h"
31 #include "../libcli/auth/libcli_auth.h"
32 #include "../auth/common_auth.h"
33 #include "lib/tsocket/tsocket.h"
34 #include "include/auth.h"
35 #include "nsswitch/libwbclient/wbclient.h"
36 #include "auth/auth_sam_reply.h"
38 #define TRUST_DOM "trustdom"
39 #define TRUST_PWD "trustpwd1232"
40 #define TRUST_SID "S-1-5-21-1111111111-2222222222-3333333333"
42 static bool samu_correct(struct samu
*s1
, struct samu
*s2
)
45 uint32_t s1_len
, s2_len
;
46 const char *s1_buf
, *s2_buf
;
47 const uint8_t *d1_buf
, *d2_buf
;
48 const struct dom_sid
*s1_sid
, *s2_sid
;
50 /* Check Unix username */
51 s1_buf
= pdb_get_username(s1
);
52 s2_buf
= pdb_get_username(s2
);
53 if (s2_buf
== NULL
&& s1_buf
!= NULL
) {
54 DEBUG(0, ("Username is not set\n"));
56 } else if (s1_buf
== NULL
) {
58 } else if (strcmp(s1_buf
,s2_buf
)) {
59 DEBUG(0, ("Username not written correctly, want %s, got \"%s\"\n",
61 pdb_get_username(s2
)));
65 /* Check NT username */
66 s1_buf
= pdb_get_nt_username(s1
);
67 s2_buf
= pdb_get_nt_username(s2
);
68 if (s2_buf
== NULL
&& s1_buf
!= NULL
) {
69 DEBUG(0, ("NT Username is not set\n"));
71 } else if (s1_buf
== NULL
) {
73 } else if (strcmp(s1_buf
, s2_buf
)) {
74 DEBUG(0, ("NT Username not written correctly, want \"%s\", got \"%s\"\n",
75 pdb_get_nt_username(s1
),
76 pdb_get_nt_username(s2
)));
81 if (pdb_get_acct_ctrl(s1
) != pdb_get_acct_ctrl(s2
)) {
82 DEBUG(0, ("Acct ctrl field not written correctly, want %d (0x%X), got %d (0x%X)\n",
83 pdb_get_acct_ctrl(s1
),
84 pdb_get_acct_ctrl(s1
),
85 pdb_get_acct_ctrl(s2
),
86 pdb_get_acct_ctrl(s2
)));
90 /* Check NT password */
91 d1_buf
= pdb_get_nt_passwd(s1
);
92 d2_buf
= pdb_get_nt_passwd(s2
);
93 if (d2_buf
== NULL
&& d1_buf
!= NULL
) {
94 DEBUG(0, ("NT password is not set\n"));
96 } else if (d1_buf
== NULL
) {
98 } else if (memcmp(d1_buf
, d2_buf
, NT_HASH_LEN
)) {
99 DEBUG(0, ("NT password not written correctly\n"));
103 /* Check lanman password */
104 d1_buf
= pdb_get_lanman_passwd(s1
);
105 d2_buf
= pdb_get_lanman_passwd(s2
);
106 if (d2_buf
== NULL
&& d1_buf
!= NULL
) {
107 DEBUG(0, ("Lanman password is not set\n"));
108 } else if (d1_buf
== NULL
) {
110 } else if (memcmp(d1_buf
, d2_buf
, NT_HASH_LEN
)) {
111 DEBUG(0, ("Lanman password not written correctly\n"));
115 /* Check password history */
116 d1_buf
= pdb_get_pw_history(s1
, &s1_len
);
117 d2_buf
= pdb_get_pw_history(s2
, &s2_len
);
118 if (d2_buf
== NULL
&& d1_buf
!= NULL
) {
119 DEBUG(0, ("Password history is not set\n"));
120 } else if (d1_buf
== NULL
) {
122 } else if (s1_len
!= s2_len
) {
123 DEBUG(0, ("Password history not written correctly, lengths differ, want %d, got %d\n",
126 } else if (strncmp(s1_buf
, s2_buf
, s1_len
)) {
127 DEBUG(0, ("Password history not written correctly\n"));
131 /* Check logon time */
132 if (pdb_get_logon_time(s1
) != pdb_get_logon_time(s2
)) {
133 DEBUG(0, ("Logon time is not written correctly\n"));
137 /* Check logoff time */
138 if (pdb_get_logoff_time(s1
) != pdb_get_logoff_time(s2
)) {
139 DEBUG(0, ("Logoff time is not written correctly: %s vs %s \n",
140 http_timestring(talloc_tos(), pdb_get_logoff_time(s1
)),
141 http_timestring(talloc_tos(), pdb_get_logoff_time(s2
))));
145 /* Check kickoff time */
146 if (pdb_get_kickoff_time(s1
) != pdb_get_kickoff_time(s2
)) {
147 DEBUG(0, ("Kickoff time is not written correctly: %s vs %s \n",
148 http_timestring(talloc_tos(), pdb_get_kickoff_time(s1
)),
149 http_timestring(talloc_tos(), pdb_get_kickoff_time(s2
))));
153 /* Check bad password time */
154 if (pdb_get_bad_password_time(s1
) != pdb_get_bad_password_time(s2
)) {
155 DEBUG(0, ("Bad password time is not written correctly\n"));
159 /* Check password last set time */
160 if (pdb_get_pass_last_set_time(s1
) != pdb_get_pass_last_set_time(s2
)) {
161 DEBUG(0, ("Password last set time is not written correctly: %s vs %s \n",
162 http_timestring(talloc_tos(), pdb_get_pass_last_set_time(s1
)),
163 http_timestring(talloc_tos(), pdb_get_pass_last_set_time(s2
))));
167 /* Check password can change time */
168 if (pdb_get_pass_can_change_time(s1
) != pdb_get_pass_can_change_time(s2
)) {
169 DEBUG(0, ("Password can change time is not written correctly %s vs %s \n",
170 http_timestring(talloc_tos(), pdb_get_pass_can_change_time(s1
)),
171 http_timestring(talloc_tos(), pdb_get_pass_can_change_time(s2
))));
175 /* Check password must change time */
176 if (pdb_get_pass_must_change_time(s1
) != pdb_get_pass_must_change_time(s2
)) {
177 DEBUG(0, ("Password must change time is not written correctly\n"));
181 /* Check logon divs */
182 if (pdb_get_logon_divs(s1
) != pdb_get_logon_divs(s2
)) {
183 DEBUG(0, ("Logon divs not written correctly\n"));
187 /* Check logon hours */
188 if (pdb_get_hours_len(s1
) != pdb_get_hours_len(s2
)) {
189 DEBUG(0, ("Logon hours length not written correctly\n"));
191 } else if (pdb_get_hours_len(s1
) != 0) {
192 d1_buf
= pdb_get_hours(s1
);
193 d2_buf
= pdb_get_hours(s2
);
194 if (d2_buf
== NULL
&& d1_buf
!= NULL
) {
195 DEBUG(0, ("Logon hours is not set\n"));
197 } else if (d1_buf
== NULL
) {
199 } else if (memcmp(d1_buf
, d2_buf
, MAX_HOURS_LEN
)) {
200 DEBUG(0, ("Logon hours is not written correctly\n"));
205 /* Check profile path */
206 s1_buf
= pdb_get_profile_path(s1
);
207 s2_buf
= pdb_get_profile_path(s2
);
208 if (s2_buf
== NULL
&& s1_buf
!= NULL
) {
209 DEBUG(0, ("Profile path is not set\n"));
211 } else if (s1_buf
== NULL
) {
213 } else if (strcmp(s1_buf
, s2_buf
)) {
214 DEBUG(0, ("Profile path is not written correctly\n"));
219 s1_buf
= pdb_get_homedir(s1
);
220 s2_buf
= pdb_get_homedir(s2
);
221 if (s2_buf
== NULL
&& s1_buf
!= NULL
) {
222 DEBUG(0, ("Home dir is not set\n"));
224 } else if (s1_buf
== NULL
) {
226 } else if (strcmp(s1_buf
, s2_buf
)) {
227 DEBUG(0, ("Home dir is not written correctly\n"));
231 /* Check logon script */
232 s1_buf
= pdb_get_logon_script(s1
);
233 s2_buf
= pdb_get_logon_script(s2
);
234 if (s2_buf
== NULL
&& s1_buf
!= NULL
) {
235 DEBUG(0, ("Logon script not set\n"));
237 } else if (s1_buf
== NULL
) {
239 } else if (strcmp(s1_buf
, s2_buf
)) {
240 DEBUG(0, ("Logon script is not written correctly\n"));
244 /* Check user and group sids */
245 s1_sid
= pdb_get_user_sid(s1
);
246 s2_sid
= pdb_get_user_sid(s2
);
247 if (s2_sid
== NULL
&& s1_sid
!= NULL
) {
248 DEBUG(0, ("USER SID not set\n"));
250 } else if (s1_sid
== NULL
) {
252 } else if (!dom_sid_equal(s1_sid
, s2_sid
)) {
253 DEBUG(0, ("USER SID is not written correctly\n"));
260 static bool test_auth(TALLOC_CTX
*mem_ctx
, struct samu
*pdb_entry
)
262 struct auth_usersupplied_info
*user_info
;
263 struct auth_context
*auth_context
;
264 static const uint8_t challenge_8
[8] = {1, 2, 3, 4, 5, 6, 7, 8};
265 DATA_BLOB challenge
= data_blob_const(challenge_8
, sizeof(challenge_8
));
266 struct tsocket_address
*remote_address
;
267 struct tsocket_address
*local_address
;
268 unsigned char local_nt_response
[24];
269 DATA_BLOB nt_resp
= data_blob_const(local_nt_response
, sizeof(local_nt_response
));
270 unsigned char local_nt_session_key
[16];
271 struct netr_SamInfo3
*info3_sam
, *info3_auth
;
272 struct auth_serversupplied_info
*server_info
;
273 struct wbcAuthUserParams params
= { .flags
= 0 };
274 struct wbcAuthUserInfo
*info
= NULL
;
275 struct wbcAuthErrorInfo
*err
= NULL
;
277 struct netr_SamInfo6
*info6_wbc
= NULL
;
280 uint8_t authoritative
= 1;
283 rc
= SMBOWFencrypt(pdb_get_nt_passwd(pdb_entry
), challenge_8
,
289 SMBsesskeygen_ntv1(pdb_get_nt_passwd(pdb_entry
), local_nt_session_key
);
291 if (tsocket_address_inet_from_strings(NULL
, "ip", NULL
, 0, &remote_address
) != 0) {
295 if (tsocket_address_inet_from_strings(NULL
, "ip", NULL
, 0, &local_address
) != 0) {
299 status
= make_user_info(mem_ctx
,
300 &user_info
, pdb_get_username(pdb_entry
), pdb_get_username(pdb_entry
),
301 pdb_get_domain(pdb_entry
), pdb_get_domain(pdb_entry
), lp_netbios_name(),
302 remote_address
,local_address
, "pdbtest",
303 NULL
, &nt_resp
, NULL
, NULL
, NULL
,
304 AUTH_PASSWORD_RESPONSE
);
305 if (!NT_STATUS_IS_OK(status
)) {
306 DEBUG(0, ("Failed to test authentication with check_sam_security_info3: %s\n", nt_errstr(status
)));
310 status
= check_sam_security_info3(&challenge
, NULL
, user_info
, &info3_sam
);
311 if (!NT_STATUS_IS_OK(status
)) {
312 DEBUG(0, ("Failed to test authentication with check_sam_security_info3: %s\n", nt_errstr(status
)));
316 if (memcmp(info3_sam
->base
.key
.key
, local_nt_session_key
, 16) != 0) {
317 DEBUG(0, ("Returned NT session key is incorrect\n"));
321 status
= make_auth3_context_for_ntlm(NULL
, &auth_context
);
323 if (!NT_STATUS_IS_OK(status
)) {
324 DEBUG(0, ("Failed to test authentication with check_sam_security_info3: %s\n", nt_errstr(status
)));
328 ok
= auth3_context_set_challenge(
329 auth_context
, challenge
.data
, "fixed");
331 DBG_ERR("auth3_context_set_challenge failed\n");
335 status
= auth_check_ntlm_password(mem_ctx
,
341 if (!NT_STATUS_IS_OK(status
)) {
342 DEBUG(0, ("Failed to test authentication with auth module: "
343 "%s authoritative[%u].\n",
344 nt_errstr(status
), authoritative
));
348 info3_auth
= talloc_zero(mem_ctx
, struct netr_SamInfo3
);
349 if (info3_auth
== NULL
) {
353 status
= serverinfo_to_SamInfo3(server_info
, info3_auth
);
354 if (!NT_STATUS_IS_OK(status
)) {
355 DEBUG(0, ("serverinfo_to_SamInfo3 failed: %s\n",
360 if (memcmp(info3_auth
->base
.key
.key
, local_nt_session_key
, 16) != 0) {
361 DEBUG(0, ("Returned NT session key is incorrect\n"));
365 if (!dom_sid_equal(info3_sam
->base
.domain_sid
, info3_auth
->base
.domain_sid
)) {
366 struct dom_sid_buf buf1
, buf2
;
367 DEBUG(0, ("domain_sid in SAM info3 %s does not match domain_sid in AUTH info3 %s\n",
368 dom_sid_str_buf(info3_sam
->base
.domain_sid
, &buf1
),
369 dom_sid_str_buf(info3_auth
->base
.domain_sid
,
375 * Compare more details from the two info3 structures,
376 * then test that an expired/disabled/pwdmustchange account
377 * returns the correct errors
380 params
.parameter_control
= user_info
->logon_parameters
;
381 params
.parameter_control
|= WBC_MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT
|
382 WBC_MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT
;
383 params
.level
= WBC_AUTH_USER_LEVEL_RESPONSE
;
385 params
.account_name
= user_info
->client
.account_name
;
386 params
.domain_name
= user_info
->client
.domain_name
;
387 params
.workstation_name
= user_info
->workstation_name
;
389 memcpy(params
.password
.response
.challenge
,
391 sizeof(params
.password
.response
.challenge
));
393 params
.password
.response
.lm_length
=
394 user_info
->password
.response
.lanman
.length
;
395 params
.password
.response
.nt_length
=
396 user_info
->password
.response
.nt
.length
;
398 params
.password
.response
.lm_data
=
399 user_info
->password
.response
.lanman
.data
;
400 params
.password
.response
.nt_data
=
401 user_info
->password
.response
.nt
.data
;
403 wbc_status
= wbcAuthenticateUserEx(¶ms
, &info
, &err
);
404 if (wbc_status
!= WBC_ERR_WINBIND_NOT_AVAILABLE
) {
405 if (wbc_status
== WBC_ERR_AUTH_ERROR
) {
407 DEBUG(1, ("error was %s (0x%08x)\nerror message was '%s'\n",
408 err
->nt_string
, err
->nt_status
, err
->display_string
));
409 status
= NT_STATUS(err
->nt_status
);
412 status
= NT_STATUS_LOGON_FAILURE
;
414 if (!NT_STATUS_IS_OK(status
)) {
417 } else if (!WBC_ERROR_IS_OK(wbc_status
)) {
418 DEBUG(1, ("wbcAuthenticateUserEx: failed with %u - %s\n",
419 wbc_status
, wbcErrorString(wbc_status
)));
421 DEBUG(1, ("error was %s (0x%08x)\nerror message was '%s'\n",
422 err
->nt_string
, err
->nt_status
, err
->display_string
));
426 info6_wbc
= wbcAuthUserInfo_to_netr_SamInfo6(mem_ctx
, info
);
429 DEBUG(1, ("wbcAuthUserInfo_to_netr_SamInfo6 failed\n"));
433 if (memcmp(info6_wbc
->base
.key
.key
, local_nt_session_key
, 16) != 0) {
434 DEBUG(0, ("Returned NT session key is incorrect\n"));
438 if (!dom_sid_equal(info3_sam
->base
.domain_sid
, info6_wbc
->base
.domain_sid
)) {
439 struct dom_sid_buf buf1
, buf2
;
440 DEBUG(0, ("domain_sid in SAM info3 %s does not match domain_sid in AUTH info3 %s\n",
441 dom_sid_str_buf(info3_sam
->base
.domain_sid
,
443 dom_sid_str_buf(info6_wbc
->base
.domain_sid
,
452 static bool test_trusted_domains(TALLOC_CTX
*ctx
,
453 struct pdb_methods
*pdb
,
457 /* test trustdom calls */
458 struct pdb_trusted_domain
*td
;
459 struct pdb_trusted_domain
*new_td
;
460 struct trustAuthInOutBlob taiob
;
461 struct AuthenticationInformation aia
;
462 enum ndr_err_code ndr_err
;
465 td
= talloc_zero(ctx
,struct pdb_trusted_domain
);
467 fprintf(stderr
, "talloc failed\n");
471 td
->domain_name
= talloc_strdup(td
, TRUST_DOM
);
472 td
->netbios_name
= talloc_strdup(td
, TRUST_DOM
);
473 if (!td
->domain_name
|| !td
->netbios_name
) {
474 fprintf(stderr
, "talloc failed\n");
477 ok
= dom_sid_parse("S-1-5-21-123-456-789", &td
->security_identifier
);
479 fprintf(stderr
, "dom_sid_parse S-1-5-21-123-456-789 failed\n");
483 td
->trust_auth_incoming
= data_blob_null
;
488 taiob
.current
.count
= 1;
489 taiob
.current
.array
= &aia
;
490 unix_to_nt_time(&aia
.LastUpdateTime
, time(NULL
));
491 aia
.AuthType
= TRUST_AUTH_TYPE_CLEAR
;
492 aia
.AuthInfo
.clear
.password
= (uint8_t *) talloc_strdup(ctx
, TRUST_PWD
);
493 aia
.AuthInfo
.clear
.size
= strlen(TRUST_PWD
);
495 taiob
.previous
.count
= 0;
496 taiob
.previous
.array
= NULL
;
498 ndr_err
= ndr_push_struct_blob(&td
->trust_auth_outgoing
,
500 (ndr_push_flags_fn_t
) ndr_push_trustAuthInOutBlob
);
501 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
502 fprintf(stderr
, "ndr_push_struct_blob failed.\n");
506 td
->trust_direction
= LSA_TRUST_DIRECTION_OUTBOUND
;
507 td
->trust_type
= LSA_TRUST_TYPE_DOWNLEVEL
;
508 td
->trust_attributes
= 0;
509 td
->trust_forest_trust_info
= data_blob_null
;
511 rv
= pdb
->set_trusted_domain(pdb
, TRUST_DOM
, td
);
512 if (!NT_STATUS_IS_OK(rv
)) {
513 fprintf(stderr
, "Error in set_trusted_domain %s\n",
514 get_friendly_nt_error_msg(rv
));
518 rv
= pdb
->get_trusted_domain(pdb
, ctx
, TRUST_DOM
, &new_td
);
519 if (!NT_STATUS_IS_OK(rv
)) {
520 fprintf(stderr
, "Error in get_trusted_domain %s\n",
521 get_friendly_nt_error_msg(rv
));
525 if (!strequal(td
->domain_name
, new_td
->domain_name
) ||
526 !strequal(td
->netbios_name
, new_td
->netbios_name
) ||
527 !dom_sid_equal(&td
->security_identifier
,
528 &new_td
->security_identifier
) ||
529 td
->trust_direction
!= new_td
->trust_direction
||
530 td
->trust_type
!= new_td
->trust_type
||
531 td
->trust_attributes
!= new_td
->trust_attributes
||
532 td
->trust_auth_incoming
.length
!= new_td
->trust_auth_incoming
.length
||
533 td
->trust_forest_trust_info
.length
!= new_td
->trust_forest_trust_info
.length
||
534 data_blob_cmp(&td
->trust_auth_outgoing
, &new_td
->trust_auth_outgoing
) != 0) {
535 fprintf(stderr
, "Old and new trusdet domain data do not match\n");
539 rv
= pdb
->del_trusted_domain(pdb
, TRUST_DOM
);
540 if (!NT_STATUS_IS_OK(rv
)) {
541 fprintf(stderr
, "Error in del_trusted_domain %s\n",
542 get_friendly_nt_error_msg(rv
));
550 int main(int argc
, const char **argv
)
553 struct samu
*out
= NULL
;
554 struct samu
*in
= NULL
;
562 uint32_t expire
, min_age
, history
;
563 struct pdb_methods
*pdb
;
565 static const char *backend
= NULL
;
566 static const char *unix_user
= "nobody";
568 struct poptOption long_options
[] = {
569 {"username", 'u', POPT_ARG_STRING
, &unix_user
, 0, "Unix user to use for testing", "USERNAME" },
570 {"backend", 'b', POPT_ARG_STRING
, &backend
, 0, "Backend to use if not default", "BACKEND[:SETTINGS]" },
577 ctx
= talloc_stackframe();
581 ok
= samba_cmdline_init(ctx
,
582 SAMBA_CMDLINE_CONFIG_CLIENT
,
583 true /* require_smbconf */);
589 pc
= samba_popt_get_context(getprogname(), argc
, argv
, long_options
, 0);
595 poptSetOtherOptionHelp(pc
, "backend[:settings] username");
597 while ((opt
= poptGetNextOpt(pc
)) != -1) {
599 case POPT_ERROR_BADOPT
:
600 fprintf(stderr
, "\nInvalid option %s: %s\n\n",
601 poptBadOption(pc
, 0), poptStrerror(opt
));
602 poptPrintUsage(pc
, stderr
, 0);
609 if (backend
== NULL
) {
610 backend
= lp_passdb_backend();
613 rv
= make_pdb_method_name(&pdb
, backend
);
614 if (NT_STATUS_IS_ERR(rv
)) {
615 fprintf(stderr
, "Error initializing '%s': %s\n", backend
, get_friendly_nt_error_msg(rv
));
619 if (!(out
= samu_new(ctx
))) {
620 fprintf(stderr
, "Can't create samu structure.\n");
624 if ((pwd
= Get_Pwnam_alloc(ctx
, unix_user
)) == NULL
) {
625 fprintf(stderr
, "Error getting user information for %s\n", unix_user
);
629 samu_set_unix(out
, pwd
);
631 pdb_set_profile_path(out
, "\\\\torture\\profile", PDB_SET
);
632 pdb_set_homedir(out
, "\\\\torture\\home", PDB_SET
);
633 pdb_set_logon_script(out
, "torture_script.cmd", PDB_SET
);
635 pdb_set_acct_ctrl(out
, ACB_NORMAL
, PDB_SET
);
637 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &history
);
638 if (history
* PW_HISTORY_ENTRY_LEN
< NT_HASH_LEN
) {
639 buf
= (uint8_t *)TALLOC(ctx
, NT_HASH_LEN
);
641 buf
= (uint8_t *)TALLOC(ctx
, history
* PW_HISTORY_ENTRY_LEN
);
644 /* Generate some random hashes */
647 for (i
= 0; i
< NT_HASH_LEN
; i
++) {
648 buf
[i
] = (uint8_t) rand();
650 pdb_set_nt_passwd(out
, buf
, PDB_SET
);
651 for (i
= 0; i
< LM_HASH_LEN
; i
++) {
652 buf
[i
] = (uint8_t) rand();
654 pdb_set_lanman_passwd(out
, buf
, PDB_SET
);
655 for (i
= 0; i
< history
* PW_HISTORY_ENTRY_LEN
; i
++) {
656 buf
[i
] = (uint8_t) rand();
658 pdb_set_pw_history(out
, buf
, history
, PDB_SET
);
660 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE
, &expire
);
661 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE
, &min_age
);
662 pdb_set_pass_last_set_time(out
, time(NULL
), PDB_SET
);
664 if (min_age
== (uint32_t)-1) {
665 pdb_set_pass_can_change_time(out
, 0, PDB_SET
);
667 pdb_set_pass_can_change_time(out
, time(NULL
)+min_age
, PDB_SET
);
670 pdb_set_logon_time(out
, time(NULL
)-3600, PDB_SET
);
672 pdb_set_logoff_time(out
, time(NULL
), PDB_SET
);
674 pdb_set_kickoff_time(out
, time(NULL
)+3600, PDB_SET
);
677 if (!NT_STATUS_IS_OK(rv
= pdb
->add_sam_account(pdb
, out
))) {
678 fprintf(stderr
, "Error in add_sam_account: %s\n",
679 get_friendly_nt_error_msg(rv
));
683 if (!(in
= samu_new(ctx
))) {
684 fprintf(stderr
, "Can't create samu structure.\n");
688 /* Get account information through getsampwnam() */
689 rv
= pdb
->getsampwnam(pdb
, in
, out
->username
);
690 if (NT_STATUS_IS_ERR(rv
)) {
691 fprintf(stderr
, "Error getting sampw of added user %s: %s\n",
692 out
->username
, nt_errstr(rv
));
693 if (!NT_STATUS_IS_OK(rv
= pdb
->delete_sam_account(pdb
, out
))) {
694 fprintf(stderr
, "Error in delete_sam_account %s\n",
695 get_friendly_nt_error_msg(rv
));
701 /* Verify integrity */
702 if (samu_correct(out
, in
)) {
703 printf("User info written correctly\n");
705 printf("User info NOT written correctly\n");
709 if (test_auth(ctx
, out
)) {
710 printf("Authentication module test passed\n");
712 printf("Authentication module test failed!\n");
718 if (!NT_STATUS_IS_OK(rv
= pdb
->delete_sam_account(pdb
, out
))) {
719 fprintf(stderr
, "Error in delete_sam_account %s\n",
720 get_friendly_nt_error_msg(rv
));
723 if (pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX
) {
724 if (!test_trusted_domains(ctx
, pdb
, &error
)) {
725 fprintf(stderr
, "failed testing trusted domains.\n");