/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include #include #include #include #include #include #include #include #ifndef SUNOS_4 #include #endif #include #include #include #include extern char *optarg; extern int optind, opterr, optopt; extern char *getenv(const char *); static void _decode_ldapResult(int result, char *printerName); static int authorized() { struct passwd *pw; uid_t uid; gid_t *list; int len; int maxgrp; if ((uid = getuid()) == 0) return (1); /* "root" is authorized */ if (((pw = getpwnam("lp")) != NULL) && (uid == pw->pw_uid)) return (1); /* "lp" is authorized */ if ((pw = getpwuid(uid)) == NULL) return (0); /* intruders are not authorized */ if (chkauthattr("solaris.print.admin", pw->pw_name) == 1) return (1); /* "solaris.print.admin" is authorized */ /* How many supplemental groups do we have? */ maxgrp = getgroups(0, NULL); list = alloca(maxgrp * sizeof (gid_t)); if ((len = getgroups(maxgrp, list)) != -1) while (len-- > 0) if (list[len] == 14) return (1); /* group 14 is authorized */ return (0); /* nobody else is authorized */ } static void Usage(char *name) { (void) fprintf(stderr, gettext("Usage: %s [-n files | ldap] [-x] " "[-h ldaphost] [-D binddn] [-w passwd] " "[-a key=value] [-d key] (printer)\n"), name); exit(1); } /* * main() calls the appropriate routine to parse the command line arguments * and then calls the local remove routine, followed by the remote remove * routine to remove jobs. */ int main(int ac, char *av[]) { int result = 0; int delete_printer = 0; int c; char *program = NULL, *printer = NULL, *host = NULL, *binddn = NULL, *passwd = NULL, *ins = NULL, *ons = "files"; char **changes = NULL; ns_cred_t *cred = NULL; ns_printer_t *printer_obj = NULL; (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) #define TEXT_DOMAIN "SYS_TEST" #endif (void) textdomain(TEXT_DOMAIN); if ((program = strrchr(av[0], '/')) == NULL) program = av[0]; else program++; openlog(program, LOG_PID, LOG_LPR); if (ac < 2) Usage(program); while ((c = getopt(ac, av, "a:d:D:h:n:r:w:x")) != EOF) switch (c) { case 'd': if (strchr(optarg, '=') != NULL) Usage(program); /* FALLTHRU */ case 'a': changes = (char **)list_append((void**)changes, (void *)strdup(optarg)); break; case 'D': binddn = optarg; break; case 'h': host = optarg; break; case 'n': ons = optarg; break; case 'r': ins = optarg; break; case 'w': passwd = optarg; break; case 'x': delete_printer++; break; default: Usage(program); } if (optind != ac-1) Usage(program); /* * Check required options have been given: [ -x | [ -a | -d ]] */ if ((changes == NULL) && (delete_printer == 0)) { Usage(program); } printer = av[optind]; if (strchr(printer, ':') != NULL) { (void) fprintf(stderr, gettext( "POSIX-Style names are not valid destinations (%s)\n"), printer); return (1); } ins = normalize_ns_name(ins); ons = normalize_ns_name(ons); if (ins == NULL) ins = ons; /* check / set the name service for writing */ if (strcasecmp("user", ons) == 0) { (void) setuid(getuid()); ons = "user"; } else if (strcasecmp("files", ons) == 0) { if (authorized() == 0) { (void) fprintf(stderr, gettext( "Permission denied: not authorized\n")); return (1); } ons = "files"; } else if (strcasecmp("ldap", ons) == 0) { if ((cred = calloc(1, sizeof (*cred))) == NULL) { (void) fprintf(stderr, gettext("could not initialize credential\n")); return (1); } if (binddn == NULL) { (void) fprintf(stderr, gettext("Distinguished Name is required.\n")); return (1); } if (passwd == NULL) { passwd = getpassphrase(gettext("Bind Password:")); } /* * Setup LDAP bind credentials, so that it uses * the default ldap port, and the NS domain for this * ldapclient box. Note: passwdType is currently not * used but once the ldap native function can select * secure or insure password it will pass the user selected * security type. */ cred->passwd = passwd; cred->passwdType = NS_PW_INSECURE; /* use default */ cred->binddn = binddn; cred->host = host; cred->port = 0; /* use default */ cred->domainDN = NULL; /* use default */ ons = "ldap"; (void) setuid(getuid()); } else { (void) fprintf(stderr, gettext("%s is not a supported name service.\n"), ons); return (1); } if (strcasecmp(NS_SVC_LDAP, ons) != 0) { /* Naming Service is not LDAP */ /* get the printer object */ if ((printer_obj = ns_printer_get_name(printer, ins)) == NULL) { if (delete_printer != 0) { (void) fprintf(stderr, gettext ("%s: unknown printer\n"), printer); return (1); } if ((printer_obj = calloc(1, sizeof (*printer_obj))) == NULL) { (void) fprintf(stderr, gettext( "could not initialize printer object\n")); return (1); } printer_obj->name = strdup(printer); } printer_obj->source = ons; if (cred != NULL) { printer_obj->cred = cred; } /* make the changes to it */ while (changes != NULL && *changes != NULL) { int has_equals = (strchr(*changes, '=') != NULL); char *p, *key = NULL, *value = NULL; key = *(changes++); for (p = key; ((p != NULL) && (*p != '\0')); p++) if (*p == '=') { *p = '\0'; value = ++p; break; } else if (*p == '\\') p++; if ((value != NULL) && (*value == '\0')) value = NULL; if ((key != NULL) && (key[0] != '\0')) { if ((value == NULL) && (ns_get_value(key, printer_obj) == NULL) && (has_equals == 0)) { fprintf(stderr, gettext("%s: unknown attribute\n"), key); result = 1; } else (void) ns_set_value_from_string(key, value, printer_obj); } } if (delete_printer != 0) printer_obj->attributes = NULL; /* write it back */ if (ns_printer_put(printer_obj) != 0) { (void) fprintf(stderr, gettext("Failed to write into %s database\n"), ons); result = 1; } } else { /* * Naming Service is LDAP * * Action the request by calling ns ldap functions to * add, modify or delete the printer object. */ if ((printer_obj = calloc(1, sizeof (*printer_obj))) == NULL) { (void) fprintf(stderr, gettext( "could not initialize printer object\n")); return (1); } if ((cred != NULL) && (printer_obj != NULL)) { printer_obj->name = strdup(printer); printer_obj->cred = cred; printer_obj->cred->domainDN = NULL; /* use default */ printer_obj->source = ons; printer_obj->nsdata = malloc(sizeof (NS_LDAPDATA)); if (printer_obj->nsdata != NULL) { /* * Update the LDAP directory for this printer */ if (delete_printer != 0) { /* Delete the printer object */ ((NS_LDAPDATA *) (printer_obj->nsdata))->attrList = NULL; } else { /* Add or modify the printer object */ ((NS_LDAPDATA *) (printer_obj->nsdata))->attrList = changes; } result = ns_printer_put(printer_obj); if (result != 0) { /* display LDAP specific message */ _decode_ldapResult(result, printer); (void) fprintf(stderr, gettext( "Failed to update %s database\n"), ons); result = 1; } free(printer_obj->nsdata); } else { _decode_ldapResult(NSL_ERR_MEMORY, NULL); result = 1; } } else { result = 1; (void) fprintf(stderr, gettext("Error - no LDAP credentials\n")); } if (printer_obj != NULL) { if (printer_obj->name != NULL) { free(printer_obj->name); } free(printer_obj); } } return (result); } /* main */ /* * ***************************************************************************** * * Function: _decode_ldapResult() * * Description: Decode the ldap_put_printer specific error codes and display * the appropriate error message. * * Parameters: * Input: int result - contains the NSL_RESULT codes * char *printerName - name of printer * Output: None * * Returns: void * * ***************************************************************************** */ static void _decode_ldapResult(int result, char *printerName) { NSL_RESULT lresult = (NSL_RESULT)result; /* ------------- */ switch (lresult) { case NSL_OK: { break; } case NSL_ERR_INTERNAL: { (void) fprintf(stderr, gettext("Unexpected software error\n")); break; } case NSL_ERR_ADD_FAILED: { (void) fprintf(stderr, "%s %s\n", gettext("Failed to add printer:"), printerName); break; } case NSL_ERR_MOD_FAILED: { (void) fprintf(stderr, "%s %s\n", gettext("Failed to modify printer:"), printerName); break; } case NSL_ERR_DEL_FAILED: { (void) fprintf(stderr, "%s %s\n", gettext("Failed to delete printer:"), printerName); break; } case NSL_ERR_UNKNOWN_PRINTER: { (void) fprintf(stderr, "%s %s\n", gettext("Unknown printer:"), printerName); break; } case NSL_ERR_CREDENTIALS: { (void) fprintf(stderr, "%s\n", gettext("Missing LDAP credential information for printer:")); break; } case NSL_ERR_CONNECT: { (void) fprintf(stderr, "%s\n", gettext("Failed to connect to LDAP server")); break; } case NSL_ERR_BIND: { (void) fprintf(stderr, gettext("LDAP bind failed\n")); break; } case NSL_ERR_RENAME: { (void) fprintf(stderr, "%s %s\n", gettext("Object rename not allowed for printer:"), printerName); break; } case NSL_ERR_KVP: { (void) fprintf(stderr, "%s", gettext("Setting sun-printer-kvp attribute is " "not supported through this command.\n")); break; } case NSL_ERR_BSDADDR: { (void) fprintf(stderr, "%s", gettext("Setting sun-printer-bsdaddr attribute is " "not supported through this command.\n" "Use the bsaddr attribute instead.\n")); break; } case NSL_ERR_PNAME: { (void) fprintf(stderr, "%s", gettext("Setting printer-name attribute is " "not supported through this command.\n")); break; } case NSL_ERR_MEMORY: { (void) fprintf(stderr, gettext("Memory allocation error\n")); break; } case NSL_ERR_MULTIOP: { (void) fprintf(stderr, gettext("Delete and add operation on the " "same key attribute is not allowed\n")); break; } case NSL_ERR_NOTALLOWED: { (void) fprintf(stderr, gettext("KVP attribute is not allowed\n")); break; } default: { (void) fprintf(stderr, gettext("Error code = %d\n"), result); break; } } } /* _decode_ldapResult */