对 krb5 库使用 jdk.incubator.foreign。调用 kadm5_init_with_skey 返回 43787552 值

问题描述 投票:0回答:0

你能帮我弄清楚我的代码有什么问题吗:

所以我需要获取 KDC 中的主体列表,我想使用 krb5 库。一开始我需要使用 keytab 初始化上下文和会话,为此我使用

kadm5_init_krb5_context
kadm5_init_with_skey
函数(here)我正在使用 jdk17 和 jdk.incubator.foreign.

我的代码:

private static void kadminInitWithKeytab(MemorySegment segmentForkadm5ServerHandle) throws Throwable {
    var linker = CLinker.getInstance();
    System.load("/usr/local/opt/krb5/bin/kadmin");
    var loaderLookup = SymbolLookup.loaderLookup();

    ResourceScope scope = ResourceScope.newImplicitScope()
    MemorySegment segmentForContext = MemorySegment.allocateNative(10000,
      ResourceScope.newImplicitScope()); // segment for context
    MemoryAddress addressSegmentForContext = segmentForContext.address();

    initContext(addressSegmentForContext); // Initialize context

    MemorySegment segmentForConfigParams = MemorySegment.allocateNative(10000,
      ResourceScope.newImplicitScope());

    MemorySegment segmentForDbArgs = MemorySegment.allocateNative(10000,
      ResourceScope.newImplicitScope());

    int kadmStructVersion1 = 0x01;
    int apiVersion = 0x04;

    String clientName = "client/admin@SOME_REALM";
    MemorySegment cClientName = CLinker.toCString(clientName, scope);

    String keytabName = "/some_path_to_keytab.keytab";
    MemorySegment ckeytabName = CLinker.toCString(keytabName, scope);

    String serviceName = "some_service_name";
    MemorySegment cServiceName = CLinker.toCString(serviceName, scope);

    MemoryAddress kadminInitWithKeytabFunction = loaderLookup.lookup("kadm5_init_with_skey").get();
    MethodHandle kadminInitWithKeytabHandle = linker.downcallHandle(kadminInitWithKeytabFunction,
      MethodType.methodType(
        long.class,
        MemoryAddress.class,
        MemoryAddress.class,
        MemoryAddress.class,
        MemoryAddress.class,
        MemoryAddress.class,
        int.class,
        int.class,
        MemoryAddress.class,
        MemoryAddress.class),
      FunctionDescriptor.of(
        CLinker.C_LONG,          // return type
        CLinker.C_POINTER,       // context
        CLinker.C_POINTER,       // client_name argument
        CLinker.C_POINTER,       // keytab argument
        CLinker.C_POINTER,       // service_name argument
        CLinker.C_POINTER,       // params argument
        CLinker.C_INT,           // struct_version argument
        CLinker.C_INT,           // api_version argument
        CLinker.C_POINTER,      // db_args argument
        CLinker.C_POINTER        // server_handle_out argument
      ));

      var result = kadminInitWithKeytabHandle.invoke( // this result is 43787552 instead of 0
        addressSegmentForContext.address(),
        cClientName.address(),
        ckeytabName.address(),
        cServiceName.address(),
        segmentForConfigParams.address(),
        kadmStructVersion1,
        apiVersion,
        segmentForDbArgs.address(),
        segmentForkadm5ServerHandle.address());
}

 private static void initContext(MemoryAddress addressForContext) throws Throwable {
    var linker = CLinker.getInstance();
    System.load("/usr/local/opt/krb5/bin/kadmin");
    var loaderLookup  = SymbolLookup.loaderLookup();

    MemoryAddress initContextFunction = loaderLookup.lookup("kadm5_init_krb5_context").get();
    MethodHandle initContextHandle = linker.downcallHandle(initContextFunction,
      MethodType.methodType(long.class, MemoryAddress.class),
      FunctionDescriptor.of(CLinker.C_LONG, CLinker.C_POINTER)
    );
    var result = initContextHandle.invoke(addressForContext.address()); //here result is 0 as expected
  }

所以

kadminInitWithKeytabHandle.invoke
的预期结果应该是 0 但现在是 43787552 这意味着发生了一些错误但似乎 43787552 不是 kerberos 错误。也许有人知道可能是什么原因或我应该注意什么?我怎样才能弄清楚这是什么类型的错误?

java c kerberos
© www.soinside.com 2019 - 2024. All rights reserved.