Example #1
0
int					/* O - 0 on success, non-zero on error */
export_dest(http_t     *http,		/* I - Connection to server */
            const char *dest)		/* I - Destination to export */
{
  int		status;			/* Status of export */
  char		ppdfile[1024],		/* PPD file for printer drivers */
		prompt[1024];		/* Password prompt */
  int		tries;			/* Number of tries */


 /*
  * Get the Windows PPD file for the printer...
  */

  if (!cupsAdminCreateWindowsPPD(http, dest, ppdfile, sizeof(ppdfile)))
  {
    _cupsLangPrintf(stderr,
                    _("cupsaddsmb: No PPD file for printer \"%s\" - %s"),
        	    dest, cupsLastErrorString());
    return (1);
  }

 /*
  * Try to export it...
  */

  for (status = 0, tries = 0; !status && tries < 3; tries ++)
  {
   /*
    * Get the password, as needed...
    */

    if (!SAMBAPassword)
    {
      snprintf(prompt, sizeof(prompt),
               _cupsLangString(cupsLangDefault(),
	                       _("Password for %s required to access %s via "
			         "SAMBA: ")),
	       SAMBAUser, SAMBAServer);

      if ((SAMBAPassword = cupsGetPassword(prompt)) == NULL)
	break;
    }

    status = cupsAdminExportSamba(dest, ppdfile, SAMBAServer,
                                  SAMBAUser, SAMBAPassword,
				  Verbosity ? stderr : NULL);

    if (!status && cupsLastError() == IPP_NOT_FOUND)
      break;
  }

  unlink(ppdfile);

  return (!status);
}
Example #2
0
int					/* O - Number of bytes written */
_cupsLangPrintFilter(
    FILE       *fp,			/* I - File to write to */
    const char *prefix,			/* I - Non-localized message prefix */
    const char *message,		/* I - Message string to use */
    ...)				/* I - Additional arguments as needed */
{
  ssize_t	bytes;			/* Number of bytes formatted */
  char		temp[2048],		/* Temporary format buffer */
		buffer[2048],		/* Message buffer */
		output[8192];		/* Output buffer */
  va_list 	ap;			/* Pointer to additional arguments */
  _cups_globals_t *cg;			/* Global data */


 /*
  * Range check...
  */

  if (!fp || !message)
    return (-1);

  cg = _cupsGlobals();

  if (!cg->lang_default)
    cg->lang_default = cupsLangDefault();

 /*
  * Format the string...
  */

  va_start(ap, message);
  snprintf(temp, sizeof(temp), "%s: %s\n", prefix,
	   _cupsLangString(cg->lang_default, message));
  vsnprintf(buffer, sizeof(buffer), temp, ap);
  va_end(ap);

 /*
  * Transcode to the destination charset...
  */

  bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output),
                            cg->lang_default->encoding);

 /*
  * Write the string and return the number of bytes written...
  */

  if (bytes > 0)
    return ((int)fwrite(output, 1, (size_t)bytes, fp));
  else
    return ((int)bytes);
}
Example #3
0
void
_cupsSetError(ipp_status_t status,	/* I - IPP status code */
              const char   *message,	/* I - status-message value */
	      int          localize)	/* I - Localize the message? */
{
  _cups_globals_t	*cg;		/* Global data */


  if (!message && errno)
  {
    message  = strerror(errno);
    localize = 0;
  }

  cg             = _cupsGlobals();
  cg->last_error = status;

  if (cg->last_status_message)
  {
    _cupsStrFree(cg->last_status_message);

    cg->last_status_message = NULL;
  }

  if (message)
  {
    if (localize)
    {
     /*
      * Get the message catalog...
      */

      if (!cg->lang_default)
	cg->lang_default = cupsLangDefault();

      cg->last_status_message = _cupsStrAlloc(_cupsLangString(cg->lang_default,
                                                              message));
    }
    else
      cg->last_status_message = _cupsStrAlloc(message);
  }

  DEBUG_printf(("4_cupsSetError: last_error=%s, last_status_message=\"%s\"",
                ippErrorString(cg->last_error), cg->last_status_message));
}
int					/* O - Number of bytes written */
_cupsLangPuts(FILE       *fp,		/* I - File to write to */
              const char *message)	/* I - Message string to use */
{
  int		bytes;			/* Number of bytes formatted */
  char		output[8192];		/* Message buffer */
  _cups_globals_t *cg;			/* Global data */


 /*
  * Range check...
  */

  if (!fp || !message)
    return (-1);

  cg = _cupsGlobals();

  if (!cg->lang_default)
    cg->lang_default = cupsLangDefault();

 /*
  * Transcode to the destination charset...
  */

  bytes = cupsUTF8ToCharset(output,
			    (cups_utf8_t *)_cupsLangString(cg->lang_default,
							   message),
			    sizeof(output) - 4, cg->lang_default->encoding);
  bytes += cupsUTF8ToCharset(output + bytes, (cups_utf8_t *)"\n",
                             sizeof(output) - bytes,
			     cg->lang_default->encoding);

 /*
  * Write the string and return the number of bytes written...
  */

  if (bytes > 0)
    return ((int)fwrite(output, 1, bytes, fp));
  else
    return (bytes);
}
Example #5
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments (6 or 7) */
     char *argv[])			/* I - Command-line arguments */
{
  const char	*device_uri;		/* Device URI */
  char		scheme[255],		/* Scheme in URI */
		hostname[1024],		/* Hostname */
		username[255],		/* Username info (not used) */
		resource[1024],		/* Resource info (not used) */
		*options,		/* Pointer to options */
		*name,			/* Name of option */
		*value,			/* Value of option */
		sep;			/* Option separator */
  int		print_fd;		/* Print file */
  int		copies;			/* Number of copies to print */
  time_t	start_time;		/* Time of first connect */
#ifdef __APPLE__
  time_t	current_time,		/* Current time */
		wait_time;		/* Time to wait before shutting down socket */
#endif /* __APPLE__ */
  int		contimeout;		/* Connection timeout */
  int		waiteof;		/* Wait for end-of-file? */
  int		port;			/* Port number */
  char		portname[255];		/* Port name */
  int		delay;			/* Delay for retries... */
  int		device_fd;		/* AppSocket */
  int		error;			/* Error code (if any) */
  http_addrlist_t *addrlist,		/* Address list */
		*addr;			/* Connected address */
  char		addrname[256];		/* Address name */
  int		snmp_fd,		/* SNMP socket */
		start_count,		/* Page count via SNMP at start */
		page_count,		/* Page count via SNMP */
		have_supplies;		/* Printer supports supply levels? */
  ssize_t	bytes = 0,		/* Initial bytes read */
		tbytes;			/* Total number of bytes written */
  char		buffer[1024];		/* Initial print buffer */
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
  struct sigaction action;		/* Actions for POSIX signals */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */


 /*
  * Make sure status messages are not buffered...
  */

  setbuf(stderr, NULL);

 /*
  * Ignore SIGPIPE signals...
  */

#ifdef HAVE_SIGSET
  sigset(SIGPIPE, SIG_IGN);
#elif defined(HAVE_SIGACTION)
  memset(&action, 0, sizeof(action));
  action.sa_handler = SIG_IGN;
  sigaction(SIGPIPE, &action, NULL);
#else
  signal(SIGPIPE, SIG_IGN);
#endif /* HAVE_SIGSET */

 /*
  * Check command-line...
  */

  if (argc == 1)
  {
    printf("network socket \"Unknown\" \"%s\"\n",
           _cupsLangString(cupsLangDefault(), _("AppSocket/HP JetDirect")));
    return (CUPS_BACKEND_OK);
  }
  else if (argc < 6 || argc > 7)
  {
    _cupsLangPrintf(stderr,
                    _("Usage: %s job-id user title copies options [file]"),
                    argv[0]);
    return (CUPS_BACKEND_FAILED);
  }

 /*
  * If we have 7 arguments, print the file named on the command-line.
  * Otherwise, send stdin instead...
  */

  if (argc == 6)
  {
    print_fd = 0;
    copies   = 1;
  }
  else
  {
   /*
    * Try to open the print file...
    */

    if ((print_fd = open(argv[6], O_RDONLY)) < 0)
    {
      _cupsLangPrintError("ERROR", _("Unable to open print file"));
      return (CUPS_BACKEND_FAILED);
    }

    copies = atoi(argv[4]);
  }

 /*
  * Extract the hostname and port number from the URI...
  */

  while ((device_uri = cupsBackendDeviceURI(argv)) == NULL)
  {
    _cupsLangPrintFilter(stderr, "INFO", _("Unable to locate printer."));
    sleep(10);

    if (getenv("CLASS") != NULL)
      return (CUPS_BACKEND_FAILED);
  }

  httpSeparateURI(HTTP_URI_CODING_ALL, device_uri, scheme, sizeof(scheme),
                  username, sizeof(username), hostname, sizeof(hostname), &port,
		  resource, sizeof(resource));

  if (port == 0)
    port = 9100;	/* Default to HP JetDirect/Tektronix PhaserShare */

 /*
  * Get options, if any...
  */

  waiteof    = 1;
  contimeout = 7 * 24 * 60 * 60;

  if ((options = strchr(resource, '?')) != NULL)
  {
   /*
    * Yup, terminate the device name string and move to the first
    * character of the options...
    */

    *options++ = '\0';

   /*
    * Parse options...
    */

    while (*options)
    {
     /*
      * Get the name...
      */

      name = options;

      while (*options && *options != '=' && *options != '+' && *options != '&')
        options ++;

      if ((sep = *options) != '\0')
        *options++ = '\0';

      if (sep == '=')
      {
       /*
        * Get the value...
	*/

        value = options;

	while (*options && *options != '+' && *options != '&')
	  options ++;

        if (*options)
	  *options++ = '\0';
      }
      else
        value = (char *)"";

     /*
      * Process the option...
      */

      if (!_cups_strcasecmp(name, "waiteof"))
      {
       /*
        * Set the wait-for-eof value...
	*/

        waiteof = !value[0] || !_cups_strcasecmp(value, "on") ||
		  !_cups_strcasecmp(value, "yes") || !_cups_strcasecmp(value, "true");
      }
      else if (!_cups_strcasecmp(name, "contimeout"))
      {
       /*
        * Set the connection timeout...
	*/

	if (atoi(value) > 0)
	  contimeout = atoi(value);
      }
    }
  }

 /*
  * Then try finding the remote host...
  */

  start_time = time(NULL);

  sprintf(portname, "%d", port);

  fputs("STATE: +connecting-to-device\n", stderr);
  fprintf(stderr, "DEBUG: Looking up \"%s\"...\n", hostname);

  while ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, portname)) == NULL)
  {
    _cupsLangPrintFilter(stderr, "INFO",
                         _("Unable to locate printer \"%s\"."), hostname);
    sleep(10);

    if (getenv("CLASS") != NULL)
    {
      fputs("STATE: -connecting-to-device\n", stderr);
      return (CUPS_BACKEND_STOP);
    }
  }

 /*
  * See if the printer supports SNMP...
  */

  if ((snmp_fd = _cupsSNMPOpen(addrlist->addr.addr.sa_family)) >= 0)
  {
    have_supplies = !backendSNMPSupplies(snmp_fd, &(addrlist->addr),
                                         &start_count, NULL);
  }
  else
    have_supplies = start_count = 0;

 /*
  * Wait for data from the filter...
  */

  if (print_fd == 0)
  {
    if (!backendWaitLoop(snmp_fd, &(addrlist->addr), 1, backendNetworkSideCB))
      return (CUPS_BACKEND_OK);
    else if ((bytes = read(0, buffer, sizeof(buffer))) <= 0)
      return (CUPS_BACKEND_OK);
  }

 /*
  * Connect to the printer...
  */

  fprintf(stderr, "DEBUG: Connecting to %s:%d\n", hostname, port);
  _cupsLangPrintFilter(stderr, "INFO", _("Connecting to printer."));

  for (delay = 5;;)
  {
    if ((addr = httpAddrConnect(addrlist, &device_fd)) == NULL)
    {
      error     = errno;
      device_fd = -1;

      if (getenv("CLASS") != NULL)
      {
       /*
        * If the CLASS environment variable is set, the job was submitted
	* to a class and not to a specific queue.  In this case, we want
	* to abort immediately so that the job can be requeued on the next
	* available printer in the class.
	*/

        _cupsLangPrintFilter(stderr, "INFO",
			     _("Unable to contact printer, queuing on next "
			       "printer in class."));

       /*
        * Sleep 5 seconds to keep the job from requeuing too rapidly...
	*/

	sleep(5);

        return (CUPS_BACKEND_FAILED);
      }

      fprintf(stderr, "DEBUG: Connection error: %s\n", strerror(error));

      if (error == ECONNREFUSED || error == EHOSTDOWN ||
          error == EHOSTUNREACH)
      {
        if (contimeout && (time(NULL) - start_time) > contimeout)
	{
	  _cupsLangPrintFilter(stderr, "ERROR",
	                       _("The printer is not responding."));
	  return (CUPS_BACKEND_FAILED);
	}

	switch (error)
	{
	  case EHOSTDOWN :
	      _cupsLangPrintFilter(stderr, "WARNING",
				   _("The printer may not exist or "
				     "is unavailable at this time."));
	      break;

	  case EHOSTUNREACH :
	      _cupsLangPrintFilter(stderr, "WARNING",
				   _("The printer is unreachable at this "
				     "time."));
	      break;

	  case ECONNREFUSED :
	  default :
	      _cupsLangPrintFilter(stderr, "WARNING",
	                           _("The printer is in use."));
	      break;
        }

	sleep(delay);

	if (delay < 30)
	  delay += 5;
      }
      else
      {
	_cupsLangPrintFilter(stderr, "ERROR",
	                     _("The printer is not responding."));
	sleep(30);
      }
    }
    else
      break;
  }

  fputs("STATE: -connecting-to-device\n", stderr);
  _cupsLangPrintFilter(stderr, "INFO", _("Connected to printer."));

  fprintf(stderr, "DEBUG: Connected to %s:%d...\n",
	  httpAddrString(&(addr->addr), addrname, sizeof(addrname)),
	  _httpAddrPort(&(addr->addr)));

 /*
  * Print everything...
  */

  tbytes = 0;

  if (bytes > 0)
    tbytes += write(device_fd, buffer, bytes);

  while (copies > 0 && tbytes >= 0)
  {
    copies --;

    if (print_fd != 0)
    {
      fputs("PAGE: 1 1\n", stderr);
      lseek(print_fd, 0, SEEK_SET);
    }

    tbytes = backendRunLoop(print_fd, device_fd, snmp_fd, &(addrlist->addr), 1,
                            0, backendNetworkSideCB);

    if (print_fd != 0 && tbytes >= 0)
      _cupsLangPrintFilter(stderr, "INFO", _("Print file sent."));
  }

#ifdef __APPLE__
 /*
  * Wait up to 5 seconds to get any pending back-channel data...
  */

  wait_time = time(NULL) + 5;
  while (wait_time >= time(&current_time))
    if (wait_bc(device_fd, wait_time - current_time) <= 0)
      break;
#endif /* __APPLE__ */

  if (waiteof)
  {
   /*
    * Shutdown the socket and wait for the other end to finish...
    */

    _cupsLangPrintFilter(stderr, "INFO", _("Waiting for printer to finish."));

    shutdown(device_fd, 1);

    while (wait_bc(device_fd, 90) > 0);
  }

 /*
  * Collect the final page count as needed...
  */

  if (have_supplies &&
      !backendSNMPSupplies(snmp_fd, &(addrlist->addr), &page_count, NULL) &&
      page_count > start_count)
    fprintf(stderr, "PAGE: total %d\n", page_count - start_count);

 /*
  * Close the socket connection...
  */

  close(device_fd);

  httpAddrFreeList(addrlist);

 /*
  * Close the input file and return...
  */

  if (print_fd != 0)
    close(print_fd);

  return (CUPS_BACKEND_OK);
}
Example #6
0
const char *				/* O - Value or NULL if not found */
ppdLocalizeIPPReason(
    ppd_file_t *ppd,			/* I - PPD file */
    const char *reason,			/* I - IPP reason keyword to look up */
    const char *scheme,			/* I - URI scheme or NULL for text */
    char       *buffer,			/* I - Value buffer */
    size_t     bufsize)			/* I - Size of value buffer */
{
  cups_lang_t	*lang;			/* Current language */
  ppd_attr_t	*locattr;		/* Localized attribute */
  char		ll_CC[6],		/* Language + country locale */
		*bufptr,		/* Pointer into buffer */
		*bufend,		/* Pointer to end of buffer */
		*valptr;		/* Pointer into value */
  int		ch;			/* Hex-encoded character */
  size_t	schemelen;		/* Length of scheme name */


 /*
  * Range check input...
  */

  if (buffer)
    *buffer = '\0';

  if (!ppd || !reason || (scheme && !*scheme) ||
      !buffer || bufsize < PPD_MAX_TEXT)
    return (NULL);

 /*
  * Get the default language...
  */

  lang = ppd_ll_CC(ll_CC, sizeof(ll_CC));

 /*
  * Find the localized attribute...
  */

  if ((locattr = _ppdLocalizedAttr(ppd, "cupsIPPReason", reason,
                                   ll_CC)) == NULL)
    locattr = ppdFindAttr(ppd, "cupsIPPReason", reason);

  if (!locattr)
  {
    if (lang && (!scheme || !strcmp(scheme, "text")))
    {
     /*
      * Try to localize a standard printer-state-reason keyword...
      */

      const char *message = NULL;	/* Localized message */

      if (!strncmp(reason, "media-needed", 12))
	message = _("Load paper.");
      else if (!strncmp(reason, "media-jam", 9))
	message = _("Paper jam.");
      else if (!strncmp(reason, "offline", 7) ||
		       !strncmp(reason, "shutdown", 8))
	message = _("The printer is not connected.");
      else if (!strncmp(reason, "toner-low", 9))
	message = _("The printer is low on toner.");
      else if (!strncmp(reason, "toner-empty", 11))
	message = _("The printer may be out of toner.");
      else if (!strncmp(reason, "cover-open", 10))
	message = _("The printer's cover is open.");
      else if (!strncmp(reason, "interlock-open", 14))
	message = _("The printer's interlock is open.");
      else if (!strncmp(reason, "door-open", 9))
	message = _("The printer's door is open.");
      else if (!strncmp(reason, "input-tray-missing", 18))
	message = _("Paper tray is missing.");
      else if (!strncmp(reason, "media-low", 9))
	message = _("Paper tray is almost empty.");
      else if (!strncmp(reason, "media-empty", 11))
	message = _("Paper tray is empty.");
      else if (!strncmp(reason, "output-tray-missing", 19))
	message = _("Output bin is missing.");
      else if (!strncmp(reason, "output-area-almost-full", 23))
	message = _("Output bin is almost full.");
      else if (!strncmp(reason, "output-area-full", 16))
	message = _("Output bin is full.");
      else if (!strncmp(reason, "marker-supply-low", 17))
	message = _("The printer is low on ink.");
      else if (!strncmp(reason, "marker-supply-empty", 19))
	message = _("The printer may be out of ink.");
      else if (!strncmp(reason, "marker-waste-almost-full", 24))
	message = _("The printer's waste bin is almost full.");
      else if (!strncmp(reason, "marker-waste-full", 17))
	message = _("The printer's waste bin is full.");
      else if (!strncmp(reason, "fuser-over-temp", 15))
	message = _("The fuser's temperature is high.");
      else if (!strncmp(reason, "fuser-under-temp", 16))
	message = _("The fuser's temperature is low.");
      else if (!strncmp(reason, "opc-near-eol", 12))
	message = _("The optical photoconductor will need to be replaced soon.");
      else if (!strncmp(reason, "opc-life-over", 13))
	message = _("The optical photoconductor needs to be replaced.");
      else if (!strncmp(reason, "developer-low", 13))
	message = _("The developer unit will need to be replaced soon.");
      else if (!strncmp(reason, "developer-empty", 15))
	message = _("The developer unit needs to be replaced.");

      if (message)
      {
        strlcpy(buffer, _cupsLangString(lang, message), bufsize);
	return (buffer);
      }
    }

    return (NULL);
  }

 /*
  * Now find the value we need...
  */

  bufend = buffer + bufsize - 1;

  if (!scheme || !strcmp(scheme, "text"))
  {
   /*
    * Copy a text value (either the translation text or text:... URIs from
    * the value...
    */

    strlcpy(buffer, locattr->text, bufsize);

    for (valptr = locattr->value, bufptr = buffer; *valptr && bufptr < bufend;)
    {
      if (!strncmp(valptr, "text:", 5))
      {
       /*
        * Decode text: URI and add to the buffer...
	*/

	valptr += 5;

        while (*valptr && !_cups_isspace(*valptr) && bufptr < bufend)
	{
	  if (*valptr == '%' && isxdigit(valptr[1] & 255) &&
	      isxdigit(valptr[2] & 255))
	  {
	   /*
	    * Pull a hex-encoded character from the URI...
	    */

            valptr ++;

	    if (isdigit(*valptr & 255))
	      ch = (*valptr - '0') << 4;
	    else
	      ch = (tolower(*valptr) - 'a' + 10) << 4;
	    valptr ++;

	    if (isdigit(*valptr & 255))
	      *bufptr++ = (char)(ch | (*valptr - '0'));
	    else
	      *bufptr++ = (char)(ch | (tolower(*valptr) - 'a' + 10));
	    valptr ++;
	  }
	  else if (*valptr == '+')
	  {
	    *bufptr++ = ' ';
	    valptr ++;
	  }
	  else
	    *bufptr++ = *valptr++;
        }
      }
      else
      {
       /*
        * Skip this URI...
	*/

        while (*valptr && !_cups_isspace(*valptr))
          valptr++;
      }

     /*
      * Skip whitespace...
      */

      while (_cups_isspace(*valptr))
	valptr ++;
    }

    if (bufptr > buffer)
      *bufptr = '\0';

    return (buffer);
  }
  else
  {
   /*
    * Copy a URI...
    */

    schemelen = strlen(scheme);
    if (scheme[schemelen - 1] == ':')	/* Force scheme to be just the name */
      schemelen --;

    for (valptr = locattr->value, bufptr = buffer; *valptr && bufptr < bufend;)
    {
      if ((!strncmp(valptr, scheme, schemelen) && valptr[schemelen] == ':') ||
          (*valptr == '/' && !strcmp(scheme, "file")))
      {
       /*
        * Copy URI...
	*/

        while (*valptr && !_cups_isspace(*valptr) && bufptr < bufend)
	  *bufptr++ = *valptr++;

	*bufptr = '\0';

	return (buffer);
      }
      else
      {
       /*
        * Skip this URI...
	*/

	while (*valptr && !_cups_isspace(*valptr))
	  valptr++;
      }

     /*
      * Skip whitespace...
      */

      while (_cups_isspace(*valptr))
	valptr ++;
    }

    return (NULL);
  }
}
Example #7
0
int					/* O - 0 on success, -1 on error */
_cupsSetNegotiateAuthString(
    http_t     *http,			/* I - Connection to server */
    const char *method,			/* I - Request method ("GET", "POST", "PUT") */
    const char *resource)		/* I - Resource path */
{
  OM_uint32	minor_status,		/* Minor status code */
		major_status;		/* Major status code */
  gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
					/* Output token */


  (void)method;
  (void)resource;

#  ifdef __APPLE__
 /*
  * If the weak-linked GSSAPI/Kerberos library is not present, don't try
  * to use it...
  */

  if (&gss_init_sec_context == NULL)
  {
    DEBUG_puts("1_cupsSetNegotiateAuthString: Weak-linked GSSAPI/Kerberos "
               "framework is not present");
    return (-1);
  }
#  endif /* __APPLE__ */

  if (http->gssname == GSS_C_NO_NAME)
  {
    http->gssname = cups_gss_getname(http, _cupsGSSServiceName());
  }

  if (http->gssctx != GSS_C_NO_CONTEXT)
  {
    gss_delete_sec_context(&minor_status, &http->gssctx, GSS_C_NO_BUFFER);
    http->gssctx = GSS_C_NO_CONTEXT;
  }

  major_status = gss_init_sec_context(&minor_status, GSS_C_NO_CREDENTIAL,
				      &http->gssctx,
				      http->gssname, http->gssmech,
				      GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG,
				      GSS_C_INDEFINITE,
				      GSS_C_NO_CHANNEL_BINDINGS,
				      GSS_C_NO_BUFFER, &http->gssmech,
				      &output_token, NULL, NULL);

#ifdef HAVE_GSS_ACQUIRE_CRED_EX_F
  if (major_status == GSS_S_NO_CRED)
  {
   /*
    * Ask the user for credentials...
    */

    char		prompt[1024],	/* Prompt for user */
			userbuf[256];	/* Kerberos username */
    const char		*username,	/* Username string */
			*password;	/* Password string */
    _cups_gss_acquire_t	data;		/* Callback data */
    gss_auth_identity_desc identity;	/* Kerberos user identity */
    _cups_globals_t	*cg = _cupsGlobals();
					/* Per-thread global data */

    if (!cg->lang_default)
      cg->lang_default = cupsLangDefault();

    snprintf(prompt, sizeof(prompt),
             _cupsLangString(cg->lang_default, _("Password for %s on %s? ")),
	     cupsUser(), http->gsshost);

    if ((password = cupsGetPassword2(prompt, http, method, resource)) == NULL)
      return (-1);

   /*
    * Try to acquire credentials...
    */

    username = cupsUser();
    if (!strchr(username, '@'))
    {
      snprintf(userbuf, sizeof(userbuf), "%s@%s", username, http->gsshost);
      username = userbuf;
    }

    identity.type           = GSS_AUTH_IDENTITY_TYPE_1;
    identity.flags          = 0;
    identity.username       = (char *)username;
    identity.realm          = (char *)"";
    identity.password       = (char *)password;
    identity.credentialsRef = NULL;

    data.sem   = dispatch_semaphore_create(0);
    data.major = 0;
    data.creds = NULL;

    if (data.sem)
    {
      major_status = gss_acquire_cred_ex_f(NULL, GSS_C_NO_NAME, 0,
				           GSS_C_INDEFINITE, GSS_KRB5_MECHANISM,
					   GSS_C_INITIATE, &identity, &data,
					   cups_gss_acquire);

      if (major_status == GSS_S_COMPLETE)
      {
	dispatch_semaphore_wait(data.sem, DISPATCH_TIME_FOREVER);
	major_status = data.major;
      }

      dispatch_release(data.sem);

      if (major_status == GSS_S_COMPLETE)
      {
        OM_uint32	release_minor;	/* Minor status from releasing creds */

	major_status = gss_init_sec_context(&minor_status, data.creds,
					    &http->gssctx,
					    http->gssname, http->gssmech,
					    GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG,
					    GSS_C_INDEFINITE,
					    GSS_C_NO_CHANNEL_BINDINGS,
					    GSS_C_NO_BUFFER, &http->gssmech,
					    &output_token, NULL, NULL);
        gss_release_cred(&release_minor, &data.creds);
      }
    }
  }
#endif /* HAVE_GSS_ACQUIRED_CRED_EX_F */

  if (GSS_ERROR(major_status))
  {
    cups_gss_printf(major_status, minor_status,
		    "_cupsSetNegotiateAuthString: Unable to initialize "
		    "security context");
    return (-1);
  }

#ifdef DEBUG
  else if (major_status == GSS_S_CONTINUE_NEEDED)
    cups_gss_printf(major_status, minor_status,
		    "_cupsSetNegotiateAuthString: Continuation needed!");
#endif /* DEBUG */

  if (output_token.length > 0 && output_token.length <= 65536)
  {
   /*
    * Allocate the authorization string since Windows KDCs can have
    * arbitrarily large credentials...
    */

    int authsize = 10 +			/* "Negotiate " */
		   (int)output_token.length * 4 / 3 + 1 + 1;
		   			/* Base64 + nul */

    httpSetAuthString(http, NULL, NULL);

    if ((http->authstring = malloc((size_t)authsize)) == NULL)
    {
      http->authstring = http->_authstring;
      authsize         = sizeof(http->_authstring);
    }

    strlcpy(http->authstring, "Negotiate ", (size_t)authsize);
    httpEncode64_2(http->authstring + 10, authsize - 10, output_token.value,
		   (int)output_token.length);

    gss_release_buffer(&minor_status, &output_token);
  }
  else
  {
    DEBUG_printf(("1_cupsSetNegotiateAuthString: Kerberos credentials too "
                  "large - %d bytes!", (int)output_token.length));
    gss_release_buffer(&minor_status, &output_token);

    return (-1);
  }

  return (0);
}
Example #8
0
int					/* O - 0 on success, -1 on error */
cupsDoAuthentication(
    http_t     *http,			/* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
    const char *method,			/* I - Request method ("GET", "POST", "PUT") */
    const char *resource)		/* I - Resource path */
{
  const char	*password,		/* Password string */
		*www_auth;		/* WWW-Authenticate header */
  char		prompt[1024],		/* Prompt for user */
		realm[HTTP_MAX_VALUE],	/* realm="xyz" string */
		nonce[HTTP_MAX_VALUE];	/* nonce="xyz" string */
  int		localauth;		/* Local authentication result */
  _cups_globals_t *cg;			/* Global data */


  DEBUG_printf(("cupsDoAuthentication(http=%p, method=\"%s\", resource=\"%s\")",
                http, method, resource));

  if (!http)
    http = _cupsConnect();

  if (!http || !method || !resource)
    return (-1);

  DEBUG_printf(("2cupsDoAuthentication: digest_tries=%d, userpass=\"%s\"",
                http->digest_tries, http->userpass));
  DEBUG_printf(("2cupsDoAuthentication: WWW-Authenticate=\"%s\"",
                httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE)));

 /*
  * Clear the current authentication string...
  */

  httpSetAuthString(http, NULL, NULL);

 /*
  * See if we can do local authentication...
  */

  if (http->digest_tries < 3)
  {
    if ((localauth = cups_local_auth(http)) == 0)
    {
      DEBUG_printf(("2cupsDoAuthentication: authstring=\"%s\"",
                    http->authstring));

      if (http->status == HTTP_STATUS_UNAUTHORIZED)
	http->digest_tries ++;

      return (0);
    }
    else if (localauth == -1)
    {
      http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;
      return (-1);			/* Error or canceled */
    }
  }

 /*
  * Nope, see if we should retry the current username:password...
  */

  www_auth = http->fields[HTTP_FIELD_WWW_AUTHENTICATE];

  if ((http->digest_tries > 1 || !http->userpass[0]) &&
      (!_cups_strncasecmp(www_auth, "Basic", 5) ||
       !_cups_strncasecmp(www_auth, "Digest", 6)))
  {
   /*
    * Nope - get a new password from the user...
    */

    char default_username[HTTP_MAX_VALUE];
					/* Default username */

    cg = _cupsGlobals();

    if (!cg->lang_default)
      cg->lang_default = cupsLangDefault();

    if (httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "username",
                        default_username))
      cupsSetUser(default_username);

    snprintf(prompt, sizeof(prompt),
             _cupsLangString(cg->lang_default, _("Password for %s on %s? ")),
	     cupsUser(),
	     http->hostname[0] == '/' ? "localhost" : http->hostname);

    http->digest_tries  = _cups_strncasecmp(www_auth, "Digest", 6) != 0;
    http->userpass[0]   = '\0';

    if ((password = cupsGetPassword2(prompt, http, method, resource)) == NULL)
    {
      http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;
      return (-1);
    }

    snprintf(http->userpass, sizeof(http->userpass), "%s:%s", cupsUser(),
             password);
  }
  else if (http->status == HTTP_STATUS_UNAUTHORIZED)
    http->digest_tries ++;

  if (http->status == HTTP_STATUS_UNAUTHORIZED && http->digest_tries >= 3)
  {
    DEBUG_printf(("1cupsDoAuthentication: Too many authentication tries (%d)",
		  http->digest_tries));

    http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;
    return (-1);
  }

 /*
  * Got a password; encode it for the server...
  */

#ifdef HAVE_GSSAPI
  if (!_cups_strncasecmp(www_auth, "Negotiate", 9))
  {
   /*
    * Kerberos authentication...
    */

    if (_cupsSetNegotiateAuthString(http, method, resource))
    {
      http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;
      return (-1);
    }
  }
  else
#endif /* HAVE_GSSAPI */
  if (!_cups_strncasecmp(www_auth, "Basic", 5))
  {
   /*
    * Basic authentication...
    */

    char	encode[256];		/* Base64 buffer */


    httpEncode64_2(encode, sizeof(encode), http->userpass,
                   (int)strlen(http->userpass));
    httpSetAuthString(http, "Basic", encode);
  }
  else if (!_cups_strncasecmp(www_auth, "Digest", 6))
  {
   /*
    * Digest authentication...
    */

    char	encode[33],		/* MD5 buffer */
		digest[1024];		/* Digest auth data */

    httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "realm", realm);
    httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "nonce", nonce);

    httpMD5(cupsUser(), realm, strchr(http->userpass, ':') + 1, encode);
    httpMD5Final(nonce, method, resource, encode);
    snprintf(digest, sizeof(digest),
	     "username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", "
	     "response=\"%s\"", cupsUser(), realm, nonce, resource, encode);
    httpSetAuthString(http, "Digest", digest);
  }
  else
  {
    DEBUG_printf(("1cupsDoAuthentication: Unknown auth type: \"%s\"",
                  www_auth));
    http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;
    return (-1);
  }

  DEBUG_printf(("1cupsDoAuthentication: authstring=\"%s\"", http->authstring));

  return (0);
}
Example #9
0
char *					/* O - Subject string or @code NULL@ */
cupsNotifySubject(cups_lang_t *lang,	/* I - Language data */
                  ipp_t       *event)	/* I - Event data */
{
  char			buffer[1024];	/* Subject buffer */
  const char		*prefix,	/* Prefix on subject */
			*state;		/* Printer/job state string */
  ipp_attribute_t	*job_id,	/* notify-job-id */
			*job_name,	/* job-name */
			*job_state,	/* job-state */
			*printer_name,	/* printer-name */
			*printer_state,	/* printer-state */
			*printer_uri,	/* notify-printer-uri */
			*subscribed;	/* notify-subscribed-event */


 /*
  * Range check input...
  */

  if (!event || !lang)
    return (NULL);

 /*
  * Get the required attributes...
  */

  job_id        = ippFindAttribute(event, "notify-job-id", IPP_TAG_INTEGER);
  job_name      = ippFindAttribute(event, "job-name", IPP_TAG_NAME);
  job_state     = ippFindAttribute(event, "job-state", IPP_TAG_ENUM);
  printer_name  = ippFindAttribute(event, "printer-name", IPP_TAG_NAME);
  printer_state = ippFindAttribute(event, "printer-state", IPP_TAG_ENUM);
  printer_uri   = ippFindAttribute(event, "notify-printer-uri", IPP_TAG_URI);
  subscribed    = ippFindAttribute(event, "notify-subscribed-event",
                                   IPP_TAG_KEYWORD);


  if (job_id && printer_name && printer_uri && job_state)
  {
   /*
    * Job event...
    */

    prefix = _cupsLangString(lang, _("Print Job:"));

    switch (job_state->values[0].integer)
    {
      case IPP_JOB_PENDING :
          state = _cupsLangString(lang, _("pending"));
	  break;
      case IPP_JOB_HELD :
          state = _cupsLangString(lang, _("held"));
	  break;
      case IPP_JOB_PROCESSING :
          state = _cupsLangString(lang, _("processing"));
	  break;
      case IPP_JOB_STOPPED :
          state = _cupsLangString(lang, _("stopped"));
	  break;
      case IPP_JOB_CANCELED :
          state = _cupsLangString(lang, _("canceled"));
	  break;
      case IPP_JOB_ABORTED :
          state = _cupsLangString(lang, _("aborted"));
	  break;
      case IPP_JOB_COMPLETED :
          state = _cupsLangString(lang, _("completed"));
	  break;
      default :
          state = _cupsLangString(lang, _("unknown"));
	  break;
    }

    snprintf(buffer, sizeof(buffer), "%s %s-%d (%s) %s",
             prefix,
	     printer_name->values[0].string.text,
	     job_id->values[0].integer,
	     job_name ? job_name->values[0].string.text :
	         _cupsLangString(lang, _("untitled")),
	     state);
  }
  else if (printer_uri && printer_name && printer_state)
  {
   /*
    * Printer event...
    */

    prefix = _cupsLangString(lang, _("Printer:"));

    switch (printer_state->values[0].integer)
    {
      case IPP_PRINTER_IDLE :
          state = _cupsLangString(lang, _("idle"));
	  break;
      case IPP_PRINTER_PROCESSING :
          state = _cupsLangString(lang, _("processing"));
	  break;
      case IPP_PRINTER_STOPPED :
          state = _cupsLangString(lang, _("stopped"));
	  break;
      default :
          state = _cupsLangString(lang, _("unknown"));
	  break;
    }

    snprintf(buffer, sizeof(buffer), "%s %s %s",
             prefix,
	     printer_name->values[0].string.text,
	     state);
  }
  else if (subscribed)
    strlcpy(buffer, subscribed->values[0].string.text, sizeof(buffer));
  else
    return (NULL);

 /*
  * Duplicate and return the subject string...
  */

  return (strdup(buffer));
}
Example #10
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments (6 or 7) */
     char *argv[])			/* I - Command-line arguments */
{
  const char	*device_uri;		/* Device URI */
  char		scheme[255],		/* Scheme in URI */
		hostname[1024],		/* Hostname */
		username[255],		/* Username info */
		resource[1024],		/* Resource info (printer name) */
		*options,		/* Pointer to options */
		*name,			/* Name of option */
		*value,			/* Value of option */
		sep,			/* Separator character */
		*filename,		/* File to print */
		title[256];		/* Title string */
  int		port;			/* Port number */
  char		portname[256];		/* Port name (string) */
  http_addrlist_t *addrlist;		/* List of addresses for printer */
  int		snmp_enabled = 1;	/* Is SNMP enabled? */
  int		snmp_fd;		/* SNMP socket */
  int		fd;			/* Print file */
  int		status;			/* Status of LPD job */
  int		mode;			/* Print mode */
  int		banner;			/* Print banner page? */
  int		format;			/* Print format */
  int		order;			/* Order of control/data files */
  int		reserve;		/* Reserve priviledged port? */
  int		sanitize_title;		/* Sanitize title string? */
  int		manual_copies,		/* Do manual copies? */
		timeout,		/* Timeout */
		contimeout,		/* Connection timeout */
		copies;			/* Number of copies */
  ssize_t	bytes = 0;		/* Initial bytes read */
  char		buffer[16384];		/* Initial print buffer */
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
  struct sigaction action;		/* Actions for POSIX signals */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
  int		num_jobopts;		/* Number of job options */
  cups_option_t	*jobopts = NULL;	/* Job options */


 /*
  * Make sure status messages are not buffered...
  */

  setbuf(stderr, NULL);

 /*
  * Ignore SIGPIPE and catch SIGTERM signals...
  */

#ifdef HAVE_SIGSET
  sigset(SIGPIPE, SIG_IGN);
  sigset(SIGTERM, sigterm_handler);
#elif defined(HAVE_SIGACTION)
  memset(&action, 0, sizeof(action));
  action.sa_handler = SIG_IGN;
  sigaction(SIGPIPE, &action, NULL);

  sigemptyset(&action.sa_mask);
  sigaddset(&action.sa_mask, SIGTERM);
  action.sa_handler = sigterm_handler;
  sigaction(SIGTERM, &action, NULL);
#else
  signal(SIGPIPE, SIG_IGN);
  signal(SIGTERM, sigterm_handler);
#endif /* HAVE_SIGSET */

 /*
  * Check command-line...
  */

  if (argc == 1)
  {
    printf("network lpd \"Unknown\" \"%s\"\n",
           _cupsLangString(cupsLangDefault(), _("LPD/LPR Host or Printer")));
    return (CUPS_BACKEND_OK);
  }
  else if (argc < 6 || argc > 7)
  {
    _cupsLangPrintf(stderr,
                    _("Usage: %s job-id user title copies options [file]"),
                    argv[0]);
    return (CUPS_BACKEND_FAILED);
  }

  num_jobopts = cupsParseOptions(argv[5], 0, &jobopts);

 /*
  * Extract the hostname and printer name from the URI...
  */

  while ((device_uri = cupsBackendDeviceURI(argv)) == NULL)
  {
    _cupsLangPrintFilter(stderr, "INFO", _("Unable to locate printer."));
    sleep(10);

    if (getenv("CLASS") != NULL)
      return (CUPS_BACKEND_FAILED);
  }

  httpSeparateURI(HTTP_URI_CODING_ALL, device_uri, scheme, sizeof(scheme),
                  username, sizeof(username), hostname, sizeof(hostname), &port,
		  resource, sizeof(resource));

  if (!port)
    port = 515;				/* Default to port 515 */

  if (!username[0])
  {
   /*
    * If no username is in the device URI, then use the print job user...
    */

    strlcpy(username, argv[2], sizeof(username));
  }

 /*
  * See if there are any options...
  */

  mode          = MODE_STANDARD;
  banner        = 0;
  format        = 'l';
  order         = ORDER_CONTROL_DATA;
  reserve       = RESERVE_ANY;
  manual_copies = 1;
  timeout       = 300;
  contimeout    = 7 * 24 * 60 * 60;

#ifdef __APPLE__
 /*
  * We want to pass UTF-8 characters by default, not re-map them (3071945)
  */

  sanitize_title = 0;
#else
 /*
  * Otherwise we want to re-map UTF-8 to "safe" characters by default...
  */

  sanitize_title = 1;
#endif /* __APPLE__ */

  if ((options = strchr(resource, '?')) != NULL)
  {
   /*
    * Yup, terminate the device name string and move to the first
    * character of the options...
    */

    *options++ = '\0';

   /*
    * Parse options...
    */

    while (*options)
    {
     /*
      * Get the name...
      */

      name = options;

      while (*options && *options != '=' && *options != '+' && *options != '&')
        options ++;

      if ((sep = *options) != '\0')
        *options++ = '\0';

      if (sep == '=')
      {
       /*
        * Get the value...
	*/

        value = options;

	while (*options && *options != '+' && *options != '&')
	  options ++;

        if (*options)
	  *options++ = '\0';
      }
      else
        value = (char *)"";

     /*
      * Process the option...
      */

      if (!_cups_strcasecmp(name, "banner"))
      {
       /*
        * Set the banner...
	*/

        banner = !value[0] || !_cups_strcasecmp(value, "on") ||
		 !_cups_strcasecmp(value, "yes") || !_cups_strcasecmp(value, "true");
      }
      else if (!_cups_strcasecmp(name, "format") && value[0])
      {
       /*
        * Set output format...
	*/

        if (strchr("cdfglnoprtv", value[0]))
	  format = value[0];
	else
	  _cupsLangPrintFilter(stderr, "ERROR",
	                       _("Unknown format character: \"%c\"."),
			       value[0]);
      }
      else if (!_cups_strcasecmp(name, "mode") && value[0])
      {
       /*
        * Set control/data order...
	*/

        if (!_cups_strcasecmp(value, "standard"))
	  mode = MODE_STANDARD;
	else if (!_cups_strcasecmp(value, "stream"))
	  mode = MODE_STREAM;
	else
	  _cupsLangPrintFilter(stderr, "ERROR",
	                       _("Unknown print mode: \"%s\"."), value);
      }
      else if (!_cups_strcasecmp(name, "order") && value[0])
      {
       /*
        * Set control/data order...
	*/

        if (!_cups_strcasecmp(value, "control,data"))
	  order = ORDER_CONTROL_DATA;
	else if (!_cups_strcasecmp(value, "data,control"))
	  order = ORDER_DATA_CONTROL;
	else
	  _cupsLangPrintFilter(stderr, "ERROR",
	                       _("Unknown file order: \"%s\"."), value);
      }
      else if (!_cups_strcasecmp(name, "reserve"))
      {
       /*
        * Set port reservation mode...
	*/

        if (!value[0] || !_cups_strcasecmp(value, "on") ||
	    !_cups_strcasecmp(value, "yes") ||
	    !_cups_strcasecmp(value, "true") ||
	    !_cups_strcasecmp(value, "rfc1179"))
	  reserve = RESERVE_RFC1179;
	else if (!_cups_strcasecmp(value, "any"))
	  reserve = RESERVE_ANY;
	else
	  reserve = RESERVE_NONE;
      }
      else if (!_cups_strcasecmp(name, "manual_copies"))
      {
       /*
        * Set manual copies...
	*/

        manual_copies = !value[0] || !_cups_strcasecmp(value, "on") ||
	 		!_cups_strcasecmp(value, "yes") ||
	 		!_cups_strcasecmp(value, "true");
      }
      else if (!_cups_strcasecmp(name, "sanitize_title"))
      {
       /*
        * Set sanitize title...
	*/

        sanitize_title = !value[0] || !_cups_strcasecmp(value, "on") ||
	 		 !_cups_strcasecmp(value, "yes") ||
	 		 !_cups_strcasecmp(value, "true");
      }
      else if (!_cups_strcasecmp(name, "snmp"))
      {
        /*
         * Enable/disable SNMP stuff...
         */

         snmp_enabled = !value[0] || !_cups_strcasecmp(value, "on") ||
                        _cups_strcasecmp(value, "yes") ||
                        _cups_strcasecmp(value, "true");
      }
      else if (!_cups_strcasecmp(name, "timeout"))
      {
       /*
        * Set the timeout...
	*/

	if (atoi(value) > 0)
	  timeout = atoi(value);
      }
      else if (!_cups_strcasecmp(name, "contimeout"))
      {
       /*
        * Set the connection timeout...
	*/

	if (atoi(value) > 0)
	  contimeout = atoi(value);
      }
    }
  }

  if (mode == MODE_STREAM)
    order = ORDER_CONTROL_DATA;

 /*
  * Find the printer...
  */

  snprintf(portname, sizeof(portname), "%d", port);

  fputs("STATE: +connecting-to-device\n", stderr);
  fprintf(stderr, "DEBUG: Looking up \"%s\"...\n", hostname);

  while ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, portname)) == NULL)
  {
    _cupsLangPrintFilter(stderr, "INFO",
			 _("Unable to locate printer \"%s\"."), hostname);
    sleep(10);

    if (getenv("CLASS") != NULL)
    {
      fputs("STATE: -connecting-to-device\n", stderr);
      exit(CUPS_BACKEND_FAILED);
    }
  }

  if (snmp_enabled)
    snmp_fd = _cupsSNMPOpen(addrlist->addr.addr.sa_family);
  else
    snmp_fd = -1;

 /*
  * Wait for data from the filter...
  */

  if (argc == 6)
  {
    if (!backendWaitLoop(snmp_fd, &(addrlist->addr), 0, backendNetworkSideCB))
      return (CUPS_BACKEND_OK);
    else if (mode == MODE_STANDARD &&
             (bytes = read(0, buffer, sizeof(buffer))) <= 0)
      return (CUPS_BACKEND_OK);
  }

 /*
  * If we have 7 arguments, print the file named on the command-line.
  * Otherwise, copy stdin to a temporary file and print the temporary
  * file.
  */

  if (argc == 6 && mode == MODE_STANDARD)
  {
   /*
    * Copy stdin to a temporary file...
    */

    if ((fd = cupsTempFd(tmpfilename, sizeof(tmpfilename))) < 0)
    {
      perror("DEBUG: Unable to create temporary file");
      return (CUPS_BACKEND_FAILED);
    }

    _cupsLangPrintFilter(stderr, "INFO", _("Copying print data."));

    if (bytes > 0)
      write(fd, buffer, bytes);

    backendRunLoop(-1, fd, snmp_fd, &(addrlist->addr), 0, 0,
		   backendNetworkSideCB);
  }
  else if (argc == 6)
  {
   /*
    * Stream from stdin...
    */

    filename = NULL;
    fd       = 0;
  }
  else
  {
    filename = argv[6];
    fd       = open(filename, O_RDONLY);

    if (fd == -1)
    {
      _cupsLangPrintError("ERROR", _("Unable to open print file"));
      return (CUPS_BACKEND_FAILED);
    }
  }

 /*
  * Sanitize the document title...
  */

  strlcpy(title, argv[3], sizeof(title));

  if (sanitize_title)
  {
   /*
    * Sanitize the title string so that we don't cause problems on
    * the remote end...
    */

    char *ptr;

    for (ptr = title; *ptr; ptr ++)
      if (!isalnum(*ptr & 255) && !isspace(*ptr & 255))
	*ptr = '_';
  }

 /*
  * Queue the job...
  */

  if (argc > 6)
  {
    if (manual_copies)
    {
      manual_copies = atoi(argv[4]);
      copies        = 1;
    }
    else
    {
      manual_copies = 1;
      copies        = atoi(argv[4]);
    }

    status = lpd_queue(hostname, addrlist, resource + 1, fd, snmp_fd, mode,
                       username, title, copies, banner, format, order, reserve,
		       manual_copies, timeout, contimeout,
		       cupsGetOption("job-originating-host-name", num_jobopts,
		                     jobopts));

    if (!status)
      fprintf(stderr, "PAGE: 1 %d\n", atoi(argv[4]));
  }
  else
    status = lpd_queue(hostname, addrlist, resource + 1, fd, snmp_fd, mode,
                       username, title, 1, banner, format, order, reserve, 1,
		       timeout, contimeout,
		       cupsGetOption("job-originating-host-name", num_jobopts,
		                     jobopts));

 /*
  * Remove the temporary file if necessary...
  */

  if (tmpfilename[0])
    unlink(tmpfilename);

  if (fd)
    close(fd);

  if (snmp_fd >= 0)
    _cupsSNMPClose(snmp_fd);

 /*
  * Return the queue status...
  */

  return (status);
}
Example #11
0
void
_cupsLangPrintError(const char *prefix,	/* I - Non-localized message prefix */
                    const char *message)/* I - Message */
{
  ssize_t	bytes;			/* Number of bytes formatted */
  int		last_errno;		/* Last error */
  char		buffer[2048],		/* Message buffer */
		*bufptr,		/* Pointer into buffer */
		output[8192];		/* Output buffer */
  _cups_globals_t *cg;			/* Global data */


 /*
  * Range check...
  */

  if (!message)
    return;

 /*
  * Save the errno value...
  */

  last_errno = errno;

 /*
  * Get the message catalog...
  */

  cg = _cupsGlobals();

  if (!cg->lang_default)
    cg->lang_default = cupsLangDefault();

 /*
  * Format the message...
  */

  if (prefix)
  {
    snprintf(buffer, sizeof(buffer), "%s:", prefix);
    bufptr = buffer + strlen(buffer);
  }
  else
    bufptr = buffer;

  snprintf(bufptr, sizeof(buffer) - (size_t)(bufptr - buffer),
	   /* TRANSLATORS: Message is "subject: error" */
	   _cupsLangString(cg->lang_default, _("%s: %s")),
	   _cupsLangString(cg->lang_default, message), strerror(last_errno));
  strlcat(buffer, "\n", sizeof(buffer));

 /*
  * Convert and write to stderr...
  */

  bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output),
                            cg->lang_default->encoding);

  if (bytes > 0)
    fwrite(output, 1, (size_t)bytes, stderr);
}
Example #12
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments */
     char *argv[])			/* I - Command-line arguments */
{
  int			i;		/* Looping var */
  int			errors = 0;	/* Number of errors */
  cups_lang_t		*language;	/* Message catalog */
  cups_lang_t		*language2;	/* Message catalog */
  struct lconv		*loc;		/* Locale data */
  char			buffer[1024];	/* String buffer */
  double		number;		/* Number */
  static const char * const tests[] =	/* Test strings */
  {
    "1",
    "-1",
    "3",
    "5.125"
  };


  _cupsSetLocale(argv);

  if (argc == 1)
  {
    language  = cupsLangDefault();
    language2 = cupsLangDefault();
  }
  else
  {
    language  = cupsLangGet(argv[1]);
    language2 = cupsLangGet(argv[1]);
  }

  if (language != language2)
  {
    errors ++;

    puts("**** ERROR: Language cache did not work! ****");
    puts("First result from cupsLangGet:");
  }

  printf("Language = \"%s\"\n", language->language);
  printf("Encoding = \"%s\"\n", _cupsEncodingName(language->encoding));
  printf("No       = \"%s\"\n", _cupsLangString(language, "No"));
  printf("Yes      = \"%s\"\n", _cupsLangString(language, "Yes"));

  if (language != language2)
  {
    puts("Second result from cupsLangGet:");

    printf("Language = \"%s\"\n", language2->language);
    printf("Encoding = \"%s\"\n", _cupsEncodingName(language2->encoding));
    printf("No       = \"%s\"\n", _cupsLangString(language2, "No"));
    printf("Yes      = \"%s\"\n", _cupsLangString(language2, "Yes"));
  }

  loc = localeconv();

  for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i ++)
  {
    number = _cupsStrScand(tests[i], NULL, loc);

    printf("_cupsStrScand(\"%s\") number=%f\n", tests[i], number);

    _cupsStrFormatd(buffer, buffer + sizeof(buffer), number, loc);

    printf("_cupsStrFormatd(%f) buffer=\"%s\"\n", number, buffer);

    if (strcmp(buffer, tests[i]))
    {
      errors ++;
      puts("**** ERROR: Bad formatted number! ****");
    }
  }

  return (errors > 0);
}
Example #13
0
int					/* O - 1 on success, 0 on failure */
cupsAdminGetServerSettings(
    http_t        *http,		/* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
    int           *num_settings,	/* O - Number of settings */
    cups_option_t **settings)		/* O - Settings */
{
  int		i;			/* Looping var */
  cups_file_t	*cupsd;			/* cupsd.conf file */
  char		cupsdconf[1024];	/* cupsd.conf filename */
  int		remote;			/* Remote cupsd.conf file? */
  http_status_t	status;			/* Status of getting cupsd.conf */
  char		line[1024],		/* Line from cupsd.conf file */
		*value;			/* Value on line */
  cups_option_t	*setting;		/* Current setting */
  _cups_globals_t *cg = _cupsGlobals();	/* Global data */


 /*
  * Range check input...
  */

  if (!http)
  {
   /*
    * See if we are connected to the same server...
    */

    if (cg->http)
    {
     /*
      * Compare the connection hostname, port, and encryption settings to
      * the cached defaults; these were initialized the first time we
      * connected...
      */

      if (strcmp(cg->http->hostname, cg->server) ||
          cg->ipp_port != httpAddrPort(cg->http->hostaddr) ||
	  (cg->http->encryption != cg->encryption &&
	   cg->http->encryption == HTTP_ENCRYPTION_NEVER))
      {
       /*
	* Need to close the current connection because something has changed...
	*/

	httpClose(cg->http);
	cg->http = NULL;
      }
    }

   /*
    * (Re)connect as needed...
    */

    if (!cg->http)
    {
      if ((cg->http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC,
                                   cupsEncryption(), 1, 0, NULL)) == NULL)
      {
	if (errno)
	  _cupsSetError(IPP_STATUS_ERROR_SERVICE_UNAVAILABLE, NULL, 0);
	else
	  _cupsSetError(IPP_STATUS_ERROR_SERVICE_UNAVAILABLE,
			_("Unable to connect to host."), 1);

	if (num_settings)
	  *num_settings = 0;

	if (settings)
	  *settings = NULL;

	return (0);
      }
    }

    http = cg->http;
  }

  if (!http || !num_settings || !settings)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);

    if (num_settings)
      *num_settings = 0;

    if (settings)
      *settings = NULL;

    return (0);
  }

  *num_settings = 0;
  *settings     = NULL;

 /*
  * Get the cupsd.conf file...
  */

  if ((status = get_cupsd_conf(http, cg, cg->cupsd_update, cupsdconf,
                               sizeof(cupsdconf), &remote)) == HTTP_STATUS_OK)
  {
    if ((cupsd = cupsFileOpen(cupsdconf, "r")) == NULL)
    {
      char	message[1024];		/* Message string */


      snprintf(message, sizeof(message),
               _cupsLangString(cupsLangDefault(), _("Open of %s failed: %s")),
               cupsdconf, strerror(errno));
      _cupsSetError(IPP_STATUS_ERROR_INTERNAL, message, 0);
    }
  }
  else
    cupsd = NULL;

  if (cupsd)
  {
   /*
    * Read the file, keeping track of what settings are enabled...
    */

    int		remote_access = 0,	/* Remote access allowed? */
		remote_admin = 0,	/* Remote administration allowed? */
		remote_any = 0,		/* Remote access from anywhere allowed? */
		browsing = 1,		/* Browsing enabled? */
		cancel_policy = 1,	/* Cancel-job policy set? */
		debug_logging = 0;	/* LogLevel debug set? */
    int		linenum = 0,		/* Line number in file */
		in_location = 0,	/* In a location section? */
		in_policy = 0,		/* In a policy section? */
		in_cancel_job = 0,	/* In a cancel-job section? */
		in_admin_location = 0;	/* In the /admin location? */


    invalidate_cupsd_cache(cg);

    cg->cupsd_update = time(NULL);
    httpGetHostname(http, cg->cupsd_hostname, sizeof(cg->cupsd_hostname));

    while (cupsFileGetConf(cupsd, line, sizeof(line), &value, &linenum))
    {
      if (!value && strncmp(line, "</", 2))
        value = line + strlen(line);

      if ((!_cups_strcasecmp(line, "Port") || !_cups_strcasecmp(line, "Listen")) && value)
      {
	char	*port;			/* Pointer to port number, if any */


	if ((port = strrchr(value, ':')) != NULL)
	  *port = '\0';
	else if (isdigit(*value & 255))
	{
	 /*
	  * Listen on a port number implies remote access...
	  */

	  remote_access = 1;
	  continue;
	}

	if (_cups_strcasecmp(value, "localhost") && strcmp(value, "127.0.0.1")
#ifdef AF_LOCAL
            && *value != '/'
#endif /* AF_LOCAL */
#ifdef AF_INET6
            && strcmp(value, "[::1]")
#endif /* AF_INET6 */
	    )
	  remote_access = 1;
      }
      else if (!_cups_strcasecmp(line, "Browsing"))
      {
	browsing = !_cups_strcasecmp(value, "yes") ||
	           !_cups_strcasecmp(value, "on") ||
	           !_cups_strcasecmp(value, "true");
      }
      else if (!_cups_strcasecmp(line, "LogLevel"))
      {
	debug_logging = !_cups_strncasecmp(value, "debug", 5);
      }
      else if (!_cups_strcasecmp(line, "<Policy") &&
               !_cups_strcasecmp(value, "default"))
      {
	in_policy = 1;
      }
      else if (!_cups_strcasecmp(line, "</Policy>"))
      {
	in_policy = 0;
      }
      else if (!_cups_strcasecmp(line, "<Limit") && in_policy && value)
      {
       /*
	* See if the policy limit is for the Cancel-Job operation...
	*/

	char	*valptr;		/* Pointer into value */


	while (*value)
	{
	  for (valptr = value; *valptr && !_cups_isspace(*valptr); valptr ++);

	  if (*valptr)
	    *valptr++ = '\0';

          if (!_cups_strcasecmp(value, "cancel-job") ||
              !_cups_strcasecmp(value, "all"))
	  {
	    in_cancel_job = 1;
	    break;
	  }

          for (value = valptr; _cups_isspace(*value); value ++);
	}
      }
      else if (!_cups_strcasecmp(line, "</Limit>"))
      {
	in_cancel_job = 0;
      }
      else if (!_cups_strcasecmp(line, "Require") && in_cancel_job)
      {
	cancel_policy = 0;
      }
      else if (!_cups_strcasecmp(line, "<Location") && value)
      {
        in_admin_location = !_cups_strcasecmp(value, "/admin");
	in_location       = 1;
      }
      else if (!_cups_strcasecmp(line, "</Location>"))
      {
	in_admin_location = 0;
	in_location       = 0;
      }
      else if (!_cups_strcasecmp(line, "Allow") && value &&
               _cups_strcasecmp(value, "localhost") &&
               _cups_strcasecmp(value, "127.0.0.1")
#ifdef AF_LOCAL
	       && *value != '/'
#endif /* AF_LOCAL */
#ifdef AF_INET6
	       && strcmp(value, "::1")
#endif /* AF_INET6 */
	       )
      {
        if (in_admin_location)
	  remote_admin = 1;
        else if (!_cups_strcasecmp(value, "all"))
	  remote_any = 1;
      }
      else if (line[0] != '<' && !in_location && !in_policy &&
	       _cups_strcasecmp(line, "Allow") &&
               _cups_strcasecmp(line, "AuthType") &&
	       _cups_strcasecmp(line, "Deny") &&
	       _cups_strcasecmp(line, "Order") &&
	       _cups_strcasecmp(line, "Require") &&
	       _cups_strcasecmp(line, "Satisfy"))
        cg->cupsd_num_settings = cupsAddOption(line, value,
	                                       cg->cupsd_num_settings,
					       &(cg->cupsd_settings));
    }

    cupsFileClose(cupsd);

    cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING,
                                           debug_logging ? "1" : "0",
					   cg->cupsd_num_settings,
					   &(cg->cupsd_settings));

    cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN,
                                           (remote_access && remote_admin) ?
					       "1" : "0",
					   cg->cupsd_num_settings,
					   &(cg->cupsd_settings));

    cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY,
                                           remote_any ? "1" : "0",
					   cg->cupsd_num_settings,
					   &(cg->cupsd_settings));

    cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS,
                                           (remote_access && browsing) ? "1" :
                                                                         "0",
					   cg->cupsd_num_settings,
					   &(cg->cupsd_settings));

    cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY,
                                           cancel_policy ? "1" : "0",
					   cg->cupsd_num_settings,
					   &(cg->cupsd_settings));
  }
  else if (status != HTTP_STATUS_NOT_MODIFIED)
    invalidate_cupsd_cache(cg);

 /*
  * Remove any temporary files and copy the settings array...
  */

  if (remote)
    unlink(cupsdconf);

  for (i = cg->cupsd_num_settings, setting = cg->cupsd_settings;
       i > 0;
       i --, setting ++)
    *num_settings = cupsAddOption(setting->name, setting->value,
                                  *num_settings, settings);

  return (cg->cupsd_num_settings > 0);
}
Example #14
0
static http_status_t			/* O - Status of request */
get_cupsd_conf(
    http_t          *http,		/* I - Connection to server */
    _cups_globals_t *cg,		/* I - Global data */
    time_t          last_update,	/* I - Last update time for file */
    char            *name,		/* I - Filename buffer */
    size_t          namesize,		/* I - Size of filename buffer */
    int             *remote)		/* O - Remote file? */
{
  int		fd;			/* Temporary file descriptor */
#ifndef _WIN32
  struct stat	info;			/* cupsd.conf file information */
#endif /* _WIN32 */
  http_status_t	status;			/* Status of getting cupsd.conf */
  char		host[HTTP_MAX_HOST];	/* Hostname for connection */


 /*
  * See if we already have the data we need...
  */

  httpGetHostname(http, host, sizeof(host));

  if (_cups_strcasecmp(cg->cupsd_hostname, host))
    invalidate_cupsd_cache(cg);

  snprintf(name, namesize, "%s/cupsd.conf", cg->cups_serverroot);
  *remote = 0;

#ifndef _WIN32
  if (!_cups_strcasecmp(host, "localhost") && !access(name, R_OK))
  {
   /*
    * Read the local file rather than using HTTP...
    */

    if (stat(name, &info))
    {
      char	message[1024];		/* Message string */


      snprintf(message, sizeof(message),
               _cupsLangString(cupsLangDefault(), _("stat of %s failed: %s")),
               name, strerror(errno));
      _cupsSetError(IPP_STATUS_ERROR_INTERNAL, message, 0);

      *name = '\0';

      return (HTTP_STATUS_SERVER_ERROR);
    }
    else if (last_update && info.st_mtime <= last_update)
      status = HTTP_STATUS_NOT_MODIFIED;
    else
      status = HTTP_STATUS_OK;
  }
  else
#endif /* !_WIN32 */
  {
   /*
    * Read cupsd.conf via a HTTP GET request...
    */

    if ((fd = cupsTempFd(name, (int)namesize)) < 0)
    {
      *name = '\0';

      _cupsSetError(IPP_STATUS_ERROR_INTERNAL, NULL, 0);

      invalidate_cupsd_cache(cg);

      return (HTTP_STATUS_SERVER_ERROR);
    }

    *remote = 1;

    httpClearFields(http);

    if (last_update)
      httpSetField(http, HTTP_FIELD_IF_MODIFIED_SINCE,
                   httpGetDateString(last_update));

    status = cupsGetFd(http, "/admin/conf/cupsd.conf", fd);

    close(fd);

    if (status != HTTP_STATUS_OK)
    {
      unlink(name);
      *name = '\0';
    }
  }

  return (status);
}
Example #15
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments */
     char *argv[])			/* I - Command-line arguments */
{
  int		i;			/* Looping var */
  char		*opt;			/* Option pointer */
  const char	*username;		/* Pointer to username */
  const char	*groupname;		/* Pointer to group name */
  int		op;			/* Operation (add, change, delete) */
  const char	*passwd;		/* Password string */
  FILE		*infile,		/* Input file */
		*outfile;		/* Output file */
  char		line[256],		/* Line from file */
		userline[17],		/* User from line */
		groupline[17],		/* Group from line */
		md5line[33],		/* MD5-sum from line */
		md5new[33];		/* New MD5 sum */
  char		passwdmd5[1024],	/* passwd.md5 file */
		passwdold[1024],	/* passwd.old file */
		passwdnew[1024];	/* passwd.tmp file */
  char		*newpass,		/* new password */
  		*oldpass;		/* old password */
  int		flag;			/* Password check flags... */
  int		fd;			/* Password file descriptor */
  int		error;			/* Write error */
  _cups_globals_t *cg = _cupsGlobals();	/* Global data */
  cups_lang_t	*lang;			/* Language info */
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
  struct sigaction action;		/* Signal action */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET*/


  _cupsSetLocale(argv);
  lang = cupsLangDefault();

 /*
  * Check to see if stdin, stdout, and stderr are still open...
  */

  if (fcntl(0, F_GETFD, &i) ||
      fcntl(1, F_GETFD, &i) ||
      fcntl(2, F_GETFD, &i))
  {
   /*
    * No, return exit status 2 and don't try to send any output since
    * someone is trying to bypass the security on the server.
    */

    return (2);
  }

 /*
  * Find the server directory...
  */

  snprintf(passwdmd5, sizeof(passwdmd5), "%s/passwd.md5", cg->cups_serverroot);
  snprintf(passwdold, sizeof(passwdold), "%s/passwd.old", cg->cups_serverroot);
  snprintf(passwdnew, sizeof(passwdnew), "%s/passwd.new", cg->cups_serverroot);

 /*
  * Find the default system group...
  */

  if (getgrnam(CUPS_DEFAULT_GROUP))
    groupname = CUPS_DEFAULT_GROUP;
  else
    groupname = "unknown";

  endgrent();

  username = NULL;
  op       = CHANGE;

 /*
  * Parse command-line options...
  */

  for (i = 1; i < argc; i ++)
    if (argv[i][0] == '-')
      for (opt = argv[i] + 1; *opt; opt ++)
        switch (*opt)
	{
	  case 'a' : /* Add */
	      op = ADD;
	      break;
	  case 'x' : /* Delete */
	      op = DELETE;
	      break;
	  case 'g' : /* Group */
	      i ++;
	      if (i >= argc)
	        usage(stderr);

              groupname = argv[i];
	      break;
	  case 'h' : /* Help */
	      usage(stdout);
	      break;
	  default : /* Bad option */
	      usage(stderr);
	      break;
	}
    else if (!username)
      username = argv[i];
    else
      usage(stderr);

 /*
  * See if we are trying to add or delete a password when we aren't logged in
  * as root...
  */

  if (getuid() && getuid() != geteuid() && (op != CHANGE || username))
  {
    _cupsLangPuts(stderr,
                  _("lppasswd: Only root can add or delete passwords!\n"));
    return (1);
  }

 /*
  * Fill in missing info...
  */

  if (!username)
    username = cupsUser();

  oldpass = newpass = NULL;

 /*
  * Obtain old and new password _before_ locking the database
  * to keep users from locking the file indefinitely.
  */

  if (op == CHANGE && getuid())
  {
    if ((passwd = cupsGetPassword(_("Enter old password:"******"lppasswd: Unable to copy password string: %s\n"),
		      strerror(errno));
      return (1);
    }
  }

 /*
  * Now get the new password, if necessary...
  */

  if (op != DELETE)
  {
    if ((passwd = cupsGetPassword(
            _cupsLangString(lang, _("Enter password:"******"lppasswd: Unable to copy password string: %s\n"),
		      strerror(errno));
      return (1);
    }

    if ((passwd = cupsGetPassword(
            _cupsLangString(lang, _("Enter password again:")))) == NULL)
      return (1);

    if (strcmp(passwd, newpass) != 0)
    {
      _cupsLangPuts(stderr,
                    _("lppasswd: Sorry, passwords don't match!\n"));
      return (1);
    }

   /*
    * Check that the password contains at least one letter and number.
    */

    flag = 0;

    for (passwd = newpass; *passwd; passwd ++)
      if (isdigit(*passwd & 255))
	flag |= 1;
      else if (isalpha(*passwd & 255))
	flag |= 2;

   /*
    * Only allow passwords that are at least 6 chars, have a letter and
    * a number, and don't contain the username.
    */

    if (strlen(newpass) < 6 || strstr(newpass, username) != NULL || flag != 3)
    {
      _cupsLangPuts(stderr,
                    _("lppasswd: Sorry, password rejected.\n"
		      "Your password must be at least 6 characters long, "
		      "cannot contain\n"
		      "your username, and must contain at least one letter "
		      "and number.\n"));
      return (1);
    }
  }

 /*
  * Ignore SIGHUP, SIGINT, SIGTERM, and SIGXFSZ (if defined) for the
  * remainder of the time so that we won't end up with bogus password
  * files...
  */

#ifndef WIN32
#  if defined(HAVE_SIGSET)
  sigset(SIGHUP, SIG_IGN);
  sigset(SIGINT, SIG_IGN);
  sigset(SIGTERM, SIG_IGN);
#    ifdef SIGXFSZ
  sigset(SIGXFSZ, SIG_IGN);
#    endif /* SIGXFSZ */
#  elif defined(HAVE_SIGACTION)
  memset(&action, 0, sizeof(action));
  action.sa_handler = SIG_IGN;

  sigaction(SIGHUP, &action, NULL);
  sigaction(SIGINT, &action, NULL);
  sigaction(SIGTERM, &action, NULL);
#    ifdef SIGXFSZ
  sigaction(SIGXFSZ, &action, NULL);
#    endif /* SIGXFSZ */
#  else
  signal(SIGHUP, SIG_IGN);
  signal(SIGINT, SIG_IGN);
  signal(SIGTERM, SIG_IGN);
#    ifdef SIGXFSZ
  signal(SIGXFSZ, SIG_IGN);
#    endif /* SIGXFSZ */
#  endif
#endif /* !WIN32 */

 /*
  * Open the output file.
  */

  if ((fd = open(passwdnew, O_WRONLY | O_CREAT | O_EXCL, 0400)) < 0)
  {
    if (errno == EEXIST)
      _cupsLangPuts(stderr, _("lppasswd: Password file busy!\n"));
    else
      _cupsLangPrintf(stderr,
                      _("lppasswd: Unable to open password file: %s\n"),
		      strerror(errno));

    return (1);
  }

  if ((outfile = fdopen(fd, "w")) == NULL)
  {
    _cupsLangPrintf(stderr,
                    _("lppasswd: Unable to open password file: %s\n"),
		    strerror(errno));

    unlink(passwdnew);

    return (1);
  }

  setbuf(outfile, NULL);

 /*
  * Open the existing password file and create a new one...
  */

  infile = fopen(passwdmd5, "r");
  if (infile == NULL && errno != ENOENT && op != ADD)
  {
    _cupsLangPrintf(stderr,
                    _("lppasswd: Unable to open password file: %s\n"),
		    strerror(errno));

    fclose(outfile);

    unlink(passwdnew);

    return (1);
  }

 /*
  * Read lines from the password file; the format is:
  *
  *   username:group:MD5-sum
  */

  error        = 0;
  userline[0]  = '\0';
  groupline[0] = '\0';
  md5line[0]   = '\0';

  if (infile)
  {
    while (fgets(line, sizeof(line), infile) != NULL)
    {
      if (sscanf(line, "%16[^:]:%16[^:]:%32s", userline, groupline, md5line) != 3)
        continue;

      if (strcmp(username, userline) == 0 &&
          strcmp(groupname, groupline) == 0)
	break;

      if (fputs(line, outfile) == EOF)
      {
	_cupsLangPrintf(stderr,
                	_("lppasswd: Unable to write to password file: %s\n"),
			strerror(errno));
        error = 1;
	break;
      }
    }

    if (!error)
    {
      while (fgets(line, sizeof(line), infile) != NULL)
	if (fputs(line, outfile) == EOF)
	{
	  _cupsLangPrintf(stderr,
                	  _("lppasswd: Unable to write to password file: %s\n"),
			  strerror(errno));
	  error = 1;
	  break;
	}
    }
  }

  if (op == CHANGE &&
      (strcmp(username, userline) || strcmp(groupname, groupline)))
  {
    _cupsLangPrintf(stderr,
                    _("lppasswd: user \"%s\" and group \"%s\" do not exist.\n"),
        	    username, groupname);
    error = 1;
  }
  else if (op != DELETE)
  {
    if (oldpass &&
        strcmp(httpMD5(username, "CUPS", oldpass, md5new), md5line) != 0)
    {
      _cupsLangPuts(stderr,
                    _("lppasswd: Sorry, password doesn't match!\n"));
      error = 1;
    }
    else
    {
      snprintf(line, sizeof(line), "%s:%s:%s\n", username, groupname,
               httpMD5(username, "CUPS", newpass, md5new));
      if (fputs(line, outfile) == EOF)
      {
	_cupsLangPrintf(stderr,
                	_("lppasswd: Unable to write to password file: %s\n"),
			strerror(errno));
        error = 1;
      }
    }
  }

 /*
  * Close the files...
  */

  if (infile)
    fclose(infile);

  if (fclose(outfile) == EOF)
    error = 1;

 /*
  * Error out gracefully as needed...
  */

  if (error)
  {
    _cupsLangPuts(stderr, _("lppasswd: Password file not updated!\n"));
    
    unlink(passwdnew);

    return (1);
  }

 /*
  * Save old passwd file
  */

  unlink(passwdold);
  if (link(passwdmd5, passwdold) && errno != ENOENT)
  {
    _cupsLangPrintf(stderr,
                    _("lppasswd: failed to backup old password file: %s\n"),
		    strerror(errno));
    unlink(passwdnew);
    return (1);
  }

 /*
  * Install new password file
  */

  if (rename(passwdnew, passwdmd5) < 0)
  {
    _cupsLangPrintf(stderr,
                    _("lppasswd: failed to rename password file: %s\n"),
		    strerror(errno));
    unlink(passwdnew);
    return (1);
  }

  return (0);
}
Example #16
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments */
     char *argv[])			/* I - Command-line arguments */
{
  int			i;		/* Looping var */
  int			errors = 0;	/* Number of errors */
  cups_lang_t		*language;	/* Message catalog */
  cups_lang_t		*language2;	/* Message catalog */
  struct lconv		*loc;		/* Locale data */
  char			buffer[1024];	/* String buffer */
  double		number;		/* Number */
  static const char * const tests[] =	/* Test strings */
  {
    "1",
    "-1",
    "3",
    "5.125"
  };


  if (argc == 1)
  {
    language  = cupsLangDefault();
    language2 = cupsLangDefault();
  }
  else
  {
    language  = cupsLangGet(argv[1]);
    language2 = cupsLangGet(argv[1]);

    setenv("LANG", argv[1], 1);
    setenv("SOFTWARE", "CUPS/" CUPS_SVERSION, 1);
  }

  _cupsSetLocale(argv);

  if (language != language2)
  {
    errors ++;

    puts("**** ERROR: Language cache did not work! ****");
    puts("First result from cupsLangGet:");
  }

  printf("Language = \"%s\"\n", language->language);
  printf("Encoding = \"%s\"\n", _cupsEncodingName(language->encoding));
  printf("No       = \"%s\"\n", _cupsLangString(language, "No"));
  printf("Yes      = \"%s\"\n", _cupsLangString(language, "Yes"));

  if (language != language2)
  {
    puts("Second result from cupsLangGet:");

    printf("Language = \"%s\"\n", language2->language);
    printf("Encoding = \"%s\"\n", _cupsEncodingName(language2->encoding));
    printf("No       = \"%s\"\n", _cupsLangString(language2, "No"));
    printf("Yes      = \"%s\"\n", _cupsLangString(language2, "Yes"));
  }

  loc = localeconv();

  for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i ++)
  {
    number = _cupsStrScand(tests[i], NULL, loc);

    printf("_cupsStrScand(\"%s\") number=%f\n", tests[i], number);

    _cupsStrFormatd(buffer, buffer + sizeof(buffer), number, loc);

    printf("_cupsStrFormatd(%f) buffer=\"%s\"\n", number, buffer);

    if (strcmp(buffer, tests[i]))
    {
      errors ++;
      puts("**** ERROR: Bad formatted number! ****");
    }
  }

  if (argc == 3)
  {
    ppd_file_t		*ppd;		/* PPD file */
    ppd_option_t	*option;	/* PageSize option */
    ppd_choice_t	*choice;	/* PageSize/Letter choice */

    if ((ppd = ppdOpenFile(argv[2])) == NULL)
    {
      printf("Unable to open PPD file \"%s\".\n", argv[2]);
      errors ++;
    }
    else
    {
      ppdLocalize(ppd);

      if ((option = ppdFindOption(ppd, "PageSize")) == NULL)
      {
        puts("No PageSize option.");
        errors ++;
      }
      else
      {
        printf("PageSize: %s\n", option->text);

        if ((choice = ppdFindChoice(option, "Letter")) == NULL)
        {
	  puts("No Letter PageSize choice.");
	  errors ++;
        }
        else
        {
	  printf("Letter: %s\n", choice->text);
        }
      }

      ppdClose(ppd);
    }
  }

  return (errors > 0);
}