微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

绑定后套接字从SOCK_STREAM更改为SOCK_DGRAM?

如何解决绑定后套接字从SOCK_STREAM更改为SOCK_DGRAM?

在Linux机器上,即使我使用PAM设置了kwallet(KDE的一部分)程序,我也无法在登录时启动它,所以我检查了源代码以诊断问题。事实证明,该程序创建了一个服务器,该服务器侦听绑定到文件的TCP套接字。

但是问题是,虽然套接字在首次实例化时是TCP套接字,但是一旦绑定到文件,它突然变成了UDP套接字,因此监听它的调用失败。

任何人都知道这里发生了什么吗?我只是安装有问题吗?

以下是相关代码,我添加了一些代码来帮助诊断问题:

static void execute_kwallet(pam_handle_t *pamh,struct passwd *userInfo,int toWalletPipe[2],char *fullSocket)
{
    //In the child pam_syslog does not work,using syslog directly
    //keep stderr open so socket doesn't returns us that fd
    int x = 3;
    //Close fd that are not of interest of kwallet
    for (; x < 64; ++x) {
        if (x != toWalletPipe[0]) {
            close (x);
        }
    }

    //This is the side of the pipe PAM will send the hash to
    close (toWalletPipe[1]);

    //Change to the user in case we are not it yet
    if (drop_privileges(userInfo) < 0) {
        syslog(LOG_ERR,"%s: Could not set gid/uid/euid/egit for kwalletd",logPrefix);
        free(fullSocket);
        goto cleanup;
    }

    int envSocket;
    if ((envSocket = socket(AF_UNIX,SOCK_STREAM,0)) == -1) {
        syslog(LOG_ERR,"%s: Couldn't create socket",logPrefix);
        free(fullSocket);
        goto cleanup;
    }

    int socket_type;
    socklen_t optlen;

    optlen = sizeof socket_type;
    if(getsockopt(envSocket,SOL_SOCKET,SO_TYPE,&socket_type,&optlen) < 0) {
      syslog(LOG_INFO,"%s-Couldn't read socket option: %d-%s\n",logPrefix,errno,strerror(errno));
    } else {
      syslog(LOG_INFO,"%s-Socket type is %d\n",socket_type);
      if(socket_type != SOCK_STREAM)
        syslog(LOG_INFO,"%s-Socket is not SOCK_STREAM.\n",logPrefix);
    }

    struct sockaddr_un local;
    local.sun_family = AF_UNIX;

    if (strlen(fullSocket) > sizeof(local.sun_path)) {
        syslog(LOG_ERR,"%s: socket path %s too long to open",fullSocket);
        free(fullSocket);
        goto cleanup;
    }
    strcpy(local.sun_path,fullSocket);
    free(fullSocket);
    fullSocket = NULL;
    unlink(local.sun_path);//Just in case it exists from a prevIoUs login

    syslog(LOG_DEBUG,"%s: final socket path: %s",local.sun_path);

    size_t len = strlen(local.sun_path) + sizeof(local.sun_family);
    if (bind(envSocket,(struct sockaddr *)&local,len) == -1) {
        syslog(LOG_INFO,"%s-kwalletd: Couldn't bind to local file\n",logPrefix);
        goto cleanup;
    }

    optlen = sizeof socket_type;
    if(getsockopt(envSocket,logPrefix);
    }

    if (listen(envSocket,5) == -1) {
        syslog(LOG_INFO,"%s-kwalletd: Couldn't listen in socket: %d-%s\n",strerror(errno));
        goto cleanup;
    }
    //finally close stderr
    close(2);

    // Fork twice to daemonize kwallet
    setsid();
    pid_t pid = fork();
    if (pid != 0) {
        if (pid == -1) {
            exit(EXIT_FAILURE);
        } else {
            exit(0);
        }
    }

    //Todo use a pam argument for full path kwalletd
    char pipeInt[4];
    sprintf(pipeInt,"%d",toWalletPipe[0]);
    char sockIn[4];
    sprintf(sockIn,envSocket);

    char *args[] = {strdup(kwalletd),"--pam-login",pipeInt,sockIn,NULL,NULL};
    execve(args[0],args,pam_getenvlist(pamh));
    syslog(LOG_ERR,"%s: Could not execute kwalletd from %s",kwalletd);

cleanup:
    exit(EXIT_FAILURE);
}

这是日志输出

Oct 12 19:31:28 fuji login[413]: pam_kwallet5-Socket type is 1
Oct 12 19:31:28 fuji login[413]: pam_kwallet5: final socket path: /run/user/1000/kwallet5.socket
Oct 12 19:31:28 fuji login[413]: pam_kwallet5-Socket type is 2
Oct 12 19:31:28 fuji login[413]: pam_kwallet5-Socket is not SOCK_STREAM.
Oct 12 19:31:28 fuji login[413]: pam_kwallet5-kwalletd: Couldn't listen in socket: 95-Operation not supported

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。