[PATCH 4/6] s3-spoolss: Hookup port creation basing name on parsed CUPS URIs
Justin Chevrier
jchevrier at gmail.com
Wed Aug 31 13:03:12 MDT 2011
Signed-off-by: Justin Chevrier <jchevrier at gmail.com>
---
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
More information about the samba-technical
mailing list