diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 17:47:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 17:47:29 +0000 |
commit | 4f5791ebd03eaec1c7da0865a383175b05102712 (patch) | |
tree | 8ce7b00f7a76baa386372422adebbe64510812d4 /source4/lib/wmi/tools | |
parent | Initial commit. (diff) | |
download | samba-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.c | 221 | ||||
-rw-r--r-- | source4/lib/wmi/tools/wmis.c | 222 |
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; +} |