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 "popt_common.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
&& d2_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
= 0;
282 SMBOWFencrypt(pdb_get_nt_passwd(pdb_entry
), challenge_8
,
284 SMBsesskeygen_ntv1(pdb_get_nt_passwd(pdb_entry
), local_nt_session_key
);
286 if (tsocket_address_inet_from_strings(NULL
, "ip", NULL
, 0, &remote_address
) != 0) {
290 if (tsocket_address_inet_from_strings(NULL
, "ip", NULL
, 0, &local_address
) != 0) {
294 status
= make_user_info(mem_ctx
,
295 &user_info
, pdb_get_username(pdb_entry
), pdb_get_username(pdb_entry
),
296 pdb_get_domain(pdb_entry
), pdb_get_domain(pdb_entry
), lp_netbios_name(),
297 remote_address
,local_address
, "pdbtest",
298 NULL
, &nt_resp
, NULL
, NULL
, NULL
,
299 AUTH_PASSWORD_RESPONSE
);
300 if (!NT_STATUS_IS_OK(status
)) {
301 DEBUG(0, ("Failed to test authentication with check_sam_security_info3: %s\n", nt_errstr(status
)));
305 status
= check_sam_security_info3(&challenge
, NULL
, user_info
, &info3_sam
);
306 if (!NT_STATUS_IS_OK(status
)) {
307 DEBUG(0, ("Failed to test authentication with check_sam_security_info3: %s\n", nt_errstr(status
)));
311 if (memcmp(info3_sam
->base
.key
.key
, local_nt_session_key
, 16) != 0) {
312 DEBUG(0, ("Returned NT session key is incorrect\n"));
316 status
= make_auth3_context_for_ntlm(NULL
, &auth_context
);
318 if (!NT_STATUS_IS_OK(status
)) {
319 DEBUG(0, ("Failed to test authentication with check_sam_security_info3: %s\n", nt_errstr(status
)));
323 ok
= auth3_context_set_challenge(
324 auth_context
, challenge
.data
, "fixed");
326 DBG_ERR("auth3_context_set_challenge failed\n");
330 status
= auth_check_ntlm_password(mem_ctx
,
336 if (!NT_STATUS_IS_OK(status
)) {
337 DEBUG(0, ("Failed to test authentication with auth module: "
338 "%s authoritative[%u].\n",
339 nt_errstr(status
), authoritative
));
343 info3_auth
= talloc_zero(mem_ctx
, struct netr_SamInfo3
);
344 if (info3_auth
== NULL
) {
348 status
= serverinfo_to_SamInfo3(server_info
, info3_auth
);
349 if (!NT_STATUS_IS_OK(status
)) {
350 DEBUG(0, ("serverinfo_to_SamInfo3 failed: %s\n",
355 if (memcmp(info3_auth
->base
.key
.key
, local_nt_session_key
, 16) != 0) {
356 DEBUG(0, ("Returned NT session key is incorrect\n"));
360 if (!dom_sid_equal(info3_sam
->base
.domain_sid
, info3_auth
->base
.domain_sid
)) {
361 DEBUG(0, ("domain_sid in SAM info3 %s does not match domain_sid in AUTH info3 %s\n",
362 dom_sid_string(NULL
, info3_sam
->base
.domain_sid
),
363 dom_sid_string(NULL
, info3_auth
->base
.domain_sid
)));
368 * Compre more details from the two info3 structures,
369 * then test that an expired/disabled/pwdmustchange account
370 * returns the correct errors
373 params
.parameter_control
= user_info
->logon_parameters
;
374 params
.parameter_control
|= WBC_MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT
|
375 WBC_MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT
;
376 params
.level
= WBC_AUTH_USER_LEVEL_RESPONSE
;
378 params
.account_name
= user_info
->client
.account_name
;
379 params
.domain_name
= user_info
->client
.domain_name
;
380 params
.workstation_name
= user_info
->workstation_name
;
382 memcpy(params
.password
.response
.challenge
,
384 sizeof(params
.password
.response
.challenge
));
386 params
.password
.response
.lm_length
=
387 user_info
->password
.response
.lanman
.length
;
388 params
.password
.response
.nt_length
=
389 user_info
->password
.response
.nt
.length
;
391 params
.password
.response
.lm_data
=
392 user_info
->password
.response
.lanman
.data
;
393 params
.password
.response
.nt_data
=
394 user_info
->password
.response
.nt
.data
;
396 wbc_status
= wbcAuthenticateUserEx(¶ms
, &info
, &err
);
397 if (wbc_status
!= WBC_ERR_WINBIND_NOT_AVAILABLE
) {
398 if (wbc_status
== WBC_ERR_AUTH_ERROR
) {
400 DEBUG(1, ("error was %s (0x%08x)\nerror message was '%s'\n",
401 err
->nt_string
, err
->nt_status
, err
->display_string
));
402 status
= NT_STATUS(err
->nt_status
);
405 status
= NT_STATUS_LOGON_FAILURE
;
407 if (!NT_STATUS_IS_OK(status
)) {
410 } else if (!WBC_ERROR_IS_OK(wbc_status
)) {
411 DEBUG(1, ("wbcAuthenticateUserEx: failed with %u - %s\n",
412 wbc_status
, wbcErrorString(wbc_status
)));
414 DEBUG(1, ("error was %s (0x%08x)\nerror message was '%s'\n",
415 err
->nt_string
, err
->nt_status
, err
->display_string
));
419 info6_wbc
= wbcAuthUserInfo_to_netr_SamInfo6(mem_ctx
, info
);
422 DEBUG(1, ("wbcAuthUserInfo_to_netr_SamInfo6 failed\n"));
426 if (memcmp(info6_wbc
->base
.key
.key
, local_nt_session_key
, 16) != 0) {
427 DEBUG(0, ("Returned NT session key is incorrect\n"));
431 if (!dom_sid_equal(info3_sam
->base
.domain_sid
, info6_wbc
->base
.domain_sid
)) {
432 DEBUG(0, ("domain_sid in SAM info3 %s does not match domain_sid in AUTH info3 %s\n",
433 dom_sid_string(NULL
, info3_sam
->base
.domain_sid
),
434 dom_sid_string(NULL
, info6_wbc
->base
.domain_sid
)));
442 static bool test_trusted_domains(TALLOC_CTX
*ctx
,
443 struct pdb_methods
*pdb
,
447 /* test trustdom calls */
448 struct pdb_trusted_domain
*td
;
449 struct pdb_trusted_domain
*new_td
;
450 struct trustAuthInOutBlob taiob
;
451 struct AuthenticationInformation aia
;
452 enum ndr_err_code ndr_err
;
455 td
= talloc_zero(ctx
,struct pdb_trusted_domain
);
457 fprintf(stderr
, "talloc failed\n");
461 td
->domain_name
= talloc_strdup(td
, TRUST_DOM
);
462 td
->netbios_name
= talloc_strdup(td
, TRUST_DOM
);
463 if (!td
->domain_name
|| !td
->netbios_name
) {
464 fprintf(stderr
, "talloc failed\n");
467 ok
= dom_sid_parse("S-1-5-21-123-456-789", &td
->security_identifier
);
469 fprintf(stderr
, "dom_sid_parse S-1-5-21-123-456-789 failed\n");
473 td
->trust_auth_incoming
= data_blob_null
;
478 taiob
.current
.count
= 1;
479 taiob
.current
.array
= &aia
;
480 unix_to_nt_time(&aia
.LastUpdateTime
, time(NULL
));
481 aia
.AuthType
= TRUST_AUTH_TYPE_CLEAR
;
482 aia
.AuthInfo
.clear
.password
= (uint8_t *) talloc_strdup(ctx
, TRUST_PWD
);
483 aia
.AuthInfo
.clear
.size
= strlen(TRUST_PWD
);
485 taiob
.previous
.count
= 0;
486 taiob
.previous
.array
= NULL
;
488 ndr_err
= ndr_push_struct_blob(&td
->trust_auth_outgoing
,
490 (ndr_push_flags_fn_t
) ndr_push_trustAuthInOutBlob
);
491 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
492 fprintf(stderr
, "ndr_push_struct_blob failed.\n");
496 td
->trust_direction
= LSA_TRUST_DIRECTION_OUTBOUND
;
497 td
->trust_type
= LSA_TRUST_TYPE_DOWNLEVEL
;
498 td
->trust_attributes
= 0;
499 td
->trust_forest_trust_info
= data_blob_null
;
501 rv
= pdb
->set_trusted_domain(pdb
, TRUST_DOM
, td
);
502 if (!NT_STATUS_IS_OK(rv
)) {
503 fprintf(stderr
, "Error in set_trusted_domain %s\n",
504 get_friendly_nt_error_msg(rv
));
508 rv
= pdb
->get_trusted_domain(pdb
, ctx
, TRUST_DOM
, &new_td
);
509 if (!NT_STATUS_IS_OK(rv
)) {
510 fprintf(stderr
, "Error in get_trusted_domain %s\n",
511 get_friendly_nt_error_msg(rv
));
515 if (!strequal(td
->domain_name
, new_td
->domain_name
) ||
516 !strequal(td
->netbios_name
, new_td
->netbios_name
) ||
517 !dom_sid_equal(&td
->security_identifier
,
518 &new_td
->security_identifier
) ||
519 td
->trust_direction
!= new_td
->trust_direction
||
520 td
->trust_type
!= new_td
->trust_type
||
521 td
->trust_attributes
!= new_td
->trust_attributes
||
522 td
->trust_auth_incoming
.length
!= new_td
->trust_auth_incoming
.length
||
523 td
->trust_forest_trust_info
.length
!= new_td
->trust_forest_trust_info
.length
||
524 data_blob_cmp(&td
->trust_auth_outgoing
, &new_td
->trust_auth_outgoing
) != 0) {
525 fprintf(stderr
, "Old and new trusdet domain data do not match\n");
529 rv
= pdb
->del_trusted_domain(pdb
, TRUST_DOM
);
530 if (!NT_STATUS_IS_OK(rv
)) {
531 fprintf(stderr
, "Error in del_trusted_domain %s\n",
532 get_friendly_nt_error_msg(rv
));
540 int main(int argc
, const char **argv
)
543 struct samu
*out
= NULL
;
544 struct samu
*in
= NULL
;
551 uint32_t expire
, min_age
, history
;
552 struct pdb_methods
*pdb
;
554 static const char *backend
= NULL
;
555 static const char *unix_user
= "nobody";
556 struct poptOption long_options
[] = {
557 {"username", 'u', POPT_ARG_STRING
, &unix_user
, 0, "Unix user to use for testing", "USERNAME" },
558 {"backend", 'b', POPT_ARG_STRING
, &backend
, 0, "Backend to use if not default", "BACKEND[:SETTINGS]" },
564 ctx
= talloc_stackframe();
568 pc
= poptGetContext("pdbtest", argc
, argv
, long_options
, 0);
570 poptSetOtherOptionHelp(pc
, "backend[:settings] username");
572 while(poptGetNextOpt(pc
) != -1);
576 /* Load configuration */
577 lp_load_global(get_dyn_CONFIGFILE());
578 setup_logging("pdbtest", DEBUG_STDOUT
);
581 if (backend
== NULL
) {
582 backend
= lp_passdb_backend();
585 rv
= make_pdb_method_name(&pdb
, backend
);
586 if (NT_STATUS_IS_ERR(rv
)) {
587 fprintf(stderr
, "Error initializing '%s': %s\n", backend
, get_friendly_nt_error_msg(rv
));
591 if (!(out
= samu_new(ctx
))) {
592 fprintf(stderr
, "Can't create samu structure.\n");
596 if ((pwd
= Get_Pwnam_alloc(ctx
, unix_user
)) == NULL
) {
597 fprintf(stderr
, "Error getting user information for %s\n", unix_user
);
601 samu_set_unix(out
, pwd
);
603 pdb_set_profile_path(out
, "\\\\torture\\profile", PDB_SET
);
604 pdb_set_homedir(out
, "\\\\torture\\home", PDB_SET
);
605 pdb_set_logon_script(out
, "torture_script.cmd", PDB_SET
);
607 pdb_set_acct_ctrl(out
, ACB_NORMAL
, PDB_SET
);
609 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &history
);
610 if (history
* PW_HISTORY_ENTRY_LEN
< NT_HASH_LEN
) {
611 buf
= (uint8_t *)TALLOC(ctx
, NT_HASH_LEN
);
613 buf
= (uint8_t *)TALLOC(ctx
, history
* PW_HISTORY_ENTRY_LEN
);
616 /* Generate some random hashes */
619 for (i
= 0; i
< NT_HASH_LEN
; i
++) {
620 buf
[i
] = (uint8_t) rand();
622 pdb_set_nt_passwd(out
, buf
, PDB_SET
);
623 for (i
= 0; i
< LM_HASH_LEN
; i
++) {
624 buf
[i
] = (uint8_t) rand();
626 pdb_set_lanman_passwd(out
, buf
, PDB_SET
);
627 for (i
= 0; i
< history
* PW_HISTORY_ENTRY_LEN
; i
++) {
628 buf
[i
] = (uint8_t) rand();
630 pdb_set_pw_history(out
, buf
, history
, PDB_SET
);
632 pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE
, &expire
);
633 pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE
, &min_age
);
634 pdb_set_pass_last_set_time(out
, time(NULL
), PDB_SET
);
636 if (min_age
== (uint32_t)-1) {
637 pdb_set_pass_can_change_time(out
, 0, PDB_SET
);
639 pdb_set_pass_can_change_time(out
, time(NULL
)+min_age
, PDB_SET
);
642 pdb_set_logon_time(out
, time(NULL
)-3600, PDB_SET
);
644 pdb_set_logoff_time(out
, time(NULL
), PDB_SET
);
646 pdb_set_kickoff_time(out
, time(NULL
)+3600, PDB_SET
);
649 if (!NT_STATUS_IS_OK(rv
= pdb
->add_sam_account(pdb
, out
))) {
650 fprintf(stderr
, "Error in add_sam_account: %s\n",
651 get_friendly_nt_error_msg(rv
));
655 if (!(in
= samu_new(ctx
))) {
656 fprintf(stderr
, "Can't create samu structure.\n");
660 /* Get account information through getsampwnam() */
661 rv
= pdb
->getsampwnam(pdb
, in
, out
->username
);
662 if (NT_STATUS_IS_ERR(rv
)) {
663 fprintf(stderr
, "Error getting sampw of added user %s: %s\n",
664 out
->username
, nt_errstr(rv
));
665 if (!NT_STATUS_IS_OK(rv
= pdb
->delete_sam_account(pdb
, out
))) {
666 fprintf(stderr
, "Error in delete_sam_account %s\n",
667 get_friendly_nt_error_msg(rv
));
673 /* Verify integrity */
674 if (samu_correct(out
, in
)) {
675 printf("User info written correctly\n");
677 printf("User info NOT written correctly\n");
681 if (test_auth(ctx
, out
)) {
682 printf("Authentication module test passed\n");
684 printf("Authentication module test failed!\n");
690 if (!NT_STATUS_IS_OK(rv
= pdb
->delete_sam_account(pdb
, out
))) {
691 fprintf(stderr
, "Error in delete_sam_account %s\n",
692 get_friendly_nt_error_msg(rv
));
695 if (pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX
) {
696 if (!test_trusted_domains(ctx
, pdb
, &error
)) {
697 fprintf(stderr
, "failed testing trusted domains.\n");