The Samba-Bugzilla – Attachment 6848 Details for
Bug 6296
Impossible to make print driver work for Xerox 7232 when installed on a Samba 3
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
git-am jumbo patch against master
printer_port_creation.diff (text/plain), 67.19 KB, created by
Justin Chevrier
on 2011-09-01 14:14:51 UTC
(
hide
)
Description:
git-am jumbo patch against master
Filename:
MIME Type:
Creator:
Justin Chevrier
Created:
2011-09-01 14:14:51 UTC
Size:
67.19 KB
patch
obsolete
>From e90efa315638c45c161e7418b33faebf1c77647f Mon Sep 17 00:00:00 2001 >From: Justin Chevrier <jchevrier@gmail.com> >Date: Thu, 18 Aug 2011 15:56:57 -0400 >Subject: [PATCH 1/6] s3-spoolss: Store the correct structure size > >--- > librpc/idl/spoolss.idl | 8 ++++---- > 1 files changed, 4 insertions(+), 4 deletions(-) > >diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl >index 4599e3a..edd2490 100644 >--- a/librpc/idl/spoolss.idl >+++ b/librpc/idl/spoolss.idl >@@ -3013,11 +3013,11 @@ cpp_quote("#define spoolss_security_descriptor security_descriptor") > PROTOCOL_LPR_TYPE = 2 > } spoolss_PortProtocol; > >- typedef [public] struct { >+ typedef [public,gensize] struct { > [charset(UTF16)] uint16 portname[64]; > [value(0x00000001)] uint32 version; > spoolss_PortProtocol protocol; >- [value(sizeof(r))] uint32 size; >+ [value(ndr_size_spoolss_PortData1(r,ndr->flags))] uint32 size; > uint32 reserved; > [charset(UTF16)] uint16 hostaddress[49]; > [charset(UTF16)] uint16 snmpcommunity[33]; >@@ -3031,11 +3031,11 @@ cpp_quote("#define spoolss_security_descriptor security_descriptor") > uint32 snmp_dev_index; > } spoolss_PortData1; > >- typedef [public] struct { >+ typedef [public,gensize] struct { > [charset(UTF16)] uint16 portname[64]; > [value(0x00000002)] uint32 version; > spoolss_PortProtocol protocol; >- [value(sizeof(r))] uint32 size; >+ [value(ndr_size_spoolss_PortData2(r,ndr->flags))] uint32 size; > uint32 reserved; > [charset(UTF16)] uint16 hostaddress[128]; > [charset(UTF16)] uint16 snmpcommunity[33]; >-- >1.7.3.4 > > >From 6def6a2e5099d891308f72147bd7c93a19ac7977 Mon Sep 17 00:00:00 2001 >From: Justin Chevrier <jchevrier@gmail.com> >Date: Thu, 18 Aug 2011 15:57:36 -0400 >Subject: [PATCH 2/6] s3-spoolss: Pull printer URI from CUPS and add support for URIs to printer_list > >--- > librpc/idl/printcap.idl | 1 + > source3/include/proto.h | 3 +- > source3/param/loadparm.c | 3 +- > source3/printing/pcap.c | 24 ++++++++++------- > source3/printing/pcap.h | 8 +++--- > source3/printing/print_cups.c | 20 ++++++++++++- > source3/printing/print_iprint.c | 2 +- > source3/printing/print_standard.c | 2 +- > source3/printing/printer_list.c | 38 +++++++++++++++++++++----- > source3/printing/printer_list.h | 4 ++- > source3/rpc_server/spoolss/srv_spoolss_nt.c | 2 + > 11 files changed, 78 insertions(+), 29 deletions(-) > >diff --git a/librpc/idl/printcap.idl b/librpc/idl/printcap.idl >index d9c34f3..f025eb2 100644 >--- a/librpc/idl/printcap.idl >+++ b/librpc/idl/printcap.idl >@@ -8,6 +8,7 @@ interface printcap > [charset(UTF8),string] uint8 *name; > [charset(UTF8),string] uint8 *info; > [charset(UTF8),string] uint8 *location; >+ [charset(UTF8),string] uint8 *uri; > } pcap_printer; > > typedef [public] struct { >diff --git a/source3/include/proto.h b/source3/include/proto.h >index 47321f3..5c073e2 100644 >--- a/source3/include/proto.h >+++ b/source3/include/proto.h >@@ -1597,7 +1597,8 @@ struct parm_struct *lp_get_parameter(const char *param_name); > struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters); > bool lp_snum_ok(int iService); > void lp_add_one_printer(const char *name, const char *comment, >- const char *location, void *pdata); >+ const char *location, const char *uri, >+ void *pdata); > bool lp_loaded(void); > void lp_killunused(struct smbd_server_connection *sconn, > bool (*snumused) (struct smbd_server_connection *, int)); >diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c >index b0c64c7..1fb5d98 100644 >--- a/source3/param/loadparm.c >+++ b/source3/param/loadparm.c >@@ -8092,7 +8092,8 @@ static void lp_add_auto_services(char *str) > ***************************************************************************/ > > void lp_add_one_printer(const char *name, const char *comment, >- const char *location, void *pdata) >+ const char *location, const char *uri, >+ void *pdata) > { > int printers = lp_servicenumber(PRINTERS_NAME); > int i; >diff --git a/source3/printing/pcap.c b/source3/printing/pcap.c >index 62db4f5..14ad6c9 100644 >--- a/source3/printing/pcap.c >+++ b/source3/printing/pcap.c >@@ -44,10 +44,11 @@ struct pcap_cache { > char *name; > char *comment; > char *location; >+ char *uri; > struct pcap_cache *next; > }; > >-bool pcap_cache_add_specific(struct pcap_cache **ppcache, const char *name, const char *comment, const char *location) >+bool pcap_cache_add_specific(struct pcap_cache **ppcache, const char *name, const char *comment, const char *location, const char *uri) > { > struct pcap_cache *p; > >@@ -57,10 +58,12 @@ bool pcap_cache_add_specific(struct pcap_cache **ppcache, const char *name, cons > p->name = SMB_STRDUP(name); > p->comment = (comment && *comment) ? SMB_STRDUP(comment) : NULL; > p->location = (location && *location) ? SMB_STRDUP(location) : NULL; >+ p->uri = (uri && *uri) ? SMB_STRDUP(uri) : NULL; > >- DEBUG(11,("pcap_cache_add_specific: Adding name %s info %s, location: %s\n", >+ DEBUG(11,("pcap_cache_add_specific: Adding name %s info %s, location: %s, uri: %s\n", > p->name, p->comment ? p->comment : "", >- p->location ? p->location : "")); >+ p->location ? p->location : "", >+ p->uri ? p->uri : "")); > > p->next = *ppcache; > *ppcache = p; >@@ -78,17 +81,18 @@ void pcap_cache_destroy_specific(struct pcap_cache **pp_cache) > SAFE_FREE(p->name); > SAFE_FREE(p->comment); > SAFE_FREE(p->location); >+ SAFE_FREE(p->uri); > SAFE_FREE(p); > } > *pp_cache = NULL; > } > >-bool pcap_cache_add(const char *name, const char *comment, const char *location) >+bool pcap_cache_add(const char *name, const char *comment, const char *location, const char *uri) > { > NTSTATUS status; > time_t t = time_mono(NULL); > >- status = printer_list_set_printer(talloc_tos(), name, comment, location, t); >+ status = printer_list_set_printer(talloc_tos(), name, comment, location, uri, t); > return NT_STATUS_IS_OK(status); > } > >@@ -113,7 +117,7 @@ bool pcap_cache_replace(const struct pcap_cache *pcache) > } > > for (p = pcache; p; p = p->next) { >- pcap_cache_add(p->name, p->comment, p->location); >+ pcap_cache_add(p->name, p->comment, p->location, p->uri); > } > > status = printer_list_clean_old(); >@@ -209,7 +213,7 @@ bool pcap_printername_ok(const char *printername) > { > NTSTATUS status; > >- status = printer_list_get_printer(talloc_tos(), printername, NULL, NULL, 0); >+ status = printer_list_get_printer(talloc_tos(), printername, NULL, NULL, NULL, 0); > return NT_STATUS_IS_OK(status); > } > >@@ -218,18 +222,18 @@ run a function on each printer name in the printcap file. > ***************************************************************************/ > > void pcap_printer_fn_specific(const struct pcap_cache *pc, >- void (*fn)(const char *, const char *, const char *, void *), >+ void (*fn)(const char *, const char *, const char *, const char *, void *), > void *pdata) > { > const struct pcap_cache *p; > > for (p = pc; p != NULL; p = p->next) >- fn(p->name, p->comment, p->location, pdata); >+ fn(p->name, p->comment, p->location, p->uri, pdata); > > return; > } > >-void pcap_printer_fn(void (*fn)(const char *, const char *, const char *, void *), void *pdata) >+void pcap_printer_fn(void (*fn)(const char *, const char *, const char *, const char *, void *), void *pdata) > { > NTSTATUS status; > >diff --git a/source3/printing/pcap.h b/source3/printing/pcap.h >index 7056213..6a7cce8 100644 >--- a/source3/printing/pcap.h >+++ b/source3/printing/pcap.h >@@ -33,13 +33,13 @@ struct pcap_cache; > > /* The following definitions come from printing/pcap.c */ > >-bool pcap_cache_add_specific(struct pcap_cache **ppcache, const char *name, const char *comment, const char *location); >+bool pcap_cache_add_specific(struct pcap_cache **ppcache, const char *name, const char *comment, const char *location, const char *uri); > void pcap_cache_destroy_specific(struct pcap_cache **ppcache); >-bool pcap_cache_add(const char *name, const char *comment, const char *location); >+bool pcap_cache_add(const char *name, const char *comment, const char *location, const char *uri); > bool pcap_cache_loaded(void); > bool pcap_cache_replace(const struct pcap_cache *cache); >-void pcap_printer_fn_specific(const struct pcap_cache *, void (*fn)(const char *, const char *, const char *, void *), void *); >-void pcap_printer_fn(void (*fn)(const char *, const char *, const char *, void *), void *); >+void pcap_printer_fn_specific(const struct pcap_cache *, void (*fn)(const char *, const char *, const char *, const char *, void *), void *); >+void pcap_printer_fn(void (*fn)(const char *, const char *, const char *, const char *, void *), void *); > > void pcap_cache_reload(struct tevent_context *ev, > struct messaging_context *msg_ctx, >diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c >index b8bbddf..371a752 100644 >--- a/source3/printing/print_cups.c >+++ b/source3/printing/print_cups.c >@@ -164,6 +164,7 @@ static bool process_cups_printers_response(TALLOC_CTX *mem_ctx, > char *name; > char *info; > char *location = NULL; >+ char *uri = NULL; > struct pcap_printer *printer; > bool ret_ok = false; > >@@ -217,6 +218,17 @@ static bool process_cups_printers_response(TALLOC_CTX *mem_ctx, > } > } > >+ if (strcmp(attr->name, "device-uri") == 0 && >+ attr->value_tag == IPP_TAG_URI) { >+ if (!pull_utf8_talloc(mem_ctx, >+ &uri, >+ attr->values[0].string.text, >+ &size)) { >+ goto err_out; >+ } >+ DEBUG(5, ("CUPS DEVICE URI: %s\n", uri)); >+ } >+ > attr = attr->next; > } > >@@ -241,6 +253,7 @@ static bool process_cups_printers_response(TALLOC_CTX *mem_ctx, > pcap_data->printers[pcap_data->count].name = name; > pcap_data->printers[pcap_data->count].info = info; > pcap_data->printers[pcap_data->count].location = location; >+ pcap_data->printers[pcap_data->count].uri = uri; > pcap_data->count++; > } > >@@ -265,7 +278,8 @@ static bool cups_cache_reload_async(int fd) > { > "printer-name", > "printer-info", >- "printer-location" >+ "printer-location", >+ "device-uri" > }; > bool ret = False; > enum ndr_err_code ndr_ret; >@@ -335,6 +349,7 @@ static bool cups_cache_reload_async(int fd) > * attributes-charset > * attributes-natural-language > * requested-attributes >+ * device-uri > */ > > request = ippNew(); >@@ -492,7 +507,8 @@ static void cups_async_callback(struct event_context *event_ctx, > ret_ok = pcap_cache_add_specific(&tmp_pcap_cache, > pcap_data.printers[i].name, > pcap_data.printers[i].info, >- pcap_data.printers[i].location); >+ pcap_data.printers[i].location, >+ pcap_data.printers[i].uri); > if (!ret_ok) { > DEBUG(0, ("failed to add to tmp pcap cache\n")); > goto err_out; >diff --git a/source3/printing/print_iprint.c b/source3/printing/print_iprint.c >index 1392cba..0efd7f6 100644 >--- a/source3/printing/print_iprint.c >+++ b/source3/printing/print_iprint.c >@@ -297,7 +297,7 @@ static int iprint_cache_add_printer(http_t *http, > */ > > if (name != NULL && !secure && smb_enabled) >- pcap_cache_add(name, info, NULL); >+ pcap_cache_add(name, info, NULL, NULL); > } > > out: >diff --git a/source3/printing/print_standard.c b/source3/printing/print_standard.c >index c4f9c5b..1bbffa8 100644 >--- a/source3/printing/print_standard.c >+++ b/source3/printing/print_standard.c >@@ -117,7 +117,7 @@ bool std_pcap_cache_reload(const char *pcap_name) > } > } > >- if (*name && !pcap_cache_add(name, comment, NULL)) { >+ if (*name && !pcap_cache_add(name, comment, NULL, NULL)) { > x_fclose(pcap_file); > return false; > } >diff --git a/source3/printing/printer_list.c b/source3/printing/printer_list.c >index 82c43bf..4584da2 100644 >--- a/source3/printing/printer_list.c >+++ b/source3/printing/printer_list.c >@@ -28,7 +28,7 @@ > #define PL_KEY_PREFIX "PRINTERLIST/PRN/" > #define PL_KEY_FORMAT PL_KEY_PREFIX"%s" > #define PL_TIMESTAMP_KEY "PRINTERLIST/GLOBAL/LAST_REFRESH" >-#define PL_DATA_FORMAT "ddPPP" >+#define PL_DATA_FORMAT "ddPPPP" > #define PL_TSTAMP_FORMAT "dd" > > static struct db_context *get_printer_list_db(void) >@@ -67,6 +67,7 @@ NTSTATUS printer_list_get_printer(TALLOC_CTX *mem_ctx, > const char *name, > const char **comment, > const char **location, >+ const char **uri, > time_t *last_refresh) > { > struct db_context *db; >@@ -76,6 +77,7 @@ NTSTATUS printer_list_get_printer(TALLOC_CTX *mem_ctx, > char *nstr = NULL; > char *cstr = NULL; > char *lstr = NULL; >+ char *ustr = NULL; > NTSTATUS status; > int ret; > >@@ -99,7 +101,7 @@ NTSTATUS printer_list_get_printer(TALLOC_CTX *mem_ctx, > > ret = tdb_unpack(data.dptr, data.dsize, > PL_DATA_FORMAT, >- &time_h, &time_l, &nstr, &cstr, &lstr); >+ &time_h, &time_l, &nstr, &cstr, &lstr, &ustr); > if (ret == -1) { > DEBUG(1, ("Failed to un pack printer data")); > status = NT_STATUS_INTERNAL_DB_CORRUPTION; >@@ -128,6 +130,15 @@ NTSTATUS printer_list_get_printer(TALLOC_CTX *mem_ctx, > } > } > >+ if (uri) { >+ *uri = talloc_strdup(mem_ctx, ustr); >+ if (*uri == NULL) { >+ DEBUG(1, ("Failed to strdup uri!\n")); >+ status = NT_STATUS_NO_MEMORY; >+ goto done; >+ } >+ } >+ > status = NT_STATUS_OK; > > done: >@@ -141,6 +152,7 @@ NTSTATUS printer_list_set_printer(TALLOC_CTX *mem_ctx, > const char *name, > const char *comment, > const char *location, >+ const char *uri, > time_t last_refresh) > { > struct db_context *db; >@@ -150,6 +162,7 @@ NTSTATUS printer_list_set_printer(TALLOC_CTX *mem_ctx, > uint32_t time_h, time_l; > const char *str = NULL; > const char *str2 = NULL; >+ const char *str3 = NULL; > NTSTATUS status; > int len; > >@@ -176,12 +189,17 @@ NTSTATUS printer_list_set_printer(TALLOC_CTX *mem_ctx, > str2 = ""; > } > >+ if (uri) { >+ str3 = uri; >+ } else { >+ str3 = ""; >+ } > > time_64 = last_refresh; > time_l = time_64 & 0xFFFFFFFFL; > time_h = time_64 >> 32; > >- len = tdb_pack(NULL, 0, PL_DATA_FORMAT, time_h, time_l, name, str, str2); >+ len = tdb_pack(NULL, 0, PL_DATA_FORMAT, time_h, time_l, name, str, str2, str3); > > data.dptr = talloc_array(key, uint8_t, len); > if (!data.dptr) { >@@ -311,6 +329,7 @@ static int printer_list_clean_fn(struct db_record *rec, void *private_data) > char *name; > char *comment; > char *location; >+ char *uri; > int ret; > > /* skip anything that does not contain PL_DATA_FORMAT data */ >@@ -321,7 +340,7 @@ static int printer_list_clean_fn(struct db_record *rec, void *private_data) > > ret = tdb_unpack(rec->value.dptr, rec->value.dsize, > PL_DATA_FORMAT, &time_h, &time_l, &name, &comment, >- &location); >+ &location, &uri); > if (ret == -1) { > DEBUG(1, ("Failed to un pack printer data")); > state->status = NT_STATUS_INTERNAL_DB_CORRUPTION; >@@ -331,6 +350,7 @@ static int printer_list_clean_fn(struct db_record *rec, void *private_data) > SAFE_FREE(name); > SAFE_FREE(comment); > SAFE_FREE(location); >+ SAFE_FREE(uri); > > refresh = (time_t)(((uint64_t)time_h << 32) + time_l); > >@@ -366,7 +386,7 @@ NTSTATUS printer_list_clean_old(void) > } > > struct printer_list_exec_state { >- void (*fn)(const char *, const char *, const char *, void *); >+ void (*fn)(const char *, const char *, const char *, const char *, void *); > void *private_data; > NTSTATUS status; > }; >@@ -379,6 +399,7 @@ static int printer_list_exec_fn(struct db_record *rec, void *private_data) > char *name; > char *comment; > char *location; >+ char *uri; > int ret; > > /* always skip PL_TIMESTAMP_KEY key */ >@@ -388,22 +409,23 @@ static int printer_list_exec_fn(struct db_record *rec, void *private_data) > > ret = tdb_unpack(rec->value.dptr, rec->value.dsize, > PL_DATA_FORMAT, &time_h, &time_l, &name, &comment, >- &location); >+ &location, &uri); > if (ret == -1) { > DEBUG(1, ("Failed to un pack printer data")); > state->status = NT_STATUS_INTERNAL_DB_CORRUPTION; > return -1; > } > >- state->fn(name, comment, location, state->private_data); >+ state->fn(name, comment, location, uri, state->private_data); > > SAFE_FREE(name); > SAFE_FREE(comment); > SAFE_FREE(location); >+ SAFE_FREE(uri); > return 0; > } > >-NTSTATUS printer_list_run_fn(void (*fn)(const char *, const char *, const char *, void *), >+NTSTATUS printer_list_run_fn(void (*fn)(const char *, const char *, const char *, const char *, void *), > void *private_data) > { > struct printer_list_exec_state state; >diff --git a/source3/printing/printer_list.h b/source3/printing/printer_list.h >index fb2e007..c5dd88b 100644 >--- a/source3/printing/printer_list.h >+++ b/source3/printing/printer_list.h >@@ -44,6 +44,7 @@ NTSTATUS printer_list_get_printer(TALLOC_CTX *mem_ctx, > const char *name, > const char **comment, > const char **location, >+ const char **uri, > time_t *last_refresh); > > /** >@@ -67,6 +68,7 @@ NTSTATUS printer_list_set_printer(TALLOC_CTX *mem_ctx, > const char *name, > const char *comment, > const char *location, >+ const char *uri, > time_t last_refresh); > > /** >@@ -100,6 +102,6 @@ NTSTATUS printer_list_mark_reload(void); > */ > NTSTATUS printer_list_clean_old(void); > >-NTSTATUS printer_list_run_fn(void (*fn)(const char *, const char *, const char *, void *), >+NTSTATUS printer_list_run_fn(void (*fn)(const char *, const char *, const char *, const char *, void *), > void *private_data); > #endif /* _PRINTER_LIST_H_ */ >diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c >index a2f8d68..6403805 100644 >--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c >+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c >@@ -2908,6 +2908,7 @@ static void spoolss_notify_location(struct messaging_context *msg_ctx, > pinfo2->sharename, > NULL, > &loc, >+ NULL, > NULL); > if (NT_STATUS_IS_OK(status)) { > if (loc == NULL) { >@@ -4056,6 +4057,7 @@ static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx, > info2->sharename, > NULL, > &loc, >+ NULL, > NULL); > if (NT_STATUS_IS_OK(nt_status)) { > if (loc != NULL) { >-- >1.7.3.4 > > >From f79729516e904d51b2eec15e575a5fb55e594462 Mon Sep 17 00:00:00 2001 >From: Justin Chevrier <jchevrier@gmail.com> >Date: Thu, 18 Aug 2011 15:58:46 -0400 >Subject: [PATCH 3/6] s3-spoolss: Add port registry functions > >--- > source3/registry/reg_backend_db.c | 2 +- > source3/rpc_client/cli_winreg_spoolss.c | 615 +++++++++++++++++++++++++ > source3/rpc_client/cli_winreg_spoolss.h | 108 +++++ > source3/rpc_server/spoolss/srv_spoolss_util.c | 51 ++ > source3/rpc_server/spoolss/srv_spoolss_util.h | 15 + > 5 files changed, 790 insertions(+), 1 deletions(-) > >diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c >index 58e7b33..9a1a3fb 100644 >--- a/source3/registry/reg_backend_db.c >+++ b/source3/registry/reg_backend_db.c >@@ -89,7 +89,7 @@ static const char *builtin_registry_paths[] = { > KEY_GP_USER_POLICY, > KEY_GP_USER_WIN_POLICY, > "HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\GPExtensions", >- "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors", >+ "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors\\Standard TCP/IP Port\\Ports", > KEY_PROD_OPTIONS, > "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration", > KEY_TCPIP_PARAMS, >diff --git a/source3/rpc_client/cli_winreg_spoolss.c b/source3/rpc_client/cli_winreg_spoolss.c >index 2a6a8d1..3159e0b 100644 >--- a/source3/rpc_client/cli_winreg_spoolss.c >+++ b/source3/rpc_client/cli_winreg_spoolss.c >@@ -36,6 +36,8 @@ > #define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers" > #define TOP_LEVEL_CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control\\Print" > #define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms" >+#define TOP_LEVEL_PORT_KEY "\\Monitors\\Standard TCP/IP Port" >+#define TOP_LEVEL_PORT_PORTS_KEY TOP_LEVEL_CONTROL_KEY TOP_LEVEL_PORT_KEY "\\Ports" > > #define EMPTY_STRING "" > >@@ -3979,3 +3981,616 @@ done: > TALLOC_FREE(tmp_ctx); > return result; > } >+ >+/** >+ * @brief Create the registry keyname for the given port. >+ * >+ * @param[in] mem_ctx The memory context to use. >+ * >+ * @param[in] port The name of the port to get the registry key. >+ * >+ * @return The registry key or NULL on error. >+ */ >+static char *winreg_port_data_keyname(TALLOC_CTX *mem_ctx, const char *port) { >+ return talloc_asprintf(mem_ctx, "%s\\%s", TOP_LEVEL_PORT_PORTS_KEY, port); >+} >+ >+WERROR winreg_update_port(TALLOC_CTX *mem_ctx, >+ struct dcerpc_binding_handle *winreg_handle, >+ const char *portname, >+ uint32_t data1_mask, >+ struct spoolss_PortData1 *data1) >+{ >+ uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; >+ struct policy_handle hive_hnd, key_hnd; >+ int snum = lp_servicenumber(portname); >+ enum ndr_err_code ndr_err; >+ DATA_BLOB blob; >+ char *path; >+ WERROR result = WERR_OK; >+ NTSTATUS status; >+ TALLOC_CTX *tmp_ctx; >+ >+ tmp_ctx = talloc_stackframe(); >+ if (tmp_ctx == NULL) { >+ return WERR_NOMEM; >+ } >+ >+ path = winreg_port_data_keyname(tmp_ctx, portname); >+ if (path == NULL) { >+ TALLOC_FREE(tmp_ctx); >+ return WERR_NOMEM; >+ } >+ >+ ZERO_STRUCT(hive_hnd); >+ ZERO_STRUCT(key_hnd); >+ >+ result = winreg_printer_openkey(tmp_ctx, >+ winreg_handle, >+ path, >+ "", >+ true, >+ access_mask, >+ &hive_hnd, >+ &key_hnd); >+ if (!W_ERROR_IS_OK(result)) { >+ DEBUG(0, ("winreg_update_port: Could not open key %s: %s\n", >+ path, win_errstr(result))); >+ goto done; >+ } >+ >+ if (data1_mask & SPOOLSS_PORT_DATA_DBLSPOOL) { >+ status = dcerpc_winreg_set_dword(tmp_ctx, >+ winreg_handle, >+ &key_hnd, >+ "Double Spool", >+ data1->dblspool, >+ &result); >+ if (!NT_STATUS_IS_OK(status)) { >+ result = ntstatus_to_werror(status); >+ } >+ if (!W_ERROR_IS_OK(result)) { >+ goto done; >+ } >+ } >+ if (data1_mask & SPOOLSS_PORT_DATA_HOSTNAME) { >+ status = dcerpc_winreg_set_sz(tmp_ctx, >+ winreg_handle, >+ &key_hnd, >+ "HostName", >+ data1->hostaddress, >+ &result); >+ if (!NT_STATUS_IS_OK(status)) { >+ result = ntstatus_to_werror(status); >+ } >+ if (!W_ERROR_IS_OK(result)) { >+ goto done; >+ } >+ } >+ if (data1_mask & SPOOLSS_PORT_DATA_HWADDRESS) { >+ status = dcerpc_winreg_set_sz(tmp_ctx, >+ winreg_handle, >+ &key_hnd, >+ "HWAddress", >+ data1->hardware_address, >+ &result); >+ if (!NT_STATUS_IS_OK(status)) { >+ result = ntstatus_to_werror(status); >+ } >+ if (!W_ERROR_IS_OK(result)) { >+ goto done; >+ } >+ } >+ if (data1_mask & SPOOLSS_PORT_DATA_IPADDRESS) { >+ status = dcerpc_winreg_set_sz(tmp_ctx, >+ winreg_handle, >+ &key_hnd, >+ "IPAddress", >+ data1->ip_address, >+ &result); >+ if (!NT_STATUS_IS_OK(status)) { >+ result = ntstatus_to_werror(status); >+ } >+ if (!W_ERROR_IS_OK(result)) { >+ goto done; >+ } >+ } >+ if (data1_mask & SPOOLSS_PORT_DATA_PORTNUMBER) { >+ status = dcerpc_winreg_set_dword(tmp_ctx, >+ winreg_handle, >+ &key_hnd, >+ "PortNumber", >+ data1->port_number, >+ &result); >+ if (!NT_STATUS_IS_OK(status)) { >+ result = ntstatus_to_werror(status); >+ } >+ if (!W_ERROR_IS_OK(result)) { >+ goto done; >+ } >+ } >+ if (data1_mask & SPOOLSS_PORT_DATA_PROTOCOL) { >+ status = dcerpc_winreg_set_dword(tmp_ctx, >+ winreg_handle, >+ &key_hnd, >+ "Protocol", >+ data1->protocol, >+ &result); >+ if (!NT_STATUS_IS_OK(status)) { >+ result = ntstatus_to_werror(status); >+ } >+ if (!W_ERROR_IS_OK(result)) { >+ goto done; >+ } >+ } >+ if (data1_mask & SPOOLSS_PORT_DATA_QUEUE) { >+ status = dcerpc_winreg_set_sz(tmp_ctx, >+ winreg_handle, >+ &key_hnd, >+ "Queue", >+ data1->queue, >+ &result); >+ if (!NT_STATUS_IS_OK(status)) { >+ result = ntstatus_to_werror(status); >+ } >+ if (!W_ERROR_IS_OK(result)) { >+ goto done; >+ } >+ } >+ if (data1_mask & SPOOLSS_PORT_DATA_SNMPCOMMUNITY) { >+ status = dcerpc_winreg_set_sz(tmp_ctx, >+ winreg_handle, >+ &key_hnd, >+ "SNMP Community", >+ data1->snmpcommunity, >+ &result); >+ if (!NT_STATUS_IS_OK(status)) { >+ result = ntstatus_to_werror(status); >+ } >+ if (!W_ERROR_IS_OK(result)) { >+ goto done; >+ } >+ } >+ if (data1_mask & SPOOLSS_PORT_DATA_SNMPENABLED) { >+ status = dcerpc_winreg_set_dword(tmp_ctx, >+ winreg_handle, >+ &key_hnd, >+ "SNMP Enabled", >+ data1->snmp_enabled, >+ &result); >+ if (!NT_STATUS_IS_OK(status)) { >+ result = ntstatus_to_werror(status); >+ } >+ if (!W_ERROR_IS_OK(result)) { >+ goto done; >+ } >+ } >+ if (data1_mask & SPOOLSS_PORT_DATA_SNMPINDEX) { >+ status = dcerpc_winreg_set_dword(tmp_ctx, >+ winreg_handle, >+ &key_hnd, >+ "SNMP Index", >+ data1->snmp_dev_index, >+ &result); >+ if (!NT_STATUS_IS_OK(status)) { >+ result = ntstatus_to_werror(status); >+ } >+ if (!W_ERROR_IS_OK(result)) { >+ goto done; >+ } >+ } >+ if (data1_mask & SPOOLSS_PORT_DATA_VERSION) { >+ status = dcerpc_winreg_set_dword(tmp_ctx, >+ winreg_handle, >+ &key_hnd, >+ "Version", >+ data1->version, >+ &result); >+ if (!NT_STATUS_IS_OK(status)) { >+ result = ntstatus_to_werror(status); >+ } >+ if (!W_ERROR_IS_OK(result)) { >+ goto done; >+ } >+ } >+ >+ result = WERR_OK; >+done: >+ if (winreg_handle != NULL) { >+ WERROR ignore; >+ >+ if (is_valid_policy_hnd(&key_hnd)) { >+ dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); >+ } >+ if (is_valid_policy_hnd(&hive_hnd)) { >+ dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); >+ } >+ } >+ >+ TALLOC_FREE(tmp_ctx); >+ return result; >+} >+ >+WERROR winreg_get_port(TALLOC_CTX *mem_ctx, >+ struct dcerpc_binding_handle *winreg_handle, >+ const char *port, >+ struct spoolss_PortData1 **pdata1) >+{ >+ struct spoolss_PortData1 *data1; >+ uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; >+ struct policy_handle hive_hnd, key_hnd; >+ struct spoolss_PrinterEnumValues enum_value; >+ struct spoolss_PrinterEnumValues *v = NULL; >+ enum ndr_err_code ndr_err; >+ uint32_t num_values = 0; >+ uint32_t i; >+ char *path; >+ NTSTATUS status; >+ WERROR result = WERR_OK; >+ TALLOC_CTX *tmp_ctx; >+ >+ const char **enum_names = NULL; >+ enum winreg_Type *enum_types = NULL; >+ DATA_BLOB *enum_data_blobs = NULL; >+ >+ tmp_ctx = talloc_stackframe(); >+ if (tmp_ctx == NULL) { >+ return WERR_NOMEM; >+ } >+ >+ path = winreg_port_data_keyname(tmp_ctx, port); >+ if (path == NULL) { >+ TALLOC_FREE(tmp_ctx); >+ return WERR_NOMEM; >+ } >+ >+ result = winreg_printer_openkey(tmp_ctx, >+ winreg_handle, >+ path, >+ "", >+ false, >+ access_mask, >+ &hive_hnd, >+ &key_hnd); >+ if (!W_ERROR_IS_OK(result)) { >+ DEBUG(2, ("winreg_get_port: Could not open key %s: %s\n", >+ path, win_errstr(result))); >+ goto done; >+ } >+ >+ status = dcerpc_winreg_enumvals(tmp_ctx, >+ winreg_handle, >+ &key_hnd, >+ &num_values, >+ &enum_names, >+ &enum_types, >+ &enum_data_blobs, >+ &result); >+ >+ if (!NT_STATUS_IS_OK(status)){ >+ result = ntstatus_to_werror(status); >+ } >+ >+ if (!W_ERROR_IS_OK(result)) { >+ DEBUG(0, ("winreg_get_port: Could not enumerate values in %s: %s\n", >+ path, win_errstr(result))); >+ goto done; >+ } >+ >+ data1 = talloc_zero(tmp_ctx, struct spoolss_PortData1); >+ if (data1 == NULL) { >+ result = WERR_NOMEM; >+ goto done; >+ } >+ >+ FILL_STRING(data1, port, data1->portname); >+ FILL_STRING(data1, EMPTY_STRING, data1->hostaddress); >+ FILL_STRING(data1, EMPTY_STRING, data1->hardware_address); >+ FILL_STRING(data1, EMPTY_STRING, data1->ip_address); >+ FILL_STRING(data1, EMPTY_STRING, data1->queue); >+ FILL_STRING(data1, EMPTY_STRING, data1->snmpcommunity); >+ FILL_STRING(data1, EMPTY_STRING, data1->device_type); >+ >+ for (i = 0; i < num_values; i++) { >+ enum_value.value_name = enum_names[i]; >+ enum_value.value_name_len = 2*strlen_m_term(enum_names[i]); >+ enum_value.type = enum_types[i]; >+ enum_value.data_length = enum_data_blobs[i].length; >+ enum_value.data = NULL; >+ if (enum_value.data_length != 0){ >+ enum_value.data = &enum_data_blobs[i]; >+ } >+ v = &enum_value; >+ >+ result = winreg_enumval_to_dword(data1, >+ v, >+ "Double Spool", >+ &data1->dblspool); >+ CHECK_ERROR(result); >+ >+ result = winreg_enumval_to_sz(data1, >+ v, >+ "HostName", >+ &data1->hostaddress); >+ CHECK_ERROR(result); >+ >+ result = winreg_enumval_to_sz(data1, >+ v, >+ "HWAddress", >+ &data1->hardware_address); >+ CHECK_ERROR(result); >+ >+ result = winreg_enumval_to_sz(data1, >+ v, >+ "IPAddress", >+ &data1->ip_address); >+ CHECK_ERROR(result); >+ >+ result = winreg_enumval_to_dword(data1, >+ v, >+ "PortNumber", >+ &data1->port_number); >+ CHECK_ERROR(result); >+ >+ result = winreg_enumval_to_dword(data1, >+ v, >+ "Protocol", >+ &data1->protocol); >+ CHECK_ERROR(result); >+ >+ result = winreg_enumval_to_sz(data1, >+ v, >+ "Queue", >+ &data1->queue); >+ CHECK_ERROR(result); >+ >+ result = winreg_enumval_to_sz(data1, >+ v, >+ "SNMP Community", >+ &data1->snmpcommunity); >+ CHECK_ERROR(result); >+ >+ result = winreg_enumval_to_dword(data1, >+ v, >+ "SNMP Enabled", >+ &data1->snmp_enabled); >+ CHECK_ERROR(result); >+ >+ result = winreg_enumval_to_dword(data1, >+ v, >+ "SNMP Index", >+ &data1->snmp_dev_index); >+ CHECK_ERROR(result); >+ >+ result = winreg_enumval_to_dword(data1, >+ v, >+ "Version", >+ &data1->version); >+ CHECK_ERROR(result); >+ } >+ >+ if (pdata1) { >+ *pdata1 = talloc_move(mem_ctx, &data1); >+ } >+ >+ result = WERR_OK; >+done: >+ if (winreg_handle != NULL) { >+ WERROR ignore; >+ >+ if (is_valid_policy_hnd(&key_hnd)) { >+ dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); >+ } >+ if (is_valid_policy_hnd(&hive_hnd)) { >+ dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); >+ } >+ } >+ >+ TALLOC_FREE(tmp_ctx); >+ return result; >+} >+ >+WERROR winreg_create_port(TALLOC_CTX *mem_ctx, >+ struct dcerpc_binding_handle *winreg_handle, >+ const char *portname, >+ const char *ipaddress) >+{ >+ uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; >+ struct policy_handle hive_hnd, key_hnd; >+ struct spoolss_PortData1 *data1; >+ struct winreg_String wkey, wkeyclass; >+ const char *path; >+ uint32_t i; >+ uint32_t data1_mask = 0; >+ WERROR result = WERR_OK; >+ TALLOC_CTX *tmp_ctx; >+ >+ tmp_ctx = talloc_stackframe(); >+ if (tmp_ctx == NULL) { >+ return WERR_NOMEM; >+ } >+ >+ path = winreg_port_data_keyname(tmp_ctx, portname); >+ if (path == NULL) { >+ TALLOC_FREE(tmp_ctx); >+ return WERR_NOMEM; >+ } >+ >+ ZERO_STRUCT(hive_hnd); >+ ZERO_STRUCT(key_hnd); >+ >+ result = winreg_printer_openkey(tmp_ctx, >+ winreg_handle, >+ path, >+ "", >+ false, >+ access_mask, >+ &hive_hnd, >+ &key_hnd); >+ if (W_ERROR_IS_OK(result)) { >+ DEBUG(2, ("winreg_create_port: Skipping, %s already exists\n", path)); >+ goto done; >+ } else if (W_ERROR_EQUAL(result, WERR_BADFILE)) { >+ DEBUG(2, ("winreg_create_port: Creating default values in %s\n", path)); >+ } else if (!W_ERROR_IS_OK(result)) { >+ DEBUG(0, ("winreg_create_port: Could not open key %s: %s\n", >+ path, win_errstr(result))); >+ goto done; >+ } >+ >+ /* Create the main key */ >+ result = winreg_printer_openkey(tmp_ctx, >+ winreg_handle, >+ path, >+ "", >+ true, >+ access_mask, >+ &hive_hnd, >+ &key_hnd); >+ if (!W_ERROR_IS_OK(result)) { >+ DEBUG(0, ("winreg_create_port: Could not create key %s: %s\n", >+ path, win_errstr(result))); >+ goto done; >+ } >+ >+ if (is_valid_policy_hnd(&key_hnd)) { >+ dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result); >+ } >+ >+ data1 = talloc_zero(tmp_ctx, struct spoolss_PortData1); >+ if (data1 == NULL) { >+ result = WERR_NOMEM; >+ goto done; >+ } >+ >+ data1->hostaddress = ""; >+ data1_mask |= SPOOLSS_PORT_DATA_HOSTNAME; >+ >+ data1->hardware_address = ""; >+ data1_mask |= SPOOLSS_PORT_DATA_HWADDRESS; >+ >+ data1->ip_address = ipaddress; >+ data1_mask |= SPOOLSS_PORT_DATA_IPADDRESS; >+ >+ data1->port_number = 9100; >+ data1_mask |= SPOOLSS_PORT_DATA_PORTNUMBER; >+ >+ data1->protocol = 1; >+ data1_mask |= SPOOLSS_PORT_DATA_PROTOCOL; >+ >+ data1->snmpcommunity = "public"; >+ data1_mask |= SPOOLSS_PORT_DATA_SNMPCOMMUNITY; >+ >+ data1->snmp_enabled = 1; >+ data1_mask |= SPOOLSS_PORT_DATA_SNMPENABLED; >+ >+ data1->snmp_dev_index = 1; >+ data1_mask |= SPOOLSS_PORT_DATA_SNMPINDEX; >+ >+ data1->version = 1; >+ data1_mask |= SPOOLSS_PORT_DATA_VERSION; >+ >+ result = winreg_update_port(tmp_ctx, >+ winreg_handle, >+ portname, >+ data1_mask, >+ data1); >+ >+done: >+ if (winreg_handle != NULL) { >+ WERROR ignore; >+ >+ if (is_valid_policy_hnd(&key_hnd)) { >+ dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); >+ } >+ if (is_valid_policy_hnd(&hive_hnd)) { >+ dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); >+ } >+ } >+ >+ talloc_free(tmp_ctx); >+ return result; >+} >+ >+/* Enumerate the subkeys of a given key */ >+WERROR winreg_enum_ports_key(TALLOC_CTX *mem_ctx, >+ struct dcerpc_binding_handle *winreg_handle, >+ uint32_t *pnum_subkeys, >+ const char ***psubkeys) >+{ >+ uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; >+ struct policy_handle hive_hnd, key_hnd; >+ char *path; >+ const char **subkeys = NULL; >+ uint32_t num_subkeys = -1; >+ >+ WERROR result = WERR_OK; >+ NTSTATUS status; >+ >+ TALLOC_CTX *tmp_ctx; >+ >+ tmp_ctx = talloc_stackframe(); >+ if (tmp_ctx == NULL) { >+ return WERR_NOMEM; >+ } >+ >+ path = TOP_LEVEL_PORT_PORTS_KEY; >+ >+ if (path == NULL) { >+ TALLOC_FREE(tmp_ctx); >+ return WERR_NOMEM; >+ } >+ >+ ZERO_STRUCT(hive_hnd); >+ ZERO_STRUCT(key_hnd); >+ >+ result = winreg_printer_openkey(tmp_ctx, >+ winreg_handle, >+ path, >+ "", >+ false, >+ access_mask, >+ &hive_hnd, >+ &key_hnd); >+ if (!W_ERROR_IS_OK(result)) { >+ DEBUG(2, ("winreg_enum_ports: Could not open key %s: %s\n", >+ path, win_errstr(result))); >+ goto done; >+ } >+ >+ status = dcerpc_winreg_enum_keys(tmp_ctx, >+ winreg_handle, >+ &key_hnd, >+ &num_subkeys, >+ &subkeys, >+ &result); >+ if (!NT_STATUS_IS_OK(status)) { >+ result = ntstatus_to_werror(status); >+ } >+ if (!W_ERROR_IS_OK(result)) { >+ DEBUG(0, ("winreg_enum_ports: Could not enumerate subkeys in %s: %s\n", >+ path, win_errstr(result))); >+ goto done; >+ } >+ >+ *pnum_subkeys = num_subkeys; >+ if (psubkeys) { >+ *psubkeys = talloc_move(mem_ctx, &subkeys); >+ } >+ >+ result = WERR_OK; >+done: >+ if (winreg_handle != NULL) { >+ WERROR ignore; >+ >+ if (is_valid_policy_hnd(&key_hnd)) { >+ dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); >+ } >+ if (is_valid_policy_hnd(&hive_hnd)) { >+ dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); >+ } >+ } >+ >+ TALLOC_FREE(tmp_ctx); >+ return result; >+} >diff --git a/source3/rpc_client/cli_winreg_spoolss.h b/source3/rpc_client/cli_winreg_spoolss.h >index aa4d98f..6cd6863 100644 >--- a/source3/rpc_client/cli_winreg_spoolss.h >+++ b/source3/rpc_client/cli_winreg_spoolss.h >@@ -24,6 +24,34 @@ > > struct dcerpc_binding_handle; > >+enum spoolss_PortData1Mask { >+ SPOOLSS_PORT_DATA_DBLSPOOL = (int)(0x00000001), >+ SPOOLSS_PORT_DATA_HOSTNAME = (int)(0x00000002), >+ SPOOLSS_PORT_DATA_HWADDRESS = (int)(0x00000004), >+ SPOOLSS_PORT_DATA_IPADDRESS = (int)(0x00000008), >+ SPOOLSS_PORT_DATA_PORTNUMBER = (int)(0x00000010), >+ SPOOLSS_PORT_DATA_PROTOCOL = (int)(0x00000020), >+ SPOOLSS_PORT_DATA_QUEUE = (int)(0x00000040), >+ SPOOLSS_PORT_DATA_SNMPCOMMUNITY = (int)(0x00000080), >+ SPOOLSS_PORT_DATA_SNMPENABLED = (int)(0x00000100), >+ SPOOLSS_PORT_DATA_SNMPINDEX = (int)(0x00000200), >+ SPOOLSS_PORT_DATA_VERSION = (int)(0x00000400), >+}; >+ >+#define SPOOLSS_PORT_DATA_ALL SPOOLSS_PORT_DATA_DBLSPOOL | \ >+ SPOOLSS_PORT_DATA_HOSTNAME | \ >+ SPOOLSS_PORT_DATA_HWADDRESS | \ >+ SPOOLSS_PORT_DATA_IPADDRESS | \ >+ SPOOLSS_PORT_DATA_PORTNUMBER | \ >+ SPOOLSS_PORT_DATA_PROTOCOL | \ >+ SPOOLSS_PORT_DATA_QUEUE | \ >+ SPOOLSS_PORT_DATA_SNMPCOMMUNITY | \ >+ SPOOLSS_PORT_DATA_SNMPENABLED | \ >+ SPOOLSS_PORT_DATA_SNMPINDEX | \ >+ SPOOLSS_PORT_DATA_VERSION >+ >+ >+ > enum spoolss_PrinterInfo2Mask { > SPOOLSS_PRINTER_INFO_ATTRIBUTES = (int)(0x00000001), > SPOOLSS_PRINTER_INFO_AVERAGEPPM = (int)(0x00000002), >@@ -566,4 +594,84 @@ WERROR winreg_get_driver_list(TALLOC_CTX *mem_ctx, > uint32_t *num_drivers, > const char ***drivers); > >+/** >+ * @brief Get the inforamtion of a port stored in the registry. >+ * >+ * @param[in] mem_ctx The talloc memory context to use. >+ * >+ * @param[in] b The dcerpc binding handle >+ * >+ * @param[in] port The name of the port to get. >+ * >+ * @param[out] pdata1 A pointer to store a PRINTER_INFO_2 structure. >+ * >+ * @return On success WERR_OK, a corresponding DOS error is >+ * something went wrong. >+ */ >+WERROR winreg_get_port(TALLOC_CTX *mem_ctx, >+ struct dcerpc_binding_handle *b, >+ const char *port, >+ struct spoolss_PortData1 **pdata1); >+ >+/** >+ * @brief Create a new port in the registry. >+ * >+ * @param[in] mem_ctx The talloc memory context to use. >+ * >+ * @param[in] b The dcerpc binding handle >+ * >+ * @param[in] portname The name of the port to get. >+ * >+ * @param[in] ipaddress The IP address of the port >+ * >+ * @return On success WERR_OK, a corresponding DOS error is >+ * something went wrong. >+ */ >+WERROR winreg_create_port(TALLOC_CTX *mem_ctx, >+ struct dcerpc_binding_handle *b, >+ const char *portname, >+ const char *ipaddress); >+ >+/** >+ * @brief Update the information of a port in the registry. >+ * >+ * @param[in] mem_ctx The talloc memory context to use. >+ * >+ * @param[in] b The dcerpc binding handle >+ * >+ * @param[in] portname The name of the port to get. >+ * >+ * @param[in] data1_mask A bitmask which defines which values should be set. >+ * >+ * @param[out] data1 The structure that holds the port information >+ * >+ * @return On success WERR_OK, a corresponding DOS error is >+ * something went wrong. >+ */ >+WERROR winreg_update_port(TALLOC_CTX *mem_ctx, >+ struct dcerpc_binding_handle *b, >+ const char *portname, >+ uint32_t data1_mask, >+ struct spoolss_PortData1 *data1); >+ >+/** >+ * @brief Enumerate a list of ports from the registry. >+ * >+ * @param[in] mem_ctx The talloc memory context to use. >+ * >+ * @param[in] b The dcerpc binding handle >+ * >+ * @param[out] pnum_subkeys A pointer to store the number of subkeys found. >+ * >+ * @param[in] psubkeys A pointer to an array to store the names of the subkeys >+ * found. >+ * >+ * @return On success WERR_OK, a corresponding DOS error is >+ * something went wrong. >+ */ >+WERROR winreg_enum_ports_key(TALLOC_CTX *mem_ctx, >+ struct dcerpc_binding_handle *b, >+ uint32_t *pnum_subkeys, >+ const char ***psubkeys); >+ > #endif /* _RPC_CLIENT_CLI_WINREG_SPOOLSS_H_ */ >diff --git a/source3/rpc_server/spoolss/srv_spoolss_util.c b/source3/rpc_server/spoolss/srv_spoolss_util.c >index 8f346a9..ed7bfa1 100644 >--- a/source3/rpc_server/spoolss/srv_spoolss_util.c >+++ b/source3/rpc_server/spoolss/srv_spoolss_util.c >@@ -754,3 +754,54 @@ WERROR winreg_enum_printer_key_internal(TALLOC_CTX *mem_ctx, > talloc_free(tmp_ctx); > return result; > } >+ >+WERROR winreg_enum_ports_key_internal(TALLOC_CTX *mem_ctx, >+ const struct auth_session_info *session_info, >+ struct messaging_context *msg_ctx, >+ uint32_t *pnum_subkeys, >+ const char ***psubkeys) >+{ >+ WERROR result; >+ struct dcerpc_binding_handle *b; >+ >+ result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); >+ W_ERROR_NOT_OK_RETURN(result); >+ >+ return winreg_enum_ports_key(mem_ctx, b, >+ pnum_subkeys, >+ psubkeys); >+} >+ >+WERROR winreg_get_port_internal(TALLOC_CTX *mem_ctx, >+ const struct auth_session_info *session_info, >+ struct messaging_context *msg_ctx, >+ const char *port, >+ struct spoolss_PortData1 **pdata1) >+{ >+ WERROR result; >+ struct dcerpc_binding_handle *b; >+ >+ result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); >+ W_ERROR_NOT_OK_RETURN(result); >+ >+ return winreg_get_port(mem_ctx, b, >+ port, >+ pdata1); >+} >+ >+WERROR winreg_create_port_internal(TALLOC_CTX *mem_ctx, >+ const struct auth_session_info *session_info, >+ struct messaging_context *msg_ctx, >+ const char *portname, >+ const char *ipaddress) >+{ >+ WERROR result; >+ struct dcerpc_binding_handle *b; >+ >+ result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b); >+ W_ERROR_NOT_OK_RETURN(result); >+ >+ return winreg_create_port(mem_ctx, b, >+ portname, >+ ipaddress); >+} >diff --git a/source3/rpc_server/spoolss/srv_spoolss_util.h b/source3/rpc_server/spoolss/srv_spoolss_util.h >index 8d6fb78..a43c133 100644 >--- a/source3/rpc_server/spoolss/srv_spoolss_util.h >+++ b/source3/rpc_server/spoolss/srv_spoolss_util.h >@@ -157,4 +157,19 @@ WERROR winreg_enum_printer_key_internal(TALLOC_CTX *mem_ctx, > const char *key, > uint32_t *pnum_subkeys, > const char ***psubkeys); >+WERROR winreg_enum_ports_key_internal(TALLOC_CTX *mem_ctx, >+ const struct auth_session_info *session_info, >+ struct messaging_context *msg_ctx, >+ uint32_t *pnum_subkeys, >+ const char ***psubkeys); >+WERROR winreg_get_port_internal(TALLOC_CTX *mem_ctx, >+ const struct auth_session_info *session_info, >+ struct messaging_context *msg_ctx, >+ const char *port, >+ struct spoolss_PortData1 **pdata1); >+WERROR winreg_create_port_internal(TALLOC_CTX *mem_ctx, >+ const struct auth_session_info *session_info, >+ struct messaging_context *msg_ctx, >+ const char *portname, >+ const char *ipaddress); > #endif /* _SRV_SPOOLSS_UITL_H */ >-- >1.7.3.4 > > >From 1b35cc68e378c5022bb2c36940102940dc6d1e5c Mon Sep 17 00:00:00 2001 >From: Justin Chevrier <jchevrier@gmail.com> >Date: Tue, 30 Aug 2011 11:22:41 -0400 >Subject: [PATCH 4/6] s3-spoolss: Hookup port creation basing name on parsed CUPS URIs > >--- > source3/rpc_client/cli_winreg_spoolss.c | 5 +- > source3/rpc_client/cli_winreg_spoolss.h | 3 +- > source3/rpc_server/spoolss/srv_spoolss_nt.c | 169 +++++++++++++++++++++---- > source3/rpc_server/spoolss/srv_spoolss_util.c | 6 +- > source3/rpc_server/spoolss/srv_spoolss_util.h | 3 +- > 5 files changed, 154 insertions(+), 32 deletions(-) > >diff --git a/source3/rpc_client/cli_winreg_spoolss.c b/source3/rpc_client/cli_winreg_spoolss.c >index 3159e0b..0d04a1a 100644 >--- a/source3/rpc_client/cli_winreg_spoolss.c >+++ b/source3/rpc_client/cli_winreg_spoolss.c >@@ -589,7 +589,8 @@ static WERROR winreg_printer_ver_to_dword(const char *str, uint64_t *data) > > WERROR winreg_create_printer(TALLOC_CTX *mem_ctx, > struct dcerpc_binding_handle *winreg_handle, >- const char *sharename) >+ const char *sharename, >+ const char *portname) > { > uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; > struct policy_handle hive_hnd, key_hnd; >@@ -865,7 +866,7 @@ WERROR winreg_create_printer(TALLOC_CTX *mem_ctx, > info2->sharename = sharename; > info2_mask |= SPOOLSS_PRINTER_INFO_SHARENAME; > >- info2->portname = SAMBA_PRINTER_PORT_NAME; >+ info2->portname = portname; > info2_mask |= SPOOLSS_PRINTER_INFO_PORTNAME; > > info2->printprocessor = "winprint"; >diff --git a/source3/rpc_client/cli_winreg_spoolss.h b/source3/rpc_client/cli_winreg_spoolss.h >index 6cd6863..93bfb65 100644 >--- a/source3/rpc_client/cli_winreg_spoolss.h >+++ b/source3/rpc_client/cli_winreg_spoolss.h >@@ -102,7 +102,8 @@ enum spoolss_PrinterInfo2Mask { > > WERROR winreg_create_printer(TALLOC_CTX *mem_ctx, > struct dcerpc_binding_handle *b, >- const char *sharename); >+ const char *sharename, >+ const char *portname); > > /** > * @internal >diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c >index 6403805..3619e6c 100644 >--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c >+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c >@@ -1697,6 +1697,76 @@ static WERROR copy_devicemode(TALLOC_CTX *mem_ctx, > return WERR_OK; > } > >+/******************************************************************** >+********************************************************************/ >+ >+static bool get_printer_port(TALLOC_CTX *mem_ctx, >+ const char *printername, >+ const char **portname, >+ const char **ipaddress) >+{ >+ const char *uri = NULL; >+ char *p, *tmpuri; >+ NTSTATUS nt_status; >+ >+ nt_status = printer_list_get_printer(mem_ctx, >+ printername, >+ NULL, >+ NULL, >+ &uri, >+ NULL); >+ >+ if (NT_STATUS_IS_OK(nt_status)) { >+ if (uri != NULL) { >+ /* We only care about network URIs */ >+ if (uri == strstr(uri, "ipp://") || uri == strstr(uri, "http://") || >+ uri == strstr(uri, "lpd://") || uri == strstr(uri, "https://") || >+ uri == strstr(uri, "socket://")) { >+ uri = strchr(uri, ':'); >+ uri += 3; >+ >+ p = talloc_strdup(mem_ctx, uri); >+ if (p == NULL) { >+ return false; >+ } >+ >+ if ((tmpuri = strchr(p, ':')) != NULL) { >+ *tmpuri = '\0'; >+ } >+ if ((tmpuri = strchr(p, '/')) != NULL) { >+ *tmpuri = '\0'; >+ } >+ >+ /* If what's left after stripping extra characters isn't a valid >+ * IP address, give up. Should we do a DNS lookup on the string? */ >+ if (inet_addr(p) == -1) { >+ goto done; >+ } >+ >+ if (portname) { >+ *portname = talloc_asprintf(mem_ctx, "IP_%s", p); >+ if(*portname == NULL) { >+ return false; >+ } >+ } >+ if (ipaddress) { >+ *ipaddress = talloc_strdup(mem_ctx, p); >+ if(*ipaddress == NULL) { >+ return false; >+ } >+ } >+ >+ talloc_free(p); >+ return true; >+ } >+ } >+ } >+ >+done: >+ DEBUGADD(2,("Printer URI references a local printer or is not recognized.\n")); >+ return false; >+} >+ > /**************************************************************** > _spoolss_OpenPrinterEx > ****************************************************************/ >@@ -1707,6 +1777,7 @@ WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p, > int snum; > char *raddr; > char *rhost; >+ const char *portname, *ipaddress; > struct printer_handle *Printer=NULL; > WERROR result; > int rc; >@@ -1923,11 +1994,23 @@ WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p, > > DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER) > ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" )); >+ >+ if (get_printer_port(p->mem_ctx, lp_const_servicename(snum), &portname, &ipaddress)) { >+ winreg_create_port_internal(p->mem_ctx, >+ get_session_info_system(), >+ p->msg_ctx, >+ portname, >+ ipaddress); >+ } else { >+ portname = talloc_strdup(p->mem_ctx, SAMBA_PRINTER_PORT_NAME); >+ W_ERROR_HAVE_NO_MEMORY(portname); >+ } > > winreg_create_printer_internal(p->mem_ctx, > get_session_info_system(), > p->msg_ctx, >- lp_const_servicename(snum)); >+ lp_const_servicename(snum), >+ portname); > > break; > >@@ -4307,6 +4390,7 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx, > > for (snum = 0; snum < n_services; snum++) { > >+ const char *portname; > const char *printer; > struct spoolss_PrinterInfo2 *info2; > >@@ -4329,8 +4413,14 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx, > } > } > >+ if(!get_printer_port(tmp_ctx, printer, &portname, NULL)) { >+ portname = talloc_strdup(tmp_ctx, SAMBA_PRINTER_PORT_NAME); >+ W_ERROR_HAVE_NO_MEMORY(portname); >+ } >+ > result = winreg_create_printer(tmp_ctx, b, >- printer); >+ printer, >+ portname); > if (!W_ERROR_IS_OK(result)) { > goto out; > } >@@ -7755,49 +7845,61 @@ static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines) > ****************************************************************************/ > > static WERROR enumports_level_1(TALLOC_CTX *mem_ctx, >+ const struct auth_session_info *session_info, >+ struct messaging_context *msg_ctx, > union spoolss_PortInfo **info_p, > uint32_t *count) > { >+ uint32_t num_keys; > union spoolss_PortInfo *info = NULL; > int i=0; > WERROR result = WERR_OK; >- char **qlines = NULL; >- int numlines = 0; >+ const char **array = NULL; >+ DATA_BLOB blob; > >- result = enumports_hook(talloc_tos(), &numlines, &qlines ); >+ result = winreg_enum_ports_key_internal(mem_ctx, >+ session_info, >+ msg_ctx, >+ &num_keys, >+ &array); > if (!W_ERROR_IS_OK(result)) { > goto out; > } > >- if (numlines) { >- info = talloc_array(mem_ctx, union spoolss_PortInfo, numlines); >+ if (!push_reg_multi_sz(mem_ctx, &blob, array)) { >+ result = WERR_NOMEM; >+ goto out; >+ } >+ >+ if (num_keys) { >+ info = talloc_array(mem_ctx, union spoolss_PortInfo, num_keys); > if (!info) { > DEBUG(10,("Returning WERR_NOMEM\n")); > result = WERR_NOMEM; > goto out; > } > >- for (i=0; i<numlines; i++) { >- DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i])); >- result = fill_port_1(info, &info[i].info1, qlines[i]); >+ for (i=0; i<num_keys; i++) { >+ DEBUG(6,("Filling port number [%d] with port [%s]\n", i, array[i])); >+ result = fill_port_1(info, &info[i].info1, array[i]); > if (!W_ERROR_IS_OK(result)) { > goto out; > } > } > } >- TALLOC_FREE(qlines); >+ TALLOC_FREE(array); > > out: > if (!W_ERROR_IS_OK(result)) { > TALLOC_FREE(info); >- TALLOC_FREE(qlines); >+ TALLOC_FREE(array); > *count = 0; > *info_p = NULL; > return result; > } > > *info_p = info; >- *count = numlines; >+ *count = num_keys; > > return WERR_OK; > } >@@ -7807,49 +7909,61 @@ out: > ****************************************************************************/ > > static WERROR enumports_level_2(TALLOC_CTX *mem_ctx, >+ const struct auth_session_info *session_info, >+ struct messaging_context *msg_ctx, > union spoolss_PortInfo **info_p, > uint32_t *count) > { >+ uint32_t num_keys; > union spoolss_PortInfo *info = NULL; > int i=0; > WERROR result = WERR_OK; >- char **qlines = NULL; >- int numlines = 0; >+ const char **array = NULL; >+ DATA_BLOB blob; > >- result = enumports_hook(talloc_tos(), &numlines, &qlines ); >+ result = winreg_enum_ports_key_internal(mem_ctx, >+ session_info, >+ msg_ctx, >+ &num_keys, >+ &array); > if (!W_ERROR_IS_OK(result)) { > goto out; > } > >- if (numlines) { >- info = talloc_array(mem_ctx, union spoolss_PortInfo, numlines); >+ if (!push_reg_multi_sz(mem_ctx, &blob, array)) { >+ result = WERR_NOMEM; >+ goto out; >+ } >+ >+ if (num_keys) { >+ info = talloc_array(mem_ctx, union spoolss_PortInfo, num_keys); > if (!info) { > DEBUG(10,("Returning WERR_NOMEM\n")); > result = WERR_NOMEM; > goto out; > } > >- for (i=0; i<numlines; i++) { >- DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i])); >- result = fill_port_2(info, &info[i].info2, qlines[i]); >+ for (i=0; i<num_keys; i++) { >+ DEBUG(6,("Filling port number [%d] with port [%s]\n", i, array[i])); >+ result = fill_port_2(info, &info[i].info2, array[i]); > if (!W_ERROR_IS_OK(result)) { > goto out; > } > } > } >- TALLOC_FREE(qlines); >+ TALLOC_FREE(array); > > out: > if (!W_ERROR_IS_OK(result)) { > TALLOC_FREE(info); >- TALLOC_FREE(qlines); >+ TALLOC_FREE(array); > *count = 0; > *info_p = NULL; > return result; > } > > *info_p = info; >- *count = numlines; >+ *count = num_keys; > > return WERR_OK; > } >@@ -7861,6 +7975,7 @@ out: > WERROR _spoolss_EnumPorts(struct pipes_struct *p, > struct spoolss_EnumPorts *r) > { >+ const struct auth_session_info *session_info = get_session_info_system(); > WERROR result; > > /* that's an [in out] buffer */ >@@ -7877,11 +7992,13 @@ WERROR _spoolss_EnumPorts(struct pipes_struct *p, > > switch (r->in.level) { > case 1: >- result = enumports_level_1(p->mem_ctx, r->out.info, >+ result = enumports_level_1(p->mem_ctx, session_info, >+ p->msg_ctx, r->out.info, > r->out.count); > break; > case 2: >- result = enumports_level_2(p->mem_ctx, r->out.info, >+ result = enumports_level_2(p->mem_ctx, session_info, >+ p->msg_ctx, r->out.info, > r->out.count); > break; > default: >diff --git a/source3/rpc_server/spoolss/srv_spoolss_util.c b/source3/rpc_server/spoolss/srv_spoolss_util.c >index ed7bfa1..4bb370a 100644 >--- a/source3/rpc_server/spoolss/srv_spoolss_util.c >+++ b/source3/rpc_server/spoolss/srv_spoolss_util.c >@@ -182,7 +182,8 @@ WERROR winreg_get_printer_internal(TALLOC_CTX *mem_ctx, > WERROR winreg_create_printer_internal(TALLOC_CTX *mem_ctx, > const struct auth_session_info *session_info, > struct messaging_context *msg_ctx, >- const char *sharename) >+ const char *sharename, >+ const char *portname) > { > WERROR result; > struct dcerpc_binding_handle *b; >@@ -201,7 +202,8 @@ WERROR winreg_create_printer_internal(TALLOC_CTX *mem_ctx, > > result = winreg_create_printer(mem_ctx, > b, >- sharename); >+ sharename, >+ portname); > > talloc_free(tmp_ctx); > return result; >diff --git a/source3/rpc_server/spoolss/srv_spoolss_util.h b/source3/rpc_server/spoolss/srv_spoolss_util.h >index a43c133..ac0107b 100644 >--- a/source3/rpc_server/spoolss/srv_spoolss_util.h >+++ b/source3/rpc_server/spoolss/srv_spoolss_util.h >@@ -52,7 +52,8 @@ WERROR winreg_get_printer_internal(TALLOC_CTX *mem_ctx, > WERROR winreg_create_printer_internal(TALLOC_CTX *mem_ctx, > const struct auth_session_info *session_info, > struct messaging_context *msg_ctx, >- const char *sharename); >+ const char *sharename, >+ const char *portname); > WERROR winreg_update_printer_internal(TALLOC_CTX *mem_ctx, > const struct auth_session_info *session_info, > struct messaging_context *msg_ctx, >-- >1.7.3.4 > > >From 26bb259076c0fc40ee16c85d7d8e61910e483068 Mon Sep 17 00:00:00 2001 >From: Justin Chevrier <jchevrier@gmail.com> >Date: Tue, 30 Aug 2011 12:34:11 -0400 >Subject: [PATCH 5/6] s3-spoolss: Support opening ports via OpenPrinterEx > >--- > librpc/idl/spoolss.idl | 1 + > source3/rpc_server/spoolss/srv_spoolss_nt.c | 43 +++++++++++++++++++++++++-- > 2 files changed, 41 insertions(+), 3 deletions(-) > >diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl >index edd2490..46efe69 100644 >--- a/librpc/idl/spoolss.idl >+++ b/librpc/idl/spoolss.idl >@@ -2102,6 +2102,7 @@ cpp_quote("#define spoolss_security_descriptor security_descriptor") > const string SPL_TCPIP_PORT = "Standard TCP/IP Port"; > const string SPL_XCV_MONITOR_LOCALMON = ",XcvMonitor Local Port"; > const string SPL_XCV_MONITOR_TCPMON = ",XcvMonitor Standard TCP/IP Port"; >+ const string SPL_XCV_PORT = ",XcvPort "; > > typedef [public,gensize] struct { > [relative] nstring *port_name; >diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c >index 3619e6c..db1d96a 100644 >--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c >+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c >@@ -539,9 +539,9 @@ static void prune_printername_cache(void) > > /**************************************************************************** > Set printer handle name.. Accept names like \\server, \\server\printer, >- \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See >- the MSDN docs regarding OpenPrinter() for details on the XcvData() and >- XcvDataPort() interface. >+ \\server\SHARE, "\\server\,XcvMonitor Standard TCP/IP Port", & >+ "\\server\,XcvPort portname" See the MSDN docs regarding OpenPrinter() >+ for details on the XcvData() and XcvDataPort() interface. > ****************************************************************************/ > > static WERROR set_printer_hnd_name(TALLOC_CTX *mem_ctx, >@@ -553,10 +553,12 @@ static WERROR set_printer_hnd_name(TALLOC_CTX *mem_ctx, > int snum; > int n_services=lp_numservices(); > char *aprinter; >+ const char *portname; > const char *printername; > const char *servername = NULL; > fstring sname; > bool found = false; >+ struct spoolss_PortData1 *data1 = NULL; > struct spoolss_PrinterInfo2 *info2 = NULL; > WERROR result; > char *p; >@@ -578,6 +580,11 @@ static WERROR set_printer_hnd_name(TALLOC_CTX *mem_ctx, > if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) { > *aprinter = '\0'; > aprinter++; >+ /* Ensure there isn't a second backslash */ >+ if ( *aprinter == '\\' ) { >+ *aprinter = '\0'; >+ aprinter++; >+ } > } > if (!is_myname_or_ipaddr(servername)) { > return WERR_INVALID_PRINTER_NAME; >@@ -627,7 +634,36 @@ static WERROR set_printer_hnd_name(TALLOC_CTX *mem_ctx, > fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON); > found = true; > } >+ else if ( strstr(aprinter, SPL_XCV_PORT) ) { >+ if ((portname = strchr_m(aprinter, ' ')) != NULL ) { >+ portname++; >+ /* Don't bother searching the registry for >+ dummy port name: "Samba Printer Port" */ >+ if (!strequal(portname, SAMBA_PRINTER_PORT_NAME)) { >+ >+ result = winreg_get_port_internal(mem_ctx, >+ session_info, >+ msg_ctx, >+ portname, >+ &data1); >+ if (!W_ERROR_IS_OK(result)) { >+ DEBUG(2,("set_printer_hnd_name: failed to lookup port [%s] -- result [%s]\n", >+ portname, win_errstr(result))); >+ return WERR_INVALID_PRINTER_NAME; >+ } > >+ DEBUG(4, ("Found Port: [%s]\n", portname)); >+ fstrcpy(sname, portname); >+ Printer->printer_type = SPLHND_PORTMON_TCP; >+ >+ TALLOC_FREE(data1); >+ goto done; >+ } >+ } >+ >+ DEBUGADD(4,("Port %s not found\n", portname)); >+ return WERR_INVALID_PRINTER_NAME; >+ } > /* > * With hundreds of printers, the "for" loop iterating all > * shares can be quite expensive, as it is done on every >@@ -722,6 +758,7 @@ static WERROR set_printer_hnd_name(TALLOC_CTX *mem_ctx, > TALLOC_FREE(cache_key); > } > >+done: > DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname)); > > strlcpy(Printer->sharename, sname, sizeof(Printer->sharename)); >-- >1.7.3.4 > > >From 6c2c1f7b6282433561fa2748f5c94fafc874018f Mon Sep 17 00:00:00 2001 >From: Justin Chevrier <jchevrier@gmail.com> >Date: Tue, 30 Aug 2011 16:55:59 -0400 >Subject: [PATCH 6/6] s3-spoolss: Add support for IPAddress and GetConfigInfo XcvData commands > >--- > librpc/idl/spoolss.idl | 4 + > source3/rpc_server/spoolss/srv_spoolss_nt.c | 154 ++++++++++++++++++++++++--- > 2 files changed, 144 insertions(+), 14 deletions(-) > >diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl >index 46efe69..7cec577 100644 >--- a/librpc/idl/spoolss.idl >+++ b/librpc/idl/spoolss.idl >@@ -3053,6 +3053,10 @@ cpp_quote("#define spoolss_security_descriptor security_descriptor") > nstring dll_name; > } spoolss_MonitorUi; > >+ typedef [public] struct { >+ nstring ip_address; >+ } spoolss_IPAddress; >+ > WERROR spoolss_XcvData( > [in,ref] policy_handle *handle, > [in] [string,charset(UTF16)] uint16 function_name[], >diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c >index db1d96a..6e2b57b 100644 >--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c >+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c >@@ -166,7 +166,9 @@ const struct standard_mapping printserver_std_mapping = { > > struct xcv_api_table { > const char *name; >- WERROR(*fn) (TALLOC_CTX *mem_ctx, struct security_token *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed); >+ WERROR(*fn) (TALLOC_CTX *mem_ctx, const struct auth_session_info *session_info, >+ struct messaging_context *msg_ctx, struct security_token *token, const char *printername, >+ DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed); > }; > > static void prune_printername_cache(void); >@@ -10078,7 +10080,10 @@ static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf, > *******************************************************************/ > > static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx, >- struct security_token *token, DATA_BLOB *in, >+ const struct auth_session_info *session_info, >+ struct messaging_context *msg_ctx, >+ struct security_token *token, >+ const char *printername, DATA_BLOB *in, > DATA_BLOB *out, uint32_t *needed) > { > const char *dllname = "tcpmonui.dll"; >@@ -10099,6 +10104,21 @@ static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx, > /******************************************************************* > ********************************************************************/ > >+static bool push_port_data_1(TALLOC_CTX *mem_ctx, DATA_BLOB *buf, >+ struct spoolss_PortData1 *port1) >+{ >+ enum ndr_err_code ndr_err; >+ ndr_err = ndr_push_struct_blob(buf, mem_ctx, port1, >+ (ndr_push_flags_fn_t)ndr_push_spoolss_PortData1); >+ if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) { >+ NDR_PRINT_DEBUG(spoolss_PortData1, port1); >+ } >+ return NDR_ERR_CODE_IS_SUCCESS(ndr_err); >+} >+ >+/******************************************************************* >+ ********************************************************************/ >+ > static bool pull_port_data_1(TALLOC_CTX *mem_ctx, > struct spoolss_PortData1 *port1, > const DATA_BLOB *buf) >@@ -10133,8 +10153,11 @@ static bool pull_port_data_2(TALLOC_CTX *mem_ctx, > *******************************************************************/ > > static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx, >- struct security_token *token, DATA_BLOB *in, >- DATA_BLOB *out, uint32_t *needed) >+ const struct auth_session_info *session_info, >+ struct messaging_context *msg_ctx, >+ struct security_token *token, >+ const char *printername, >+ DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed) > { > struct spoolss_PortData1 port1; > struct spoolss_PortData2 port2; >@@ -10216,16 +10239,110 @@ static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx, > } > > /******************************************************************* >+ Streams the PortData1 structure of the port >+*******************************************************************/ >+ >+static WERROR xcvtcp_getconfiginfo(TALLOC_CTX *mem_ctx, >+ const struct auth_session_info *session_info, >+ struct messaging_context *msg_ctx, >+ struct security_token *token, >+ const char *printername, DATA_BLOB *in, >+ DATA_BLOB *out, uint32_t *needed) >+{ >+ WERROR result; >+ struct spoolss_PortData1 *port1 = NULL; >+ /* Windows appears to set needed to 0 */ >+ *needed = 0; >+ >+ result = winreg_get_port_internal(mem_ctx, >+ session_info, >+ msg_ctx, >+ printername, >+ &port1); >+ >+ if (!W_ERROR_IS_OK(result)) { >+ return WERR_UNKNOWN_PORT; >+ } >+ >+ if (!push_port_data_1(mem_ctx, out, port1)) { >+ return WERR_NOMEM; >+ } >+ >+ TALLOC_FREE(port1); >+ >+ return WERR_OK; >+} >+ >+/******************************************************************* >+ ********************************************************************/ >+ >+static bool push_ipaddress_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf, >+ const char *ipaddress) >+{ >+ enum ndr_err_code ndr_err; >+ struct spoolss_IPAddress ip; >+ >+ ip.ip_address = ipaddress; >+ >+ ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ip, >+ (ndr_push_flags_fn_t)ndr_push_spoolss_IPAddress); >+ if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) { >+ NDR_PRINT_DEBUG(spoolss_IPAddress, &ip); >+ } >+ return NDR_ERR_CODE_IS_SUCCESS(ndr_err); >+} >+ >+/******************************************************************* >+ Streams the IP Address of the port >+*******************************************************************/ >+ >+static WERROR xcvtcp_ipaddress(TALLOC_CTX *mem_ctx, >+ const struct auth_session_info *session_info, >+ struct messaging_context *msg_ctx, >+ struct security_token *token, >+ const char *printername, DATA_BLOB *in, >+ DATA_BLOB *out, uint32_t *needed) >+{ >+ WERROR result; >+ struct spoolss_PortData1 *port1 = NULL; >+ /* Windows appears to set needed to 0 */ >+ *needed = 0; >+ >+ result = winreg_get_port_internal(mem_ctx, >+ session_info, >+ msg_ctx, >+ printername, >+ &port1); >+ >+ if (!W_ERROR_IS_OK(result)) { >+ return WERR_UNKNOWN_PORT; >+ } >+ >+ if (!push_ipaddress_buf(mem_ctx, out, port1->ip_address)) { >+ return WERR_NOMEM; >+ } >+ >+ TALLOC_FREE(port1); >+ >+ return WERR_OK; >+} >+ >+/******************************************************************* > *******************************************************************/ > > struct xcv_api_table xcvtcp_cmds[] = { >- { "MonitorUI", xcvtcp_monitorui }, >- { "AddPort", xcvtcp_addport}, >- { NULL, NULL } >+ { "MonitorUI", xcvtcp_monitorui }, >+ { "AddPort", xcvtcp_addport }, >+ { "GetConfigInfo", xcvtcp_getconfiginfo }, >+ { "IPAddress", xcvtcp_ipaddress }, >+ { NULL, NULL } > }; > > static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx, >+ const struct auth_session_info *session_info, >+ struct messaging_context *msg_ctx, > struct security_token *token, const char *command, >+ const char *printername, > DATA_BLOB *inbuf, > DATA_BLOB *outbuf, > uint32_t *needed ) >@@ -10236,7 +10353,7 @@ static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx, > > for ( i=0; xcvtcp_cmds[i].name; i++ ) { > if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 ) >- return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed); >+ return xcvtcp_cmds[i].fn(mem_ctx, session_info, msg_ctx, token, printername, inbuf, outbuf, needed); > } > > return WERR_BADFUNC; >@@ -10247,7 +10364,7 @@ static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx, > #if 0 /* don't support management using the "Local Port" monitor */ > > static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx, >- struct security_token *token, DATA_BLOB *in, >+ struct security_token *token, const char *printername, DATA_BLOB *in, > DATA_BLOB *out, uint32_t *needed) > { > const char *dllname = "localui.dll"; >@@ -10284,8 +10401,10 @@ struct xcv_api_table xcvlocal_cmds[] = { > *******************************************************************/ > > static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx, >+ const struct auth_session_info *session_info, >+ struct messaging_context *msg_ctx, > struct security_token *token, const char *command, >- DATA_BLOB *inbuf, DATA_BLOB *outbuf, >+ const char *printername, DATA_BLOB *inbuf, DATA_BLOB *outbuf, > uint32_t *needed) > { > int i; >@@ -10294,7 +10413,7 @@ static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx, > > for ( i=0; xcvlocal_cmds[i].name; i++ ) { > if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 ) >- return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed); >+ return xcvlocal_cmds[i].fn(mem_ctx, session_info, msg_ctx, token, printername, inbuf, outbuf, needed); > } > return WERR_BADFUNC; > } >@@ -10323,9 +10442,10 @@ WERROR _spoolss_XcvData(struct pipes_struct *p, > return WERR_BADFID; > } > >- /* requires administrative access to the server */ >- >- if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) { >+ /* AddPort, ConfigPort, DeletePort and MonitorUI require administrative access to the server */ >+ if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) && >+ (strequal(r->in.function_name, "AddPort") || strequal(r->in.function_name, "ConfigPort") || >+ strequal(r->in.function_name, "DeletePort") || strequal(r->in.function_name, "MonitorUI")) ) { > DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n")); > return WERR_ACCESS_DENIED; > } >@@ -10342,15 +10462,21 @@ WERROR _spoolss_XcvData(struct pipes_struct *p, > switch ( Printer->printer_type ) { > case SPLHND_PORTMON_TCP: > werror = process_xcvtcp_command(p->mem_ctx, >+ p->session_info, >+ p->msg_ctx, > p->session_info->security_token, > r->in.function_name, >+ Printer->sharename, > &r->in.in_data, &out_data, > r->out.needed); > break; > case SPLHND_PORTMON_LOCAL: > werror = process_xcvlocal_command(p->mem_ctx, >+ p->session_info, >+ p->msg_ctx, > p->session_info->security_token, > r->in.function_name, >+ Printer->sharename, > &r->in.in_data, &out_data, > r->out.needed); > break; >-- >1.7.3.4 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
gd
:
review?
(
gd
)
Actions:
View
Attachments on
bug 6296
: 6848