Different order for getsockopt SO_PEERCRED in Linux and OpenBSD

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












2















I'm trying to get the Unix socket peer credentials in python.



I am using this piece of code for that:



peercred = conn.getsockopt(socket.SOL_SOCKET, socket.SO_PEERCRED, struct.calcsize("3i"))
pid, uid, gid = struct.unpack("3i", peercred)


This works correctly in Linux, but in OpenBSD the order is different.
In OpenBsd the order is [uid, gid, pid] instead.



What is causing this difference? How do I know when to use which order?



The linux systems I tried were running on a x86_64 architecture and the openbsd system was on a amd64 architecture.










share|improve this question


























    2















    I'm trying to get the Unix socket peer credentials in python.



    I am using this piece of code for that:



    peercred = conn.getsockopt(socket.SOL_SOCKET, socket.SO_PEERCRED, struct.calcsize("3i"))
    pid, uid, gid = struct.unpack("3i", peercred)


    This works correctly in Linux, but in OpenBSD the order is different.
    In OpenBsd the order is [uid, gid, pid] instead.



    What is causing this difference? How do I know when to use which order?



    The linux systems I tried were running on a x86_64 architecture and the openbsd system was on a amd64 architecture.










    share|improve this question
























      2












      2








      2








      I'm trying to get the Unix socket peer credentials in python.



      I am using this piece of code for that:



      peercred = conn.getsockopt(socket.SOL_SOCKET, socket.SO_PEERCRED, struct.calcsize("3i"))
      pid, uid, gid = struct.unpack("3i", peercred)


      This works correctly in Linux, but in OpenBSD the order is different.
      In OpenBsd the order is [uid, gid, pid] instead.



      What is causing this difference? How do I know when to use which order?



      The linux systems I tried were running on a x86_64 architecture and the openbsd system was on a amd64 architecture.










      share|improve this question














      I'm trying to get the Unix socket peer credentials in python.



      I am using this piece of code for that:



      peercred = conn.getsockopt(socket.SOL_SOCKET, socket.SO_PEERCRED, struct.calcsize("3i"))
      pid, uid, gid = struct.unpack("3i", peercred)


      This works correctly in Linux, but in OpenBSD the order is different.
      In OpenBsd the order is [uid, gid, pid] instead.



      What is causing this difference? How do I know when to use which order?



      The linux systems I tried were running on a x86_64 architecture and the openbsd system was on a amd64 architecture.







      linux python openbsd unix-sockets






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Jan 24 at 23:34









      TroidoTroido

      484




      484




















          2 Answers
          2






          active

          oldest

          votes


















          3














          I'm no python programmer, but I guess you should special case your code based on sys.platform.



          SO_PEERCRED is not a standardized interface, and the actual structure / binary interface is different between the systems.



          On Linux, as defined in /usr/include/bits/socket.h:



          struct ucred 
          __u32 pid;
          __u32 uid;
          __u32 gid;
          ;


          On OpenBSD, as defined in /usr/include/sys/socket.h:



          struct sockpeercred 
          uid_t uid; /* effective user id */
          gid_t gid; /* effective group id */
          pid_t pid;
          ;


          (uid_t, gid_t and pid_t are also 32bit on OpenBSD)



          Other systems (eg. solaris, FreeBSD) have a completely different interface -- for some code that gets the peer credentials in a "system-independent" manner you could look at the update_client_creds() function from the heimdal source code (which is using the getpeereid(3) library function on OpenBSD and FreeBSD instead of directly SO_PEERCRED or LOCAL_PEERCRED).



          In any case, the credentials got this way will be those of the process that called connect(2) or listen(2) on the socket (a process that may no longer exist), not necessarily those of the process actually using the socket by writing to or reading from it.






          share|improve this answer
































            1














            You could use cffi and the "API level" approach. This requires a C compiler, although it is possible to do the compiling on a compatible system and then re-use the result.



            https://cffi.readthedocs.io/en/latest/overview.html#api-mode-calling-the-c-standard-library




            Note that this works independently of the exact C layout of struct passwd (it is “API level”, as opposed to “ABI level”).







            share|improve this answer
























              Your Answer








              StackExchange.ready(function()
              var channelOptions =
              tags: "".split(" "),
              id: "106"
              ;
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function()
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled)
              StackExchange.using("snippets", function()
              createEditor();
              );

              else
              createEditor();

              );

              function createEditor()
              StackExchange.prepareEditor(
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: false,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              imageUploader:
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              ,
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );













              draft saved

              draft discarded


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f496577%2fdifferent-order-for-getsockopt-so-peercred-in-linux-and-openbsd%23new-answer', 'question_page');

              );

              Post as a guest















              Required, but never shown

























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              3














              I'm no python programmer, but I guess you should special case your code based on sys.platform.



              SO_PEERCRED is not a standardized interface, and the actual structure / binary interface is different between the systems.



              On Linux, as defined in /usr/include/bits/socket.h:



              struct ucred 
              __u32 pid;
              __u32 uid;
              __u32 gid;
              ;


              On OpenBSD, as defined in /usr/include/sys/socket.h:



              struct sockpeercred 
              uid_t uid; /* effective user id */
              gid_t gid; /* effective group id */
              pid_t pid;
              ;


              (uid_t, gid_t and pid_t are also 32bit on OpenBSD)



              Other systems (eg. solaris, FreeBSD) have a completely different interface -- for some code that gets the peer credentials in a "system-independent" manner you could look at the update_client_creds() function from the heimdal source code (which is using the getpeereid(3) library function on OpenBSD and FreeBSD instead of directly SO_PEERCRED or LOCAL_PEERCRED).



              In any case, the credentials got this way will be those of the process that called connect(2) or listen(2) on the socket (a process that may no longer exist), not necessarily those of the process actually using the socket by writing to or reading from it.






              share|improve this answer





























                3














                I'm no python programmer, but I guess you should special case your code based on sys.platform.



                SO_PEERCRED is not a standardized interface, and the actual structure / binary interface is different between the systems.



                On Linux, as defined in /usr/include/bits/socket.h:



                struct ucred 
                __u32 pid;
                __u32 uid;
                __u32 gid;
                ;


                On OpenBSD, as defined in /usr/include/sys/socket.h:



                struct sockpeercred 
                uid_t uid; /* effective user id */
                gid_t gid; /* effective group id */
                pid_t pid;
                ;


                (uid_t, gid_t and pid_t are also 32bit on OpenBSD)



                Other systems (eg. solaris, FreeBSD) have a completely different interface -- for some code that gets the peer credentials in a "system-independent" manner you could look at the update_client_creds() function from the heimdal source code (which is using the getpeereid(3) library function on OpenBSD and FreeBSD instead of directly SO_PEERCRED or LOCAL_PEERCRED).



                In any case, the credentials got this way will be those of the process that called connect(2) or listen(2) on the socket (a process that may no longer exist), not necessarily those of the process actually using the socket by writing to or reading from it.






                share|improve this answer



























                  3












                  3








                  3







                  I'm no python programmer, but I guess you should special case your code based on sys.platform.



                  SO_PEERCRED is not a standardized interface, and the actual structure / binary interface is different between the systems.



                  On Linux, as defined in /usr/include/bits/socket.h:



                  struct ucred 
                  __u32 pid;
                  __u32 uid;
                  __u32 gid;
                  ;


                  On OpenBSD, as defined in /usr/include/sys/socket.h:



                  struct sockpeercred 
                  uid_t uid; /* effective user id */
                  gid_t gid; /* effective group id */
                  pid_t pid;
                  ;


                  (uid_t, gid_t and pid_t are also 32bit on OpenBSD)



                  Other systems (eg. solaris, FreeBSD) have a completely different interface -- for some code that gets the peer credentials in a "system-independent" manner you could look at the update_client_creds() function from the heimdal source code (which is using the getpeereid(3) library function on OpenBSD and FreeBSD instead of directly SO_PEERCRED or LOCAL_PEERCRED).



                  In any case, the credentials got this way will be those of the process that called connect(2) or listen(2) on the socket (a process that may no longer exist), not necessarily those of the process actually using the socket by writing to or reading from it.






                  share|improve this answer















                  I'm no python programmer, but I guess you should special case your code based on sys.platform.



                  SO_PEERCRED is not a standardized interface, and the actual structure / binary interface is different between the systems.



                  On Linux, as defined in /usr/include/bits/socket.h:



                  struct ucred 
                  __u32 pid;
                  __u32 uid;
                  __u32 gid;
                  ;


                  On OpenBSD, as defined in /usr/include/sys/socket.h:



                  struct sockpeercred 
                  uid_t uid; /* effective user id */
                  gid_t gid; /* effective group id */
                  pid_t pid;
                  ;


                  (uid_t, gid_t and pid_t are also 32bit on OpenBSD)



                  Other systems (eg. solaris, FreeBSD) have a completely different interface -- for some code that gets the peer credentials in a "system-independent" manner you could look at the update_client_creds() function from the heimdal source code (which is using the getpeereid(3) library function on OpenBSD and FreeBSD instead of directly SO_PEERCRED or LOCAL_PEERCRED).



                  In any case, the credentials got this way will be those of the process that called connect(2) or listen(2) on the socket (a process that may no longer exist), not necessarily those of the process actually using the socket by writing to or reading from it.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Jan 25 at 5:45

























                  answered Jan 25 at 1:35









                  mosvymosvy

                  7,5321530




                  7,5321530























                      1














                      You could use cffi and the "API level" approach. This requires a C compiler, although it is possible to do the compiling on a compatible system and then re-use the result.



                      https://cffi.readthedocs.io/en/latest/overview.html#api-mode-calling-the-c-standard-library




                      Note that this works independently of the exact C layout of struct passwd (it is “API level”, as opposed to “ABI level”).







                      share|improve this answer





























                        1














                        You could use cffi and the "API level" approach. This requires a C compiler, although it is possible to do the compiling on a compatible system and then re-use the result.



                        https://cffi.readthedocs.io/en/latest/overview.html#api-mode-calling-the-c-standard-library




                        Note that this works independently of the exact C layout of struct passwd (it is “API level”, as opposed to “ABI level”).







                        share|improve this answer



























                          1












                          1








                          1







                          You could use cffi and the "API level" approach. This requires a C compiler, although it is possible to do the compiling on a compatible system and then re-use the result.



                          https://cffi.readthedocs.io/en/latest/overview.html#api-mode-calling-the-c-standard-library




                          Note that this works independently of the exact C layout of struct passwd (it is “API level”, as opposed to “ABI level”).







                          share|improve this answer















                          You could use cffi and the "API level" approach. This requires a C compiler, although it is possible to do the compiling on a compatible system and then re-use the result.



                          https://cffi.readthedocs.io/en/latest/overview.html#api-mode-calling-the-c-standard-library




                          Note that this works independently of the exact C layout of struct passwd (it is “API level”, as opposed to “ABI level”).








                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Jan 25 at 2:00

























                          answered Jan 25 at 1:54









                          sourcejedisourcejedi

                          24.2k439106




                          24.2k439106



























                              draft saved

                              draft discarded
















































                              Thanks for contributing an answer to Unix & Linux Stack Exchange!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid


                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.

                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f496577%2fdifferent-order-for-getsockopt-so-peercred-in-linux-and-openbsd%23new-answer', 'question_page');

                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown






                              Popular posts from this blog

                              How to check contact read email or not when send email to Individual?

                              Displaying single band from multi-band raster using QGIS

                              How many registers does an x86_64 CPU actually have?