summaryrefslogtreecommitdiffstats
path: root/source4/lib/wmi/tools
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 17:47:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 17:47:29 +0000
commit4f5791ebd03eaec1c7da0865a383175b05102712 (patch)
tree8ce7b00f7a76baa386372422adebbe64510812d4 /source4/lib/wmi/tools
parentInitial commit. (diff)
downloadsamba-upstream.tar.xz
samba-upstream.zip
Adding upstream version 2:4.17.12+dfsg.upstream/2%4.17.12+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'source4/lib/wmi/tools')
-rw-r--r--source4/lib/wmi/tools/wmic.c221
-rw-r--r--source4/lib/wmi/tools/wmis.c222
2 files changed, 443 insertions, 0 deletions
diff --git a/source4/lib/wmi/tools/wmic.c b/source4/lib/wmi/tools/wmic.c
new file mode 100644
index 0000000..4817dec
--- /dev/null
+++ b/source4/lib/wmi/tools/wmic.c
@@ -0,0 +1,221 @@
+/*
+ WMI Sample client
+ Copyright (C) 2006 Andrzej Hajda <andrzej.hajda@wp.pl>
+ Copyright (C) 2008 Jelmer Vernooij <jelmer@samba.org>
+
+ 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.
+*/
+
+#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 "lib/com/dcom/dcom.h"
+#include "lib/com/com.h"
+
+#include "lib/wmi/wmi.h"
+
+struct program_args {
+ char *hostname;
+ char *query;
+ char *ns;
+};
+
+static void 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
+ {"namespace", 0, POPT_ARG_STRING, &pmyargs->ns, 0,
+ "WMI namespace, default to root\\cimv2", 0},
+ POPT_TABLEEND
+ };
+
+ pc = poptGetContext("wmi", argc, (const char **) argv,
+ long_options, POPT_CONTEXT_KEEP_FIRST);
+
+ poptSetOtherOptionHelp(pc, "//host query\n\nExample: wmic -U [domain/]adminuser%password //host \"select * from Win32_ComputerSystem\"");
+
+ while ((opt = poptGetNextOpt(pc)) != -1) {
+ poptPrintUsage(pc, stdout, 0);
+ poptFreeContext(pc);
+ exit(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] != '/') {
+ poptPrintUsage(pc, stdout, 0);
+ poptFreeContext(pc);
+ exit(1);
+ }
+
+ pmyargs->hostname = argv_new[1] + 2;
+ pmyargs->query = argv_new[2];
+ poptFreeContext(pc);
+}
+
+#define WERR_CHECK(msg) if (!W_ERROR_IS_OK(result)) { \
+ DEBUG(0, ("ERROR: %s\n", msg)); \
+ goto error; \
+ } else { \
+ DEBUG(1, ("OK : %s\n", msg)); \
+ }
+
+#define RETURN_CVAR_ARRAY_STR(fmt, arr) {\
+ uint32_t i;\
+ char *r;\
+\
+ if (!arr) {\
+ return talloc_strdup(mem_ctx, "NULL");\
+ }\
+ r = talloc_strdup(mem_ctx, "(");\
+ for (i = 0; i < arr->count; ++i) {\
+ r = talloc_asprintf_append(r, fmt "%s", arr->item[i], (i+1 == arr->count)?"":",");\
+ }\
+ return talloc_asprintf_append(r, ")");\
+}
+
+char *string_CIMVAR(TALLOC_CTX *mem_ctx, union CIMVAR *v, enum CIMTYPE_ENUMERATION cimtype)
+{
+ 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, "%f", (double)v->v_uint32);
+ case CIM_REAL64: return talloc_asprintf(mem_ctx, "%f", (double)v->v_uint64);
+ 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_SINT8: RETURN_CVAR_ARRAY_STR("%d", v->a_sint8);
+ case CIM_ARR_UINT8: RETURN_CVAR_ARRAY_STR("%u", v->a_uint8);
+ case CIM_ARR_SINT16: RETURN_CVAR_ARRAY_STR("%d", v->a_sint16);
+ case CIM_ARR_UINT16: RETURN_CVAR_ARRAY_STR("%u", v->a_uint16);
+ case CIM_ARR_SINT32: RETURN_CVAR_ARRAY_STR("%d", v->a_sint32);
+ case CIM_ARR_UINT32: RETURN_CVAR_ARRAY_STR("%u", v->a_uint32);
+ case CIM_ARR_SINT64: RETURN_CVAR_ARRAY_STR("%lld", v->a_sint64);
+ case CIM_ARR_UINT64: RETURN_CVAR_ARRAY_STR("%llu", v->a_uint64);
+ case CIM_ARR_REAL32: RETURN_CVAR_ARRAY_STR("%f", v->a_real32);
+ case CIM_ARR_REAL64: RETURN_CVAR_ARRAY_STR("%f", v->a_real64);
+ case CIM_ARR_BOOLEAN: RETURN_CVAR_ARRAY_STR("%d", v->a_boolean);
+ case CIM_ARR_STRING: RETURN_CVAR_ARRAY_STR("%s", v->a_string);
+ case CIM_ARR_DATETIME: RETURN_CVAR_ARRAY_STR("%s", v->a_datetime);
+ case CIM_ARR_REFERENCE: RETURN_CVAR_ARRAY_STR("%s", v->a_reference);
+ default: return talloc_asprintf(mem_ctx, "Unsupported");
+ }
+}
+
+#undef RETURN_CVAR_ARRAY_STR
+
+int main(int argc, char **argv)
+{
+ struct program_args args = {};
+ uint32_t cnt = 5, ret;
+ char *class_name = NULL;
+ WERROR result;
+ NTSTATUS status;
+ struct IWbemServices *pWS = NULL;
+ struct BSTR queryLanguage, query;
+ struct IEnumWbemClassObject *pEnum = NULL;
+ struct com_context *ctx = NULL;
+
+ parse_args(argc, argv, &args);
+
+ wmi_init(&ctx, popt_get_cmdline_credentials());
+
+ if (!args.ns)
+ args.ns = "root\\cimv2";
+ result = WBEM_ConnectServer(ctx, args.hostname, args.ns, 0, 0, 0, 0, 0, 0, &pWS);
+ WERR_CHECK("Login to remote object.");
+
+ queryLanguage.data = "WQL";
+ query.data = args.query;
+ result = IWbemServices_ExecQuery(pWS, ctx, queryLanguage, query, WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_ENSURE_LOCATABLE, NULL, &pEnum);
+ WERR_CHECK("WMI query execute.");
+
+ IEnumWbemClassObject_Reset(pEnum, ctx);
+ WERR_CHECK("Reset result of WMI query.");
+
+ do {
+ uint32_t i, j;
+ struct WbemClassObject *co[cnt];
+
+ result = IEnumWbemClassObject_SmartNext(pEnum, ctx, 0xFFFFFFFF, cnt, co, &ret);
+ /* WERR_INVALID_FUNCTION is OK, it means only that there is less returned objects than requested */
+ if (!W_ERROR_EQUAL(result, WERR_INVALID_FUNCTION)) {
+ WERR_CHECK("Retrieve result data.");
+ } else {
+ DEBUG(1, ("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(ctx, co[i]->obj_class->__CLASS);
+ printf("CLASS: %s\n", class_name);
+ for (j = 0; j < co[i]->obj_class->__PROPERTY_COUNT; ++j)
+ printf("%s%s", j?"|":"", co[i]->obj_class->properties[j].property.name);
+ printf("\n");
+ }
+ for (j = 0; j < co[i]->obj_class->__PROPERTY_COUNT; ++j) {
+ char *s;
+ s = string_CIMVAR(ctx, &co[i]->instance->data[j], co[i]->obj_class->properties[j].property.desc->cimtype & CIM_TYPEMASK);
+ printf("%s%s", j?"|":"", s);
+ }
+ printf("\n");
+ }
+ } while (ret == cnt);
+ talloc_free(ctx);
+ return 0;
+error:
+ status = werror_to_ntstatus(result);
+ fprintf(stderr, "NTSTATUS: %s - %s\n", nt_errstr(status), get_friendly_nt_error_msg(status));
+ talloc_free(ctx);
+ return 1;
+}
diff --git a/source4/lib/wmi/tools/wmis.c b/source4/lib/wmi/tools/wmis.c
new file mode 100644
index 0000000..395cec2
--- /dev/null
+++ b/source4/lib/wmi/tools/wmis.c
@@ -0,0 +1,222 @@
+/*
+ WMI Sample client
+ Copyright (C) 2006 Andrzej Hajda <andrzej.hajda@wp.pl>
+ Copyright (C) 2008 Jelmer Vernooij <jelmer@samba.org>
+
+ 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.
+*/
+
+#include "includes.h"
+#include "lib/cmdline/popt_common.h"
+#include "auth/credentials/credentials.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/dcom.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 "lib/com/dcom/dcom.h"
+#include "librpc/gen_ndr/com_wmi.h"
+#include "librpc/ndr/ndr_table.h"
+
+#include "lib/wmi/wmi.h"
+
+struct program_args {
+ char *hostname;
+ char *query;
+};
+
+static void 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("wmi", argc, (const char **) argv,
+ long_options, POPT_CONTEXT_KEEP_FIRST);
+
+ poptSetOtherOptionHelp(pc, "//host\n\nExample: wmis -U [domain/]adminuser%password //host");
+
+ while ((opt = poptGetNextOpt(pc)) != -1) {
+ poptPrintUsage(pc, stdout, 0);
+ poptFreeContext(pc);
+ exit(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] != '/') {
+ poptPrintUsage(pc, stdout, 0);
+ poptFreeContext(pc);
+ exit(1);
+ }
+
+ pmyargs->hostname = argv_new[1] + 2;
+ poptFreeContext(pc);
+}
+
+#define WERR_CHECK(msg) if (!W_ERROR_IS_OK(result)) { \
+ DEBUG(0, ("ERROR: %s\n", msg)); \
+ goto error; \
+ } else { \
+ DEBUG(1, ("OK : %s\n", msg)); \
+ }
+/*
+WERROR WBEM_ConnectServer(struct com_context *ctx, const char *server, const char *nspace, const char *user, const char *password, const char *locale, uint32_t flags, const char *authority, struct IWbemContext* wbem_ctx, struct IWbemServices** services)
+{
+ struct GUID clsid;
+ struct GUID iid;
+ WERROR result;
+ HRESULT coresult;
+ struct IUnknown **mqi;
+ struct IWbemLevel1Login *pL;
+
+ if (user) {
+ char *cred;
+ struct cli_credentials *cc;
+
+ cred = talloc_asprintf(NULL, "%s%%%s", user, password);
+ cc = cli_credentials_init(ctx);
+ cli_credentials_set_conf(cc);
+ cli_credentials_parse_string(cc, cred, CRED_SPECIFIED);
+ dcom_set_server_credentials(ctx, server, cc);
+ talloc_free(cred);
+ }
+
+ GUID_from_string(CLSID_WBEMLEVEL1LOGIN, &clsid);
+ GUID_from_string(COM_IWBEMLEVEL1LOGIN_UUID, &iid);
+ result = dcom_create_object(ctx, &clsid, server, 1, &iid, &mqi, &coresult);
+ WERR_CHECK("dcom_create_object.");
+ result = coresult;
+ WERR_CHECK("Create remote WMI object.");
+ pL = (struct IWbemLevel1Login *)mqi[0];
+ talloc_free(mqi);
+
+ result = IWbemLevel1Login_NTLMLogin(pL, ctx, nspace, locale, flags, wbem_ctx, services);
+ WERR_CHECK("Login to remote object.");
+error:
+ return result;
+}
+*/
+WERROR WBEM_RemoteExecute(struct IWbemServices *pWS, const char *cmdline, uint32_t *ret_code)
+{
+ struct IWbemClassObject *wco = NULL;
+ struct IWbemClassObject *inc, *outc, *in;
+ struct IWbemClassObject *out = NULL;
+ WERROR result;
+ union CIMVAR v;
+ TALLOC_CTX *ctx;
+ struct BSTR objectPath, methodName;
+
+ ctx = talloc_new(0);
+
+ objectPath.data = "Win32_Process";
+
+ result = IWbemServices_GetObject(pWS, ctx, objectPath,
+ WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL, &wco, NULL);
+ WERR_CHECK("GetObject.");
+
+ result = IWbemClassObject_GetMethod(wco, ctx, "Create", 0, &inc, &outc);
+ WERR_CHECK("IWbemClassObject_GetMethod.");
+
+ result = IWbemClassObject_SpawnInstance(inc, ctx, 0, &in);
+ WERR_CHECK("IWbemClassObject_SpawnInstance.");
+
+ v.v_string = cmdline;
+ result = IWbemClassObject_Put(in, ctx, "CommandLine", 0, &v, 0);
+ WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+
+ methodName.data = "Create";
+ result = IWbemServices_ExecMethod(pWS, ctx, objectPath, methodName, 0, NULL, in, &out,
+ NULL);
+ WERR_CHECK("IWbemServices_ExecMethod.");
+
+ if (ret_code) {
+ result = WbemClassObject_Get(out->object_data, ctx, "ReturnValue", 0, &v, 0, 0);
+ WERR_CHECK("IWbemClassObject_Put(CommandLine).");
+ *ret_code = v.v_uint32;
+ }
+error:
+ talloc_free(ctx);
+ return result;
+}
+
+int main(int argc, char **argv)
+{
+ struct program_args args = {};
+ struct com_context *ctx = NULL;
+ WERROR result;
+ NTSTATUS status;
+ struct IWbemServices *pWS = NULL;
+ struct IEnumWbemClassObject *pEnum = NULL;
+ uint32_t cnt;
+ struct BSTR queryLanguage;
+ struct BSTR query;
+
+ parse_args(argc, argv, &args);
+
+ wmi_init(&ctx, popt_get_cmdline_credentials());
+ result = WBEM_ConnectServer(ctx, args.hostname, "root\\cimv2", 0, 0, 0, 0, 0, 0, &pWS);
+ WERR_CHECK("WBEM_ConnectServer.");
+
+ printf("1: Creating directory C:\\wmi_test_dir_tmp using method Win32_Process.Create\n");
+ WBEM_RemoteExecute(pWS, "cmd.exe /C mkdir C:\\wmi_test_dir_tmp", &cnt);
+ WERR_CHECK("WBEM_RemoteExecute.");
+ printf("2: ReturnCode: %d\n", cnt);
+
+ printf("3: Monitoring directory C:\\wmi_test_dir_tmp. Please create/delete files in that directory to see notifications, after 4 events program quits.\n");
+ query.data = "SELECT * FROM __InstanceOperationEvent WITHIN 1 WHERE Targetinstance ISA 'CIM_DirectoryContainsFile' and TargetInstance.GroupComponent= 'Win32_Directory.Name=\"C:\\\\\\\\wmi_test_dir_tmp\"'";
+ queryLanguage.data = "WQL";
+ result = IWbemServices_ExecNotificationQuery(pWS, ctx, queryLanguage,
+ query, WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, NULL, &pEnum);
+ WERR_CHECK("WMI query execute.");
+ for (cnt = 0; cnt < 4; ++cnt) {
+ struct WbemClassObject *co;
+ uint32_t ret;
+ result = IEnumWbemClassObject_SmartNext(pEnum, ctx, 0xFFFFFFFF, 1, &co, &ret);
+ WERR_CHECK("IEnumWbemClassObject_Next.");
+ printf("%s\n", co->obj_class->__CLASS);
+ }
+
+error:
+ status = werror_to_ntstatus(result);
+ fprintf(stderr, "NTSTATUS: %s - %s\n", nt_errstr(status), get_friendly_nt_error_msg(status));
+ talloc_free(ctx);
+ return 1;
+}