/* * 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. * * DoPrinterNS class * Worker class for updating name services. * Interfaces to JNI code. */ package com.sun.admin.pm.server; public class DoPrinterNS { // // JNI member functions // private synchronized static native int dorexec(String nshost, String user, String passwd, String cmd, String locale); private synchronized static native int updateoldyp(String action, String printername, String printserver, String extensions, String comment, String isdefault); private synchronized static native int updateldap(String action, String host, String binddn, String passwd, String printername, String printserver, String extensions, String comment, String isdefault); private synchronized static native String getstderr(); private synchronized static native String getstdout(); // // Load JNI. // static { System.loadLibrary("pmgr"); } // // main for testing // public static void main(String[] args) { // // Set attributes for testing. // NameService ns = null; try { ns = new NameService("nis"); } catch (Exception e) { System.out.println(e); System.exit(1); } ns.setPasswd(""); Printer p = new Printer(ns); p.setPrinterName("javatest"); p.setPrintServer("zelkova"); p.setComment("This is a comment"); p.setIsDefaultPrinter(false); p.setLocale(null); String action = "add"; if (args.length >= 1) action = args[0]; try { set(action, p, ns); } catch (Exception e) { System.out.println(e); } System.out.println("Commands:\n" + p.getCmdLog()); System.out.println("Errors:\n" + p.getErrorLog()); System.out.println("Warnings:\n" + p.getWarnLog()); System.exit(0); } // // Interface to DoPrinter[add|mod|delete] // public static void set( String action, Printer p, NameService ns) throws Exception { String nameservice = ns.getNameService(); if (nameservice.equals("system")) { return; } else if (nameservice.equals("nis")) { setNIS(action, p, ns); return; } setNS(action, p, ns); return; } private static void setNIS( String action, Printer p, NameService ns) throws Exception { Debug.message("SVR: DoPrinterNS.setNIS(): " + action); String printername = p.getPrinterName(); String printserver = p.getPrintServer(); String comment = p.getComment(); String extensions = p.getExtensions(); boolean default_printer = p.getIsDefaultPrinter(); String locale = p.getLocale(); if (locale == null) locale = "C"; String nameservice = ns.getNameService(); String nshost = ns.getNameServiceHost(); String user = ns.getUser(); String passwd = ns.getPasswd(); String cmd = null; String err = null; int ret = 0; int exitvalue = 0; // // If this is the nis master we only need to do the make // locally. // Host h = new Host(); String lh = h.getLocalHostName(); if (lh.equals(nshost)) { cmd = "/usr/ccs/bin/make -f /var/yp/Makefile"; cmd = cmd.concat(" -f /usr/lib/print/Makefile.yp "); cmd = cmd.concat("printers.conf"); p.setCmdLog(cmd); SysCommand syscmd = new SysCommand(); syscmd.exec(cmd); err = syscmd.getError(); if (syscmd.getExitValue() != 0) { p.setErrorLog(err); syscmd = null; throw new pmCmdFailedException(err); } else { // ignore touch warning // p.setWarnLog(err); } syscmd = null; return; } String cmdprefix = "rexec(" + nshost + "): "; cmd = "/usr/bin/echo"; Debug.message("SVR: " + cmdprefix + cmd); ret = dorexec(nshost, user, passwd, cmd, locale); if (ret != 0) { throw new pmAuthException(getstderr()); } // // Do we have lpset // cmd = "/usr/bin/ls /usr/bin/lpset"; Debug.message("SVR: " + cmdprefix + cmd); ret = dorexec(nshost, user, passwd, cmd, locale); if (ret != 0) { throw new pmCmdFailedException(getstderr()); } String tmpstr = getstdout(); tmpstr = tmpstr.trim(); if (!tmpstr.equals("/usr/bin/lpset")) { Debug.message("SVR: No lpset found. Checking rhosts."); // Are we set up in rhosts? cmd = "rsh "; cmd = cmd.concat(nshost); cmd = cmd.concat(" echo"); SysCommand syscmd = new SysCommand(); syscmd.exec(cmd); err = syscmd.getError(); if (syscmd.getExitValue() != 0) { syscmd = null; throw new pmAuthRhostException(err); } syscmd = null; // // We don't have lpset. Must be pre-2.6 master. // We are set up in rhosts so use libprint // to update it. // p.setCmdLog("rsh " + nshost + "..."); String def = "false"; if (default_printer) def = "true"; Debug.message("SVR: updateoldyp(): "); Debug.message("SVR: action=" + action); Debug.message("SVR: printername=" + printername); Debug.message("SVR: printserver=" + printserver); Debug.message("SVR: extensions=" + extensions); Debug.message("SVR: comment=" + comment); Debug.message("SVR: default=" + def); ret = updateoldyp(action, printername, printserver, extensions, comment, def); if (ret != 0) { throw new pmCmdFailedException("libprint"); } return; } // // Add and modify are the same // boolean domake = false; if (!action.equals("delete")) { // // If we are here from a modify and only need // to change the default printer ... // if (!p.modhints.equals("defaultonly")) { String bsdaddr = "bsdaddr=" + printserver + "," + printername; if (extensions != null) { bsdaddr = bsdaddr.concat("," + extensions); } cmd = "/usr/bin/lpset -a " + bsdaddr; if (comment != null) { cmd = cmd.concat(" -a " + "description=" + "\"" + comment + "\""); } cmd = cmd.concat(" " + printername); Debug.message("SVR: " + cmdprefix + cmd); p.setCmdLog(cmdprefix + cmd); ret = dorexec(nshost, user, passwd, cmd, locale); err = getstderr(); if (ret != 0) { p.setErrorLog(err); throw new pmCmdFailedException(err); } if (!err.equals("")) { p.setWarnLog(err); } domake = true; } cmd = null; String def = DoPrinterUtil.getDefault("nis"); if (default_printer) { if (!printername.equals(def)) { cmd = "/usr/bin/lpset -a " + "use=" + printername + " _default"; } } else { if ((def != null) && (def.equals(printername))) { // // It was the default but not any more. // cmd = "/usr/bin/lpset -x _default"; } } if (cmd != null) { Debug.message("SVR: " + cmdprefix + cmd); p.setCmdLog(cmdprefix + cmd); ret = dorexec(nshost, user, passwd, cmd, locale); err = getstderr(); if (ret != 0) { p.setErrorLog(err); throw new pmCmdFailedException(err); } if (!err.equals("")) { p.setWarnLog(err); } domake = true; } } else { if (DoPrinterUtil.exists(printername, "nis")) { // delete cmd = "/usr/bin/lpset -x " + printername; Debug.message("SVR: " + cmdprefix + cmd); p.setCmdLog(cmdprefix + cmd); ret = dorexec(nshost, user, passwd, cmd, locale); err = getstderr(); if (ret != 0) { p.setErrorLog(err); throw new pmCmdFailedException(err); } if (!err.equals("")) { p.setWarnLog(err); } domake = true; } String def = DoPrinterUtil.getDefault("nis"); if ((def != null) && (def.equals(printername))) { cmd = "/usr/bin/lpset -x _default"; Debug.message("SVR: " + cmdprefix + cmd); p.setCmdLog(cmdprefix + cmd); ret = dorexec(nshost, user, passwd, cmd, locale); err = getstderr(); if (ret != 0) { p.setErrorLog(err); throw new pmCmdFailedException(err); } if (!err.equals("")) { p.setWarnLog(err); } domake = true; } } if (!domake) { return; } cmd = "cd /var/yp; /usr/ccs/bin/make -f /var/yp/Makefile"; cmd = cmd.concat(" -f /usr/lib/print/Makefile.yp printers.conf"); Debug.message("SVR: " + cmdprefix + cmd); p.setCmdLog(cmdprefix + cmd); ret = dorexec(nshost, user, passwd, cmd, locale); err = getstderr(); if (ret != 0) { p.setErrorLog(err); throw new pmCmdFailedException(err); } if (!err.equals("")) { p.setWarnLog(err); } return; } private static void setNS( String action, Printer p, NameService ns) throws Exception { Debug.message("SVR: DoPrinterNS.setNS(): " + action); String printername = p.getPrinterName(); String printserver = p.getPrintServer(); String extensions = p.getExtensions(); String comment = p.getComment(); boolean default_printer = p.getIsDefaultPrinter(); String nameservice = ns.getNameService(); String nshost = ns.getNameServiceHost(); String user = ns.getUser(); String passwd = ns.getPasswd(); int exitvalue; SysCommand syscmd = null; String err; String cmd = null; String cmd_log = null; String cmd_array[] = new String[14]; int index = 0; String base_cmd = "/usr/bin/lpset -n " + nameservice; String base_cmd_log = "/usr/bin/lpset -n " + nameservice; cmd_array[index++] = "/usr/bin/lpset"; cmd_array[index++] = "-n"; cmd_array[index++] = nameservice; /* * Use jni to update ldap since the passwd is sensitive. */ if (nameservice.equals("ldap")) { if ((nshost == null) || (nshost.equals(""))) { throw new pmInternalErrorException( "Missing LDAP host for ldap operation"); } if ((user == null) && (user.equals(""))) { throw new pmInternalErrorException( "Missing Binddn for ldap operation"); } if ((passwd == null) && (passwd.equals(""))) { throw new pmInternalErrorException( "Missing passwd for ldap operation"); } p.setCmdLog("ldap ..."); String def = "false"; if (default_printer) def = "true"; Debug.message("SVR: updateldap(): "); Debug.message("SVR: action=" + action); Debug.message("SVR: host=" + nshost); Debug.message("SVR: binddn=" + user); Debug.message("SVR: passwd=****"); Debug.message("SVR: printername=" + printername); Debug.message("SVR: printserver=" + printserver); Debug.message("SVR: extensions=" + extensions); Debug.message("SVR: comment=" + comment); Debug.message("SVR: default=" + def); exitvalue = updateldap(action, nshost, user, passwd, printername, printserver, extensions, comment, def); if (exitvalue != 0) { throw new pmCmdFailedException("libprint"); } return; } // // Add and modify are the same // if (!action.equals("delete")) { // // If we are here for a modify and we're only setting // the default printer ... // if (!p.modhints.equals("defaultonly")) { String bsdaddr = "bsdaddr=" + printserver + "," + printername; if (extensions != null) { bsdaddr = bsdaddr.concat("," + extensions); } cmd_array[index++] = "-a"; cmd_array[index++] = bsdaddr; cmd_log = base_cmd_log + " -a " + bsdaddr; if (comment != null) { cmd_array[index++] = "-a"; cmd_array[index++] = "description=" + comment; cmd_log = cmd_log.concat(" -a " + "description=" + "\"" + comment + "\""); } cmd_array[index++] = printername; cmd_log = cmd_log.concat(" " + printername); p.setCmdLog(cmd_log); syscmd = new SysCommand(); syscmd.exec(cmd_array); err = syscmd.getError(); if (syscmd.getExitValue() != 0) { p.setErrorLog(err); syscmd = null; throw new pmCmdFailedException(err); } else { p.setWarnLog(err); } syscmd = null; } cmd = null; cmd_log = null; String args = null; String def = DoPrinterUtil.getDefault(nameservice); if (default_printer) { if (!printername.equals(def)) { args = " -a " + "use=" + printername + " _default"; cmd = base_cmd + args; cmd_log = base_cmd_log + args; } } else { if ((def != null) && (def.equals(printername))) { // // It was the default but not any more. // args = " -x _default"; cmd = base_cmd + args; cmd_log = base_cmd_log + args; } } if (cmd != null) { p.setCmdLog(cmd_log); syscmd = new SysCommand(); syscmd.exec(cmd); err = syscmd.getError(); if (syscmd.getExitValue() != 0) { p.setErrorLog(err); syscmd = null; throw new pmCmdFailedException(err); } else { p.setWarnLog(err); } syscmd = null; } } else { if (DoPrinterUtil.exists(printername, nameservice)) { // delete cmd = base_cmd + " -x " + printername; cmd_log = base_cmd_log + " -x " + printername; p.setCmdLog(cmd_log); syscmd = new SysCommand(); syscmd.exec(cmd); err = syscmd.getError(); if (syscmd.getExitValue() != 0) { p.setErrorLog(err); syscmd = null; throw new pmCmdFailedException(err); } else { p.setWarnLog(err); } syscmd = null; } String def = DoPrinterUtil.getDefault(nameservice); if ((def != null) && (def.equals(printername))) { cmd = base_cmd + " -x _default"; cmd_log = base_cmd_log + " -x _default"; p.setCmdLog(cmd_log); syscmd = new SysCommand(); syscmd.exec(cmd); err = syscmd.getError(); if (syscmd.getExitValue() != 0) { p.setErrorLog(err); syscmd = null; throw new pmCmdFailedException(err); } else { p.setWarnLog(err); } syscmd = null; } } return; } public static boolean doAuth(NameService ns) throws Exception { Debug.message("SVR: DoPrinterNS.checkAuth()"); String nsname = ns.getNameService(); String host = ns.getNameServiceHost(); String user = ns.getUser(); String passwd = ns.getPasswd(); if (nsname.equals("system")) { if (!isRoot()) { Debug.error( "SVR: User does not have root priveleges."); throw new pmAuthException(); } } else if (nsname.equals("nis")) { Host h = new Host(); String lh = h.getLocalHostName(); String nm = h.getNisHost("master"); if (lh.equals(nm)) { // Since we are on the NIS master the // check is the same as for "system". Debug.message("SVR: Host is NIS master."); if (!isRoot()) { Debug.error( "SVR: User does not have root access."); throw new pmAuthException(); } } int ret = dorexec(host, user, passwd, "/usr/bin/echo", "C"); if (ret != 0) { Debug.error( "SVR: User does not have NIS update access."); throw new pmAuthException(getstderr()); } } else if (nsname.equals("ldap")) { int ret = updateldap("add", host, user, passwd, "_pmTestAuthToken", null, null, null, "false"); if (ret != 0) { Debug.error( "SVR: User does not have LDAP update priveleges."); throw new pmAuthException(); } ret = updateldap("delete", host, user, passwd, "_pmTestAuthToken", null, null, null, "false"); } else { throw new pmInternalErrorException( "doAuth(): Invalid name service: " + nsname); } return (true); } public static void doCheckRootPasswd(String p) throws Exception { Host h = new Host(); String lh = h.getLocalHostName(); int ret = dorexec(lh, "root", p, "/usr/bin/echo", "C"); if (ret != 0) { throw new pmAuthException(getstderr()); } return; } public static boolean isRoot() throws Exception { SysCommand syscmd = new SysCommand(); syscmd.exec("/usr/bin/id", "LC_ALL=C"); String o = syscmd.getOutput(); if (o == null) { throw new pmCmdFailedException(syscmd.getError()); } if (o.indexOf("uid=0(") == -1) { return (false); } return (true); } }