xref: /titanic_44/usr/src/cmd/print/printmgr/com/sun/admin/pm/server/DoPrinterNS.java (revision 36e852a172cba914383d7341c988128b2c667fbd)
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