nsswitch/winbindd_ccache_access.c

ソースコードを見る。

関数

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.c31 行で定義されています。

参照先 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.c43 行で定義されています。

参照先 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.c126 行で定義されています。

参照先 errnowinbindd_cli_state::sockstrerror()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.c150 行で定義されています。

参照先 canonicalize_username()winbindd_request::ccache_ntlm_authcheck_client_uid()winbindd_request::datafind_auth_domain()winbindd_cli_state::pidwinbindd_cli_state::requestrequest_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.c189 行で定義されています。

参照先 winbindd_response::ccache_ntlm_authwinbindd_request::ccache_ntlm_authclient_can_access_ccache_entry()data_blob_::datawinbindd_response::datawinbindd_request::datadata_blob()data_blob_free()do_ntlm_auth_with_hashes()winbindd_response::extra_datawinbindd_request::extra_datawinbindd_request::extra_lenfind_memory_creds_by_name()winbindd_response::lengthdata_blob_::lengthWINBINDD_MEMORY_CREDS::lm_hashWINBINDD_MEMORY_CREDS::nt_hashparse_domain_user()winbindd_cli_state::pidwinbindd_cli_state::requestwinbindd_cli_state::responseresultsmb_xmemdup()WINBINDD_MEMORY_CREDS::usernameWINBINDD_ERRORWINBINDD_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 }


Sambaに対してSat Aug 29 21:23:56 2009に生成されました。  doxygen 1.4.7