[PATCH 2/6] s3-spoolss: Pull printer URI from CUPS and add support for URIs to printer_list

Justin Chevrier jchevrier at gmail.com
Wed Aug 31 13:03:10 MDT 2011


Signed-off-by: Justin Chevrier <jchevrier at gmail.com>
---
 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



More information about the samba-technical mailing list