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 // 37 private synchronized static native int dorexec(String nshost, 38 String user, String passwd, String cmd, String locale); 39 private synchronized static native int updateoldyp(String action, 40 String printername, String printserver, String extensions, 41 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); 46 private synchronized static native String getstderr(); 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 // 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 // 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 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 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 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 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 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