From 784b05c4895fa8d7f5215d4444bc74e91a918114 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 26 Jan 2004 08:45:02 +0000 Subject: This adds client-side support for the unicode/SAMR password change scheme. As well as avoiding DOS charset issues, this scheme returns useful error codes, that we can map back via the pam interface. This patch also cleans up the interfaces used for password buffers, to avoid duplication of code. Andrew Bartlett (This used to be commit 2a2b1f0c872d154fbcce71a250e23dfad085ba1e) --- source3/Makefile.in | 8 ++-- source3/libsmb/clirap.c | 12 +++--- source3/libsmb/passchange.c | 88 +++++++++++++++++++++++++++++++-------- source3/libsmb/smbencrypt.c | 68 +++++++++++++++--------------- source3/nsswitch/winbindd_pam.c | 10 +---- source3/rpc_client/cli_samr.c | 90 ++++++++++++++++++++++++++++++++++++++++ source3/rpc_parse/parse_samr.c | 14 +++---- source3/rpc_server/srv_samr_nt.c | 4 +- source3/utils/net_rpc.c | 8 +--- source3/utils/net_rpc_join.c | 9 +--- 10 files changed, 220 insertions(+), 91 deletions(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index a01a641842..d9a4cba711 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -226,7 +226,7 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \ libsmb/cliquota.o libsmb/clifsinfo.o \ libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \ libsmb/clioplock.o libsmb/errormap.o libsmb/clirap2.o \ - libsmb/passchange.o libsmb/doserr.o \ + libsmb/doserr.o \ $(RPC_PARSE_OBJ1) $(LIBSAMBA_OBJ) $(LIBNMB_OBJ) LIBMSRPC_OBJ = rpc_client/cli_lsarpc.o rpc_client/cli_samr.o \ @@ -407,7 +407,7 @@ SWAT_OBJ1 = web/cgi.o web/diagnose.o web/startstop.o web/statuspage.o \ SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(LIBSMB_OBJ) \ $(LOCKING_OBJ) $(PASSDB_OBJ) $(SECRETS_OBJ) $(KRBCLIENT_OBJ) \ $(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \ - $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) lib/dummyroot.o + $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ) libsmb/passchange.o lib/dummyroot.o SMBSH_OBJ = smbwrapper/smbsh.o smbwrapper/shared.o \ $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) @@ -432,10 +432,10 @@ TESTPARM_OBJ = utils/testparm.o \ TESTPRNS_OBJ = utils/testprns.o $(PARAM_OBJ) $(PRINTING_OBJ) $(UBIQX_OBJ) \ $(LIB_OBJ) -SMBPASSWD_OBJ = utils/smbpasswd.o $(PARAM_OBJ) $(SECRETS_OBJ) \ +SMBPASSWD_OBJ = utils/smbpasswd.o libsmb/passchange.o $(PARAM_OBJ) $(SECRETS_OBJ) \ $(LIBSMB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ)\ $(UBIQX_OBJ) $(LIB_OBJ) $(KRBCLIENT_OBJ) \ - $(SMBLDAP_OBJ) lib/dummyroot.o + $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ) lib/dummyroot.o PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(PASSDB_OBJ) $(LIBSAMBA_OBJ) \ $(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ) $(SECRETS_OBJ) \ diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 79ad38fc8c..36bc403e0b 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -291,7 +291,6 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char char *rparam = NULL; char *rdata = NULL; unsigned int rprcnt, rdrcnt; - pstring dos_new_password; if (strlen(user) >= sizeof(fstring)-1) { DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user)); @@ -317,10 +316,13 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char */ E_deshash(old_password, old_pw_hash); - clistr_push(cli, dos_new_password, new_password, sizeof(dos_new_password), STR_TERMINATE|STR_ASCII); - - if (!make_oem_passwd_hash( data, dos_new_password, old_pw_hash, False)) - return False; + encode_pw_buffer(data, new_password, STR_ASCII); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("make_oem_passwd_hash\n")); + dump_data(100, data, 516); +#endif + SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, 516); /* * Now place the old password hash in the data. diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 41b6095520..dc0cbbcb7c 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -30,6 +30,9 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, struct nmb_name calling, called; struct cli_state cli; struct in_addr ip; + struct ntuser_creds creds; + + NTSTATUS result; *err_str = '\0'; @@ -66,18 +69,28 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, return False; } - /* - * We should connect as the anonymous user here, in case - * the server has "must change password" checked... - * Thanks to for this fix. - */ + /* Given things like SMB signing, restrict anonymous and the like, + try an authenticated connection first */ + if (!cli_session_setup(&cli, user_name, old_passwd, strlen(old_passwd)+1, old_passwd, strlen(old_passwd)+1, "")) { + /* + * We should connect as the anonymous user here, in case + * the server has "must change password" checked... + * Thanks to for this fix. + */ - if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { - slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - cli_shutdown(&cli); - return False; - } + if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { + slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + cli_shutdown(&cli); + return False; + } + + init_creds(&creds, "", "", NULL); + cli_init_creds(&cli, &creds); + } else { + init_creds(&creds, user_name, "", old_passwd); + cli_init_creds(&cli, &creds); + } if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { slprintf(err_str, err_str_len-1, "machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", @@ -86,13 +99,54 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, return False; } - if(!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { - slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - cli_shutdown(&cli); - return False; - } + /* Try not to give the password away to easily */ + + cli.pipe_auth_flags = AUTH_PIPE_NTLMSSP; + cli.pipe_auth_flags |= AUTH_PIPE_SIGN; + cli.pipe_auth_flags |= AUTH_PIPE_SEAL; + if ( !cli_nt_session_open( &cli, PI_SAMR ) ) { + if (lp_client_lanman_auth()) { + if (!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { + slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + cli_shutdown(&cli); + return False; + } + } else { + slprintf(err_str, err_str_len-1, "machine %s does not support SAMR connections, but LANMAN password changed are disabled\n", + remote_machine); + cli_shutdown(&cli); + return False; + } + } + + if (!NT_STATUS_IS_OK(result = cli_samr_chgpasswd_user(&cli, cli.mem_ctx, user_name, + new_passwd, old_passwd))) { + + if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) + || NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) { + /* try the old Lanman method */ + if (lp_client_lanman_auth()) { + if (!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { + slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + cli_shutdown(&cli); + return False; + } + } else { + slprintf(err_str, err_str_len-1, "machine %s does not support SAMR connections, but LANMAN password changed are disabled\n", + remote_machine); + cli_shutdown(&cli); + return False; + } + } else { + slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", + remote_machine, get_friendly_nt_error_msg(result)); + cli_shutdown(&cli); + return False; + } + } cli_shutdown(&cli); return True; } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index cfcc24a1df..1d192b816a 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -70,20 +70,29 @@ void E_md4hash(const char *passwd, uchar p16[16]) * Creates the DES forward-only Hash of the users password in DOS ASCII charset * @param passwd password in 'unix' charset. * @param p16 return password hashed with DES, caller allocated 16 byte buffer + * @return False if password was > 14 characters, and therefore may be incorrect, otherwise True + * @note p16 is filled in regardless */ -void E_deshash(const char *passwd, uchar p16[16]) +BOOL E_deshash(const char *passwd, uchar p16[16]) { + BOOL ret = True; fstring dospwd; ZERO_STRUCT(dospwd); /* Password must be converted to DOS charset - null terminated, uppercase. */ push_ascii(dospwd, passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); - + /* Only the fisrt 14 chars are considered, password need not be null terminated. */ E_P16((const unsigned char *)dospwd, p16); + if (strlen(dospwd) > 14) { + ret = False; + } + ZERO_STRUCT(dospwd); + + return ret; } /** @@ -219,24 +228,7 @@ void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24) BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode) { - int new_pw_len = strlen(passwd) * (unicode ? 2 : 1); - - if (new_pw_len > 512) - { - DEBUG(0,("make_oem_passwd_hash: new password is too long.\n")); - return False; - } - - /* - * Now setup the data area. - * We need to generate a random fill - * for this area to make it harder to - * decrypt. JRA. - */ - generate_random_buffer((unsigned char *)data, 516, False); - push_string(NULL, &data[512 - new_pw_len], passwd, new_pw_len, - STR_NOALIGN | (unicode?STR_UNICODE:STR_ASCII)); - SIVAL(data, 512, new_pw_len); + encode_pw_buffer(data, passwd, (unicode?STR_UNICODE:STR_ASCII)); #ifdef DEBUG_PASSWORD DEBUG(100,("make_oem_passwd_hash\n")); @@ -473,37 +465,46 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password } /*********************************************************** - encode a password buffer. The caller gets to figure out - what to put in it. + encode a password buffer with a unicode password. The buffer + is filled with random data to make it harder to attack. ************************************************************/ -BOOL encode_pw_buffer(char buffer[516], char *new_pw, int new_pw_length) +BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags) { - generate_random_buffer((unsigned char *)buffer, 516, True); + uchar new_pw[512]; + size_t new_pw_len; - memcpy(&buffer[512 - new_pw_length], new_pw, new_pw_length); + new_pw_len = push_string(NULL, new_pw, + password, + sizeof(new_pw), string_flags); + + memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len); + + generate_random_buffer((unsigned char *)buffer, 512 - new_pw_len, True); /* * The length of the new password is in the last 4 bytes of * the data buffer. */ - SIVAL(buffer, 512, new_pw_length); - + SIVAL(buffer, 512, new_pw_len); + ZERO_STRUCT(new_pw); return True; } + /*********************************************************** decode a password buffer *new_pw_len is the length in bytes of the possibly mulitbyte returned password including termination. ************************************************************/ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, - int new_pwrd_size, uint32 *new_pw_len) + int new_pwrd_size, uint32 *new_pw_len, + int string_flags) { int byte_len=0; /* Warning !!! : This function is called from some rpc call. - The password IN the buffer is a UNICODE string. + The password IN the buffer may be a UNICODE string. The password IN new_pwrd is an ASCII string If you reuse that code somewhere else check first. */ @@ -516,15 +517,16 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, dump_data(100, in_buffer, 516); #endif - /* Password cannot be longer than 128 characters */ - if ( (byte_len < 0) || (byte_len > new_pwrd_size - 1)) { + /* Password cannot be longer than the size of the password buffer */ + if ( (byte_len < 0) || (byte_len > 512)) { DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", byte_len)); DEBUG(0, ("decode_pw_buffer: check that 'encrypt passwords = yes'\n")); return False; } - /* decode into the return buffer. Buffer must be a pstring */ - *new_pw_len = pull_string(NULL, new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, byte_len, STR_UNICODE); + /* decode into the return buffer. Buffer length supplied */ + *new_pw_len = pull_string(NULL, new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, + byte_len, string_flags); #ifdef DEBUG_PASSWORD DEBUG(100,("decode_pw_buffer: new_pwrd: ")); diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index ad4f17cd07..37b2a9f21b 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -506,18 +506,12 @@ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state) /* Get sam handle */ - if ( NT_STATUS_IS_ERR(result = cm_get_sam_handle(contact_domain, &hnd)) ) { + if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(contact_domain, &hnd)) ) { DEBUG(1, ("could not get SAM handle on DC for %s\n", domain)); goto done; } - if (!cli_oem_change_password(hnd->cli, user, newpass, oldpass)) { - DEBUG(1, ("password change failed for user %s/%s\n", domain, - user)); - result = NT_STATUS_WRONG_PASSWORD; - } else { - result = NT_STATUS_OK; - } + result = cli_samr_chgpasswd_user(hnd->cli, mem_ctx, user, newpass, oldpass); done: state->response.data.auth.nt_status = NT_STATUS_V(result); diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c index 0eebcd0a6f..38d2119e83 100644 --- a/source3/rpc_client/cli_samr.c +++ b/source3/rpc_client/cli_samr.c @@ -1043,6 +1043,96 @@ NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* User change password */ + +NTSTATUS cli_samr_chgpasswd_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, + const char *username, + const char *newpassword, + const char *oldpassword ) +{ + prs_struct qbuf, rbuf; + SAMR_Q_CHGPASSWD_USER q; + SAMR_R_CHGPASSWD_USER r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + uchar new_nt_password[516]; + uchar new_lm_password[516]; + uchar old_nt_hash[16]; + uchar old_lanman_hash[16]; + uchar old_nt_hash_enc[16]; + uchar old_lanman_hash_enc[16]; + + uchar new_nt_hash[16]; + uchar new_lanman_hash[16]; + + DEBUG(10,("cli_samr_query_dom_info\n")); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Calculate the MD4 hash (NT compatible) of the password */ + E_md4hash(oldpassword, old_nt_hash); + E_md4hash(newpassword, new_nt_hash); + + if (lp_client_lanman_auth() + && E_deshash(newpassword, new_lanman_hash) + && E_deshash(oldpassword, old_lanman_hash)) { + /* E_deshash returns false for 'long' passwords (> 14 + DOS chars). This allows us to match Win2k, which + does not store a LM hash for these passwords (which + would reduce the effective password length to 14) */ + + encode_pw_buffer(new_lm_password, newpassword, STR_UNICODE); + + SamOEMhash( new_lm_password, old_nt_hash, 516); + E_old_pw_hash( new_nt_hash, old_lanman_hash, old_lanman_hash_enc); + } else { + ZERO_STRUCT(new_lm_password); + ZERO_STRUCT(old_lanman_hash_enc); + } + + encode_pw_buffer(new_nt_password, newpassword, STR_UNICODE); + + SamOEMhash( new_nt_password, old_nt_hash, 516); + E_old_pw_hash( new_nt_hash, old_nt_hash, old_nt_hash_enc); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_chgpasswd_user(&q, cli->srv_name_slash, username, + new_nt_password, + old_nt_hash_enc, + new_lm_password, + old_lanman_hash_enc); + + if (!samr_io_q_chgpasswd_user("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_CHGPASSWD_USER, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_chgpasswd_user("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + if (!NT_STATUS_IS_OK(result = r.status)) { + goto done; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /* This function returns the bizzare set of (max_entries, max_size) required for the QueryDisplayInfo RPC to actually work against a domain controller with large (10k and higher) numbers of users. These values were diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index 607c9ecf64..712baa5cf7 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -6954,7 +6954,7 @@ BOOL samr_io_r_get_dom_pwinfo(const char *desc, SAMR_R_GET_DOM_PWINFO * r_u, make a SAMR_ENC_PASSWD structure. ********************************************************************/ -void init_enc_passwd(SAMR_ENC_PASSWD * pwd, char pass[512]) +void init_enc_passwd(SAMR_ENC_PASSWD * pwd, const char pass[512]) { ZERO_STRUCTP(pwd); @@ -6997,7 +6997,7 @@ BOOL samr_io_enc_passwd(const char *desc, SAMR_ENC_PASSWD * pwd, inits a SAMR_ENC_HASH structure. ********************************************************************/ -void init_enc_hash(SAMR_ENC_HASH * hsh, uchar hash[16]) +void init_enc_hash(SAMR_ENC_HASH * hsh, const uchar hash[16]) { ZERO_STRUCTP(hsh); @@ -7040,11 +7040,11 @@ inits a SAMR_R_GET_DOM_PWINFO structure. ********************************************************************/ void init_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER * q_u, - char *dest_host, char *user_name, - char nt_newpass[516], - uchar nt_oldhash[16], - char lm_newpass[516], - uchar lm_oldhash[16]) + const char *dest_host, const char *user_name, + const char nt_newpass[516], + const uchar nt_oldhash[16], + const char lm_newpass[516], + const uchar lm_oldhash[16]) { DEBUG(5, ("init_samr_q_chgpasswd_user\n")); diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index f189587e85..bcb5b239be 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -2815,7 +2815,7 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid) acct_ctrl = pdb_get_acct_ctrl(pwd); - if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) { + if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) { pdb_free_sam(&pwd); return False; } @@ -2881,7 +2881,7 @@ static BOOL set_user_info_pw(char *pass, DOM_SID *sid) ZERO_STRUCT(plaintext_buf); - if (!decode_pw_buffer(pass, plaintext_buf, 256, &len)) { + if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) { pdb_free_sam(&pwd); return False; } diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index eb5a9634c8..804faf3b9a 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -1849,15 +1849,9 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli { SAM_USERINFO_CTR ctr; SAM_USER_INFO_24 p24; - fstring ucs2_trust_password; - int ucs2_pw_len; uchar pwbuf[516]; - ucs2_pw_len = push_ucs2(NULL, ucs2_trust_password, argv[1], - sizeof(ucs2_trust_password), 0); - - encode_pw_buffer((char *)pwbuf, ucs2_trust_password, - ucs2_pw_len); + encode_pw_buffer((char *)pwbuf, argv[1], STR_UNICODE); ZERO_STRUCT(ctr); ZERO_STRUCT(p24); diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index eb91a7df61..6bfeedc8a0 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -115,8 +115,6 @@ int net_rpc_join_newstyle(int argc, const char **argv) /* Password stuff */ char *clear_trust_password = NULL; - fstring ucs2_trust_password; - int ucs2_pw_len; uchar pwbuf[516]; SAM_USERINFO_CTR ctr; SAM_USER_INFO_24 p24; @@ -264,12 +262,7 @@ int net_rpc_join_newstyle(int argc, const char **argv) E_md4hash(clear_trust_password, md4_trust_password); } - ucs2_pw_len = push_ucs2(NULL, ucs2_trust_password, - clear_trust_password, - sizeof(ucs2_trust_password), 0); - - encode_pw_buffer((char *)pwbuf, ucs2_trust_password, - ucs2_pw_len); + encode_pw_buffer(pwbuf, clear_trust_password, STR_UNICODE); /* Set password on machine account */ -- cgit