From 854467851da48e02dcd8f869cb031c8943707017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Fri, 13 May 2011 10:02:42 +0200 Subject: [PATCH] s3-printing: Get the location info from cups. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Günther Deschner --- 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_aix.c | 4 +-- source3/printing/print_cups.c | 18 +++++++++++-- source3/printing/print_iprint.c | 2 +- source3/printing/print_standard.c | 2 +- source3/printing/print_svid.c | 2 +- source3/printing/printer_list.c | 42 +++++++++++++++++++++++++------ source3/printing/printer_list.h | 8 +++++- 12 files changed, 85 insertions(+), 32 deletions(-) diff --git a/librpc/idl/printcap.idl b/librpc/idl/printcap.idl index 5ab380ce6cb..d9c34f3fab7 100644 --- a/librpc/idl/printcap.idl +++ b/librpc/idl/printcap.idl @@ -7,6 +7,7 @@ interface printcap typedef struct { [charset(UTF8),string] uint8 *name; [charset(UTF8),string] uint8 *info; + [charset(UTF8),string] uint8 *location; } pcap_printer; typedef [public] struct { diff --git a/source3/include/proto.h b/source3/include/proto.h index 7e25f8e3adb..8c00e3a2746 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1634,7 +1634,8 @@ bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal); 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, void *pdata); +void lp_add_one_printer(const char *name, const char *comment, + const char *location, void *pdata); bool lp_loaded(void); void lp_killunused(bool (*snumused) (int)); void lp_kill_all_services(void); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index e4dd3661da8..e245ecf5948 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -8610,7 +8610,8 @@ static void lp_add_auto_services(char *str) Auto-load one printer. ***************************************************************************/ -void lp_add_one_printer(const char *name, const char *comment, void *pdata) +void lp_add_one_printer(const char *name, const char *comment, + const char *location, void *pdata) { int printers = lp_servicenumber(PRINTERS_NAME); int i; diff --git a/source3/printing/pcap.c b/source3/printing/pcap.c index 7208f4b7f8c..62db4f5efc1 100644 --- a/source3/printing/pcap.c +++ b/source3/printing/pcap.c @@ -43,10 +43,11 @@ struct pcap_cache { char *name; char *comment; + char *location; struct pcap_cache *next; }; -bool pcap_cache_add_specific(struct pcap_cache **ppcache, const char *name, const char *comment) +bool pcap_cache_add_specific(struct pcap_cache **ppcache, const char *name, const char *comment, const char *location) { struct pcap_cache *p; @@ -55,9 +56,11 @@ 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; - DEBUG(11,("pcap_cache_add_specific: Adding name %s info %s\n", - p->name, p->comment ? p->comment : "")); + DEBUG(11,("pcap_cache_add_specific: Adding name %s info %s, location: %s\n", + p->name, p->comment ? p->comment : "", + p->location ? p->location : "")); p->next = *ppcache; *ppcache = p; @@ -74,17 +77,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); } *pp_cache = NULL; } -bool pcap_cache_add(const char *name, const char *comment) +bool pcap_cache_add(const char *name, const char *comment, const char *location) { NTSTATUS status; time_t t = time_mono(NULL); - status = printer_list_set_printer(talloc_tos(), name, comment, t); + status = printer_list_set_printer(talloc_tos(), name, comment, location, t); return NT_STATUS_IS_OK(status); } @@ -109,7 +113,7 @@ bool pcap_cache_replace(const struct pcap_cache *pcache) } for (p = pcache; p; p = p->next) { - pcap_cache_add(p->name, p->comment); + pcap_cache_add(p->name, p->comment, p->location); } status = printer_list_clean_old(); @@ -205,7 +209,7 @@ bool pcap_printername_ok(const char *printername) { NTSTATUS status; - status = printer_list_get_printer(talloc_tos(), printername, NULL, 0); + status = printer_list_get_printer(talloc_tos(), printername, NULL, NULL, 0); return NT_STATUS_IS_OK(status); } @@ -214,18 +218,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 *, void *), + void (*fn)(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, pdata); + fn(p->name, p->comment, p->location, pdata); return; } -void pcap_printer_fn(void (*fn)(const char *, const char *, void *), void *pdata) +void pcap_printer_fn(void (*fn)(const char *, const char *, const char *, void *), void *pdata) { NTSTATUS status; diff --git a/source3/printing/pcap.h b/source3/printing/pcap.h index e24142e8b2a..e8276f9aadb 100644 --- a/source3/printing/pcap.h +++ b/source3/printing/pcap.h @@ -20,13 +20,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); +bool pcap_cache_add_specific(struct pcap_cache **ppcache, const char *name, const char *comment, const char *location); void pcap_cache_destroy_specific(struct pcap_cache **ppcache); -bool pcap_cache_add(const char *name, const char *comment); +bool pcap_cache_add(const char *name, const char *comment, const char *location); 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 *, void *), void *); -void pcap_printer_fn(void (*fn)(const char *, const char *, void *), void *); +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_cache_reload(struct tevent_context *ev, struct messaging_context *msg_ctx, diff --git a/source3/printing/print_aix.c b/source3/printing/print_aix.c index b7198d36322..23d9a86fe37 100644 --- a/source3/printing/print_aix.c +++ b/source3/printing/print_aix.c @@ -86,7 +86,7 @@ bool aix_cache_reload(void) /* name is found without stanza device */ /* probably a good printer ??? */ iEtat = 0; - if (!pcap_cache_add(name, NULL)) { + if (!pcap_cache_add(name, NULL, NULL)) { SAFE_FREE(line); x_fclose(pfile); TALLOC_FREE(ctx); @@ -101,7 +101,7 @@ bool aix_cache_reload(void) } else if (strstr_m(line, "device")) { /* it's a good virtual printer */ iEtat = 0; - if (!pcap_cache_add(name, NULL)) { + if (!pcap_cache_add(name, NULL, NULL)) { SAFE_FREE(line); x_fclose(pfile); TALLOC_FREE(ctx); diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c index 077d82bcbfb..44890131e82 100644 --- a/source3/printing/print_cups.c +++ b/source3/printing/print_cups.c @@ -163,6 +163,7 @@ static bool process_cups_printers_response(TALLOC_CTX *mem_ctx, ipp_attribute_t *attr; char *name; char *info; + char *location = NULL; struct pcap_printer *printer; bool ret_ok = false; @@ -206,6 +207,16 @@ static bool process_cups_printers_response(TALLOC_CTX *mem_ctx, } } + if (strcmp(attr->name, "printer-location") == 0 && + attr->value_tag == IPP_TAG_TEXT) { + if (!pull_utf8_talloc(mem_ctx, + &location, + attr->values[0].string.text, + &size)) { + goto err_out; + } + } + attr = attr->next; } @@ -229,6 +240,7 @@ static bool process_cups_printers_response(TALLOC_CTX *mem_ctx, pcap_data->printers = printer; 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->count++; } @@ -252,7 +264,8 @@ static bool cups_cache_reload_async(int fd) static const char *requested[] =/* Requested attributes */ { "printer-name", - "printer-info" + "printer-info", + "printer-location" }; bool ret = False; enum ndr_err_code ndr_ret; @@ -478,7 +491,8 @@ static void cups_async_callback(struct event_context *event_ctx, for (i = 0; i < pcap_data.count; i++) { ret_ok = pcap_cache_add_specific(&tmp_pcap_cache, pcap_data.printers[i].name, - pcap_data.printers[i].info); + pcap_data.printers[i].info, + pcap_data.printers[i].location); 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 ea375da3b70..1392cba7b8f 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); + pcap_cache_add(name, info, NULL); } out: diff --git a/source3/printing/print_standard.c b/source3/printing/print_standard.c index a8460935c99..6a86d84b1e2 100644 --- a/source3/printing/print_standard.c +++ b/source3/printing/print_standard.c @@ -120,7 +120,7 @@ bool std_pcap_cache_reload(const char *pcap_name) comment[60] = 0; name[MAXPRINTERLEN] = 0; - if (*name && !pcap_cache_add(name, comment)) { + if (*name && !pcap_cache_add(name, comment, NULL)) { x_fclose(pcap_file); return false; } diff --git a/source3/printing/print_svid.c b/source3/printing/print_svid.c index 4929be14bc7..222649308ca 100644 --- a/source3/printing/print_svid.c +++ b/source3/printing/print_svid.c @@ -111,7 +111,7 @@ bool sysv_cache_reload(void) *tmp = '\0'; /* add it to the cache */ - if (!pcap_cache_add(name, NULL)) { + if (!pcap_cache_add(name, NULL, NULL)) { TALLOC_FREE(lines); return False; } diff --git a/source3/printing/printer_list.c b/source3/printing/printer_list.c index d8be89363e5..d28278d069b 100644 --- a/source3/printing/printer_list.c +++ b/source3/printing/printer_list.c @@ -27,7 +27,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 "ddPP" +#define PL_DATA_FORMAT "ddPPP" #define PL_TSTAMP_FORMAT "dd" static struct db_context *get_printer_list_db(void) @@ -65,6 +65,7 @@ bool printer_list_parent_init(void) NTSTATUS printer_list_get_printer(TALLOC_CTX *mem_ctx, const char *name, const char **comment, + const char **location, time_t *last_refresh) { struct db_context *db; @@ -73,6 +74,7 @@ NTSTATUS printer_list_get_printer(TALLOC_CTX *mem_ctx, uint32_t time_h, time_l; char *nstr = NULL; char *cstr = NULL; + char *lstr = NULL; NTSTATUS status; int ret; @@ -96,7 +98,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); + &time_h, &time_l, &nstr, &cstr, &lstr); if (ret == -1) { DEBUG(1, ("Failed to un pack printer data")); status = NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -116,6 +118,15 @@ NTSTATUS printer_list_get_printer(TALLOC_CTX *mem_ctx, } } + if (location) { + *location = talloc_strdup(mem_ctx, lstr); + if (*location == NULL) { + DEBUG(1, ("Failed to strdup location!\n")); + status = NT_STATUS_NO_MEMORY; + goto done; + } + } + status = NT_STATUS_OK; done: @@ -128,6 +139,7 @@ done: NTSTATUS printer_list_set_printer(TALLOC_CTX *mem_ctx, const char *name, const char *comment, + const char *location, time_t last_refresh) { struct db_context *db; @@ -136,6 +148,7 @@ NTSTATUS printer_list_set_printer(TALLOC_CTX *mem_ctx, uint64_t time_64; uint32_t time_h, time_l; const char *str = NULL; + const char *str2 = NULL; NTSTATUS status; int len; @@ -156,11 +169,18 @@ NTSTATUS printer_list_set_printer(TALLOC_CTX *mem_ctx, str = ""; } + if (location) { + str2 = location; + } else { + str2 = ""; + } + + 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); + len = tdb_pack(NULL, 0, PL_DATA_FORMAT, time_h, time_l, name, str, str2); data.dptr = talloc_array(key, uint8_t, len); if (!data.dptr) { @@ -289,6 +309,7 @@ static int printer_list_clean_fn(struct db_record *rec, void *private_data) time_t refresh; char *name; char *comment; + char *location; int ret; /* skip anything that does not contain PL_DATA_FORMAT data */ @@ -298,7 +319,8 @@ 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); + PL_DATA_FORMAT, &time_h, &time_l, &name, &comment, + &location); if (ret == -1) { DEBUG(1, ("Failed to un pack printer data")); state->status = NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -307,6 +329,7 @@ static int printer_list_clean_fn(struct db_record *rec, void *private_data) SAFE_FREE(name); SAFE_FREE(comment); + SAFE_FREE(location); refresh = (time_t)(((uint64_t)time_h << 32) + time_l); @@ -342,7 +365,7 @@ NTSTATUS printer_list_clean_old(void) } struct printer_list_exec_state { - void (*fn)(const char *, const char *, void *); + void (*fn)(const char *, const char *, const char *, void *); void *private_data; NTSTATUS status; }; @@ -354,6 +377,7 @@ static int printer_list_exec_fn(struct db_record *rec, void *private_data) uint32_t time_h, time_l; char *name; char *comment; + char *location; int ret; /* always skip PL_TIMESTAMP_KEY key */ @@ -362,21 +386,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); + PL_DATA_FORMAT, &time_h, &time_l, &name, &comment, + &location); if (ret == -1) { DEBUG(1, ("Failed to un pack printer data")); state->status = NT_STATUS_INTERNAL_DB_CORRUPTION; return -1; } - state->fn(name, comment, state->private_data); + state->fn(name, comment, location, state->private_data); SAFE_FREE(name); SAFE_FREE(comment); + SAFE_FREE(location); return 0; } -NTSTATUS printer_list_run_fn(void (*fn)(const char *, const char *, void *), +NTSTATUS printer_list_run_fn(void (*fn)(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 fce3e34248c..fb2e007ae6c 100644 --- a/source3/printing/printer_list.h +++ b/source3/printing/printer_list.h @@ -32,6 +32,8 @@ bool printer_list_parent_init(void); * * @param[out] comment A pointer to store the comment of the printer. * + * @param[out] location A pointer to store the location of the printer. + * * @param[out] last_refresh A pointer to store the last refresh time of the * printer. * @@ -41,6 +43,7 @@ bool printer_list_parent_init(void); NTSTATUS printer_list_get_printer(TALLOC_CTX *mem_ctx, const char *name, const char **comment, + const char **location, time_t *last_refresh); /** @@ -52,6 +55,8 @@ NTSTATUS printer_list_get_printer(TALLOC_CTX *mem_ctx, * * @param[in] comment The comment to store in the db. * + * @param[in] location The location to store in the db. + * * @param[in] last_refresh The last refresh time of the printer to store in * the db. * @@ -61,6 +66,7 @@ NTSTATUS printer_list_get_printer(TALLOC_CTX *mem_ctx, NTSTATUS printer_list_set_printer(TALLOC_CTX *mem_ctx, const char *name, const char *comment, + const char *location, time_t last_refresh); /** @@ -94,6 +100,6 @@ NTSTATUS printer_list_mark_reload(void); */ NTSTATUS printer_list_clean_old(void); -NTSTATUS printer_list_run_fn(void (*fn)(const char *, const char *, void *), +NTSTATUS printer_list_run_fn(void (*fn)(const char *, const char *, const char *, void *), void *private_data); #endif /* _PRINTER_LIST_H_ */