From 9e5a32f7b25dabe1dc6f56307d33ac800a4d7d80 Mon Sep 17 00:00:00 2001 From: Jan Just Keijser Date: Fri, 26 Nov 2021 17:39:24 +0100 Subject: [PATCH 1/2] Fix drowning of minor_status code when accepting GSSAPI security context Signed-off-by: Jan Just Keijser --- scheduler/auth.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scheduler/auth.c b/scheduler/auth.c index 4fdcf1177..35e34e6c8 100644 --- a/scheduler/auth.c +++ b/scheduler/auth.c @@ -717,7 +717,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ int len; /* Length of authorization string */ gss_ctx_id_t context; /* Authorization context */ OM_uint32 major_status, /* Major status code */ - minor_status; /* Minor status code */ + minor_status, /* Minor status code */ + tmp_status; /* Temporary status code */ gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER, /* Input token from string */ output_token = GSS_C_EMPTY_BUFFER; @@ -781,7 +782,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ NULL); if (output_token.length > 0) - gss_release_buffer(&minor_status, &output_token); + gss_release_buffer(&tmp_status, &output_token); if (GSS_ERROR(major_status)) { From 360ac78818ee7cea24cf78fcfb9bc9470e2e1657 Mon Sep 17 00:00:00 2001 From: Jan Just Keijser Date: Thu, 7 Apr 2022 16:41:08 +0200 Subject: [PATCH 2/2] Add support for filtering the list of printers on the client side Signed-off-by: Jan Just Keijser --- cups/dest.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 2 deletions(-) diff --git a/cups/dest.c b/cups/dest.c index 984c6bddf..ae9755e51 100644 --- a/cups/dest.c +++ b/cups/dest.c @@ -230,6 +230,7 @@ static int cups_find_dest(const char *name, const char *instance, static int cups_get_cb(_cups_getdata_t *data, unsigned flags, cups_dest_t *dest); static char *cups_get_default(const char *filename, char *namebuf, size_t namesize, const char **instance); +static char *cups_get_printer_list(const char *filename, char *namebuf, size_t namesize); static int cups_get_dests(const char *filename, const char *match_name, const char *match_inst, int load_all, int user_default_set, int num_dests, cups_dest_t **dests); static char *cups_make_string(ipp_attribute_t *attr, char *buffer, size_t bufsize); @@ -1441,6 +1442,12 @@ _cupsGetDests(http_t *http, /* I - Connection to server or ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type-mask", (int)mask); } + if (name) + { + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "limit", 1); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "first-printer-name", NULL, name); + } + /* * Do the request and get back a response... */ @@ -1571,6 +1578,16 @@ _cupsGetDests(http_t *http, /* I - Connection to server or continue; } + if (name && printer_name && strcmp(name, printer_name) != 0) + { + cupsFreeOptions(num_options, options); + + if (attr == NULL) + break; + else + continue; + } + if ((dest = cups_add_dest(printer_name, NULL, &num_dests, dests)) != NULL) { dest->num_options = num_options; @@ -3384,8 +3401,10 @@ cups_enum_dests( void *user_data) /* I - User data */ { int i, j, k, /* Looping vars */ - num_dests; /* Number of destinations */ + num_dests, /* Number of destinations */ + tmp_num_dests; /* Number of destinations */ cups_dest_t *dests = NULL, /* Destinations */ + *tmp_dests = NULL, /* Destinations */ *dest; /* Current destination */ cups_option_t *option; /* Current option */ const char *user_default; /* Default printer from environment */ @@ -3422,6 +3441,11 @@ cups_enum_dests( char filename[1024]; /* Local lpoptions file */ _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + char printer_list[1024]; /* List of desired printers */ + char *token = NULL; + char *rest = NULL; + char *saveptr = NULL; + DEBUG_printf(("cups_enum_dests(flags=%x, msec=%d, cancel=%p, type=%x, mask=%x, cb=%p, user_data=%p)", flags, msec, (void *)cancel, type, mask, (void *)cb, (void *)user_data)); @@ -3504,7 +3528,33 @@ cups_enum_dests( * Get the list of local printers and pass them to the callback function... */ - num_dests = _cupsGetDests(http, IPP_OP_CUPS_GET_PRINTERS, NULL, &dests, type, mask); + /* Get a list from the user to see which printers should be visible */ + rest = getenv("CUPS_PRINTER_LIST"); + if (!rest) rest = cups_get_printer_list(filename, printer_list, sizeof(printer_list)); + + if (rest && (strlen(rest) > 0)) + { + /* Make a copy of the list and tokenize it; then check each printter in the list + * whether it exists + */ + rest = strdup(rest); + num_dests = 0; + while ((token = strtok_r(rest, ", ", &saveptr))) + { + rest = NULL; + tmp_dests = NULL; + tmp_num_dests = _cupsGetDests(http, IPP_OP_CUPS_GET_PRINTERS, token, &tmp_dests, type, mask); + if (tmp_num_dests == 1) + { + cupsCopyDest(tmp_dests, num_dests++, &dests); + } + cupsFreeDests(tmp_num_dests, tmp_dests); + } + } + else + { + num_dests = _cupsGetDests(http, IPP_OP_CUPS_GET_PRINTERS, NULL, &dests, type, mask); + } if (data.def_name[0]) { @@ -4100,6 +4150,48 @@ cups_get_default(const char *filename, /* I - File to read */ } +/* + * 'cups_get_printer_list()' - Get the list of desired printers from an lpoptions file. + */ + +static char * /* O - Default destination or NULL */ +cups_get_printer_list(const char *filename, /* I - File to read */ + char *namebuf, /* I - Name buffer */ + size_t namesize) /* I - Size of name buffer */ +{ + cups_file_t *fp; /* lpoptions file */ + char line[8192], /* Line from file */ + *value, /* Value for line */ + *nameptr; /* Pointer into name */ + int linenum; /* Current line */ + + + *namebuf = '\0'; + + if ((fp = cupsFileOpen(filename, "r")) != NULL) + { + linenum = 0; + + while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + { + if (!_cups_strcasecmp(line, "printer-list") && value) + { + strlcpy(namebuf, value, namesize); + + if ((nameptr = strchr(namebuf, '\t')) != NULL) + *nameptr = ' '; + + break; + } + } + + cupsFileClose(fp); + } + + return (*namebuf ? namebuf : NULL); +} + + /* * 'cups_get_dests()' - Get destinations from a file. */