1/* 2 WMI Sample client 3 Copyright (C) 2006 Andrzej Hajda <andrzej.hajda@wp.pl> 4 Copyright (C) 2008 Jelmer Vernooij <jelmer@samba.org> 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19*/ 20 21#include "includes.h" 22#include "lib/cmdline/popt_common.h" 23#include "auth/credentials/credentials.h" 24#include "librpc/rpc/dcerpc.h" 25#include "librpc/gen_ndr/ndr_oxidresolver.h" 26#include "librpc/gen_ndr/ndr_oxidresolver_c.h" 27#include "librpc/gen_ndr/dcom.h" 28#include "librpc/gen_ndr/ndr_dcom.h" 29#include "librpc/gen_ndr/ndr_dcom_c.h" 30#include "librpc/gen_ndr/ndr_remact_c.h" 31#include "librpc/gen_ndr/ndr_epmapper_c.h" 32#include "librpc/gen_ndr/com_dcom.h" 33 34#include "lib/com/dcom/dcom.h" 35#include "librpc/gen_ndr/com_wmi.h" 36#include "librpc/ndr/ndr_table.h" 37 38#include "lib/wmi/wmi.h" 39 40struct program_args { 41 char *hostname; 42 char *query; 43}; 44 45static void parse_args(int argc, char *argv[], struct program_args *pmyargs) 46{ 47 poptContext pc; 48 int opt, i; 49 50 int argc_new; 51 char **argv_new; 52 53 struct poptOption long_options[] = { 54 POPT_AUTOHELP 55 POPT_COMMON_SAMBA 56 POPT_COMMON_CONNECTION 57 POPT_COMMON_CREDENTIALS 58 POPT_COMMON_VERSION 59 POPT_TABLEEND 60 }; 61 62 pc = poptGetContext("wmi", argc, (const char **) argv, 63 long_options, POPT_CONTEXT_KEEP_FIRST); 64 65 poptSetOtherOptionHelp(pc, "//host\n\nExample: wmis -U [domain/]adminuser%password //host"); 66 67 while ((opt = poptGetNextOpt(pc)) != -1) { 68 poptPrintUsage(pc, stdout, 0); 69 poptFreeContext(pc); 70 exit(1); 71 } 72 73 argv_new = discard_const_p(char *, poptGetArgs(pc)); 74 75 argc_new = argc; 76 for (i = 0; i < argc; i++) { 77 if (argv_new[i] == NULL) { 78 argc_new = i; 79 break; 80 } 81 } 82 83 if (argc_new < 2 || argv_new[1][0] != '/' 84 || argv_new[1][1] != '/') { 85 poptPrintUsage(pc, stdout, 0); 86 poptFreeContext(pc); 87 exit(1); 88 } 89 90 pmyargs->hostname = argv_new[1] + 2; 91 poptFreeContext(pc); 92} 93 94#define WERR_CHECK(msg) if (!W_ERROR_IS_OK(result)) { \ 95 DEBUG(0, ("ERROR: %s\n", msg)); \ 96 goto error; \ 97 } else { \ 98 DEBUG(1, ("OK : %s\n", msg)); \ 99 } 100/* 101WERROR 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) 102{ 103 struct GUID clsid; 104 struct GUID iid; 105 WERROR result, coresult; 106 struct IUnknown **mqi; 107 struct IWbemLevel1Login *pL; 108 109 if (user) { 110 char *cred; 111 struct cli_credentials *cc; 112 113 cred = talloc_asprintf(NULL, "%s%%%s", user, password); 114 cc = cli_credentials_init(ctx); 115 cli_credentials_set_conf(cc); 116 cli_credentials_parse_string(cc, cred, CRED_SPECIFIED); 117 dcom_set_server_credentials(ctx, server, cc); 118 talloc_free(cred); 119 } 120 121 GUID_from_string(CLSID_WBEMLEVEL1LOGIN, &clsid); 122 GUID_from_string(COM_IWBEMLEVEL1LOGIN_UUID, &iid); 123 result = dcom_create_object(ctx, &clsid, server, 1, &iid, &mqi, &coresult); 124 WERR_CHECK("dcom_create_object."); 125 result = coresult; 126 WERR_CHECK("Create remote WMI object."); 127 pL = (struct IWbemLevel1Login *)mqi[0]; 128 talloc_free(mqi); 129 130 result = IWbemLevel1Login_NTLMLogin(pL, ctx, nspace, locale, flags, wbem_ctx, services); 131 WERR_CHECK("Login to remote object."); 132error: 133 return result; 134} 135*/ 136WERROR WBEM_RemoteExecute(struct IWbemServices *pWS, const char *cmdline, uint32_t *ret_code) 137{ 138 struct IWbemClassObject *wco = NULL; 139 struct IWbemClassObject *inc, *outc, *in; 140 struct IWbemClassObject *out = NULL; 141 WERROR result; 142 union CIMVAR v; 143 TALLOC_CTX *ctx; 144 struct BSTR objectPath, methodName; 145 146 ctx = talloc_new(0); 147 148 objectPath.data = "Win32_Process"; 149 150 result = IWbemServices_GetObject(pWS, ctx, objectPath, 151 WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL, &wco, NULL); 152 WERR_CHECK("GetObject."); 153 154 result = IWbemClassObject_GetMethod(wco, ctx, "Create", 0, &inc, &outc); 155 WERR_CHECK("IWbemClassObject_GetMethod."); 156 157 result = IWbemClassObject_SpawnInstance(inc, ctx, 0, &in); 158 WERR_CHECK("IWbemClassObject_SpawnInstance."); 159 160 v.v_string = cmdline; 161 result = IWbemClassObject_Put(in, ctx, "CommandLine", 0, &v, 0); 162 WERR_CHECK("IWbemClassObject_Put(CommandLine)."); 163 164 methodName.data = "Create"; 165 result = IWbemServices_ExecMethod(pWS, ctx, objectPath, methodName, 0, NULL, in, &out, 166 NULL); 167 WERR_CHECK("IWbemServices_ExecMethod."); 168 169 if (ret_code) { 170 result = WbemClassObject_Get(out->object_data, ctx, "ReturnValue", 0, &v, 0, 0); 171 WERR_CHECK("IWbemClassObject_Put(CommandLine)."); 172 *ret_code = v.v_uint32; 173 } 174error: 175 talloc_free(ctx); 176 return result; 177} 178 179int main(int argc, char **argv) 180{ 181 struct program_args args = {}; 182 struct com_context *ctx = NULL; 183 WERROR result; 184 NTSTATUS status; 185 struct IWbemServices *pWS = NULL; 186 struct IEnumWbemClassObject *pEnum = NULL; 187 uint32_t cnt; 188 struct BSTR queryLanguage; 189 struct BSTR query; 190 191 parse_args(argc, argv, &args); 192 193 wmi_init(&ctx, cmdline_credentials); 194 result = WBEM_ConnectServer(ctx, args.hostname, "root\\cimv2", 0, 0, 0, 0, 0, 0, &pWS); 195 WERR_CHECK("WBEM_ConnectServer."); 196 197 printf("1: Creating directory C:\\wmi_test_dir_tmp using method Win32_Process.Create\n"); 198 WBEM_RemoteExecute(pWS, "cmd.exe /C mkdir C:\\wmi_test_dir_tmp", &cnt); 199 WERR_CHECK("WBEM_RemoteExecute."); 200 printf("2: ReturnCode: %d\n", cnt); 201 202 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"); 203 query.data = "SELECT * FROM __InstanceOperationEvent WITHIN 1 WHERE Targetinstance ISA 'CIM_DirectoryContainsFile' and TargetInstance.GroupComponent= 'Win32_Directory.Name=\"C:\\\\\\\\wmi_test_dir_tmp\"'"; 204 queryLanguage.data = "WQL"; 205 result = IWbemServices_ExecNotificationQuery(pWS, ctx, queryLanguage, 206 query, WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, NULL, &pEnum); 207 WERR_CHECK("WMI query execute."); 208 for (cnt = 0; cnt < 4; ++cnt) { 209 struct WbemClassObject *co; 210 uint32_t ret; 211 result = IEnumWbemClassObject_SmartNext(pEnum, ctx, 0xFFFFFFFF, 1, &co, &ret); 212 WERR_CHECK("IEnumWbemClassObject_Next."); 213 printf("%s\n", co->obj_class->__CLASS); 214 } 215 216error: 217 status = werror_to_ntstatus(result); 218 fprintf(stderr, "NTSTATUS: %s - %s\n", nt_errstr(status), get_friendly_nt_error_msg(status)); 219 talloc_free(ctx); 220 return 1; 221} 222