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 |
|
---|
40 | struct program_args {
|
---|
41 | char *hostname;
|
---|
42 | char *query;
|
---|
43 | };
|
---|
44 |
|
---|
45 | static 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 | /*
|
---|
101 | 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)
|
---|
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.");
|
---|
132 | error:
|
---|
133 | return result;
|
---|
134 | }
|
---|
135 | */
|
---|
136 | WERROR 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 | }
|
---|
174 | error:
|
---|
175 | talloc_free(ctx);
|
---|
176 | return result;
|
---|
177 | }
|
---|
178 |
|
---|
179 | int 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 |
|
---|
216 | error:
|
---|
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 | }
|
---|