Changeset 124 for branches/samba-3.0/source/libads/sasl.c
- Timestamp:
- Mar 12, 2008, 9:08:18 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/samba-3.0/source/libads/sasl.c
r26 r124 138 138 139 139 #ifdef HAVE_KRB5 140 struct ads_service_principal { 141 char *string; 142 #ifdef HAVE_GSSAPI 143 gss_name_t name; 144 #endif 145 }; 146 147 static void ads_free_service_principal(struct ads_service_principal *p) 148 { 149 SAFE_FREE(p->string); 150 151 #ifdef HAVE_GSSAPI 152 if (p->name) { 153 uint32 minor_status; 154 gss_release_name(&minor_status, &p->name); 155 } 156 #endif 157 ZERO_STRUCTP(p); 158 } 159 160 static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads, 161 const char *given_principal, 162 struct ads_service_principal *p) 163 { 164 ADS_STATUS status; 165 #ifdef HAVE_GSSAPI 166 gss_buffer_desc input_name; 167 /* GSS_KRB5_NT_PRINCIPAL_NAME */ 168 gss_OID_desc nt_principal = 169 {10, CONST_DISCARD(char *, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01")}; 170 uint32 minor_status; 171 int gss_rc; 172 #endif 173 174 ZERO_STRUCTP(p); 175 176 /* I've seen a child Windows 2000 domain not send 177 the principal name back in the first round of 178 the SASL bind reply. So we guess based on server 179 name and realm. --jerry */ 180 /* Also try best guess when we get the w2k8 ignore 181 principal back - gd */ 182 183 if (!given_principal || 184 strequal(given_principal, ADS_IGNORE_PRINCIPAL)) { 185 186 status = ads_guess_service_principal(ads, &p->string); 187 if (!ADS_ERR_OK(status)) { 188 return status; 189 } 190 } else { 191 p->string = SMB_STRDUP(given_principal); 192 if (!p->string) { 193 return ADS_ERROR(LDAP_NO_MEMORY); 194 } 195 } 196 197 #ifdef HAVE_GSSAPI 198 input_name.value = p->string; 199 input_name.length = strlen(p->string); 200 201 gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &p->name); 202 if (gss_rc) { 203 ads_free_service_principal(p); 204 return ADS_ERROR_GSS(gss_rc, minor_status); 205 } 206 #endif 207 208 return ADS_SUCCESS; 209 } 210 140 211 /* 141 212 perform a LDAP/SASL/SPNEGO/KRB5 bind 142 213 */ 143 static ADS_STATUS ads_sasl_spnego_ krb5_bind(ADS_STRUCT *ads, const char *principal)214 static ADS_STATUS ads_sasl_spnego_rawkrb5_bind(ADS_STRUCT *ads, const char *principal) 144 215 { 145 216 DATA_BLOB blob = data_blob(NULL, 0); … … 168 239 return ADS_ERROR(rc); 169 240 } 241 242 static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, 243 struct ads_service_principal *p) 244 { 245 return ads_sasl_spnego_rawkrb5_bind(ads, p->string); 246 } 247 170 248 #endif 171 249 … … 179 257 ADS_STATUS status; 180 258 DATA_BLOB blob; 181 char * principal = NULL;259 char *given_principal = NULL; 182 260 char *OIDs[ASN1_MAX_OIDS]; 183 261 #ifdef HAVE_KRB5 … … 202 280 /* the server sent us the first part of the SPNEGO exchange in the negprot 203 281 reply */ 204 if (!spnego_parse_negTokenInit(blob, OIDs, & principal)) {282 if (!spnego_parse_negTokenInit(blob, OIDs, &given_principal)) { 205 283 data_blob_free(&blob); 206 284 status = ADS_ERROR(LDAP_OPERATIONS_ERROR); … … 220 298 free(OIDs[i]); 221 299 } 222 DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", principal));300 DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", given_principal)); 223 301 224 302 #ifdef HAVE_KRB5 … … 226 304 got_kerberos_mechanism) 227 305 { 228 /* I've seen a child Windows 2000 domain not send 229 the principal name back in the first round of 230 the SASL bind reply. So we guess based on server 231 name and realm. --jerry */ 232 if ( !principal ) { 233 if ( ads->server.realm && ads->server.ldap_server ) { 234 char *server, *server_realm; 235 236 server = SMB_STRDUP( ads->server.ldap_server ); 237 server_realm = SMB_STRDUP( ads->server.realm ); 238 239 if ( !server || !server_realm ) 240 return ADS_ERROR(LDAP_NO_MEMORY); 241 242 strlower_m( server ); 243 strupper_m( server_realm ); 244 asprintf( &principal, "ldap/%s@%s", server, server_realm ); 245 246 SAFE_FREE( server ); 247 SAFE_FREE( server_realm ); 248 249 if ( !principal ) 250 return ADS_ERROR(LDAP_NO_MEMORY); 251 } 252 253 } 254 255 status = ads_sasl_spnego_krb5_bind(ads, principal); 306 struct ads_service_principal p; 307 308 status = ads_generate_service_principal(ads, given_principal, &p); 309 SAFE_FREE(given_principal); 310 if (!ADS_ERR_OK(status)) { 311 return status; 312 } 313 314 status = ads_sasl_spnego_krb5_bind(ads, &p); 256 315 if (ADS_ERR_OK(status)) { 257 SAFE_FREE(principal);316 ads_free_service_principal(&p); 258 317 return status; 259 318 } … … 265 324 266 325 if (ADS_ERR_OK(status)) { 267 status = ads_sasl_spnego_krb5_bind(ads, principal); 268 } 326 status = ads_sasl_spnego_krb5_bind(ads, &p); 327 if (!ADS_ERR_OK(status)) { 328 DEBUG(0,("kinit succeeded but " 329 "ads_sasl_spnego_krb5_bind failed: %s\n", 330 ads_errstr(status))); 331 } 332 } 333 334 ads_free_service_principal(&p); 269 335 270 336 /* only fallback to NTLMSSP if allowed */ 271 337 if (ADS_ERR_OK(status) || 272 338 !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) { 273 SAFE_FREE(principal);274 339 return status; 275 340 } 276 } 277 #endif 278 279 SAFE_FREE(principal); 341 } else 342 #endif 343 { 344 SAFE_FREE(given_principal); 345 } 280 346 281 347 /* lets do NTLMSSP ... this has the big advantage that we don't need
Note:
See TracChangeset
for help on using the changeset viewer.