関数 | |
| NTSTATUS | remote_password_change (const char *remote_machine, const char *user_name, const char *old_passwd, const char *new_passwd, char *err_str, size_t err_str_len) |
| NTSTATUS remote_password_change | ( | const char * | remote_machine, | |
| const char * | user_name, | |||
| const char * | old_passwd, | |||
| const char * | new_passwd, | |||
| char * | err_str, | |||
| size_t | err_str_len | |||
| ) |
passchange.c の 27 行で定義されています。
参照先 cli・cli_connect()・cli_errstr()・cli_init_creds()・cli_initialise()・cli_negprot()・cli_nt_error()・cli_oem_change_password()・cli_rpc_pipe_close()・cli_rpc_pipe_open_noauth()・cli_rpc_pipe_open_ntlmssp()・cli_send_tconX()・cli_session_request()・cli_session_setup()・cli_shutdown()・get_friendly_nt_error_msg()・global_myname・make_nmb_name()・cli_state::mem_ctx・nt_errstr()・PIPE_AUTH_LEVEL_PRIVACY・cli_state::protocol・PROTOCOL_NT1・resolve_name()・result・rpccli_samr_chgpasswd_user().
参照元 change_password()・password_change().
00030 { 00031 struct nmb_name calling, called; 00032 struct cli_state *cli; 00033 struct rpc_pipe_client *pipe_hnd; 00034 struct in_addr ip; 00035 00036 NTSTATUS result; 00037 BOOL pass_must_change = False; 00038 00039 *err_str = '\0'; 00040 00041 if(!resolve_name( remote_machine, &ip, 0x20)) { 00042 slprintf(err_str, err_str_len-1, "Unable to find an IP address for machine %s.\n", 00043 remote_machine ); 00044 return NT_STATUS_UNSUCCESSFUL; 00045 } 00046 00047 cli = cli_initialise(); 00048 if (!cli) { 00049 return NT_STATUS_NO_MEMORY; 00050 } 00051 00052 result = cli_connect(cli, remote_machine, &ip); 00053 if (!NT_STATUS_IS_OK(result)) { 00054 slprintf(err_str, err_str_len-1, "Unable to connect to SMB server on machine %s. Error was : %s.\n", 00055 remote_machine, nt_errstr(result) ); 00056 cli_shutdown(cli); 00057 return result; 00058 } 00059 00060 make_nmb_name(&calling, global_myname() , 0x0); 00061 make_nmb_name(&called , remote_machine, 0x20); 00062 00063 if (!cli_session_request(cli, &calling, &called)) { 00064 slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", 00065 remote_machine, cli_errstr(cli) ); 00066 result = cli_nt_error(cli); 00067 cli_shutdown(cli); 00068 return result; 00069 } 00070 00071 cli->protocol = PROTOCOL_NT1; 00072 00073 if (!cli_negprot(cli)) { 00074 slprintf(err_str, err_str_len-1, "machine %s rejected the negotiate protocol. Error was : %s.\n", 00075 remote_machine, cli_errstr(cli) ); 00076 result = cli_nt_error(cli); 00077 cli_shutdown(cli); 00078 return result; 00079 } 00080 00081 /* Given things like SMB signing, restrict anonymous and the like, 00082 try an authenticated connection first */ 00083 result = cli_session_setup(cli, user_name, 00084 old_passwd, strlen(old_passwd)+1, 00085 old_passwd, strlen(old_passwd)+1, ""); 00086 00087 if (!NT_STATUS_IS_OK(result)) { 00088 00089 /* Password must change or Password expired are the only valid 00090 * error conditions here from where we can proceed, the rest like 00091 * account locked out or logon failure will lead to errors later 00092 * anyway */ 00093 00094 if (!NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_MUST_CHANGE) && 00095 !NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_EXPIRED)) { 00096 slprintf(err_str, err_str_len-1, "Could not " 00097 "connect to machine %s: %s\n", 00098 remote_machine, cli_errstr(cli)); 00099 cli_shutdown(cli); 00100 return result; 00101 } 00102 00103 pass_must_change = True; 00104 00105 /* 00106 * We should connect as the anonymous user here, in case 00107 * the server has "must change password" checked... 00108 * Thanks to <Nicholas.S.Jenkins@cdc.com> for this fix. 00109 */ 00110 00111 result = cli_session_setup(cli, "", "", 0, "", 0, ""); 00112 00113 if (!NT_STATUS_IS_OK(result)) { 00114 slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", 00115 remote_machine, cli_errstr(cli) ); 00116 cli_shutdown(cli); 00117 return result; 00118 } 00119 00120 cli_init_creds(cli, "", "", NULL); 00121 } else { 00122 cli_init_creds(cli, user_name, "", old_passwd); 00123 } 00124 00125 if (!cli_send_tconX(cli, "IPC$", "IPC", "", 1)) { 00126 slprintf(err_str, err_str_len-1, "machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", 00127 remote_machine, cli_errstr(cli) ); 00128 result = cli_nt_error(cli); 00129 cli_shutdown(cli); 00130 return result; 00131 } 00132 00133 /* Try not to give the password away too easily */ 00134 00135 if (!pass_must_change) { 00136 pipe_hnd = cli_rpc_pipe_open_ntlmssp(cli, 00137 PI_SAMR, 00138 PIPE_AUTH_LEVEL_PRIVACY, 00139 "", /* what domain... ? */ 00140 user_name, 00141 old_passwd, 00142 &result); 00143 } else { 00144 /* 00145 * If the user password must be changed the ntlmssp bind will 00146 * fail the same way as the session setup above did. The 00147 * difference ist that with a pipe bind we don't get a good 00148 * error message, the result will be that the rpc call below 00149 * will just fail. So we do it anonymously, there's no other 00150 * way. 00151 */ 00152 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result); 00153 } 00154 00155 if (!pipe_hnd) { 00156 if (lp_client_lanman_auth()) { 00157 /* Use the old RAP method. */ 00158 if (!cli_oem_change_password(cli, user_name, new_passwd, old_passwd)) { 00159 slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", 00160 remote_machine, cli_errstr(cli) ); 00161 result = cli_nt_error(cli); 00162 cli_shutdown(cli); 00163 return result; 00164 } 00165 } else { 00166 slprintf(err_str, err_str_len-1, 00167 "SAMR connection to machine %s failed. Error was %s, " 00168 "but LANMAN password changed are disabled\n", 00169 nt_errstr(result), remote_machine); 00170 result = cli_nt_error(cli); 00171 cli_shutdown(cli); 00172 return result; 00173 } 00174 } 00175 00176 if (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, cli->mem_ctx, user_name, 00177 new_passwd, old_passwd))) { 00178 /* Great - it all worked! */ 00179 cli_shutdown(cli); 00180 return NT_STATUS_OK; 00181 00182 } else if (!(NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) 00183 || NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))) { 00184 /* it failed, but for reasons such as wrong password, too short etc ... */ 00185 00186 slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", 00187 remote_machine, get_friendly_nt_error_msg(result)); 00188 cli_shutdown(cli); 00189 return result; 00190 } 00191 00192 /* OK, that failed, so try again... */ 00193 cli_rpc_pipe_close(pipe_hnd); 00194 00195 /* Try anonymous NTLMSSP... */ 00196 cli_init_creds(cli, "", "", NULL); 00197 00198 result = NT_STATUS_UNSUCCESSFUL; 00199 00200 /* OK, this is ugly, but... try an anonymous pipe. */ 00201 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result); 00202 00203 if ( pipe_hnd && 00204 (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, 00205 cli->mem_ctx, 00206 user_name, 00207 new_passwd, 00208 old_passwd)))) { 00209 /* Great - it all worked! */ 00210 cli_shutdown(cli); 00211 return NT_STATUS_OK; 00212 } else { 00213 if (!(NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) 00214 || NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))) { 00215 /* it failed, but again it was due to things like new password too short */ 00216 00217 slprintf(err_str, err_str_len-1, 00218 "machine %s rejected the (anonymous) password change: Error was : %s.\n", 00219 remote_machine, get_friendly_nt_error_msg(result)); 00220 cli_shutdown(cli); 00221 return result; 00222 } 00223 00224 /* We have failed to change the user's password, and we think the server 00225 just might not support SAMR password changes, so fall back */ 00226 00227 if (lp_client_lanman_auth()) { 00228 /* Use the old RAP method. */ 00229 if (cli_oem_change_password(cli, user_name, new_passwd, old_passwd)) { 00230 /* SAMR failed, but the old LanMan protocol worked! */ 00231 00232 cli_shutdown(cli); 00233 return NT_STATUS_OK; 00234 } 00235 slprintf(err_str, err_str_len-1, 00236 "machine %s rejected the password change: Error was : %s.\n", 00237 remote_machine, cli_errstr(cli) ); 00238 result = cli_nt_error(cli); 00239 cli_shutdown(cli); 00240 return result; 00241 } else { 00242 slprintf(err_str, err_str_len-1, 00243 "SAMR connection to machine %s failed. Error was %s, " 00244 "but LANMAN password changed are disabled\n", 00245 nt_errstr(result), remote_machine); 00246 cli_shutdown(cli); 00247 return NT_STATUS_UNSUCCESSFUL; 00248 } 00249 } 00250 }
1.4.7