xref: /titanic_51/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     //
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