PageRenderTime 32ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/samba-3.6.6/source3/utils/net_printing.c

#
C | 376 lines | 292 code | 58 blank | 26 comment | 39 complexity | 8c700e77bad2a78b6a8928cfa3b877c0 MD5 | raw file
Possible License(s): GPL-3.0, Apache-2.0, BSD-3-Clause
  1. /*
  2. Samba Unix/Linux SMB client library
  3. Distributed SMB/CIFS Server Management Utility
  4. Local printing tdb migration interface
  5. Copyright (C) Guenther Deschner 2010
  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 3 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "includes.h"
  18. #include "system/filesys.h"
  19. #include "utils/net.h"
  20. #include "rpc_client/rpc_client.h"
  21. #include "rpc_client/cli_pipe.h"
  22. #include "librpc/gen_ndr/ndr_ntprinting.h"
  23. #include "librpc/gen_ndr/ndr_spoolss.h"
  24. #include "../libcli/security/security.h"
  25. #include "../librpc/gen_ndr/ndr_security.h"
  26. #include "../librpc/gen_ndr/ndr_winreg.h"
  27. #include "util_tdb.h"
  28. #include "printing/nt_printing_migrate.h"
  29. #define FORMS_PREFIX "FORMS/"
  30. #define DRIVERS_PREFIX "DRIVERS/"
  31. #define PRINTERS_PREFIX "PRINTERS/"
  32. #define SECDESC_PREFIX "SECDESC/"
  33. static void dump_form(TALLOC_CTX *mem_ctx,
  34. const char *key_name,
  35. unsigned char *data,
  36. size_t length)
  37. {
  38. enum ndr_err_code ndr_err;
  39. DATA_BLOB blob;
  40. char *s;
  41. struct ntprinting_form r;
  42. printf("found form: %s\n", key_name);
  43. blob = data_blob_const(data, length);
  44. ZERO_STRUCT(r);
  45. ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
  46. (ndr_pull_flags_fn_t)ndr_pull_ntprinting_form);
  47. if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
  48. d_fprintf(stderr, _("form pull failed: %s\n"),
  49. ndr_errstr(ndr_err));
  50. return;
  51. }
  52. s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_form, &r);
  53. if (s) {
  54. printf("%s\n", s);
  55. }
  56. }
  57. static void dump_driver(TALLOC_CTX *mem_ctx,
  58. const char *key_name,
  59. unsigned char *data,
  60. size_t length)
  61. {
  62. enum ndr_err_code ndr_err;
  63. DATA_BLOB blob;
  64. char *s;
  65. struct ntprinting_driver r;
  66. printf("found driver: %s\n", key_name);
  67. blob = data_blob_const(data, length);
  68. ZERO_STRUCT(r);
  69. ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
  70. (ndr_pull_flags_fn_t)ndr_pull_ntprinting_driver);
  71. if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
  72. d_fprintf(stderr, _("driver pull failed: %s\n"),
  73. ndr_errstr(ndr_err));
  74. return;
  75. }
  76. s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_driver, &r);
  77. if (s) {
  78. printf("%s\n", s);
  79. }
  80. }
  81. static void dump_printer(TALLOC_CTX *mem_ctx,
  82. const char *key_name,
  83. unsigned char *data,
  84. size_t length)
  85. {
  86. enum ndr_err_code ndr_err;
  87. DATA_BLOB blob;
  88. char *s;
  89. struct ntprinting_printer r;
  90. printf("found printer: %s\n", key_name);
  91. blob = data_blob_const(data, length);
  92. ZERO_STRUCT(r);
  93. ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
  94. (ndr_pull_flags_fn_t)ndr_pull_ntprinting_printer);
  95. if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
  96. d_fprintf(stderr, _("printer pull failed: %s\n"),
  97. ndr_errstr(ndr_err));
  98. return;
  99. }
  100. s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_printer, &r);
  101. if (s) {
  102. printf("%s\n", s);
  103. }
  104. }
  105. static void dump_sd(TALLOC_CTX *mem_ctx,
  106. const char *key_name,
  107. unsigned char *data,
  108. size_t length)
  109. {
  110. enum ndr_err_code ndr_err;
  111. DATA_BLOB blob;
  112. char *s;
  113. struct sec_desc_buf r;
  114. printf("found security descriptor: %s\n", key_name);
  115. blob = data_blob_const(data, length);
  116. ZERO_STRUCT(r);
  117. ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
  118. (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
  119. if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
  120. d_fprintf(stderr, _("security descriptor pull failed: %s\n"),
  121. ndr_errstr(ndr_err));
  122. return;
  123. }
  124. s = NDR_PRINT_STRUCT_STRING(mem_ctx, sec_desc_buf, &r);
  125. if (s) {
  126. printf("%s\n", s);
  127. }
  128. }
  129. static int net_printing_dump(struct net_context *c, int argc,
  130. const char **argv)
  131. {
  132. int ret = -1;
  133. TALLOC_CTX *ctx = talloc_stackframe();
  134. TDB_CONTEXT *tdb;
  135. TDB_DATA kbuf, newkey, dbuf;
  136. if (argc < 1 || c->display_usage) {
  137. d_fprintf(stderr, "%s\nnet printing dump <file.tdb>\n",
  138. _("Usage:"));
  139. goto done;
  140. }
  141. tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0600);
  142. if (!tdb) {
  143. d_fprintf(stderr, _("failed to open tdb file: %s\n"), argv[0]);
  144. goto done;
  145. }
  146. for (kbuf = tdb_firstkey(tdb);
  147. kbuf.dptr;
  148. newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf=newkey)
  149. {
  150. dbuf = tdb_fetch(tdb, kbuf);
  151. if (!dbuf.dptr) {
  152. continue;
  153. }
  154. if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
  155. dump_form(ctx, (const char *)kbuf.dptr+strlen(FORMS_PREFIX), dbuf.dptr, dbuf.dsize);
  156. SAFE_FREE(dbuf.dptr);
  157. continue;
  158. }
  159. if (strncmp((const char *)kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
  160. dump_driver(ctx, (const char *)kbuf.dptr+strlen(DRIVERS_PREFIX), dbuf.dptr, dbuf.dsize);
  161. SAFE_FREE(dbuf.dptr);
  162. continue;
  163. }
  164. if (strncmp((const char *)kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
  165. dump_printer(ctx, (const char *)kbuf.dptr+strlen(PRINTERS_PREFIX), dbuf.dptr, dbuf.dsize);
  166. SAFE_FREE(dbuf.dptr);
  167. continue;
  168. }
  169. if (strncmp((const char *)kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
  170. dump_sd(ctx, (const char *)kbuf.dptr+strlen(SECDESC_PREFIX), dbuf.dptr, dbuf.dsize);
  171. SAFE_FREE(dbuf.dptr);
  172. continue;
  173. }
  174. }
  175. ret = 0;
  176. done:
  177. talloc_free(ctx);
  178. return ret;
  179. }
  180. static NTSTATUS printing_migrate_internal(struct net_context *c,
  181. const struct dom_sid *domain_sid,
  182. const char *domain_name,
  183. struct cli_state *cli,
  184. struct rpc_pipe_client *winreg_pipe,
  185. TALLOC_CTX *mem_ctx,
  186. int argc,
  187. const char **argv)
  188. {
  189. TALLOC_CTX *tmp_ctx;
  190. TDB_CONTEXT *tdb;
  191. TDB_DATA kbuf, newkey, dbuf;
  192. NTSTATUS status;
  193. tmp_ctx = talloc_new(mem_ctx);
  194. if (tmp_ctx == NULL) {
  195. return NT_STATUS_NO_MEMORY;
  196. }
  197. tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0600);
  198. if (tdb == NULL) {
  199. d_fprintf(stderr, _("failed to open tdb file: %s\n"), argv[0]);
  200. status = NT_STATUS_NO_SUCH_FILE;
  201. goto done;
  202. }
  203. for (kbuf = tdb_firstkey(tdb);
  204. kbuf.dptr;
  205. newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
  206. {
  207. dbuf = tdb_fetch(tdb, kbuf);
  208. if (!dbuf.dptr) {
  209. continue;
  210. }
  211. if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
  212. printing_tdb_migrate_form(tmp_ctx,
  213. winreg_pipe,
  214. (const char *) kbuf.dptr + strlen(FORMS_PREFIX),
  215. dbuf.dptr,
  216. dbuf.dsize);
  217. SAFE_FREE(dbuf.dptr);
  218. continue;
  219. }
  220. if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
  221. printing_tdb_migrate_driver(tmp_ctx,
  222. winreg_pipe,
  223. (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
  224. dbuf.dptr,
  225. dbuf.dsize);
  226. SAFE_FREE(dbuf.dptr);
  227. continue;
  228. }
  229. if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
  230. printing_tdb_migrate_printer(tmp_ctx,
  231. winreg_pipe,
  232. (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX),
  233. dbuf.dptr,
  234. dbuf.dsize);
  235. SAFE_FREE(dbuf.dptr);
  236. continue;
  237. }
  238. SAFE_FREE(dbuf.dptr);
  239. }
  240. for (kbuf = tdb_firstkey(tdb);
  241. kbuf.dptr;
  242. newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
  243. {
  244. dbuf = tdb_fetch(tdb, kbuf);
  245. if (!dbuf.dptr) {
  246. continue;
  247. }
  248. if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
  249. printing_tdb_migrate_secdesc(tmp_ctx,
  250. winreg_pipe,
  251. (const char *) kbuf.dptr + strlen(SECDESC_PREFIX),
  252. dbuf.dptr,
  253. dbuf.dsize);
  254. SAFE_FREE(dbuf.dptr);
  255. continue;
  256. }
  257. SAFE_FREE(dbuf.dptr);
  258. }
  259. status = NT_STATUS_OK;
  260. done:
  261. talloc_free(tmp_ctx);
  262. return status;
  263. }
  264. static int net_printing_migrate(struct net_context *c,
  265. int argc,
  266. const char **argv)
  267. {
  268. if (argc < 1 || c->display_usage) {
  269. d_printf( "%s\n"
  270. "net printing migrate <file.tdb>\n"
  271. " %s\n",
  272. _("Usage:"),
  273. _("Migrate tdb printing files to new storage"));
  274. return 0;
  275. }
  276. return run_rpc_command(c,
  277. NULL,
  278. &ndr_table_winreg.syntax_id,
  279. 0,
  280. printing_migrate_internal,
  281. argc,
  282. argv);
  283. }
  284. /**
  285. * 'net printing' entrypoint.
  286. * @param argc Standard main() style argc.
  287. * @param argv Standard main() style argv. Initial components are already
  288. * stripped.
  289. **/
  290. int net_printing(struct net_context *c, int argc, const char **argv)
  291. {
  292. int ret = -1;
  293. struct functable func[] = {
  294. {
  295. "dump",
  296. net_printing_dump,
  297. NET_TRANSPORT_LOCAL,
  298. N_("Dump printer databases"),
  299. N_("net printing dump\n"
  300. " Dump tdb printing file")
  301. },
  302. {
  303. "migrate",
  304. net_printing_migrate,
  305. NET_TRANSPORT_LOCAL | NET_TRANSPORT_RPC,
  306. N_("Migrate printer databases"),
  307. N_("net printing migrate\n"
  308. " Migrate tdb printing files to new storage")
  309. },
  310. { NULL, NULL, 0, NULL, NULL }
  311. };
  312. ret = net_run_function(c, argc, argv, "net printing", func);
  313. return ret;
  314. }