1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * 25 * DoPrinterNS class 26 * Worker class for updating name services. 27 * Interfaces to JNI code. 28 */ 29 30 package com.sun.admin.pm.server; 31 32 public class DoPrinterNS 33 { 34 // 35 // JNI member functions 36 // dorexec(String nshost, String user, String passwd, String cmd, String locale)37 private synchronized static native int dorexec(String nshost, 38 String user, String passwd, String cmd, String locale); updateoldyp(String action, String printername, String printserver, String extensions, String comment, String isdefault)39 private synchronized static native int updateoldyp(String action, 40 String printername, String printserver, String extensions, 41 String comment, String isdefault); updateldap(String action, String host, String binddn, String passwd, String printername, String printserver, String extensions, String comment, String isdefault)42 private synchronized static native int updateldap(String action, 43 String host, String binddn, String passwd, 44 String printername, String printserver, String extensions, 45 String comment, String isdefault); getstderr()46 private synchronized static native String getstderr(); getstdout()47 private synchronized static native String getstdout(); 48 49 // 50 // Load JNI. 51 // 52 static 53 { 54 System.loadLibrary("pmgr"); 55 } 56 57 // 58 // main for testing 59 // main(String[] args)60 public static void main(String[] args) { 61 // 62 // Set attributes for testing. 63 // 64 NameService ns = null; 65 try { 66 ns = new NameService("nis"); 67 } 68 catch (Exception e) { 69 System.out.println(e); 70 System.exit(1); 71 } 72 ns.setPasswd(""); 73 74 Printer p = new Printer(ns); 75 p.setPrinterName("javatest"); 76 p.setPrintServer("zelkova"); 77 p.setComment("This is a comment"); 78 p.setIsDefaultPrinter(false); 79 p.setLocale(null); 80 81 String action = "add"; 82 if (args.length >= 1) 83 action = args[0]; 84 try { 85 set(action, p, ns); 86 } 87 catch (Exception e) { 88 System.out.println(e); 89 } 90 System.out.println("Commands:\n" + p.getCmdLog()); 91 System.out.println("Errors:\n" + p.getErrorLog()); 92 System.out.println("Warnings:\n" + p.getWarnLog()); 93 System.exit(0); 94 } 95 96 // 97 // Interface to DoPrinter[add|mod|delete] 98 // set( String action, Printer p, NameService ns)99 public static void set( 100 String action, 101 Printer p, 102 NameService ns) throws Exception 103 { 104 String nameservice = ns.getNameService(); 105 106 if (nameservice.equals("system")) { 107 return; 108 } else if (nameservice.equals("nis")) { 109 setNIS(action, p, ns); 110 return; 111 } 112 setNS(action, p, ns); 113 return; 114 } 115 setNIS( String action, Printer p, NameService ns)116 private static void setNIS( 117 String action, 118 Printer p, 119 NameService ns) throws Exception 120 { 121 Debug.message("SVR: DoPrinterNS.setNIS(): " + action); 122 123 String printername = p.getPrinterName(); 124 String printserver = p.getPrintServer(); 125 String comment = p.getComment(); 126 String extensions = p.getExtensions(); 127 boolean default_printer = p.getIsDefaultPrinter(); 128 String locale = p.getLocale(); 129 if (locale == null) 130 locale = "C"; 131 132 String nameservice = ns.getNameService(); 133 String nshost = ns.getNameServiceHost(); 134 String user = ns.getUser(); 135 String passwd = ns.getPasswd(); 136 137 String cmd = null; 138 String err = null; 139 int ret = 0; 140 int exitvalue = 0; 141 142 // 143 // If this is the nis master we only need to do the make 144 // locally. 145 // 146 Host h = new Host(); 147 String lh = h.getLocalHostName(); 148 if (lh.equals(nshost)) { 149 cmd = "/usr/ccs/bin/make -f /var/yp/Makefile"; 150 cmd = cmd.concat(" -f /usr/lib/print/Makefile.yp "); 151 cmd = cmd.concat("printers.conf"); 152 153 p.setCmdLog(cmd); 154 SysCommand syscmd = new SysCommand(); 155 syscmd.exec(cmd); 156 157 err = syscmd.getError(); 158 if (syscmd.getExitValue() != 0) { 159 p.setErrorLog(err); 160 syscmd = null; 161 throw new pmCmdFailedException(err); 162 } else { 163 // ignore touch warning 164 // p.setWarnLog(err); 165 } 166 syscmd = null; 167 return; 168 } 169 170 String cmdprefix = "rexec(" + nshost + "): "; 171 172 cmd = "/usr/bin/echo"; 173 Debug.message("SVR: " + cmdprefix + cmd); 174 ret = dorexec(nshost, user, passwd, cmd, locale); 175 if (ret != 0) { 176 throw new pmAuthException(getstderr()); 177 } 178 // 179 // Do we have lpset 180 // 181 cmd = "/usr/bin/ls /usr/bin/lpset"; 182 Debug.message("SVR: " + cmdprefix + cmd); 183 ret = dorexec(nshost, user, passwd, cmd, locale); 184 if (ret != 0) { 185 throw new pmCmdFailedException(getstderr()); 186 } 187 String tmpstr = getstdout(); 188 tmpstr = tmpstr.trim(); 189 if (!tmpstr.equals("/usr/bin/lpset")) { 190 Debug.message("SVR: No lpset found. Checking rhosts."); 191 192 // Are we set up in rhosts? 193 cmd = "rsh "; 194 cmd = cmd.concat(nshost); 195 cmd = cmd.concat(" echo"); 196 197 SysCommand syscmd = new SysCommand(); 198 syscmd.exec(cmd); 199 err = syscmd.getError(); 200 if (syscmd.getExitValue() != 0) { 201 syscmd = null; 202 throw new pmAuthRhostException(err); 203 } 204 syscmd = null; 205 // 206 // We don't have lpset. Must be pre-2.6 master. 207 // We are set up in rhosts so use libprint 208 // to update it. 209 // 210 p.setCmdLog("rsh " + nshost + "..."); 211 String def = "false"; 212 if (default_printer) 213 def = "true"; 214 215 Debug.message("SVR: updateoldyp(): "); 216 Debug.message("SVR: action=" + action); 217 Debug.message("SVR: printername=" + printername); 218 Debug.message("SVR: printserver=" + printserver); 219 Debug.message("SVR: extensions=" + extensions); 220 Debug.message("SVR: comment=" + comment); 221 Debug.message("SVR: default=" + def); 222 223 ret = updateoldyp(action, printername, 224 printserver, extensions, comment, def); 225 if (ret != 0) { 226 throw new pmCmdFailedException("libprint"); 227 } 228 return; 229 } 230 231 // 232 // Add and modify are the same 233 // 234 boolean domake = false; 235 if (!action.equals("delete")) { 236 // 237 // If we are here from a modify and only need 238 // to change the default printer ... 239 // 240 if (!p.modhints.equals("defaultonly")) { 241 String bsdaddr = "bsdaddr=" + printserver + "," + 242 printername; 243 if (extensions != null) { 244 bsdaddr = bsdaddr.concat("," + extensions); 245 } 246 cmd = "/usr/bin/lpset -a " + bsdaddr; 247 if (comment != null) { 248 cmd = cmd.concat(" -a " + "description=" + 249 "\"" + comment + "\""); 250 } 251 cmd = cmd.concat(" " + printername); 252 253 Debug.message("SVR: " + cmdprefix + cmd); 254 p.setCmdLog(cmdprefix + cmd); 255 ret = dorexec(nshost, user, passwd, cmd, locale); 256 err = getstderr(); 257 if (ret != 0) { 258 p.setErrorLog(err); 259 throw new pmCmdFailedException(err); 260 } 261 if (!err.equals("")) { 262 p.setWarnLog(err); 263 } 264 domake = true; 265 } 266 267 cmd = null; 268 String def = DoPrinterUtil.getDefault("nis"); 269 if (default_printer) { 270 if (!printername.equals(def)) { 271 cmd = "/usr/bin/lpset -a " + "use=" + 272 printername + " _default"; 273 } 274 } else { 275 if ((def != null) && (def.equals(printername))) { 276 // 277 // It was the default but not any more. 278 // 279 cmd = "/usr/bin/lpset -x _default"; 280 } 281 } 282 if (cmd != null) { 283 Debug.message("SVR: " + cmdprefix + cmd); 284 p.setCmdLog(cmdprefix + cmd); 285 ret = dorexec(nshost, user, passwd, cmd, locale); 286 err = getstderr(); 287 if (ret != 0) { 288 p.setErrorLog(err); 289 throw new pmCmdFailedException(err); 290 } 291 if (!err.equals("")) { 292 p.setWarnLog(err); 293 } 294 domake = true; 295 } 296 } else { 297 if (DoPrinterUtil.exists(printername, "nis")) { 298 // delete 299 cmd = "/usr/bin/lpset -x " + printername; 300 Debug.message("SVR: " + cmdprefix + cmd); 301 p.setCmdLog(cmdprefix + cmd); 302 ret = dorexec(nshost, user, passwd, cmd, locale); 303 err = getstderr(); 304 if (ret != 0) { 305 p.setErrorLog(err); 306 throw new pmCmdFailedException(err); 307 } 308 if (!err.equals("")) { 309 p.setWarnLog(err); 310 } 311 domake = true; 312 } 313 String def = DoPrinterUtil.getDefault("nis"); 314 if ((def != null) && (def.equals(printername))) { 315 cmd = "/usr/bin/lpset -x _default"; 316 Debug.message("SVR: " + cmdprefix + cmd); 317 p.setCmdLog(cmdprefix + cmd); 318 ret = dorexec(nshost, user, passwd, cmd, locale); 319 err = getstderr(); 320 if (ret != 0) { 321 p.setErrorLog(err); 322 throw new pmCmdFailedException(err); 323 } 324 if (!err.equals("")) { 325 p.setWarnLog(err); 326 } 327 domake = true; 328 } 329 } 330 if (!domake) { 331 return; 332 } 333 334 cmd = "cd /var/yp; /usr/ccs/bin/make -f /var/yp/Makefile"; 335 cmd = cmd.concat(" -f /usr/lib/print/Makefile.yp printers.conf"); 336 Debug.message("SVR: " + cmdprefix + cmd); 337 p.setCmdLog(cmdprefix + cmd); 338 ret = dorexec(nshost, user, passwd, cmd, locale); 339 err = getstderr(); 340 if (ret != 0) { 341 p.setErrorLog(err); 342 throw new pmCmdFailedException(err); 343 } 344 if (!err.equals("")) { 345 p.setWarnLog(err); 346 } 347 return; 348 } 349 setNS( String action, Printer p, NameService ns)350 private static void setNS( 351 String action, 352 Printer p, 353 NameService ns) throws Exception 354 { 355 Debug.message("SVR: DoPrinterNS.setNS(): " + action); 356 357 String printername = p.getPrinterName(); 358 String printserver = p.getPrintServer(); 359 String extensions = p.getExtensions(); 360 String comment = p.getComment(); 361 boolean default_printer = p.getIsDefaultPrinter(); 362 363 String nameservice = ns.getNameService(); 364 365 String nshost = ns.getNameServiceHost(); 366 String user = ns.getUser(); 367 String passwd = ns.getPasswd(); 368 369 int exitvalue; 370 SysCommand syscmd = null; 371 String err; 372 String cmd = null; 373 String cmd_log = null; 374 String cmd_array[] = new String[14]; 375 376 int index = 0; 377 String base_cmd = "/usr/bin/lpset -n " + nameservice; 378 String base_cmd_log = "/usr/bin/lpset -n " + nameservice; 379 380 cmd_array[index++] = "/usr/bin/lpset"; 381 cmd_array[index++] = "-n"; 382 cmd_array[index++] = nameservice; 383 384 /* 385 * Use jni to update ldap since the passwd is sensitive. 386 */ 387 if (nameservice.equals("ldap")) { 388 389 if ((nshost == null) || (nshost.equals(""))) { 390 throw new pmInternalErrorException( 391 "Missing LDAP host for ldap operation"); 392 } 393 if ((user == null) && (user.equals(""))) { 394 throw new pmInternalErrorException( 395 "Missing Binddn for ldap operation"); 396 } 397 if ((passwd == null) && (passwd.equals(""))) { 398 throw new pmInternalErrorException( 399 "Missing passwd for ldap operation"); 400 } 401 402 p.setCmdLog("ldap ..."); 403 404 String def = "false"; 405 if (default_printer) 406 def = "true"; 407 408 Debug.message("SVR: updateldap(): "); 409 Debug.message("SVR: action=" + action); 410 Debug.message("SVR: host=" + nshost); 411 Debug.message("SVR: binddn=" + user); 412 Debug.message("SVR: passwd=****"); 413 Debug.message("SVR: printername=" + printername); 414 Debug.message("SVR: printserver=" + printserver); 415 Debug.message("SVR: extensions=" + extensions); 416 Debug.message("SVR: comment=" + comment); 417 Debug.message("SVR: default=" + def); 418 419 exitvalue = updateldap(action, nshost, user, passwd, 420 printername, printserver, extensions, comment, 421 def); 422 423 if (exitvalue != 0) { 424 throw new pmCmdFailedException("libprint"); 425 } 426 return; 427 } 428 429 // 430 // Add and modify are the same 431 // 432 if (!action.equals("delete")) { 433 // 434 // If we are here for a modify and we're only setting 435 // the default printer ... 436 // 437 if (!p.modhints.equals("defaultonly")) { 438 String bsdaddr = "bsdaddr=" + printserver + "," + 439 printername; 440 if (extensions != null) { 441 bsdaddr = bsdaddr.concat("," + extensions); 442 } 443 cmd_array[index++] = "-a"; 444 cmd_array[index++] = bsdaddr; 445 cmd_log = base_cmd_log + " -a " + bsdaddr; 446 if (comment != null) { 447 cmd_array[index++] = "-a"; 448 cmd_array[index++] = "description=" + comment; 449 cmd_log = cmd_log.concat(" -a " + 450 "description=" + "\"" + comment + "\""); 451 } 452 cmd_array[index++] = printername; 453 cmd_log = cmd_log.concat(" " + printername); 454 455 p.setCmdLog(cmd_log); 456 syscmd = new SysCommand(); 457 syscmd.exec(cmd_array); 458 err = syscmd.getError(); 459 if (syscmd.getExitValue() != 0) { 460 p.setErrorLog(err); 461 syscmd = null; 462 throw new pmCmdFailedException(err); 463 } else { 464 p.setWarnLog(err); 465 } 466 syscmd = null; 467 } 468 cmd = null; 469 cmd_log = null; 470 String args = null; 471 String def = DoPrinterUtil.getDefault(nameservice); 472 if (default_printer) { 473 if (!printername.equals(def)) { 474 args = " -a " + "use=" + printername + 475 " _default"; 476 cmd = base_cmd + args; 477 cmd_log = base_cmd_log + args; 478 } 479 } else { 480 if ((def != null) && (def.equals(printername))) { 481 // 482 // It was the default but not any more. 483 // 484 args = " -x _default"; 485 cmd = base_cmd + args; 486 cmd_log = base_cmd_log + args; 487 } 488 } 489 if (cmd != null) { 490 p.setCmdLog(cmd_log); 491 syscmd = new SysCommand(); 492 syscmd.exec(cmd); 493 err = syscmd.getError(); 494 if (syscmd.getExitValue() != 0) { 495 p.setErrorLog(err); 496 syscmd = null; 497 throw new pmCmdFailedException(err); 498 } else { 499 p.setWarnLog(err); 500 } 501 syscmd = null; 502 } 503 } else { 504 if (DoPrinterUtil.exists(printername, nameservice)) { 505 // delete 506 cmd = base_cmd + " -x " + printername; 507 cmd_log = base_cmd_log + " -x " + printername; 508 p.setCmdLog(cmd_log); 509 syscmd = new SysCommand(); 510 syscmd.exec(cmd); 511 err = syscmd.getError(); 512 if (syscmd.getExitValue() != 0) { 513 p.setErrorLog(err); 514 syscmd = null; 515 throw new pmCmdFailedException(err); 516 } else { 517 p.setWarnLog(err); 518 } 519 syscmd = null; 520 521 } 522 String def = DoPrinterUtil.getDefault(nameservice); 523 if ((def != null) && (def.equals(printername))) { 524 cmd = base_cmd + " -x _default"; 525 cmd_log = base_cmd_log + " -x _default"; 526 p.setCmdLog(cmd_log); 527 syscmd = new SysCommand(); 528 syscmd.exec(cmd); 529 err = syscmd.getError(); 530 if (syscmd.getExitValue() != 0) { 531 p.setErrorLog(err); 532 syscmd = null; 533 throw new pmCmdFailedException(err); 534 } else { 535 p.setWarnLog(err); 536 } 537 syscmd = null; 538 } 539 } 540 return; 541 } 542 doAuth(NameService ns)543 public static boolean doAuth(NameService ns) throws Exception 544 { 545 Debug.message("SVR: DoPrinterNS.checkAuth()"); 546 547 String nsname = ns.getNameService(); 548 String host = ns.getNameServiceHost(); 549 String user = ns.getUser(); 550 String passwd = ns.getPasswd(); 551 552 if (nsname.equals("system")) { 553 if (!isRoot()) { 554 Debug.error( 555 "SVR: User does not have root priveleges."); 556 throw new pmAuthException(); 557 } 558 } else if (nsname.equals("nis")) { 559 Host h = new Host(); 560 String lh = h.getLocalHostName(); 561 String nm = h.getNisHost("master"); 562 if (lh.equals(nm)) { 563 // Since we are on the NIS master the 564 // check is the same as for "system". 565 Debug.message("SVR: Host is NIS master."); 566 if (!isRoot()) { 567 Debug.error( 568 "SVR: User does not have root access."); 569 throw new pmAuthException(); 570 } 571 } 572 int ret = dorexec(host, user, passwd, "/usr/bin/echo", "C"); 573 if (ret != 0) { 574 Debug.error( 575 "SVR: User does not have NIS update access."); 576 throw new pmAuthException(getstderr()); 577 } 578 } else if (nsname.equals("ldap")) { 579 int ret = updateldap("add", host, user, passwd, 580 "_pmTestAuthToken", null, null, null, "false"); 581 582 if (ret != 0) { 583 Debug.error( 584 "SVR: User does not have LDAP update priveleges."); 585 throw new pmAuthException(); 586 } 587 ret = updateldap("delete", host, user, passwd, 588 "_pmTestAuthToken", null, null, null, "false"); 589 590 } else { 591 throw new pmInternalErrorException( 592 "doAuth(): Invalid name service: " + nsname); 593 } 594 return (true); 595 } 596 doCheckRootPasswd(String p)597 public static void doCheckRootPasswd(String p) 598 throws Exception 599 { 600 Host h = new Host(); 601 String lh = h.getLocalHostName(); 602 603 int ret = dorexec(lh, "root", p, "/usr/bin/echo", "C"); 604 if (ret != 0) { 605 throw new pmAuthException(getstderr()); 606 } 607 return; 608 } 609 isRoot()610 public static boolean isRoot() 611 throws Exception 612 { 613 SysCommand syscmd = new SysCommand(); 614 syscmd.exec("/usr/bin/id", "LC_ALL=C"); 615 616 String o = syscmd.getOutput(); 617 618 if (o == null) { 619 throw new pmCmdFailedException(syscmd.getError()); 620 } 621 if (o.indexOf("uid=0(") == -1) { 622 return (false); 623 } 624 return (true); 625 } 626 } 627