utils/ntlm_auth.c

ソースコードを見る。

型定義

typedef void(*) stdio_helper_function (enum stdio_helper_mode stdio_helper_mode, char *buf, int length)

列挙型

enum  stdio_helper_mode {
  SQUID_2_4_BASIC, SQUID_2_5_BASIC, SQUID_2_5_NTLMSSP,
  NTLMSSP_CLIENT_1, GSS_SPNEGO, GSS_SPNEGO_CLIENT,
  NTLM_SERVER_1, NTLM_CHANGE_PASSWORD_1, NUM_HELPER_MODES
}
enum  {
  OPT_USERNAME = 1000, OPT_DOMAIN, OPT_WORKSTATION,
  OPT_CHALLENGE, OPT_RESPONSE, OPT_LM,
  OPT_NT, OPT_PASSWORD, OPT_LM_KEY,
  OPT_USER_SESSION_KEY, OPT_DIAGNOSTICS, OPT_REQUIRE_MEMBERSHIP,
  OPT_USE_CACHED_CREDS
}

関数

static void manage_squid_basic_request (enum stdio_helper_mode stdio_helper_mode, char *buf, int length)
static void manage_squid_ntlmssp_request (enum stdio_helper_mode stdio_helper_mode, char *buf, int length)
static void manage_client_ntlmssp_request (enum stdio_helper_mode stdio_helper_mode, char *buf, int length)
static void manage_gss_spnego_request (enum stdio_helper_mode stdio_helper_mode, char *buf, int length)
static void manage_gss_spnego_client_request (enum stdio_helper_mode stdio_helper_mode, char *buf, int length)
static void manage_ntlm_server_1_request (enum stdio_helper_mode stdio_helper_mode, char *buf, int length)
static void manage_ntlm_change_password_1_request (enum stdio_helper_mode helper_mode, char *buf, int length)
static char winbind_separator (void)
const char * get_winbind_domain (void)
const char * get_winbind_netbios_name (void)
DATA_BLOB get_challenge (void)
static BOOL parse_ntlm_auth_domain_user (const char *domuser, fstring domain, fstring user)
static BOOL get_require_membership_sid (void)
static BOOL check_plaintext_auth (const char *user, const char *pass, BOOL stdout_diagnostics)
NTSTATUS contact_winbind_auth_crap (const char *username, const char *domain, const char *workstation, const DATA_BLOB *challenge, const DATA_BLOB *lm_response, const DATA_BLOB *nt_response, uint32 flags, uint8 lm_key[8], uint8 user_session_key[16], char **error_string, char **unix_name)
static NTSTATUS contact_winbind_change_pswd_auth_crap (const char *username, const char *domain, const DATA_BLOB new_nt_pswd, const DATA_BLOB old_nt_hash_enc, const DATA_BLOB new_lm_pswd, const DATA_BLOB old_lm_hash_enc, char **error_string)
static NTSTATUS winbind_pw_check (struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
static NTSTATUS local_pw_check (struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
static NTSTATUS ntlm_auth_start_ntlmssp_client (NTLMSSP_STATE **client_ntlmssp_state)
static NTSTATUS ntlm_auth_start_ntlmssp_server (NTLMSSP_STATE **ntlmssp_state)
static NTSTATUS do_ccache_ntlm_auth (DATA_BLOB initial_msg, DATA_BLOB challenge_msg, DATA_BLOB *reply)
static void manage_squid_ntlmssp_request (enum stdio_helper_mode stdio_helper_mode, char *buf, int length)
static void manage_client_ntlmssp_request (enum stdio_helper_mode stdio_helper_mode, char *buf, int length)
static void manage_squid_basic_request (enum stdio_helper_mode stdio_helper_mode, char *buf, int length)
static void offer_gss_spnego_mechs (void)
static void manage_gss_spnego_request (enum stdio_helper_mode stdio_helper_mode, char *buf, int length)
static BOOL manage_client_ntlmssp_init (SPNEGO_DATA spnego)
static void manage_client_ntlmssp_targ (SPNEGO_DATA spnego)
static BOOL manage_client_krb5_init (SPNEGO_DATA spnego)
static void manage_client_krb5_targ (SPNEGO_DATA spnego)
static void manage_gss_spnego_client_request (enum stdio_helper_mode stdio_helper_mode, char *buf, int length)
static void manage_ntlm_server_1_request (enum stdio_helper_mode stdio_helper_mode, char *buf, int length)
static void manage_squid_request (enum stdio_helper_mode helper_mode, stdio_helper_function fn)
static void squid_stream (enum stdio_helper_mode stdio_mode, stdio_helper_function fn)
static BOOL check_auth_crap (void)
int main (int argc, const char **argv)

変数

struct {
   enum stdio_helper_mode   mode
   const char *   name
   stdio_helper_function   fn
stdio_helper_protocols []
int winbindd_fd
const char * opt_username
const char * opt_domain
const char * opt_workstation
const char * opt_password
static DATA_BLOB opt_challenge
static DATA_BLOB opt_lm_response
static DATA_BLOB opt_nt_response
static int request_lm_key
static int request_user_session_key
static int use_cached_creds
static const char * require_membership_of
static const char * require_membership_of_sid
static NTLMSSP_STATEclient_ntlmssp_state = NULL


型定義

typedef void(*) stdio_helper_function(enum stdio_helper_mode stdio_helper_mode, char *buf, int length)

ntlm_auth.c46 行で定義されています。


列挙型

enum stdio_helper_mode

列挙型の値:
SQUID_2_4_BASIC 
SQUID_2_5_BASIC 
SQUID_2_5_NTLMSSP 
NTLMSSP_CLIENT_1 
GSS_SPNEGO 
GSS_SPNEGO_CLIENT 
NTLM_SERVER_1 
NTLM_CHANGE_PASSWORD_1 
NUM_HELPER_MODES 

ntlm_auth.c34 行で定義されています。

anonymous enum

列挙型の値:
OPT_USERNAME 
OPT_DOMAIN 
OPT_WORKSTATION 
OPT_CHALLENGE 
OPT_RESPONSE 
OPT_LM 
OPT_NT 
OPT_PASSWORD 
OPT_LM_KEY 
OPT_USER_SESSION_KEY 
OPT_DIAGNOSTICS 
OPT_REQUIRE_MEMBERSHIP 
OPT_USE_CACHED_CREDS 

ntlm_auth.c2166 行で定義されています。

02166      {
02167         OPT_USERNAME = 1000,
02168         OPT_DOMAIN,
02169         OPT_WORKSTATION,
02170         OPT_CHALLENGE,
02171         OPT_RESPONSE,
02172         OPT_LM,
02173         OPT_NT,
02174         OPT_PASSWORD,
02175         OPT_LM_KEY,
02176         OPT_USER_SESSION_KEY,
02177         OPT_DIAGNOSTICS,
02178         OPT_REQUIRE_MEMBERSHIP,
02179         OPT_USE_CACHED_CREDS
02180 };


関数

static void manage_squid_basic_request ( enum stdio_helper_mode  stdio_helper_mode,
char *  buf,
int  length 
) [static]

static void manage_squid_ntlmssp_request ( enum stdio_helper_mode  stdio_helper_mode,
char *  buf,
int  length 
) [static]

static void manage_client_ntlmssp_request ( enum stdio_helper_mode  stdio_helper_mode,
char *  buf,
int  length 
) [static]

static void manage_gss_spnego_request ( enum stdio_helper_mode  stdio_helper_mode,
char *  buf,
int  length 
) [static]

static void manage_gss_spnego_client_request ( enum stdio_helper_mode  stdio_helper_mode,
char *  buf,
int  length 
) [static]

static void manage_ntlm_server_1_request ( enum stdio_helper_mode  stdio_helper_mode,
char *  buf,
int  length 
) [static]

static void manage_ntlm_change_password_1_request ( enum stdio_helper_mode  helper_mode,
char *  buf,
int  length 
) [static]

ntlm_auth.c1838 行で定義されています。

参照先 base64_decode_inplace()contact_winbind_change_pswd_auth_crap()data_blob_::datadata_blob()E_deshash()E_md4hash()E_old_pw_hash()encode_pw_buffer()winbindd_response::error_stringdata_blob_::lengthparse_ntlm_auth_domain_user()SamOEMhash()smb_xstrdup()strequal()strhex_to_data_blob()strstr_m()usernamex_fprintf()x_stdout.

01839 {
01840         char *request, *parameter;      
01841         static DATA_BLOB new_nt_pswd;
01842         static DATA_BLOB old_nt_hash_enc;
01843         static DATA_BLOB new_lm_pswd;
01844         static DATA_BLOB old_lm_hash_enc;
01845         static char *full_username = NULL;
01846         static char *username = NULL;
01847         static char *domain = NULL;
01848         static char *newpswd =  NULL;
01849         static char *oldpswd = NULL;
01850 
01851         if (strequal(buf, ".")) {
01852                 if(newpswd && oldpswd) {
01853                         uchar old_nt_hash[16];
01854                         uchar old_lm_hash[16];
01855                         uchar new_nt_hash[16];
01856                         uchar new_lm_hash[16];
01857 
01858                         new_nt_pswd = data_blob(NULL, 516);
01859                         old_nt_hash_enc = data_blob(NULL, 16);
01860                         
01861                         /* Calculate the MD4 hash (NT compatible) of the
01862                          * password */
01863                         E_md4hash(oldpswd, old_nt_hash);
01864                         E_md4hash(newpswd, new_nt_hash);
01865 
01866                         /* E_deshash returns false for 'long'
01867                            passwords (> 14 DOS chars).  
01868                            
01869                            Therefore, don't send a buffer
01870                            encrypted with the truncated hash
01871                            (it could allow an even easier
01872                            attack on the password)
01873 
01874                            Likewise, obey the admin's restriction
01875                         */
01876 
01877                         if (lp_client_lanman_auth() &&
01878                             E_deshash(newpswd, new_lm_hash) &&
01879                             E_deshash(oldpswd, old_lm_hash)) {
01880                                 new_lm_pswd = data_blob(NULL, 516);
01881                                 old_lm_hash_enc = data_blob(NULL, 16);
01882                                 encode_pw_buffer(new_lm_pswd.data, newpswd,
01883                                                  STR_UNICODE);
01884 
01885                                 SamOEMhash(new_lm_pswd.data, old_nt_hash, 516);
01886                                 E_old_pw_hash(new_nt_hash, old_lm_hash,
01887                                               old_lm_hash_enc.data);
01888                         } else {
01889                                 new_lm_pswd.data = NULL;
01890                                 new_lm_pswd.length = 0;
01891                                 old_lm_hash_enc.data = NULL;
01892                                 old_lm_hash_enc.length = 0;
01893                         }
01894 
01895                         encode_pw_buffer(new_nt_pswd.data, newpswd,
01896                                          STR_UNICODE);
01897         
01898                         SamOEMhash(new_nt_pswd.data, old_nt_hash, 516);
01899                         E_old_pw_hash(new_nt_hash, old_nt_hash,
01900                                       old_nt_hash_enc.data);
01901                 }
01902                 
01903                 if (!full_username && !username) {      
01904                         x_fprintf(x_stdout, "Error: No username supplied!\n");
01905                 } else if ((!new_nt_pswd.data || !old_nt_hash_enc.data) &&
01906                            (!new_lm_pswd.data || old_lm_hash_enc.data) ) {
01907                         x_fprintf(x_stdout, "Error: No NT or LM password "
01908                                   "blobs supplied!\n");
01909                 } else {
01910                         char *error_string = NULL;
01911                         
01912                         if (full_username && !username) {
01913                                 fstring fstr_user;
01914                                 fstring fstr_domain;
01915                                 
01916                                 if (!parse_ntlm_auth_domain_user(full_username,
01917                                                                  fstr_user,
01918                                                                  fstr_domain)) {
01919                                         /* username might be 'tainted', don't
01920                                          * print into our new-line
01921                                          * deleimianted stream */
01922                                         x_fprintf(x_stdout, "Error: Could not "
01923                                                   "parse into domain and "
01924                                                   "username\n");
01925                                         SAFE_FREE(username);
01926                                         username = smb_xstrdup(full_username);
01927                                 } else {
01928                                         SAFE_FREE(username);
01929                                         SAFE_FREE(domain);
01930                                         username = smb_xstrdup(fstr_user);
01931                                         domain = smb_xstrdup(fstr_domain);
01932                                 }
01933                                 
01934                         }
01935 
01936                         if(!NT_STATUS_IS_OK(contact_winbind_change_pswd_auth_crap(
01937                                                     username, domain,
01938                                                     new_nt_pswd,
01939                                                     old_nt_hash_enc,
01940                                                     new_lm_pswd,
01941                                                     old_lm_hash_enc,
01942                                                     &error_string))) {
01943                                 x_fprintf(x_stdout, "Password-Change: No\n");
01944                                 x_fprintf(x_stdout, "Password-Change-Error: "
01945                                           "%s\n.\n", error_string);
01946                         } else {
01947                                 x_fprintf(x_stdout, "Password-Change: Yes\n");
01948                         }
01949 
01950                         SAFE_FREE(error_string);
01951                 }
01952                 /* clear out the state */
01953                 new_nt_pswd = data_blob(NULL, 0);
01954                 old_nt_hash_enc = data_blob(NULL, 0);
01955                 new_lm_pswd = data_blob(NULL, 0);
01956                 old_nt_hash_enc = data_blob(NULL, 0);
01957                 SAFE_FREE(full_username);
01958                 SAFE_FREE(username);
01959                 SAFE_FREE(domain);
01960                 SAFE_FREE(newpswd);
01961                 SAFE_FREE(oldpswd);
01962                 x_fprintf(x_stdout, ".\n");
01963 
01964                 return;
01965         }
01966 
01967         request = buf;
01968 
01969         /* Indicates a base64 encoded structure */
01970         parameter = strstr_m(request, ":: ");
01971         if (!parameter) {
01972                 parameter = strstr_m(request, ": ");
01973                 
01974                 if (!parameter) {
01975                         DEBUG(0, ("Parameter not found!\n"));
01976                         x_fprintf(x_stdout, "Error: Parameter not found!\n.\n");
01977                         return;
01978                 }
01979                 
01980                 parameter[0] ='\0';
01981                 parameter++;
01982                 parameter[0] ='\0';
01983                 parameter++;
01984         } else {
01985                 parameter[0] ='\0';
01986                 parameter++;
01987                 parameter[0] ='\0';
01988                 parameter++;
01989                 parameter[0] ='\0';
01990                 parameter++;
01991 
01992                 base64_decode_inplace(parameter);
01993         }
01994 
01995         if (strequal(request, "new-nt-password-blob")) {
01996                 new_nt_pswd = strhex_to_data_blob(NULL, parameter);
01997                 if (new_nt_pswd.length != 516) {
01998                         x_fprintf(x_stdout, "Error: hex decode of %s failed! "
01999                                   "(got %d bytes, expected 516)\n.\n", 
02000                                   parameter,
02001                                   (int)new_nt_pswd.length);
02002                         new_nt_pswd = data_blob(NULL, 0);
02003                 }
02004         } else if (strequal(request, "old-nt-hash-blob")) {
02005                 old_nt_hash_enc = strhex_to_data_blob(NULL, parameter);
02006                 if (old_nt_hash_enc.length != 16) {
02007                         x_fprintf(x_stdout, "Error: hex decode of %s failed! "
02008                                   "(got %d bytes, expected 16)\n.\n", 
02009                                   parameter,
02010                                   (int)old_nt_hash_enc.length);
02011                         old_nt_hash_enc = data_blob(NULL, 0);
02012                 }
02013         } else if (strequal(request, "new-lm-password-blob")) {
02014                 new_lm_pswd = strhex_to_data_blob(NULL, parameter);
02015                 if (new_lm_pswd.length != 516) {
02016                         x_fprintf(x_stdout, "Error: hex decode of %s failed! "
02017                                   "(got %d bytes, expected 516)\n.\n", 
02018                                   parameter,
02019                                   (int)new_lm_pswd.length);
02020                         new_lm_pswd = data_blob(NULL, 0);
02021                 }
02022         }
02023         else if (strequal(request, "old-lm-hash-blob")) {
02024                 old_lm_hash_enc = strhex_to_data_blob(NULL, parameter);
02025                 if (old_lm_hash_enc.length != 16)
02026                 {
02027                         x_fprintf(x_stdout, "Error: hex decode of %s failed! "
02028                                   "(got %d bytes, expected 16)\n.\n", 
02029                                   parameter,
02030                                   (int)old_lm_hash_enc.length);
02031                         old_lm_hash_enc = data_blob(NULL, 0);
02032                 }
02033         } else if (strequal(request, "nt-domain")) {
02034                 domain = smb_xstrdup(parameter);
02035         } else if(strequal(request, "username")) {
02036                 username = smb_xstrdup(parameter);
02037         } else if(strequal(request, "full-username")) {
02038                 username = smb_xstrdup(parameter);
02039         } else if(strequal(request, "new-password")) {
02040                 newpswd = smb_xstrdup(parameter);
02041         } else if (strequal(request, "old-password")) {
02042                 oldpswd = smb_xstrdup(parameter);
02043         } else {
02044                 x_fprintf(x_stdout, "Error: Unknown request %s\n.\n", request);
02045         }
02046 }

static char winbind_separator ( void   )  [static]

ntlm_auth.c101 行で定義されています。

参照先 d_printf()winbindd_response::datawinbindd_response::infoNSS_STATUS_SUCCESSWINBINDD_INFOwinbindd_request_response().

00102 {
00103         struct winbindd_response response;
00104         static BOOL got_sep;
00105         static char sep;
00106 
00107         if (got_sep)
00108                 return sep;
00109 
00110         ZERO_STRUCT(response);
00111 
00112         /* Send off request */
00113 
00114         if (winbindd_request_response(WINBINDD_INFO, NULL, &response) !=
00115             NSS_STATUS_SUCCESS) {
00116                 d_printf("could not obtain winbind separator!\n");
00117                 return *lp_winbind_separator();
00118         }
00119 
00120         sep = response.data.info.winbind_separator;
00121         got_sep = True;
00122 
00123         if (!sep) {
00124                 d_printf("winbind separator was NULL!\n");
00125                 return *lp_winbind_separator();
00126         }
00127         
00128         return sep;
00129 }

const char* get_winbind_domain ( void   ) 

ntlm_auth.c131 行で定義されています。

参照先 winbindd_response::datawinbindd_response::domain_namelp_workgroup()NSS_STATUS_SUCCESSWINBINDD_DOMAIN_NAMEwinbindd_request_response().

00132 {
00133         struct winbindd_response response;
00134 
00135         static fstring winbind_domain;
00136         if (*winbind_domain) {
00137                 return winbind_domain;
00138         }
00139 
00140         ZERO_STRUCT(response);
00141 
00142         /* Send off request */
00143 
00144         if (winbindd_request_response(WINBINDD_DOMAIN_NAME, NULL, &response) !=
00145             NSS_STATUS_SUCCESS) {
00146                 DEBUG(0, ("could not obtain winbind domain name!\n"));
00147                 return lp_workgroup();
00148         }
00149 
00150         fstrcpy(winbind_domain, response.data.domain_name);
00151 
00152         return winbind_domain;
00153 
00154 }

const char* get_winbind_netbios_name ( void   ) 

ntlm_auth.c156 行で定義されています。

参照先 winbindd_response::dataglobal_mynamewinbindd_response::netbios_nameNSS_STATUS_SUCCESSWINBINDD_NETBIOS_NAMEwinbindd_request_response().

参照元 ntlm_auth_start_ntlmssp_server()test_lmv2_ntlmv2_broken().

00157 {
00158         struct winbindd_response response;
00159 
00160         static fstring winbind_netbios_name;
00161 
00162         if (*winbind_netbios_name) {
00163                 return winbind_netbios_name;
00164         }
00165 
00166         ZERO_STRUCT(response);
00167 
00168         /* Send off request */
00169 
00170         if (winbindd_request_response(WINBINDD_NETBIOS_NAME, NULL, &response) !=
00171             NSS_STATUS_SUCCESS) {
00172                 DEBUG(0, ("could not obtain winbind netbios name!\n"));
00173                 return global_myname();
00174         }
00175 
00176         fstrcpy(winbind_netbios_name, response.data.netbios_name);
00177 
00178         return winbind_netbios_name;
00179 
00180 }

DATA_BLOB get_challenge ( void   ) 

ntlm_auth.c182 行で定義されています。

参照先 data_blob_::datadata_blob()generate_random_buffer()data_blob_::lengthopt_challenge.

00183 {
00184         static DATA_BLOB chal;
00185         if (opt_challenge.length)
00186                 return opt_challenge;
00187         
00188         chal = data_blob(NULL, 8);
00189 
00190         generate_random_buffer(chal.data, chal.length);
00191         return chal;
00192 }

static BOOL parse_ntlm_auth_domain_user ( const char *  domuser,
fstring  domain,
fstring  user 
) [static]

ntlm_auth.c197 行で定義されています。

参照先 strupper_m()winbind_separator().

参照元 get_require_membership_sid()manage_ntlm_change_password_1_request()manage_ntlm_server_1_request().

00199 {
00200 
00201         char *p = strchr(domuser,winbind_separator());
00202 
00203         if (!p) {
00204                 return False;
00205         }
00206         
00207         fstrcpy(user, p+1);
00208         fstrcpy(domain, domuser);
00209         domain[PTR_DIFF(p, domuser)] = 0;
00210         strupper_m(domain);
00211 
00212         return True;
00213 }

static BOOL get_require_membership_sid ( void   )  [static]

ntlm_auth.c215 行で定義されています。

参照先 winbindd_response::datawinbindd_request::datawinbindd_request::nameNSS_STATUS_SUCCESSparse_ntlm_auth_domain_user()require_membership_ofrequire_membership_of_sidwinbindd_response::sidWINBINDD_LOOKUPNAMEwinbindd_request_response().

参照元 check_plaintext_auth()contact_winbind_auth_crap()contact_winbind_change_pswd_auth_crap().

00215                                              {
00216         struct winbindd_request request;
00217         struct winbindd_response response;
00218 
00219         if (!require_membership_of) {
00220                 return True;
00221         }
00222 
00223         if (require_membership_of_sid) {
00224                 return True;
00225         }
00226 
00227         /* Otherwise, ask winbindd for the name->sid request */
00228 
00229         ZERO_STRUCT(request);
00230         ZERO_STRUCT(response);
00231 
00232         if (!parse_ntlm_auth_domain_user(require_membership_of, 
00233                                          request.data.name.dom_name, 
00234                                          request.data.name.name)) {
00235                 DEBUG(0, ("Could not parse %s into seperate domain/name parts!\n", 
00236                           require_membership_of));
00237                 return False;
00238         }
00239 
00240         if (winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response) !=
00241             NSS_STATUS_SUCCESS) {
00242                 DEBUG(0, ("Winbindd lookupname failed to resolve %s into a SID!\n", 
00243                           require_membership_of));
00244                 return False;
00245         }
00246 
00247         require_membership_of_sid = SMB_STRDUP(response.data.sid.sid);
00248 
00249         if (require_membership_of_sid)
00250                 return True;
00251 
00252         return False;
00253 }

static BOOL check_plaintext_auth ( const char *  user,
const char *  pass,
BOOL  stdout_diagnostics 
) [static]

ntlm_auth.c256 行で定義されています。

参照先 winbindd_response::authwinbindd_request::authd_printf()winbindd_response::datawinbindd_request::dataget_require_membership_sid()NSS_STATUS_SUCCESSrequire_membership_of_sidresultWINBINDD_PAM_AUTHwinbindd_request_response().

参照元 main()manage_ntlm_server_1_request()manage_squid_basic_request().

00258 {
00259         struct winbindd_request request;
00260         struct winbindd_response response;
00261         NSS_STATUS result;
00262 
00263         if (!get_require_membership_sid()) {
00264                 return False;
00265         }
00266 
00267         /* Send off request */
00268 
00269         ZERO_STRUCT(request);
00270         ZERO_STRUCT(response);
00271 
00272         fstrcpy(request.data.auth.user, user);
00273         fstrcpy(request.data.auth.pass, pass);
00274         if (require_membership_of_sid)
00275                 pstrcpy(request.data.auth.require_membership_of_sid, require_membership_of_sid);
00276 
00277         result = winbindd_request_response(WINBINDD_PAM_AUTH, &request, &response);
00278 
00279         /* Display response */
00280         
00281         if (stdout_diagnostics) {
00282                 if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0)) {
00283                         d_printf("Reading winbind reply failed! (0x01)\n");
00284                 }
00285                 
00286                 d_printf("%s: %s (0x%x)\n", 
00287                          response.data.auth.nt_status_string, 
00288                          response.data.auth.error_string, 
00289                          response.data.auth.nt_status);
00290         } else {
00291                 if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0)) {
00292                         DEBUG(1, ("Reading winbind reply failed! (0x01)\n"));
00293                 }
00294                 
00295                 DEBUG(3, ("%s: %s (0x%x)\n", 
00296                           response.data.auth.nt_status_string, 
00297                           response.data.auth.error_string,
00298                           response.data.auth.nt_status));               
00299         }
00300                 
00301         return (result == NSS_STATUS_SUCCESS);
00302 }

NTSTATUS contact_winbind_auth_crap ( const char *  username,
const char *  domain,
const char *  workstation,
const DATA_BLOB challenge,
const DATA_BLOB lm_response,
const DATA_BLOB nt_response,
uint32  flags,
uint8  lm_key[8],
uint8  user_session_key[16],
char **  error_string,
char **  unix_name 
)

ntlm_auth.c306 行で定義されています。

参照先 winbindd_response::authwinbindd_request::auth_crapwinbindd_response::datadata_blob_::datawinbindd_request::datawinbindd_response::extra_datawinbindd_request::flagsfree_response()get_require_membership_sid()data_blob_::lengthNSS_STATUS_SUCCESSwinbindd_response::nt_statusrequire_membership_of_sidresultsmb_xstrdup()WINBINDD_PAM_AUTH_CRAPwinbindd_request_response().

参照元 check_auth_crap()manage_ntlm_server_1_request()test_lm_ntlm_broken()test_lmv2_ntlmv2_broken()test_ntlm_in_both()test_ntlm_in_lm()test_plaintext()winbind_pw_check().

00317 {
00318         NTSTATUS nt_status;
00319         NSS_STATUS result;
00320         struct winbindd_request request;
00321         struct winbindd_response response;
00322 
00323         if (!get_require_membership_sid()) {
00324                 return NT_STATUS_INVALID_PARAMETER;
00325         }
00326 
00327         ZERO_STRUCT(request);
00328         ZERO_STRUCT(response);
00329 
00330         request.flags = flags;
00331 
00332         request.data.auth_crap.logon_parameters = MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT | MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT;
00333 
00334         if (require_membership_of_sid)
00335                 fstrcpy(request.data.auth_crap.require_membership_of_sid, require_membership_of_sid);
00336 
00337         fstrcpy(request.data.auth_crap.user, username);
00338         fstrcpy(request.data.auth_crap.domain, domain);
00339 
00340         fstrcpy(request.data.auth_crap.workstation, 
00341                 workstation);
00342 
00343         memcpy(request.data.auth_crap.chal, challenge->data, MIN(challenge->length, 8));
00344 
00345         if (lm_response && lm_response->length) {
00346                 memcpy(request.data.auth_crap.lm_resp, 
00347                        lm_response->data, 
00348                        MIN(lm_response->length, sizeof(request.data.auth_crap.lm_resp)));
00349                 request.data.auth_crap.lm_resp_len = lm_response->length;
00350         }
00351 
00352         if (nt_response && nt_response->length) {
00353                 memcpy(request.data.auth_crap.nt_resp, 
00354                        nt_response->data, 
00355                        MIN(nt_response->length, sizeof(request.data.auth_crap.nt_resp)));
00356                 request.data.auth_crap.nt_resp_len = nt_response->length;
00357         }
00358         
00359         result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response);
00360 
00361         /* Display response */
00362 
00363         if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0)) {
00364                 nt_status = NT_STATUS_UNSUCCESSFUL;
00365                 if (error_string)
00366                         *error_string = smb_xstrdup("Reading winbind reply failed!");
00367                 free_response(&response);
00368                 return nt_status;
00369         }
00370         
00371         nt_status = (NT_STATUS(response.data.auth.nt_status));
00372         if (!NT_STATUS_IS_OK(nt_status)) {
00373                 if (error_string) 
00374                         *error_string = smb_xstrdup(response.data.auth.error_string);
00375                 free_response(&response);
00376                 return nt_status;
00377         }
00378 
00379         if ((flags & WBFLAG_PAM_LMKEY) && lm_key) {
00380                 memcpy(lm_key, response.data.auth.first_8_lm_hash, 
00381                        sizeof(response.data.auth.first_8_lm_hash));
00382         }
00383         if ((flags & WBFLAG_PAM_USER_SESSION_KEY) && user_session_key) {
00384                 memcpy(user_session_key, response.data.auth.user_session_key, 
00385                         sizeof(response.data.auth.user_session_key));
00386         }
00387 
00388         if (flags & WBFLAG_PAM_UNIX_NAME) {
00389                 *unix_name = SMB_STRDUP((char *)response.extra_data.data);
00390                 if (!*unix_name) {
00391                         free_response(&response);
00392                         return NT_STATUS_NO_MEMORY;
00393                 }
00394         }
00395 
00396         free_response(&response);
00397         return nt_status;
00398 }

static NTSTATUS contact_winbind_change_pswd_auth_crap ( const char *  username,
const char *  domain,
const DATA_BLOB  new_nt_pswd,
const DATA_BLOB  old_nt_hash_enc,
const DATA_BLOB  new_lm_pswd,
const DATA_BLOB  old_lm_hash_enc,
char **  error_string 
) [static]

ntlm_auth.c401 行で定義されています。

参照先 winbindd_response::authwinbindd_request::chng_pswd_auth_crapwinbindd_response::datadata_blob_::datawinbindd_request::datafree_response()get_require_membership_sid()data_blob_::lengthNSS_STATUS_SUCCESSwinbindd_response::nt_statusresultsmb_xstrdup()WINBINDD_PAM_CHNG_PSWD_AUTH_CRAPwinbindd_request_response().

参照元 manage_ntlm_change_password_1_request().

00408 {
00409         NTSTATUS nt_status;
00410         NSS_STATUS result;
00411         struct winbindd_request request;
00412         struct winbindd_response response;
00413 
00414         if (!get_require_membership_sid())
00415         {
00416                 if(error_string)
00417                         *error_string = smb_xstrdup("Can't get membership sid.");
00418                 return NT_STATUS_INVALID_PARAMETER;
00419         }
00420 
00421         ZERO_STRUCT(request);
00422         ZERO_STRUCT(response);
00423 
00424         if(username != NULL)
00425                 fstrcpy(request.data.chng_pswd_auth_crap.user, username);
00426         if(domain != NULL)
00427                 fstrcpy(request.data.chng_pswd_auth_crap.domain,domain);
00428 
00429         if(new_nt_pswd.length)
00430         {
00431                 memcpy(request.data.chng_pswd_auth_crap.new_nt_pswd, new_nt_pswd.data, sizeof(request.data.chng_pswd_auth_crap.new_nt_pswd));
00432                 request.data.chng_pswd_auth_crap.new_nt_pswd_len = new_nt_pswd.length;
00433         }
00434 
00435         if(old_nt_hash_enc.length)
00436         {
00437                 memcpy(request.data.chng_pswd_auth_crap.old_nt_hash_enc, old_nt_hash_enc.data, sizeof(request.data.chng_pswd_auth_crap.old_nt_hash_enc));
00438                 request.data.chng_pswd_auth_crap.old_nt_hash_enc_len = old_nt_hash_enc.length;
00439         }
00440 
00441         if(new_lm_pswd.length)
00442         {
00443                 memcpy(request.data.chng_pswd_auth_crap.new_lm_pswd, new_lm_pswd.data, sizeof(request.data.chng_pswd_auth_crap.new_lm_pswd));
00444                 request.data.chng_pswd_auth_crap.new_lm_pswd_len = new_lm_pswd.length;
00445         }
00446 
00447         if(old_lm_hash_enc.length)
00448         {
00449                 memcpy(request.data.chng_pswd_auth_crap.old_lm_hash_enc, old_lm_hash_enc.data, sizeof(request.data.chng_pswd_auth_crap.old_lm_hash_enc));
00450                 request.data.chng_pswd_auth_crap.old_lm_hash_enc_len = old_lm_hash_enc.length;
00451         }
00452         
00453         result = winbindd_request_response(WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, &request, &response);
00454 
00455         /* Display response */
00456 
00457         if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0))
00458         {
00459                 nt_status = NT_STATUS_UNSUCCESSFUL;
00460                 if (error_string)
00461                         *error_string = smb_xstrdup("Reading winbind reply failed!");
00462                 free_response(&response);
00463                 return nt_status;
00464         }
00465         
00466         nt_status = (NT_STATUS(response.data.auth.nt_status));
00467         if (!NT_STATUS_IS_OK(nt_status))
00468         {
00469                 if (error_string) 
00470                         *error_string = smb_xstrdup(response.data.auth.error_string);
00471                 free_response(&response);
00472                 return nt_status;
00473         }
00474 
00475         free_response(&response);
00476         
00477     return nt_status;
00478 }

static NTSTATUS winbind_pw_check ( struct ntlmssp_state ntlmssp_state,
DATA_BLOB user_session_key,
DATA_BLOB lm_session_key 
) [static]

ntlm_auth.c480 行で定義されています。

参照先 ntlmssp_state::auth_contextntlmssp_state::chalcontact_winbind_auth_crap()data_blob_::datadata_blob()ntlmssp_state::domainwinbindd_response::error_stringntlmssp_state::lm_respntlmssp_state::mem_ctxntlmssp_state::nt_respwinbindd_response::nt_statustalloc_strdup()ntlmssp_state::userwinbindd_response::user_session_keyntlmssp_state::workstation.

参照元 ntlm_auth_start_ntlmssp_server().

00481 {
00482         static const char zeros[16] = { 0, };
00483         NTSTATUS nt_status;
00484         char *error_string;
00485         uint8 lm_key[8]; 
00486         uint8 user_sess_key[16]; 
00487         char *unix_name;
00488 
00489         nt_status = contact_winbind_auth_crap(ntlmssp_state->user, ntlmssp_state->domain,
00490                                               ntlmssp_state->workstation,
00491                                               &ntlmssp_state->chal,
00492                                               &ntlmssp_state->lm_resp,
00493                                               &ntlmssp_state->nt_resp, 
00494                                               WBFLAG_PAM_LMKEY | WBFLAG_PAM_USER_SESSION_KEY | WBFLAG_PAM_UNIX_NAME,
00495                                               lm_key, user_sess_key, 
00496                                               &error_string, &unix_name);
00497 
00498         if (NT_STATUS_IS_OK(nt_status)) {
00499                 if (memcmp(lm_key, zeros, 8) != 0) {
00500                         *lm_session_key = data_blob(NULL, 16);
00501                         memcpy(lm_session_key->data, lm_key, 8);
00502                         memset(lm_session_key->data+8, '\0', 8);
00503                 }
00504                 
00505                 if (memcmp(user_sess_key, zeros, 16) != 0) {
00506                         *user_session_key = data_blob(user_sess_key, 16);
00507                 }
00508                 ntlmssp_state->auth_context = talloc_strdup(ntlmssp_state->mem_ctx, unix_name);
00509                 SAFE_FREE(unix_name);
00510         } else {
00511                 DEBUG(NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED) ? 0 : 3, 
00512                       ("Login for user [%s]\\[%s]@[%s] failed due to [%s]\n", 
00513                        ntlmssp_state->domain, ntlmssp_state->user, 
00514                        ntlmssp_state->workstation, 
00515                        error_string ? error_string : "unknown error (NULL)"));
00516                 ntlmssp_state->auth_context = NULL;
00517         }
00518         return nt_status;
00519 }

static NTSTATUS local_pw_check ( struct ntlmssp_state ntlmssp_state,
DATA_BLOB user_session_key,
DATA_BLOB lm_session_key 
) [static]

ntlm_auth.c521 行で定義されています。

参照先 ntlmssp_state::auth_contextntlmssp_state::chalntlmssp_state::domainntlmssp_state::lm_respntlmssp_state::mem_ctxnt_errstr()nt_lm_owf_gen()ntlmssp_state::nt_respwinbindd_response::nt_statusntlm_password_check()opt_passwordtalloc_asprintf()ntlmssp_state::userwinbindd_response::user_session_keyntlmssp_state::workstation.

参照元 ntlm_auth_start_ntlmssp_server().

00522 {
00523         NTSTATUS nt_status;
00524         uint8 lm_pw[16], nt_pw[16];
00525 
00526         nt_lm_owf_gen (opt_password, nt_pw, lm_pw);
00527         
00528         nt_status = ntlm_password_check(ntlmssp_state->mem_ctx, 
00529                                         &ntlmssp_state->chal,
00530                                         &ntlmssp_state->lm_resp,
00531                                         &ntlmssp_state->nt_resp, 
00532                                         NULL, NULL,
00533                                         ntlmssp_state->user, 
00534                                         ntlmssp_state->user, 
00535                                         ntlmssp_state->domain,
00536                                         lm_pw, nt_pw, user_session_key, lm_session_key);
00537         
00538         if (NT_STATUS_IS_OK(nt_status)) {
00539                 ntlmssp_state->auth_context = talloc_asprintf(ntlmssp_state->mem_ctx, 
00540                                                               "%s%c%s", ntlmssp_state->domain, 
00541                                                               *lp_winbind_separator(), 
00542                                                               ntlmssp_state->user);
00543         } else {
00544                 DEBUG(3, ("Login for user [%s]\\[%s]@[%s] failed due to [%s]\n", 
00545                           ntlmssp_state->domain, ntlmssp_state->user, ntlmssp_state->workstation, 
00546                           nt_errstr(nt_status)));
00547                 ntlmssp_state->auth_context = NULL;
00548         }
00549         return nt_status;
00550 }

static NTSTATUS ntlm_auth_start_ntlmssp_client ( NTLMSSP_STATE **  client_ntlmssp_state  )  [static]

ntlm_auth.c552 行で定義されています。

参照先 client_ntlmssp_statent_errstr()ntlmssp_client_start()ntlmssp_end()ntlmssp_set_domain()ntlmssp_set_password()ntlmssp_set_username()opt_domainopt_passwordopt_usernamestatus.

参照元 manage_client_ntlmssp_init()manage_client_ntlmssp_request().

00553 {
00554         NTSTATUS status;
00555         if ( (opt_username == NULL) || (opt_domain == NULL) ) {
00556                 status = NT_STATUS_UNSUCCESSFUL;
00557                 DEBUG(1, ("Need username and domain for NTLMSSP\n"));
00558                 return NT_STATUS_INVALID_PARAMETER;
00559         }
00560 
00561         status = ntlmssp_client_start(client_ntlmssp_state);
00562 
00563         if (!NT_STATUS_IS_OK(status)) {
00564                 DEBUG(1, ("Could not start NTLMSSP client: %s\n",
00565                           nt_errstr(status)));
00566                 ntlmssp_end(client_ntlmssp_state);
00567                 return status;
00568         }
00569 
00570         status = ntlmssp_set_username(*client_ntlmssp_state, opt_username);
00571 
00572         if (!NT_STATUS_IS_OK(status)) {
00573                 DEBUG(1, ("Could not set username: %s\n",
00574                           nt_errstr(status)));
00575                 ntlmssp_end(client_ntlmssp_state);
00576                 return status;
00577         }
00578 
00579         status = ntlmssp_set_domain(*client_ntlmssp_state, opt_domain);
00580 
00581         if (!NT_STATUS_IS_OK(status)) {
00582                 DEBUG(1, ("Could not set domain: %s\n",
00583                           nt_errstr(status)));
00584                 ntlmssp_end(client_ntlmssp_state);
00585                 return status;
00586         }
00587 
00588         if (opt_password) {
00589                 status = ntlmssp_set_password(*client_ntlmssp_state, opt_password);
00590         
00591                 if (!NT_STATUS_IS_OK(status)) {
00592                         DEBUG(1, ("Could not set password: %s\n",
00593                                   nt_errstr(status)));
00594                         ntlmssp_end(client_ntlmssp_state);
00595                         return status;
00596                 }
00597         }
00598 
00599         return NT_STATUS_OK;
00600 }

static NTSTATUS ntlm_auth_start_ntlmssp_server ( NTLMSSP_STATE **  ntlmssp_state  )  [static]

ntlm_auth.c602 行で定義されています。

参照先 get_winbind_domain()get_winbind_netbios_name()global_mynamelocal_pw_check()lp_workgroup()nt_errstr()ntlmssp_server_start()opt_passwordstatuswinbind_pw_check().

参照元 manage_gss_spnego_request()manage_squid_ntlmssp_request().

00603 {
00604         NTSTATUS status = ntlmssp_server_start(ntlmssp_state);
00605         
00606         if (!NT_STATUS_IS_OK(status)) {
00607                 DEBUG(1, ("Could not start NTLMSSP server: %s\n",
00608                           nt_errstr(status)));
00609                 return status;
00610         }
00611 
00612         /* Have we been given a local password, or should we ask winbind? */
00613         if (opt_password) {
00614                 (*ntlmssp_state)->check_password = local_pw_check;
00615                 (*ntlmssp_state)->get_domain = lp_workgroup;
00616                 (*ntlmssp_state)->get_global_myname = global_myname;
00617         } else {
00618                 (*ntlmssp_state)->check_password = winbind_pw_check;
00619                 (*ntlmssp_state)->get_domain = get_winbind_domain;
00620                 (*ntlmssp_state)->get_global_myname = get_winbind_netbios_name;
00621         }
00622         return NT_STATUS_OK;
00623 }

static NTSTATUS do_ccache_ntlm_auth ( DATA_BLOB  initial_msg,
DATA_BLOB  challenge_msg,
DATA_BLOB reply 
) [static]

ntlm_auth.c629 行で定義されています。

参照先 winbindd_response::ccache_ntlm_authwinbindd_request::ccache_ntlm_authwinbindd_response::datadata_blob_::datawinbindd_request::datadata_blob()winbindd_response::extra_datawinbindd_request::extra_datawinbindd_request::extra_lenfree_response()fstr_sprintf()data_blob_::lengthNSS_STATUS_SUCCESSopt_domainopt_usernameresultwinbind_separator()WINBINDD_CCACHE_NTLMAUTHwinbindd_request_response().

参照元 manage_client_ntlmssp_request().

00631 {
00632         struct winbindd_request wb_request;
00633         struct winbindd_response wb_response;
00634         NSS_STATUS result;
00635 
00636         /* get winbindd to do the ntlmssp step on our behalf */
00637         ZERO_STRUCT(wb_request);
00638         ZERO_STRUCT(wb_response);
00639 
00640         fstr_sprintf(wb_request.data.ccache_ntlm_auth.user,
00641                 "%s%c%s", opt_domain, winbind_separator(), opt_username);
00642         wb_request.data.ccache_ntlm_auth.uid = geteuid();
00643         wb_request.data.ccache_ntlm_auth.initial_blob_len = initial_msg.length;
00644         wb_request.data.ccache_ntlm_auth.challenge_blob_len = challenge_msg.length;
00645         wb_request.extra_len = initial_msg.length + challenge_msg.length;
00646 
00647         if (wb_request.extra_len > 0) {
00648                 wb_request.extra_data.data = SMB_MALLOC_ARRAY(char, wb_request.extra_len);
00649                 if (wb_request.extra_data.data == NULL) {
00650                         return NT_STATUS_NO_MEMORY;
00651                 }
00652 
00653                 memcpy(wb_request.extra_data.data, initial_msg.data, initial_msg.length);
00654                 memcpy(wb_request.extra_data.data + initial_msg.length,
00655                         challenge_msg.data, challenge_msg.length);
00656         }
00657 
00658         result = winbindd_request_response(WINBINDD_CCACHE_NTLMAUTH, &wb_request, &wb_response);
00659         SAFE_FREE(wb_request.extra_data.data);
00660 
00661         if (result != NSS_STATUS_SUCCESS) {
00662                 free_response(&wb_response);
00663                 return NT_STATUS_UNSUCCESSFUL;
00664         }
00665 
00666         if (reply) {
00667                 *reply = data_blob(wb_response.extra_data.data,
00668                                 wb_response.data.ccache_ntlm_auth.auth_blob_len);
00669                 if (wb_response.data.ccache_ntlm_auth.auth_blob_len > 0 &&
00670                                 reply->data == NULL) {
00671                         free_response(&wb_response);
00672                         return NT_STATUS_NO_MEMORY;
00673                 }
00674         }
00675 
00676         free_response(&wb_response);
00677         return NT_STATUS_MORE_PROCESSING_REQUIRED;
00678 }

static void manage_squid_ntlmssp_request ( enum stdio_helper_mode  stdio_helper_mode,
char *  buf,
int  length 
) [static]

ntlm_auth.c680 行で定義されています。

参照先 ntlmssp_state::auth_contextbase64_decode_data_blob()base64_encode_data_blob()data_blob_::datadata_blob()data_blob_free()dump_data()data_blob_::lengthntlmssp_state::neg_flagsnt_errstr()winbindd_response::nt_statusntlm_auth_start_ntlmssp_server()ntlmssp_end()ntlmssp_update()ntlmssp_want_feature_list()opt_passwordntlmssp_state::session_keyx_fprintf()x_stdout.

00682 {
00683         static NTLMSSP_STATE *ntlmssp_state = NULL;
00684         static char* want_feature_list = NULL;
00685         static uint32 neg_flags = 0;
00686         static BOOL have_session_key = False;
00687         static DATA_BLOB session_key;
00688         DATA_BLOB request, reply;
00689         NTSTATUS nt_status;
00690 
00691         if (strlen(buf) < 2) {
00692                 DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
00693                 x_fprintf(x_stdout, "BH NTLMSSP query invalid\n");
00694                 return;
00695         }
00696 
00697         if (strlen(buf) > 3) {
00698                 if(strncmp(buf, "SF ", 3) == 0){
00699                         DEBUG(10, ("Setting flags to negotioate\n"));
00700                         SAFE_FREE(want_feature_list);
00701                         want_feature_list = SMB_STRNDUP(buf+3, strlen(buf)-3);
00702                         x_fprintf(x_stdout, "OK\n");
00703                         return;
00704                 }
00705                 request = base64_decode_data_blob(buf + 3);
00706         } else {
00707                 request = data_blob(NULL, 0);
00708         }
00709 
00710         if ((strncmp(buf, "PW ", 3) == 0)) {
00711                 /* The calling application wants us to use a local password (rather than winbindd) */
00712 
00713                 opt_password = SMB_STRNDUP((const char *)request.data, request.length);
00714 
00715                 if (opt_password == NULL) {
00716                         DEBUG(1, ("Out of memory\n"));
00717                         x_fprintf(x_stdout, "BH Out of memory\n");
00718                         data_blob_free(&request);
00719                         return;
00720                 }
00721 
00722                 x_fprintf(x_stdout, "OK\n");
00723                 data_blob_free(&request);
00724                 return;
00725         }
00726 
00727         if (strncmp(buf, "YR", 2) == 0) {
00728                 if (ntlmssp_state)
00729                         ntlmssp_end(&ntlmssp_state);
00730         } else if (strncmp(buf, "KK", 2) == 0) {
00731                 
00732         } else if (strncmp(buf, "GF", 2) == 0) {
00733                 DEBUG(10, ("Requested negotiated NTLMSSP flags\n"));
00734                 x_fprintf(x_stdout, "GF 0x%08lx\n", have_session_key?neg_flags:0l);
00735                 data_blob_free(&request);
00736                 return;
00737         } else if (strncmp(buf, "GK", 2) == 0) {
00738                 DEBUG(10, ("Requested NTLMSSP session key\n"));
00739                 if(have_session_key) {
00740                         char *key64 = base64_encode_data_blob(session_key);
00741                         x_fprintf(x_stdout, "GK %s\n", key64?key64:"<NULL>");
00742                         SAFE_FREE(key64);
00743                 } else {
00744                         x_fprintf(x_stdout, "BH No session key available\n");
00745                 }
00746                         
00747                 data_blob_free(&request);
00748                 return;
00749         } else {
00750                 DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
00751                 x_fprintf(x_stdout, "BH NTLMSSP query invalid\n");
00752                 return;
00753         }
00754 
00755         if (!ntlmssp_state) {
00756                 if (!NT_STATUS_IS_OK(nt_status = ntlm_auth_start_ntlmssp_server(&ntlmssp_state))) {
00757                         x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
00758                         return;
00759                 }
00760                 ntlmssp_want_feature_list(ntlmssp_state, want_feature_list);
00761         }
00762 
00763         DEBUG(10, ("got NTLMSSP packet:\n"));
00764         dump_data(10, (const char *)request.data, request.length);
00765 
00766         nt_status = ntlmssp_update(ntlmssp_state, request, &reply);
00767         
00768         if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
00769                 char *reply_base64 = base64_encode_data_blob(reply);
00770                 x_fprintf(x_stdout, "TT %s\n", reply_base64);
00771                 SAFE_FREE(reply_base64);
00772                 data_blob_free(&reply);
00773                 DEBUG(10, ("NTLMSSP challenge\n"));
00774         } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) {
00775                 x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
00776                 DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status)));
00777 
00778                 ntlmssp_end(&ntlmssp_state);
00779         } else if (!NT_STATUS_IS_OK(nt_status)) {
00780                 x_fprintf(x_stdout, "NA %s\n", nt_errstr(nt_status));
00781                 DEBUG(10, ("NTLMSSP %s\n", nt_errstr(nt_status)));
00782         } else {
00783                 x_fprintf(x_stdout, "AF %s\n", (char *)ntlmssp_state->auth_context);
00784                 DEBUG(10, ("NTLMSSP OK!\n"));
00785                 
00786                 if(have_session_key)
00787                         data_blob_free(&session_key);
00788                 session_key = data_blob(ntlmssp_state->session_key.data, 
00789                                 ntlmssp_state->session_key.length);
00790                 neg_flags = ntlmssp_state->neg_flags;
00791                 have_session_key = True;
00792         }
00793 
00794         data_blob_free(&request);
00795 }

static void manage_client_ntlmssp_request ( enum stdio_helper_mode  stdio_helper_mode,
char *  buf,
int  length 
) [static]

ntlm_auth.c797 行で定義されています。

参照先 base64_decode_data_blob()base64_encode_data_blob()data_blob_::datadata_blob()data_blob_free()do_ccache_ntlm_auth()dump_data()data_blob_::lengthntlmssp_state::neg_flagsnt_errstr()winbindd_response::nt_statusntlm_auth_start_ntlmssp_client()ntlmssp_end()ntlmssp_update()ntlmssp_want_feature_list()opt_passwordopt_usernamentlmssp_state::session_keyuse_cached_credsx_fprintf()x_stderrx_stdout.

00799 {
00800         /* The statics here are *HORRIBLE* and this entire concept
00801            needs to be rewritten. Essentially it's using these statics
00802            as the state in a state machine. BLEEEGH ! JRA. */
00803 
00804         static NTLMSSP_STATE *ntlmssp_state = NULL;
00805         static DATA_BLOB initial_message;
00806         static char* want_feature_list = NULL;
00807         static uint32 neg_flags = 0;
00808         static BOOL have_session_key = False;
00809         static DATA_BLOB session_key;
00810         DATA_BLOB request, reply;
00811         NTSTATUS nt_status;
00812         BOOL first = False;
00813         
00814         if (!opt_username || !*opt_username) {
00815                 x_fprintf(x_stderr, "username must be specified!\n\n");
00816                 exit(1);
00817         }
00818 
00819         if (strlen(buf) < 2) {
00820                 DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
00821                 x_fprintf(x_stdout, "BH NTLMSSP query invalid\n");
00822                 return;
00823         }
00824 
00825         if (strlen(buf) > 3) {
00826                 if(strncmp(buf, "SF ", 3) == 0) {
00827                         DEBUG(10, ("Looking for flags to negotiate\n"));
00828                         SAFE_FREE(want_feature_list);
00829                         want_feature_list = SMB_STRNDUP(buf+3, strlen(buf)-3);
00830                         x_fprintf(x_stdout, "OK\n");
00831                         return;
00832                 }
00833                 request = base64_decode_data_blob(buf + 3);
00834         } else {
00835                 request = data_blob(NULL, 0);
00836         }
00837 
00838         if (strncmp(buf, "PW ", 3) == 0) {
00839                 /* We asked for a password and obviously got it :-) */
00840 
00841                 opt_password = SMB_STRNDUP((const char *)request.data, request.length);
00842 
00843                 if (opt_password == NULL) {
00844                         DEBUG(1, ("Out of memory\n"));
00845                         x_fprintf(x_stdout, "BH Out of memory\n");
00846                         data_blob_free(&request);
00847                         return;
00848                 }
00849 
00850                 x_fprintf(x_stdout, "OK\n");
00851                 data_blob_free(&request);
00852                 return;
00853         }
00854 
00855         if (!ntlmssp_state && use_cached_creds) {
00856                 /* check whether credentials are usable. */
00857                 DATA_BLOB empty_blob = data_blob(NULL, 0);
00858 
00859                 nt_status = do_ccache_ntlm_auth(empty_blob, empty_blob, NULL);
00860                 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
00861                         /* failed to use cached creds */
00862                         use_cached_creds = False;
00863                 }
00864         }
00865 
00866         if (opt_password == NULL && !use_cached_creds) {
00867                 
00868                 /* Request a password from the calling process.  After
00869                    sending it, the calling process should retry asking for the negotiate. */
00870                 
00871                 DEBUG(10, ("Requesting password\n"));
00872                 x_fprintf(x_stdout, "PW\n");
00873                 return;
00874         }
00875 
00876         if (strncmp(buf, "YR", 2) == 0) {
00877                 if (ntlmssp_state)
00878                         ntlmssp_end(&ntlmssp_state);
00879         } else if (strncmp(buf, "TT", 2) == 0) {
00880                 
00881         } else if (strncmp(buf, "GF", 2) == 0) {
00882                 DEBUG(10, ("Requested negotiated NTLMSSP flags\n"));
00883                 x_fprintf(x_stdout, "GF 0x%08lx\n", have_session_key?neg_flags:0l);
00884                 data_blob_free(&request);
00885                 return;
00886         } else if (strncmp(buf, "GK", 2) == 0 ) {
00887                 DEBUG(10, ("Requested session key\n"));
00888 
00889                 if(have_session_key) {
00890                         char *key64 = base64_encode_data_blob(session_key);
00891                         x_fprintf(x_stdout, "GK %s\n", key64?key64:"<NULL>");
00892                         SAFE_FREE(key64);
00893                 }
00894                 else {
00895                         x_fprintf(x_stdout, "BH No session key available\n");
00896                 }
00897 
00898                 data_blob_free(&request);
00899                 return;
00900         } else {
00901                 DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
00902                 x_fprintf(x_stdout, "BH NTLMSSP query invalid\n");
00903                 return;
00904         }
00905 
00906         if (!ntlmssp_state) {
00907                 if (!NT_STATUS_IS_OK(nt_status = ntlm_auth_start_ntlmssp_client(&ntlmssp_state))) {
00908                         x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
00909                         return;
00910                 }
00911                 ntlmssp_want_feature_list(ntlmssp_state, want_feature_list);
00912                 first = True;
00913                 initial_message = data_blob(NULL, 0);
00914         }
00915 
00916         DEBUG(10, ("got NTLMSSP packet:\n"));
00917         dump_data(10, (const char *)request.data, request.length);
00918 
00919         if (use_cached_creds && !opt_password && !first) {
00920                 nt_status = do_ccache_ntlm_auth(initial_message, request, &reply);
00921         } else {
00922                 nt_status = ntlmssp_update(ntlmssp_state, request, &reply);
00923         }
00924         
00925         if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
00926                 char *reply_base64 = base64_encode_data_blob(reply);
00927                 if (first) {
00928                         x_fprintf(x_stdout, "YR %s\n", reply_base64);
00929                 } else { 
00930                         x_fprintf(x_stdout, "KK %s\n", reply_base64);
00931                 }
00932                 SAFE_FREE(reply_base64);
00933                 if (first) {
00934                         initial_message = reply;
00935                 } else {
00936                         data_blob_free(&reply);
00937                 }
00938                 DEBUG(10, ("NTLMSSP challenge\n"));
00939         } else if (NT_STATUS_IS_OK(nt_status)) {
00940                 char *reply_base64 = base64_encode_data_blob(reply);
00941                 x_fprintf(x_stdout, "AF %s\n", reply_base64);
00942                 SAFE_FREE(reply_base64);
00943 
00944                 if(have_session_key)
00945                         data_blob_free(&session_key);
00946 
00947                 session_key = data_blob(ntlmssp_state->session_key.data, 
00948                                 ntlmssp_state->session_key.length);
00949                 neg_flags = ntlmssp_state->neg_flags;
00950                 have_session_key = True;
00951 
00952                 DEBUG(10, ("NTLMSSP OK!\n"));
00953                 if (ntlmssp_state)
00954                         ntlmssp_end(&ntlmssp_state);
00955         } else {
00956                 x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
00957                 DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status)));
00958                 if (ntlmssp_state)
00959                         ntlmssp_end(&ntlmssp_state);
00960         }
00961 
00962         data_blob_free(&request);
00963 }

static void manage_squid_basic_request ( enum stdio_helper_mode  stdio_helper_mode,
char *  buf,
int  length 
) [static]

ntlm_auth.c965 行で定義されています。

参照先 check_plaintext_auth()rfc1738_unescape()SQUID_2_5_BASICx_fprintf()x_stdout.

00967 {
00968         char *user, *pass;      
00969         user=buf;
00970         
00971         pass=(char *)memchr(buf,' ',length);
00972         if (!pass) {
00973                 DEBUG(2, ("Password not found. Denying access\n"));
00974                 x_fprintf(x_stdout, "ERR\n");
00975                 return;
00976         }
00977         *pass='\0';
00978         pass++;
00979         
00980         if (stdio_helper_mode == SQUID_2_5_BASIC) {
00981                 rfc1738_unescape(user);
00982                 rfc1738_unescape(pass);
00983         }
00984         
00985         if (check_plaintext_auth(user, pass, False)) {
00986                 x_fprintf(x_stdout, "OK\n");
00987         } else {
00988                 x_fprintf(x_stdout, "ERR\n");
00989         }
00990 }

static void offer_gss_spnego_mechs ( void   )  [static]

ntlm_auth.c992 行で定義されています。

参照先 base64_encode_data_blob()data_blob()data_blob_free()free_spnego_data()global_mynamelenspnego_negTokenInit::mechListMICspnego_negTokenInit::mechTypesspnego_spnego::negTokenInitpstr_sprintf()smb_xstrdup()strlower_m()spnego_spnego::typewrite_spnego_data()x_fprintf()x_stdout.

参照元 manage_gss_spnego_request().

00992                                          {
00993 
00994         DATA_BLOB token;
00995         SPNEGO_DATA spnego;
00996         ssize_t len;
00997         char *reply_base64;
00998 
00999         pstring principal;
01000         pstring myname_lower;
01001 
01002         ZERO_STRUCT(spnego);
01003 
01004         pstrcpy(myname_lower, global_myname());
01005         strlower_m(myname_lower);
01006 
01007         pstr_sprintf(principal, "%s$@%s", myname_lower, lp_realm());
01008 
01009         /* Server negTokenInit (mech offerings) */
01010         spnego.type = SPNEGO_NEG_TOKEN_INIT;
01011         spnego.negTokenInit.mechTypes = SMB_XMALLOC_ARRAY(const char *, 2);
01012 #ifdef HAVE_KRB5
01013         spnego.negTokenInit.mechTypes[0] = smb_xstrdup(OID_KERBEROS5_OLD);
01014         spnego.negTokenInit.mechTypes[1] = smb_xstrdup(OID_NTLMSSP);
01015         spnego.negTokenInit.mechTypes[2] = NULL;
01016 #else
01017         spnego.negTokenInit.mechTypes[0] = smb_xstrdup(OID_NTLMSSP);
01018         spnego.negTokenInit.mechTypes[1] = NULL;
01019 #endif
01020 
01021 
01022         spnego.negTokenInit.mechListMIC = data_blob(principal,
01023                                                     strlen(principal));
01024 
01025         len = write_spnego_data(&token, &spnego);
01026         free_spnego_data(&spnego);
01027 
01028         if (len == -1) {
01029                 DEBUG(1, ("Could not write SPNEGO data blob\n"));
01030                 x_fprintf(x_stdout, "BH Could not write SPNEGO data blob\n");
01031                 return;
01032         }
01033 
01034         reply_base64 = base64_encode_data_blob(token);
01035         x_fprintf(x_stdout, "TT %s *\n", reply_base64);
01036 
01037         SAFE_FREE(reply_base64);
01038         data_blob_free(&token);
01039         DEBUG(10, ("sent SPNEGO negTokenInit\n"));
01040         return;
01041 }

static void manage_gss_spnego_request ( enum stdio_helper_mode  stdio_helper_mode,
char *  buf,
int  length 
) [static]

ntlm_auth.c1043 行で定義されています。

参照先 ads_verify_ticket()base64_decode_data_blob()base64_encode_data_blob()data_blob_::datadata_blob()data_blob_free()ntlmssp_state::domaindump_data()free_spnego_data()lendata_blob_::lengthspnego_negTokenTarg::mechListMICspnego_negTokenInit::mechTokenspnego_negTokenInit::mechTypesspnego_negTokenTarg::negResultspnego_spnego::negTokenInitspnego_spnego::negTokenTargnt_errstr()ntlm_auth_start_ntlmssp_server()ntlmssp_end()ntlmssp_update()offer_gss_spnego_mechs()pstr_sprintf()read_spnego_data()spnego_negTokenTarg::responseTokenSPNEGO_ACCEPT_COMPLETEDSPNEGO_ACCEPT_INCOMPLETESPNEGO_REJECTstatusstrchr_m()spnego_negTokenTarg::supportedMechtalloc_init()spnego_spnego::typentlmssp_state::userwrite_spnego_data()x_fprintf()x_stdout.

01045 {
01046         static NTLMSSP_STATE *ntlmssp_state = NULL;
01047         SPNEGO_DATA request, response;
01048         DATA_BLOB token;
01049         NTSTATUS status;
01050         ssize_t len;
01051 
01052         char *user = NULL;
01053         char *domain = NULL;
01054 
01055         const char *reply_code;
01056         char       *reply_base64;
01057         pstring     reply_argument;
01058 
01059         if (strlen(buf) < 2) {
01060                 DEBUG(1, ("SPENGO query [%s] invalid", buf));
01061                 x_fprintf(x_stdout, "BH SPENGO query invalid\n");
01062                 return;
01063         }
01064 
01065         if (strncmp(buf, "YR", 2) == 0) {
01066                 if (ntlmssp_state)
01067                         ntlmssp_end(&ntlmssp_state);
01068         } else if (strncmp(buf, "KK", 2) == 0) {
01069                 
01070         } else {
01071                 DEBUG(1, ("SPENGO query [%s] invalid", buf));
01072                 x_fprintf(x_stdout, "BH SPENGO query invalid\n");
01073                 return;
01074         }
01075 
01076         if ( (strlen(buf) == 2)) {
01077 
01078                 /* no client data, get the negTokenInit offering
01079                    mechanisms */
01080 
01081                 offer_gss_spnego_mechs();
01082                 return;
01083         }
01084 
01085         /* All subsequent requests have a blob. This might be negTokenInit or negTokenTarg */
01086 
01087         if (strlen(buf) <= 3) {
01088                 DEBUG(1, ("GSS-SPNEGO query [%s] invalid\n", buf));
01089                 x_fprintf(x_stdout, "BH GSS-SPNEGO query invalid\n");
01090                 return;
01091         }
01092 
01093         token = base64_decode_data_blob(buf + 3);
01094         len = read_spnego_data(token, &request);
01095         data_blob_free(&token);
01096 
01097         if (len == -1) {
01098                 DEBUG(1, ("GSS-SPNEGO query [%s] invalid", buf));
01099                 x_fprintf(x_stdout, "BH GSS-SPNEGO query invalid\n");
01100                 return;
01101         }
01102 
01103         if (request.type == SPNEGO_NEG_TOKEN_INIT) {
01104 
01105                 /* Second request from Client. This is where the
01106                    client offers its mechanism to use. */
01107 
01108                 if ( (request.negTokenInit.mechTypes == NULL) ||
01109                      (request.negTokenInit.mechTypes[0] == NULL) ) {
01110                         DEBUG(1, ("Client did not offer any mechanism"));
01111                         x_fprintf(x_stdout, "BH Client did not offer any mechanism\n");
01112                         return;
01113                 }
01114 
01115                 status = NT_STATUS_UNSUCCESSFUL;
01116                 if (strcmp(request.negTokenInit.mechTypes[0], OID_NTLMSSP) == 0) {
01117 
01118                         if ( request.negTokenInit.mechToken.data == NULL ) {
01119                                 DEBUG(1, ("Client did not provide NTLMSSP data\n"));
01120                                 x_fprintf(x_stdout, "BH Client did not provide NTLMSSP data\n");
01121                                 return;
01122                         }
01123 
01124                         if ( ntlmssp_state != NULL ) {
01125                                 DEBUG(1, ("Client wants a new NTLMSSP challenge, but "
01126                                           "already got one\n"));
01127                                 x_fprintf(x_stdout, "BH Client wants a new NTLMSSP challenge, but already got one\n");
01128                                 ntlmssp_end(&ntlmssp_state);
01129                                 return;
01130                         }
01131 
01132                         if (!NT_STATUS_IS_OK(status = ntlm_auth_start_ntlmssp_server(&ntlmssp_state))) {
01133                                 x_fprintf(x_stdout, "BH %s\n", nt_errstr(status));
01134                                 return;
01135                         }
01136 
01137                         DEBUG(10, ("got NTLMSSP packet:\n"));
01138                         dump_data(10, (const char *)request.negTokenInit.mechToken.data,
01139                                   request.negTokenInit.mechToken.length);
01140 
01141                         response.type = SPNEGO_NEG_TOKEN_TARG;
01142                         response.negTokenTarg.supportedMech = SMB_STRDUP(OID_NTLMSSP);
01143                         response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
01144 
01145                         status = ntlmssp_update(ntlmssp_state,
01146                                                        request.negTokenInit.mechToken,
01147                                                        &response.negTokenTarg.responseToken);
01148                 }
01149 
01150 #ifdef HAVE_KRB5
01151                 if (strcmp(request.negTokenInit.mechTypes[0], OID_KERBEROS5_OLD) == 0) {
01152 
01153                         TALLOC_CTX *mem_ctx = talloc_init("manage_gss_spnego_request");
01154                         char *principal;
01155                         DATA_BLOB ap_rep;
01156                         DATA_BLOB session_key;
01157 
01158                         if ( request.negTokenInit.mechToken.data == NULL ) {
01159                                 DEBUG(1, ("Client did not provide Kerberos data\n"));
01160                                 x_fprintf(x_stdout, "BH Client did not provide Kerberos data\n");
01161                                 return;
01162                         }
01163 
01164                         response.type = SPNEGO_NEG_TOKEN_TARG;
01165                         response.negTokenTarg.supportedMech = SMB_STRDUP(OID_KERBEROS5_OLD);
01166                         response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
01167                         response.negTokenTarg.responseToken = data_blob(NULL, 0);
01168 
01169                         status = ads_verify_ticket(mem_ctx, lp_realm(), 0,
01170                                                    &request.negTokenInit.mechToken,
01171                                                    &principal, NULL, &ap_rep,
01172                                                    &session_key);
01173 
01174                         talloc_destroy(mem_ctx);
01175 
01176                         /* Now in "principal" we have the name we are
01177                            authenticated as. */
01178 
01179                         if (NT_STATUS_IS_OK(status)) {
01180 
01181                                 domain = strchr_m(principal, '@');
01182 
01183                                 if (domain == NULL) {
01184                                         DEBUG(1, ("Did not get a valid principal "
01185                                                   "from ads_verify_ticket\n"));
01186                                         x_fprintf(x_stdout, "BH Did not get a valid principal from ads_verify_ticket\n");
01187                                         return;
01188                                 }
01189 
01190                                 *domain++ = '\0';
01191                                 domain = SMB_STRDUP(domain);
01192                                 user = SMB_STRDUP(principal);
01193 
01194                                 data_blob_free(&ap_rep);
01195 
01196                                 SAFE_FREE(principal);
01197                         }
01198                 }
01199 #endif
01200 
01201         } else {
01202 
01203                 if ( (request.negTokenTarg.supportedMech == NULL) ||
01204                      ( strcmp(request.negTokenTarg.supportedMech, OID_NTLMSSP) != 0 ) ) {
01205                         /* Kerberos should never send a negTokenTarg, OID_NTLMSSP
01206                            is the only one we support that sends this stuff */
01207                         DEBUG(1, ("Got a negTokenTarg for something non-NTLMSSP: %s\n",
01208                                   request.negTokenTarg.supportedMech));
01209                         x_fprintf(x_stdout, "BH Got a negTokenTarg for something non-NTLMSSP\n");
01210                         return;
01211                 }
01212 
01213                 if (request.negTokenTarg.responseToken.data == NULL) {
01214                         DEBUG(1, ("Got a negTokenTarg without a responseToken!\n"));
01215                         x_fprintf(x_stdout, "BH Got a negTokenTarg without a responseToken!\n");
01216                         return;
01217                 }
01218 
01219                 status = ntlmssp_update(ntlmssp_state,
01220                                                request.negTokenTarg.responseToken,
01221                                                &response.negTokenTarg.responseToken);
01222 
01223                 response.type = SPNEGO_NEG_TOKEN_TARG;
01224                 response.negTokenTarg.supportedMech = SMB_STRDUP(OID_NTLMSSP);
01225                 response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
01226 
01227                 if (NT_STATUS_IS_OK(status)) {
01228                         user = SMB_STRDUP(ntlmssp_state->user);
01229                         domain = SMB_STRDUP(ntlmssp_state->domain);
01230                         ntlmssp_end(&ntlmssp_state);
01231                 }
01232         }
01233 
01234         free_spnego_data(&request);
01235 
01236         if (NT_STATUS_IS_OK(status)) {
01237                 response.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED;
01238                 reply_code = "AF";
01239                 pstr_sprintf(reply_argument, "%s\\%s", domain, user);
01240         } else if (NT_STATUS_EQUAL(status,
01241                                    NT_STATUS_MORE_PROCESSING_REQUIRED)) {
01242                 response.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE;
01243                 reply_code = "TT";
01244                 pstr_sprintf(reply_argument, "*");
01245         } else {
01246                 response.negTokenTarg.negResult = SPNEGO_REJECT;
01247                 reply_code = "NA";
01248                 pstrcpy(reply_argument, nt_errstr(status));
01249         }
01250 
01251         SAFE_FREE(user);
01252         SAFE_FREE(domain);
01253 
01254         len = write_spnego_data(&token, &response);
01255         free_spnego_data(&response);
01256 
01257         if (len == -1) {
01258                 DEBUG(1, ("Could not write SPNEGO data blob\n"));
01259                 x_fprintf(x_stdout, "BH Could not write SPNEGO data blob\n");
01260                 return;
01261         }
01262 
01263         reply_base64 = base64_encode_data_blob(token);
01264 
01265         x_fprintf(x_stdout, "%s %s %s\n",
01266                   reply_code, reply_base64, reply_argument);
01267 
01268         SAFE_FREE(reply_base64);
01269         data_blob_free(&token);
01270 
01271         return;
01272 }

static BOOL manage_client_ntlmssp_init ( SPNEGO_DATA  spnego  )  [static]

ntlm_auth.c1276 行で定義されています。

参照先 base64_encode_data_blob()client_ntlmssp_statedata_blob()data_blob_free()spnego_negTokenInit::mechListMICspnego_negTokenInit::mechTokenspnego_negTokenInit::mechTypesspnego_spnego::negTokenInitnt_errstr()ntlm_auth_start_ntlmssp_client()ntlmssp_end()ntlmssp_update()opt_passwordspnego_negTokenInit::reqFlagsstatusspnego_spnego::typewrite_spnego_data()x_fprintf()x_stdout.

参照元 manage_gss_spnego_client_request().

01277 {
01278         NTSTATUS status;
01279         DATA_BLOB null_blob = data_blob(NULL, 0);
01280         DATA_BLOB to_server;
01281         char *to_server_base64;
01282         const char *my_mechs[] = {OID_NTLMSSP, NULL};
01283 
01284         DEBUG(10, ("Got spnego negTokenInit with NTLMSSP\n"));
01285 
01286         if (client_ntlmssp_state != NULL) {
01287                 DEBUG(1, ("Request for initial SPNEGO request where "
01288                           "we already have a state\n"));
01289                 return False;
01290         }
01291 
01292         if (!client_ntlmssp_state) {
01293                 if (!NT_STATUS_IS_OK(status = ntlm_auth_start_ntlmssp_client(&client_ntlmssp_state))) {
01294                         x_fprintf(x_stdout, "BH %s\n", nt_errstr(status));
01295                         return False;
01296                 }
01297         }
01298 
01299 
01300         if (opt_password == NULL) {
01301 
01302                 /* Request a password from the calling process.  After
01303                    sending it, the calling process should retry with
01304                    the negTokenInit. */
01305 
01306                 DEBUG(10, ("Requesting password\n"));
01307                 x_fprintf(x_stdout, "PW\n");
01308                 return True;
01309         }
01310 
01311         spnego.type = SPNEGO_NEG_TOKEN_INIT;
01312         spnego.negTokenInit.mechTypes = my_mechs;
01313         spnego.negTokenInit.reqFlags = 0;
01314         spnego.negTokenInit.mechListMIC = null_blob;
01315 
01316         status = ntlmssp_update(client_ntlmssp_state, null_blob,
01317                                        &spnego.negTokenInit.mechToken);
01318 
01319         if ( !(NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) ||
01320                         NT_STATUS_IS_OK(status)) ) {
01321                 DEBUG(1, ("Expected OK or MORE_PROCESSING_REQUIRED, got: %s\n",
01322                           nt_errstr(status)));
01323                 ntlmssp_end(&client_ntlmssp_state);
01324                 return False;
01325         }
01326 
01327         write_spnego_data(&to_server, &spnego);
01328         data_blob_free(&spnego.negTokenInit.mechToken);
01329 
01330         to_server_base64 = base64_encode_data_blob(to_server);
01331         data_blob_free(&to_server);
01332         x_fprintf(x_stdout, "KK %s\n", to_server_base64);
01333         SAFE_FREE(to_server_base64);
01334         return True;
01335 }

static void manage_client_ntlmssp_targ ( SPNEGO_DATA  spnego  )  [static]

ntlm_auth.c1337 行で定義されています。

参照先 base64_encode_data_blob()client_ntlmssp_statedata_blob()data_blob_free()spnego_negTokenTarg::mechListMICspnego_negTokenTarg::negResultspnego_spnego::negTokenTargnt_errstr()ntlmssp_end()ntlmssp_update()spnego_negTokenTarg::responseTokenSPNEGO_ACCEPT_COMPLETEDSPNEGO_ACCEPT_INCOMPLETESPNEGO_REJECTstatusspnego_negTokenTarg::supportedMechspnego_spnego::typewrite_spnego_data()x_fprintf()x_stdout.

参照元 manage_gss_spnego_client_request().

01338 {
01339         NTSTATUS status;
01340         DATA_BLOB null_blob = data_blob(NULL, 0);
01341         DATA_BLOB request;
01342         DATA_BLOB to_server;
01343         char *to_server_base64;
01344 
01345         DEBUG(10, ("Got spnego negTokenTarg with NTLMSSP\n"));
01346 
01347         if (client_ntlmssp_state == NULL) {
01348                 DEBUG(1, ("Got NTLMSSP tArg without a client state\n"));
01349                 x_fprintf(x_stdout, "BH Got NTLMSSP tArg without a client state\n");
01350                 return;
01351         }
01352 
01353         if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) {
01354                 x_fprintf(x_stdout, "NA\n");
01355                 ntlmssp_end(&client_ntlmssp_state);
01356                 return;
01357         }
01358 
01359         if (spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_COMPLETED) {
01360                 x_fprintf(x_stdout, "AF\n");
01361                 ntlmssp_end(&client_ntlmssp_state);
01362                 return;
01363         }
01364 
01365         status = ntlmssp_update(client_ntlmssp_state,
01366                                        spnego.negTokenTarg.responseToken,
01367                                        &request);
01368                 
01369         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
01370                 DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED from "
01371                           "ntlmssp_client_update, got: %s\n",
01372                           nt_errstr(status)));
01373                 x_fprintf(x_stdout, "BH Expected MORE_PROCESSING_REQUIRED from ntlmssp_client_update\n");
01374                 data_blob_free(&request);
01375                 ntlmssp_end(&client_ntlmssp_state);
01376                 return;
01377         }
01378 
01379         spnego.type = SPNEGO_NEG_TOKEN_TARG;
01380         spnego.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE;
01381         spnego.negTokenTarg.supportedMech = (char *)OID_NTLMSSP;
01382         spnego.negTokenTarg.responseToken = request;
01383         spnego.negTokenTarg.mechListMIC = null_blob;
01384         
01385         write_spnego_data(&to_server, &spnego);
01386         data_blob_free(&request);
01387 
01388         to_server_base64 = base64_encode_data_blob(to_server);
01389         data_blob_free(&to_server);
01390         x_fprintf(x_stdout, "KK %s\n", to_server_base64);
01391         SAFE_FREE(to_server_base64);
01392         return;
01393 }

static BOOL manage_client_krb5_init ( SPNEGO_DATA  spnego  )  [static]

ntlm_auth.c1397 行で定義されています。

参照先 base64_encode_data_blob()cli_krb5_get_ticket()data_blob_::datadata_blob()data_blob_free()kerberos_kinit_password()lendata_blob_::lengthspnego_negTokenInit::mechListMICspnego_negTokenInit::mechTokenspnego_negTokenInit::mechTypesspnego_spnego::negTokenInitopt_domainopt_passwordopt_usernamepstr_sprintf()spnego_negTokenInit::reqFlagsspnego_spnego::typewrite_spnego_data()x_fprintf()x_stdout.

参照元 manage_gss_spnego_client_request().

01398 {
01399         char *principal;
01400         DATA_BLOB tkt, to_server;
01401         DATA_BLOB session_key_krb5 = data_blob(NULL, 0);
01402         SPNEGO_DATA reply;
01403         char *reply_base64;
01404         int retval;
01405         
01406         const char *my_mechs[] = {OID_KERBEROS5_OLD, NULL};
01407         ssize_t len;
01408 
01409         if ( (spnego.negTokenInit.mechListMIC.data == NULL) ||
01410              (spnego.negTokenInit.mechListMIC.length == 0) ) {
01411                 DEBUG(1, ("Did not get a principal for krb5\n"));
01412                 return False;
01413         }
01414 
01415         principal = (char *)SMB_MALLOC(
01416                 spnego.negTokenInit.mechListMIC.length+1);
01417 
01418         if (principal == NULL) {
01419                 DEBUG(1, ("Could not malloc principal\n"));
01420                 return False;
01421         }
01422 
01423         memcpy(principal, spnego.negTokenInit.mechListMIC.data,
01424                spnego.negTokenInit.mechListMIC.length);
01425         principal[spnego.negTokenInit.mechListMIC.length] = '\0';
01426 
01427         retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5, 0, NULL, NULL);
01428 
01429         if (retval) {
01430 
01431                 pstring user;
01432 
01433                 /* Let's try to first get the TGT, for that we need a
01434                    password. */
01435 
01436                 if (opt_password == NULL) {
01437                         DEBUG(10, ("Requesting password\n"));
01438                         x_fprintf(x_stdout, "PW\n");
01439                         return True;
01440                 }
01441 
01442                 pstr_sprintf(user, "%s@%s", opt_username, opt_domain);
01443 
01444                 if ((retval = kerberos_kinit_password(user, opt_password, 0, NULL))) {
01445                         DEBUG(10, ("Requesting TGT failed: %s\n", error_message(retval)));
01446                         return False;
01447                 }
01448 
01449                 retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5, 0, NULL, NULL);
01450 
01451                 if (retval) {
01452                         DEBUG(10, ("Kinit suceeded, but getting a ticket failed: %s\n", error_message(retval)));
01453                         return False;
01454                 }
01455         }
01456 
01457         data_blob_free(&session_key_krb5);
01458 
01459         ZERO_STRUCT(reply);
01460 
01461         reply.type = SPNEGO_NEG_TOKEN_INIT;
01462         reply.negTokenInit.mechTypes = my_mechs;
01463         reply.negTokenInit.reqFlags = 0;
01464         reply.negTokenInit.mechToken = tkt;
01465         reply.negTokenInit.mechListMIC = data_blob(NULL, 0);
01466 
01467         len = write_spnego_data(&to_server, &reply);
01468         data_blob_free(&tkt);
01469 
01470         if (len == -1) {
01471                 DEBUG(1, ("Could not write SPNEGO data blob\n"));
01472                 return False;
01473         }
01474 
01475         reply_base64 = base64_encode_data_blob(to_server);
01476         x_fprintf(x_stdout, "KK %s *\n", reply_base64);
01477 
01478         SAFE_FREE(reply_base64);
01479         data_blob_free(&to_server);
01480         DEBUG(10, ("sent GSS-SPNEGO KERBEROS5 negTokenInit\n"));
01481         return True;
01482 }

static void manage_client_krb5_targ ( SPNEGO_DATA  spnego  )  [static]

ntlm_auth.c1484 行で定義されています。

参照先 spnego_negTokenTarg::negResultspnego_spnego::negTokenTargSPNEGO_ACCEPT_COMPLETEDSPNEGO_ACCEPT_INCOMPLETESPNEGO_REJECTx_fprintf()x_stdout.

参照元 manage_gss_spnego_client_request().

01485 {
01486         switch (spnego.negTokenTarg.negResult) {
01487         case SPNEGO_ACCEPT_INCOMPLETE:
01488                 DEBUG(1, ("Got a Kerberos negTokenTarg with ACCEPT_INCOMPLETE\n"));
01489                 x_fprintf(x_stdout, "BH Got a Kerberos negTokenTarg with ACCEPT_INCOMPLETE\n");
01490                 break;
01491         case SPNEGO_ACCEPT_COMPLETED:
01492                 DEBUG(10, ("Accept completed\n"));
01493                 x_fprintf(x_stdout, "AF\n");
01494                 break;
01495         case SPNEGO_REJECT:
01496                 DEBUG(10, ("Rejected\n"));
01497                 x_fprintf(x_stdout, "NA\n");
01498                 break;
01499         default:
01500                 DEBUG(1, ("Got an invalid negTokenTarg\n"));
01501                 x_fprintf(x_stdout, "AF\n");
01502         }
01503 }

static void manage_gss_spnego_client_request ( enum stdio_helper_mode  stdio_helper_mode,
char *  buf,
int  length 
) [static]

ntlm_auth.c1507 行で定義されています。

参照先 base64_decode_data_blob()client_ntlmssp_statedata_blob_::datadata_blob_free()free_spnego_data()lendata_blob_::lengthmanage_client_krb5_init()manage_client_krb5_targ()manage_client_ntlmssp_init()manage_client_ntlmssp_targ()spnego_negTokenInit::mechTypesspnego_negTokenTarg::negResultspnego_spnego::negTokenInitspnego_spnego::negTokenTargntlmssp_end()opt_passwordopt_usernameread_spnego_data()SPNEGO_ACCEPT_COMPLETEDSPNEGO_REJECTspnego_negTokenTarg::supportedMechspnego_spnego::typex_fprintf()x_stderrx_stdout.

01509 {
01510         DATA_BLOB request;
01511         SPNEGO_DATA spnego;
01512         ssize_t len;
01513 
01514         if (!opt_username || !*opt_username) {
01515                 x_fprintf(x_stderr, "username must be specified!\n\n");
01516                 exit(1);
01517         }
01518 
01519         if (strlen(buf) <= 3) {
01520                 DEBUG(1, ("SPNEGO query [%s] too short\n", buf));
01521                 x_fprintf(x_stdout, "BH SPNEGO query too short\n");
01522                 return;
01523         }
01524 
01525         request = base64_decode_data_blob(buf+3);
01526 
01527         if (strncmp(buf, "PW ", 3) == 0) {
01528 
01529                 /* We asked for a password and obviously got it :-) */
01530 
01531                 opt_password = SMB_STRNDUP((const char *)request.data, request.length);
01532                 
01533                 if (opt_password == NULL) {
01534                         DEBUG(1, ("Out of memory\n"));
01535                         x_fprintf(x_stdout, "BH Out of memory\n");
01536                         data_blob_free(&request);
01537                         return;
01538                 }
01539 
01540                 x_fprintf(x_stdout, "OK\n");
01541                 data_blob_free(&request);
01542                 return;
01543         }
01544 
01545         if ( (strncmp(buf, "TT ", 3) != 0) &&
01546              (strncmp(buf, "AF ", 3) != 0) &&
01547              (strncmp(buf, "NA ", 3) != 0) ) {
01548                 DEBUG(1, ("SPNEGO request [%s] invalid\n", buf));
01549                 x_fprintf(x_stdout, "BH SPNEGO request invalid\n");
01550                 data_blob_free(&request);
01551                 return;
01552         }
01553 
01554         /* So we got a server challenge to generate a SPNEGO
01555            client-to-server request... */
01556 
01557         len = read_spnego_data(request, &spnego);
01558         data_blob_free(&request);
01559 
01560         if (len == -1) {
01561                 DEBUG(1, ("Could not read SPNEGO data for [%s]\n", buf));
01562                 x_fprintf(x_stdout, "BH Could not read SPNEGO data\n");
01563                 return;
01564         }
01565 
01566         if (spnego.type == SPNEGO_NEG_TOKEN_INIT) {
01567 
01568                 /* The server offers a list of mechanisms */
01569 
01570                 const char **mechType = (const char **)spnego.negTokenInit.mechTypes;
01571 
01572                 while (*mechType != NULL) {
01573 
01574 #ifdef HAVE_KRB5
01575                         if ( (strcmp(*mechType, OID_KERBEROS5_OLD) == 0) ||
01576                              (strcmp(*mechType, OID_KERBEROS5) == 0) ) {
01577                                 if (manage_client_krb5_init(spnego))
01578                                         goto out;
01579                         }
01580 #endif
01581 
01582                         if (strcmp(*mechType, OID_NTLMSSP) == 0) {
01583                                 if (manage_client_ntlmssp_init(spnego))
01584                                         goto out;
01585                         }
01586 
01587                         mechType++;
01588                 }
01589 
01590                 DEBUG(1, ("Server offered no compatible mechanism\n"));
01591                 x_fprintf(x_stdout, "BH Server offered no compatible mechanism\n");
01592                 return;
01593         }
01594 
01595         if (spnego.type == SPNEGO_NEG_TOKEN_TARG) {
01596 
01597                 if (spnego.negTokenTarg.supportedMech == NULL) {
01598                         /* On accept/reject Windows does not send the
01599                            mechanism anymore. Handle that here and
01600                            shut down the mechanisms. */
01601 
01602                         switch (spnego.negTokenTarg.negResult) {
01603                         case SPNEGO_ACCEPT_COMPLETED:
01604                                 x_fprintf(x_stdout, "AF\n");
01605                                 break;
01606                         case SPNEGO_REJECT:
01607                                 x_fprintf(x_stdout, "NA\n");
01608                                 break;
01609                         default:
01610                                 DEBUG(1, ("Got a negTokenTarg with no mech and an "
01611                                           "unknown negResult: %d\n",
01612                                           spnego.negTokenTarg.negResult));
01613                                 x_fprintf(x_stdout, "BH Got a negTokenTarg with no mech and an unknown negResult\n");
01614                         }
01615 
01616                         ntlmssp_end(&client_ntlmssp_state);
01617                         goto out;
01618                 }
01619 
01620                 if (strcmp(spnego.negTokenTarg.supportedMech,
01621                            OID_NTLMSSP) == 0) {
01622                         manage_client_ntlmssp_targ(spnego);
01623                         goto out;
01624                 }
01625 
01626 #if HAVE_KRB5
01627                 if (strcmp(spnego.negTokenTarg.supportedMech,
01628                            OID_KERBEROS5_OLD) == 0) {
01629                         manage_client_krb5_targ(spnego);
01630                         goto out;
01631                 }
01632 #endif
01633 
01634         }
01635 
01636         DEBUG(1, ("Got an SPNEGO token I could not handle [%s]!\n", buf));
01637         x_fprintf(x_stdout, "BH Got an SPNEGO token I could not handle\n");
01638         return;
01639 
01640  out:
01641         free_spnego_data(&spnego);
01642         return;
01643 }

static void manage_ntlm_server_1_request ( enum stdio_helper_mode  stdio_helper_mode,
char *  buf,
int  length 
) [static]

ntlm_auth.c1645 行で定義されています。

参照先 asprintf()base64_decode_inplace()check_plaintext_auth()contact_winbind_auth_crap()data_blob_::datadata_blob()winbindd_response::error_stringflagsget_winbind_domain()global_mynamehex_encode()data_blob_::lengthparse_ntlm_auth_domain_user()smb_xstrdup()strequal()strhex_to_data_blob()strstr_m()winbindd_response::user_session_keyusernamewinbind_separator()x_fprintf()x_stdout.

01647 {
01648         char *request, *parameter;      
01649         static DATA_BLOB challenge;
01650         static DATA_BLOB lm_response;
01651         static DATA_BLOB nt_response;
01652         static char *full_username;
01653         static char *username;
01654         static char *domain;
01655         static char *plaintext_password;
01656         static BOOL ntlm_server_1_user_session_key;
01657         static BOOL ntlm_server_1_lm_session_key;
01658         
01659         if (strequal(buf, ".")) {
01660                 if (!full_username && !username) {      
01661                         x_fprintf(x_stdout, "Error: No username supplied!\n");
01662                 } else if (plaintext_password) {
01663                         /* handle this request as plaintext */
01664                         if (!full_username) {
01665                                 if (asprintf(&full_username, "%s%c%s", domain, winbind_separator(), username) == -1) {
01666                                         x_fprintf(x_stdout, "Error: Out of memory in asprintf!\n.\n");
01667                                         return;
01668                                 }
01669                         }
01670                         if (check_plaintext_auth(full_username, plaintext_password, False)) {
01671                                 x_fprintf(x_stdout, "Authenticated: Yes\n");
01672                         } else {
01673                                 x_fprintf(x_stdout, "Authenticated: No\n");
01674                         }
01675                 } else if (!lm_response.data && !nt_response.data) {
01676                         x_fprintf(x_stdout, "Error: No password supplied!\n");
01677                 } else if (!challenge.data) {   
01678                         x_fprintf(x_stdout, "Error: No lanman-challenge supplied!\n");
01679                 } else {
01680                         char *error_string = NULL;
01681                         uchar lm_key[8];
01682                         uchar user_session_key[16];
01683                         uint32 flags = 0;
01684 
01685                         if (full_username && !username) {
01686                                 fstring fstr_user;
01687                                 fstring fstr_domain;
01688                                 
01689                                 if (!parse_ntlm_auth_domain_user(full_username, fstr_user, fstr_domain)) {
01690                                         /* username might be 'tainted', don't print into our new-line deleimianted stream */
01691                                         x_fprintf(x_stdout, "Error: Could not parse into domain and username\n");
01692                                 }
01693                                 SAFE_FREE(username);
01694                                 SAFE_FREE(domain);
01695                                 username = smb_xstrdup(fstr_user);
01696                                 domain = smb_xstrdup(fstr_domain);
01697                         }
01698 
01699                         if (!domain) {
01700                                 domain = smb_xstrdup(get_winbind_domain());
01701                         }
01702 
01703                         if (ntlm_server_1_lm_session_key) 
01704                                 flags |= WBFLAG_PAM_LMKEY;
01705                         
01706                         if (ntlm_server_1_user_session_key) 
01707                                 flags |= WBFLAG_PAM_USER_SESSION_KEY;
01708 
01709                         if (!NT_STATUS_IS_OK(
01710                                     contact_winbind_auth_crap(username, 
01711                                                               domain, 
01712                                                               global_myname(),
01713                                                               &challenge, 
01714                                                               &lm_response, 
01715                                                               &nt_response, 
01716                                                               flags, 
01717                                                               lm_key, 
01718                                                               user_session_key,
01719                                                               &error_string,
01720                                                               NULL))) {
01721 
01722                                 x_fprintf(x_stdout, "Authenticated: No\n");
01723                                 x_fprintf(x_stdout, "Authentication-Error: %s\n.\n", error_string);
01724                                 SAFE_FREE(error_string);
01725                         } else {
01726                                 static char zeros[16];
01727                                 char *hex_lm_key;
01728                                 char *hex_user_session_key;
01729 
01730                                 x_fprintf(x_stdout, "Authenticated: Yes\n");
01731 
01732                                 if (ntlm_server_1_lm_session_key 
01733                                     && (memcmp(zeros, lm_key, 
01734                                                sizeof(lm_key)) != 0)) {
01735                                         hex_lm_key = hex_encode(NULL,
01736                                                                 (const unsigned char *)lm_key,
01737                                                                 sizeof(lm_key));
01738                                         x_fprintf(x_stdout, "LANMAN-Session-Key: %s\n", hex_lm_key);
01739                                         TALLOC_FREE(hex_lm_key);
01740                                 }
01741 
01742                                 if (ntlm_server_1_user_session_key 
01743                                     && (memcmp(zeros, user_session_key, 
01744                                                sizeof(user_session_key)) != 0)) {
01745                                         hex_user_session_key = hex_encode(NULL,
01746                                                                           (const unsigned char *)user_session_key, 
01747                                                                           sizeof(user_session_key));
01748                                         x_fprintf(x_stdout, "User-Session-Key: %s\n", hex_user_session_key);
01749                                         TALLOC_FREE(hex_user_session_key);
01750                                 }
01751                         }
01752                 }
01753                 /* clear out the state */
01754                 challenge = data_blob(NULL, 0);
01755                 nt_response = data_blob(NULL, 0);
01756                 lm_response = data_blob(NULL, 0);
01757                 SAFE_FREE(full_username);
01758                 SAFE_FREE(username);
01759                 SAFE_FREE(domain);
01760                 SAFE_FREE(plaintext_password);
01761                 ntlm_server_1_user_session_key = False;
01762                 ntlm_server_1_lm_session_key = False;
01763                 x_fprintf(x_stdout, ".\n");
01764 
01765                 return;
01766         }
01767 
01768         request = buf;
01769 
01770         /* Indicates a base64 encoded structure */
01771         parameter = strstr_m(request, ":: ");
01772         if (!parameter) {
01773                 parameter = strstr_m(request, ": ");
01774                 
01775                 if (!parameter) {
01776                         DEBUG(0, ("Parameter not found!\n"));
01777                         x_fprintf(x_stdout, "Error: Parameter not found!\n.\n");
01778                         return;
01779                 }
01780                 
01781                 parameter[0] ='\0';
01782                 parameter++;
01783                 parameter[0] ='\0';
01784                 parameter++;
01785 
01786         } else {
01787                 parameter[0] ='\0';
01788                 parameter++;
01789                 parameter[0] ='\0';
01790                 parameter++;
01791                 parameter[0] ='\0';
01792                 parameter++;
01793 
01794                 base64_decode_inplace(parameter);
01795         }
01796 
01797         if (strequal(request, "LANMAN-Challenge")) {
01798                 challenge = strhex_to_data_blob(NULL, parameter);
01799                 if (challenge.length != 8) {
01800                         x_fprintf(x_stdout, "Error: hex decode of %s failed! (got %d bytes, expected 8)\n.\n", 
01801                                   parameter,
01802                                   (int)challenge.length);
01803                         challenge = data_blob(NULL, 0);
01804                 }
01805         } else if (strequal(request, "NT-Response")) {
01806                 nt_response = strhex_to_data_blob(NULL, parameter);
01807                 if (nt_response.length < 24) {
01808                         x_fprintf(x_stdout, "Error: hex decode of %s failed! (only got %d bytes, needed at least 24)\n.\n", 
01809                                   parameter,
01810                                   (int)nt_response.length);
01811                         nt_response = data_blob(NULL, 0);
01812                 }
01813         } else if (strequal(request, "LANMAN-Response")) {
01814                 lm_response = strhex_to_data_blob(NULL, parameter);
01815                 if (lm_response.length != 24) {
01816                         x_fprintf(x_stdout, "Error: hex decode of %s failed! (got %d bytes, expected 24)\n.\n", 
01817                                   parameter,
01818                                   (int)lm_response.length);
01819                         lm_response = data_blob(NULL, 0);
01820                 }
01821         } else if (strequal(request, "Password")) {
01822                 plaintext_password = smb_xstrdup(parameter);
01823         } else if (strequal(request, "NT-Domain")) {
01824                 domain = smb_xstrdup(parameter);
01825         } else if (strequal(request, "Username")) {
01826                 username = smb_xstrdup(parameter);
01827         } else if (strequal(request, "Full-Username")) {
01828                 full_username = smb_xstrdup(parameter);
01829         } else if (strequal(request, "Request-User-Session-Key")) {
01830                 ntlm_server_1_user_session_key = strequal(parameter, "Yes");
01831         } else if (strequal(request, "Request-LanMan-Session-Key")) {
01832                 ntlm_server_1_lm_session_key = strequal(parameter, "Yes");
01833         } else {
01834                 x_fprintf(x_stdout, "Error: Unknown request %s\n.\n", request);
01835         }
01836 }

static void manage_squid_request ( enum stdio_helper_mode  helper_mode,
stdio_helper_function  fn 
) [static]

ntlm_auth.c2048 行で定義されています。

参照先 bufcerrfnwinbindd_response::lengthstrerror()x_fprintf()x_stderr.

参照元 squid_stream().

02049 {
02050         char buf[SQUID_BUFFER_SIZE+1];
02051         int length;
02052         char *c;
02053         static BOOL err;
02054 
02055         /* this is not a typo - x_fgets doesn't work too well under squid */
02056         if (fgets(buf, sizeof(buf)-1, stdin) == NULL) {
02057                 if (ferror(stdin)) {
02058                         DEBUG(1, ("fgets() failed! dying..... errno=%d (%s)\n", ferror(stdin),
02059                                   strerror(ferror(stdin))));
02060                         
02061                         exit(1);    /* BIIG buffer */
02062                 }
02063                 exit(0);
02064         }
02065     
02066         c=(char *)memchr(buf,'\n',sizeof(buf)-1);
02067         if (c) {
02068                 *c = '\0';
02069                 length = c-buf;
02070         } else {
02071                 err = 1;
02072                 return;
02073         }
02074         if (err) {
02075                 DEBUG(2, ("Oversized message\n"));
02076                 x_fprintf(x_stderr, "ERR\n");
02077                 err = 0;
02078                 return;
02079         }
02080 
02081         DEBUG(10, ("Got '%s' from squid (length: %d).\n",buf,length));
02082 
02083         if (buf[0] == '\0') {
02084                 DEBUG(2, ("Invalid Request\n"));
02085                 x_fprintf(x_stderr, "ERR\n");
02086                 return;
02087         }
02088         
02089         fn(helper_mode, buf, length);
02090 }

static void squid_stream ( enum stdio_helper_mode  stdio_mode,
stdio_helper_function  fn 
) [static]

ntlm_auth.c2093 行で定義されています。

参照先 manage_squid_request()x_setbuf()x_stderrx_stdout.

参照元 main().

02093                                                                                       {
02094         /* initialize FDescs */
02095         x_setbuf(x_stdout, NULL);
02096         x_setbuf(x_stderr, NULL);
02097         while(1) {
02098                 manage_squid_request(stdio_mode, fn);
02099         }
02100 }

static BOOL check_auth_crap ( void   )  [static]

ntlm_auth.c2105 行で定義されています。

参照先 contact_winbind_auth_crap()winbindd_response::error_stringflagshex_encode()winbindd_response::nt_statusopt_challengeopt_domainopt_lm_responseopt_nt_responseopt_usernameopt_workstationrequest_lm_keyrequest_user_session_keywinbindd_response::user_session_keyx_fprintf()x_setbuf()x_stdout.

参照元 main().

02106 {
02107         NTSTATUS nt_status;
02108         uint32 flags = 0;
02109         char lm_key[8];
02110         char user_session_key[16];
02111         char *hex_lm_key;
02112         char *hex_user_session_key;
02113         char *error_string;
02114         static uint8 zeros[16];
02115 
02116         x_setbuf(x_stdout, NULL);
02117 
02118         if (request_lm_key) 
02119                 flags |= WBFLAG_PAM_LMKEY;
02120 
02121         if (request_user_session_key) 
02122                 flags |= WBFLAG_PAM_USER_SESSION_KEY;
02123 
02124         flags |= WBFLAG_PAM_NT_STATUS_SQUASH;
02125 
02126         nt_status = contact_winbind_auth_crap(opt_username, opt_domain, 
02127                                               opt_workstation,
02128                                               &opt_challenge, 
02129                                               &opt_lm_response, 
02130                                               &opt_nt_response, 
02131                                               flags,
02132                                               (unsigned char *)lm_key, 
02133                                               (unsigned char *)user_session_key, 
02134                                               &error_string, NULL);
02135 
02136         if (!NT_STATUS_IS_OK(nt_status)) {
02137                 x_fprintf(x_stdout, "%s (0x%x)\n", 
02138                           error_string,
02139                           NT_STATUS_V(nt_status));
02140                 SAFE_FREE(error_string);
02141                 return False;
02142         }
02143 
02144         if (request_lm_key 
02145             && (memcmp(zeros, lm_key, 
02146                        sizeof(lm_key)) != 0)) {
02147                 hex_lm_key = hex_encode(NULL, (const unsigned char *)lm_key,
02148                                         sizeof(lm_key));
02149                 x_fprintf(x_stdout, "LM_KEY: %s\n", hex_lm_key);
02150                 TALLOC_FREE(hex_lm_key);
02151         }
02152         if (request_user_session_key 
02153             && (memcmp(zeros, user_session_key, 
02154                        sizeof(user_session_key)) != 0)) {
02155                 hex_user_session_key = hex_encode(NULL, (const unsigned char *)user_session_key, 
02156                                                   sizeof(user_session_key));
02157                 x_fprintf(x_stdout, "NT_KEY: %s\n", hex_user_session_key);
02158                 TALLOC_FREE(hex_user_session_key);
02159         }
02160 
02161         return True;
02162 }

int main ( int  argc,
const char **  argv 
)

ntlm_auth.c2182 行で定義されています。

参照先 check_auth_crap()check_plaintext_auth()d_fprintf()dbfdiagnose_ntlm_auth()dyn_CONFIGFILEerrnofnfstr_sprintf()get_winbind_domain()data_blob_::lengthload_case_tables()modenameNUM_HELPER_MODESopt_challengeOPT_CHALLENGEOPT_DIAGNOSTICSopt_domainOPT_DOMAINOPT_LMOPT_LM_KEYopt_lm_responseOPT_NTopt_nt_responseOPT_PASSWORDopt_passwordOPT_REQUIRE_MEMBERSHIPOPT_USE_CACHED_CREDSOPT_USER_SESSION_KEYOPT_USERNAMEopt_usernameOPT_WORKSTATIONopt_workstationpoptFreeContext()poptGetContext()poptGetNextOpt()poptPrintHelp()request_lm_keyrequest_user_session_keyrequire_membership_ofrequire_membership_of_sidsquid_stream()stdio_helper_protocolsstrchr_m()strequal()strerror()strhex_to_data_blob()StrnCaseCmp()use_cached_credswinbind_separator()x_fprintf()x_stderr.

02183 {
02184         int opt;
02185         static const char *helper_protocol;
02186         static int diagnostics;
02187 
02188         static const char *hex_challenge;
02189         static const char *hex_lm_response;
02190         static const char *hex_nt_response;
02191 
02192         poptContext pc;
02193 
02194         /* NOTE: DO NOT change this interface without considering the implications!
02195            This is an external interface, which other programs will use to interact 
02196            with this helper.
02197         */
02198 
02199         /* We do not use single-letter command abbreviations, because they harm future 
02200            interface stability. */
02201 
02202         struct poptOption long_options[] = {
02203                 POPT_AUTOHELP
02204                 { "helper-protocol", 0, POPT_ARG_STRING, &helper_protocol, OPT_DOMAIN, "operate as a stdio-based helper", "helper protocol to use"},
02205                 { "username", 0, POPT_ARG_STRING, &opt_username, OPT_USERNAME, "username"},
02206                 { "domain", 0, POPT_ARG_STRING, &opt_domain, OPT_DOMAIN, "domain name"},
02207                 { "workstation", 0, POPT_ARG_STRING, &opt_workstation, OPT_WORKSTATION, "workstation"},
02208                 { "challenge", 0, POPT_ARG_STRING, &hex_challenge, OPT_CHALLENGE, "challenge (HEX encoded)"},
02209                 { "lm-response", 0, POPT_ARG_STRING, &hex_lm_response, OPT_LM, "LM Response to the challenge (HEX encoded)"},
02210                 { "nt-response", 0, POPT_ARG_STRING, &hex_nt_response, OPT_NT, "NT or NTLMv2 Response to the challenge (HEX encoded)"},
02211                 { "password", 0, POPT_ARG_STRING, &opt_password, OPT_PASSWORD, "User's plaintext password"},            
02212                 { "request-lm-key", 0, POPT_ARG_NONE, &request_lm_key, OPT_LM_KEY, "Retrieve LM session key"},
02213                 { "request-nt-key", 0, POPT_ARG_NONE, &request_user_session_key, OPT_USER_SESSION_KEY, "Retrieve User (NT) session key"},
02214                 { "use-cached-creds", 0, POPT_ARG_NONE, &use_cached_creds, OPT_USE_CACHED_CREDS, "Use cached credentials if no password is given"},
02215                 { "diagnostics", 0, POPT_ARG_NONE, &diagnostics, OPT_DIAGNOSTICS, "Perform diagnostics on the authentictaion chain"},
02216                 { "require-membership-of", 0, POPT_ARG_STRING, &require_membership_of, OPT_REQUIRE_MEMBERSHIP, "Require that a user be a member of this group (either name or SID) for authentication to succeed" },
02217                 POPT_COMMON_SAMBA
02218                 POPT_TABLEEND
02219         };
02220 
02221         /* Samba client initialisation */
02222         load_case_tables();
02223 
02224         dbf = x_stderr;
02225         
02226         /* Samba client initialisation */
02227 
02228         if (!lp_load(dyn_CONFIGFILE, True, False, False, True)) {
02229                 d_fprintf(stderr, "ntlm_auth: error opening config file %s. Error was %s\n",
02230                         dyn_CONFIGFILE, strerror(errno));
02231                 exit(1);
02232         }
02233 
02234         /* Parse options */
02235 
02236         pc = poptGetContext("ntlm_auth", argc, argv, long_options, 0);
02237 
02238         /* Parse command line options */
02239 
02240         if (argc == 1) {
02241                 poptPrintHelp(pc, stderr, 0);
02242                 return 1;
02243         }
02244 
02245         pc = poptGetContext(NULL, argc, (const char **)argv, long_options, 
02246                             POPT_CONTEXT_KEEP_FIRST);
02247 
02248         while((opt = poptGetNextOpt(pc)) != -1) {
02249                 switch (opt) {
02250                 case OPT_CHALLENGE:
02251                         opt_challenge = strhex_to_data_blob(NULL, hex_challenge);
02252                         if (opt_challenge.length != 8) {
02253                                 x_fprintf(x_stderr, "hex decode of %s failed! (only got %d bytes)\n", 
02254                                           hex_challenge,
02255                                           (int)opt_challenge.length);
02256                                 exit(1);
02257                         }
02258                         break;
02259                 case OPT_LM: 
02260                         opt_lm_response = strhex_to_data_blob(NULL, hex_lm_response);
02261                         if (opt_lm_response.length != 24) {
02262                                 x_fprintf(x_stderr, "hex decode of %s failed! (only got %d bytes)\n", 
02263                                           hex_lm_response,
02264                                           (int)opt_lm_response.length);
02265                                 exit(1);
02266                         }
02267                         break;
02268 
02269                 case OPT_NT: 
02270                         opt_nt_response = strhex_to_data_blob(NULL, hex_nt_response);
02271                         if (opt_nt_response.length < 24) {
02272                                 x_fprintf(x_stderr, "hex decode of %s failed! (only got %d bytes)\n", 
02273                                           hex_nt_response,
02274                                           (int)opt_nt_response.length);
02275                                 exit(1);
02276                         }
02277                         break;
02278 
02279                 case OPT_REQUIRE_MEMBERSHIP:
02280                         if (StrnCaseCmp("S-", require_membership_of, 2) == 0) {
02281                                 require_membership_of_sid = require_membership_of;
02282                         }
02283                         break;
02284                 }
02285         }
02286 
02287         if (opt_username) {
02288                 char *domain = SMB_STRDUP(opt_username);
02289                 char *p = strchr_m(domain, *lp_winbind_separator());
02290                 if (p) {
02291                         opt_username = p+1;
02292                         *p = '\0';
02293                         if (opt_domain && !strequal(opt_domain, domain)) {
02294                                 x_fprintf(x_stderr, "Domain specified in username (%s) "
02295                                         "doesn't match specified domain (%s)!\n\n",
02296                                         domain, opt_domain);
02297                                 poptPrintHelp(pc, stderr, 0);
02298                                 exit(1);
02299                         }
02300                         opt_domain = domain;
02301                 } else {
02302                         SAFE_FREE(domain);
02303                 }
02304         }
02305 
02306         /* Note: if opt_domain is "" then send no domain */
02307         if (opt_domain == NULL) {
02308                 opt_domain = get_winbind_domain();
02309         }
02310 
02311         if (opt_workstation == NULL) {
02312                 opt_workstation = "";
02313         }
02314 
02315         if (helper_protocol) {
02316                 int i;
02317                 for (i=0; i<NUM_HELPER_MODES; i++) {
02318                         if (strcmp(helper_protocol, stdio_helper_protocols[i].name) == 0) {
02319                                 squid_stream(stdio_helper_protocols[i].mode, stdio_helper_protocols[i].fn);
02320                                 exit(0);
02321                         }
02322                 }
02323                 x_fprintf(x_stderr, "unknown helper protocol [%s]\n\nValid helper protools:\n\n", helper_protocol);
02324 
02325                 for (i=0; i<NUM_HELPER_MODES; i++) {
02326                         x_fprintf(x_stderr, "%s\n", stdio_helper_protocols[i].name);
02327                 }
02328 
02329                 exit(1);
02330         }
02331 
02332         if (!opt_username || !*opt_username) {
02333                 x_fprintf(x_stderr, "username must be specified!\n\n");
02334                 poptPrintHelp(pc, stderr, 0);
02335                 exit(1);
02336         }
02337 
02338         if (opt_challenge.length) {
02339                 if (!check_auth_crap()) {
02340                         exit(1);
02341                 }
02342                 exit(0);
02343         } 
02344 
02345         if (!opt_password) {
02346                 opt_password = getpass("password: ");
02347         }
02348 
02349         if (diagnostics) {
02350                 if (!diagnose_ntlm_auth()) {
02351                         return 1;
02352                 }
02353         } else {
02354                 fstring user;
02355 
02356                 fstr_sprintf(user, "%s%c%s", opt_domain, winbind_separator(), opt_username);
02357                 if (!check_plaintext_auth(user, opt_password, True)) {
02358                         return 1;
02359                 }
02360         }
02361 
02362         /* Exit code */
02363 
02364         poptFreeContext(pc);
02365         return 0;
02366 }


変数

enum stdio_helper_mode mode

ntlm_auth.c70 行で定義されています。

参照元 aixjfs2_getacl_alloc()cacl_get()call_trans2qfilepathinfo()cmd_chmod()cmd_fchmod()cmd_mknod()cmd_open()cmd_posix_mkdir()cmd_posix_open()create_default_mode()dos_attr_query()get_lanman2_dir_entry()globals_page()main()map_nt_perms()mkdir_internal()printers_page()recycle_create_dir()reply_getatr()reply_getattrE()reply_lseek()reply_search()reply_setatr()shares_page()smb_file_mode_information()smbc_chmod_ctx()smbc_fstat_ctx()smbc_opendir_ctx()smbc_stat_ctx()smbc_unlink_ctx()writetarheader().

const char* name

ntlm_auth.c71 行で定義されています。

stdio_helper_function fn

ntlm_auth.c72 行で定義されています。

struct { ... } stdio_helper_protocols[] [static]

参照元 main().

int winbindd_fd

wb_common.c35 行で定義されています。

参照元 close_sock()read_sock()wbinfo_ping()winbind_open_pipe_sock()write_sock().

const char* opt_username

ntlm_auth.c87 行で定義されています。

参照元 check_auth_crap()do_ccache_ntlm_auth()main()manage_client_krb5_init()manage_client_ntlmssp_request()manage_gss_spnego_client_request()ntlm_auth_start_ntlmssp_client()test_lm_ntlm_broken()test_lmv2_ntlmv2_broken()test_ntlm_in_both()test_ntlm_in_lm()test_plaintext().

const char* opt_domain

ntlm_auth.c88 行で定義されています。

参照元 check_auth_crap()do_ccache_ntlm_auth()main()manage_client_krb5_init()ntlm_auth_start_ntlmssp_client()test_lm_ntlm_broken()test_lmv2_ntlmv2_broken()test_ntlm_in_both()test_ntlm_in_lm()test_plaintext().

const char* opt_workstation

ntlm_auth.c89 行で定義されています。

参照元 check_auth_crap()main()test_lm_ntlm_broken()test_lmv2_ntlmv2_broken()test_ntlm_in_both()test_ntlm_in_lm()test_plaintext().

const char* opt_password

ntlm_auth.c90 行で定義されています。

DATA_BLOB opt_challenge [static]

ntlm_auth.c91 行で定義されています。

参照元 check_auth_crap()get_challenge()main().

DATA_BLOB opt_lm_response [static]

ntlm_auth.c92 行で定義されています。

参照元 check_auth_crap()main().

DATA_BLOB opt_nt_response [static]

ntlm_auth.c93 行で定義されています。

参照元 check_auth_crap()main().

int request_lm_key [static]

ntlm_auth.c94 行で定義されています。

参照元 check_auth_crap()main().

int request_user_session_key [static]

ntlm_auth.c95 行で定義されています。

参照元 check_auth_crap()main().

int use_cached_creds [static]

ntlm_auth.c96 行で定義されています。

参照元 main()manage_client_ntlmssp_request().

const char* require_membership_of [static]

ntlm_auth.c98 行で定義されています。

参照元 get_require_membership_sid()main().

const char* require_membership_of_sid [static]

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

参照元 check_info3_in_group()check_plaintext_auth()contact_winbind_auth_crap()get_require_membership_sid()main().

NTLMSSP_STATE* client_ntlmssp_state = NULL [static]

ntlm_auth.c1274 行で定義されています。

参照元 manage_client_ntlmssp_init()manage_client_ntlmssp_targ()manage_gss_spnego_client_request()ntlm_auth_start_ntlmssp_client().


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