GNOME Bugzilla – Bug 705029
Support for Solaris credentials
Last modified: 2013-10-04 13:58:07 UTC
Created attachment 250308 [details] [review] Proposed patch Here is a patch adding support for Solaris credentials in gio/gcredentials.c It is quite trivial, but Solaris uses transparent structure, so I create my own structure. For references see http://docs.oracle.com/cd/E26502_01/html/E29034/ucred-get-3c.html This also affects Solaris derivatives such as illumos and OpenIndiana. Without this patch all dbus clients (such as lightdm and pkexec) do not work :)
Review of attachment 250308 [details] [review]: Ooops, need to patch more files. Wait a minute.
Created attachment 250334 [details] [review] Proposed patch support for Solaris credentials
Test are not enabled, and setting uid does not work. But pkexec works!
Comment on attachment 250334 [details] [review] Proposed patch Cool. If possible, please submit patches in "git format-patch" format; see https://wiki.gnome.org/Git/Developers#Contributing_patches >+#if !defined(USE_SOLARIS_UCRED) >+# if defined(__sun__) || defined(__illumos__) || defined (__OpenSolaris_kernel__) >+# define USE_SOLARIS_UCRED >+# endif >+#endif It's ugly to have to add this in several different places; bug 701482 suggested some API additions to GCredentials, and I've added a suggestion there on how we can clean up all the #ifdefs to simplify things. > static void > g_credentials_finalize (GObject *object) > { >+#ifdef USE_SOLARIS_UCRED >+ GCredentials *credentials = G_CREDENTIALS (object); >+ ucred_free(credentials->native); >+#else > G_GNUC_UNUSED GCredentials *credentials = G_CREDENTIALS (object); >+#endif You could just get rid of the unused "credentials = ..." line in the non-solaris case. Also, there should be a space between "ucred_free" and "(". (Likewise in many other places throughout the patch.) > g_credentials_to_string (GCredentials *credentials) > { > GString *ret; >+#if defined(USE_SOLARIS_UCRED) >+#endif cruft. presumably leftover from an earlier version of the patch? >+ { >+ /* native is allocated in g_credentials_class_init(), >+ ucred_size() is constant until reboot. */ >+ memcpy (credentials->native, native, ucred_size()); >+ } Not totally sure about this... The man page says only: The ucred_size() function can be used to determine the size of the buffer needed to receive a credential option with SO_RECVUCRED. It doesn't explicitly say you can copy data from one ucred_t to another (and still have ucred_free() work correctly). Do you have a pointer to the source code for these functions? >+#elif defined(USE_SOLARIS_UCRED) >+ /* WHY? */ >+ ret = FALSE; We need to update the docs here (g_credentials_set_unix_user) to clarify that it will also return false on platforms that don't allow you to spoof credentials. >+ g_set_error (error, >+ G_IO_ERROR, >+ errno, >+ _("Unable to get pending error: %s"), >+ strerror (errno)); That error message is wrong, but I see you just copied it from the existing g_socket_get_credentials() code, which is also wrong. (It was copied+pasted from elsewhere and then not rewritten.) Anyway, you should just merge this case with the other one. Note that you can't just use errno as the error number, because using G_IO_ERROR means that the error code should be a GIOErrorEnum, not an errno value. >+ g_credentials_set_native (credentials, G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED, ucred); (in g_unix_credentials_message_deserialize()). Should be SOLARIS_UCRED of course.
>> g_credentials_to_string (GCredentials *credentials) >> { >> GString *ret; >>+#if defined(USE_SOLARIS_UCRED) >>+#endif > cruft. presumably leftover from an earlier version of the patch? Yep, moved :id_t id;" >>+ { >>+ /* native is allocated in g_credentials_class_init(), >>+ ucred_size() is constant until reboot. */ >>+ memcpy (credentials->native, native, ucred_size()); >>+ } > Not totally sure about this... "ucred_t" is "struct ucred_s" which is a header for ucred data. From /usr/include/sys/ucred.h: 55 #if defined(_KERNEL) || _STRUCTURED_PROC != 0 56 /* 57 * bitness neutral struct 58 * 59 * Add new fixed fields at the end of the structure. 60 */ 61 struct ucred_s { 62 uint32_t uc_size; /* Size of the full structure */ 63 uint32_t uc_credoff; /* Credential offset: 0 - no cred */ 64 uint32_t uc_privoff; /* Privilege offset: 0 - no privs */ 65 pid_t uc_pid; /* Process id */ 66 uint32_t uc_audoff; /* Audit info offset: 0 - no aud */ 67 zoneid_t uc_zoneid; /* Zone id */ 68 projid_t uc_projid; /* Project id */ 69 uint32_t uc_labeloff; /* label offset: 0 - no label */ 70 /* The rest goes here */ 71 }; From illumos libc :-) void ucred_free(ucred_t *uc) { free(uc); }
can you try the wip/danw/creds branch in git and see if it still compiles and works for you? (and if credentials and gdbus-peer tests in gio/tests/ pass)
(In reply to comment #6) > can you try the wip/danw/creds branch in git and see if it still compiles and > works for you? (and if credentials and gdbus-peer tests in gio/tests/ pass) Thanks! I had to patch credentials test, see glib-creds-solaris-test.patch. gdbus-peer test fails: ./gio/tests/gdbus-peer.c:184:test_interface_method_call: assertion failed: (fd != -1)
Created attachment 255493 [details] [review] glib-creds-solaris-test.patch
Fixed in master, will probably end up in glib-2-38