Win32 port

Peter Kümmel syntheticpp at gmx.net
Wed Jun 28 07:11:41 PDT 2006


Havoc Pennington wrote:
> 
> You could also just go with the "keep the uid as integer on all
> platforms" approach which is probably fine.
> 

Attached a proposal for such a solution. It uses the 'quark'
functions from windows and the strings are freed when the
hash table is deleted.

>From the outer you only see the two sid<->uid_t mapping functions.


Peter
-------------- next part --------------
Index: dbus-sysdeps.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-sysdeps.h,v
retrieving revision 1.49
diff -u -b -B -r1.49 dbus-sysdeps.h
--- dbus-sysdeps.h	8 Jul 2005 14:36:22 -0000	1.49
+++ dbus-sysdeps.h	28 Jun 2006 13:46:59 -0000
@@ -27,7 +27,14 @@
 
 #include <config.h>
 
+#if defined(_WIN32) || defined(_WIN64)
+#define DBUS_WIN
+#else
+#define DBUS_UNIX
+#endif
+
 #include <dbus/dbus-errors.h>

 
 /* this is perhaps bogus, but strcmp() etc. are faster if we use the
  * stuff straight out of string.h, so have this here for now.

@@ -99,6 +107,50 @@
 #define DBUS_UID_FORMAT "%lu"
 #define DBUS_GID_FORMAT "%lu"
 
+#ifdef DBUS_UNIX
+
+#else
+
+dbus_uid_t  _dbus_win_sid_to_uid_t (void        *psid);        
+
+void        _dbus_win_uid_t_to_sid (dbus_uid_t   uid, 
+                                    void       **ppsid);
+
+#endif //DBUS_UNIX

 /**
  * Struct representing socket credentials
  */
@@ -179,9 +231,14 @@
 
 
 unsigned long _dbus_getpid (void);
 dbus_uid_t    _dbus_getuid (void);
+dbus_uid_t    _dbus_getuid_unix (void);
+dbus_uid_t    _dbus_getuid_win  (void);
 dbus_gid_t    _dbus_getgid (void);
 
 typedef struct DBusAtomic DBusAtomic;
 
 /**

   else


Index: dbus-internals.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-internals.h,v
retrieving revision 1.55
diff -u -b -B -r1.55 dbus-internals.h
--- dbus-internals.h	26 Feb 2005 06:37:46 -0000	1.55
+++ dbus-internals.h	28 Jun 2006 13:46:55 -0000
@@ -270,6 +273,10 @@
 #define _DBUS_LOCK(name)                _dbus_mutex_lock   (_dbus_lock_##name)
 #define _DBUS_UNLOCK(name)              _dbus_mutex_unlock (_dbus_lock_##name)
 
+#ifdef _WIN32
+_DBUS_DECLARE_GLOBAL_LOCK (win32_fds);
+_DBUS_DECLARE_GLOBAL_LOCK (sid_atom_cache);
+#endif
 _DBUS_DECLARE_GLOBAL_LOCK (list);
 _DBUS_DECLARE_GLOBAL_LOCK (connection_slots);
 _DBUS_DECLARE_GLOBAL_LOCK (pending_call_slots);
@@ -281,7 +288,11 @@
 _DBUS_DECLARE_GLOBAL_LOCK (system_users);
 _DBUS_DECLARE_GLOBAL_LOCK (message_cache);
 _DBUS_DECLARE_GLOBAL_LOCK (shared_connections);
+#ifdef _WIN32
+#define _DBUS_N_GLOBAL_LOCKS (13)
+#else
 #define _DBUS_N_GLOBAL_LOCKS (11)
+#endif
 
 dbus_bool_t _dbus_threads_init_debug (void);
 

Index: dbus-sysdeps.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-sysdeps.c,v
retrieving revision 1.102
diff -u -b -B -r1.102 dbus-sysdeps.c
--- dbus-sysdeps.c	30 May 2006 15:34:10 -0000	1.102
+++ dbus-sysdeps.c	28 Jun 2006 13:46:59 -0000
@@ -3,6 +3,7 @@
  * 
  * Copyright (C) 2002, 2003  Red Hat, Inc.
  * Copyright (C) 2003 CodeFactory AB
+ * Copyright (C) 2005 Novell, Inc.
  *
  * Licensed under the Academic Free License version 2.1
  * 
@@ -26,28 +27,37 @@
 #include "dbus-sysdeps.h"
 #include "dbus-threads.h"
 #include "dbus-protocol.h"
+#include "dbus-hash.h"
+#include "dbus-sockets.h"
 #include "dbus-string.h"
 #include <sys/types.h>
 #include <stdlib.h>
 #include <string.h>
 #include <signal.h>
-#include <unistd.h>
 #include <stdio.h>
 #include <errno.h>
 #include <fcntl.h>
-#include <sys/socket.h>
 #include <dirent.h>
-#include <sys/un.h>
+#include <locale.h>
+#include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+#ifdef HAVE_PWD_H
 #include <pwd.h>
+#endif
+#ifdef HAVE_TIME_H
 #include <time.h>
-#include <locale.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
-#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
 #include <sys/wait.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <grp.h>
+#endif
+
 #ifdef HAVE_WRITEV
 #include <sys/uio.h>
 #endif
@@ -60,7 +70,28 @@
 #ifdef HAVE_GETPEERUCRED
 #include <ucred.h>
 #endif
+#ifdef DBUS_WIN
+#include <ctype.h>
+#include <malloc.h>
+#include <windows.h>
+#include <aclapi.h>
+#include <lm.h>
+
+/* Declarations missing in mingw's headers */
+extern BOOL WINAPI ConvertStringSidToSidA (LPCSTR  StringSid,
+					   PSID   *Sid);
+extern BOOL WINAPI ConvertSidToStringSidA (PSID    Sid,
+					   LPSTR  *StringSid);
+#include <io.h>
+#include <share.h>
+
+#endif
 
+#endif
 #ifndef O_BINARY
 #define O_BINARY 0
 #endif
@@ -69,6 +100,67 @@
 #define socklen_t int
 #endif
 
+#ifdef DBUS_WIN
+
+
+static DBusHashTable *sid_atom_cache = NULL;
+
+_DBUS_DEFINE_GLOBAL_LOCK (sid_atom_cache);
+
+#endif

 /**
  * @addtogroup DBusInternalsUtils
  * @{


 /**
@@ -1830,26 +2751,91 @@
 unsigned long
 _dbus_getpid (void)
 {
+#ifdef DBUS_UNIX
   return getpid ();
+#else
+  return GetCurrentProcessId ();
+#endif
 }
 
 /** Gets our UID
- * @returns process UID
+ * @returns process user identifier
  */
 dbus_uid_t
 _dbus_getuid (void)
 {
-  return getuid ();
+#ifdef DBUS_UNIX
+  return _dbus_getuid_unix ();
+#else
+  return _dbus_getuid_win ();
+#endif
+}
+
+#ifdef DBUS_UNIX
+dbus_uid_t
+_dbus_getuid_unix (void)
+{
+	return getuid();
+}
+#else
+
+dbus_uid_t
+_dbus_getuid_win (void)
+{
+  dbus_uid_t retval = DBUS_UID_UNSET;
+  HANDLE process_token = NULL;
+  TOKEN_USER *token_user = NULL;
+  DWORD n;
+
+  if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &process_token))
+    _dbus_win_warn_win_error ("OpenProcessToken failed", GetLastError ());
+  else if ((!GetTokenInformation (process_token, TokenUser, NULL, 0, &n) 
+	        && GetLastError () != ERROR_INSUFFICIENT_BUFFER) 
+               || (token_user = alloca (n)) == NULL 
+               || !GetTokenInformation (process_token, TokenUser, token_user, n, &n))
+    _dbus_win_warn_win_error ("GetTokenInformation failed", GetLastError ());
+  else
+    retval = _dbus_win_sid_to_uid_t (token_user->User.Sid);
+
+  if (process_token != NULL)
+    CloseHandle (process_token);
+
+  _dbus_verbose("_dbus_getuid()=%d\n",retval);
+  return retval;
 }
+#endif
+
+static void
+_sid_atom_cache_shutdown_win (void *unused)
+{
+ DBusHashIter iter;
+ _DBUS_LOCK (sid_atom_cache);
+ _dbus_hash_iter_init (sid_atom_cache, &iter);
+ while (_dbus_hash_iter_next (&iter))
+   {
+     ATOM atom;
+     atom = (ATOM) _dbus_hash_iter_get_value (&iter);
+     GlobalDeleteAtom(atom);
+     _dbus_hash_iter_remove_entry(&iter);
+   }
+  _DBUS_UNLOCK (sid_atom_cache);
+  _dbus_hash_table_unref (sid_atom_cache);
+  sid_atom_cache = NULL;
+}
+  
+/**
+ * Returns the 2-way associated dbus_uid_t form a SID.
+ *
+ * @param psid pointer to the SID
+ */
+dbus_uid_t
+_dbus_win_sid_to_uid_t (PSID psid)
+{
+  dbus_uid_t uid;
+  dbus_uid_t olduid;
+  char *string;
+  ATOM atom;
+  
+  if (!IsValidSid (psid)) 
+    {
+      _dbus_verbose("%s invalid sid\n",__FUNCTION__);
+      return DBUS_UID_UNSET;
+    }  
+  if (!ConvertSidToStringSidA (psid, &string)) 
+    {
+      _dbus_verbose("%s invalid sid\n",__FUNCTION__);
+      return DBUS_UID_UNSET;
+    }
+
+  atom = GlobalAddAtom(string);
+
+  if (atom == 0)
+    {
+      _dbus_verbose("%s GlobalAddAtom failed\n",__FUNCTION__);
+      LocalFree (string);
+      return DBUS_UID_UNSET;
+    }
+
+  _DBUS_LOCK (sid_atom_cache);
+
+  if (sid_atom_cache == NULL)
+    {
+      sid_atom_cache = _dbus_hash_table_new (DBUS_HASH_ULONG, NULL, NULL);
+      _dbus_register_shutdown_func (_sid_atom_cache_shutdown_win, NULL);
+    }
+
+  uid = atom;
+  olduid = (dbus_uid_t) _dbus_hash_table_lookup_ulong (sid_atom_cache, uid);
+
+  if (olduid)
+    {
+      _dbus_verbose("%s sid %s found in cache\n",__FUNCTION__, olduid);
+      uid = olduid;
+    }
+  else
+    {
+      _dbus_hash_table_insert_ulong (sid_atom_cache, olduid, (void*) olduid);
+      _dbus_verbose("%s sid %s added with uid %i to cache\n",__FUNCTION__, string, olduid);
+    }
+
+  _DBUS_UNLOCK (sid_atom_cache);
+
+  return olduid;
+}
+
+void  _dbus_win_uid_t_to_sid (dbus_uid_t uid, PSID *ppsid)
+{
+  void* atom;
+  char string[255];
+
+  atom = _dbus_hash_table_lookup_ulong (sid_atom_cache, uid);
+  if (atom == NULL)
+	{
+      _dbus_verbose("%s uid %i not found in cache\n",__FUNCTION__,uid);
+      return;
+    }
+  memset( string, '.', sizeof(string) );
+  if (!GlobalGetAtomNameA( (ATOM) atom, string, 255 ))
+    {
+      _dbus_verbose("%s uid %i not found in cache\n",__FUNCTION__, uid);
+      return;
+    }
+  if (!ConvertStringSidToSidA(string, ppsid))
+    {
+      _dbus_verbose("%s could not convert %s into sid \n",__FUNCTION__, string);
+      return;
+    }
+  _dbus_verbose("%s converted %s into sid \n",__FUNCTION__, string);
+}
+
+#endif
+
 /** @} end of sysdeps */
 
 /* tests in dbus-sysdeps-util.c */
Index: dbus-threads.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-threads.c,v
retrieving revision 1.23
diff -u -b -B -r1.23 dbus-threads.c
--- dbus-threads.c	26 Feb 2005 06:37:46 -0000	1.23
+++ dbus-threads.c	28 Jun 2006 13:46:59 -0000
@@ -222,6 +222,10 @@
   
   DBusMutex **global_locks[] = {
 #define LOCK_ADDR(name) (& _dbus_lock_##name)
+#ifdef DBUS_WIN
+    LOCK_ADDR (win32_fds),
+    LOCK_ADDR (sid_atom_cache),
+#endif
     LOCK_ADDR (list),
     LOCK_ADDR (connection_slots),
     LOCK_ADDR (pending_call_slots),




More information about the dbus mailing list