int smb_krb5_update_keytab(TALLOC_CTX *parent_ctx,
			   struct cli_credentials *machine_account,
			   struct smb_krb5_context *smb_krb5_context,
			   const char **enctype_strings,
			   struct keytab_container *keytab_container) 
{
	krb5_error_code ret;
	BOOL found_previous;
	TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
	if (!mem_ctx) {
		return ENOMEM;
	}

	ret = remove_old_entries(mem_ctx, machine_account, 
				 smb_krb5_context, keytab_container->keytab, &found_previous);
	if (ret != 0) {
		talloc_free(mem_ctx);
		return ret;
	}
	
	/* Create a new keytab.  If during the cleanout we found
	 * entires for kvno -1, then don't try and duplicate them.
	 * Otherwise, add kvno, and kvno -1 */
	
	ret = create_keytab(mem_ctx, machine_account, smb_krb5_context, 
			    enctype_strings, 
			    keytab_container->keytab, 
			    found_previous ? False : True);
	talloc_free(mem_ctx);
	return ret;
}
Exemple #2
0
krb5_error_code smb_krb5_update_keytab(TALLOC_CTX *parent_ctx,
                                       krb5_context context,
                                       const char *keytab_name,
                                       const char *samAccountName,
                                       const char *realm,
                                       const char **SPNs,
                                       int num_SPNs,
                                       const char *saltPrincipal,
                                       const char *new_secret,
                                       const char *old_secret,
                                       int kvno,
                                       uint32_t supp_enctypes,
                                       bool delete_all_kvno,
                                       krb5_keytab *_keytab,
                                       const char **error_string)
{
    krb5_keytab keytab;
    krb5_error_code ret;
    bool found_previous;
    TALLOC_CTX *tmp_ctx;
    krb5_principal *principals = NULL;

    if (keytab_name == NULL) {
        return ENOENT;
    }

    ret = krb5_kt_resolve(context, keytab_name, &keytab);
    if (ret) {
        *error_string = smb_get_krb5_error_message(context,
                        ret, parent_ctx);
        return ret;
    }

    DEBUG(5, ("Opened keytab %s\n", keytab_name));

    tmp_ctx = talloc_new(parent_ctx);
    if (!tmp_ctx) {
        return ENOMEM;
    }

    /* Get the principal we will store the new keytab entries under */
    ret = principals_from_list(tmp_ctx,
                               samAccountName, realm, SPNs, num_SPNs,
                               context, &principals, error_string);

    if (ret != 0) {
        *error_string = talloc_asprintf(parent_ctx,
                                        "Failed to load principals from ldb message: %s\n",
                                        *error_string);
        goto done;
    }

    ret = remove_old_entries(tmp_ctx, kvno, principals, delete_all_kvno,
                             context, keytab, &found_previous, error_string);
    if (ret != 0) {
        *error_string = talloc_asprintf(parent_ctx,
                                        "Failed to remove old principals from keytab: %s\n",
                                        *error_string);
        goto done;
    }

    if (!delete_all_kvno) {
        /* Create a new keytab.  If during the cleanout we found
         * entires for kvno -1, then don't try and duplicate them.
         * Otherwise, add kvno, and kvno -1 */

        ret = create_keytab(tmp_ctx,
                            samAccountName, realm, saltPrincipal,
                            kvno, new_secret, old_secret,
                            supp_enctypes, principals,
                            context, keytab,
                            found_previous ? false : true,
                            error_string);
        if (ret) {
            talloc_steal(parent_ctx, *error_string);
        }
    }

    if (ret == 0 && _keytab != NULL) {
        /* caller wants the keytab handle back */
        *_keytab = keytab;
    }

done:
    keytab_principals_free(context, principals);
    if (ret != 0 || _keytab == NULL) {
        krb5_kt_close(context, keytab);
    }
    talloc_free(tmp_ctx);
    return ret;
}