00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "includes.h"
00030
00031 #ifdef HAVE_KRB5
00032
00033
00034 #ifndef MAX_KEYTAB_NAME_LEN
00035 #define MAX_KEYTAB_NAME_LEN 1100
00036 #endif
00037
00038
00039
00040
00041
00042 static int smb_krb5_kt_add_entry( krb5_context context, krb5_keytab keytab,
00043 krb5_kvno kvno, const char *princ_s,
00044 krb5_enctype *enctypes, krb5_data password )
00045 {
00046 krb5_error_code ret = 0;
00047 krb5_kt_cursor cursor;
00048 krb5_keytab_entry kt_entry;
00049 krb5_principal princ = NULL;
00050 int i;
00051 char *ktprinc = NULL;
00052
00053 ZERO_STRUCT(kt_entry);
00054 ZERO_STRUCT(cursor);
00055
00056 ret = smb_krb5_parse_name(context, princ_s, &princ);
00057 if (ret) {
00058 DEBUG(1,("smb_krb5_kt_add_entry: smb_krb5_parse_name(%s) failed (%s)\n", princ_s, error_message(ret)));
00059 goto out;
00060 }
00061
00062
00063 ret = krb5_kt_start_seq_get(context, keytab, &cursor);
00064 if (ret != KRB5_KT_END && ret != ENOENT ) {
00065 DEBUG(3,("smb_krb5_kt_add_entry: Will try to delete old keytab entries\n"));
00066 while(!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) {
00067 BOOL compare_name_ok = False;
00068
00069 ret = smb_krb5_unparse_name(context, kt_entry.principal, &ktprinc);
00070 if (ret) {
00071 DEBUG(1,("smb_krb5_kt_add_entry: smb_krb5_unparse_name failed (%s)\n",
00072 error_message(ret)));
00073 goto out;
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 #ifdef HAVE_KRB5_KT_COMPARE
00086 compare_name_ok = (krb5_kt_compare(context, &kt_entry, princ, 0, 0) == True);
00087 #else
00088 compare_name_ok = (strcmp(ktprinc, princ_s) == 0);
00089 #endif
00090
00091 if (!compare_name_ok) {
00092 DEBUG(10,("smb_krb5_kt_add_entry: ignoring keytab entry principal %s, kvno = %d\n",
00093 ktprinc, kt_entry.vno));
00094 }
00095
00096 SAFE_FREE(ktprinc);
00097
00098 if (compare_name_ok) {
00099 if (kt_entry.vno == kvno - 1) {
00100 DEBUG(5,("smb_krb5_kt_add_entry: Saving previous (kvno %d) entry for principal: %s.\n",
00101 kvno - 1, princ_s));
00102 } else {
00103
00104 DEBUG(5,("smb_krb5_kt_add_entry: Found old entry for principal: %s (kvno %d) - trying to remove it.\n",
00105 princ_s, kt_entry.vno));
00106 ret = krb5_kt_end_seq_get(context, keytab, &cursor);
00107 ZERO_STRUCT(cursor);
00108 if (ret) {
00109 DEBUG(1,("smb_krb5_kt_add_entry: krb5_kt_end_seq_get() failed (%s)\n",
00110 error_message(ret)));
00111 goto out;
00112 }
00113 ret = krb5_kt_remove_entry(context, keytab, &kt_entry);
00114 if (ret) {
00115 DEBUG(1,("smb_krb5_kt_add_entry: krb5_kt_remove_entry failed (%s)\n",
00116 error_message(ret)));
00117 goto out;
00118 }
00119
00120 DEBUG(5,("smb_krb5_kt_add_entry: removed old entry for principal: %s (kvno %d).\n",
00121 princ_s, kt_entry.vno));
00122
00123 ret = krb5_kt_start_seq_get(context, keytab, &cursor);
00124 if (ret) {
00125 DEBUG(1,("smb_krb5_kt_add_entry: krb5_kt_start_seq failed (%s)\n",
00126 error_message(ret)));
00127 goto out;
00128 }
00129 ret = smb_krb5_kt_free_entry(context, &kt_entry);
00130 ZERO_STRUCT(kt_entry);
00131 if (ret) {
00132 DEBUG(1,("smb_krb5_kt_add_entry: krb5_kt_remove_entry failed (%s)\n",
00133 error_message(ret)));
00134 goto out;
00135 }
00136 continue;
00137 }
00138 }
00139
00140
00141 ret = smb_krb5_kt_free_entry(context, &kt_entry);
00142 ZERO_STRUCT(kt_entry);
00143 if (ret) {
00144 DEBUG(1,("smb_krb5_kt_add_entry: smb_krb5_kt_free_entry failed (%s)\n", error_message(ret)));
00145 goto out;
00146 }
00147 }
00148
00149 ret = krb5_kt_end_seq_get(context, keytab, &cursor);
00150 ZERO_STRUCT(cursor);
00151 if (ret) {
00152 DEBUG(1,("smb_krb5_kt_add_entry: krb5_kt_end_seq_get failed (%s)\n",error_message(ret)));
00153 goto out;
00154 }
00155 }
00156
00157
00158 ZERO_STRUCT(kt_entry);
00159 ZERO_STRUCT(cursor);
00160
00161
00162
00163
00164 for (i = 0; enctypes[i]; i++) {
00165 krb5_keyblock *keyp;
00166
00167 #if !defined(HAVE_KRB5_KEYTAB_ENTRY_KEY) && !defined(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK)
00168 #error krb5_keytab_entry has no key or keyblock member
00169 #endif
00170 #ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY
00171 keyp = &kt_entry.key;
00172 #endif
00173 #ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK
00174 keyp = &kt_entry.keyblock;
00175 #endif
00176 if (create_kerberos_key_from_string(context, princ, &password, keyp, enctypes[i])) {
00177 continue;
00178 }
00179
00180 kt_entry.principal = princ;
00181 kt_entry.vno = kvno;
00182
00183 DEBUG(3,("smb_krb5_kt_add_entry: adding keytab entry for (%s) with encryption type (%d) and version (%d)\n",
00184 princ_s, enctypes[i], kt_entry.vno));
00185 ret = krb5_kt_add_entry(context, keytab, &kt_entry);
00186 krb5_free_keyblock_contents(context, keyp);
00187 ZERO_STRUCT(kt_entry);
00188 if (ret) {
00189 DEBUG(1,("smb_krb5_kt_add_entry: adding entry to keytab failed (%s)\n", error_message(ret)));
00190 goto out;
00191 }
00192 }
00193
00194
00195 out:
00196 {
00197 krb5_keytab_entry zero_kt_entry;
00198 ZERO_STRUCT(zero_kt_entry);
00199 if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) {
00200 smb_krb5_kt_free_entry(context, &kt_entry);
00201 }
00202 }
00203 if (princ) {
00204 krb5_free_principal(context, princ);
00205 }
00206
00207 {
00208 krb5_kt_cursor zero_csr;
00209 ZERO_STRUCT(zero_csr);
00210 if ((memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) {
00211 krb5_kt_end_seq_get(context, keytab, &cursor);
00212 }
00213 }
00214
00215 return (int)ret;
00216 }
00217
00218
00219
00220
00221
00222
00223 int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc)
00224 {
00225 krb5_error_code ret = 0;
00226 krb5_context context = NULL;
00227 krb5_keytab keytab = NULL;
00228 krb5_data password;
00229 krb5_kvno kvno;
00230 krb5_enctype enctypes[4] = { ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_MD5, 0, 0 };
00231 char *princ_s = NULL, *short_princ_s = NULL;
00232 char *password_s = NULL;
00233 char *my_fqdn;
00234 char keytab_name[MAX_KEYTAB_NAME_LEN];
00235 TALLOC_CTX *ctx = NULL;
00236 char *machine_name;
00237
00238 #if defined(ENCTYPE_ARCFOUR_HMAC)
00239 enctypes[2] = ENCTYPE_ARCFOUR_HMAC;
00240 #endif
00241
00242 initialize_krb5_error_table();
00243 ret = krb5_init_context(&context);
00244 if (ret) {
00245 DEBUG(1,("ads_keytab_add_entry: could not krb5_init_context: %s\n",error_message(ret)));
00246 return -1;
00247 }
00248
00249 #ifdef HAVE_WRFILE_KEYTAB
00250 keytab_name[0] = 'W';
00251 keytab_name[1] = 'R';
00252 ret = krb5_kt_default_name(context, (char *) &keytab_name[2], MAX_KEYTAB_NAME_LEN - 4);
00253 #else
00254 ret = krb5_kt_default_name(context, (char *) &keytab_name[0], MAX_KEYTAB_NAME_LEN - 2);
00255 #endif
00256 if (ret) {
00257 DEBUG(1,("ads_keytab_add_entry: krb5_kt_default_name failed (%s)\n", error_message(ret)));
00258 goto out;
00259 }
00260 DEBUG(2,("ads_keytab_add_entry: Using default system keytab: %s\n", (char *) &keytab_name));
00261 ret = krb5_kt_resolve(context, (char *) &keytab_name, &keytab);
00262 if (ret) {
00263 DEBUG(1,("ads_keytab_add_entry: krb5_kt_resolve failed (%s)\n", error_message(ret)));
00264 goto out;
00265 }
00266
00267
00268 if (!secrets_init()) {
00269 DEBUG(1,("ads_keytab_add_entry: secrets_init failed\n"));
00270 ret = -1;
00271 goto out;
00272 }
00273 password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
00274 if (!password_s) {
00275 DEBUG(1,("ads_keytab_add_entry: failed to fetch machine password\n"));
00276 ret = -1;
00277 goto out;
00278 }
00279 password.data = password_s;
00280 password.length = strlen(password_s);
00281
00282
00283
00284 if ( (ctx = talloc_init("ads_keytab_add_entry")) == NULL ) {
00285 DEBUG(0,("ads_keytab_add_entry: talloc() failed!\n"));
00286 ret = -1;
00287 goto out;
00288 }
00289
00290 if ( (my_fqdn = ads_get_dnshostname( ads, ctx, global_myname())) == NULL ) {
00291 DEBUG(0,("ads_keytab_add_entry: unable to determine machine account's dns name in AD!\n"));
00292 ret = -1;
00293 goto out;
00294 }
00295
00296 if ( (machine_name = ads_get_samaccountname( ads, ctx, global_myname())) == NULL ) {
00297 DEBUG(0,("ads_keytab_add_entry: unable to determine machine account's short name in AD!\n"));
00298 ret = -1;
00299 goto out;
00300 }
00301
00302 machine_name[strlen(machine_name)-1] = '\0';
00303
00304
00305
00306 if (strchr_m(srvPrinc, '@')) {
00307
00308 asprintf(&princ_s, "%s", srvPrinc);
00309 } else if (srvPrinc[strlen(srvPrinc)-1] == '$') {
00310
00311 asprintf(&princ_s, "%s@%s", srvPrinc, lp_realm());
00312 } else {
00313
00314
00315
00316
00317 asprintf(&princ_s, "%s/%s@%s", srvPrinc, my_fqdn, lp_realm());
00318 asprintf(&short_princ_s, "%s/%s@%s", srvPrinc, machine_name, lp_realm());
00319
00320
00321
00322
00323
00324
00325 if ( !strequal( srvPrinc, "cifs" ) && !strequal(srvPrinc, "host" ) ) {
00326 DEBUG(3,("ads_keytab_add_entry: Attempting to add/update '%s'\n", princ_s));
00327
00328 if (!ADS_ERR_OK(ads_add_service_principal_name(ads, global_myname(), my_fqdn, srvPrinc))) {
00329 DEBUG(1,("ads_keytab_add_entry: ads_add_service_principal_name failed.\n"));
00330 goto out;
00331 }
00332 }
00333 }
00334
00335 kvno = (krb5_kvno) ads_get_kvno(ads, global_myname());
00336 if (kvno == -1) {
00337 DEBUG(1,("ads_keytab_add_entry: ads_get_kvno failed to determine the system's kvno.\n"));
00338 ret = -1;
00339 goto out;
00340 }
00341
00342
00343
00344 ret = smb_krb5_kt_add_entry( context, keytab, kvno, princ_s, enctypes, password );
00345 if ( ret ) {
00346 DEBUG(1,("ads_keytab_add_entry: Failed to add entry to keytab file\n"));
00347 goto out;
00348 }
00349
00350
00351
00352 if ( short_princ_s ) {
00353 ret = smb_krb5_kt_add_entry( context, keytab, kvno, short_princ_s, enctypes, password );
00354 if ( ret ) {
00355 DEBUG(1,("ads_keytab_add_entry: Failed to add short entry to keytab file\n"));
00356 goto out;
00357 }
00358 }
00359
00360 out:
00361 SAFE_FREE( princ_s );
00362 SAFE_FREE( short_princ_s );
00363 TALLOC_FREE( ctx );
00364
00365 if (keytab) {
00366 krb5_kt_close(context, keytab);
00367 }
00368 if (context) {
00369 krb5_free_context(context);
00370 }
00371 return (int)ret;
00372 }
00373
00374
00375
00376
00377
00378 int ads_keytab_flush(ADS_STRUCT *ads)
00379 {
00380 krb5_error_code ret = 0;
00381 krb5_context context = NULL;
00382 krb5_keytab keytab = NULL;
00383 krb5_kt_cursor cursor;
00384 krb5_keytab_entry kt_entry;
00385 krb5_kvno kvno;
00386 char keytab_name[MAX_KEYTAB_NAME_LEN];
00387
00388 ZERO_STRUCT(kt_entry);
00389 ZERO_STRUCT(cursor);
00390
00391 initialize_krb5_error_table();
00392 ret = krb5_init_context(&context);
00393 if (ret) {
00394 DEBUG(1,("ads_keytab_flush: could not krb5_init_context: %s\n",error_message(ret)));
00395 return ret;
00396 }
00397 #ifdef HAVE_WRFILE_KEYTAB
00398 keytab_name[0] = 'W';
00399 keytab_name[1] = 'R';
00400 ret = krb5_kt_default_name(context, (char *) &keytab_name[2], MAX_KEYTAB_NAME_LEN - 4);
00401 #else
00402 ret = krb5_kt_default_name(context, (char *) &keytab_name[0], MAX_KEYTAB_NAME_LEN - 2);
00403 #endif
00404 if (ret) {
00405 DEBUG(1,("ads_keytab_flush: krb5_kt_default failed (%s)\n", error_message(ret)));
00406 goto out;
00407 }
00408 DEBUG(3,("ads_keytab_flush: Using default keytab: %s\n", (char *) &keytab_name));
00409 ret = krb5_kt_resolve(context, (char *) &keytab_name, &keytab);
00410 if (ret) {
00411 DEBUG(1,("ads_keytab_flush: krb5_kt_resolve failed (%s)\n", error_message(ret)));
00412 goto out;
00413 }
00414
00415 kvno = (krb5_kvno) ads_get_kvno(ads, global_myname());
00416 if (kvno == -1) {
00417 DEBUG(1,("ads_keytab_flush: Error determining the system's kvno.\n"));
00418 goto out;
00419 }
00420
00421 ret = krb5_kt_start_seq_get(context, keytab, &cursor);
00422 if (ret != KRB5_KT_END && ret != ENOENT) {
00423 while (!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) {
00424 ret = krb5_kt_end_seq_get(context, keytab, &cursor);
00425 ZERO_STRUCT(cursor);
00426 if (ret) {
00427 DEBUG(1,("ads_keytab_flush: krb5_kt_end_seq_get() failed (%s)\n",error_message(ret)));
00428 goto out;
00429 }
00430 ret = krb5_kt_remove_entry(context, keytab, &kt_entry);
00431 if (ret) {
00432 DEBUG(1,("ads_keytab_flush: krb5_kt_remove_entry failed (%s)\n",error_message(ret)));
00433 goto out;
00434 }
00435 ret = krb5_kt_start_seq_get(context, keytab, &cursor);
00436 if (ret) {
00437 DEBUG(1,("ads_keytab_flush: krb5_kt_start_seq failed (%s)\n",error_message(ret)));
00438 goto out;
00439 }
00440 ret = smb_krb5_kt_free_entry(context, &kt_entry);
00441 ZERO_STRUCT(kt_entry);
00442 if (ret) {
00443 DEBUG(1,("ads_keytab_flush: krb5_kt_remove_entry failed (%s)\n",error_message(ret)));
00444 goto out;
00445 }
00446 }
00447 }
00448
00449
00450 ZERO_STRUCT(kt_entry);
00451 ZERO_STRUCT(cursor);
00452
00453 if (!ADS_ERR_OK(ads_clear_service_principal_names(ads, global_myname()))) {
00454 DEBUG(1,("ads_keytab_flush: Error while clearing service principal listings in LDAP.\n"));
00455 goto out;
00456 }
00457
00458 out:
00459
00460 {
00461 krb5_keytab_entry zero_kt_entry;
00462 ZERO_STRUCT(zero_kt_entry);
00463 if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) {
00464 smb_krb5_kt_free_entry(context, &kt_entry);
00465 }
00466 }
00467 {
00468 krb5_kt_cursor zero_csr;
00469 ZERO_STRUCT(zero_csr);
00470 if ((memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) {
00471 krb5_kt_end_seq_get(context, keytab, &cursor);
00472 }
00473 }
00474 if (keytab) {
00475 krb5_kt_close(context, keytab);
00476 }
00477 if (context) {
00478 krb5_free_context(context);
00479 }
00480 return ret;
00481 }
00482
00483
00484
00485
00486
00487 int ads_keytab_create_default(ADS_STRUCT *ads)
00488 {
00489 krb5_error_code ret = 0;
00490 krb5_context context = NULL;
00491 krb5_keytab keytab = NULL;
00492 krb5_kt_cursor cursor;
00493 krb5_keytab_entry kt_entry;
00494 krb5_kvno kvno;
00495 int i, found = 0;
00496 char *sam_account_name, *upn;
00497 char **oldEntries = NULL, *princ_s[26];
00498 TALLOC_CTX *ctx = NULL;
00499 fstring machine_name;
00500
00501 memset(princ_s, '\0', sizeof(princ_s));
00502
00503 fstrcpy( machine_name, global_myname() );
00504
00505
00506
00507 if ( (ret = ads_keytab_add_entry(ads, "host") ) != 0 ) {
00508 DEBUG(1,("ads_keytab_create_default: ads_keytab_add_entry failed while adding 'host'.\n"));
00509 return ret;
00510 }
00511
00512
00513 #if 0
00514
00515
00516 if ( (ret = ads_keytab_add_entry(ads, "cifs")) != 0 ) {
00517 DEBUG(1,("ads_keytab_create_default: ads_keytab_add_entry failed while adding 'cifs'.\n"));
00518 return ret;
00519 }
00520 #endif
00521
00522 if ( (ctx = talloc_init("ads_keytab_create_default")) == NULL ) {
00523 DEBUG(0,("ads_keytab_create_default: talloc() failed!\n"));
00524 return -1;
00525 }
00526
00527
00528
00529 if ( (sam_account_name = ads_get_samaccountname( ads, ctx, machine_name)) == NULL ) {
00530 DEBUG(0,("ads_keytab_add_entry: unable to determine machine account's name in AD!\n"));
00531 TALLOC_FREE( ctx );
00532 return -1;
00533 }
00534
00535
00536
00537
00538 strupper_m( sam_account_name );
00539
00540 if ( (ret = ads_keytab_add_entry(ads, sam_account_name )) != 0 ) {
00541 DEBUG(1,("ads_keytab_create_default: ads_keytab_add_entry failed while adding sAMAccountName (%s)\n",
00542 sam_account_name));
00543 return ret;
00544 }
00545
00546
00547
00548 upn = ads_get_upn( ads, ctx, machine_name);
00549 if ( upn ) {
00550 if ( (ret = ads_keytab_add_entry(ads, upn)) != 0 ) {
00551 DEBUG(1,("ads_keytab_create_default: ads_keytab_add_entry failed while adding UPN (%s)\n",
00552 upn));
00553 TALLOC_FREE( ctx );
00554 return ret;
00555 }
00556 }
00557
00558 TALLOC_FREE( ctx );
00559
00560
00561
00562 kvno = (krb5_kvno) ads_get_kvno(ads, machine_name);
00563 if (kvno == -1) {
00564 DEBUG(1,("ads_keytab_create_default: ads_get_kvno failed to determine the system's kvno.\n"));
00565 return -1;
00566 }
00567
00568 DEBUG(3,("ads_keytab_create_default: Searching for keytab entries to "
00569 "preserve and update.\n"));
00570
00571 ZERO_STRUCT(kt_entry);
00572 ZERO_STRUCT(cursor);
00573
00574 initialize_krb5_error_table();
00575 ret = krb5_init_context(&context);
00576 if (ret) {
00577 DEBUG(1,("ads_keytab_create_default: could not krb5_init_context: %s\n",error_message(ret)));
00578 return ret;
00579 }
00580 ret = krb5_kt_default(context, &keytab);
00581 if (ret) {
00582 DEBUG(1,("ads_keytab_create_default: krb5_kt_default failed (%s)\n",error_message(ret)));
00583 goto done;
00584 }
00585
00586 ret = krb5_kt_start_seq_get(context, keytab, &cursor);
00587 if (ret != KRB5_KT_END && ret != ENOENT ) {
00588 while ((ret = krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) == 0) {
00589 smb_krb5_kt_free_entry(context, &kt_entry);
00590 ZERO_STRUCT(kt_entry);
00591 found++;
00592 }
00593 }
00594 krb5_kt_end_seq_get(context, keytab, &cursor);
00595 ZERO_STRUCT(cursor);
00596
00597
00598
00599
00600
00601
00602
00603 DEBUG(3, ("ads_keytab_create_default: Found %d entries in the keytab.\n", found));
00604 if (!found) {
00605 goto done;
00606 }
00607 oldEntries = SMB_MALLOC_ARRAY(char *, found );
00608 if (!oldEntries) {
00609 DEBUG(1,("ads_keytab_create_default: Failed to allocate space to store the old keytab entries (malloc failed?).\n"));
00610 ret = -1;
00611 goto done;
00612 }
00613 memset(oldEntries, '\0', found * sizeof(char *));
00614
00615 ret = krb5_kt_start_seq_get(context, keytab, &cursor);
00616 if (ret != KRB5_KT_END && ret != ENOENT ) {
00617 while (krb5_kt_next_entry(context, keytab, &kt_entry, &cursor) == 0) {
00618 if (kt_entry.vno != kvno) {
00619 char *ktprinc = NULL;
00620 char *p;
00621
00622
00623 ret = smb_krb5_unparse_name(context, kt_entry.principal, &ktprinc);
00624 if (ret) {
00625 DEBUG(1,("smb_krb5_unparse_name failed (%s)\n", error_message(ret)));
00626 goto done;
00627 }
00628
00629
00630
00631
00632
00633 p = strchr_m(ktprinc, '@');
00634 if (p) {
00635 *p = '\0';
00636 }
00637
00638 p = strchr_m(ktprinc, '/');
00639 if (p) {
00640 *p = '\0';
00641 }
00642 for (i = 0; i < found; i++) {
00643 if (!oldEntries[i]) {
00644 oldEntries[i] = ktprinc;
00645 break;
00646 }
00647 if (!strcmp(oldEntries[i], ktprinc)) {
00648 SAFE_FREE(ktprinc);
00649 break;
00650 }
00651 }
00652 if (i == found) {
00653 SAFE_FREE(ktprinc);
00654 }
00655 }
00656 smb_krb5_kt_free_entry(context, &kt_entry);
00657 ZERO_STRUCT(kt_entry);
00658 }
00659 ret = 0;
00660 for (i = 0; oldEntries[i]; i++) {
00661 ret |= ads_keytab_add_entry(ads, oldEntries[i]);
00662 SAFE_FREE(oldEntries[i]);
00663 }
00664 krb5_kt_end_seq_get(context, keytab, &cursor);
00665 }
00666 ZERO_STRUCT(cursor);
00667
00668 done:
00669
00670 SAFE_FREE(oldEntries);
00671
00672 {
00673 krb5_keytab_entry zero_kt_entry;
00674 ZERO_STRUCT(zero_kt_entry);
00675 if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) {
00676 smb_krb5_kt_free_entry(context, &kt_entry);
00677 }
00678 }
00679 {
00680 krb5_kt_cursor zero_csr;
00681 ZERO_STRUCT(zero_csr);
00682 if ((memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) {
00683 krb5_kt_end_seq_get(context, keytab, &cursor);
00684 }
00685 }
00686 if (keytab) {
00687 krb5_kt_close(context, keytab);
00688 }
00689 if (context) {
00690 krb5_free_context(context);
00691 }
00692 return ret;
00693 }
00694 #endif