関数 | |
static BOOL | client_can_access_ccache_entry (uid_t client_uid, struct WINBINDD_MEMORY_CREDS *entry) |
static NTSTATUS | do_ntlm_auth_with_hashes (const char *username, const char *domain, const unsigned char lm_hash[LM_HASH_LEN], const unsigned char nt_hash[NT_HASH_LEN], const DATA_BLOB initial_msg, const DATA_BLOB challenge_msg, DATA_BLOB *auth_msg) |
static BOOL | check_client_uid (struct winbindd_cli_state *state, uid_t uid) |
void | winbindd_ccache_ntlm_auth (struct winbindd_cli_state *state) |
enum winbindd_result | winbindd_dual_ccache_ntlm_auth (struct winbindd_domain *domain, struct winbindd_cli_state *state) |
static BOOL client_can_access_ccache_entry | ( | uid_t | client_uid, | |
struct WINBINDD_MEMORY_CREDS * | entry | |||
) | [static] |
winbindd_ccache_access.c の 31 行で定義されています。
参照先 WINBINDD_MEMORY_CREDS::uid.
参照元 winbindd_dual_ccache_ntlm_auth().
00033 { 00034 if (client_uid == entry->uid || client_uid == 0) { 00035 DEBUG(10, ("Access granted to uid %d\n", client_uid)); 00036 return True; 00037 } 00038 00039 DEBUG(1, ("Access denied to uid %d (expected %d)\n", client_uid, entry->uid)); 00040 return False; 00041 }
static NTSTATUS do_ntlm_auth_with_hashes | ( | const char * | username, | |
const char * | domain, | |||
const unsigned char | lm_hash[LM_HASH_LEN], | |||
const unsigned char | nt_hash[NT_HASH_LEN], | |||
const DATA_BLOB | initial_msg, | |||
const DATA_BLOB | challenge_msg, | |||
DATA_BLOB * | auth_msg | |||
) | [static] |
winbindd_ccache_access.c の 43 行で定義されています。
参照先 data_blob()・data_blob_free()・nt_errstr()・ntlmssp_client_start()・ntlmssp_end()・ntlmssp_set_domain()・ntlmssp_set_hashes()・ntlmssp_set_username()・ntlmssp_update()・status.
参照元 winbindd_dual_ccache_ntlm_auth().
00050 { 00051 NTSTATUS status; 00052 NTLMSSP_STATE *ntlmssp_state = NULL; 00053 DATA_BLOB dummy_msg, reply; 00054 00055 status = ntlmssp_client_start(&ntlmssp_state); 00056 00057 if (!NT_STATUS_IS_OK(status)) { 00058 DEBUG(1, ("Could not start NTLMSSP client: %s\n", 00059 nt_errstr(status))); 00060 goto done; 00061 } 00062 00063 status = ntlmssp_set_username(ntlmssp_state, username); 00064 00065 if (!NT_STATUS_IS_OK(status)) { 00066 DEBUG(1, ("Could not set username: %s\n", 00067 nt_errstr(status))); 00068 goto done; 00069 } 00070 00071 status = ntlmssp_set_domain(ntlmssp_state, domain); 00072 00073 if (!NT_STATUS_IS_OK(status)) { 00074 DEBUG(1, ("Could not set domain: %s\n", 00075 nt_errstr(status))); 00076 goto done; 00077 } 00078 00079 status = ntlmssp_set_hashes(ntlmssp_state, lm_hash, nt_hash); 00080 00081 if (!NT_STATUS_IS_OK(status)) { 00082 DEBUG(1, ("Could not set hashes: %s\n", 00083 nt_errstr(status))); 00084 goto done; 00085 } 00086 00087 /* We need to get our protocol handler into the right state. So first 00088 we ask it to generate the initial message. Actually the client has already 00089 sent its own initial message, so we're going to drop this one on the floor. 00090 The client might have sent a different message, for example with different 00091 negotiation options, but as far as I can tell this won't hurt us. (Unless 00092 the client sent a different username or domain, in which case that's their 00093 problem for telling us the wrong username or domain.) 00094 Since we have a copy of the initial message that the client sent, we could 00095 resolve any discrepancies if we had to. 00096 */ 00097 dummy_msg = data_blob(NULL, 0); 00098 reply = data_blob(NULL, 0); 00099 status = ntlmssp_update(ntlmssp_state, dummy_msg, &reply); 00100 data_blob_free(&dummy_msg); 00101 data_blob_free(&reply); 00102 00103 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 00104 DEBUG(1, ("Failed to create initial message! [%s]\n", 00105 nt_errstr(status))); 00106 goto done; 00107 } 00108 00109 /* Now we are ready to handle the server's actual response. */ 00110 status = ntlmssp_update(ntlmssp_state, challenge_msg, &reply); 00111 00112 if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) { 00113 DEBUG(1, ("We didn't get a response to the challenge! [%s]\n", 00114 nt_errstr(status))); 00115 data_blob_free(&reply); 00116 goto done; 00117 } 00118 *auth_msg = reply; 00119 status = NT_STATUS_OK; 00120 00121 done: 00122 ntlmssp_end(&ntlmssp_state); 00123 return status; 00124 }
static BOOL check_client_uid | ( | struct winbindd_cli_state * | state, | |
uid_t | uid | |||
) | [static] |
winbindd_ccache_access.c の 126 行で定義されています。
参照先 errno・winbindd_cli_state::sock・strerror()・sys_getpeereid().
参照元 winbindd_ccache_ntlm_auth().
00127 { 00128 int ret; 00129 uid_t ret_uid; 00130 00131 ret_uid = (uid_t)-1; 00132 00133 ret = sys_getpeereid(state->sock, &ret_uid); 00134 if (ret != 0) { 00135 DEBUG(1, ("check_client_uid: Could not get socket peer uid: %s; " 00136 "denying access\n", strerror(errno))); 00137 return False; 00138 } 00139 00140 if (uid != ret_uid) { 00141 DEBUG(1, ("check_client_uid: Client lied about its uid: said %d, " 00142 "actually was %d; denying access\n", 00143 uid, ret_uid)); 00144 return False; 00145 } 00146 00147 return True; 00148 }
void winbindd_ccache_ntlm_auth | ( | struct winbindd_cli_state * | state | ) |
winbindd_ccache_access.c の 150 行で定義されています。
参照先 canonicalize_username()・winbindd_request::ccache_ntlm_auth・check_client_uid()・winbindd_request::data・find_auth_domain()・winbindd_cli_state::pid・winbindd_cli_state::request・request_error()・sendto_domain().
00151 { 00152 struct winbindd_domain *domain; 00153 fstring name_domain, name_user; 00154 00155 /* Ensure null termination */ 00156 state->request.data.ccache_ntlm_auth.user[ 00157 sizeof(state->request.data.ccache_ntlm_auth.user)-1]='\0'; 00158 00159 DEBUG(3, ("[%5lu]: perform NTLM auth on behalf of user %s\n", (unsigned long)state->pid, 00160 state->request.data.ccache_ntlm_auth.user)); 00161 00162 /* Parse domain and username */ 00163 00164 if (!canonicalize_username(state->request.data.ccache_ntlm_auth.user, 00165 name_domain, name_user)) { 00166 DEBUG(5,("winbindd_ccache_ntlm_auth: cannot parse domain and user from name [%s]\n", 00167 state->request.data.ccache_ntlm_auth.user)); 00168 request_error(state); 00169 return; 00170 } 00171 00172 domain = find_auth_domain(state, name_domain); 00173 00174 if (domain == NULL) { 00175 DEBUG(5,("winbindd_ccache_ntlm_auth: can't get domain [%s]\n", 00176 name_domain)); 00177 request_error(state); 00178 return; 00179 } 00180 00181 if (!check_client_uid(state, state->request.data.ccache_ntlm_auth.uid)) { 00182 request_error(state); 00183 return; 00184 } 00185 00186 sendto_domain(state, domain); 00187 }
enum winbindd_result winbindd_dual_ccache_ntlm_auth | ( | struct winbindd_domain * | domain, | |
struct winbindd_cli_state * | state | |||
) |
winbindd_ccache_access.c の 189 行で定義されています。
参照先 winbindd_response::ccache_ntlm_auth・winbindd_request::ccache_ntlm_auth・client_can_access_ccache_entry()・data_blob_::data・winbindd_response::data・winbindd_request::data・data_blob()・data_blob_free()・do_ntlm_auth_with_hashes()・winbindd_response::extra_data・winbindd_request::extra_data・winbindd_request::extra_len・find_memory_creds_by_name()・winbindd_response::length・data_blob_::length・WINBINDD_MEMORY_CREDS::lm_hash・WINBINDD_MEMORY_CREDS::nt_hash・parse_domain_user()・winbindd_cli_state::pid・winbindd_cli_state::request・winbindd_cli_state::response・result・smb_xmemdup()・WINBINDD_MEMORY_CREDS::username・WINBINDD_ERROR・WINBINDD_OK.
00191 { 00192 NTSTATUS result = NT_STATUS_NOT_SUPPORTED; 00193 struct WINBINDD_MEMORY_CREDS *entry; 00194 DATA_BLOB initial, challenge, auth; 00195 fstring name_domain, name_user; 00196 uint32 initial_blob_len, challenge_blob_len, extra_len; 00197 00198 /* Ensure null termination */ 00199 state->request.data.ccache_ntlm_auth.user[ 00200 sizeof(state->request.data.ccache_ntlm_auth.user)-1]='\0'; 00201 00202 DEBUG(3, ("winbindd_dual_ccache_ntlm_auth: [%5lu]: perform NTLM auth on " 00203 "behalf of user %s (dual)\n", (unsigned long)state->pid, 00204 state->request.data.ccache_ntlm_auth.user)); 00205 00206 /* validate blob lengths */ 00207 initial_blob_len = state->request.data.ccache_ntlm_auth.initial_blob_len; 00208 challenge_blob_len = state->request.data.ccache_ntlm_auth.challenge_blob_len; 00209 extra_len = state->request.extra_len; 00210 00211 if (initial_blob_len > extra_len || challenge_blob_len > extra_len || 00212 initial_blob_len + challenge_blob_len > extra_len || 00213 initial_blob_len + challenge_blob_len < initial_blob_len || 00214 initial_blob_len + challenge_blob_len < challenge_blob_len) { 00215 00216 DEBUG(10,("winbindd_dual_ccache_ntlm_auth: blob lengths overrun " 00217 "or wrap. Buffer [%d+%d > %d]\n", 00218 initial_blob_len, 00219 challenge_blob_len, 00220 extra_len)); 00221 goto process_result; 00222 } 00223 00224 /* Parse domain and username */ 00225 if (!parse_domain_user(state->request.data.ccache_ntlm_auth.user, name_domain, name_user)) { 00226 DEBUG(10,("winbindd_dual_ccache_ntlm_auth: cannot parse " 00227 "domain and user from name [%s]\n", 00228 state->request.data.ccache_ntlm_auth.user)); 00229 goto process_result; 00230 } 00231 00232 entry = find_memory_creds_by_name(state->request.data.ccache_ntlm_auth.user); 00233 if (entry == NULL || entry->nt_hash == NULL || entry->lm_hash == NULL) { 00234 DEBUG(10,("winbindd_dual_ccache_ntlm_auth: could not find " 00235 "credentials for user %s\n", 00236 state->request.data.ccache_ntlm_auth.user)); 00237 goto process_result; 00238 } 00239 00240 DEBUG(10,("winbindd_dual_ccache_ntlm_auth: found ccache [%s]\n", entry->username)); 00241 00242 if (!client_can_access_ccache_entry(state->request.data.ccache_ntlm_auth.uid, entry)) { 00243 goto process_result; 00244 } 00245 00246 if (initial_blob_len == 0 && challenge_blob_len == 0) { 00247 /* this is just a probe to see if credentials are available. */ 00248 result = NT_STATUS_OK; 00249 state->response.data.ccache_ntlm_auth.auth_blob_len = 0; 00250 goto process_result; 00251 } 00252 00253 initial = data_blob(state->request.extra_data.data, initial_blob_len); 00254 challenge = data_blob(state->request.extra_data.data + initial_blob_len, 00255 state->request.data.ccache_ntlm_auth.challenge_blob_len); 00256 00257 if (!initial.data || !challenge.data) { 00258 result = NT_STATUS_NO_MEMORY; 00259 } else { 00260 result = do_ntlm_auth_with_hashes(name_user, name_domain, 00261 entry->lm_hash, entry->nt_hash, 00262 initial, challenge, &auth); 00263 } 00264 00265 data_blob_free(&initial); 00266 data_blob_free(&challenge); 00267 00268 if (!NT_STATUS_IS_OK(result)) { 00269 goto process_result; 00270 } 00271 00272 state->response.extra_data.data = smb_xmemdup(auth.data, auth.length); 00273 if (!state->response.extra_data.data) { 00274 result = NT_STATUS_NO_MEMORY; 00275 goto process_result; 00276 } 00277 state->response.length += auth.length; 00278 state->response.data.ccache_ntlm_auth.auth_blob_len = auth.length; 00279 00280 data_blob_free(&auth); 00281 00282 process_result: 00283 return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; 00284 }