win32 dbus_connection_get_unix_user() problem

Havoc Pennington hp at redhat.com
Sun Mar 11 10:33:35 PDT 2007


Peter Kümmel wrote:
> Isn't the code full of things like this?
> 
> void
> bus_connection_disconnected (DBusConnection *connection)
> {
> ....
>   dbus_connection_set_unix_user_function (connection,
>                                           NULL, NULL, NULL);
> 
> ...
>           if (dbus_connection_get_unix_user (connection, &uid))
> 
> 
> Why is there no platform independent function call?
> All is only
> designed for unix (name of the function, type of uid), not in mind
> that there could be other systems than unix.

The reason there's no platform-independent call is because it's doing 
something that only works on one platform.

"Cross-platform" does not mean there is no platform-specific code. It 
means as much code as can be cross-platform is, and then there is 
platform-specific code suitable for each platform.

As I explained in the other email I just sent, I do not want a 
"DBusUser" abstraction in the public API or config file, because dbus is 
not the right place for a whole bunch of cross-platform user and file 
APIs. So in the public API and config file there should be 
platform-specific concepts to a certain extent.

In a binding like QtDBus, you would then convert those platform-native 
concepts into the Qt abstractions for users and files and so forth.

However, QtDBus can't convert "DBusUser" to anything sensible, and no 
app programmer wants to write their app using "DBusUser" as the concept 
of a user. What people need is the unix user id and windows sid, and 
then the other APIs they are using, whether Qt or platform-specific, 
will have functions and objects that operate on the unix user id and 
windows sid. None of the other APIs they are using will support 
operations with a "DBusUser"

*Internally* to DBus we can have DBusUser. The problem you're running 
into is that dbus-daemon uses the *public* API, so you need to have some 
platform-specific code to deal with platform-specific aspects of the 
public API. However, we should be able to deal with this. It is not 
rocket science.

> The problem is, that we've implemented the unix interface
> which is used all over the place, and now you are saying that you
> don't wanna have used this interface on Windows.

It's not my random "don't wanna" - it doesn't make any sense on Windows, 
because *there aren't any unix user ids on windows*

> My idea is to replace all this unix function with platform
> independent function calls.

You are welcome to do this as long as it does not introduce a DBusUser, 
DBusFile, etc. into the *public* API or config file, and as long as it 
*works*. Don't neglect the point that passing a process-specific made-up 
integer over the wire simply does not *work*.

> But your suggestion, when I understand it correctly,
> is that we should just add the windows function,
> e.g. dbus_connection_get_windows_user():
> 
...
>           if (dbus_connection_get_windows_user(connection, &uid))
>

Don't forget the other half of my suggestion, which is that Windows does 
not need this entire feature, because the system bus is bogus on 
Windows. So instead of doing this you can essentially just make the unix 
user stuff in bus/*.c get ignored when on Windows - reject any config 
file if the user attribute is anything other than user="*", and be sure 
user="*" works fine even if dbus_connection_get_unix_user returns false.

The places with unix in the public API are *intrinsically unix-specific* 
and simply don't make sense on Windows. My whole point is, don't port 
these; either make them no-ops if they make no sense on windows, or add 
windows-appropriate equivalent functionality.

> What happens when sometimes there is a new non-unix and non-windows
> system?

Then we will have to port to that system.

> Such a solution I would call a hack, the clean solution is
> to have a interface.

You cannot implement an interface on Windows that looks like:

  interface Connection {
    uid_t get_unix_user_id();
  }

To implement this on Windows would require what I'm calling "unix 
emulation" and it's just not what anyone wants. If I'm writing a windows 
app, I don't want a uid_t that only libdbus understands when on Windows, 
but happens to be the same as uid_t on unix. That leads to apps that 
work fine on unix and don't work on Windows.

What you could implement on Windows is this:

   interface Connection {
     DBusUserAbstractionObject get_user();
   }

*However* to interoperate with any other APIs or in any way use 
DBusUserAbstractionObject, people would need:

   interface DBusUserAbstractionObject {
     uid_t get_unix_user_id();
     sid get_windows_sid();
   }

We could keep people from needing get_unix_user_id/get_windows_sid if we 
had a bunch of cross-platform operations on the 
DBusUserAbstractionObject: get_full_name(), get_groups(), etc.

However, *nobody* is going to write their whole app using 
DBusUserAbstractionObject, because this does not belong in dbus. What 
people will do instead is convert the DBus stuff into their own user 
abstraction, whether found in Qt or app-specific.

Therefore, having a whole interface with get_full_name, get_groups, and 
so on in libdbus public API is just *broken*, nobody will use it except 
dbus itself. The right thing to have in libdbus public API is simply the 
unix user id and windows sid, and then people can *convert* those into 
whatever abstraction they are using.

We might have DBusUserAbstractionObject *inside* dbus, but it can't 
*leak out* or it's just bloat and confusing.

Since we use the user id in only one or two functions, simply offering 
windows and unix flavors that take either uid_t or an sid is by far the 
cleanest and simplest approach, compared to having a 
DBusUserAbstractionObject with only two methods 
(get_unix_id/get_windows_sid).

Havoc



More information about the dbus mailing list