Changeset 596 for trunk/server/source3/utils/ntlm_auth.c
- Timestamp:
- Jul 2, 2011, 3:35:33 PM (14 years ago)
- File:
-
- 1 edited
-
trunk/server/source3/utils/ntlm_auth.c (modified) (25 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/server/source3/utils/ntlm_auth.c
r429 r596 77 77 uint32_t neg_flags; 78 78 char *want_feature_list; 79 80 79 81 bool have_session_key; 80 82 DATA_BLOB session_key; … … 779 781 } 780 782 781 static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, 782 char *buf, int length) 783 static void manage_squid_ntlmssp_request_int(struct ntlm_auth_state *state, 784 char *buf, int length, 785 TALLOC_CTX *mem_ctx, 786 char **response) 783 787 { 784 788 DATA_BLOB request, reply; … … 786 790 787 791 if (strlen(buf) < 2) { 788 DEBUG(1, ("NTLMSSP query [%s] invalid ", buf));789 x_fprintf(x_stdout, "BH NTLMSSP query invalid\n");792 DEBUG(1, ("NTLMSSP query [%s] invalid", buf)); 793 "); 790 794 return; 791 795 } … … 797 801 state->want_feature_list = talloc_strdup(state->mem_ctx, 798 802 buf+3); 799 x_fprintf(x_stdout, "OK\n");803 "); 800 804 return; 801 805 } … … 814 818 if (opt_password == NULL) { 815 819 DEBUG(1, ("Out of memory\n")); 816 x_fprintf(x_stdout, "BH Out of memory\n");820 "); 817 821 data_blob_free(&request); 818 822 return; 819 823 } 820 824 821 x_fprintf(x_stdout, "OK\n");825 "); 822 826 data_blob_free(&request); 823 827 return; … … 834 838 835 839 if (state->svr_state == SERVER_FINISHED) { 836 x_fprintf(x_stdout, "GF 0x%08x\n", state->neg_flags); 840 *response = talloc_asprintf(mem_ctx, "GF 0x%08x", 841 state->neg_flags); 837 842 } 838 843 else { 839 x_fprintf(x_stdout, "BH\n");844 , "BH\n"); 840 845 } 841 846 data_blob_free(&request); … … 846 851 char *key64 = base64_encode_data_blob(state->mem_ctx, 847 852 state->session_key); 848 x_fprintf(x_stdout, "GK %s\n", key64?key64:"<NULL>"); 853 *response = talloc_asprintf(mem_ctx, "GK %s", 854 key64 ? key64 : "<NULL>"); 849 855 TALLOC_FREE(key64); 850 856 } else { 851 x_fprintf(x_stdout, "BH\n");857 "); 852 858 } 853 859 … … 855 861 return; 856 862 } else { 857 DEBUG(1, ("NTLMSSP query [%s] invalid ", buf));858 x_fprintf(x_stdout, "BH NTLMSSP query invalid\n");863 DEBUG(1, ("NTLMSSP query [%s] invalid", buf)); 864 "); 859 865 return; 860 866 } … … 864 870 &state->ntlmssp_state); 865 871 if (!NT_STATUS_IS_OK(nt_status)) { 866 x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); 872 *response = talloc_asprintf( 873 mem_ctx, "BH %s", nt_errstr(nt_status)); 867 874 return; 868 875 } … … 879 886 char *reply_base64 = base64_encode_data_blob(state->mem_ctx, 880 887 reply); 881 x_fprintf(x_stdout, "TT %s\n", reply_base64);888 ", reply_base64); 882 889 TALLOC_FREE(reply_base64); 883 890 data_blob_free(&reply); … … 885 892 DEBUG(10, ("NTLMSSP challenge\n")); 886 893 } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) { 887 x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); 894 *response = talloc_asprintf(mem_ctx, "BH %s", 895 nt_errstr(nt_status)); 888 896 DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status))); 889 897 890 898 ntlmssp_end(&state->ntlmssp_state); 891 899 } else if (!NT_STATUS_IS_OK(nt_status)) { 892 x_fprintf(x_stdout, "NA %s\n", nt_errstr(nt_status)); 900 *response = talloc_asprintf(mem_ctx, "NA %s", 901 nt_errstr(nt_status)); 893 902 DEBUG(10, ("NTLMSSP %s\n", nt_errstr(nt_status))); 894 903 } else { 895 x_fprintf(x_stdout, "AF %s\n", 896 (char *)state->ntlmssp_state->auth_context); 904 *response = talloc_asprintf( 905 mem_ctx, "AF %s", 906 (char *)state->ntlmssp_state->auth_context); 897 907 DEBUG(10, ("NTLMSSP OK!\n")); 898 908 … … 910 920 } 911 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 912 938 static void manage_client_ntlmssp_request(struct ntlm_auth_state *state, 913 939 char *buf, int length) … … 922 948 923 949 if (strlen(buf) < 2) { 924 DEBUG(1, ("NTLMSSP query [%s] invalid ", buf));950 DEBUG(1, ("NTLMSSP query [%s] invalid", buf)); 925 951 x_fprintf(x_stdout, "BH NTLMSSP query invalid\n"); 926 952 return; … … 1014 1040 return; 1015 1041 } else { 1016 DEBUG(1, ("NTLMSSP query [%s] invalid ", buf));1042 DEBUG(1, ("NTLMSSP query [%s] invalid", buf)); 1017 1043 x_fprintf(x_stdout, "BH NTLMSSP query invalid\n"); 1018 1044 return; … … 1138 1164 /* Server negTokenInit (mech offerings) */ 1139 1165 spnego.type = SPNEGO_NEG_TOKEN_INIT; 1140 spnego.negTokenInit.mechTypes = talloc_array(ctx, const char *, 2);1166 spnego.negTokenInit.mechTypes = talloc_array(ctx, const char *, ); 1141 1167 #ifdef HAVE_KRB5 1142 1168 spnego.negTokenInit.mechTypes[0] = talloc_strdup(ctx, OID_KERBEROS5_OLD); 1143 spnego.negTokenInit.mechTypes[1] = talloc_strdup(ctx, OID_NTLMSSP); 1144 spnego.negTokenInit.mechTypes[2] = NULL; 1169 spnego.negTokenInit.mechTypes[1] = talloc_strdup(ctx, OID_KERBEROS5); 1170 spnego.negTokenInit.mechTypes[2] = talloc_strdup(ctx, OID_NTLMSSP); 1171 spnego.negTokenInit.mechTypes[3] = NULL; 1145 1172 #else 1146 1173 spnego.negTokenInit.mechTypes[0] = talloc_strdup(ctx, OID_NTLMSSP); … … 1170 1197 } 1171 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1172 1238 static void manage_gss_spnego_request(struct ntlm_auth_state *state, 1173 1239 char *buf, int length) 1174 1240 { 1175 static NTLMSSP_STATE *ntlmssp_state = NULL;1176 1241 struct spnego_data request, response; 1177 1242 DATA_BLOB token; 1243 1244 1178 1245 NTSTATUS status; 1179 1246 ssize_t len; … … 1186 1253 char *reply_base64; 1187 1254 char *reply_argument = NULL; 1255 1188 1256 1189 1257 if (strlen(buf) < 2) { 1190 DEBUG(1, ("SPENGO query [%s] invalid ", buf));1258 DEBUG(1, ("SPENGO query [%s] invalid", buf)); 1191 1259 x_fprintf(x_stdout, "BH SPENGO query invalid\n"); 1192 1260 return; … … 1194 1262 1195 1263 if (strncmp(buf, "YR", 2) == 0) { 1196 if (ntlmssp_state) 1197 ntlmssp_end(&ntlmssp_state); 1264 if (state->ntlmssp_state) 1265 ntlmssp_end(&state->ntlmssp_state); 1266 TALLOC_FREE(state->spnego_mech); 1267 TALLOC_FREE(state->spnego_mech_oid); 1198 1268 } else if (strncmp(buf, "KK", 2) == 0) { 1199 1269 ; 1200 1270 } else { 1201 DEBUG(1, ("SPENGO query [%s] invalid ", buf));1271 DEBUG(1, ("SPENGO query [%s] invalid", buf)); 1202 1272 x_fprintf(x_stdout, "BH SPENGO query invalid\n"); 1203 1273 return; … … 1222 1292 1223 1293 token = base64_decode_data_blob(buf + 3); 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1224 1322 len = spnego_read_data(ctx, token, &request); 1225 1323 data_blob_free(&token); 1226 1324 1227 1325 if (len == -1) { 1228 DEBUG(1, ("GSS-SPNEGO query [%s] invalid ", buf));1326 DEBUG(1, ("GSS-SPNEGO query [%s] invalid", buf)); 1229 1327 x_fprintf(x_stdout, "BH GSS-SPNEGO query invalid\n"); 1230 1328 return; … … 1232 1330 1233 1331 if (request.type == SPNEGO_NEG_TOKEN_INIT) { 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1234 1346 1235 1347 /* Second request from Client. This is where the … … 1238 1350 if ( (request.negTokenInit.mechTypes == NULL) || 1239 1351 (request.negTokenInit.mechTypes[0] == NULL) ) { 1240 DEBUG(1, ("Client did not offer any mechanism "));1352 DEBUG(1, ("Client did not offer any mechanism")); 1241 1353 x_fprintf(x_stdout, "BH Client did not offer any " 1242 1354 "mechanism\n"); … … 1245 1357 1246 1358 status = NT_STATUS_UNSUCCESSFUL; 1247 if (strcmp(request.negTokenInit.mechTypes[0], OID_NTLMSSP) == 0) { 1248 1249 if ( request.negTokenInit.mechToken.data == NULL ) { 1250 DEBUG(1, ("Client did not provide NTLMSSP data\n")); 1251 x_fprintf(x_stdout, "BH Client did not provide " 1252 "NTLMSSP data\n"); 1359 for (i = 0; request.negTokenInit.mechTypes[i] != NULL; i++) { 1360 DEBUG(10,("got mech[%d][%s]\n", 1361 i, request.negTokenInit.mechTypes[i])); 1362 #ifdef HAVE_KRB5 1363 if (strcmp(request.negTokenInit.mechTypes[i], OID_KERBEROS5_OLD) == 0) { 1364 krb5_idx = i; 1365 break; 1366 } 1367 if (strcmp(request.negTokenInit.mechTypes[i], OID_KERBEROS5) == 0) { 1368 krb5_idx = i; 1369 break; 1370 } 1371 #endif 1372 if (strcmp(request.negTokenInit.mechTypes[i], OID_NTLMSSP) == 0) { 1373 ntlm_idx = i; 1374 break; 1375 } 1376 } 1377 1378 used_idx = ntlm_idx; 1379 #ifdef HAVE_KRB5 1380 if (krb5_idx != -1) { 1381 ntlm_idx = -1; 1382 used_idx = krb5_idx; 1383 } 1384 #endif 1385 if (ntlm_idx > -1) { 1386 state->spnego_mech = talloc_strdup(state, "ntlmssp"); 1387 if (state->spnego_mech == NULL) { 1388 x_fprintf(x_stdout, "BH Out of memory\n"); 1253 1389 return; 1254 1390 } 1255 1391 1256 if ( ntlmssp_state != NULL) {1392 if () { 1257 1393 DEBUG(1, ("Client wants a new NTLMSSP challenge, but " 1258 1394 "already got one\n")); … … 1260 1396 "NTLMSSP challenge, but " 1261 1397 "already got one\n"); 1262 ntlmssp_end(& ntlmssp_state);1398 ntlmssp_end(&ntlmssp_state); 1263 1399 return; 1264 1400 } 1265 1401 1266 if (!NT_STATUS_IS_OK(status = ntlm_auth_start_ntlmssp_server(&ntlmssp_state))) { 1402 status = ntlm_auth_start_ntlmssp_server(&state->ntlmssp_state); 1403 if (!NT_STATUS_IS_OK(status)) { 1267 1404 x_fprintf(x_stdout, "BH %s\n", nt_errstr(status)); 1268 1405 return; 1269 1406 } 1270 1271 DEBUG(10, ("got NTLMSSP packet:\n"));1272 dump_data(10, request.negTokenInit.mechToken.data,1273 request.negTokenInit.mechToken.length);1274 1275 response.type = SPNEGO_NEG_TOKEN_TARG;1276 response.negTokenTarg.supportedMech = talloc_strdup(ctx, OID_NTLMSSP);1277 response.negTokenTarg.mechListMIC = data_blob_talloc(ctx, NULL, 0);1278 1279 status = ntlmssp_update(ntlmssp_state,1280 request.negTokenInit.mechToken,1281 &response.negTokenTarg.responseToken);1282 1407 } 1283 1408 1284 1409 #ifdef HAVE_KRB5 1285 if (strcmp(request.negTokenInit.mechTypes[0], OID_KERBEROS5_OLD) == 0) { 1286 1287 TALLOC_CTX *mem_ctx = talloc_init("manage_gss_spnego_request"); 1288 char *principal; 1289 DATA_BLOB ap_rep; 1290 DATA_BLOB session_key; 1291 struct PAC_DATA *pac_data = NULL; 1292 1293 if ( request.negTokenInit.mechToken.data == NULL ) { 1294 DEBUG(1, ("Client did not provide Kerberos data\n")); 1295 x_fprintf(x_stdout, "BH Client did not provide " 1296 "Kerberos data\n"); 1410 if (krb5_idx > -1) { 1411 state->spnego_mech = talloc_strdup(state, "krb5"); 1412 if (state->spnego_mech == NULL) { 1413 x_fprintf(x_stdout, "BH Out of memory\n"); 1297 1414 return; 1298 1415 } 1299 1300 response.type = SPNEGO_NEG_TOKEN_TARG; 1301 response.negTokenTarg.supportedMech = talloc_strdup(ctx, OID_KERBEROS5_OLD); 1302 response.negTokenTarg.mechListMIC = data_blob_talloc(ctx, NULL, 0); 1303 response.negTokenTarg.responseToken = data_blob_talloc(ctx, NULL, 0); 1304 1305 status = ads_verify_ticket(mem_ctx, lp_realm(), 0, 1306 &request.negTokenInit.mechToken, 1307 &principal, &pac_data, &ap_rep, 1308 &session_key, True); 1309 1310 /* Now in "principal" we have the name we are 1311 authenticated as. */ 1312 1313 if (NT_STATUS_IS_OK(status)) { 1314 1315 domain = strchr_m(principal, '@'); 1316 1317 if (domain == NULL) { 1318 DEBUG(1, ("Did not get a valid principal " 1319 "from ads_verify_ticket\n")); 1320 x_fprintf(x_stdout, "BH Did not get a " 1321 "valid principal from " 1322 "ads_verify_ticket\n"); 1323 return; 1416 } 1417 #endif 1418 if (used_idx > -1) { 1419 state->spnego_mech_oid = talloc_strdup(state, 1420 request.negTokenInit.mechTypes[used_idx]); 1421 if (state->spnego_mech_oid == NULL) { 1422 x_fprintf(x_stdout, "BH Out of memory\n"); 1423 return; 1424 } 1425 supportedMech = talloc_strdup(ctx, state->spnego_mech_oid); 1426 if (supportedMech == NULL) { 1427 x_fprintf(x_stdout, "BH Out of memory\n"); 1428 return; 1429 } 1430 1431 status = NT_STATUS_MORE_PROCESSING_REQUIRED; 1432 } else { 1433 status = NT_STATUS_NOT_SUPPORTED; 1434 } 1435 if (used_idx == 0) { 1436 status = NT_STATUS_OK; 1437 raw_in_token = request.negTokenInit.mechToken; 1438 } 1439 } else { 1440 if (state->spnego_mech == NULL) { 1441 DEBUG(1,("Got netTokenTarg without negTokenInit\n")); 1442 x_fprintf(x_stdout, "BH Got a negTokenTarg without " 1443 "negTokenInit\n"); 1444 return; 1445 } 1446 1447 if ((request.negTokenTarg.supportedMech != NULL) && 1448 (strcmp(request.negTokenTarg.supportedMech, state->spnego_mech_oid) != 0 ) ) { 1449 DEBUG(1, ("Got a negTokenTarg with mech[%s] while [%s] was already negotiated\n", 1450 request.negTokenTarg.supportedMech, 1451 state->spnego_mech_oid)); 1452 x_fprintf(x_stdout, "BH Got a negTokenTarg with speficied mech\n"); 1453 return; 1454 } 1455 1456 status = NT_STATUS_OK; 1457 raw_in_token = request.negTokenTarg.responseToken; 1458 } 1459 1460 if (!NT_STATUS_IS_OK(status)) { 1461 /* error or more processing */ 1462 } else if (strcmp(state->spnego_mech, "ntlmssp") == 0) { 1463 1464 DEBUG(10, ("got NTLMSSP packet:\n")); 1465 dump_data(10, raw_in_token.data, raw_in_token.length); 1466 1467 status = ntlmssp_update(state->ntlmssp_state, 1468 raw_in_token, 1469 &raw_out_token); 1470 if (NT_STATUS_IS_OK(status)) { 1471 user = talloc_strdup(ctx, state->ntlmssp_state->user); 1472 domain = talloc_strdup(ctx, state->ntlmssp_state->domain); 1473 } 1474 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1475 ntlmssp_end(&state->ntlmssp_state); 1476 } 1477 #ifdef HAVE_KRB5 1478 } else if (strcmp(state->spnego_mech, "krb5") == 0) { 1479 char *principal; 1480 DATA_BLOB ap_rep; 1481 DATA_BLOB session_key; 1482 struct PAC_DATA *pac_data = NULL; 1483 DATA_BLOB ticket; 1484 uint8_t tok_id[2]; 1485 1486 if (!_spnego_parse_krb5_wrap(ctx, raw_in_token, 1487 &ticket, tok_id)) { 1488 DEBUG(1, ("spnego_parse_krb5_wrap failed\n")); 1489 x_fprintf(x_stdout, "BH spnego_parse_krb5_wrap failed\n"); 1490 return; 1491 } 1492 1493 status = ads_verify_ticket(ctx, lp_realm(), 0, 1494 &ticket, 1495 &principal, &pac_data, &ap_rep, 1496 &session_key, True); 1497 1498 /* Now in "principal" we have the name we are authenticated as. */ 1499 1500 if (NT_STATUS_IS_OK(status)) { 1501 1502 domain = strchr_m(principal, '@'); 1503 1504 if (domain == NULL) { 1505 DEBUG(1, ("Did not get a valid principal " 1506 "from ads_verify_ticket\n")); 1507 x_fprintf(x_stdout, "BH Did not get a " 1508 "valid principal from " 1509 "ads_verify_ticket\n"); 1510 return; 1511 } 1512 1513 *domain++ = '\0'; 1514 domain = talloc_strdup(ctx, domain); 1515 user = talloc_strdup(ctx, principal); 1516 1517 if (pac_data) { 1518 struct PAC_LOGON_INFO *logon_info; 1519 logon_info = get_logon_info_from_pac( 1520 pac_data); 1521 if (logon_info) { 1522 netsamlogon_cache_store( 1523 user, 1524 &logon_info->info3); 1324 1525 } 1325 1326 *domain++ = '\0'; 1327 domain = SMB_STRDUP(domain); 1328 user = SMB_STRDUP(principal); 1329 1330 data_blob_free(&ap_rep); 1331 } 1332 1333 TALLOC_FREE(mem_ctx); 1334 } 1526 } 1527 1528 data_blob_free(&ap_rep); 1529 data_blob_free(&session_key); 1530 } 1531 data_blob_free(&ticket); 1335 1532 #endif 1336 1337 } else {1338 1339 if ( (request.negTokenTarg.supportedMech == NULL) ||1340 ( strcmp(request.negTokenTarg.supportedMech, OID_NTLMSSP) != 0 ) ) {1341 /* Kerberos should never send a negTokenTarg, OID_NTLMSSP1342 is the only one we support that sends this stuff */1343 DEBUG(1, ("Got a negTokenTarg for something non-NTLMSSP: %s\n",1344 request.negTokenTarg.supportedMech));1345 x_fprintf(x_stdout, "BH Got a negTokenTarg for "1346 "something non-NTLMSSP\n");1347 return;1348 }1349 1350 if (request.negTokenTarg.responseToken.data == NULL) {1351 DEBUG(1, ("Got a negTokenTarg without a responseToken!\n"));1352 x_fprintf(x_stdout, "BH Got a negTokenTarg without a "1353 "responseToken!\n");1354 return;1355 }1356 1357 status = ntlmssp_update(ntlmssp_state,1358 request.negTokenTarg.responseToken,1359 &response.negTokenTarg.responseToken);1360 1361 response.type = SPNEGO_NEG_TOKEN_TARG;1362 response.negTokenTarg.supportedMech = talloc_strdup(ctx, OID_NTLMSSP);1363 response.negTokenTarg.mechListMIC = data_blob_talloc(ctx, NULL, 0);1364 1365 if (NT_STATUS_IS_OK(status)) {1366 user = SMB_STRDUP(ntlmssp_state->user);1367 domain = SMB_STRDUP(ntlmssp_state->domain);1368 ntlmssp_end(&ntlmssp_state);1369 }1370 1533 } 1371 1534 1372 1535 spnego_free_data(&request); 1536 1537 1373 1538 1374 1539 if (NT_STATUS_IS_OK(status)) { 1540 1541 1375 1542 response.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED; 1543 1376 1544 reply_code = "AF"; 1377 1545 reply_argument = talloc_asprintf(ctx, "%s\\%s", domain, user); 1378 1546 } else if (NT_STATUS_EQUAL(status, 1379 1547 NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1548 1549 1380 1550 response.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE; 1381 1551 reply_code = "TT"; 1382 1552 reply_argument = talloc_strdup(ctx, "*"); 1383 1553 } else { 1554 1555 1556 1384 1557 response.negTokenTarg.negResult = SPNEGO_REJECT; 1385 1558 reply_code = "NA"; … … 1390 1563 DEBUG(1, ("Could not write SPNEGO data blob\n")); 1391 1564 x_fprintf(x_stdout, "BH Could not write SPNEGO data blob\n"); 1392 return; 1393 } 1394 1395 SAFE_FREE(user); 1396 SAFE_FREE(domain); 1565 spnego_free_data(&response); 1566 return; 1567 } 1397 1568 1398 1569 len = spnego_write_data(ctx, &token, &response); … … 2289 2460 2290 2461 while(1) { 2462 2291 2463 manage_squid_request(state, fn); 2464 2292 2465 } 2293 2466 }
Note:
See TracChangeset
for help on using the changeset viewer.
