Index: wmi-1.3.13/Samba/source/wmi/winsmb.c
===================================================================
--- wmi-1.3.13/Samba/source/wmi/winsmb.c	(revision 0)
+++ wmi-1.3.13/Samba/source/wmi/winsmb.c	(revision 0)
@@ -0,0 +1,377 @@
+/*
+###############################################################################
+# SMB Client lib
+# This is a derivative work of smbclient (clien/client.c)
+
+# Authors:
+# Chandrashekhar B <bchandra@secpod.com>
+#
+# Copyright:
+# Copyright (c) 2009 Intevation GmbH, http://www.intevation.net
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2
+# (or any later version), as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+###############################################################################
+*/
+
+
+/**
+ * @file winsmb.c
+ * @brief Implements application specific SMB functions invoking
+ * low level Samba API's.
+ *
+ */
+
+#include "includes.h"
+#include "version.h"
+#include "libcli/libcli.h"
+#include "lib/cmdline/popt_common.h"
+#include "libcli/raw/libcliraw.h"
+#include "system/dir.h"
+#include "system/filesys.h"
+#include "lib/util/dlinklist.h"
+#include "system/readline.h"
+#include "auth/credentials/credentials.h"
+#include "auth/gensec/gensec.h"
+#include "system/time.h"
+#include "libcli/resolve/resolve.h"
+#include "libcli/security/security.h"
+#include "lib/smbreadline/smbreadline.h"
+#include "librpc/gen_ndr/ndr_nbt.h"
+#include "param/param.h"
+
+#include "librpc/gen_ndr/ndr_srvsvc_c.h"
+#include "librpc/gen_ndr/ndr_lsa.h"
+#include "librpc/gen_ndr/ndr_security.h"
+
+#include "openvas_smb_interface.h"
+
+#define SMB_LIB_VERSION "0.0.1"
+
+TALLOC_CTX *mem_ctx;
+
+
+/**
+ * @brief Returns SMB Client library version
+ * @return, SMB client library version
+ */
+
+char *
+smb_versioninfo()
+{
+  return SMB_LIB_VERSION;
+}
+
+
+/**
+ * @brief Estiablish connection to a SMB service.
+ *
+ * @param[in] server - The host system to connect to
+ *
+ * @param[in] share - The file system share.
+ *
+ * @param[in] username - The username for getting access to SMB service
+ *
+ * @param[in] password - The password that corresponds to username
+ *
+ * @param[out] handle - A connection handle in case of success.
+ *
+ * @return, 0 on success, -1 on failure
+ */
+int smb_connect(const char *server, const char *share, const char *username, const char *password, SMB_HANDLE *handle)
+{
+  int opt;
+  poptContext pc;
+  struct smbcli_state * SmbClientState;
+  struct smbcli_options smb_options;
+  NTSTATUS status;
+  struct cli_credentials *creds;
+  char *DelimAt = NULL;
+  char *domain = NULL;
+
+  int argc = 1;
+  char **argv = NULL;
+
+  struct poptOption long_options[] = {
+    POPT_AUTOHELP
+    POPT_COMMON_SAMBA
+    POPT_COMMON_CONNECTION
+    POPT_COMMON_CREDENTIALS
+    POPT_COMMON_VERSION
+    { NULL }
+  };
+
+  pc = poptGetContext("smbcli", argc, (const char **) argv,
+                       long_options, 0);
+
+  while ((opt = poptGetNextOpt(pc)) != -1) {
+    break;
+  }
+  poptFreeContext(pc);
+
+  mem_ctx = talloc_init("winsmb.c/smb_connect");
+  if (!mem_ctx) {
+    fprintf(stderr, "\nclient.c: Not enough memory\n");
+    return -1;
+  }
+
+  SmbClientState = talloc(mem_ctx, struct smbcli_state);
+  gensec_init();
+
+  DelimAt = strpbrk(username, "\\/");
+  if (DelimAt)
+  {
+    domain = talloc_strndup(mem_ctx, username, DelimAt - username);
+    username = talloc_strdup(mem_ctx, DelimAt+1);
+  }
+
+  creds = cli_credentials_init(mem_ctx);
+  cli_credentials_set_conf(creds);
+  cli_credentials_set_username(creds, username, CRED_SPECIFIED);
+  cli_credentials_set_password(creds, password, CRED_SPECIFIED);
+  if (domain)
+    cli_credentials_set_domain(creds, domain, CRED_SPECIFIED);
+  gensec_set_credentials(mem_ctx, creds);
+
+  status = smbcli_full_connection(mem_ctx, &SmbClientState, server,
+                                  share,
+                                  NULL, creds,
+                                  NULL);
+
+
+  if (!NT_STATUS_IS_OK(status)) {
+    return -1;
+  }
+
+  *handle = (SMB_HANDLE) SmbClientState;
+  return 0;
+}
+
+
+/**
+ * @brief Close the connection handle for SMB service.
+ *
+ * @param[in] handle - SMB connection handle
+ *
+ * @return, 0 on success, -1 on failure
+ */
+int smb_close(SMB_HANDLE handle) {
+  if(handle){
+    talloc_free((struct smbcli_state *) handle);
+    talloc_free(mem_ctx);
+    return 0;
+  }
+  else
+    return -1;
+}
+
+/**
+ * @brief Obtain Windows file rights in SDDL format
+ *
+ * @param[in] handle - SMB connection handle
+ *
+ * @param[in] filename - File system path
+ *
+ * @return, Security Descriptor in SDDL format on success, NULL on failure.
+ */
+char *smb_file_SDDL(SMB_HANDLE handle, const char *filename)
+{
+  union smb_fileinfo query;
+  NTSTATUS status;
+  int fnum;
+  struct smbcli_state *SmbClientState;
+
+  if((!handle) || (!filename))
+    return NULL;
+
+  SmbClientState = (struct smbcli_state *) handle;
+
+  fnum = smbcli_nt_create_full(SmbClientState->tree, filename, 0,
+                               SEC_STD_READ_CONTROL,
+                               0,
+                               NTCREATEX_SHARE_ACCESS_DELETE|
+                               NTCREATEX_SHARE_ACCESS_READ|
+                               NTCREATEX_SHARE_ACCESS_WRITE,
+                               NTCREATEX_DISP_OPEN,
+                               0, 0);
+
+  if(!fnum)
+    return NULL;
+
+  query.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
+  query.query_secdesc.in.file.fnum = fnum;
+  query.query_secdesc.in.secinfo_flags = 0x7;
+
+  status = smb_raw_fileinfo(SmbClientState->tree, mem_ctx, &query);
+
+  if (!NT_STATUS_IS_OK(status)) {
+    fprintf(stderr, "%s\n", nt_errstr(status));
+    return NULL;
+  }
+
+  return sddl_encode(SmbClientState, query.query_secdesc.out.sd, NULL);
+}
+
+
+/**
+ * @brief Obtain the SID of the Owner for a given file/path
+ *
+ * @param[in] handle - SMB connection handle
+ *
+ * @param[in] filename - File system path
+ *
+ * @return, Owner SID string on success, NULL on failure.
+ */
+char *smb_file_OwnerSID(SMB_HANDLE handle, const char *filename)
+{
+  union smb_fileinfo query;
+  NTSTATUS status;
+  int fnum;
+  struct smbcli_state *SmbClientState;
+
+  if((!handle) || (!filename))
+    return NULL;
+
+  SmbClientState = (struct smbcli_state *) handle;
+
+  fnum = smbcli_nt_create_full(SmbClientState->tree, filename, 0,
+                               SEC_STD_READ_CONTROL,
+                               0,
+                               NTCREATEX_SHARE_ACCESS_DELETE|
+                               NTCREATEX_SHARE_ACCESS_READ|
+                               NTCREATEX_SHARE_ACCESS_WRITE,
+                               NTCREATEX_DISP_OPEN,
+                               0, 0);
+
+  if(!fnum)
+    return NULL;
+
+  query.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
+  query.query_secdesc.in.file.fnum = fnum;
+  query.query_secdesc.in.secinfo_flags = 0x7;
+
+  status = smb_raw_fileinfo(SmbClientState->tree, mem_ctx, &query);
+
+  if (!NT_STATUS_IS_OK(status)) {
+    fprintf(stderr, "%s\n", nt_errstr(status));
+    return NULL;
+  }
+
+  return dom_sid_string(NULL, query.query_secdesc.out.sd->owner_sid);
+}
+
+
+/**
+ * @brief Obtain the SID of the Group for a given file/path
+ *
+ * @param[in] handle - SMB connection handle
+ *
+ * @param[in] filename - File system path
+ *
+ * @return, Group SID string on success, NULL on failure.
+ */
+char *smb_file_GroupSID(SMB_HANDLE handle, const char *filename)
+{
+  union smb_fileinfo query;
+  NTSTATUS status;
+  int fnum;
+  struct smbcli_state *SmbClientState;
+
+  if((!handle) || (!filename))
+    return NULL;
+
+  SmbClientState = (struct smbcli_state *) handle;
+
+  fnum = smbcli_nt_create_full(SmbClientState->tree, filename, 0,
+                               SEC_STD_READ_CONTROL,
+                               0,
+                               NTCREATEX_SHARE_ACCESS_DELETE|
+                               NTCREATEX_SHARE_ACCESS_READ|
+                               NTCREATEX_SHARE_ACCESS_WRITE,
+                               NTCREATEX_DISP_OPEN,
+                               0, 0);
+
+  if(!fnum)
+    return NULL;
+
+  query.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
+  query.query_secdesc.in.file.fnum = fnum;
+  query.query_secdesc.in.secinfo_flags = 0x7;
+
+  status = smb_raw_fileinfo(SmbClientState->tree, mem_ctx, &query);
+
+  if (!NT_STATUS_IS_OK(status)) {
+    fprintf(stderr, "%s\n", nt_errstr(status));
+    return NULL;
+  }
+
+  return dom_sid_string(NULL, query.query_secdesc.out.sd->group_sid);
+}
+
+
+/**
+ * @brief Obtain the Trustee SID and their rights for a given file/path
+ *
+ * @param[in] handle - SMB connection handle
+ *
+ * @param[in] filename - File system path
+ *
+ * @return, Trustee SID:Access_Mask string on success, NULL on failure.
+ */
+char *smb_file_TrusteeRights(SMB_HANDLE handle, const char *filename)
+{
+
+  union smb_fileinfo query;
+  NTSTATUS status;
+  int fnum;
+  struct smbcli_state *SmbClientState;
+  int i = 0;
+  char *TrusteeSids;
+
+  if((!handle) || (!filename))
+    return NULL;
+
+  SmbClientState = (struct smbcli_state *) handle;
+  TrusteeSids  = talloc_strdup(SmbClientState, "");
+
+  fnum = smbcli_nt_create_full(SmbClientState->tree, filename, 0,
+                               SEC_STD_READ_CONTROL,
+                               0,
+                               NTCREATEX_SHARE_ACCESS_DELETE|
+                               NTCREATEX_SHARE_ACCESS_READ|
+                               NTCREATEX_SHARE_ACCESS_WRITE,
+                               NTCREATEX_DISP_OPEN,
+                               0, 0);
+
+  if(!fnum)
+    return NULL;
+
+  query.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
+  query.query_secdesc.in.file.fnum = fnum;
+  query.query_secdesc.in.secinfo_flags = 0x7;
+
+  status = smb_raw_fileinfo(SmbClientState->tree, mem_ctx, &query);
+
+  if (!NT_STATUS_IS_OK(status)) {
+    fprintf(stderr, "%s - %s\n", filename, nt_errstr(status));
+    return NULL;
+  }
+
+  for (i=0; i< query.query_secdesc.out.sd->dacl->num_aces; i++ ) {
+    TrusteeSids = talloc_asprintf_append(TrusteeSids, "%s:%08x,",
+                   dom_sid_string(NULL, &query.query_secdesc.out.sd->dacl->aces[i].trustee),
+                   query.query_secdesc.out.sd->dacl->aces[i].access_mask);
+  }
+
+  return TrusteeSids;
+}
Index: wmi-1.3.13/Samba/source/wmi/wmirsop.c
===================================================================
--- wmi-1.3.13/Samba/source/wmi/wmirsop.c	(revision 0)
+++ wmi-1.3.13/Samba/source/wmi/wmirsop.c	(revision 0)
@@ -0,0 +1,297 @@
+/*
+###############################################################################
+# WMI Client lib
+# This is a derivative work of the WMI Sample command line client
+#
+# Authors:
+# Chandrashekhar B <bchandra@secpod.com>
+#
+# Copyright:
+# Copyright (c) 2009 Intevation GmbH, http://www.intevation.net
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2
+# (or any later version), as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+###############################################################################
+
+*/
+
+/**
+ * @file wmirsop.c
+ *
+ * @brief WMI functions
+ *
+ * Provides WMI RSOP functionalities.
+ */
+#include "includes.h"
+#include "lib/cmdline/popt_common.h"
+#include "librpc/rpc/dcerpc.h"
+#include "librpc/gen_ndr/ndr_oxidresolver.h"
+#include "librpc/gen_ndr/ndr_oxidresolver_c.h"
+#include "librpc/gen_ndr/ndr_dcom.h"
+#include "librpc/gen_ndr/ndr_dcom_c.h"
+#include "librpc/gen_ndr/ndr_remact_c.h"
+#include "librpc/gen_ndr/ndr_epmapper_c.h"
+#include "librpc/gen_ndr/com_dcom.h"
+#include "param/param.h"
+
+#include "lib/com/dcom/dcom.h"
+#include "lib/com/proto.h"
+#include "lib/com/dcom/proto.h"
+
+struct WBEMCLASS;
+struct WBEMOBJECT;
+
+#include "wmi/proto.h"
+#include "wmi/wmi.h"
+#include "openvas_wmi_interface.h"
+
+
+#define WERR_CHECK(msg) if (!W_ERROR_IS_OK(result)) { \
+                            DEBUG(2, ("ERROR: %s\n", msg)); \
+                            goto error; \
+                        } else { \
+                            DEBUG(1, ("OK   : %s\n", msg)); \
+                        }
+
+struct program_args {
+  char *hostname;       // Hostname
+};
+
+
+static int parse_args(int argc, char *argv[], struct program_args *pmyargs)
+{
+    poptContext pc;
+    int opt, i;
+    int argc_new;
+    char **argv_new;
+ 
+    struct poptOption long_options[] = {
+        POPT_AUTOHELP
+        POPT_COMMON_SAMBA
+        POPT_COMMON_CONNECTION
+        POPT_COMMON_CREDENTIALS
+        POPT_COMMON_VERSION
+        POPT_TABLEEND
+    };
+ 
+    pc = poptGetContext("wmic", argc, (const char **) argv,
+                long_options, POPT_CONTEXT_KEEP_FIRST);
+ 
+ 
+    while ((opt = poptGetNextOpt(pc)) != -1) {
+          poptFreeContext(pc);
+          return 1;
+    }
+ 
+    argv_new = discard_const_p(char *, poptGetArgs(pc));
+ 
+    argc_new = argc;
+    for (i = 0; i < argc; i++) {
+          if (argv_new[i] == NULL) {
+            argc_new = i;
+            break;
+          }
+    }
+    if (argc_new != 2 || argv_new[1][0] != '/'
+        || argv_new[1][1] != '/') {
+      poptFreeContext(pc);
+          return 1;
+    }
+ 
+    pmyargs->hostname = argv_new[1] + 2;
+    poptFreeContext(pc);
+    return 0;
+}
+
+
+/**
+ * @brief Estiablish connection to a WMI RSOP service.
+ *
+ * @param[in] username - The username for getting access to WMI service
+ *
+ * @param[in] password - The password that corresponds to username
+ *
+ * @param[in] host - The host system to connect to
+ *
+ * @param[in] namespace - The WMI namespace of the service.
+ *
+ * @param[out] handle - A connection handle in case of success.
+ *
+ * @return, 0 on success, -1 on failure
+ */
+
+int wmi_connect_rsop(int argc, char **argv, WMI_HANDLE *handle)
+{
+  /*Works only for domain based systems and not for WORKGROUP */
+
+  struct com_context *ctx = NULL;
+  NTSTATUS status;
+  struct IWbemServices *pWS = NULL;
+  uint32_t *ret_code;
+
+  struct IWbemClassObject *wco = NULL;
+  struct IWbemClassObject *inc, *outc, *in;
+  struct IWbemClassObject *out = NULL;
+  WERROR result;
+  union CIMVAR v;
+  char *namespace = NULL;
+  int ret;
+  struct program_args args = {};
+
+  ret = parse_args(argc, argv, &args);
+ 
+  if(ret == 1)
+  {
+    DEBUG(1, ("ERROR: %s\n", "Invalid input arguments"));
+    return -1;
+  }
+
+
+  dcerpc_init();
+  dcerpc_table_init();
+
+  dcom_proxy_IUnknown_init();
+  dcom_proxy_IWbemLevel1Login_init();
+  dcom_proxy_IWbemServices_init();
+  dcom_proxy_IEnumWbemClassObject_init();
+  dcom_proxy_IRemUnknown_init();
+  dcom_proxy_IWbemFetchSmartEnum_init();
+  dcom_proxy_IWbemWCOSmartEnum_init();
+  dcom_proxy_IWbemClassObject_init();
+
+  com_init_ctx(&ctx, NULL);
+  dcom_client_init(ctx, cmdline_credentials);
+
+  /* Connect to RSOP namespace */
+  result = WBEM_ConnectServer(ctx, args.hostname, "root\\rsop", 0, 0, 0, 0, 0, 0, &pWS);
+  WERR_CHECK("WBEM_ConnectServer.");
+
+  result = IWbemServices_GetObject(pWS, ctx, "RsopLoggingModeProvider",
+                                   WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL,
+                                   &wco, NULL);
+  WERR_CHECK("GetObject.");
+
+  result = IWbemClassObject_GetMethod(wco, ctx, "RsopCreateSession", 0,
+                                      &inc, &outc);
+  WERR_CHECK("IWbemClassObject_GetMethod.");
+
+  result = IWbemClassObject_SpawnInstance(inc, ctx, 0, &in);
+  WERR_CHECK("IWbemClassObject_SpawnInstance.");
+
+  /* Flag that ensures creation of temporary RSOP db */
+  v.v_uint32 = 4;
+  result = IWbemClassObject_Put(in, ctx, "flags", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+
+  result = IWbemServices_ExecMethod(pWS, ctx, "RsopLoggingModeProvider",
+                                    "RsopCreateSession", 0, NULL, in, &out,
+                                     NULL);
+  WERR_CHECK("IWbemServices_ExecMethod.");
+
+  if(ret_code){
+    result = WbemClassObject_Get(out->object_data, ctx, "nameSpace", 0, &v,
+                                 0, 0);
+    WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+  }
+
+  /* Computer namespace only, user namespace doesn't seem to work */
+  namespace = talloc_asprintf_append(v.v_string, "%s", "\\computer");
+  result = WBEM_ConnectServer(ctx, args.hostname, "\\computer", 0, 0, 0, 0, 0, 0, &pWS);
+
+  *handle = (WMI_HANDLE) pWS;
+  return 0;
+
+error:
+  status = werror_to_ntstatus(result);
+  DEBUG(3, ("NTSTATUS: %s - %s\n", nt_errstr(status), get_friendly_nt_error_msg(status)));
+  return -1;
+}
+
+
+/**
+ * @brief WMI RSOP query.
+ *
+ * @param[in] handle - WMI connection handle
+ *
+ * @param[in] query - WQL RSOP query
+ *
+ * @param[in] val_name - Registry value to be queried
+ *
+ * @return, 0 on success, -1 on failure
+ */
+int wmi_query_rsop(WMI_HANDLE handle, const char *query, char **res)
+{
+  WERROR result;
+  NTSTATUS status;
+  struct IWbemServices *pWS = NULL;
+  struct IEnumWbemClassObject *pEnum = NULL;
+  uint32_t cnt = 5, ret;
+  char *class_name = NULL;
+
+  pWS = (struct IWbemServices *) handle;
+  if(pWS->ctx == 0)
+    return -1;
+
+  result = IWbemServices_ExecQuery(pWS, pWS->ctx, "WQL", query,
+                                   WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_ENSURE_LOCATABLE,
+                                   NULL, &pEnum);
+  WERR_CHECK("WMI query execute.");
+
+  IEnumWbemClassObject_Reset(pEnum, pWS->ctx);
+  WERR_CHECK("Reset result of WMI query.");
+
+  do {
+    uint32_t i, j;
+    struct WbemClassObject *co[cnt];
+
+    result = IEnumWbemClassObject_SmartNext(pEnum, pWS->ctx, 0xFFFFFFFF,
+                                            cnt, co, &ret);
+    /* WERR_BADFUNC is OK, it means only that there is less returned
+     * objects than requested
+     */
+    if (!W_ERROR_EQUAL(result, WERR_BADFUNC)){
+      WERR_CHECK("Retrieve result data.");
+    }
+    else{
+      DEBUG(2, ("OK   : Retrieved less objects than requested (it is normal).\n"));
+    }
+    if(!ret) break;
+
+    for (i = 0; i < ret; ++i){
+      if (!class_name || strcmp(co[i]->obj_class->__CLASS, class_name)){
+        if (class_name) talloc_free(class_name);
+        class_name = talloc_strdup(pWS->ctx, co[i]->obj_class->__CLASS);
+
+        *res = (char *) talloc_strdup(NULL , "");
+        for (j = 0; j < co[i]->obj_class->__PROPERTY_COUNT; ++j)
+          *res = (char *) talloc_asprintf_append(*res, "%s%s", j?"|":"",
+                                                 co[i]->obj_class->properties[j].name);
+        *res = (char *) talloc_asprintf_append(*res, "\n");
+      }
+      for (j = 0; j < co[i]->obj_class->__PROPERTY_COUNT; ++j){
+        char *s;
+        s = string_CIMVAR(pWS->ctx, &co[i]->instance->data[j],
+                          co[i]->obj_class->properties[j].desc->cimtype & CIM_TYPEMASK);
+        *res = (char *) talloc_asprintf_append(*res, "%s%s", j?"|":"", s);
+      }
+      *res = (char *) talloc_asprintf_append(*res, "\n");
+    }
+  } while (ret == cnt);
+  return 0;
+
+error:
+  status = werror_to_ntstatus(result);
+  DEBUG(3, ("NTSTATUS: %s - %s\n", nt_errstr(status), get_friendly_nt_error_msg(status)));
+  return -1;
+}
Index: wmi-1.3.13/Samba/source/wmi/openvas_smb_interface.h
===================================================================
--- wmi-1.3.13/Samba/source/wmi/openvas_smb_interface.h	(revision 0)
+++ wmi-1.3.13/Samba/source/wmi/openvas_smb_interface.h	(revision 0)
@@ -0,0 +1,48 @@
+/* OpenVAS
+ *
+ * $Id$
+ * Description: API protos describing the interface of a smb interface
+ * implementation.
+ *
+ * Authors:
+ * Chandrashekhar B <bchandra@secpod.com>
+ *
+ * Copyright:
+ * Copyright (c) 2009 Greenbone Networks GmbH, http://www.greenbone.net
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * (or any later version), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/**
+ * @file openvas_smb_interface.h
+ * @brief API protos describing the interface of a smb interface implementation.
+ *
+ * This file contains API protos describing the interface of a smb
+ * interface implementation.
+ */
+
+#ifndef _NASL_OPENVAS_SMB_INTERFACE_H
+#define _NASL_OPENVAS_SMB_INTERFACE_H
+
+typedef int SMB_HANDLE;
+
+char * smb_versioninfo();
+int smb_connect(const char *, const char *, const char *, const char *, SMB_HANDLE *);
+int smb_close(SMB_HANDLE);
+char * smb_file_SDDL(SMB_HANDLE, const char *);
+char * smb_file_OwnerSID(SMB_HANDLE, const char *);
+char * smb_file_GroupSID(SMB_HANDLE, const char *);
+char * smb_file_TrusteeRights(SMB_HANDLE, const char *);
+
+#endif
Index: wmi-1.3.13/Samba/source/wmi/wmicso.c
===================================================================
--- wmi-1.3.13/Samba/source/wmi/wmicso.c	(revision 0)
+++ wmi-1.3.13/Samba/source/wmi/wmicso.c	(revision 0)
@@ -0,0 +1,341 @@
+/*
+###############################################################################
+# WMI Client lib
+# This is a derivative work of the WMI Sample command line client
+#
+# Authors:
+# Chandrashekhar B <bchandra@secpod.com>
+#
+# Copyright:
+# Copyright (c) 2009 SecPod, http://www.secpod.com
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2
+# (or any later version), as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+###############################################################################
+
+*/
+
+/*
+   WMI Sample client
+   Copyright (C) 2006 Andrzej Hajda <andrzej.hajda@wp.pl>
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/**
+ * @file wmicso.c
+ *
+ * @brief WMI functions
+ *
+ * Provides WMI functionalities.
+ */
+#include "includes.h"
+#include "lib/cmdline/popt_common.h"
+#include "librpc/rpc/dcerpc.h"
+#include "librpc/gen_ndr/ndr_oxidresolver.h"
+#include "librpc/gen_ndr/ndr_oxidresolver_c.h"
+#include "librpc/gen_ndr/ndr_dcom.h"
+#include "librpc/gen_ndr/ndr_dcom_c.h"
+#include "librpc/gen_ndr/ndr_remact_c.h"
+#include "librpc/gen_ndr/ndr_epmapper_c.h"
+#include "librpc/gen_ndr/com_dcom.h"
+#include "librpc/rpc/dcerpc_table.h"
+#include "param/param.h"
+
+#include "lib/com/dcom/dcom.h"
+#include "lib/com/proto.h"
+#include "lib/com/dcom/proto.h"
+
+struct WBEMCLASS;
+struct WBEMOBJECT;
+
+#include "wmi/proto.h"
+#include "wmi/wmi.h"
+
+#include "openvas_wmi_interface.h"
+
+#define WMI_LIB_VERSION "0.0.1"
+
+#define WERR_CHECK(msg) if (!W_ERROR_IS_OK(result)) { \
+                            DEBUG(2, ("ERROR: %s\n", msg)); \
+                            goto error; \
+                        } else { \
+                            DEBUG(1, ("OK   : %s\n", msg)); \
+                        }
+
+
+struct program_args {
+  char *hostname;       // Hostname
+  char *ns;             // WMI namspace, ex: root\cimv2
+};
+
+
+static int parse_args(int argc, char *argv[], struct program_args *pmyargs)
+{
+    poptContext pc;
+    int opt, i;
+    int argc_new;
+    char **argv_new;
+ 
+    struct poptOption long_options[] = {
+        POPT_AUTOHELP
+        POPT_COMMON_SAMBA
+        POPT_COMMON_CONNECTION
+        POPT_COMMON_CREDENTIALS
+        POPT_COMMON_VERSION
+        POPT_TABLEEND
+    };
+ 
+    pc = poptGetContext("wmic", argc, (const char **) argv,
+                long_options, POPT_CONTEXT_KEEP_FIRST);
+ 
+ 
+    while ((opt = poptGetNextOpt(pc)) != -1) {
+          poptFreeContext(pc);
+          return 1;
+    }
+ 
+    argv_new = discard_const_p(char *, poptGetArgs(pc));
+ 
+    argc_new = argc;
+    for (i = 0; i < argc; i++) {
+          if (argv_new[i] == NULL) {
+            argc_new = i;
+            break;
+          }
+    }
+    if (argc_new != 3 || argv_new[1][0] != '/'
+        || argv_new[1][1] != '/') {
+      poptFreeContext(pc);
+          return 1;
+    }
+ 
+    pmyargs->hostname = argv_new[1] + 2;
+    pmyargs->ns = argv_new[2];
+    poptFreeContext(pc);
+    return 0;
+}
+
+
+
+/*
+ * @brief Decode the values based on data type
+ */
+char *string_CIMVAR(TALLOC_CTX *mem_ctx, union CIMVAR *v, enum CIMTYPE_ENUMERATION cimtype)
+{
+  int i;
+  char *s = NULL;
+
+  switch (cimtype) {
+    case CIM_SINT8: return talloc_asprintf(mem_ctx, "%d", v->v_sint8);
+    case CIM_UINT8: return talloc_asprintf(mem_ctx, "%u", v->v_uint8);
+    case CIM_SINT16: return talloc_asprintf(mem_ctx, "%d", v->v_sint16);
+    case CIM_UINT16: return talloc_asprintf(mem_ctx, "%u", v->v_uint16);
+    case CIM_SINT32: return talloc_asprintf(mem_ctx, "%d", v->v_sint32);
+    case CIM_UINT32: return talloc_asprintf(mem_ctx, "%u", v->v_uint32);
+    case CIM_SINT64: return talloc_asprintf(mem_ctx, "%lld", v->v_sint64);
+    case CIM_UINT64: return talloc_asprintf(mem_ctx, "%llu", v->v_sint64);
+    case CIM_REAL32: return talloc_asprintf(mem_ctx, "Unsupported");
+    case CIM_REAL64: return talloc_asprintf(mem_ctx, "Unsupported");
+    case CIM_BOOLEAN: return talloc_asprintf(mem_ctx, "%s", v->v_boolean?"True":"False");
+    case CIM_STRING:
+    case CIM_DATETIME:
+    case CIM_REFERENCE: return talloc_asprintf(mem_ctx, "%s", v->v_string);
+    case CIM_CHAR16: return talloc_asprintf(mem_ctx, "Unsupported");
+    case CIM_OBJECT: return talloc_asprintf(mem_ctx, "Unsupported");
+    case CIM_ARR_STRING:
+      if(v->a_string){
+        for (i = 0; i < v->a_uint8->count; ++i){
+          s = (char *) talloc_asprintf_append(s, "%s%s", i?"|":"", v->a_string->item[i]);
+        }
+      }
+      return s;
+    default: return talloc_asprintf(mem_ctx, "Unsupported");
+  }
+}
+
+
+/**
+ * @brief Returns WMI Client library version
+ * @return, WMI client library version
+ */
+char *
+wmi_versioninfo()
+{
+  return WMI_LIB_VERSION;
+}
+
+
+/**
+ * @brief Estiablish connection to a WMI service.
+ *
+ * @param[in] username - The username for getting access to WMI service
+ *
+ * @param[in] password - The password that corresponds to username
+ *
+ * @param[in] host - The host system to connect to
+ *
+ * @param[in] namespace - The WMI namespace of the service.
+ *
+ * @param[out] handle - A connection handle in case of success.
+ *
+ * @return, 0 on success, -1 on failure
+ */
+
+int wmi_connect(int argc, char **argv, WMI_HANDLE *handle)
+{
+
+  WERROR result;
+  NTSTATUS status;
+  struct IWbemServices *pWS = NULL;
+  struct com_context *ctx;
+  int ret;
+  struct program_args args = {};
+
+  ret = parse_args(argc, argv, &args);
+ 
+  if(ret == 1)
+  {
+    DEBUG(1, ("ERROR: %s\n", "Invalid input arguments"));
+    return -1;
+  }
+
+  dcerpc_init();
+  dcerpc_table_init();
+
+  dcom_proxy_IUnknown_init();
+  dcom_proxy_IWbemLevel1Login_init();
+  dcom_proxy_IWbemServices_init();
+  dcom_proxy_IEnumWbemClassObject_init();
+  dcom_proxy_IRemUnknown_init();
+  dcom_proxy_IWbemFetchSmartEnum_init();
+  dcom_proxy_IWbemWCOSmartEnum_init();
+
+  com_init_ctx(&ctx, NULL);
+  dcom_client_init(ctx, cmdline_credentials);
+
+  result = WBEM_ConnectServer(ctx, args.hostname, args.ns, 0, 0, 0, 0, 0, 0, &pWS);
+  WERR_CHECK("Login to remote object.\n");
+  *handle = (WMI_HANDLE) pWS;
+  return 0;
+
+error:
+  status = werror_to_ntstatus(result);
+  DEBUG(3, ("NTSTATUS: %s - %s\n", nt_errstr(status), get_friendly_nt_error_msg(status)));
+  return -1;
+}
+
+
+/**
+ * @brief Query WMI service using a WQL query
+ *
+ * @param[in] handle - WMI connection handle
+ *
+ * @param[in] query - The WQL query string
+ *
+ * @param[out] result - Result of query as string
+ *
+ * @return, 0 on success, -1 on failure
+ */
+int wmi_query(WMI_HANDLE handle, const char *query, char **res)
+{
+  uint32_t cnt = 5, ret = 0;
+  char *class_name = NULL;
+  WERROR result;
+  NTSTATUS status;
+  struct IWbemServices *pWS = NULL;
+  struct IEnumWbemClassObject *pEnum = NULL;
+
+  pWS = (struct IWbemServices *)handle;
+  if(pWS->ctx == 0)
+    return -1;
+
+  result = IWbemServices_ExecQuery(pWS, pWS->ctx, "WQL", query, WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_ENSURE_LOCATABLE, NULL, &pEnum);
+  WERR_CHECK("WMI query execute.");
+
+  IEnumWbemClassObject_Reset(pEnum, pWS->ctx);
+  WERR_CHECK("Reset result of WMI query.");
+
+  do {
+    uint32_t i, j;
+    struct WbemClassObject *co[cnt];
+
+    result = IEnumWbemClassObject_SmartNext(pEnum, pWS->ctx, 0xFFFFFFFF, cnt, co, &ret);
+    /* WERR_BADFUNC is OK, it means only that there is less returned objects than requested */
+    if (!W_ERROR_EQUAL(result, WERR_BADFUNC)) {
+      WERR_CHECK("Retrieve result data.");
+    }
+    else {
+      DEBUG(2, ("OK   : Retrieved less objects than requested (it is normal).\n"));
+    }
+    if(!ret)
+      break;
+
+    for (i = 0; i < ret; ++i){
+      if (!class_name || strcmp(co[i]->obj_class->__CLASS, class_name)){
+        if (class_name) talloc_free(class_name);
+          class_name = talloc_strdup(pWS->ctx, co[i]->obj_class->__CLASS);
+          *res = (char *) talloc_strdup(NULL , "");
+          for (j = 0; j < co[i]->obj_class->__PROPERTY_COUNT; ++j)
+            *res = (char *) talloc_asprintf_append(*res, "%s%s", j?"|":"", co[i]->obj_class->properties[j].name);
+          *res = (char *) talloc_asprintf_append(*res, "\n");
+      }
+      for (j = 0; j < co[i]->obj_class->__PROPERTY_COUNT; ++j){
+        char *s;
+        s = string_CIMVAR(pWS->ctx, &co[i]->instance->data[j], co[i]->obj_class->properties[j].desc->cimtype & CIM_TYPEMASK);
+        *res = (char *) talloc_asprintf_append(*res, "%s%s", j?"|":"", s);
+      }
+      *res = (char *) talloc_asprintf_append(*res, "\n");
+    }
+  } while (ret == cnt);
+
+  return 0;
+
+  error:
+    status = werror_to_ntstatus(result);
+    DEBUG(3, ("NTSTATUS: %s - %s\n", nt_errstr(status), get_friendly_nt_error_msg(status)));
+    return -1;
+}
+
+
+/**
+ * @brief Close the connection handle for a WMI service.
+ *
+ * @param[in] handle - WMI service connection handle
+ *
+ * @return, 0 on success, -1 on failure
+ */
+int wmi_close(WMI_HANDLE handle)
+{
+  struct IWbemServices *pWS = NULL;
+  pWS = (struct IWbemServices *) handle;
+  if(pWS)
+  {
+    talloc_free(pWS->ctx);
+    pWS->ctx = NULL;
+  }
+  return 0;
+}
+
Index: wmi-1.3.13/Samba/source/wmi/openvas_wmi_interface.h
===================================================================
--- wmi-1.3.13/Samba/source/wmi/openvas_wmi_interface.h	(revision 0)
+++ wmi-1.3.13/Samba/source/wmi/openvas_wmi_interface.h	(revision 0)
@@ -0,0 +1,66 @@
+/* OpenVAS
+ *
+ * $Id$
+ * Description: API protos describing the interface of a wmi interface
+ * implementation.
+ *
+ * Authors:
+ * Jan-Oliver Wagner <jan-oliver.wagner@greenbone.net>
+ *
+ * Copyright:
+ * Copyright (c) 2009 Greenbone Networks GmbH, http://www.greenbone.net
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * (or any later version), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/**
+ * @file openvas_wmi_interface.h
+ * @brief API protos describing the interface of a wmi interface implementation.
+ *
+ * This file contains API protos describing the interface of a wmi
+ * interface implementation.
+ */
+
+#ifndef _NASL_OPENVAS_WMI_INTERFACE_H
+#define _NASL_OPENVAS_WMI_INTERFACE_H
+
+typedef int WMI_HANDLE;
+
+char *wmi_versioninfo ();
+int wmi_connect(int argc, char **argv, WMI_HANDLE * handle);
+//int wmi_connect (const char *, const char *, const char *, const char *,
+//                 WMI_HANDLE *);
+int wmi_close (WMI_HANDLE);
+int wmi_query (WMI_HANDLE, const char *, char **);
+
+int wmi_connect_rsop(int argc, char **argv, WMI_HANDLE * handle);
+int wmi_query_rsop (WMI_HANDLE, const char *, char **);
+
+int wmi_connect_reg(int argc, char **argv, WMI_HANDLE * handle);
+int wmi_reg_get_sz (WMI_HANDLE, unsigned int, const char *, const char *,
+                    char **);
+int wmi_reg_enum_value (WMI_HANDLE, unsigned int, const char *, char **);
+int wmi_reg_enum_key (WMI_HANDLE, unsigned int, const char *, char **);
+int wmi_reg_get_bin_val (WMI_HANDLE, unsigned int, const char *, const char *,
+                         char **);
+int wmi_reg_get_dword_val (WMI_HANDLE, unsigned int, const char *, const char *,
+                           char **);
+int wmi_reg_get_ex_string_val (WMI_HANDLE, unsigned int, const char *,
+                               const char *, char **);
+int wmi_reg_get_mul_string_val (WMI_HANDLE, unsigned int, const char *,
+                                const char *, char **);
+int wmi_reg_get_qword_val (WMI_HANDLE, unsigned int, const char *, const char *,
+                           char **);
+
+#endif
Index: wmi-1.3.13/Samba/source/wmi/wbemdata.c
===================================================================
--- wmi-1.3.13/Samba/source/wmi/wbemdata.c	(revision 31)
+++ wmi-1.3.13/Samba/source/wmi/wbemdata.c	(working copy)
@@ -216,6 +216,7 @@
 
 void duplicate_WbemQualifier(TALLOC_CTX *mem_ctx, const struct WbemQualifier *src, struct WbemQualifier *dst)
 {
+	dst = talloc_zero(mem_ctx, struct WbemQualifier);
 	dst->name = src->name;
 	if (src->name) dst->name = talloc_strdup(mem_ctx, src->name);
 
@@ -231,8 +232,10 @@
 	uint32_t i;
 
 	dst->count = src->count;
-	for (i = 0; i < src->count; ++i)
+	for (i = 0; i < src->count; ++i){
+		dst->item = talloc_zero(mem_ctx, CIMSTRING);
 		dst->item[i] = talloc_strdup(mem_ctx, src->item[i]);
+	}
 }
 
 void duplicate_WbemQualifiers(TALLOC_CTX *mem_ctx, const struct WbemQualifiers *src, struct WbemQualifiers *dst)
@@ -241,8 +244,8 @@
 
 	dst->count = src->count;
 	for (i = 0; i < src->count; ++i) {
-		dst->item[i] = talloc_zero(mem_ctx, struct WbemQualifier);
-		duplicate_WbemQualifier(dst->item[i], src->item[i], dst->item[i]);
+		dst->item = talloc_zero(mem_ctx, struct WbemQualifier*);
+		duplicate_WbemQualifier(mem_ctx, src->item[i], dst->item[i]);
 	}
 }
 
@@ -271,7 +274,7 @@
 	dst->default_values = talloc_array(mem_ctx, union CIMVAR, src->__PROPERTY_COUNT);
 	for (i = 0; i < src->__PROPERTY_COUNT; ++i) {
 		dst->default_flags[i] = src->default_flags[i];
-		duplicate_CIMVAR(dst->default_values, &src->default_values[i], &dst->default_values[i], src->properties[i].desc->cimtype);
+		duplicate_CIMVAR(mem_ctx, &src->default_values[i], &dst->default_values[i], src->properties[i].desc->cimtype);
 	}
 }
 
@@ -380,13 +383,17 @@
 		dst->v_string = talloc_strdup(mem_ctx, src->v_string);
 		break;
 	case CIM_OBJECT:
-		dst->v_object = talloc_zero(mem_ctx, struct WbemClassObject);
-		duplicate_WbemClassObject(dst->v_object, src->v_object, dst->v_object);
+		if(src->v_object){
+			dst->v_object = talloc_zero(mem_ctx, struct WbemClassObject);
+			duplicate_WbemClassObject(dst->v_object, src->v_object, dst->v_object);
+		}
 		break;
         case CIM_ARR_SINT8:
 	case CIM_ARR_UINT8:
-		dst->a_uint8 = talloc_memdup(mem_ctx, src->a_uint8, sizeof(struct arr_uint8));
-		dst->a_uint8->item = talloc_memdup(dst->a_uint8, src->a_uint8->item, src->a_uint8->count);
+		if(src->a_uint8){
+		  dst->a_uint8 = talloc_memdup(mem_ctx, src->a_uint8, sizeof(struct arr_uint8));
+		  dst->a_uint8->item = talloc_memdup(dst->a_uint8, src->a_uint8->item, src->a_uint8->count);
+		}
 		break;
         case CIM_ARR_SINT16:
         case CIM_ARR_UINT16:
@@ -409,10 +416,14 @@
         case CIM_ARR_STRING:
         case CIM_ARR_DATETIME:
         case CIM_ARR_REFERENCE:
-		dst->a_uint8 = talloc_memdup(mem_ctx, src->a_uint8, sizeof(struct arr_uint8));
-		dst->a_uint8->item = talloc_memdup(dst->a_uint8, src->a_uint8->item, 4*src->a_uint8->count);
-		for (i = 0; i < src->a_uint8->count; ++i)
-			dst->a_string->item[i] = talloc_strdup(dst->a_uint8->item, src->a_string->item[i]);
+		if(src->a_uint8)
+        {
+		  dst->a_uint8 = talloc_memdup(mem_ctx, src->a_uint8, sizeof(struct arr_uint8));
+		  dst->a_uint8->item = talloc_memdup(dst->a_uint8, src->a_uint8->item, 4*src->a_uint8->count);
+		  for (i = 0; i < src->a_uint8->count; ++i){
+		    dst->a_string->item[i] = talloc_strdup(dst->a_uint8->item, src->a_string->item[i]);
+		  }
+		}
 		break;
 	default:
     		DEBUG(0, ("duplicate_CIMVAR: cimtype 0x%04X not supported\n", cimtype & CIM_TYPEMASK));
Index: wmi-1.3.13/Samba/source/wmi/config.mk
===================================================================
--- wmi-1.3.13/Samba/source/wmi/config.mk	(revision 31)
+++ wmi-1.3.13/Samba/source/wmi/config.mk	(working copy)
@@ -13,7 +13,6 @@
 OBJ_FILES = async_wmi_lib.o zenoss_events.o
 # End LIBRARY async_wmi_lib
 #######################
-
 #################################
 # Start BINARY wmic
 [BINARY::wmic]
@@ -53,24 +52,46 @@
 # End BINARY wmis
 #################################
 
-#################################
-# Start BINARY wmis
-[BINARY::wmiq]
-INSTALLDIR = BINDIR
-OBJ_FILES = wmiq.o
-PRIVATE_DEPENDENCIES = \
-                POPT_SAMBA \
+################################################
+# Start SUBSYSTEM WINSMB
+[SUBSYSTEM::WINSMB]
+OBJ_FILES = winsmb.o
+PUBLIC_DEPENDENCIES = \
+		LIBSAMBA-CONFIG \
+		LIBSAMBA-UTIL \
+		LIBCLI_SMB \
+		LIBPOPT \
+		POPT_SAMBA \
+		POPT_CREDENTIALS \
+		LIBCLI_RAW
+# End SUBSYSTEM WINSMB
+################################################
+
+#start Librarby libwinwmiclient
+[LIBRARY::wmiclient]
+VERSION=0.0.1
+SO_VERSION=0
+LIBRARY_REALNAME = libwmiclient.$(SHLIBEXT)
+PUBLIC_DEPENDENCIES = LIBCLI_SMB NDR_MISC LIBSAMBA-UTIL LIBSAMBA-CONFIG RPC_NDR_SAMR RPC_NDR_LSA DYNCONFIG \
                 POPT_CREDENTIALS \
                 LIBPOPT \
-		RPC_NDR_OXIDRESOLVER \
-		NDR_DCOM \
-		RPC_NDR_REMACT \
-		NDR_TABLE \
-		DCOM_PROXY_DCOM \
-		dcom \
-		wmi
-# End BINARY wmis
-#################################
+                RPC_NDR_OXIDRESOLVER \
+                NDR_DCOM \
+                RPC_NDR_REMACT \
+                NDR_TABLE \
+                DCOM_PROXY_DCOM \
+                dcom 
+PRIVATE_DEPENDENCIES = POPT_SAMBA WINSMB
+OBJ_FILES = \
+                wmicso.o \
+                wmicore.o \
+		wmireg.o \
+		wmirsop.o \
+                wbemdata.o \
+		winsmb.o \
+                ../librpc/gen_ndr/ndr_dcom.o \
+                ../librpc/gen_ndr/dcom_p.o
+######################################
 
 librpc/gen_ndr/dcom_p.c: idl
 
Index: wmi-1.3.13/Samba/source/wmi/wmireg.c
===================================================================
--- wmi-1.3.13/Samba/source/wmi/wmireg.c	(revision 0)
+++ wmi-1.3.13/Samba/source/wmi/wmireg.c	(revision 0)
@@ -0,0 +1,800 @@
+/*
+###############################################################################
+# WMI Client lib
+#
+# Authors:
+# Chandrashekhar B <bchandra@secpod.com>
+#
+# Copyright:
+# Copyright (c) 2009 Intevation GmbH, http://www.intevation.net
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2
+# (or any later version), as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+###############################################################################
+
+*/
+
+/**
+ * @file wmireg.c
+ *
+ * @brief WMI Registry functions
+ *
+ * Provides WMI registry functionalities.
+ */
+
+#include "includes.h"
+#include "lib/cmdline/popt_common.h"
+#include "librpc/rpc/dcerpc.h"
+#include "librpc/gen_ndr/ndr_oxidresolver.h"
+#include "librpc/gen_ndr/ndr_oxidresolver_c.h"
+#include "librpc/gen_ndr/ndr_dcom.h"
+#include "librpc/gen_ndr/ndr_dcom_c.h"
+#include "librpc/gen_ndr/ndr_remact_c.h"
+#include "librpc/gen_ndr/ndr_epmapper_c.h"
+#include "librpc/gen_ndr/com_dcom.h"
+#include "param/param.h"
+
+#include "lib/com/dcom/dcom.h"
+#include "lib/com/proto.h"
+#include "lib/com/dcom/proto.h"
+
+struct WBEMCLASS;
+struct WBEMOBJECT;
+
+#include "wmi/proto.h"
+#include "wmi/wmi.h"
+#include "openvas_wmi_interface.h"
+
+
+#define WERR_CHECK(msg) if (!W_ERROR_IS_OK(result)) { \
+                            DEBUG(2, ("ERROR: %s\n", msg)); \
+                            goto error; \
+                        } else { \
+                            DEBUG(1, ("OK   : %s\n", msg)); \
+                        }
+
+struct program_args {
+  char *hostname;       // Hostname
+};
+
+
+static int parse_args(int argc, char *argv[], struct program_args *pmyargs)
+{
+    poptContext pc;
+    int opt, i;
+    int argc_new;
+    char **argv_new;
+ 
+    struct poptOption long_options[] = {
+        POPT_AUTOHELP
+        POPT_COMMON_SAMBA
+        POPT_COMMON_CONNECTION
+        POPT_COMMON_CREDENTIALS
+        POPT_COMMON_VERSION
+        POPT_TABLEEND
+    };
+ 
+    pc = poptGetContext("wmic", argc, (const char **) argv,
+                long_options, POPT_CONTEXT_KEEP_FIRST);
+ 
+ 
+    while ((opt = poptGetNextOpt(pc)) != -1) {
+          poptFreeContext(pc);
+          return 1;
+    }
+ 
+    argv_new = discard_const_p(char *, poptGetArgs(pc));
+ 
+    argc_new = argc;
+    for (i = 0; i < argc; i++) {
+          if (argv_new[i] == NULL) {
+            argc_new = i;
+            break;
+          }
+    }
+    if (argc_new != 2 || argv_new[1][0] != '/'
+        || argv_new[1][1] != '/') {
+      poptFreeContext(pc);
+          return 1;
+    }
+ 
+    pmyargs->hostname = argv_new[1] + 2;
+    poptFreeContext(pc);
+    return 0;
+}
+
+/**
+ * @brief Estiablish connection to a WMI Registry service.
+ *
+ * @param[in] username - The username for getting access to WMI service
+ *
+ * @param[in] password - The password that corresponds to username
+ *
+ * @param[in] host - The host system to connect to
+ *
+ * @param[in] namespace - The WMI namespace of the service.
+ *
+ * @param[out] handle - A connection handle in case of success.
+ *
+ * @return, 0 on success, -1 on failure
+ */
+int wmi_connect_reg(int argc, char **argv, WMI_HANDLE *handle)
+{
+  WERROR result;
+  NTSTATUS status;
+  struct IWbemServices *pWS = NULL;
+  struct com_context *ctx;
+  int ret;
+  struct program_args args = {};
+
+  ret = parse_args(argc, argv, &args);
+ 
+  if(ret == 1)
+  {
+    DEBUG(1, ("ERROR: %s\n", "Invalid input arguments"));
+    return -1;
+  }
+
+  dcerpc_init();
+  dcerpc_table_init();
+
+  dcom_proxy_IUnknown_init();
+  dcom_proxy_IWbemLevel1Login_init();
+  dcom_proxy_IWbemServices_init();
+  dcom_proxy_IEnumWbemClassObject_init();
+  dcom_proxy_IRemUnknown_init();
+  dcom_proxy_IWbemFetchSmartEnum_init();
+  dcom_proxy_IWbemWCOSmartEnum_init();
+  dcom_proxy_IWbemClassObject_init();
+
+  com_init_ctx(&ctx, NULL);
+  dcom_client_init(ctx, cmdline_credentials);
+
+  result = WBEM_ConnectServer(ctx, args.hostname, "root\\default", 0, 0, 0, 0, 0, 0, &pWS);
+  WERR_CHECK("Login to remote object.\n");
+  *handle = (WMI_HANDLE) pWS;
+
+  return 0;
+
+error:
+  status = werror_to_ntstatus(result);
+  DEBUG(3, ("NTSTATUS: %s - %s\n", nt_errstr(status), get_friendly_nt_error_msg(status)));
+  return -1;
+}
+
+
+/**
+ * @brief Get Registry string value.
+ *
+ * @param[in] handle - WMI connection handle
+ *
+ * @param[in] hive - Registry hive
+ *
+ * @param[in] key - Registry key name
+ *
+ * @param[in] key_name - Registry value name.
+ *
+ * @param[out] res - Result string.
+ *
+ * @return, 0 on success, -1 on failure
+ */
+int wmi_reg_get_sz(WMI_HANDLE handle, const unsigned int hive, const char *key,
+                   const char *key_name, char **res)
+{
+  struct IWbemClassObject *wco = NULL;
+  struct IWbemClassObject *inc, *outc, *in;
+  struct IWbemClassObject *out = NULL;
+  WERROR result;
+  NTSTATUS status;
+  union CIMVAR v;
+  struct IWbemServices *pWS;
+
+  pWS = (struct IWbemServices *) handle;
+  if(pWS->ctx == 0)
+    return -1;
+
+  result = IWbemServices_GetObject(pWS, pWS->ctx, "StdRegProv",
+                                   WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL, &wco, NULL);
+  WERR_CHECK("GetObject.");
+
+
+  result = IWbemClassObject_GetMethod(wco, pWS->ctx, "GetStringValue", 0,
+                                      &inc, &outc);
+  WERR_CHECK("IWbemClassObject_GetMethod.");
+
+  result = IWbemClassObject_SpawnInstance(inc, pWS->ctx, 0, &in);
+  WERR_CHECK("IWbemClassObject_SpawnInstance.");
+
+  if(hive)
+    v.v_uint32 = hive;
+  else
+    v.v_uint32 = 0x80000002; // Try default, HKEY_LOCAL_MACHINE
+
+  result = IWbemClassObject_Put(in, pWS->ctx, "hDefKey", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+
+  v.v_string = key;
+  result = IWbemClassObject_Put(in, pWS->ctx, "sSubKeyName", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+
+  v.v_string = key_name;
+  result = IWbemClassObject_Put(in, pWS->ctx, "sValueName", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+  result = IWbemServices_ExecMethod(pWS, pWS->ctx, "StdRegProv", "GetStringValue",
+                                    0, NULL, in, &out, NULL);
+  WERR_CHECK("IWbemServices_ExecMethod.");
+
+  result = WbemClassObject_Get(out->object_data, pWS->ctx, "sValue", 0, &v, 0, 0);
+  if(v.v_string){
+    *res = talloc_asprintf(pWS->ctx, "%s", v.v_string);
+  }
+
+  return 0;
+
+error:
+  status = werror_to_ntstatus(result);
+  DEBUG(3, ("NTSTATUS: %s - %s\n", nt_errstr(status), get_friendly_nt_error_msg(status)));
+  return -1;
+}
+
+
+/**
+ * @brief Enumerate Registry keys.
+ *
+ * @param[in] handle - WMI connection handle
+ *
+ * @param[in] hive - Registry hive
+ *
+ * @param[in] key - Registry key
+ *
+ * @param[out] res - Result string
+ *
+ * @return, 0 on success, -1 on failure
+ */
+int wmi_reg_enum_key(WMI_HANDLE handle, const unsigned int hive,
+                     const char *key, char **res)
+{
+  struct IWbemClassObject *wco = NULL;
+  struct IWbemClassObject *inc, *outc, *in;
+  struct IWbemClassObject *out = NULL;
+  int i = 0;
+  WERROR result;
+  NTSTATUS status;
+  union CIMVAR v;
+  struct IWbemServices *pWS;
+
+  pWS = (struct IWbemServices *) handle;
+  if(pWS->ctx == 0)
+    return -1;
+
+  result = IWbemServices_GetObject(pWS, pWS->ctx, "StdRegProv",
+                                   WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL,
+                                   &wco, NULL);
+  WERR_CHECK("GetObject.");
+
+  result = IWbemClassObject_GetMethod(wco, pWS->ctx, "EnumKey", 0, &inc,
+                                      &outc);
+  WERR_CHECK("IWbemClassObject_GetMethod.");
+
+  result = IWbemClassObject_SpawnInstance(inc, pWS->ctx, 0, &in);
+  WERR_CHECK("IWbemClassObject_SpawnInstance.");
+
+  if(hive)
+    v.v_uint32 = hive;
+  else
+    v.v_uint32 = 0x80000002; // Try default, HKEY_LOCAL_MACHINE
+
+  result = IWbemClassObject_Put(in, pWS->ctx, "hDefKey", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+
+  v.v_string = key;
+  result = IWbemClassObject_Put(in, pWS->ctx, "sSubKeyName", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+  v.v_string = NULL;
+
+  result = IWbemServices_ExecMethod(pWS, pWS->ctx, "StdRegProv", "EnumKey", 0, NULL,
+                                    in, &out, NULL);
+  WERR_CHECK("IWbemServices_ExecMethod.");
+
+  result = WbemClassObject_Get(out->object_data, pWS->ctx, "sNames", 0, &v,
+                               0, 0);
+
+  if(v.a_string){
+    for (i = 0; i < v.a_string->count; ++i)
+      *res = (char *) talloc_asprintf_append(*res, "%s%s", i?"|":"",
+                                             v.a_string->item[i]);
+  }
+  return 0;
+
+error:
+  status = werror_to_ntstatus(result);
+  DEBUG(3, ("NTSTATUS: %s - %s\n", nt_errstr(status),
+             get_friendly_nt_error_msg(status)));
+  return -1;
+}
+
+
+/**
+ * @brief Enumerate Registry values.
+ *
+ * @param[in] handle - WMI connection handle
+ *
+ * @param[in] hive - Registry hive
+ *
+ * @param[in] key - Registry key name
+ *
+ * @param[out] res - Result string
+ *
+ * @return, 0 on success, -1 on failure
+ */
+int wmi_reg_enum_value(WMI_HANDLE handle, const unsigned int hive,
+                       const char *key, char **res)
+{
+  struct IWbemClassObject *wco = NULL;
+  struct IWbemClassObject *inc, *outc, *in;
+  struct IWbemClassObject *out = NULL;
+  int i = 0;
+  WERROR result;
+  NTSTATUS status;
+  union CIMVAR v;
+  struct IWbemServices *pWS;
+
+  pWS = (struct IWbemServices *) handle;
+  if(pWS->ctx == 0)
+    return -1;
+
+  result = IWbemServices_GetObject(pWS, pWS->ctx, "StdRegProv",
+                                   WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL,
+                                   &wco, NULL);
+  WERR_CHECK("GetObject.");
+
+  result = IWbemClassObject_GetMethod(wco, pWS->ctx, "EnumValues", 0,
+                                      &inc, &outc);
+  WERR_CHECK("IWbemClassObject_GetMethod.");
+
+  result = IWbemClassObject_SpawnInstance(inc, pWS->ctx, 0, &in);
+  WERR_CHECK("IWbemClassObject_SpawnInstance.");
+
+  if(hive)
+    v.v_uint32 = hive;
+  else
+    v.v_uint32 = 0x80000002; // Try default, HKEY_LOCAL_MACHINE
+
+  result = IWbemClassObject_Put(in, pWS->ctx, "hDefKey", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+  v.v_uint32 = 0;
+
+  v.v_string = key;
+  result = IWbemClassObject_Put(in, pWS->ctx, "sSubKeyName", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+  v.v_string = NULL;
+
+  result = IWbemServices_ExecMethod(pWS, pWS->ctx, "StdRegProv", "EnumValues", 0,
+                                    NULL, in, &out, NULL);
+  WERR_CHECK("IWbemServices_ExecMethod.");
+
+  result = WbemClassObject_Get(out->object_data, pWS->ctx, "sNames", 0, &v, 0, 0);
+  if(v.a_string){
+    for (i = 0; i < v.a_string->count; ++i)
+      *res = (char *) talloc_asprintf_append(*res, "%s%s", i?"|":"",
+                                             v.a_string->item[i]);
+  }
+  return 0;
+
+error:
+  status = werror_to_ntstatus(result);
+  DEBUG(3, ("NTSTATUS: %s - %s\n", nt_errstr(status),
+            get_friendly_nt_error_msg(status)));
+  return -1;
+}
+
+
+/**
+ * @brief Get Registry binary value.
+ *
+ * @param[in] handle - WMI connection handle
+ *
+ * @param[in] hive - Registry hive
+ *
+ * @param[in] key - Registry key containing the value to be queried
+ *
+ * @param[in] val_name - Registry value to be queried
+ *
+ * @param[out] res - Result string
+ *
+ * @return, 0 on success, -1 on failure
+ */
+int wmi_reg_get_bin_val(WMI_HANDLE handle, const unsigned int hive, const char *key,
+                        const char *val_name, char **res)
+{
+  struct IWbemClassObject *wco = NULL;
+  struct IWbemClassObject *inc, *outc, *in;
+  struct IWbemClassObject *out = NULL;
+  int i = 0;
+  WERROR result;
+  NTSTATUS status;
+  union CIMVAR v;
+  struct IWbemServices *pWS;
+
+  pWS = (struct IWbemServices *) handle;
+  if(pWS->ctx == 0)
+    return -1;
+
+  result = IWbemServices_GetObject(pWS, pWS->ctx, "StdRegProv",
+                                   WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL,
+                                   &wco, NULL);
+  WERR_CHECK("GetObject.");
+
+  result = IWbemClassObject_GetMethod(wco, pWS->ctx, "GetBinaryValue", 0,
+                                      &inc, &outc);
+  WERR_CHECK("IWbemClassObject_GetMethod.");
+
+  result = IWbemClassObject_SpawnInstance(inc, pWS->ctx, 0, &in);
+  WERR_CHECK("IWbemClassObject_SpawnInstance.");
+
+  if(hive)
+    v.v_uint32 = hive;
+  else
+    v.v_uint32 = 0x80000002; // Try default, HKEY_LOCAL_MACHINE
+
+  result = IWbemClassObject_Put(in, pWS->ctx, "hDefKey", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+
+  v.v_string = key;
+  result = IWbemClassObject_Put(in, pWS->ctx, "sSubKeyName", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+
+  v.v_string = val_name;
+  result = IWbemClassObject_Put(in, pWS->ctx, "sValueName", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+  v.v_string = NULL;
+
+  result = IWbemServices_ExecMethod(pWS, pWS->ctx, "StdRegProv", "GetBinaryValue",
+                                    0, NULL, in, &out, NULL);
+  WERR_CHECK("IWbemServices_ExecMethod.");
+  result = WbemClassObject_Get(out->object_data, pWS->ctx, "uValue", 0, &v, 0, 0);
+  if(v.a_uint8){
+    for (i = 0; i < v.a_uint8->count; ++i){
+      *res = (char *)talloc_asprintf_append(*res, "%0X", v.a_uint8->item[i]);
+    }
+  }
+  return 0;
+
+error:
+  status = werror_to_ntstatus(result);
+  DEBUG(3, ("NTSTATUS: %s - %s\n", nt_errstr(status),
+            get_friendly_nt_error_msg(status)));
+  return 1;
+}
+
+
+/**
+ * @brief Get Registry DWORD value.
+ *
+ * @param[in] handle - WMI connection handle
+ *
+ * @param[in] hive - Registry hive
+ *
+ * @param[in] key - Registry key containing the value to be queried
+ *
+ * @param[in] val_name - Registry value to be queried
+ *
+ * @param[out] res - Result string
+ *
+ * @return, 0 on success, -1 on failure
+ */
+int wmi_reg_get_dword_val(WMI_HANDLE handle, const unsigned int hive, const char *key,
+                          const char *val_name, char **res)
+{
+  struct IWbemClassObject *wco = NULL;
+  struct IWbemClassObject *inc, *outc, *in;
+  struct IWbemClassObject *out = NULL;
+  int i = 0;
+  WERROR result;
+  NTSTATUS status;
+  union CIMVAR v;
+  struct IWbemServices *pWS;
+
+  pWS = (struct IWbemServices *) handle;
+  if(pWS->ctx == 0)
+    return -1;
+  result = IWbemServices_GetObject(pWS, pWS->ctx, "StdRegProv",
+                                   WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL,
+                                   &wco, NULL);
+  WERR_CHECK("GetObject.");
+
+  result = IWbemClassObject_GetMethod(wco, pWS->ctx, "GetDWORDValue", 0,
+                                      &inc, &outc);
+  WERR_CHECK("IWbemClassObject_GetMethod.");
+
+  result = IWbemClassObject_SpawnInstance(inc, pWS->ctx, 0, &in);
+  WERR_CHECK("IWbemClassObject_SpawnInstance.");
+
+  if(hive)
+    v.v_uint32 = hive;
+  else
+    v.v_uint32 = 0x80000002; // Try default, HKEY_LOCAL_MACHINE
+
+  result = IWbemClassObject_Put(in, pWS->ctx, "hDefKey", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+
+  v.v_string = key;
+  result = IWbemClassObject_Put(in, pWS->ctx, "sSubKeyName", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+
+  v.v_string = val_name;
+  result = IWbemClassObject_Put(in, pWS->ctx, "sValueName", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+  v.v_string = NULL;
+
+  result = IWbemServices_ExecMethod(pWS, pWS->ctx, "StdRegProv", "GetDWORDValue",
+                                      0, NULL, in, &out, NULL);
+  WERR_CHECK("IWbemServices_ExecMethod.");
+
+  result = WbemClassObject_Get(out->object_data, pWS->ctx, "uValue", 0,
+                               &v, 0, 0);
+  if(v.v_uint32){
+    *res = talloc_asprintf(pWS->ctx, "%0X", v.v_uint32);
+  }
+  return 0;
+
+error:
+  status = werror_to_ntstatus(result);
+  DEBUG(3, ("NTSTATUS: %s - %s\n", nt_errstr(status),
+            get_friendly_nt_error_msg(status)));
+  return -1;
+}
+
+
+/**
+ * @brief Get Registry Expanded string value.
+ *
+ * @param[in] handle - WMI connection handle
+ *
+ * @param[in] hive - Registry hive
+ *
+ * @param[in] key - Registry key containing the value to be queried
+ *
+ * @param[in] val_name - Registry value to be queried
+ *
+ * @param[out] res - Result string
+ *
+ * @return, 0 on success, -1 on failure
+ */
+int wmi_reg_get_ex_string_val(WMI_HANDLE handle, const unsigned int hive, const char *key,
+                              const char *val_name, char **res)
+{
+  struct IWbemClassObject *wco = NULL;
+  struct IWbemClassObject *inc, *outc, *in;
+  struct IWbemClassObject *out = NULL;
+  int i = 0;
+  WERROR result;
+  NTSTATUS status;
+  union CIMVAR v;
+  struct IWbemServices *pWS;
+
+  pWS = (struct IWbemServices *) handle;
+  if(pWS->ctx == 0)
+    return -1;
+
+  result = IWbemServices_GetObject(pWS, pWS->ctx, "StdRegProv",
+                                   WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL,
+                                   &wco, NULL);
+  WERR_CHECK("GetObject.");
+
+  result = IWbemClassObject_GetMethod(wco, pWS->ctx, "GetExpandedStringValue",
+                                      0, &inc, &outc);
+  WERR_CHECK("IWbemClassObject_GetMethod.");
+
+  result = IWbemClassObject_SpawnInstance(inc, pWS->ctx, 0, &in);
+  WERR_CHECK("IWbemClassObject_SpawnInstance.");
+
+  if(hive)
+    v.v_uint32 = hive;
+  else
+    v.v_uint32 = 0x80000002; // Try default, HKEY_LOCAL_MACHINE
+
+  result = IWbemClassObject_Put(in, pWS->ctx, "hDefKey", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+
+  v.v_string = key;
+  result = IWbemClassObject_Put(in, pWS->ctx, "sSubKeyName", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+
+  v.v_string = val_name;
+  result = IWbemClassObject_Put(in, pWS->ctx, "sValueName", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+  v.v_string = NULL;
+
+  result = IWbemServices_ExecMethod(pWS, pWS->ctx, "StdRegProv",
+                                    "GetExpandedStringValue", 0,
+                                    NULL, in, &out, NULL);
+  WERR_CHECK("IWbemServices_ExecMethod.");
+
+  result = WbemClassObject_Get(out->object_data, pWS->ctx, "sValue", 0, &v,
+                               0, 0);
+  if(v.v_string){
+    *res = talloc_asprintf(pWS->ctx, "%s", v.v_string);
+  }
+  return 0;
+
+error:
+  status = werror_to_ntstatus(result);
+  DEBUG(3, ("NTSTATUS: %s - %s\n", nt_errstr(status),
+            get_friendly_nt_error_msg(status)));
+  return -1;
+}
+
+
+/**
+ * @brief Get Registry multi-valued strings.
+ *
+ * @param[in] handle - WMI connection handle
+ *
+ * @param[in] hive - Registry hive
+ *
+ * @param[in] key - Registry key containing the value to be queried
+ *
+ * @param[in] val_name - Registry value to be queried
+ *
+ * @param[out] res - Result string
+ *
+ * @return, 0 on success, -1 on failure
+ */
+int wmi_reg_get_mul_string_val(WMI_HANDLE handle, const unsigned int hive, const char *key,
+                               const char *val_name, char **res)
+{
+  struct IWbemClassObject *wco = NULL;
+  struct IWbemClassObject *inc, *outc, *in;
+  struct IWbemClassObject *out = NULL;
+  int i = 0;
+  WERROR result;
+  NTSTATUS status;
+  union CIMVAR v;
+  struct IWbemServices *pWS;
+
+  pWS = (struct IWbemServices *) handle;
+  if(pWS->ctx == 0)
+    return -1;
+
+  result = IWbemServices_GetObject(pWS, pWS->ctx, "StdRegProv",
+                                   WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL,
+                                   &wco, NULL);
+  WERR_CHECK("GetObject.");
+
+  result = IWbemClassObject_GetMethod(wco, pWS->ctx, "GetMultiStringValue", 0,
+                                      &inc, &outc);
+  WERR_CHECK("IWbemClassObject_GetMethod.");
+
+  result = IWbemClassObject_SpawnInstance(inc, pWS->ctx, 0, &in);
+  WERR_CHECK("IWbemClassObject_SpawnInstance.");
+
+  if(hive)
+    v.v_uint32 = hive;
+  else
+    v.v_uint32 = 0x80000002; // Try default, HKEY_LOCAL_MACHINE
+
+  result = IWbemClassObject_Put(in, pWS->ctx, "hDefKey", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+  v.v_uint32 = 0;
+
+  v.v_string = key;
+  result = IWbemClassObject_Put(in, pWS->ctx, "sSubKeyName", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+
+  v.v_string = val_name;
+  result = IWbemClassObject_Put(in, pWS->ctx, "sValueName", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+  v.v_string = NULL;
+
+  result = IWbemServices_ExecMethod(pWS, pWS->ctx, "StdRegProv",
+                                    "GetMultiStringValue", 0,
+                                    NULL, in, &out, NULL);
+  WERR_CHECK("IWbemServices_ExecMethod.");
+
+  result = WbemClassObject_Get(out->object_data, pWS->ctx, "sValue", 0,
+                               &v, 0, 0);
+  if(v.a_string){
+    for (i = 0; i < v.a_string->count; ++i)
+      *res = (char *) talloc_asprintf_append(*res, "%s%s", i?"|":"",
+                                             v.a_string->item[i]);
+  }
+  return 0;
+
+error:
+  status = werror_to_ntstatus(result);
+  DEBUG(3, ("NTSTATUS: %s - %s\n", nt_errstr(status),
+            get_friendly_nt_error_msg(status)));
+  return -1;
+}
+
+
+/**
+ * @brief Get Registry QWORD value.
+ *
+ * @param[in] handle - WMI connection handle
+ *
+ * @param[in] hive - Registry hive
+ *
+ * @param[in] key - Registry key containing the value to be queried
+ *
+ * @param[in] val_name - Registry value to be queried
+ *
+ * @param[out] res - Result string
+ *
+ * @return, 0 on success, -1 on failure
+ */
+int wmi_reg_get_qword_val(WMI_HANDLE handle, const unsigned int hive, const char *key,
+                          const char *val_name, char **res)
+{
+  struct IWbemClassObject *wco = NULL;
+  struct IWbemClassObject *inc, *outc, *in;
+  struct IWbemClassObject *out = NULL;
+  int i = 0;
+  WERROR result;
+  NTSTATUS status;
+  union CIMVAR v;
+  struct IWbemServices *pWS;
+
+  pWS = (struct IWbemServices *) handle;
+  if(pWS->ctx == 0)
+    return -1;
+
+  result = IWbemServices_GetObject(pWS, pWS->ctx, "StdRegProv",
+                                   WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL,
+                                   &wco, NULL);
+  WERR_CHECK("GetObject.");
+
+  result = IWbemClassObject_GetMethod(wco, pWS->ctx, "GetQWORDValue", 0,
+                                      &inc, &outc);
+  WERR_CHECK("IWbemClassObject_GetMethod.");
+
+  result = IWbemClassObject_SpawnInstance(inc, pWS->ctx, 0, &in);
+  WERR_CHECK("IWbemClassObject_SpawnInstance.");
+
+  if(hive)
+    v.v_uint32 = hive;
+  else
+    v.v_uint32 = 0x80000002; // Try default, HKEY_LOCAL_MACHINE
+
+  result = IWbemClassObject_Put(in, pWS->ctx, "hDefKey", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+  v.v_uint32 = 0;
+
+  v.v_string = key;
+  result = IWbemClassObject_Put(in, pWS->ctx, "sSubKeyName", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+
+  v.v_string = val_name;
+  result = IWbemClassObject_Put(in, pWS->ctx, "sValueName", 0, &v, 0);
+  WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+  v.v_string = NULL;
+
+  result = IWbemServices_ExecMethod(pWS, pWS->ctx, "StdRegProv", "GetQWORDValue",
+                                    0, NULL, in, &out, NULL);
+  WERR_CHECK("IWbemServices_ExecMethod.");
+
+  result = WbemClassObject_Get(out->object_data, pWS->ctx, "uValue", 0, &v, 0, 0);
+  if(v.v_uint64){
+    *res = talloc_asprintf(pWS->ctx, "%0X", v.v_uint64);
+  }
+
+  return 0;
+
+error:
+  status = werror_to_ntstatus(result);
+  DEBUG(3, ("NTSTATUS: %s - %s\n", nt_errstr(status), get_friendly_nt_error_msg(status)));
+  return -1;
+}
+

