smbd/sesssetup.c

ソースコードを見る。

関数

static NTSTATUS do_map_to_guest (NTSTATUS status, auth_serversupplied_info **server_info, const char *user, const char *domain)
static int add_signature (char *outbuf, char *p)
static void sessionsetup_start_signing_engine (const auth_serversupplied_info *server_info, char *inbuf)
static BOOL reply_sesssetup_blob (connection_struct *conn, char *outbuf, DATA_BLOB blob, NTSTATUS nt_status)
static NTSTATUS check_guest_password (auth_serversupplied_info **server_info)
static BOOL make_krb5_skew_error (DATA_BLOB *pblob_out)
static int reply_spnego_kerberos (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, DATA_BLOB *secblob, BOOL *p_invalidate_vuid)
static BOOL reply_spnego_ntlmssp (connection_struct *conn, char *inbuf, char *outbuf, uint16 vuid, AUTH_NTLMSSP_STATE **auth_ntlmssp_state, DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status, BOOL wrap)
static NTSTATUS parse_spnego_mechanisms (DATA_BLOB blob_in, DATA_BLOB *pblob_out, BOOL *p_is_krb5)
static int reply_spnego_negotiate (connection_struct *conn, char *inbuf, char *outbuf, uint16 vuid, int length, int bufsize, DATA_BLOB blob1, AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
static int reply_spnego_auth (connection_struct *conn, char *inbuf, char *outbuf, uint16 vuid, int length, int bufsize, DATA_BLOB blob1, AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
static void delete_partial_auth (struct pending_auth_data *pad)
static struct pending_auth_dataget_pending_auth_data (uint16 smbpid)
static NTSTATUS check_spnego_blob_complete (uint16 smbpid, uint16 vuid, DATA_BLOB *pblob)
static int reply_sesssetup_and_X_spnego (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize)
static int shutdown_other_smbds (TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *p)
static void setup_new_vc_session (void)
int reply_sesssetup_and_X (connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize)

変数

auth_contextnegprot_global_auth_context
BOOL global_encrypted_passwords_negotiated
BOOL global_spnego_negotiated
enum protocol_types Protocol
int max_send
uint32 global_client_caps = 0
static struct pending_auth_datapd_list


関数

static NTSTATUS do_map_to_guest ( NTSTATUS  status,
auth_serversupplied_info **  server_info,
const char *  user,
const char *  domain 
) [static]

sesssetup.c38 行で定義されています。

参照先 make_server_info_guest()status.

参照元 reply_sesssetup_and_X()reply_spnego_ntlmssp().

00040 {
00041         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
00042                 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) || 
00043                     (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
00044                         DEBUG(3,("No such user %s [%s] - using guest account\n",
00045                                  user, domain));
00046                         status = make_server_info_guest(server_info);
00047                 }
00048         }
00049 
00050         if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
00051                 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
00052                         DEBUG(3,("Registered username %s for guest access\n",user));
00053                         status = make_server_info_guest(server_info);
00054                 }
00055         }
00056 
00057         return status;
00058 }

static int add_signature ( char *  outbuf,
char *  p 
) [static]

sesssetup.c64 行で定義されています。

参照先 fstr_sprintf()lp_workgroup().

参照元 reply_sesssetup_and_X()reply_sesssetup_blob().

00065 {
00066         char *start = p;
00067         fstring lanman;
00068 
00069         fstr_sprintf( lanman, "Samba %s", SAMBA_VERSION_STRING);
00070 
00071         p += srvstr_push(outbuf, p, "Unix", BUFFER_SIZE - (p - outbuf), STR_TERMINATE);
00072         p += srvstr_push(outbuf, p, lanman, BUFFER_SIZE - (p - outbuf), STR_TERMINATE);
00073         p += srvstr_push(outbuf, p, lp_workgroup(), BUFFER_SIZE - (p - outbuf), STR_TERMINATE);
00074 
00075         return PTR_DIFF(p, start);
00076 }

static void sessionsetup_start_signing_engine ( const auth_serversupplied_info server_info,
char *  inbuf 
) [static]

sesssetup.c82 行で定義されています。

参照先 auth_serversupplied_info::guestsrv_check_sign_mac()srv_signing_started().

参照元 reply_sesssetup_and_X()reply_spnego_kerberos()reply_spnego_ntlmssp().

00083 {
00084         if (!server_info->guest && !srv_signing_started()) {
00085                 /* We need to start the signing engine
00086                  * here but a W2K client sends the old
00087                  * "BSRSPYL " signature instead of the
00088                  * correct one. Subsequent packets will
00089                  * be correct.
00090                  */
00091                 srv_check_sign_mac(inbuf, False);
00092         }
00093 }

static BOOL reply_sesssetup_blob ( connection_struct conn,
char *  outbuf,
DATA_BLOB  blob,
NTSTATUS  nt_status 
) [static]

sesssetup.c99 行で定義されています。

参照先 add_signature()data_blob_::datadata_blob_::lengthnt_status_squash()send_smb()set_message()set_message_end()show_msg()smbd_server_fd().

参照元 reply_spnego_kerberos()reply_spnego_ntlmssp().

00101 {
00102         char *p;
00103 
00104         if (!NT_STATUS_IS_OK(nt_status) && !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
00105                 ERROR_NT(nt_status_squash(nt_status));
00106         } else {
00107                 set_message(outbuf,4,0,True);
00108 
00109                 nt_status = nt_status_squash(nt_status);
00110                 SIVAL(outbuf, smb_rcls, NT_STATUS_V(nt_status));
00111                 SSVAL(outbuf, smb_vwv0, 0xFF); /* no chaining possible */
00112                 SSVAL(outbuf, smb_vwv3, blob.length);
00113                 p = smb_buf(outbuf);
00114 
00115                 /* should we cap this? */
00116                 memcpy(p, blob.data, blob.length);
00117                 p += blob.length;
00118 
00119                 p += add_signature( outbuf, p );
00120 
00121                 set_message_end(outbuf,p);
00122         }
00123 
00124         show_msg(outbuf);
00125         return send_smb(smbd_server_fd(),outbuf);
00126 }

static NTSTATUS check_guest_password ( auth_serversupplied_info **  server_info  )  [static]

sesssetup.c132 行で定義されています。

参照先 auth_context::check_ntlm_passwordauth_context::freefree_user_info()make_auth_context_fixed()make_user_info_guest().

参照元 reply_sesssetup_and_X().

00133 {
00134         struct auth_context *auth_context;
00135         auth_usersupplied_info *user_info = NULL;
00136         
00137         NTSTATUS nt_status;
00138         unsigned char chal[8];
00139 
00140         ZERO_STRUCT(chal);
00141 
00142         DEBUG(3,("Got anonymous request\n"));
00143 
00144         if (!NT_STATUS_IS_OK(nt_status = make_auth_context_fixed(&auth_context, chal))) {
00145                 return nt_status;
00146         }
00147 
00148         if (!make_user_info_guest(&user_info)) {
00149                 (auth_context->free)(&auth_context);
00150                 return NT_STATUS_NO_MEMORY;
00151         }
00152         
00153         nt_status = auth_context->check_ntlm_password(auth_context, user_info, server_info);
00154         (auth_context->free)(&auth_context);
00155         free_user_info(&user_info);
00156         return nt_status;
00157 }

static BOOL make_krb5_skew_error ( DATA_BLOB pblob_out  )  [static]

sesssetup.c168 行で定義されています。

参照先 asprintf()data_blob()global_mynamekerberos_free_data_contents()smb_krb5_mk_error()smb_krb5_parse_name()strlower_m().

参照元 reply_spnego_kerberos().

00169 {
00170         krb5_context context = NULL;
00171         krb5_error_code kerr = 0;
00172         krb5_data reply;
00173         krb5_principal host_princ = NULL;
00174         char *host_princ_s = NULL;
00175         BOOL ret = False;
00176 
00177         *pblob_out = data_blob(NULL,0);
00178 
00179         initialize_krb5_error_table();
00180         kerr = krb5_init_context(&context);
00181         if (kerr) {
00182                 return False;
00183         }
00184         /* Create server principal. */
00185         asprintf(&host_princ_s, "%s$@%s", global_myname(), lp_realm());
00186         if (!host_princ_s) {
00187                 goto out;
00188         }
00189         strlower_m(host_princ_s);
00190 
00191         kerr = smb_krb5_parse_name(context, host_princ_s, &host_princ);
00192         if (kerr) {
00193                 DEBUG(10,("make_krb5_skew_error: smb_krb5_parse_name failed for name %s: Error %s\n",
00194                         host_princ_s, error_message(kerr) ));
00195                 goto out;
00196         }
00197         
00198         kerr = smb_krb5_mk_error(context, KRB5KRB_AP_ERR_SKEW, host_princ, &reply);
00199         if (kerr) {
00200                 DEBUG(10,("make_krb5_skew_error: smb_krb5_mk_error failed: Error %s\n",
00201                         error_message(kerr) ));
00202                 goto out;
00203         }
00204 
00205         *pblob_out = data_blob(reply.data, reply.length);
00206         kerberos_free_data_contents(context,&reply);
00207         ret = True;
00208 
00209   out:
00210 
00211         if (host_princ_s) {
00212                 SAFE_FREE(host_princ_s);
00213         }
00214         if (host_princ) {
00215                 krb5_free_principal(context, host_princ);
00216         }
00217         krb5_free_context(context);
00218         return ret;
00219 }

static int reply_spnego_kerberos ( connection_struct conn,
char *  inbuf,
char *  outbuf,
int  length,
int  bufsize,
DATA_BLOB secblob,
BOOL p_invalidate_vuid 
) [static]

sesssetup.c226 行で定義されています。

参照先 ads_verify_ticket()create_local_token()winbindd_response::datadata_blob()data_blob_free()winbindd_response::domain_infowinbindd_request::domain_namefstr_sprintf()get_logon_info_from_pac()auth_serversupplied_info::guestnet_user_info_3::hdr_logon_dompac_logon_info::info3make_krb5_skew_error()make_server_info_guest()make_server_info_info3()make_server_info_pw()map_username()auth_context::mem_ctxnetsamlogon_cache_store()NSS_STATUS_SUCCESSnt_errstr()nt_status_squash()PDB_SETpdb_set_domain()auth_serversupplied_info::ptokregister_vuid()reload_services()reply_sesssetup_blob()auth_serversupplied_info::sam_accountsessionsetup_start_signing_engine()set_message()smb_getpwnam()smb_pam_accountcheck()spnego_gen_auth_response()spnego_gen_krb5_wrap()spnego_parse_krb5_wrap()strchr_m()strequal()sub_set_smb_name()talloc_init()net_user_info_3::uni_logon_domUNIHDR::uni_str_lenunistr2_to_ascii()auth_serversupplied_info::was_mappedWINBINDD_DOMAIN_INFOwinbindd_request_response().

参照元 reply_spnego_auth()reply_spnego_negotiate().

00231 {
00232         TALLOC_CTX *mem_ctx;
00233         DATA_BLOB ticket;
00234         char *client, *p, *domain;
00235         fstring netbios_domain_name;
00236         struct passwd *pw;
00237         fstring user;
00238         int sess_vuid;
00239         NTSTATUS ret;
00240         PAC_DATA *pac_data;
00241         DATA_BLOB ap_rep, ap_rep_wrapped, response;
00242         auth_serversupplied_info *server_info = NULL;
00243         DATA_BLOB session_key = data_blob(NULL, 0);
00244         uint8 tok_id[2];
00245         DATA_BLOB nullblob = data_blob(NULL, 0);
00246         fstring real_username;
00247         BOOL map_domainuser_to_guest = False;
00248         BOOL username_was_mapped;
00249         PAC_LOGON_INFO *logon_info = NULL;
00250 
00251         ZERO_STRUCT(ticket);
00252         ZERO_STRUCT(pac_data);
00253         ZERO_STRUCT(ap_rep);
00254         ZERO_STRUCT(ap_rep_wrapped);
00255         ZERO_STRUCT(response);
00256 
00257         /* Normally we will always invalidate the intermediate vuid. */
00258         *p_invalidate_vuid = True;
00259 
00260         mem_ctx = talloc_init("reply_spnego_kerberos");
00261         if (mem_ctx == NULL) {
00262                 return ERROR_NT(nt_status_squash(NT_STATUS_NO_MEMORY));
00263         }
00264 
00265         if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) {
00266                 talloc_destroy(mem_ctx);
00267                 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
00268         }
00269 
00270         ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket, &client, &pac_data, &ap_rep, &session_key);
00271 
00272         data_blob_free(&ticket);
00273 
00274         if (!NT_STATUS_IS_OK(ret)) {
00275 #if 0
00276                 /* Experiment that failed. See "only happens with a KDC" comment below. */
00277 
00278                 if (NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
00279 
00280                         /*
00281                          * Windows in this case returns NT_STATUS_MORE_PROCESSING_REQUIRED
00282                          * with a negTokenTarg blob containing an krb5_error struct ASN1 encoded
00283                          * containing KRB5KRB_AP_ERR_SKEW. The client then fixes its
00284                          * clock and continues rather than giving an error. JRA.
00285                          * -- Looks like this only happens with a KDC. JRA.
00286                          */
00287 
00288                         BOOL ok = make_krb5_skew_error(&ap_rep);
00289                         if (!ok) {
00290                                 talloc_destroy(mem_ctx);
00291                                 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
00292                         }
00293                         ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, TOK_ID_KRB_ERROR);
00294                         response = spnego_gen_auth_response(&ap_rep_wrapped, ret, OID_KERBEROS5_OLD);
00295                         reply_sesssetup_blob(conn, outbuf, response, NT_STATUS_MORE_PROCESSING_REQUIRED);
00296 
00297                         /*
00298                          * In this one case we don't invalidate the intermediate vuid.
00299                          * as we're expecting the client to re-use it for the next
00300                          * sessionsetupX packet. JRA.
00301                          */
00302 
00303                         *p_invalidate_vuid = False;
00304 
00305                         data_blob_free(&ap_rep);
00306                         data_blob_free(&ap_rep_wrapped);
00307                         data_blob_free(&response);
00308                         talloc_destroy(mem_ctx);
00309                         return -1; /* already replied */
00310                 }
00311 #else
00312                 if (!NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
00313                         ret = NT_STATUS_LOGON_FAILURE;
00314                 }
00315 #endif
00316                 DEBUG(1,("Failed to verify incoming ticket with error %s!\n", nt_errstr(ret))); 
00317                 talloc_destroy(mem_ctx);
00318                 return ERROR_NT(nt_status_squash(ret));
00319         }
00320 
00321         DEBUG(3,("Ticket name is [%s]\n", client));
00322 
00323         p = strchr_m(client, '@');
00324         if (!p) {
00325                 DEBUG(3,("Doesn't look like a valid principal\n"));
00326                 data_blob_free(&ap_rep);
00327                 data_blob_free(&session_key);
00328                 SAFE_FREE(client);
00329                 talloc_destroy(mem_ctx);
00330                 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
00331         }
00332 
00333         *p = 0;
00334 
00335         /* save the PAC data if we have it */
00336 
00337         if (pac_data) {
00338                 logon_info = get_logon_info_from_pac(pac_data);
00339                 if (logon_info) {
00340                         netsamlogon_cache_store( client, &logon_info->info3 );
00341                 }
00342         }
00343 
00344         if (!strequal(p+1, lp_realm())) {
00345                 DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1));
00346                 if (!lp_allow_trusted_domains()) {
00347                         data_blob_free(&ap_rep);
00348                         data_blob_free(&session_key);
00349                         SAFE_FREE(client);
00350                         talloc_destroy(mem_ctx);
00351                         return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
00352                 }
00353         }
00354 
00355         /* this gives a fully qualified user name (ie. with full realm).
00356            that leads to very long usernames, but what else can we do? */
00357 
00358         domain = p+1;
00359 
00360         if (logon_info && logon_info->info3.hdr_logon_dom.uni_str_len) {
00361 
00362                 unistr2_to_ascii(netbios_domain_name, &logon_info->info3.uni_logon_dom, -1);
00363                 domain = netbios_domain_name;
00364                 DEBUG(10, ("Mapped to [%s] (using PAC)\n", domain));
00365 
00366         } else {
00367 
00368                 /* If we have winbind running, we can (and must) shorten the
00369                    username by using the short netbios name. Otherwise we will
00370                    have inconsistent user names. With Kerberos, we get the
00371                    fully qualified realm, with ntlmssp we get the short
00372                    name. And even w2k3 does use ntlmssp if you for example
00373                    connect to an ip address. */
00374 
00375                 struct winbindd_request wb_request;
00376                 struct winbindd_response wb_response;
00377                 NSS_STATUS wb_result;
00378 
00379                 ZERO_STRUCT(wb_request);
00380                 ZERO_STRUCT(wb_response);
00381 
00382                 DEBUG(10, ("Mapping [%s] to short name\n", domain));
00383 
00384                 fstrcpy(wb_request.domain_name, domain);
00385 
00386                 wb_result = winbindd_request_response(WINBINDD_DOMAIN_INFO,
00387                                              &wb_request, &wb_response);
00388 
00389                 if (wb_result == NSS_STATUS_SUCCESS) {
00390 
00391                         fstrcpy(netbios_domain_name,
00392                                 wb_response.data.domain_info.name);
00393                         domain = netbios_domain_name;
00394 
00395                         DEBUG(10, ("Mapped to [%s] (using Winbind)\n", domain));
00396                 } else {
00397                         DEBUG(3, ("Could not find short name -- winbind "
00398                                   "not running?\n"));
00399                 }
00400         }
00401 
00402         fstr_sprintf(user, "%s%c%s", domain, *lp_winbind_separator(), client);
00403         
00404         /* lookup the passwd struct, create a new user if necessary */
00405 
00406         username_was_mapped = map_username( user );
00407 
00408         pw = smb_getpwnam( mem_ctx, user, real_username, True );
00409 
00410         if (pw) {
00411                 /* if a real user check pam account restrictions */
00412                 /* only really perfomed if "obey pam restriction" is true */
00413                 /* do this before an eventual mappign to guest occurs */
00414                 ret = smb_pam_accountcheck(pw->pw_name);
00415                 if (  !NT_STATUS_IS_OK(ret)) {
00416                         DEBUG(1, ("PAM account restriction prevents user login\n"));
00417                         data_blob_free(&ap_rep);
00418                         data_blob_free(&session_key);
00419                         TALLOC_FREE(mem_ctx);
00420                         return ERROR_NT(nt_status_squash(ret));
00421                 }
00422         }
00423 
00424         if (!pw) {
00425 
00426                 /* this was originally the behavior of Samba 2.2, if a user
00427                    did not have a local uid but has been authenticated, then 
00428                    map them to a guest account */
00429 
00430                 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID){ 
00431                         map_domainuser_to_guest = True;
00432                         fstrcpy(user,lp_guestaccount());
00433                         pw = smb_getpwnam( mem_ctx, user, real_username, True );
00434                 } 
00435 
00436                 /* extra sanity check that the guest account is valid */
00437 
00438                 if ( !pw ) {
00439                         DEBUG(1,("Username %s is invalid on this system\n", user));
00440                         SAFE_FREE(client);
00441                         data_blob_free(&ap_rep);
00442                         data_blob_free(&session_key);
00443                         TALLOC_FREE(mem_ctx);
00444                         return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
00445                 }
00446         }
00447 
00448         /* setup the string used by %U */
00449         
00450         sub_set_smb_name( real_username );
00451         reload_services(True);
00452 
00453         if ( map_domainuser_to_guest ) {
00454                 make_server_info_guest(&server_info);
00455         } else if (logon_info) {
00456                 /* pass the unmapped username here since map_username() 
00457                    will be called again from inside make_server_info_info3() */
00458                 
00459                 ret = make_server_info_info3(mem_ctx, client, domain, 
00460                                              &server_info, &logon_info->info3);
00461                 if ( !NT_STATUS_IS_OK(ret) ) {
00462                         DEBUG(1,("make_server_info_info3 failed: %s!\n",
00463                                  nt_errstr(ret)));
00464                         SAFE_FREE(client);
00465                         data_blob_free(&ap_rep);
00466                         data_blob_free(&session_key);
00467                         TALLOC_FREE(mem_ctx);
00468                         return ERROR_NT(nt_status_squash(ret));
00469                 }
00470 
00471         } else {
00472                 ret = make_server_info_pw(&server_info, real_username, pw);
00473 
00474                 if ( !NT_STATUS_IS_OK(ret) ) {
00475                         DEBUG(1,("make_server_info_pw failed: %s!\n",
00476                                  nt_errstr(ret)));
00477                         SAFE_FREE(client);
00478                         data_blob_free(&ap_rep);
00479                         data_blob_free(&session_key);
00480                         TALLOC_FREE(mem_ctx);
00481                         return ERROR_NT(nt_status_squash(ret));
00482                 }
00483 
00484                 /* make_server_info_pw does not set the domain. Without this
00485                  * we end up with the local netbios name in substitutions for
00486                  * %D. */
00487 
00488                 if (server_info->sam_account != NULL) {
00489                         pdb_set_domain(server_info->sam_account, domain, PDB_SET);
00490                 }
00491         }
00492 
00493         server_info->was_mapped |= username_was_mapped;
00494         
00495         /* we need to build the token for the user. make_server_info_guest()
00496            already does this */
00497         
00498         if ( !server_info->ptok ) {
00499                 ret = create_local_token( server_info );
00500                 if ( !NT_STATUS_IS_OK(ret) ) {
00501                         SAFE_FREE(client);
00502                         data_blob_free(&ap_rep);
00503                         data_blob_free(&session_key);
00504                         TALLOC_FREE( mem_ctx );
00505                         TALLOC_FREE( server_info );
00506                         return ERROR_NT(nt_status_squash(ret));
00507                 }
00508         }
00509 
00510         /* register_vuid keeps the server info */
00511         /* register_vuid takes ownership of session_key, no need to free after this.
00512            A better interface would copy it.... */
00513         sess_vuid = register_vuid(server_info, session_key, nullblob, client);
00514 
00515         SAFE_FREE(client);
00516 
00517         if (sess_vuid == UID_FIELD_INVALID ) {
00518                 ret = NT_STATUS_LOGON_FAILURE;
00519         } else {
00520                 /* current_user_info is changed on new vuid */
00521                 reload_services( True );
00522 
00523                 set_message(outbuf,4,0,True);
00524                 SSVAL(outbuf, smb_vwv3, 0);
00525                         
00526                 if (server_info->guest) {
00527                         SSVAL(outbuf,smb_vwv2,1);
00528                 }
00529                 
00530                 SSVAL(outbuf, smb_uid, sess_vuid);
00531 
00532                 sessionsetup_start_signing_engine(server_info, inbuf);
00533         }
00534 
00535         /* wrap that up in a nice GSS-API wrapping */
00536         if (NT_STATUS_IS_OK(ret)) {
00537                 ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, TOK_ID_KRB_AP_REP);
00538         } else {
00539                 ap_rep_wrapped = data_blob(NULL, 0);
00540         }
00541         response = spnego_gen_auth_response(&ap_rep_wrapped, ret, OID_KERBEROS5_OLD);
00542         reply_sesssetup_blob(conn, outbuf, response, ret);
00543 
00544         data_blob_free(&ap_rep);
00545         data_blob_free(&ap_rep_wrapped);
00546         data_blob_free(&response);
00547         TALLOC_FREE(mem_ctx);
00548 
00549         return -1; /* already replied */
00550 }

static BOOL reply_spnego_ntlmssp ( connection_struct conn,
char *  inbuf,
char *  outbuf,
uint16  vuid,
AUTH_NTLMSSP_STATE **  auth_ntlmssp_state,
DATA_BLOB ntlmssp_blob,
NTSTATUS  nt_status,
BOOL  wrap 
) [static]

sesssetup.c561 行で定義されています。

参照先 auth_ntlmssp_end()data_blob()data_blob_free()do_map_to_guest()auth_serversupplied_info::guestinvalidate_intermediate_vuid()register_vuid()reload_services()reply_sesssetup_blob()sessionsetup_start_signing_engine()set_message()spnego_gen_auth_response().

参照元 reply_sesssetup_and_X_spnego()reply_spnego_auth()reply_spnego_negotiate().

00566 {
00567         BOOL ret;
00568         DATA_BLOB response;
00569         struct auth_serversupplied_info *server_info = NULL;
00570 
00571         if (NT_STATUS_IS_OK(nt_status)) {
00572                 server_info = (*auth_ntlmssp_state)->server_info;
00573         } else {
00574                 nt_status = do_map_to_guest(nt_status, 
00575                                             &server_info, 
00576                                             (*auth_ntlmssp_state)->ntlmssp_state->user, 
00577                                             (*auth_ntlmssp_state)->ntlmssp_state->domain);
00578         }
00579 
00580         if (NT_STATUS_IS_OK(nt_status)) {
00581                 int sess_vuid;
00582                 DATA_BLOB nullblob = data_blob(NULL, 0);
00583                 DATA_BLOB session_key = data_blob((*auth_ntlmssp_state)->ntlmssp_state->session_key.data, (*auth_ntlmssp_state)->ntlmssp_state->session_key.length);
00584 
00585                 /* register_vuid keeps the server info */
00586                 sess_vuid = register_vuid(server_info, session_key, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user);
00587                 (*auth_ntlmssp_state)->server_info = NULL;
00588 
00589                 if (sess_vuid == UID_FIELD_INVALID ) {
00590                         nt_status = NT_STATUS_LOGON_FAILURE;
00591                 } else {
00592                         
00593                         /* current_user_info is changed on new vuid */
00594                         reload_services( True );
00595 
00596                         set_message(outbuf,4,0,True);
00597                         SSVAL(outbuf, smb_vwv3, 0);
00598                         
00599                         if (server_info->guest) {
00600                                 SSVAL(outbuf,smb_vwv2,1);
00601                         }
00602                         
00603                         SSVAL(outbuf,smb_uid,sess_vuid);
00604 
00605                         sessionsetup_start_signing_engine(server_info, inbuf);
00606                 }
00607         }
00608 
00609         if (wrap) {
00610                 response = spnego_gen_auth_response(ntlmssp_blob, nt_status, OID_NTLMSSP);
00611         } else {
00612                 response = *ntlmssp_blob;
00613         }
00614 
00615         ret = reply_sesssetup_blob(conn, outbuf, response, nt_status);
00616         if (wrap) {
00617                 data_blob_free(&response);
00618         }
00619 
00620         /* NT_STATUS_MORE_PROCESSING_REQUIRED from our NTLMSSP code tells us,
00621            and the other end, that we are not finished yet. */
00622 
00623         if (!ret || !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
00624                 /* NB. This is *NOT* an error case. JRA */
00625                 auth_ntlmssp_end(auth_ntlmssp_state);
00626                 /* Kill the intermediate vuid */
00627                 invalidate_intermediate_vuid(vuid);
00628         }
00629 
00630         return ret;
00631 }

static NTSTATUS parse_spnego_mechanisms ( DATA_BLOB  blob_in,
DATA_BLOB pblob_out,
BOOL p_is_krb5 
) [static]

sesssetup.c637 行で定義されています。

参照先 parse_negTokenTarg().

参照元 reply_spnego_auth()reply_spnego_negotiate().

00638 {
00639         char *OIDs[ASN1_MAX_OIDS];
00640         int i;
00641 
00642         *p_is_krb5 = False;
00643 
00644         /* parse out the OIDs and the first sec blob */
00645         if (!parse_negTokenTarg(blob_in, OIDs, pblob_out)) {
00646                 return NT_STATUS_LOGON_FAILURE;
00647         }
00648 
00649         /* only look at the first OID for determining the mechToken --
00650            accoirding to RFC2478, we should choose the one we want 
00651            and renegotiate, but i smell a client bug here..  
00652            
00653            Problem observed when connecting to a member (samba box) 
00654            of an AD domain as a user in a Samba domain.  Samba member 
00655            server sent back krb5/mskrb5/ntlmssp as mechtypes, but the 
00656            client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an 
00657            NTLMSSP mechtoken.                 --jerry              */
00658 
00659 #ifdef HAVE_KRB5        
00660         if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 ||
00661             strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
00662                 *p_is_krb5 = True;
00663         }
00664 #endif
00665                 
00666         for (i=0;OIDs[i];i++) {
00667                 DEBUG(5,("parse_spnego_mechanisms: Got OID %s\n", OIDs[i]));
00668                 free(OIDs[i]);
00669         }
00670         return NT_STATUS_OK;
00671 }

static int reply_spnego_negotiate ( connection_struct conn,
char *  inbuf,
char *  outbuf,
uint16  vuid,
int  length,
int  bufsize,
DATA_BLOB  blob1,
AUTH_NTLMSSP_STATE **  auth_ntlmssp_state 
) [static]

sesssetup.c677 行で定義されています。

参照先 auth_ntlmssp_end()auth_ntlmssp_start()auth_ntlmssp_update()data_blob_free()invalidate_intermediate_vuid()data_blob_::lengthnt_status_squash()parse_spnego_mechanisms()reply_spnego_kerberos()reply_spnego_ntlmssp()SEC_ADSstatus.

参照元 reply_sesssetup_and_X_spnego().

00684 {
00685         DATA_BLOB secblob;
00686         DATA_BLOB chal;
00687         BOOL got_kerberos_mechanism = False;
00688         NTSTATUS status;
00689 
00690         status = parse_spnego_mechanisms(blob1, &secblob, &got_kerberos_mechanism);
00691         if (!NT_STATUS_IS_OK(status)) {
00692                 /* Kill the intermediate vuid */
00693                 invalidate_intermediate_vuid(vuid);
00694                 return ERROR_NT(nt_status_squash(status));
00695         }
00696 
00697         DEBUG(3,("reply_spnego_negotiate: Got secblob of size %lu\n", (unsigned long)secblob.length));
00698 
00699 #ifdef HAVE_KRB5
00700         if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) {
00701                 BOOL destroy_vuid = True;
00702                 int ret = reply_spnego_kerberos(conn, inbuf, outbuf, 
00703                                                 length, bufsize, &secblob, &destroy_vuid);
00704                 data_blob_free(&secblob);
00705                 if (destroy_vuid) {
00706                         /* Kill the intermediate vuid */
00707                         invalidate_intermediate_vuid(vuid);
00708                 }
00709                 return ret;
00710         }
00711 #endif
00712 
00713         if (got_kerberos_mechanism) {
00714                 invalidate_intermediate_vuid(vuid);
00715                 DEBUG(3,("reply_spnego_negotiate: network "
00716                         "misconfiguration, client sent us a "
00717                         "krb5 ticket and kerberos security "
00718                         "not enabled"));
00719                 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
00720         }
00721 
00722         if (*auth_ntlmssp_state) {
00723                 auth_ntlmssp_end(auth_ntlmssp_state);
00724         }
00725 
00726         status = auth_ntlmssp_start(auth_ntlmssp_state);
00727         if (!NT_STATUS_IS_OK(status)) {
00728                 /* Kill the intermediate vuid */
00729                 invalidate_intermediate_vuid(vuid);
00730                 return ERROR_NT(nt_status_squash(status));
00731         }
00732 
00733         status = auth_ntlmssp_update(*auth_ntlmssp_state, 
00734                                         secblob, &chal);
00735 
00736         data_blob_free(&secblob);
00737 
00738         reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid, auth_ntlmssp_state,
00739                              &chal, status, True);
00740 
00741         data_blob_free(&chal);
00742 
00743         /* already replied */
00744         return -1;
00745 }

static int reply_spnego_auth ( connection_struct conn,
char *  inbuf,
char *  outbuf,
uint16  vuid,
int  length,
int  bufsize,
DATA_BLOB  blob1,
AUTH_NTLMSSP_STATE **  auth_ntlmssp_state 
) [static]

sesssetup.c751 行で定義されています。

参照先 auth_ntlmssp_update()data_blob_::datadata_blob()data_blob_free()file_save()invalidate_intermediate_vuid()data_blob_::lengthnt_status_squash()parse_spnego_mechanisms()reply_spnego_kerberos()reply_spnego_ntlmssp()SEC_ADSspnego_parse_auth()status.

参照元 reply_sesssetup_and_X_spnego().

00756 {
00757         DATA_BLOB auth = data_blob(NULL,0);
00758         DATA_BLOB auth_reply = data_blob(NULL,0);
00759         DATA_BLOB secblob = data_blob(NULL,0);
00760         NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
00761 
00762         if (!spnego_parse_auth(blob1, &auth)) {
00763 #if 0
00764                 file_save("auth.dat", blob1.data, blob1.length);
00765 #endif
00766                 /* Kill the intermediate vuid */
00767                 invalidate_intermediate_vuid(vuid);
00768 
00769                 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
00770         }
00771 
00772         if (auth.data[0] == ASN1_APPLICATION(0)) {
00773                 /* Might be a second negTokenTarg packet */
00774 
00775                 BOOL got_krb5_mechanism = False;
00776                 status = parse_spnego_mechanisms(auth, &secblob, &got_krb5_mechanism);
00777                 if (NT_STATUS_IS_OK(status)) {
00778                         DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n", (unsigned long)secblob.length));
00779 #ifdef HAVE_KRB5
00780                         if ( got_krb5_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) {
00781                                 BOOL destroy_vuid = True;
00782                                 int ret = reply_spnego_kerberos(conn, inbuf, outbuf, 
00783                                                                 length, bufsize, &secblob, &destroy_vuid);
00784                                 data_blob_free(&secblob);
00785                                 data_blob_free(&auth);
00786                                 if (destroy_vuid) {
00787                                         /* Kill the intermediate vuid */
00788                                         invalidate_intermediate_vuid(vuid);
00789                                 }
00790                                 return ret;
00791                         }
00792 #endif
00793                 }
00794         }
00795 
00796         /* If we get here it wasn't a negTokenTarg auth packet. */
00797         data_blob_free(&secblob);
00798 
00799         if (!*auth_ntlmssp_state) {
00800                 /* Kill the intermediate vuid */
00801                 invalidate_intermediate_vuid(vuid);
00802 
00803                 /* auth before negotiatiate? */
00804                 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
00805         }
00806 
00807         status = auth_ntlmssp_update(*auth_ntlmssp_state,
00808                                         auth, &auth_reply);
00809 
00810         data_blob_free(&auth);
00811 
00812         reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid,
00813                              auth_ntlmssp_state,
00814                              &auth_reply, status, True);
00815 
00816         data_blob_free(&auth_reply);
00817 
00818         /* and tell smbd that we have already replied to this packet */
00819         return -1;
00820 }

static void delete_partial_auth ( struct pending_auth_data pad  )  [static]

sesssetup.c832 行で定義されています。

参照先 data_blob_free()pending_auth_data::partial_datapd_list.

参照元 check_spnego_blob_complete().

00833 {
00834         if (!pad) {
00835                 return;
00836         }
00837         DLIST_REMOVE(pd_list, pad);
00838         data_blob_free(&pad->partial_data);
00839         SAFE_FREE(pad);
00840 }

static struct pending_auth_data* get_pending_auth_data ( uint16  smbpid  )  [static]

sesssetup.c846 行で定義されています。

参照先 pending_auth_data::nextpd_listpending_auth_data::smbpid.

参照元 check_spnego_blob_complete()reply_sesssetup_and_X_spnego().

00847 {
00848         struct pending_auth_data *pad;
00849 
00850         for (pad = pd_list; pad; pad = pad->next) {
00851                 if (pad->smbpid == smbpid) {
00852                         break;
00853                 }
00854         }
00855         return pad;
00856 }

static NTSTATUS check_spnego_blob_complete ( uint16  smbpid,
uint16  vuid,
DATA_BLOB pblob 
) [static]

sesssetup.c863 行で定義されています。

参照先 asn1_free()asn1_load()asn1_start_tag()data_blob_::datadata_blob()data_blob_free()delete_partial_auth()get_pending_auth_data()asn1_data::has_errordata_blob_::lengthpending_auth_data::needed_lenasn1_data::nestingpending_auth_data::partial_datapd_listpending_auth_data::smbpidnesting::startnesting::taglenpending_auth_data::vuid.

参照元 reply_sesssetup_and_X_spnego().

00864 {
00865         struct pending_auth_data *pad = NULL;
00866         ASN1_DATA data;
00867         size_t needed_len = 0;
00868 
00869         pad = get_pending_auth_data(smbpid);
00870 
00871         /* Ensure we have some data. */
00872         if (pblob->length == 0) {
00873                 /* Caller can cope. */
00874                 DEBUG(2,("check_spnego_blob_complete: zero blob length !\n"));
00875                 delete_partial_auth(pad);
00876                 return NT_STATUS_OK;
00877         }
00878 
00879         /* Were we waiting for more data ? */
00880         if (pad) {
00881                 DATA_BLOB tmp_blob;
00882                 size_t copy_len = MIN(65536, pblob->length);
00883 
00884                 /* Integer wrap paranoia.... */
00885 
00886                 if (pad->partial_data.length + copy_len < pad->partial_data.length ||
00887                     pad->partial_data.length + copy_len < copy_len) {
00888 
00889                         DEBUG(2,("check_spnego_blob_complete: integer wrap "
00890                                 "pad->partial_data.length = %u, "
00891                                 "copy_len = %u\n",
00892                                 (unsigned int)pad->partial_data.length,
00893                                 (unsigned int)copy_len ));
00894 
00895                         delete_partial_auth(pad);
00896                         return NT_STATUS_INVALID_PARAMETER;
00897                 }
00898 
00899                 DEBUG(10,("check_spnego_blob_complete: "
00900                         "pad->partial_data.length = %u, "
00901                         "pad->needed_len = %u, "
00902                         "copy_len = %u, "
00903                         "pblob->length = %u,\n",
00904                         (unsigned int)pad->partial_data.length,
00905                         (unsigned int)pad->needed_len,
00906                         (unsigned int)copy_len,
00907                         (unsigned int)pblob->length ));
00908 
00909                 tmp_blob = data_blob(NULL,
00910                                 pad->partial_data.length + copy_len);
00911 
00912                 /* Concatenate the two (up to copy_len) bytes. */
00913                 memcpy(tmp_blob.data,
00914                         pad->partial_data.data,
00915                         pad->partial_data.length);
00916                 memcpy(tmp_blob.data + pad->partial_data.length,
00917                         pblob->data,
00918                         copy_len);
00919 
00920                 /* Replace the partial data. */
00921                 data_blob_free(&pad->partial_data);
00922                 pad->partial_data = tmp_blob;
00923                 ZERO_STRUCT(tmp_blob);
00924 
00925                 /* Are we done ? */
00926                 if (pblob->length >= pad->needed_len) {
00927                         /* Yes, replace pblob. */
00928                         data_blob_free(pblob);
00929                         *pblob = pad->partial_data;
00930                         ZERO_STRUCT(pad->partial_data);
00931                         delete_partial_auth(pad);
00932                         return NT_STATUS_OK;
00933                 }
00934 
00935                 /* Still need more data. */
00936                 pad->needed_len -= copy_len;
00937                 return NT_STATUS_MORE_PROCESSING_REQUIRED;
00938         }
00939 
00940         if ((pblob->data[0] != ASN1_APPLICATION(0)) &&
00941             (pblob->data[0] != ASN1_CONTEXT(1))) {
00942                 /* Not something we can determine the
00943                  * length of.
00944                  */
00945                 return NT_STATUS_OK;
00946         }
00947 
00948         /* This is a new SPNEGO sessionsetup - see if
00949          * the data given in this blob is enough.
00950          */
00951 
00952         asn1_load(&data, *pblob);
00953         asn1_start_tag(&data, pblob->data[0]);
00954         if (data.has_error || data.nesting == NULL) {
00955                 asn1_free(&data);
00956                 /* Let caller catch. */
00957                 return NT_STATUS_OK;
00958         }
00959 
00960         /* Integer wrap paranoia.... */
00961 
00962         if (data.nesting->taglen + data.nesting->start < data.nesting->taglen ||
00963             data.nesting->taglen + data.nesting->start < data.nesting->start) {
00964 
00965                 DEBUG(2,("check_spnego_blob_complete: integer wrap "
00966                         "data.nesting->taglen = %u, "
00967                         "data.nesting->start = %u\n",
00968                         (unsigned int)data.nesting->taglen,
00969                         (unsigned int)data.nesting->start ));
00970 
00971                 asn1_free(&data);
00972                 return NT_STATUS_INVALID_PARAMETER;
00973         }
00974 
00975         /* Total length of the needed asn1 is the tag length
00976          * plus the current offset. */
00977 
00978         needed_len = data.nesting->taglen + data.nesting->start;
00979         asn1_free(&data);
00980 
00981         DEBUG(10,("check_spnego_blob_complete: needed_len = %u, "
00982                 "pblob->length = %u\n",
00983                 (unsigned int)needed_len,
00984                 (unsigned int)pblob->length ));
00985 
00986         if (needed_len <= pblob->length) {
00987                 /* Nothing to do - blob is complete. */
00988                 return NT_STATUS_OK;
00989         }
00990 
00991         /* Refuse the blob if it's bigger than 64k. */
00992         if (needed_len > 65536) {
00993                 DEBUG(2,("check_spnego_blob_complete: needed_len too large (%u)\n",
00994                         (unsigned int)needed_len ));
00995                 return NT_STATUS_INVALID_PARAMETER;
00996         }
00997 
00998         /* We must store this blob until complete. */
00999         pad = SMB_MALLOC(sizeof(struct pending_auth_data));
01000         if (!pad) {
01001                 return NT_STATUS_NO_MEMORY;
01002         }
01003         pad->needed_len = needed_len - pblob->length;
01004         pad->partial_data = data_blob(pblob->data, pblob->length);
01005         if (pad->partial_data.data == NULL) {
01006                 SAFE_FREE(pad);
01007                 return NT_STATUS_NO_MEMORY;
01008         }
01009         pad->smbpid = smbpid;
01010         pad->vuid = vuid;
01011         DLIST_ADD(pd_list, pad);
01012 
01013         return NT_STATUS_MORE_PROCESSING_REQUIRED;
01014 }

static int reply_sesssetup_and_X_spnego ( connection_struct conn,
char *  inbuf,
char *  outbuf,
int  length,
int  bufsize 
) [static]

sesssetup.c1021 行で定義されています。

参照先 auth_ntlmssp_start()user_struct::auth_ntlmssp_stateauth_ntlmssp_update()check_spnego_blob_complete()data_blob_::datadata_blob()data_blob_free()file_save()get_partial_auth_user_struct()get_pending_auth_data()get_remote_arch()global_client_capsinvalidate_intermediate_vuid()data_blob_::lengthnt_status_squash()ra_lanman_string()ra_typeRA_VISTARA_WIN2Kregister_vuid()remove_from_common_flags2()reply_spnego_auth()reply_spnego_negotiate()reply_spnego_ntlmssp()set_remote_arch()pending_auth_data::smbpidstatuspending_auth_data::vuid.

参照元 reply_sesssetup_and_X().

01024 {
01025         uint8 *p;
01026         DATA_BLOB blob1;
01027         int ret;
01028         size_t bufrem;
01029         fstring native_os, native_lanman, primary_domain;
01030         char *p2;
01031         uint16 data_blob_len = SVAL(inbuf, smb_vwv7);
01032         enum remote_arch_types ra_type = get_remote_arch();
01033         int vuid = SVAL(inbuf,smb_uid);
01034         user_struct *vuser = NULL;
01035         NTSTATUS status = NT_STATUS_OK;
01036         uint16 smbpid = SVAL(inbuf,smb_pid);
01037 
01038         DEBUG(3,("Doing spnego session setup\n"));
01039 
01040         if (global_client_caps == 0) {
01041                 global_client_caps = IVAL(inbuf,smb_vwv10);
01042 
01043                 if (!(global_client_caps & CAP_STATUS32)) {
01044                         remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
01045                 }
01046 
01047         }
01048                 
01049         p = (uint8 *)smb_buf(inbuf);
01050 
01051         if (data_blob_len == 0) {
01052                 /* an invalid request */
01053                 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
01054         }
01055 
01056         bufrem = smb_bufrem(inbuf, p);
01057         /* pull the spnego blob */
01058         blob1 = data_blob(p, MIN(bufrem, data_blob_len));
01059 
01060 #if 0
01061         file_save("negotiate.dat", blob1.data, blob1.length);
01062 #endif
01063 
01064         p2 = inbuf + smb_vwv13 + data_blob_len;
01065         p2 += srvstr_pull_buf(inbuf, native_os, p2, sizeof(native_os), STR_TERMINATE);
01066         p2 += srvstr_pull_buf(inbuf, native_lanman, p2, sizeof(native_lanman), STR_TERMINATE);
01067         p2 += srvstr_pull_buf(inbuf, primary_domain, p2, sizeof(primary_domain), STR_TERMINATE);
01068         DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n", 
01069                 native_os, native_lanman, primary_domain));
01070 
01071         if ( ra_type == RA_WIN2K ) {
01072                 /* Vista sets neither the OS or lanman strings */
01073 
01074                 if ( !strlen(native_os) && !strlen(native_lanman) )
01075                         set_remote_arch(RA_VISTA);
01076                 
01077                 /* Windows 2003 doesn't set the native lanman string, 
01078                    but does set primary domain which is a bug I think */
01079                            
01080                 if ( !strlen(native_lanman) ) {
01081                         ra_lanman_string( primary_domain );
01082                 } else {
01083                         ra_lanman_string( native_lanman );
01084                 }
01085         }
01086                 
01087         vuser = get_partial_auth_user_struct(vuid);
01088         if (!vuser) {
01089                 struct pending_auth_data *pad = get_pending_auth_data(smbpid);
01090                 if (pad) {
01091                         DEBUG(10,("reply_sesssetup_and_X_spnego: found pending vuid %u\n",
01092                                 (unsigned int)pad->vuid ));
01093                         vuid = pad->vuid;
01094                         vuser = get_partial_auth_user_struct(vuid);
01095                 }
01096         }
01097 
01098         if (!vuser) {
01099                 vuid = register_vuid(NULL, data_blob(NULL, 0), data_blob(NULL, 0), NULL);
01100                 if (vuid == UID_FIELD_INVALID ) {
01101                         data_blob_free(&blob1);
01102                         return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER));
01103                 }
01104         
01105                 vuser = get_partial_auth_user_struct(vuid);
01106         }
01107 
01108         if (!vuser) {
01109                 data_blob_free(&blob1);
01110                 return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER));
01111         }
01112         
01113         SSVAL(outbuf,smb_uid,vuid);
01114 
01115         /* Large (greater than 4k) SPNEGO blobs are split into multiple
01116          * sessionsetup requests as the Windows limit on the security blob
01117          * field is 4k. Bug #4400. JRA.
01118          */
01119 
01120         status = check_spnego_blob_complete(smbpid, vuid, &blob1);
01121         if (!NT_STATUS_IS_OK(status)) {
01122                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
01123                         /* Real error - kill the intermediate vuid */
01124                         invalidate_intermediate_vuid(vuid);
01125                 }
01126                 data_blob_free(&blob1);
01127                 return ERROR_NT(nt_status_squash(status));
01128         }
01129 
01130         if (blob1.data[0] == ASN1_APPLICATION(0)) {
01131                 /* its a negTokenTarg packet */
01132                 ret = reply_spnego_negotiate(conn, inbuf, outbuf, vuid, length, bufsize, blob1,
01133                                              &vuser->auth_ntlmssp_state);
01134                 data_blob_free(&blob1);
01135                 return ret;
01136         }
01137 
01138         if (blob1.data[0] == ASN1_CONTEXT(1)) {
01139                 /* its a auth packet */
01140                 ret = reply_spnego_auth(conn, inbuf, outbuf, vuid, length, bufsize, blob1,
01141                                         &vuser->auth_ntlmssp_state);
01142                 data_blob_free(&blob1);
01143                 return ret;
01144         }
01145 
01146         if (strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0) {
01147                 DATA_BLOB chal;
01148                 if (!vuser->auth_ntlmssp_state) {
01149                         status = auth_ntlmssp_start(&vuser->auth_ntlmssp_state);
01150                         if (!NT_STATUS_IS_OK(status)) {
01151                                 /* Kill the intermediate vuid */
01152                                 invalidate_intermediate_vuid(vuid);
01153                                 data_blob_free(&blob1);
01154                                 return ERROR_NT(nt_status_squash(status));
01155                         }
01156                 }
01157 
01158                 status = auth_ntlmssp_update(vuser->auth_ntlmssp_state,
01159                                                 blob1, &chal);
01160                 
01161                 data_blob_free(&blob1);
01162                 
01163                 reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid, 
01164                                            &vuser->auth_ntlmssp_state,
01165                                            &chal, status, False);
01166                 data_blob_free(&chal);
01167                 return -1;
01168         }
01169 
01170         /* what sort of packet is this? */
01171         DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));
01172 
01173         data_blob_free(&blob1);
01174 
01175         return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
01176 }

static int shutdown_other_smbds ( TDB_CONTEXT tdb,
TDB_DATA  kbuf,
TDB_DATA  dbuf,
void *  p 
) [static]

sesssetup.c1184 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizemessage_send_pid()pid_to_procid()process_exists()sys_getpid().

参照元 setup_new_vc_session().

01186 {
01187         struct sessionid sessionid;
01188         const char *ip = (const char *)p;
01189 
01190         SMB_ASSERT(dbuf.dsize == sizeof(sessionid));
01191         memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
01192 
01193         if (!process_exists(pid_to_procid(sessionid.pid))) {
01194                 return 0;
01195         }
01196 
01197         if (sessionid.pid == sys_getpid()) {
01198                 return 0;
01199         }
01200 
01201         if (strcmp(ip, sessionid.ip_addr) != 0) {
01202                 return 0;
01203         }
01204 
01205         message_send_pid(pid_to_procid(sessionid.pid), MSG_SHUTDOWN,
01206                          NULL, 0, True);
01207         return 0;
01208 }

static void setup_new_vc_session ( void   )  [static]

sesssetup.c1210 行で定義されています。

参照先 client_addr()conn_close_all()invalidate_all_vuids()session_traverse()shutdown_other_smbds().

参照元 reply_sesssetup_and_X().

01211 {
01212         DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x compatible we would close all old resources.\n"));
01213 #if 0
01214         conn_close_all();
01215         invalidate_all_vuids();
01216 #endif
01217         if (lp_reset_on_zero_vc()) {
01218                 session_traverse(shutdown_other_smbds, client_addr());
01219         }
01220 }

int reply_sesssetup_and_X ( connection_struct conn,
char *  inbuf,
char *  outbuf,
int  length,
int  bufsize 
)

sesssetup.c1226 行で定義されています。

参照先 add_session_user()add_session_workgroup()add_signature()chain_reply()check_guest_password()auth_context::check_ntlm_passwordcreate_local_token()data_blob_::datadata_blob()data_blob_clear_free()data_blob_free()do_map_to_guest()auth_context::freefree_user_info()auth_context::get_ntlm_challengeget_remote_arch()get_remote_machine_name()global_client_capsglobal_encrypted_passwords_negotiatedglobal_spnego_negotiatedauth_serversupplied_info::guestdata_blob_::lengthmake_auth_context_subsystem()make_user_info_for_reply()make_user_info_for_reply_enc()map_username()max_sendnegprot_global_auth_contextnt_errstr()nt_status_squash()ProtocolPROTOCOL_NT1auth_serversupplied_info::ptokra_lanman_string()ra_typeRA_WIN2KRA_WIN95RA_WINNTregister_vuid()reload_services()remove_from_common_flags2()reply_sesssetup_and_X_spnego()SEC_SHAREsessionsetup_start_signing_engine()set_message()set_message_end()set_remote_arch()setup_new_vc_session()sub_set_smb_name()auth_serversupplied_info::user_session_key.


変数

struct auth_context* negprot_global_auth_context

negprot.c29 行で定義されています。

BOOL global_encrypted_passwords_negotiated

negprot.c27 行で定義されています。

BOOL global_spnego_negotiated

negprot.c28 行で定義されています。

参照元 negprot_spnego()reply_sesssetup_and_X().

enum protocol_types Protocol

util.c61 行で定義されています。

int max_send

process.c38 行で定義されています。

uint32 global_client_caps = 0

sesssetup.c32 行で定義されています。

struct pending_auth_data* pd_list [static]

sesssetup.c826 行で定義されています。

参照元 check_spnego_blob_complete()delete_partial_auth()get_pending_auth_data().


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