summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2004-10-13 01:40:35 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:52:57 -0500
commit3eff1f48d5806aeb0347f13c50e7620bbdc04dd5 (patch)
tree8720d02fa53dd9e11cd4d461264757e2785c9730 /source3
parente66c8217f8c8944fde00e3cb944d7d27065c40a9 (diff)
downloadsamba-3eff1f48d5806aeb0347f13c50e7620bbdc04dd5.tar.gz
samba-3eff1f48d5806aeb0347f13c50e7620bbdc04dd5.tar.bz2
samba-3eff1f48d5806aeb0347f13c50e7620bbdc04dd5.zip
r2942: Add client-side support of triggering ads printer publishing over msrpc
setprinter calls inside the net-tool. This is usefull to mimic the same queries a windows-client does. At least win2k returns WERR_IO_PENDING when printer is published via setprinter, samba returns WERR_OK but this does not hurt. Guenther (This used to be commit 69b745fb98b8054d1f52e8a3fe3b933fb04336db)
Diffstat (limited to 'source3')
-rw-r--r--source3/include/doserr.h1
-rw-r--r--source3/libsmb/doserr.c1
-rw-r--r--source3/utils/net_help.c3
-rw-r--r--source3/utils/net_rpc.c102
-rw-r--r--source3/utils/net_rpc_printer.c188
5 files changed, 295 insertions, 0 deletions
diff --git a/source3/include/doserr.h b/source3/include/doserr.h
index 576aeda2bf..c6d6b1fac9 100644
--- a/source3/include/doserr.h
+++ b/source3/include/doserr.h
@@ -183,6 +183,7 @@
#define WERR_NO_MORE_ITEMS W_ERROR(259)
#define WERR_MORE_DATA W_ERROR(234)
#define WERR_INVALID_OWNER W_ERROR(1307)
+#define WERR_IO_PENDING W_ERROR(997)
#define WERR_CAN_NOT_COMPLETE W_ERROR(1003)
#define WERR_INVALID_SECURITY_DESCRIPTOR W_ERROR(1338)
#define WERR_SERVER_UNAVAILABLE W_ERROR(1722)
diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c
index c6348568cf..96c052c7c5 100644
--- a/source3/libsmb/doserr.c
+++ b/source3/libsmb/doserr.c
@@ -68,6 +68,7 @@ werror_code_struct dos_errs[] =
{ "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR },
{ "WERR_INVALID_OWNER", WERR_INVALID_OWNER },
{ "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE },
+ { "WERR_IO_PENDING", WERR_IO_PENDING },
{ NULL, W_ERROR(0) }
};
diff --git a/source3/utils/net_help.c b/source3/utils/net_help.c
index 4b19bcf5aa..cc5208b821 100644
--- a/source3/utils/net_help.c
+++ b/source3/utils/net_help.c
@@ -176,6 +176,9 @@ int net_help_printer(int argc, const char **argv)
"\tlists all printers on print-server\n\n");
d_printf("net rpc printer DRIVER [printer] [misc. options] [targets]\n"\
"\tlists all printer-drivers on print-server\n\n");
+ d_printf("net rpc printer PUBLISH action [printer] [misc. options] [targets]\n"\
+ "\tpublishes printer settings in Active Directory\n"
+ "\taction can be one of PUBLISH, UPDATE, UNPUBLISH or LIST\n\n");
d_printf("net rpc printer MIGRATE PRINTERS [printer] [misc. options] [targets]"\
"\n\tmigrates printers from remote to local server\n\n");
d_printf("net rpc printer MIGRATE SETTINGS [printer] [misc. options] [targets]"\
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index 018731afda..295c8c5853 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -3,6 +3,7 @@
Distributed SMB/CIFS Server Management Utility
Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
Copyright (C) 2002 Jim McDonough (jmcd@us.ibm.com)
+ Copyright (C) 2004 Guenther Deschner (gd@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
@@ -5045,6 +5046,106 @@ static int rpc_printer_driver_list(int argc, const char **argv)
}
/**
+ * Publish printer in ADS via MSRPC
+ *
+ * @param argc Standard main() style argc
+ * @param argv Standard main() style argv. Initial components are already
+ * stripped
+ *
+ * @return A shell status integer (0 for success)
+ **/
+static int rpc_printer_publish_publish(int argc, const char **argv)
+{
+
+ return run_rpc_command(NULL, PI_SPOOLSS, 0,
+ rpc_printer_publish_publish_internals,
+ argc, argv);
+}
+
+/**
+ * Update printer in ADS via MSRPC
+ *
+ * @param argc Standard main() style argc
+ * @param argv Standard main() style argv. Initial components are already
+ * stripped
+ *
+ * @return A shell status integer (0 for success)
+ **/
+static int rpc_printer_publish_update(int argc, const char **argv)
+{
+
+ return run_rpc_command(NULL, PI_SPOOLSS, 0,
+ rpc_printer_publish_update_internals,
+ argc, argv);
+}
+
+/**
+ * UnPublish printer in ADS via MSRPC
+ *
+ * @param argc Standard main() style argc
+ * @param argv Standard main() style argv. Initial components are already
+ * stripped
+ *
+ * @return A shell status integer (0 for success)
+ **/
+static int rpc_printer_publish_unpublish(int argc, const char **argv)
+{
+
+ return run_rpc_command(NULL, PI_SPOOLSS, 0,
+ rpc_printer_publish_unpublish_internals,
+ argc, argv);
+}
+
+/**
+ * List published printers via MSRPC
+ *
+ * @param argc Standard main() style argc
+ * @param argv Standard main() style argv. Initial components are already
+ * stripped
+ *
+ * @return A shell status integer (0 for success)
+ **/
+static int rpc_printer_publish_list(int argc, const char **argv)
+{
+
+ return run_rpc_command(NULL, PI_SPOOLSS, 0,
+ rpc_printer_publish_list_internals,
+ argc, argv);
+}
+
+
+/**
+ * Publish printer in ADS
+ *
+ * @param argc Standard main() style argc
+ * @param argv Standard main() style argv. Initial components are already
+ * stripped
+ *
+ * @return A shell status integer (0 for success)
+ **/
+static int rpc_printer_publish(int argc, const char **argv)
+{
+
+ struct functable func[] = {
+ {"publish", rpc_printer_publish_publish},
+ {"update", rpc_printer_publish_update},
+ {"unpublish", rpc_printer_publish_unpublish},
+ {"list", rpc_printer_publish_list},
+ {"help", rpc_printer_usage},
+ {NULL, NULL}
+ };
+
+ if (argc == 0)
+ return run_rpc_command(NULL, PI_SPOOLSS, 0,
+ rpc_printer_publish_list_internals,
+ argc, argv);
+
+ return net_run_function(argc, argv, func, rpc_printer_usage);
+
+}
+
+
+/**
* Display rpc printer help page.
* @param argc Standard main() style argc
* @param argv Standard main() style argv. Initial components are already
@@ -5067,6 +5168,7 @@ int net_rpc_printer(int argc, const char **argv)
{"list", rpc_printer_list},
{"migrate", rpc_printer_migrate},
{"driver", rpc_printer_driver_list},
+ {"publish", rpc_printer_publish},
{NULL, NULL}
};
diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c
index f470d8b6d9..a7e0ebeb6c 100644
--- a/source3/utils/net_rpc_printer.c
+++ b/source3/utils/net_rpc_printer.c
@@ -1288,6 +1288,194 @@ done:
}
+/**
+ * Publish print-queues with args-wrapper
+ *
+ * @param cli A cli_state connected to the server.
+ * @param mem_ctx Talloc context, destoyed on compleation of the function.
+ * @param argc Standard main() style argc
+ * @param argv Standard main() style argv. Initial components are already
+ * stripped
+ * @param action
+ *
+ * @return Normal NTSTATUS return.
+ **/
+
+static NTSTATUS rpc_printer_publish_internals_args(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv, uint32 action)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ uint32 i, num_printers;
+ uint32 level = 7;
+ pstring printername, sharename;
+ PRINTER_INFO_CTR ctr, ctr_pub;
+ POLICY_HND hnd;
+ BOOL got_hnd = False;
+ WERROR result;
+ char *action_str;
+
+ if (!get_printer_info(cli, mem_ctx, 2, argc, argv, &num_printers, &ctr))
+ return nt_status;
+
+ for (i = 0; i < num_printers; i++) {
+
+ /* do some initialization */
+ rpcstr_pull(printername, ctr.printers_2[i].printername.buffer,
+ sizeof(printername), -1, STR_TERMINATE);
+ rpcstr_pull(sharename, ctr.printers_2[i].sharename.buffer,
+ sizeof(sharename), -1, STR_TERMINATE);
+
+ /* open printer handle */
+ if (!net_spoolss_open_printer_ex(cli, mem_ctx, sharename,
+ PRINTER_ALL_ACCESS, cli->user_name, &hnd))
+ goto done;
+
+ got_hnd = True;
+
+ /* check for existing dst printer */
+ if (!net_spoolss_getprinter(cli, mem_ctx, &hnd, level, &ctr_pub))
+ goto done;
+
+ /* check action and set string */
+ switch (action) {
+ case SPOOL_DS_PUBLISH:
+ action_str = "published";
+ break;
+ case SPOOL_DS_UPDATE:
+ action_str = "updated";
+ break;
+ case SPOOL_DS_UNPUBLISH:
+ action_str = "unpublished";
+ break;
+ default:
+ printf("unkown action: %d\n", action);
+ break;
+ }
+
+ ctr_pub.printers_7->action = action;
+
+ result = cli_spoolss_setprinter(cli, mem_ctx, &hnd, level, &ctr_pub, 0);
+ if (!W_ERROR_IS_OK(result) && (W_ERROR_V(result) =! W_ERROR_V(WERR_IO_PENDING))) {
+ printf("cannot set printer-info: %s\n", dos_errstr(result));
+ goto done;
+ }
+
+ printf("successfully %s printer %s in Active Directory\n", action_str, sharename);
+ }
+
+ nt_status = NT_STATUS_OK;
+
+done:
+ if (got_hnd)
+ cli_spoolss_close_printer(cli, mem_ctx, &hnd);
+
+ return nt_status;
+}
+
+NTSTATUS rpc_printer_publish_publish_internals(const DOM_SID *domain_sid, const char *domain_name,
+ struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv)
+{
+ return rpc_printer_publish_internals_args(cli, mem_ctx, argc, argv, SPOOL_DS_PUBLISH);
+}
+
+NTSTATUS rpc_printer_publish_unpublish_internals(const DOM_SID *domain_sid, const char *domain_name,
+ struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv)
+{
+ return rpc_printer_publish_internals_args(cli, mem_ctx, argc, argv, SPOOL_DS_UNPUBLISH);
+}
+
+NTSTATUS rpc_printer_publish_update_internals(const DOM_SID *domain_sid, const char *domain_name,
+ struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv)
+{
+ return rpc_printer_publish_internals_args(cli, mem_ctx, argc, argv, SPOOL_DS_UPDATE);
+}
+
+/**
+ * List print-queues w.r.t. thei publishing
+ *
+ * All parameters are provided by the run_rpc_command function, except for
+ * argc, argv which are passed through.
+ *
+ * @param domain_sid The domain sid aquired from the remote server
+ * @param cli A cli_state connected to the server.
+ * @param mem_ctx Talloc context, destoyed on compleation of the function.
+ * @param argc Standard main() style argc
+ * @param argv Standard main() style argv. Initial components are already
+ * stripped
+ *
+ * @return Normal NTSTATUS return.
+ **/
+NTSTATUS rpc_printer_publish_list_internals(const DOM_SID *domain_sid, const char *domain_name,
+ struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ uint32 i, num_printers;
+ uint32 level = 7;
+ pstring printername, sharename;
+ pstring guid;
+ PRINTER_INFO_CTR ctr, ctr_pub;
+ POLICY_HND hnd;
+ BOOL got_hnd = False;
+ int state;
+
+ if (!get_printer_info(cli, mem_ctx, 2, argc, argv, &num_printers, &ctr))
+ return nt_status;
+
+ for (i = 0; i < num_printers; i++) {
+
+ ZERO_STRUCT(ctr_pub);
+
+ /* do some initialization */
+ rpcstr_pull(printername, ctr.printers_2[i].printername.buffer,
+ sizeof(printername), -1, STR_TERMINATE);
+ rpcstr_pull(sharename, ctr.printers_2[i].sharename.buffer,
+ sizeof(sharename), -1, STR_TERMINATE);
+
+ /* open printer handle */
+ if (!net_spoolss_open_printer_ex(cli, mem_ctx, sharename,
+ PRINTER_ALL_ACCESS, cli->user_name, &hnd))
+ goto done;
+
+ got_hnd = True;
+
+ /* check for existing dst printer */
+ if (!net_spoolss_getprinter(cli, mem_ctx, &hnd, level, &ctr_pub))
+ goto done;
+
+ rpcstr_pull(guid, ctr_pub.printers_7->guid.buffer, sizeof(guid), -1, STR_TERMINATE);
+
+ state = ctr_pub.printers_7->action;
+ switch (state) {
+ case SPOOL_DS_PUBLISH:
+ printf("printer [%s] is published", sharename);
+ if (opt_verbose)
+ printf(", guid: %s", guid);
+ printf("\n");
+ break;
+ case SPOOL_DS_UNPUBLISH:
+ printf("printer [%s] is unpublished\n", sharename);
+ break;
+ case SPOOL_DS_UPDATE:
+ printf("printer [%s] is currently updating\n", sharename);
+ break;
+ default:
+ printf("unkown state: %d\n", state);
+ break;
+ }
+ }
+
+ nt_status = NT_STATUS_OK;
+
+done:
+ if (got_hnd)
+ cli_spoolss_close_printer(cli, mem_ctx, &hnd);
+
+ return nt_status;
+}
/**
* Migrate Printer-ACLs from a source server to the destination server