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