Changeset 745 for trunk/server/source3/libads/authdata.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/libads/authdata.c
r414 r745 26 26 #include "librpc/gen_ndr/ndr_krb5pac.h" 27 27 #include "smb_krb5.h" 28 #include " authdata.h"28 #include "libads/kerberos_proto.h" 29 29 30 30 #ifdef HAVE_KRB5 … … 69 69 } 70 70 71 /**************************************************************** 72 ****************************************************************/ 73 74 NTSTATUS decode_pac_data(TALLOC_CTX *mem_ctx, 71 /** 72 * @brief Decode a blob containing a NDR envoded PAC structure 73 * 74 * @param mem_ctx - The memory context 75 * @param pac_data_blob - The data blob containing the NDR encoded data 76 * @param context - The Kerberos Context 77 * @param service_keyblock - The Service Key used to verify the checksum 78 * @param client_principal - The client principal 79 * @param tgs_authtime - The ticket timestamp 80 * @param pac_data_out - [out] The decoded PAC 81 * 82 * @return - A NTSTATUS error code 83 */ 84 NTSTATUS decode_pac_data(TALLOC_CTX *mem_ctx, 75 85 DATA_BLOB *pac_data_blob, 76 86 krb5_context context, … … 101 111 DATA_BLOB *kdc_sig_blob = NULL; 102 112 113 bool bool_ret; 114 103 115 *pac_data_out = NULL; 104 116 … … 111 123 } 112 124 113 ndr_err = ndr_pull_struct_blob(pac_data_blob, pac_data, 114 NULL, pac_data, 125 ndr_err = ndr_pull_struct_blob(pac_data_blob, pac_data, pac_data, 115 126 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); 116 127 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { … … 127 138 } 128 139 129 ndr_err = ndr_pull_struct_blob( pac_data_blob, pac_data_raw,130 NULL, pac_data_raw,131 140 ndr_err = ndr_pull_struct_blob( 141 pac_data_blob, pac_data_raw, pac_data_raw, 142 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA_RAW); 132 143 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 133 144 status = ndr_map_error2ntstatus(ndr_err); … … 145 156 if (pac_data->num_buffers != pac_data_raw->num_buffers) { 146 157 /* we need logon_ingo, service_key and kdc_key */ 147 DEBUG(0,("misparse! PAC_DATA has %d buffers while PAC_DATA_RAW has %d\n", 148 pac_data->num_buffers, pac_data_raw->num_buffers)); 158 DEBUG(0, ("misparse! PAC_DATA has %d buffers while " 159 "PAC_DATA_RAW has %d\n", pac_data->num_buffers, 160 pac_data_raw->num_buffers)); 149 161 return NT_STATUS_INVALID_PARAMETER; 150 162 } 151 163 152 164 for (i=0; i < pac_data->num_buffers; i++) { 153 if (pac_data->buffers[i].type != pac_data_raw->buffers[i].type) { 154 DEBUG(0,("misparse! PAC_DATA buffer %d has type %d while PAC_DATA_RAW has %d\n", 155 i, pac_data->buffers[i].type, pac_data->buffers[i].type)); 165 struct PAC_BUFFER *data_buf = &pac_data->buffers[i]; 166 struct PAC_BUFFER_RAW *raw_buf = &pac_data_raw->buffers[i]; 167 168 if (data_buf->type != raw_buf->type) { 169 DEBUG(0, ("misparse! PAC_DATA buffer %d has type " 170 "%d while PAC_DATA_RAW has %d\n", i, 171 data_buf->type, raw_buf->type)); 156 172 return NT_STATUS_INVALID_PARAMETER; 157 173 } 158 switch (pac_data->buffers[i].type) { 159 case PAC_TYPE_LOGON_INFO: 160 if (!pac_data->buffers[i].info) { 161 break; 162 } 163 logon_info = pac_data->buffers[i].info->logon_info.info; 174 switch (data_buf->type) { 175 case PAC_TYPE_LOGON_INFO: 176 if (!data_buf->info) { 164 177 break; 165 case PAC_TYPE_SRV_CHECKSUM: 166 if (!pac_data->buffers[i].info) { 167 break; 168 } 169 srv_sig_ptr = &pac_data->buffers[i].info->srv_cksum; 170 srv_sig_blob = &pac_data_raw->buffers[i].info->remaining; 178 } 179 logon_info = data_buf->info->logon_info.info; 180 break; 181 case PAC_TYPE_SRV_CHECKSUM: 182 if (!data_buf->info) { 171 183 break; 172 case PAC_TYPE_KDC_CHECKSUM:173 if (!pac_data->buffers[i].info) {174 break;175 }176 kdc_sig_ptr = &pac_data->buffers[i].info->kdc_cksum;177 kdc_sig_blob = &pac_data_raw->buffers[i].info->remaining;184 } 185 srv_sig_ptr = &data_buf->info->srv_cksum; 186 srv_sig_blob = &raw_buf->info->remaining; 187 break; 188 case PAC_TYPE_KDC_CHECKSUM: 189 if (!data_buf->info) { 178 190 break; 179 case PAC_TYPE_LOGON_NAME: 180 logon_name = &pac_data->buffers[i].info->logon_name; 181 break; 182 default: 183 break; 191 } 192 kdc_sig_ptr = &data_buf->info->kdc_cksum; 193 kdc_sig_blob = &raw_buf->info->remaining; 194 break; 195 case PAC_TYPE_LOGON_NAME: 196 logon_name = &data_buf->info->logon_name; 197 break; 198 default: 199 break; 184 200 } 185 201 } … … 205 221 } 206 222 207 /* Find and zero out the signatures, as required by the signing algorithm */ 208 209 /* We find the data blobs above, now we parse them to get at the exact portion we should zero */ 210 ndr_err = ndr_pull_struct_blob(kdc_sig_blob, kdc_sig_wipe, 211 NULL, kdc_sig_wipe, 212 (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA); 223 /* Find and zero out the signatures, 224 * as required by the signing algorithm */ 225 226 /* We find the data blobs above, 227 * now we parse them to get at the exact portion we should zero */ 228 ndr_err = ndr_pull_struct_blob( 229 kdc_sig_blob, kdc_sig_wipe, kdc_sig_wipe, 230 (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA); 213 231 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 214 232 status = ndr_map_error2ntstatus(ndr_err); … … 218 236 } 219 237 220 ndr_err = ndr_pull_struct_blob( srv_sig_blob, srv_sig_wipe,221 NULL, srv_sig_wipe,222 238 ndr_err = ndr_pull_struct_blob( 239 srv_sig_blob, srv_sig_wipe, srv_sig_wipe, 240 (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA); 223 241 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 224 242 status = ndr_map_error2ntstatus(ndr_err); … … 229 247 230 248 /* Now zero the decoded structure */ 231 memset(kdc_sig_wipe->signature.data, '\0', kdc_sig_wipe->signature.length); 232 memset(srv_sig_wipe->signature.data, '\0', srv_sig_wipe->signature.length); 249 memset(kdc_sig_wipe->signature.data, 250 '\0', kdc_sig_wipe->signature.length); 251 memset(srv_sig_wipe->signature.data, 252 '\0', srv_sig_wipe->signature.length); 233 253 234 254 /* and reencode, back into the same place it came from */ 235 ndr_err = ndr_push_struct_blob( kdc_sig_blob, pac_data_raw,236 NULL, kdc_sig_wipe,237 255 ndr_err = ndr_push_struct_blob( 256 kdc_sig_blob, pac_data_raw, kdc_sig_wipe, 257 (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA); 238 258 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 239 259 status = ndr_map_error2ntstatus(ndr_err); … … 242 262 return status; 243 263 } 244 ndr_err = ndr_push_struct_blob( srv_sig_blob, pac_data_raw,245 NULL, srv_sig_wipe,246 264 ndr_err = ndr_push_struct_blob( 265 srv_sig_blob, pac_data_raw, srv_sig_wipe, 266 (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA); 247 267 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 248 268 status = ndr_map_error2ntstatus(ndr_err); … … 253 273 254 274 /* push out the whole structure, but now with zero'ed signatures */ 255 ndr_err = ndr_push_struct_blob( &modified_pac_blob, pac_data_raw,256 NULL, pac_data_raw,257 275 ndr_err = ndr_push_struct_blob( 276 &modified_pac_blob, pac_data_raw, pac_data_raw, 277 (ndr_push_flags_fn_t)ndr_push_PAC_DATA_RAW); 258 278 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 259 279 status = ndr_map_error2ntstatus(ndr_err); … … 269 289 service_keyblock); 270 290 if (ret) { 271 DEBUG(1, ("PAC Decode: Failed to verify the service signature: %s\n",272 error_message(ret)));291 DEBUG(1, ("PAC Decode: Failed to verify the service " 292 "signature: %s\n", error_message(ret))); 273 293 return NT_STATUS_ACCESS_DENIED; 274 294 } … … 278 298 279 299 if (tgs_authtime_nttime != logon_name->logon_time) { 280 DEBUG(2, ("PAC Decode: Logon time mismatch between ticket and PAC!\n")); 281 DEBUG(2, ("PAC Decode: PAC: %s\n", nt_time_string(mem_ctx, logon_name->logon_time))); 282 DEBUG(2, ("PAC Decode: Ticket: %s\n", nt_time_string(mem_ctx, tgs_authtime_nttime))); 300 DEBUG(2, ("PAC Decode: " 301 "Logon time mismatch between ticket and PAC!\n")); 302 DEBUG(2, ("PAC Decode: PAC: %s\n", 303 nt_time_string(mem_ctx, logon_name->logon_time))); 304 DEBUG(2, ("PAC Decode: Ticket: %s\n", 305 nt_time_string(mem_ctx, tgs_authtime_nttime))); 283 306 return NT_STATUS_ACCESS_DENIED; 284 307 } 285 308 286 ret = smb_krb5_parse_name_norealm(context, logon_name->account_name, 287 &client_principal_pac); 309 ret = smb_krb5_parse_name_norealm(context, 310 logon_name->account_name, 311 &client_principal_pac); 288 312 if (ret) { 289 DEBUG(2, ("Could not parse name from incoming PAC: [%s]: %s\n", 290 logon_name->account_name, 291 error_message(ret))); 292 return NT_STATUS_INVALID_PARAMETER; 293 } 294 295 if (!smb_krb5_principal_compare_any_realm(context, client_principal, client_principal_pac)) { 296 DEBUG(2, ("Name in PAC [%s] does not match principal name in ticket\n", 297 logon_name->account_name)); 298 krb5_free_principal(context, client_principal_pac); 313 DEBUG(2, ("Could not parse name from PAC: [%s]:%s\n", 314 logon_name->account_name, error_message(ret))); 315 return NT_STATUS_INVALID_PARAMETER; 316 } 317 318 bool_ret = smb_krb5_principal_compare_any_realm(context, 319 client_principal, 320 client_principal_pac); 321 322 krb5_free_principal(context, client_principal_pac); 323 324 if (!bool_ret) { 325 DEBUG(2, ("Name in PAC [%s] does not match principal name " 326 "in ticket\n", logon_name->account_name)); 299 327 return NT_STATUS_ACCESS_DENIED; 300 328 } … … 320 348 321 349 /**************************************************************** 322 ****************************************************************/ 323 324 struct PAC_LOGON_INFO *get_logon_info_from_pac(struct PAC_DATA *pac_data) 325 { 326 int i; 327 328 for (i=0; i < pac_data->num_buffers; i++) { 329 330 if (pac_data->buffers[i].type != PAC_TYPE_LOGON_INFO) { 331 continue; 332 } 333 334 return pac_data->buffers[i].info->logon_info.info; 335 } 336 337 return NULL; 338 } 339 340 /**************************************************************** 350 Given a username, password and other details, return the 351 PAC_LOGON_INFO (the structure containing the important user 352 information such as groups). 341 353 ****************************************************************/ 342 354 … … 352 364 time_t renewable_time, 353 365 const char *impersonate_princ_s, 354 struct PAC_ DATA **pac_ret)366 struct PAC_LOGON_INFO **logon_info) 355 367 { 356 368 krb5_error_code ret; 357 369 NTSTATUS status = NT_STATUS_INVALID_PARAMETER; 358 370 DATA_BLOB tkt, ap_rep, sesskey1, sesskey2; 359 struct PAC_DATA *pac_data = NULL;360 371 char *client_princ_out = NULL; 361 372 const char *auth_princ = NULL; … … 425 436 } 426 437 427 ret = cli_krb5_get_ticket(local_service, 438 ret = cli_krb5_get_ticket(mem_ctx, 439 local_service, 428 440 time_offset, 429 441 &tkt, … … 448 460 &tkt, 449 461 &client_princ_out, 450 &pac_data,462 logon_info, 451 463 &ap_rep, 452 464 &sesskey2, … … 458 470 } 459 471 460 if (! pac_data) {472 if (!*logon_info) { 461 473 DEBUG(1,("no PAC\n")); 462 474 status = NT_STATUS_INVALID_PARAMETER; 463 475 goto out; 464 476 } 465 466 *pac_ret = pac_data;467 477 468 478 out: … … 481 491 } 482 492 483 /****************************************************************484 ****************************************************************/485 486 static NTSTATUS kerberos_return_pac_logon_info(TALLOC_CTX *mem_ctx,487 const char *name,488 const char *pass,489 time_t time_offset,490 time_t *expire_time,491 time_t *renew_till_time,492 const char *cache_name,493 bool request_pac,494 bool add_netbios_addr,495 time_t renewable_time,496 const char *impersonate_princ_s,497 struct PAC_LOGON_INFO **logon_info)498 {499 NTSTATUS status;500 struct PAC_DATA *pac_data = NULL;501 struct PAC_LOGON_INFO *info = NULL;502 503 status = kerberos_return_pac(mem_ctx,504 name,505 pass,506 time_offset,507 expire_time,508 renew_till_time,509 cache_name,510 request_pac,511 add_netbios_addr,512 renewable_time,513 impersonate_princ_s,514 &pac_data);515 if (!NT_STATUS_IS_OK(status)) {516 return status;517 }518 519 if (!pac_data) {520 DEBUG(3,("no pac\n"));521 return NT_STATUS_INVALID_USER_BUFFER;522 }523 524 info = get_logon_info_from_pac(pac_data);525 if (!info) {526 DEBUG(1,("no logon_info\n"));527 return NT_STATUS_INVALID_USER_BUFFER;528 }529 530 *logon_info = info;531 532 return NT_STATUS_OK;533 }534 535 /****************************************************************536 ****************************************************************/537 538 NTSTATUS kerberos_return_info3_from_pac(TALLOC_CTX *mem_ctx,539 const char *name,540 const char *pass,541 time_t time_offset,542 time_t *expire_time,543 time_t *renew_till_time,544 const char *cache_name,545 bool request_pac,546 bool add_netbios_addr,547 time_t renewable_time,548 const char *impersonate_princ_s,549 struct netr_SamInfo3 **info3)550 {551 NTSTATUS status;552 struct PAC_LOGON_INFO *logon_info = NULL;553 554 status = kerberos_return_pac_logon_info(mem_ctx,555 name,556 pass,557 time_offset,558 expire_time,559 renew_till_time,560 cache_name,561 request_pac,562 add_netbios_addr,563 renewable_time,564 impersonate_princ_s,565 &logon_info);566 if (!NT_STATUS_IS_OK(status)) {567 return status;568 }569 570 *info3 = &logon_info->info3;571 572 return NT_STATUS_OK;573 }574 493 #endif
Note:
See TracChangeset
for help on using the changeset viewer.