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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 #pragma ident	"%Z%%M%	%I%	%E% SMI"
23 /*
24  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
28 /*LINTLIBRARY*/
29 
30 #include <stdio.h>
31 #include <errno.h>
32 #include <string.h>
33 #include <netdb.h>
34 #include <unistd.h>
35 #include <stdlib.h>
36 #include <arpa/inet.h>
37 #include <rpcsvc/ypclnt.h>
38 
39 char glob_stdout[BUFSIZ];
40 char glob_stderr[BUFSIZ];
41 
42 void f_cleanup(FILE *fp, char *tmpf);
43 void fd_cleanup(int fd1, int fd2);
44 static void _freeList(char ***list);
45 
46 extern void **list_append(void **list, void *item);
47 
48 #ifdef MAIN
49 
50 #define	THOSTNAME "cherwell"
51 #define	TPRINTERNAME "c"
52 
53 int
main()54 main() {
55 	char *host = THOSTNAME;
56 	const char *user = "cn=Directory Manager";
57 	const char *passwd = "directorymanager";
58 	int result = 0;
59 
60 	result = _updateldap("add", host, user, passwd,
61 		    "_pmTestAuthToken", NULL, NULL, "new comment", "false");
62 	if (result != 0) {
63 		printf("Add 1 failed, err code = %d\n");
64 	}
65 
66 	result = _updateldap("delete", host, user, passwd,
67 		    "_pmTestAuthToken", NULL, NULL, NULL, "false");
68 	if (result != 0) {
69 		printf("Delete 1 failed, err code = %d\n");
70 	}
71 
72 	result = _updateldap("delete", host, user, passwd, TPRINTERNAME,
73 			THOSTNAME, "", "new comment", "true");
74 	if (result != 0) {
75 		printf("delete failed, err code = %d\n");
76 	}
77 
78 	result = _updateldap("delete", host, user, passwd, "_default",
79 			THOSTNAME, "", "new comment", "true");
80 	if (result != 0) {
81 		printf("delete failed, err code = %d\n");
82 	}
83 
84 	result = _updateldap("add", host, user, passwd, TPRINTERNAME,
85 			THOSTNAME, "Solaris", "new comment", "true");
86 	if (result != 0) {
87 		printf("add failed, err code = %d\n");
88 	}
89 
90 	result = _updateldap("modify", host, user, passwd, TPRINTERNAME,
91 			THOSTNAME, "", "modified comment", "true");
92 	if (result != 0) {
93 		printf("modify failed, err code = %d\n");
94 	}
95 
96 	result = _updateldap("modify", host, user, passwd, TPRINTERNAME,
97 			THOSTNAME, "", NULL, "false");
98 	if (result != 0) {
99 		printf("modify failed, err code = %d\n");
100 	}
101 
102 
103 	exit(0);
104 }
105 #endif
106 
107 
108 int
_dorexec(const char * host,const char * user,const char * passwd,const char * cmd,const char * locale)109 _dorexec(
110 	const char *host,
111 	const char *user,
112 	const char *passwd,
113 	const char *cmd,
114 	const char *locale) {
115 
116 	int ret = 0;
117 	int fd = 0;
118 	int fd2 = 1;
119 
120 	FILE *fderr;
121 	char *ferr;
122 
123 	(void) memset(glob_stdout, 0, BUFSIZ);
124 	(void) memset(glob_stderr, 0, BUFSIZ);
125 
126 	/*
127 	 * Re-direct stderr to a file
128 	 */
129 	ferr = tempnam(NULL, NULL);
130 	if (ferr != NULL) {
131 		fderr = freopen(ferr, "w+", stderr);
132 	}
133 
134 	fd = rexec((char **)&host, htons(512), user,
135 	    passwd, cmd, &fd2);
136 
137 	if (fd > -1) {
138 		/*
139 		 * rexec worked. Clean up stderr file.
140 		 */
141 		f_cleanup(fderr, ferr);
142 
143 		ret = read(fd, glob_stdout, BUFSIZ - 1);
144 		if (ret < 0) {
145 			(void) strncpy(glob_stderr, strerror(errno),
146 			    (BUFSIZ - 1));
147 			fd_cleanup(fd, fd2);
148 			return (errno);
149 		}
150 
151 		ret = read(fd2, glob_stderr, BUFSIZ - 1);
152 		if (ret < 0) {
153 			(void) strncpy(glob_stderr, strerror(errno),
154 			    (BUFSIZ - 1));
155 			fd_cleanup(fd, fd2);
156 			return (errno);
157 		}
158 	} else {
159 		/*
160 		 * rexec failed. Read from the stderr file.
161 		 */
162 		if (fderr != NULL) {
163 			char tmpbuf[BUFSIZ];
164 
165 			(void) rewind(fderr);
166 			strcpy(glob_stderr, "");
167 			while (fgets(tmpbuf, BUFSIZ - 1,
168 			    fderr) != NULL) {
169 				if ((strlen(glob_stderr) +
170 				    strlen(tmpbuf)) > BUFSIZ - 1) {
171 					break;
172 				} else {
173 					(void) strcat(glob_stderr, tmpbuf);
174 				}
175 			}
176 		}
177 		f_cleanup(fderr, ferr);
178 		fd_cleanup(fd, fd2);
179 		return (1);
180 	}
181 	fd_cleanup(fd, fd2);
182 	return (0);
183 }
184 
185 void
fd_cleanup(int fd,int fd2)186 fd_cleanup(int fd, int fd2)
187 {
188 	if (fd > 0) {
189 		(void) close(fd);
190 	}
191 	if (fd2 > 0) {
192 		(void) close(fd2);
193 	}
194 }
195 
196 void
f_cleanup(FILE * fp,char * tmpf)197 f_cleanup(FILE *fp, char *tmpf)
198 {
199 	if (fp != NULL) {
200 		(void) fclose(fp);
201 	}
202 	if (tmpf != NULL) {
203 		(void) unlink(tmpf);
204 		(void) free(tmpf);
205 	}
206 }
207 
208 struct ns_bsd_addr {
209 	char  *server;		/* server name */
210 	char  *printer;		/* printer name or NULL */
211 	char  *extension;	/* RFC-1179 conformance */
212 	char  *pname;		/* Local printer name */
213 };
214 typedef struct ns_bsd_addr ns_bsd_addr_t;
215 
216 /* Key/Value pair structure */
217 struct ns_kvp {
218 	char *key;	/* key */
219 	void *value;	/* value converted */
220 };
221 typedef struct ns_kvp ns_kvp_t;
222 
223 /*
224  * Information needed to update a name service.
225  * Currently only used for ldap. (see lib/print/ns.h)
226  */
227 
228 /* LDAP bind password security type */
229 
230 typedef enum NS_PASSWD_TYPE {
231 	NS_PW_INSECURE = 0,
232 	NS_PW_SECURE = 1
233 } NS_PASSWD_TYPE;
234 
235 
236 struct ns_cred {
237 	char	*binddn;
238 	char	*passwd;
239 	char	*host;
240 	int	port;			/* LDAP port, 0 = default */
241 	NS_PASSWD_TYPE passwdType;	/* password security type */
242 	uchar_t  *domainDN;		/* NS domain DN */
243 };
244 typedef struct ns_cred ns_cred_t;
245 
246 /* LDAP specific NS Data */
247 
248 typedef struct NS_LDAPDATA {
249 	char **attrList;	/* list of user defined Key Value Pairs */
250 } NS_LDAPDATA;
251 
252 /* Printer Object structure */
253 struct ns_printer {
254 	char	*name;		/* primary name of printer */
255 	char	**aliases;	/* aliases for printer */
256 	char	*source;	/* name service derived from */
257 	ns_kvp_t	**attributes;	/* key/value pairs. */
258 	ns_cred_t	*cred;	/* info to update name service */
259 	void	*nsdata;	/* name service specific data */
260 };
261 typedef struct ns_printer ns_printer_t;
262 
263 extern ns_printer_t *ns_printer_get_name(const char *, const char *);
264 extern int ns_printer_put(const ns_printer_t *);
265 extern char *ns_get_value_string(const char *, const ns_printer_t *);
266 extern int ns_set_value(const char *, const void *, ns_printer_t *);
267 extern int ns_set_value_from_string(const char *, const char *,
268 					ns_printer_t *);
269 extern ns_bsd_addr_t *bsd_addr_create(const char *, const char *,
270 					const char *);
271 extern char *bsd_addr_to_string(const ns_bsd_addr_t *);
272 extern void ns_printer_destroy(ns_printer_t *);
273 
274 int
_updateoldyp(const char * action,const char * printername,const char * printserver,const char * extensions,const char * comment,const char * isdefault)275 _updateoldyp(
276 	const char *action,
277 	const char *printername,
278 	const char *printserver,
279 	const char *extensions,
280 	const char *comment,
281 	const char *isdefault) {
282 
283 	ns_printer_t *printer;
284 	ns_bsd_addr_t *addr;
285 	int status = 0;
286 
287 	char mkcmd[BUFSIZ];
288 	char *domain = NULL;
289 	char *host = NULL;
290 
291 	/*
292 	 * libprint returns before we know that the printers.conf
293 	 * map is made. So we'll make it again.
294 	 */
295 	(void) yp_get_default_domain(&domain);
296 
297 	if ((yp_master(domain, "printers.conf.byname", &host) != 0) &&
298 	    (yp_master(domain, "passwd.byname", &host) != 0)) {
299 		strcpy(mkcmd, "/usr/bin/sleep 1");
300 	} else {
301 		sprintf(mkcmd, "/usr/bin/rsh -n %s 'cd /var/yp; "
302 				"/usr/ccs/bin/make -f /var/yp/Makefile "
303 				"-f /var/yp/Makefile.print printers.conf "
304 				"> /dev/null'", host);
305 	}
306 
307 	if (strcmp(action, "delete") == 0) {
308 		if ((printer = (ns_printer_t *)
309 		    ns_printer_get_name(printername, "nis")) == NULL) {
310 			return (0);
311 		}
312 
313 		printer->attributes = NULL;
314 		status = ns_printer_put(printer);
315 		if (status != 0) {
316 			(void) free(printer);
317 			return (status);
318 		}
319 
320 		if ((printer = (ns_printer_t *)
321 		    ns_printer_get_name("_default", "nis")) != NULL) {
322 			char *dflt = (char *)
323 			    ns_get_value_string("use", printer);
324 			if ((dflt != NULL) &&
325 			    (strcmp(dflt, printername) == 0)) {
326 				printer->attributes = NULL;
327 				status = ns_printer_put(printer);
328 				if (status != 0) {
329 					(void) free(printer);
330 					return (status);
331 				}
332 			}
333 		}
334 		(void) free(printer);
335 		(void) system(mkcmd);
336 		return (0);
337 
338 	} else if (strcmp(action, "add") == 0) {
339 		printer = (ns_printer_t *)malloc(sizeof (*printer));
340 		memset(printer, 0, sizeof (*printer));
341 		printer->name = (char *)printername;
342 		printer->source = "nis";
343 
344 		addr = (ns_bsd_addr_t *)malloc(sizeof (*addr));
345 		memset(addr, 0, sizeof (*addr));
346 		addr->printer = (char *)printername;
347 		addr->server = (char *)printserver;
348 		if ((extensions != NULL) &&
349 		    (strlen(extensions) > 0)) {
350 			addr->extension = (char *)extensions;
351 		}
352 		ns_set_value("bsdaddr", addr, printer);
353 
354 		if ((comment != NULL) && (strlen(comment) > 0)) {
355 			ns_set_value_from_string("description",
356 			    comment, printer);
357 		}
358 		status = ns_printer_put(printer);
359 		if (status != 0) {
360 			(void) free(addr);
361 			(void) free(printer);
362 			return (status);
363 		}
364 
365 		if (strcmp(isdefault, "true") == 0) {
366 			printer->name = "_default";
367 			printer->attributes = NULL;
368 			ns_set_value_from_string("use", printername, printer);
369 			status = ns_printer_put(printer);
370 			if (status != 0) {
371 				(void) free(addr);
372 				(void) free(printer);
373 				return (status);
374 			}
375 		}
376 		(void) free(addr);
377 		(void) free(printer);
378 		(void) system(mkcmd);
379 		return (0);
380 	}
381 
382 	/*
383 	 * Modify
384 	 */
385 	if ((printer = (ns_printer_t *)
386 	    ns_printer_get_name(printername, "nis")) == NULL) {
387 		return (1);
388 	}
389 	if ((comment != NULL) && (strlen(comment) > 0)) {
390 		ns_set_value_from_string("description", comment, printer);
391 	} else {
392 		ns_set_value_from_string("description",
393 		    NULL, printer);
394 	}
395 	status = ns_printer_put(printer);
396 	if (status != 0) {
397 		(void) free(printer);
398 		return (status);
399 	}
400 
401 	if ((printer = (ns_printer_t *)
402 	    ns_printer_get_name("_default", "nis")) != NULL) {
403 		char *dflt = (char *)ns_get_value_string("use", printer);
404 		if (strcmp(printername, dflt) == 0) {
405 			if (strcmp(isdefault, "false") == 0) {
406 				/*
407 				 * We were the default printer but not
408 				 * any more.
409 				 */
410 				printer->attributes = NULL;
411 				status = ns_printer_put(printer);
412 				if (status != 0) {
413 					(void) free(printer);
414 					return (status);
415 				}
416 			}
417 		} else {
418 			if (strcmp(isdefault, "true") == 0) {
419 				ns_set_value_from_string("use",
420 				    printername, printer);
421 				status = ns_printer_put(printer);
422 				if (status != 0) {
423 					(void) free(printer);
424 					return (status);
425 				}
426 			}
427 		}
428 	} else {
429 		printer = (ns_printer_t *)malloc(sizeof (*printer));
430 		memset(printer, 0, sizeof (*printer));
431 		printer->name = "_default";
432 		printer->source = "nis";
433 		ns_set_value_from_string("use", printername, printer);
434 		status = ns_printer_put(printer);
435 		if (status != 0) {
436 			(void) free(printer);
437 			return (status);
438 		}
439 	}
440 	(void) system(mkcmd);
441 	return (0);
442 }
443 
444 int
_updateldap(const char * action,const char * host,const char * binddn,const char * passwd,const char * printername,const char * printserver,const char * extensions,const char * comment,const char * isdefault)445 _updateldap(
446 	const char *action,
447 	const char *host,
448 	const char *binddn,
449 	const char *passwd,
450 	const char *printername,
451 	const char *printserver,
452 	const char *extensions,
453 	const char *comment,
454 	const char *isdefault)
455 
456 {
457 	ns_printer_t *printer;
458 	ns_bsd_addr_t *addr;
459 	ns_cred_t *cred;
460 
461 	char *item = NULL;
462 	char **attrList = NULL;
463 
464 	int status;
465 
466 	if (printserver == NULL) {
467 		/* printserver not given so use host */
468 		printserver = host;
469 	}
470 
471 	cred = (ns_cred_t *)malloc(sizeof (*cred));
472 	(void) memset(cred, '\0', sizeof (*cred));
473 	cred->passwd = strdup((char *)passwd);
474 	cred->binddn = strdup((char *)binddn);
475 	cred->host = strdup((char *)host);
476 
477 	cred->passwdType = NS_PW_INSECURE; /* use default */
478 	cred->port = 0;		/* use default */
479 	cred->domainDN = NULL;	/* use default */
480 
481 	if (strcmp(action, "delete") == 0) {
482 		/*
483 		 * Delete printer object from LDAP directory DIT
484 		 */
485 
486 		if ((printer = (ns_printer_t *)
487 		    ns_printer_get_name(printername, "ldap")) == NULL) {
488 			return (0);
489 		}
490 
491 		printer->attributes = NULL;
492 		printer->nsdata = malloc(sizeof (NS_LDAPDATA));
493 		if (printer->nsdata == NULL) {
494 			return (1);
495 		}
496 		((NS_LDAPDATA *)(printer->nsdata))->attrList = NULL;
497 		printer->cred = cred;
498 		printer->source = strdup("ldap");
499 		status = ns_printer_put(printer);
500 		free(printer->nsdata);
501 		(void) ns_printer_destroy(printer);
502 
503 		if (status != 0) {
504 			return (status);
505 		}
506 
507 		if ((printer = (ns_printer_t *)
508 		    ns_printer_get_name("_default", "ldap")) != NULL) {
509 			char *dflt = (char *)
510 			    ns_get_value_string("use", printer);
511 			if ((dflt != NULL) &&
512 			    (strcmp(dflt, printername) == 0)) {
513 				printer->attributes = NULL;
514 				printer->nsdata = malloc(sizeof (NS_LDAPDATA));
515 				if (printer->nsdata == NULL) {
516 					(void) ns_printer_destroy(printer);
517 					return (1);
518 				}
519 		((NS_LDAPDATA *)(printer->nsdata))->attrList = NULL;
520 				printer->cred = cred;
521 				printer->source = strdup("ldap");
522 				status = ns_printer_put(printer);
523 				free(printer->nsdata);
524 				if (status != 0) {
525 					(void) ns_printer_destroy(printer);
526 					return (status);
527 				}
528 			}
529 
530 			(void) ns_printer_destroy(printer);
531 		}
532 		return (0);
533 
534 	} else if (strcmp(action, "add") == 0) {
535 		/*
536 		 * Add new printer object into LDAP directory DIT
537 		 */
538 
539 		printer = (ns_printer_t *)malloc(sizeof (*printer));
540 		if (printer == NULL) {
541 			return (1);
542 		}
543 		(void) memset(printer, 0, sizeof (*printer));
544 		printer->name = strdup((char *)printername);
545 		printer->source = strdup("ldap");
546 
547 		printer->cred = cred;
548 
549 		/* set BSD address in attribute list */
550 
551 		if (extensions == NULL) {
552 			item = (char *)malloc(strlen("bsdaddr") +
553 						strlen(printserver) +
554 						strlen(printername) +
555 						strlen("Solaris") + 6);
556 		} else {
557 			item = (char *)malloc(strlen("bsdaddr") +
558 						strlen(printserver) +
559 						strlen(printername) +
560 						strlen(extensions) + 6);
561 		}
562 		if (item == NULL) {
563 			(void) ns_printer_destroy(printer);
564 			return (1);
565 		}
566 
567 		if (extensions == NULL) {
568 			sprintf(item, "%s=%s,%s,%s", "bsdaddr",
569 				printserver, printername, "Solaris");
570 		} else {
571 			sprintf(item, "%s=%s,%s,%s", "bsdaddr",
572 				printserver, printername, extensions);
573 		}
574 
575 		attrList = (char **)list_append((void**)attrList,
576 						(void *)item);
577 		if ((comment != NULL) && (strlen(comment) > 0)) {
578 			item = (char *)malloc(strlen("description") +
579 							strlen(comment) + 4);
580 			if (item == NULL) {
581 				(void) ns_printer_destroy(printer);
582 				return (1);
583 			}
584 			sprintf(item, "%s=%s", "description", comment);
585 			attrList = (char **)list_append((void**)attrList,
586 							(void *)item);
587 		}
588 
589 		printer->attributes = NULL;
590 		printer->nsdata = malloc(sizeof (NS_LDAPDATA) + 2);
591 		if (printer->nsdata == NULL) {
592 			(void) ns_printer_destroy(printer);
593 			return (1);
594 		}
595 		((NS_LDAPDATA *)(printer->nsdata))->attrList = attrList;
596 
597 		status = ns_printer_put(printer);
598 		_freeList(&attrList);
599 		if (status != 0) {
600 			free(printer->nsdata);
601 			(void) ns_printer_destroy(printer);
602 			return (status);
603 		}
604 
605 		if (strcmp(isdefault, "true") == 0) {
606 			(void) free(printer->name);
607 
608 			printer->name = strdup("_default");
609 			printer->attributes = NULL;
610 
611 			attrList = NULL;
612 			item = (char *)malloc(strlen("use") +
613 						strlen(printername) + 4);
614 			if (item == NULL) {
615 				(void) ns_printer_destroy(printer);
616 				return (1);
617 			}
618 			sprintf(item, "%s=%s", "use", printername);
619 			attrList = (char **)list_append((void**)attrList,
620 							(void *)item);
621 
622 			((NS_LDAPDATA *)(printer->nsdata))->attrList = attrList;
623 
624 			status = ns_printer_put(printer);
625 			_freeList(&attrList);
626 			free(printer->nsdata);
627 			if (status != 0) {
628 				(void) ns_printer_destroy(printer);
629 				return (status);
630 			}
631 		}
632 		(void) ns_printer_destroy(printer);
633 		return (0);
634 	}
635 
636 	/*
637 	 * Modify printer object in the LDAP directory DIT
638 	 */
639 
640 	if ((printer = (ns_printer_t *)
641 	    ns_printer_get_name(printername, "ldap")) == NULL) {
642 		return (1);
643 	}
644 	printer->cred = cred;
645 	printer->source = strdup("ldap");
646 
647 	if ((comment != NULL) && (strlen(comment) > 0)) {
648 		item = (char *)malloc(strlen("description") +
649 						strlen(comment) + 4);
650 		if (item == NULL) {
651 			(void) ns_printer_destroy(printer);
652 			return (1);
653 		}
654 		sprintf(item, "%s=%s", "description", comment);
655 		attrList = (char **)list_append((void**)attrList, (void *)item);
656 	} else {
657 		item = (char *)malloc(strlen("description") + 4);
658 		if (item == NULL) {
659 			(void) ns_printer_destroy(printer);
660 			return (1);
661 		}
662 		sprintf(item, "%s=", "description");
663 		attrList = (char **)list_append((void**)attrList, (void *)item);
664 	}
665 
666 	printer->attributes = NULL;
667 	printer->nsdata = malloc(sizeof (NS_LDAPDATA));
668 	if (printer->nsdata == NULL) {
669 		(void) ns_printer_destroy(printer);
670 		return (1);
671 	}
672 	((NS_LDAPDATA *)(printer->nsdata))->attrList = attrList;
673 
674 	status = ns_printer_put(printer);
675 	_freeList(&attrList);
676 	free(printer->nsdata);
677 	if (status != 0) {
678 		(void) ns_printer_destroy(printer);
679 		return (status);
680 	}
681 
682 	/*
683 	 * Handle the default printer.
684 	 */
685 	if ((printer = (ns_printer_t *)
686 	    ns_printer_get_name("_default", "ldap")) != NULL) {
687 		char *dflt = (char *)ns_get_value_string("use", printer);
688 
689 		printer->source = strdup("ldap");
690 		printer->cred = cred;
691 		if (strcmp(printername, dflt) == 0) {
692 			if (strcmp(isdefault, "false") == 0) {
693 				/*
694 				 * We were the default printer but not
695 				 * any more. So delete the default entry
696 				 */
697 				printer->attributes = NULL;
698 				printer->nsdata = malloc(sizeof (NS_LDAPDATA));
699 				if (printer->nsdata == NULL) {
700 					(void) ns_printer_destroy(printer);
701 					return (1);
702 				}
703 			((NS_LDAPDATA *)(printer->nsdata))->attrList = NULL;
704 				status = ns_printer_put(printer);
705 				free(printer->nsdata);
706 				if (status != 0) {
707 					(void) ns_printer_destroy(printer);
708 					return (status);
709 				}
710 			}
711 		} else if (strcmp(isdefault, "true") == 0) {
712 			/*
713 			 * Modify this default entry to use us.
714 			 */
715 			printer->attributes = NULL;
716 			printer->nsdata = malloc(sizeof (NS_LDAPDATA));
717 			if (printer->nsdata == NULL) {
718 				(void) ns_printer_destroy(printer);
719 				return (1);
720 			}
721 			attrList = NULL;
722 			item = (char *)malloc(strlen("use") +
723 						strlen(printername) + 4);
724 			if (item == NULL) {
725 				(void) ns_printer_destroy(printer);
726 				return (1);
727 			}
728 			sprintf(item, "%s=%s", "use", printername);
729 			attrList = (char **)list_append((void**)attrList,
730 							(void *)item);
731 
732 			((NS_LDAPDATA *)(printer->nsdata))->attrList = attrList;
733 
734 			status = ns_printer_put(printer);
735 			_freeList(&attrList);
736 			free(printer->nsdata);
737 
738 			if (status != 0) {
739 				(void) ns_printer_destroy(printer);
740 				return (status);
741 			}
742 		}
743 	} else if (strcmp(isdefault, "true") == 0) {
744 		/*
745 		 * No default entry existed and we need one.
746 		 */
747 		printer = (ns_printer_t *)malloc(sizeof (*printer));
748 		(void) memset(printer, 0, sizeof (*printer));
749 		printer->name = strdup("_default");
750 		printer->source = strdup("ldap");
751 		printer->cred = cred;
752 
753 		printer->nsdata = malloc(sizeof (NS_LDAPDATA));
754 		if (printer->nsdata == NULL) {
755 			(void) ns_printer_destroy(printer);
756 			return (1);
757 		}
758 
759 		attrList = NULL;
760 		item = (char *)malloc(strlen("use") + strlen(printername) + 4);
761 		if (item == NULL) {
762 			(void) ns_printer_destroy(printer);
763 			return (1);
764 		}
765 		sprintf(item, "%s=%s", "use", printername);
766 		attrList = (char **)list_append((void**)attrList, (void *)item);
767 
768 		((NS_LDAPDATA *)(printer->nsdata))->attrList = attrList;
769 
770 		status = ns_printer_put(printer);
771 		_freeList(&attrList);
772 		free(printer->nsdata);
773 
774 		if (status != 0) {
775 			(void) ns_printer_destroy(printer);
776 			return (status);
777 		}
778 	}
779 
780 	(void) ns_printer_destroy(printer);
781 	return (0);
782 }
783 
784 
785 
786 
787 /*
788  * *****************************************************************************
789  *
790  * Function:    _freeList()
791  *
792  * Description: Free the list created by list_append() where the items in
793  *              the list have been strdup'ed.
794  *
795  * Parameters:
796  * Input:       char ***list   - returned set of kvp values
797  *
798  * Result:      void
799  *
800  * *****************************************************************************
801  */
802 
803 static void
_freeList(char *** list)804 _freeList(char ***list)
805 
806 {
807 	int i = 0;
808 
809 	/* ------ */
810 
811 	if (list != NULL) {
812 		if (*list != NULL) {
813 			for (i = 0; (*list)[i] != NULL; i++) {
814 				free((*list)[i]);
815 			}
816 			free(*list);
817 		}
818 
819 		*list = NULL;
820 	}
821 } /* _freeList */
822