PageRenderTime 59ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/source4/torture/libnet/libnet_domain.c

https://github.com/endisd/samba
C | 444 lines | 315 code | 90 blank | 39 comment | 30 complexity | 0d728b3d35be1bb154ef118cc11f094b MD5 | raw file
Possible License(s): GPL-3.0
  1. /*
  2. Unix SMB/CIFS implementation.
  3. Test suite for libnet calls.
  4. Copyright (C) Rafal Szczesniak 2006
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include "includes.h"
  17. #include "lib/cmdline/popt_common.h"
  18. #include "libnet/libnet.h"
  19. #include "librpc/gen_ndr/ndr_samr_c.h"
  20. #include "librpc/gen_ndr/ndr_lsa_c.h"
  21. #include "torture/rpc/rpc.h"
  22. #include "param/param.h"
  23. static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
  24. struct policy_handle *handle, struct lsa_String *domname,
  25. uint32_t *access_mask, struct dom_sid **sid_p)
  26. {
  27. NTSTATUS status;
  28. struct policy_handle h, domain_handle;
  29. struct samr_Connect r1;
  30. struct samr_LookupDomain r2;
  31. struct dom_sid2 *sid = NULL;
  32. struct samr_OpenDomain r3;
  33. printf("connecting\n");
  34. *access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
  35. r1.in.system_name = 0;
  36. r1.in.access_mask = *access_mask;
  37. r1.out.connect_handle = &h;
  38. status = dcerpc_samr_Connect(p, mem_ctx, &r1);
  39. if (!NT_STATUS_IS_OK(status)) {
  40. printf("Connect failed - %s\n", nt_errstr(status));
  41. return false;
  42. }
  43. r2.in.connect_handle = &h;
  44. r2.in.domain_name = domname;
  45. r2.out.sid = &sid;
  46. printf("domain lookup on %s\n", domname->string);
  47. status = dcerpc_samr_LookupDomain(p, mem_ctx, &r2);
  48. if (!NT_STATUS_IS_OK(status)) {
  49. printf("LookupDomain failed - %s\n", nt_errstr(status));
  50. return false;
  51. }
  52. r3.in.connect_handle = &h;
  53. r3.in.access_mask = *access_mask;
  54. r3.in.sid = *sid_p = *r2.out.sid;
  55. r3.out.domain_handle = &domain_handle;
  56. printf("opening domain\n");
  57. status = dcerpc_samr_OpenDomain(p, mem_ctx, &r3);
  58. if (!NT_STATUS_IS_OK(status)) {
  59. printf("OpenDomain failed - %s\n", nt_errstr(status));
  60. return false;
  61. } else {
  62. *handle = domain_handle;
  63. }
  64. return true;
  65. }
  66. static bool test_opendomain_lsa(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
  67. struct policy_handle *handle, struct lsa_String *domname,
  68. uint32_t *access_mask)
  69. {
  70. NTSTATUS status;
  71. struct lsa_OpenPolicy2 open;
  72. struct lsa_ObjectAttribute attr;
  73. struct lsa_QosInfo qos;
  74. *access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
  75. ZERO_STRUCT(attr);
  76. ZERO_STRUCT(qos);
  77. qos.len = 0;
  78. qos.impersonation_level = 2;
  79. qos.context_mode = 1;
  80. qos.effective_only = 0;
  81. attr.sec_qos = &qos;
  82. open.in.system_name = domname->string;
  83. open.in.attr = &attr;
  84. open.in.access_mask = *access_mask;
  85. open.out.handle = handle;
  86. status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &open);
  87. if (!NT_STATUS_IS_OK(status)) {
  88. return false;
  89. }
  90. return true;
  91. }
  92. bool torture_domain_open_lsa(struct torture_context *torture)
  93. {
  94. NTSTATUS status;
  95. bool ret = true;
  96. struct libnet_context *ctx;
  97. struct libnet_DomainOpen r;
  98. struct lsa_Close lsa_close;
  99. struct policy_handle h;
  100. const char *domain_name;
  101. /* we're accessing domain controller so the domain name should be
  102. passed (it's going to be resolved to dc name and address) instead
  103. of specific server name. */
  104. domain_name = lp_workgroup(torture->lp_ctx);
  105. ctx = libnet_context_init(torture->ev, torture->lp_ctx);
  106. if (ctx == NULL) {
  107. d_printf("failed to create libnet context\n");
  108. return false;
  109. }
  110. ctx->cred = cmdline_credentials;
  111. ZERO_STRUCT(r);
  112. r.in.type = DOMAIN_LSA;
  113. r.in.domain_name = domain_name;
  114. r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
  115. status = libnet_DomainOpen(ctx, torture, &r);
  116. if (!NT_STATUS_IS_OK(status)) {
  117. d_printf("failed to open domain on lsa service: %s\n", nt_errstr(status));
  118. ret = false;
  119. goto done;
  120. }
  121. ZERO_STRUCT(lsa_close);
  122. lsa_close.in.handle = &ctx->lsa.handle;
  123. lsa_close.out.handle = &h;
  124. status = dcerpc_lsa_Close(ctx->lsa.pipe, ctx, &lsa_close);
  125. if (!NT_STATUS_IS_OK(status)) {
  126. d_printf("failed to close domain on lsa service: %s\n", nt_errstr(status));
  127. ret = false;
  128. }
  129. done:
  130. talloc_free(ctx);
  131. return ret;
  132. }
  133. bool torture_domain_close_lsa(struct torture_context *torture)
  134. {
  135. bool ret = true;
  136. NTSTATUS status;
  137. TALLOC_CTX *mem_ctx=NULL;
  138. struct libnet_context *ctx;
  139. struct lsa_String domain_name;
  140. struct dcerpc_binding *binding;
  141. uint32_t access_mask;
  142. struct policy_handle h;
  143. struct dcerpc_pipe *p;
  144. struct libnet_DomainClose r;
  145. status = torture_rpc_binding(torture, &binding);
  146. if (!NT_STATUS_IS_OK(status)) {
  147. return false;
  148. }
  149. ctx = libnet_context_init(torture->ev, torture->lp_ctx);
  150. if (ctx == NULL) {
  151. d_printf("failed to create libnet context\n");
  152. ret = false;
  153. goto done;
  154. }
  155. ctx->cred = cmdline_credentials;
  156. mem_ctx = talloc_init("torture_domain_close_lsa");
  157. status = dcerpc_pipe_connect_b(mem_ctx, &p, binding, &ndr_table_lsarpc,
  158. cmdline_credentials, torture->ev, torture->lp_ctx);
  159. if (!NT_STATUS_IS_OK(status)) {
  160. d_printf("failed to connect to server: %s\n", nt_errstr(status));
  161. ret = false;
  162. goto done;
  163. }
  164. domain_name.string = lp_workgroup(torture->lp_ctx);
  165. if (!test_opendomain_lsa(p, torture, &h, &domain_name, &access_mask)) {
  166. d_printf("failed to open domain on lsa service\n");
  167. ret = false;
  168. goto done;
  169. }
  170. ctx->lsa.pipe = p;
  171. ctx->lsa.name = domain_name.string;
  172. ctx->lsa.access_mask = access_mask;
  173. ctx->lsa.handle = h;
  174. /* we have to use pipe's event context, otherwise the call will
  175. hang indefinitely */
  176. ctx->event_ctx = p->conn->event_ctx;
  177. ZERO_STRUCT(r);
  178. r.in.type = DOMAIN_LSA;
  179. r.in.domain_name = domain_name.string;
  180. status = libnet_DomainClose(ctx, mem_ctx, &r);
  181. if (!NT_STATUS_IS_OK(status)) {
  182. ret = false;
  183. goto done;
  184. }
  185. done:
  186. talloc_free(mem_ctx);
  187. talloc_free(ctx);
  188. return ret;
  189. }
  190. bool torture_domain_open_samr(struct torture_context *torture)
  191. {
  192. NTSTATUS status;
  193. struct libnet_context *ctx;
  194. TALLOC_CTX *mem_ctx;
  195. struct policy_handle domain_handle, handle;
  196. struct libnet_DomainOpen io;
  197. struct samr_Close r;
  198. const char *domain_name;
  199. bool ret = true;
  200. mem_ctx = talloc_init("test_domainopen_lsa");
  201. ctx = libnet_context_init(torture->ev, torture->lp_ctx);
  202. ctx->cred = cmdline_credentials;
  203. /* we're accessing domain controller so the domain name should be
  204. passed (it's going to be resolved to dc name and address) instead
  205. of specific server name. */
  206. domain_name = lp_workgroup(torture->lp_ctx);
  207. /*
  208. * Testing synchronous version
  209. */
  210. printf("opening domain\n");
  211. io.in.type = DOMAIN_SAMR;
  212. io.in.domain_name = domain_name;
  213. io.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
  214. status = libnet_DomainOpen(ctx, mem_ctx, &io);
  215. if (!NT_STATUS_IS_OK(status)) {
  216. printf("Composite domain open failed - %s\n", nt_errstr(status));
  217. ret = false;
  218. goto done;
  219. }
  220. domain_handle = ctx->samr.handle;
  221. r.in.handle = &domain_handle;
  222. r.out.handle = &handle;
  223. printf("closing domain handle\n");
  224. status = dcerpc_samr_Close(ctx->samr.pipe, mem_ctx, &r);
  225. if (!NT_STATUS_IS_OK(status)) {
  226. printf("Close failed - %s\n", nt_errstr(status));
  227. ret = false;
  228. goto done;
  229. }
  230. done:
  231. talloc_free(mem_ctx);
  232. talloc_free(ctx);
  233. return ret;
  234. }
  235. bool torture_domain_close_samr(struct torture_context *torture)
  236. {
  237. bool ret = true;
  238. NTSTATUS status;
  239. TALLOC_CTX *mem_ctx = NULL;
  240. struct libnet_context *ctx;
  241. struct lsa_String domain_name;
  242. struct dcerpc_binding *binding;
  243. uint32_t access_mask;
  244. struct policy_handle h;
  245. struct dcerpc_pipe *p;
  246. struct libnet_DomainClose r;
  247. struct dom_sid *sid;
  248. status = torture_rpc_binding(torture, &binding);
  249. if (!NT_STATUS_IS_OK(status)) {
  250. return false;
  251. }
  252. ctx = libnet_context_init(torture->ev, torture->lp_ctx);
  253. if (ctx == NULL) {
  254. d_printf("failed to create libnet context\n");
  255. ret = false;
  256. goto done;
  257. }
  258. ctx->cred = cmdline_credentials;
  259. mem_ctx = talloc_init("torture_domain_close_samr");
  260. status = dcerpc_pipe_connect_b(mem_ctx, &p, binding, &ndr_table_samr,
  261. ctx->cred, torture->ev, torture->lp_ctx);
  262. if (!NT_STATUS_IS_OK(status)) {
  263. d_printf("failed to connect to server: %s\n", nt_errstr(status));
  264. ret = false;
  265. goto done;
  266. }
  267. domain_name.string = talloc_strdup(mem_ctx, lp_workgroup(torture->lp_ctx));
  268. if (!test_opendomain_samr(p, torture, &h, &domain_name, &access_mask, &sid)) {
  269. d_printf("failed to open domain on samr service\n");
  270. ret = false;
  271. goto done;
  272. }
  273. ctx->samr.pipe = p;
  274. ctx->samr.name = talloc_steal(ctx, domain_name.string);
  275. ctx->samr.access_mask = access_mask;
  276. ctx->samr.handle = h;
  277. ctx->samr.sid = talloc_steal(ctx, sid);
  278. /* we have to use pipe's event context, otherwise the call will
  279. hang indefinitely - this wouldn't be the case if pipe was opened
  280. by means of libnet call */
  281. ctx->event_ctx = p->conn->event_ctx;
  282. ZERO_STRUCT(r);
  283. r.in.type = DOMAIN_SAMR;
  284. r.in.domain_name = domain_name.string;
  285. status = libnet_DomainClose(ctx, mem_ctx, &r);
  286. if (!NT_STATUS_IS_OK(status)) {
  287. ret = false;
  288. goto done;
  289. }
  290. done:
  291. talloc_free(mem_ctx);
  292. talloc_free(ctx);
  293. return ret;
  294. }
  295. bool torture_domain_list(struct torture_context *torture)
  296. {
  297. bool ret = true;
  298. NTSTATUS status;
  299. TALLOC_CTX *mem_ctx = NULL;
  300. struct dcerpc_binding *binding;
  301. struct libnet_context *ctx;
  302. struct libnet_DomainList r;
  303. int i;
  304. status = torture_rpc_binding(torture, &binding);
  305. if (!NT_STATUS_IS_OK(status)) {
  306. return false;
  307. }
  308. ctx = libnet_context_init(torture->ev, torture->lp_ctx);
  309. if (ctx == NULL) {
  310. d_printf("failed to create libnet context\n");
  311. ret = false;
  312. goto done;
  313. }
  314. ctx->cred = cmdline_credentials;
  315. mem_ctx = talloc_init("torture_domain_close_samr");
  316. /*
  317. * querying the domain list using default buffer size
  318. */
  319. ZERO_STRUCT(r);
  320. r.in.hostname = binding->host;
  321. status = libnet_DomainList(ctx, mem_ctx, &r);
  322. if (!NT_STATUS_IS_OK(status)) {
  323. ret = false;
  324. goto done;
  325. }
  326. d_printf("Received list or domains (everything in one piece):\n");
  327. for (i = 0; i < r.out.count; i++) {
  328. d_printf("Name[%d]: %s\n", i, r.out.domains[i].name);
  329. }
  330. /*
  331. * querying the domain list using specified (much smaller) buffer size
  332. */
  333. ctx->samr.buf_size = 32;
  334. ZERO_STRUCT(r);
  335. r.in.hostname = binding->host;
  336. status = libnet_DomainList(ctx, mem_ctx, &r);
  337. if (!NT_STATUS_IS_OK(status)) {
  338. ret = false;
  339. goto done;
  340. }
  341. d_printf("Received list or domains (collected in more than one round):\n");
  342. for (i = 0; i < r.out.count; i++) {
  343. d_printf("Name[%d]: %s\n", i, r.out.domains[i].name);
  344. }
  345. done:
  346. d_printf("\nStatus: %s\n", nt_errstr(status));
  347. talloc_free(mem_ctx);
  348. talloc_free(ctx);
  349. return ret;
  350. }