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); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { int status = 0, /* Exit status */ i, /* Looping var */ num_dests; /* Number of destinations */ cups_dest_t *dests, /* Destinations */ *dest, /* Current destination */ *named_dest; /* Current named destination */ const char *ppdfile; /* PPD file */ ppd_file_t *ppd; /* PPD file data */ int num_jobs; /* Number of jobs for queue */ cups_job_t *jobs; /* Jobs for queue */ if (argc > 1) { if (!strcmp(argv[1], "enum")) { cups_ptype_t mask = CUPS_PRINTER_LOCAL, /* Printer type mask */ type = CUPS_PRINTER_LOCAL; /* Printer type */ int msec = 0; /* Timeout in milliseconds */ for (i = 2; i < argc; i ++) if (isdigit(argv[i][0] & 255) || argv[i][0] == '.') msec = (int)(atof(argv[i]) * 1000); else if (!_cups_strcasecmp(argv[i], "bw")) { mask |= CUPS_PRINTER_BW; type |= CUPS_PRINTER_BW; } else if (!_cups_strcasecmp(argv[i], "color")) { mask |= CUPS_PRINTER_COLOR; type |= CUPS_PRINTER_COLOR; } else if (!_cups_strcasecmp(argv[i], "mono")) { mask |= CUPS_PRINTER_COLOR; } else if (!_cups_strcasecmp(argv[i], "duplex")) { mask |= CUPS_PRINTER_DUPLEX; type |= CUPS_PRINTER_DUPLEX; } else if (!_cups_strcasecmp(argv[i], "simplex")) { mask |= CUPS_PRINTER_DUPLEX; } else if (!_cups_strcasecmp(argv[i], "staple")) { mask |= CUPS_PRINTER_STAPLE; type |= CUPS_PRINTER_STAPLE; } else if (!_cups_strcasecmp(argv[i], "copies")) { mask |= CUPS_PRINTER_COPIES; type |= CUPS_PRINTER_COPIES; } else if (!_cups_strcasecmp(argv[i], "collate")) { mask |= CUPS_PRINTER_COLLATE; type |= CUPS_PRINTER_COLLATE; } else if (!_cups_strcasecmp(argv[i], "punch")) { mask |= CUPS_PRINTER_PUNCH; type |= CUPS_PRINTER_PUNCH; } else if (!_cups_strcasecmp(argv[i], "cover")) { mask |= CUPS_PRINTER_COVER; type |= CUPS_PRINTER_COVER; } else if (!_cups_strcasecmp(argv[i], "bind")) { mask |= CUPS_PRINTER_BIND; type |= CUPS_PRINTER_BIND; } else if (!_cups_strcasecmp(argv[i], "sort")) { mask |= CUPS_PRINTER_SORT; type |= CUPS_PRINTER_SORT; } else if (!_cups_strcasecmp(argv[i], "mfp")) { mask |= CUPS_PRINTER_MFP; type |= CUPS_PRINTER_MFP; } else if (!_cups_strcasecmp(argv[i], "printer")) { mask |= CUPS_PRINTER_MFP; } else if (!_cups_strcasecmp(argv[i], "large")) { mask |= CUPS_PRINTER_LARGE; type |= CUPS_PRINTER_LARGE; } else if (!_cups_strcasecmp(argv[i], "medium")) { mask |= CUPS_PRINTER_MEDIUM; type |= CUPS_PRINTER_MEDIUM; } else if (!_cups_strcasecmp(argv[i], "small")) { mask |= CUPS_PRINTER_SMALL; type |= CUPS_PRINTER_SMALL; } else fprintf(stderr, "Unknown argument \"%s\" ignored...\n", argv[i]); cupsEnumDests(CUPS_DEST_FLAGS_NONE, msec, NULL, type, mask, enum_cb, NULL); } else if (!strcmp(argv[1], "password")) { const char *pass = cupsGetPassword("Password:"******"Password entered: %s\n", pass); else puts("No password entered."); } else if (!strcmp(argv[1], "ppd") && argc == 3) { /* * ./testcups ppd printer */ http_status_t http_status; /* Status */ char buffer[1024]; /* PPD filename */ time_t modtime = 0; /* Last modified */ if ((http_status = cupsGetPPD3(CUPS_HTTP_DEFAULT, argv[2], &modtime, buffer, sizeof(buffer))) != HTTP_STATUS_OK) printf("Unable to get PPD: %d (%s)\n", (int)http_status, cupsLastErrorString()); else puts(buffer); } else if (!strcmp(argv[1], "print") && argc == 5) { /* * ./testcups print printer file interval */ int interval, /* Interval between writes */ job_id; /* Job ID */ cups_file_t *fp; /* Print file */ char buffer[16384]; /* Read/write buffer */ ssize_t bytes; /* Bytes read/written */ if ((fp = cupsFileOpen(argv[3], "r")) == NULL) { printf("Unable to open \"%s\": %s\n", argv[2], strerror(errno)); return (1); } if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, argv[2], "testcups", 0, NULL)) <= 0) { printf("Unable to create print job on %s: %s\n", argv[1], cupsLastErrorString()); return (1); } interval = atoi(argv[4]); if (cupsStartDocument(CUPS_HTTP_DEFAULT, argv[1], job_id, argv[2], CUPS_FORMAT_AUTO, 1) != HTTP_STATUS_CONTINUE) { puts("Unable to start document!"); return (1); } while ((bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0) { printf("Writing %d bytes...\n", (int)bytes); if (cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, bytes) != HTTP_STATUS_CONTINUE) { puts("Unable to write bytes!"); return (1); } if (interval > 0) sleep(interval); } cupsFileClose(fp); if (cupsFinishDocument(CUPS_HTTP_DEFAULT, argv[1]) > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED) { puts("Unable to finish document!"); return (1); } } else { puts("Usage:"); puts(""); puts("Run basic unit tests:"); puts(""); puts(" ./testcups"); puts(""); puts("Enumerate printers (for N seconds, -1 for indefinitely):"); puts(""); puts(" ./testcups enum [seconds]"); puts(""); puts("Ask for a password:"******""); puts(" ./testcups password"); puts(""); puts("Get the PPD file:"); puts(""); puts(" ./testcups ppd printer"); puts(""); puts("Print a file (interval controls delay between buffers in seconds):"); puts(""); puts(" ./testcups print printer file interval"); return (1); } return (0); } /* * cupsGetDests() */ fputs("cupsGetDests: ", stdout); fflush(stdout); num_dests = cupsGetDests(&dests); if (num_dests == 0) { puts("FAIL"); return (1); } else { printf("PASS (%d dests)\n", num_dests); for (i = num_dests, dest = dests; i > 0; i --, dest ++) { printf(" %s", dest->name); if (dest->instance) printf(" /%s", dest->instance); if (dest->is_default) puts(" ***DEFAULT***"); else putchar('\n'); } } /* * cupsGetDest(NULL) */ fputs("cupsGetDest(NULL): ", stdout); fflush(stdout); if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL) { for (i = num_dests, dest = dests; i > 0; i --, dest ++) if (dest->is_default) break; if (i) { status = 1; puts("FAIL"); } else puts("PASS (no default)"); dest = NULL; } else printf("PASS (%s)\n", dest->name); /* * cupsGetNamedDest(NULL, NULL, NULL) */ fputs("cupsGetNamedDest(NULL, NULL, NULL): ", stdout); fflush(stdout); if ((named_dest = cupsGetNamedDest(NULL, NULL, NULL)) == NULL || !dests_equal(dest, named_dest)) { if (!dest) puts("PASS (no default)"); else if (named_dest) { puts("FAIL (different values)"); show_diffs(dest, named_dest); status = 1; } else { puts("FAIL (no default)"); status = 1; } } else printf("PASS (%s)\n", named_dest->name); if (named_dest) cupsFreeDests(1, named_dest); /* * cupsGetDest(printer) */ printf("cupsGetDest(\"%s\"): ", dests[num_dests / 2].name); fflush(stdout); if ((dest = cupsGetDest(dests[num_dests / 2].name, NULL, num_dests, dests)) == NULL) { puts("FAIL"); return (1); } else puts("PASS"); /* * cupsGetNamedDest(NULL, printer, instance) */ printf("cupsGetNamedDest(NULL, \"%s\", \"%s\"): ", dest->name, dest->instance ? dest->instance : "(null)"); fflush(stdout); if ((named_dest = cupsGetNamedDest(NULL, dest->name, dest->instance)) == NULL || !dests_equal(dest, named_dest)) { if (named_dest) { puts("FAIL (different values)"); show_diffs(dest, named_dest); } else puts("FAIL (no destination)"); status = 1; } else puts("PASS"); if (named_dest) cupsFreeDests(1, named_dest); /* * cupsPrintFile() */ fputs("cupsPrintFile: ", stdout); fflush(stdout); if (cupsPrintFile(dest->name, "../data/testprint", "Test Page", dest->num_options, dest->options) <= 0) { printf("FAIL (%s)\n", cupsLastErrorString()); return (1); } else puts("PASS"); /* * cupsGetPPD(printer) */ fputs("cupsGetPPD(): ", stdout); fflush(stdout); if ((ppdfile = cupsGetPPD(dest->name)) == NULL) { puts("FAIL"); } else { puts("PASS"); /* * ppdOpenFile() */ fputs("ppdOpenFile(): ", stdout); fflush(stdout); if ((ppd = ppdOpenFile(ppdfile)) == NULL) { puts("FAIL"); return (1); } else puts("PASS"); ppdClose(ppd); unlink(ppdfile); } /* * cupsGetJobs() */ fputs("cupsGetJobs: ", stdout); fflush(stdout); num_jobs = cupsGetJobs(&jobs, NULL, 0, -1); if (num_jobs == 0) { puts("FAIL"); return (1); } else puts("PASS"); cupsFreeJobs(num_jobs, jobs); cupsFreeDests(num_dests, dests); return (status); }
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); }