xref: /titanic_52/usr/src/lib/print/libprint/common/nss_ldap.c (revision c1ecd8b9404ee0d96d93f02e82c441b9bb149a3d)
1355b4669Sjacobs /*
2355b4669Sjacobs  * CDDL HEADER START
3355b4669Sjacobs  *
4355b4669Sjacobs  * The contents of this file are subject to the terms of the
5355b4669Sjacobs  * Common Development and Distribution License (the "License").
6355b4669Sjacobs  * You may not use this file except in compliance with the License.
7355b4669Sjacobs  *
8355b4669Sjacobs  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9355b4669Sjacobs  * or http://www.opensolaris.org/os/licensing.
10355b4669Sjacobs  * See the License for the specific language governing permissions
11355b4669Sjacobs  * and limitations under the License.
12355b4669Sjacobs  *
13355b4669Sjacobs  * When distributing Covered Code, include this CDDL HEADER in each
14355b4669Sjacobs  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15355b4669Sjacobs  * If applicable, add the following below this CDDL HEADER, with the
16355b4669Sjacobs  * fields enclosed by brackets "[]" replaced with your own identifying
17355b4669Sjacobs  * information: Portions Copyright [yyyy] [name of copyright owner]
18355b4669Sjacobs  *
19355b4669Sjacobs  * CDDL HEADER END
20355b4669Sjacobs  */
21355b4669Sjacobs /*
22*c1ecd8b9Sjacobs  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23355b4669Sjacobs  * Use is subject to license terms.
24355b4669Sjacobs  */
25355b4669Sjacobs 
26355b4669Sjacobs #pragma ident	"%Z%%M%	%I%	%E% SMI"
27355b4669Sjacobs 
28355b4669Sjacobs #include <stdio.h>
29355b4669Sjacobs #include <stdlib.h>
30355b4669Sjacobs #include <unistd.h>
31355b4669Sjacobs #include <sys/types.h>
32355b4669Sjacobs #include <sys/stat.h>
33355b4669Sjacobs #include <string.h>
34355b4669Sjacobs #include <stdarg.h>
35355b4669Sjacobs #include <fcntl.h>
36355b4669Sjacobs #include <syslog.h>
37355b4669Sjacobs #include <errno.h>
38355b4669Sjacobs #include <pwd.h>
39355b4669Sjacobs #include <libintl.h>
40355b4669Sjacobs #include <netdb.h>	/* for rcmd() */
41355b4669Sjacobs 
42355b4669Sjacobs #include <ns.h>
43355b4669Sjacobs #include <list.h>
44355b4669Sjacobs 
45355b4669Sjacobs #define	LDAP_REFERRALS
46355b4669Sjacobs #include <lber.h>
47355b4669Sjacobs #include <ldap.h>
48355b4669Sjacobs #include <sys/systeminfo.h>
49355b4669Sjacobs 
50355b4669Sjacobs 
51355b4669Sjacobs /*
52355b4669Sjacobs  * This modules contains the code required to manipulate printer objects in
53355b4669Sjacobs  * a LDAP directory for the Naming Service (NS) switch.
54355b4669Sjacobs  * It can "add", "modify" and "delete" the objects on the given ldap server
55355b4669Sjacobs  * and in the given NS domain DN, eg. "dc=mkg,dc=sun,dc=com".
56355b4669Sjacobs  * Note: printers known to the naming service are contained in the RDN
57355b4669Sjacobs  * "ou=printers" under the NS domain DN
58355b4669Sjacobs  */
59355b4669Sjacobs 
60355b4669Sjacobs #define	PCONTAINER	"ou=printers"
61355b4669Sjacobs 
62355b4669Sjacobs /* attribute keywords */
63355b4669Sjacobs #define	ATTR_DN		"dn"
64355b4669Sjacobs #define	ATTR_OCLASS	"objectClass"
65355b4669Sjacobs #define	ATTR_URI	"printer-uri"
66355b4669Sjacobs #define	ATTR_PNAME	"printer-name"
67355b4669Sjacobs #define	ATTR_XRISUP	"printer-xri-supported"
68355b4669Sjacobs #define	ATTR_BSDADDR	"sun-printer-bsdaddr"
69355b4669Sjacobs #define	ATTR_KVP	"sun-printer-kvp"
70355b4669Sjacobs 
71355b4669Sjacobs /* objectClass values */
72355b4669Sjacobs #define	OCV_TOP		"top"
73355b4669Sjacobs #define	OCV_PSERVICE	"printerService"
74355b4669Sjacobs #define	OCV_SUNPRT	"sunPrinter"
75355b4669Sjacobs #define	OCV_PABSTRACT	"printerAbstract"
76355b4669Sjacobs 
77355b4669Sjacobs /* xri-supported attribute value */
78355b4669Sjacobs #define	AV_UNKNOWN	"unknown"
79355b4669Sjacobs 
80355b4669Sjacobs 
81355b4669Sjacobs /*
82355b4669Sjacobs  * LDAP objectclass atributes that the user can explicity change
83355b4669Sjacobs  */
84355b4669Sjacobs 
85355b4669Sjacobs static const char *nsl_attr_printerService[] = {
86355b4669Sjacobs 	"printer-uri",
87355b4669Sjacobs 	"printer-xri-supported",
88355b4669Sjacobs 	/* Not allowed "printer-name", */
89355b4669Sjacobs 	"printer-natural-language-configured",
90355b4669Sjacobs 	"printer-location",
91355b4669Sjacobs 	"printer-info",
92355b4669Sjacobs 	"printer-more-info",
93355b4669Sjacobs 	"printer-make-and-model",
94355b4669Sjacobs 	"printer-charset-configured",
95355b4669Sjacobs 	"printer-charset-supported",
96355b4669Sjacobs 	"printer-generated-natural-language-supported",
97355b4669Sjacobs 	"printer-document-format-supported",
98355b4669Sjacobs 	"printer-color-supported",
99355b4669Sjacobs 	"printer-compression-supported",
100355b4669Sjacobs 	"printer-pages-per-minute",
101355b4669Sjacobs 	"printer-pages-per-minute-color",
102355b4669Sjacobs 	"printer-finishings-supported",
103355b4669Sjacobs 	"printer-number-up-supported",
104355b4669Sjacobs 	"printer-sides-supported",
105355b4669Sjacobs 	"printer-media-supported",
106355b4669Sjacobs 	"printer-media-local-supported",
107355b4669Sjacobs 	"printer-resolution-supported",
108355b4669Sjacobs 	"printer-print-quality-supported",
109355b4669Sjacobs 	"printer-job-priority-supported",
110355b4669Sjacobs 	"printer-copies-supported",
111355b4669Sjacobs 	"printer-job-k-octets-supported",
112355b4669Sjacobs 	"printer-current-operator",
113355b4669Sjacobs 	"printer-service-person",
114355b4669Sjacobs 	"printer-delivery-orientation-supported",
115355b4669Sjacobs 	"printer-stacking-order-supported",
116355b4669Sjacobs 	"printer-output-features-supported",
117355b4669Sjacobs 	(char *)NULL
118355b4669Sjacobs };
119355b4669Sjacobs 
120355b4669Sjacobs 
121355b4669Sjacobs static const char *nsl_attr_printerIPP[] = {
122355b4669Sjacobs 	"printer-ipp-versions-supported",
123355b4669Sjacobs 	"printer-multiple-document-jobs-supported",
124355b4669Sjacobs 	(char *)NULL
125355b4669Sjacobs };
126355b4669Sjacobs 
127355b4669Sjacobs static const char *nsl_attr_sunPrinter[] = {
128355b4669Sjacobs 	/* Not allowed "sun-printer-bsdaddr", */
129355b4669Sjacobs 	/* Not allowed "sun-printer-kvp", */
130355b4669Sjacobs 	(char *)NULL
131355b4669Sjacobs };
132355b4669Sjacobs 
133355b4669Sjacobs 
134355b4669Sjacobs /*
135355b4669Sjacobs  * List of LDAP attributes that user is not allowed to explicitly change
136355b4669Sjacobs  */
137355b4669Sjacobs static const char *nsl_attr_notAllowed[] = {
138355b4669Sjacobs 	ATTR_DN,
139355b4669Sjacobs 	ATTR_OCLASS,		/* objectclass */
140355b4669Sjacobs 	ATTR_PNAME,		/* printer-name */
141355b4669Sjacobs 	ATTR_BSDADDR,
142355b4669Sjacobs 	ATTR_KVP,
143355b4669Sjacobs 	(char *)NULL
144355b4669Sjacobs };
145355b4669Sjacobs 
146355b4669Sjacobs 
147355b4669Sjacobs static NSL_RESULT _connectToLDAP(ns_cred_t *cred, LDAP **ld);
148355b4669Sjacobs static uchar_t *_constructPrinterDN(uchar_t *printerName,
149355b4669Sjacobs 				uchar_t *domainDN, char **attrList);
150355b4669Sjacobs static NSL_RESULT _checkPrinterExists(LDAP *ld, uchar_t *printerName,
151355b4669Sjacobs 			uchar_t *domainDN, uchar_t **printerDN);
152355b4669Sjacobs static NSL_RESULT _checkPrinterDNExists(LDAP *ld, uchar_t *objectDN);
153355b4669Sjacobs static NSL_RESULT _checkSunPrinter(LDAP *ld, uchar_t *printerDN);
154355b4669Sjacobs static NSL_RESULT _addNewPrinterObject(LDAP *ld, uchar_t *printerName,
155355b4669Sjacobs 					uchar_t *domainDN, char **attrList);
156355b4669Sjacobs static NSL_RESULT _modifyPrinterObject(LDAP *ld, uchar_t *printerDN,
157355b4669Sjacobs 		uchar_t *printerName, uchar_t *domainDN, char **attrList);
158355b4669Sjacobs static NSL_RESULT _checkAttributes(char **list);
159355b4669Sjacobs static NSL_RESULT _addLDAPmodValue(LDAPMod ***attrs, char *type, char *value);
160355b4669Sjacobs static NSL_RESULT _modLDAPmodValue(LDAPMod ***attrs, char *type, char *value);
161355b4669Sjacobs static NSL_RESULT _constructAddLDAPMod(uchar_t *printerName,
162355b4669Sjacobs 					char **attrList,  LDAPMod ***attrs);
163355b4669Sjacobs static NSL_RESULT _constructModLDAPMod(uchar_t *printerName, int sunPrinter,
164355b4669Sjacobs 			char **attrList, char ***oldKVPList, LDAPMod ***attrs);
165355b4669Sjacobs static NSL_RESULT _compareURIinDNs(uchar_t *dn1, uchar_t *dn2);
166355b4669Sjacobs static uchar_t *_getThisNSDomainDN(void);
167355b4669Sjacobs static int _popen(char *cmd, char *results, int size);
168355b4669Sjacobs static int _attrInList(char *attr, const char **list);
169355b4669Sjacobs static int _attrInLDAPList(char *attr);
170355b4669Sjacobs static NSL_RESULT _getCurrentKVPValues(LDAP *ld,
171355b4669Sjacobs 					uchar_t *objectDN, char ***list);
172355b4669Sjacobs static void _freeList(char ***list);
173355b4669Sjacobs static NSL_RESULT _modAttrKVP(char *value, char ***kvpList);
174355b4669Sjacobs static NSL_RESULT _attrAddKVP(LDAPMod ***attrs, char **kvpList, int kvpExists);
175355b4669Sjacobs static int _manageReferralCredentials(LDAP *ld, char **dn, char **credp,
176355b4669Sjacobs 					int *methodp, int freeit);
177355b4669Sjacobs 
178355b4669Sjacobs /*
179355b4669Sjacobs  * *****************************************************************************
180355b4669Sjacobs  *
181355b4669Sjacobs  * Function:    ldap_put_printer()
182355b4669Sjacobs  *
183355b4669Sjacobs  * Description: Action the request to change a printer object in the LDAP
184355b4669Sjacobs  *              directory DIT. The object is either added, modified or deleted
185355b4669Sjacobs  *              depending on the request's attribute list. A null list indicates
186355b4669Sjacobs  *              the request is a delete.
187355b4669Sjacobs  *              The object's DN is constructed from the supplied domain DN and
188355b4669Sjacobs  *              a check is done to see if the object exists already, if it
189355b4669Sjacobs  *              doesn't exist then this is a request to add a new object
190355b4669Sjacobs  *              If a URI is given in the attribute list and it is different to
191355b4669Sjacobs  *              the existing printing object's DN then the request will be
192355b4669Sjacobs  *              rejected.
193355b4669Sjacobs  *
194355b4669Sjacobs  *
195355b4669Sjacobs  * Parameters:
196355b4669Sjacobs  * Input:       const ns_printer_t *printer
197355b4669Sjacobs  *                - this structure contains the following :
198355b4669Sjacobs  *                  char *printerName - name of the printer
199355b4669Sjacobs  *                  ns_cred_t *cred - structure containing the ldap host and
200355b4669Sjacobs  *                                port, user, password and NS domain DN for the
201355b4669Sjacobs  *                                directory server to be updated.
202355b4669Sjacobs  *                  char **attrList - pointer to a list of attribute key values
203355b4669Sjacobs  *                                for the printer object. If the object does
204355b4669Sjacobs  *                                not already exist then this list contains the
205355b4669Sjacobs  *                                values for the new object, otherwise this list
206355b4669Sjacobs  *                                is a list of attributes to modify. For modify
207355b4669Sjacobs  *                                a null attribute value is a attribute delete
208355b4669Sjacobs  *                                request. A NULL ptr = delete the object.
209355b4669Sjacobs  * Output:      None
210355b4669Sjacobs  *
211355b4669Sjacobs  * Returns:     int - 0 = request actioned okay
212355b4669Sjacobs  *                   !0 = error - see NSL_RESULT codes
213355b4669Sjacobs  *
214355b4669Sjacobs  * *****************************************************************************
215355b4669Sjacobs  */
216355b4669Sjacobs 
217355b4669Sjacobs int
218355b4669Sjacobs ldap_put_printer(const ns_printer_t *printer)
219355b4669Sjacobs 
220355b4669Sjacobs {
221355b4669Sjacobs 	NSL_RESULT result = NSL_OK;
222355b4669Sjacobs 	NSL_RESULT printerExists = NSL_ERR_UNKNOWN_PRINTER;
223355b4669Sjacobs 	LDAP *ld = NULL;
224355b4669Sjacobs 	uchar_t *printerDN = NULL;
225355b4669Sjacobs 	uchar_t *domainDN = NULL;
226355b4669Sjacobs 	char *printerName = NULL;
227355b4669Sjacobs 	ns_cred_t *cred = NULL;
228355b4669Sjacobs 	char **attrList = NULL;
229355b4669Sjacobs 
230355b4669Sjacobs 	/* -------- */
231355b4669Sjacobs 
232355b4669Sjacobs 	/*
233355b4669Sjacobs 	 * Note: the "attributes" list should be null for ldap as the attribute
234355b4669Sjacobs 	 * values are passed in the nsdata field
235355b4669Sjacobs 	 */
236355b4669Sjacobs 
237355b4669Sjacobs 	if ((printer != NULL) &&
238355b4669Sjacobs 	    (printer->attributes == NULL) && (printer->name != NULL))
239355b4669Sjacobs 	{
240355b4669Sjacobs 		/* extract required pointer values from structure */
241355b4669Sjacobs 
242355b4669Sjacobs 		printerName = printer->name;
243355b4669Sjacobs 		cred = printer->cred;
244355b4669Sjacobs 		if (printer->nsdata != NULL)
245355b4669Sjacobs 		{
246355b4669Sjacobs 			attrList = ((NS_LDAPDATA *)(printer->nsdata))->attrList;
247355b4669Sjacobs 		}
248355b4669Sjacobs 
249355b4669Sjacobs 		/* connect and bind to the ldap directory server */
250355b4669Sjacobs 
251355b4669Sjacobs 		result = _connectToLDAP(cred, &ld);
252355b4669Sjacobs 		if ((result == NSL_OK) && (ld != NULL))
253355b4669Sjacobs 		{
254355b4669Sjacobs 			/*
255355b4669Sjacobs 			 * check if the NS domain DN was given, if not use the
256355b4669Sjacobs 			 * current NS domain
257355b4669Sjacobs 			 */
258355b4669Sjacobs 
259355b4669Sjacobs 			if (cred->domainDN != NULL)
260355b4669Sjacobs 			{
261355b4669Sjacobs 				domainDN = (uchar_t *)
262355b4669Sjacobs 					strdup((char *)cred->domainDN);
263355b4669Sjacobs 			}
264355b4669Sjacobs 			else
265355b4669Sjacobs 			{
266355b4669Sjacobs 				/* get DN of current domain */
267355b4669Sjacobs 				domainDN = _getThisNSDomainDN();
268355b4669Sjacobs 			}
269355b4669Sjacobs 
270355b4669Sjacobs 			printerExists =
271355b4669Sjacobs 				_checkPrinterExists(ld, (uchar_t *)printerName,
272355b4669Sjacobs 							domainDN, &printerDN);
273355b4669Sjacobs 			if (printerExists != LDAP_SUCCESS)
274355b4669Sjacobs 			{
275355b4669Sjacobs 				/*
276355b4669Sjacobs 				 * could not find the printer by printer-name,
277355b4669Sjacobs 				 * but there could be a non sunPrinter object
278355b4669Sjacobs 				 * so if the printer-uri was given check if
279355b4669Sjacobs 				 * an object for that exists
280355b4669Sjacobs 				 */
281355b4669Sjacobs 				printerDN =
282355b4669Sjacobs 				    _constructPrinterDN(NULL,
283355b4669Sjacobs 							domainDN, attrList);
284355b4669Sjacobs 				if (printerDN != NULL)
285355b4669Sjacobs 				{
286355b4669Sjacobs 					printerExists = _checkPrinterDNExists(
287355b4669Sjacobs 								ld, printerDN);
288355b4669Sjacobs 				}
289355b4669Sjacobs 			}
290355b4669Sjacobs #ifdef DEBUG
291355b4669Sjacobs if (printerExists == NSL_OK)
292355b4669Sjacobs {
293355b4669Sjacobs printf("DN found = '%s' for '%s'\n", printerDN, printerName);
294355b4669Sjacobs }
295355b4669Sjacobs #endif
296355b4669Sjacobs 
297355b4669Sjacobs 			if (attrList == NULL)
298355b4669Sjacobs 			{
299355b4669Sjacobs 				/*
300355b4669Sjacobs 				 * a null list indicates that this is a DELETE
301355b4669Sjacobs 				 * object request, so if object exists delete
302355b4669Sjacobs 				 * it, otherwise report an error.
303355b4669Sjacobs 				 */
304355b4669Sjacobs 				if (printerExists == LDAP_SUCCESS)
305355b4669Sjacobs 				{
306355b4669Sjacobs 				    result = ldap_delete_s(ld,
307355b4669Sjacobs 						(char *)printerDN);
308355b4669Sjacobs 				    if (result != LDAP_SUCCESS)
309355b4669Sjacobs 				    {
310355b4669Sjacobs 					result = NSL_ERR_DEL_FAILED;
311355b4669Sjacobs #ifdef DEBUG
312355b4669Sjacobs ldap_perror(ld, "ldap_delete_s failed");
313355b4669Sjacobs #endif
314355b4669Sjacobs 				    }
315355b4669Sjacobs 				}
316355b4669Sjacobs 				else
317355b4669Sjacobs 				{
318355b4669Sjacobs 				    result = NSL_ERR_UNKNOWN_PRINTER;
319355b4669Sjacobs 				}
320355b4669Sjacobs 			}
321355b4669Sjacobs 			else
322355b4669Sjacobs 			{
323355b4669Sjacobs 				/*
324355b4669Sjacobs 				 * if object exists then this is a
325355b4669Sjacobs 				 * modify request otherwise is is an add request
326355b4669Sjacobs 				 */
327355b4669Sjacobs 
328355b4669Sjacobs 				if (printerExists == LDAP_SUCCESS)
329355b4669Sjacobs 				{
330355b4669Sjacobs 					/*
331355b4669Sjacobs 					 * Modify the printer object to
332355b4669Sjacobs 					 * give it the new attribute values
333355b4669Sjacobs 					 * specified by the user
334355b4669Sjacobs 					 */
335355b4669Sjacobs 					result =
336355b4669Sjacobs 					_modifyPrinterObject(ld, printerDN,
337355b4669Sjacobs 						(uchar_t *)printerName,
338355b4669Sjacobs 						domainDN, attrList);
339355b4669Sjacobs 				}
340355b4669Sjacobs 				else
341355b4669Sjacobs 				{
342355b4669Sjacobs 					/*
343355b4669Sjacobs 					 * add new printer object into the
344355b4669Sjacobs 					 * ldap directory with the user
345355b4669Sjacobs 					 * specified attribute values
346355b4669Sjacobs 					 */
347355b4669Sjacobs 					result =
348355b4669Sjacobs 					    _addNewPrinterObject(ld,
349355b4669Sjacobs 						(uchar_t *)printerName,
350355b4669Sjacobs 						domainDN, attrList);
351355b4669Sjacobs 				}
352355b4669Sjacobs 			}
353355b4669Sjacobs 
354355b4669Sjacobs 			if (printerDN != NULL)
355355b4669Sjacobs 			{
356355b4669Sjacobs 				free(printerDN);
357355b4669Sjacobs 			}
358355b4669Sjacobs 			if (domainDN != NULL)
359355b4669Sjacobs 			{
360355b4669Sjacobs 				free(domainDN);
361355b4669Sjacobs 			}
362355b4669Sjacobs 
363355b4669Sjacobs 			/* disconnect from LDAP server */
364355b4669Sjacobs 
365355b4669Sjacobs 			(void) ldap_unbind(ld);
366355b4669Sjacobs 		}
367355b4669Sjacobs 	}
368355b4669Sjacobs 
369355b4669Sjacobs 	else
370355b4669Sjacobs 	{
371355b4669Sjacobs 		/* no printerName given */
372355b4669Sjacobs 		result = NSL_ERR_INTERNAL;
373355b4669Sjacobs 	}
374355b4669Sjacobs 
375355b4669Sjacobs 	return ((int)result);
376355b4669Sjacobs } /* ldap_put_printer */
377355b4669Sjacobs 
378355b4669Sjacobs 
379355b4669Sjacobs 
380355b4669Sjacobs 
381355b4669Sjacobs /*
382355b4669Sjacobs  * *****************************************************************************
383355b4669Sjacobs  *
384355b4669Sjacobs  * Function:    _connectToLDAP()
385355b4669Sjacobs  *
386355b4669Sjacobs  * Description: Setup the connection and bind to the LDAP directory server.
387355b4669Sjacobs  *              The function returns the ldap connection descriptor
388355b4669Sjacobs  *
389355b4669Sjacobs  * Note:        Currently the native ldap functions do not support secure
390355b4669Sjacobs  *              passwords, when this is supported this function will require
391355b4669Sjacobs  *              updating to allow the type passed in cred->passwdType to
392355b4669Sjacobs  *              be used with the ldap_simple_bind()
393355b4669Sjacobs  *
394355b4669Sjacobs  * Parameters:
395355b4669Sjacobs  * Input:       ns_cred_t *cred - structure containing the credentials (host,
396355b4669Sjacobs  *                                port, user and password) required to bind
397355b4669Sjacobs  *                                to the directory server to be updated.
398355b4669Sjacobs  *              char *printerName - printer name used only for error messages
399355b4669Sjacobs  * Output:      LDAP** - ldap connection descriptor pointer. NULL = failed
400355b4669Sjacobs  *
401355b4669Sjacobs  * Returns:     NSL_RESULT - NSL_OK = connected okay
402355b4669Sjacobs  *
403355b4669Sjacobs  * *****************************************************************************
404355b4669Sjacobs  */
405355b4669Sjacobs 
406355b4669Sjacobs static NSL_RESULT
407355b4669Sjacobs _connectToLDAP(ns_cred_t *cred, LDAP **ld)
408355b4669Sjacobs 
409355b4669Sjacobs {
410355b4669Sjacobs 	NSL_RESULT result = NSL_OK;
411355b4669Sjacobs 	int lresult = 0;
412355b4669Sjacobs 	int ldapPort = LDAP_PORT;	/* default LDAP port number */
413355b4669Sjacobs 	int protoVersion = LDAP_VERSION3;
414355b4669Sjacobs 	int derefOption = LDAP_DEREF_NEVER;
415355b4669Sjacobs 	int referrals = 1;
416355b4669Sjacobs 	char hostname[MAXHOSTNAMELEN];
417355b4669Sjacobs 	int tmpMethod = LDAP_AUTH_SIMPLE; /* temp - until its passed in */
418355b4669Sjacobs 
419355b4669Sjacobs 	/* -------- */
420355b4669Sjacobs 
421355b4669Sjacobs 	if ((ld == NULL) || (cred == NULL) ||
422355b4669Sjacobs 		((cred->passwd == NULL) || (cred->binddn == NULL)))
423355b4669Sjacobs 	{
424355b4669Sjacobs 		result = NSL_ERR_CREDENTIALS;
425355b4669Sjacobs 	}
426355b4669Sjacobs 
427355b4669Sjacobs 	else
428355b4669Sjacobs 	{
429355b4669Sjacobs 		*ld = NULL;
430355b4669Sjacobs 
431355b4669Sjacobs 		/* if host was not given then bind to local host */
432355b4669Sjacobs 
433355b4669Sjacobs 		if (cred->host != NULL)
434355b4669Sjacobs 		{
435355b4669Sjacobs 			(void) strlcpy(hostname, cred->host, sizeof (hostname));
436355b4669Sjacobs 		}
437355b4669Sjacobs 		else
438355b4669Sjacobs 		{
439355b4669Sjacobs 			(void) sysinfo(SI_HOSTNAME,
440355b4669Sjacobs 					hostname, sizeof (hostname));
441355b4669Sjacobs 		}
442355b4669Sjacobs 
443355b4669Sjacobs 		/* initialise the connection to the ldap server */
444355b4669Sjacobs 
445355b4669Sjacobs 		if (cred->port != 0)
446355b4669Sjacobs 		{
447355b4669Sjacobs 			ldapPort = cred->port;
448355b4669Sjacobs 		}
449355b4669Sjacobs 		*ld = ldap_init(hostname, ldapPort);
450355b4669Sjacobs 		if (*ld == NULL)
451355b4669Sjacobs 		{
452355b4669Sjacobs 			/* connection setup failed */
453355b4669Sjacobs 			result = NSL_ERR_CONNECT;
454355b4669Sjacobs #ifdef DEBUG
455355b4669Sjacobs (void) perror("ldap_init");
456355b4669Sjacobs #endif
457355b4669Sjacobs 		}
458355b4669Sjacobs 		else
459355b4669Sjacobs 		{
460355b4669Sjacobs 			/* set ldap options */
461355b4669Sjacobs 
462355b4669Sjacobs 			(void) ldap_set_option(*ld, LDAP_OPT_DEREF,
463355b4669Sjacobs 						&derefOption);
464355b4669Sjacobs 			(void) ldap_set_option(*ld, LDAP_OPT_PROTOCOL_VERSION,
465355b4669Sjacobs 						&protoVersion);
466355b4669Sjacobs 			(void) ldap_set_option(*ld, LDAP_OPT_REFERRALS,
467355b4669Sjacobs 						&referrals);
468355b4669Sjacobs 
469355b4669Sjacobs 			/* bind to the user DN in the directory */
470355b4669Sjacobs 
471355b4669Sjacobs 			/* cred->passwdType is currently not supported */
472355b4669Sjacobs 
473355b4669Sjacobs 			lresult = ldap_simple_bind_s(*ld,
474355b4669Sjacobs 						cred->binddn, cred->passwd);
475355b4669Sjacobs 
476355b4669Sjacobs 			/*
477355b4669Sjacobs 			 * before doing anything else, set up the function to
478355b4669Sjacobs 			 * call to get authentication details if the
479355b4669Sjacobs 			 * ldap update function calls (eg. ldap_add_s()) get a
480355b4669Sjacobs 			 * "referral" (to another ldap server) from the
481355b4669Sjacobs 			 * original ldap server, eg. if we are trying to do
482355b4669Sjacobs 			 * a update on a LDAP replica server.
483355b4669Sjacobs 			 */
484355b4669Sjacobs 			(void) _manageReferralCredentials(*ld,
485355b4669Sjacobs 					&(cred->binddn), &(cred->passwd),
486355b4669Sjacobs 					&tmpMethod, -1);
487355b4669Sjacobs 			ldap_set_rebind_proc(*ld,
488355b4669Sjacobs 			    (LDAP_REBINDPROC_CALLBACK *)
489355b4669Sjacobs 				_manageReferralCredentials, NULL);
490355b4669Sjacobs 
491355b4669Sjacobs 			if (lresult != LDAP_SUCCESS)
492355b4669Sjacobs 			{
493355b4669Sjacobs 				result = NSL_ERR_BIND;
494355b4669Sjacobs 				*ld = NULL;
495355b4669Sjacobs #ifdef DEBUG
496355b4669Sjacobs (void) ldap_perror(*ld, "ldap_simple_bind_s");
497355b4669Sjacobs #endif
498355b4669Sjacobs 			}
499355b4669Sjacobs 		}
500355b4669Sjacobs 	}
501355b4669Sjacobs 
502355b4669Sjacobs 	return (result);
503355b4669Sjacobs } /* _connectToLDAP */
504355b4669Sjacobs 
505355b4669Sjacobs 
506355b4669Sjacobs 
507355b4669Sjacobs 
508355b4669Sjacobs 
509355b4669Sjacobs /*
510355b4669Sjacobs  * *****************************************************************************
511355b4669Sjacobs  *
512355b4669Sjacobs  * Function:    _constructPrinterDN()
513355b4669Sjacobs  *
514355b4669Sjacobs  * Description: Construct the DN for the printer object from its name and NS
515355b4669Sjacobs  *              domain DN. If the printer-uri is given in the attrList then
516355b4669Sjacobs  *              that is used instead of the printerName.
517355b4669Sjacobs  *
518355b4669Sjacobs  * Parameters:
519355b4669Sjacobs  * Input:       uchar_t *printerName
520355b4669Sjacobs  *              uchar_t *domainDN
521355b4669Sjacobs  *              char **attrList - this list is searched for printer-uri
522355b4669Sjacobs  * Output:      None
523355b4669Sjacobs  *
524355b4669Sjacobs  * Returns:     uchar_t* - pointer to the DN, this memory is malloced so
525355b4669Sjacobs  *                         must be freed using free() when finished with.
526355b4669Sjacobs  *
527355b4669Sjacobs  * *****************************************************************************
528355b4669Sjacobs  */
529355b4669Sjacobs 
530355b4669Sjacobs static uchar_t *
531355b4669Sjacobs _constructPrinterDN(uchar_t *printerName, uchar_t *domainDN, char **attrList)
532355b4669Sjacobs 
533355b4669Sjacobs {
534355b4669Sjacobs 	uchar_t *dn = NULL;
535355b4669Sjacobs 	uchar_t *uri = NULL;
536355b4669Sjacobs 	char **p = NULL;
537355b4669Sjacobs 	int len = 0;
538355b4669Sjacobs 
539355b4669Sjacobs 	/* ------- */
540355b4669Sjacobs 
541355b4669Sjacobs 	/* first search for printer-uri in the attribute list */
542355b4669Sjacobs 
543355b4669Sjacobs 	for (p = attrList; (p != NULL) && (*p != NULL) && (uri == NULL); p++)
544355b4669Sjacobs 	{
545355b4669Sjacobs 		/* get length of this key word */
546355b4669Sjacobs 
547355b4669Sjacobs 		for (len = 0; ((*p)[len] != '=') && ((*p)[len] != '\0'); len++);
548355b4669Sjacobs 
549355b4669Sjacobs 		if ((strncasecmp(*p, ATTR_URI, len) == 0) &&
550355b4669Sjacobs 		    (strlen(*p) > len+1))
551355b4669Sjacobs 		{
552355b4669Sjacobs 			uri = (uchar_t *)&((*p)[len+1]);
553355b4669Sjacobs 		}
554355b4669Sjacobs 	}
555355b4669Sjacobs 
556355b4669Sjacobs 
557355b4669Sjacobs 	if (domainDN != NULL) {
558355b4669Sjacobs 		size_t size;
559355b4669Sjacobs 
560355b4669Sjacobs 		/* malloc memory for the DN and then construct it */
561355b4669Sjacobs 
562355b4669Sjacobs 		if ((uri == NULL) && (printerName != NULL))
563355b4669Sjacobs 		{
564355b4669Sjacobs 			/* use the printerName for the RDN */
565355b4669Sjacobs 
566355b4669Sjacobs 			size = strlen(ATTR_URI) +
567355b4669Sjacobs 			    strlen((char *)printerName) +
568355b4669Sjacobs 			    strlen((char *)domainDN) +
569355b4669Sjacobs 			    strlen(PCONTAINER) +
570355b4669Sjacobs 			    10; /* plus a few extra */
571355b4669Sjacobs 
572355b4669Sjacobs 			if ((dn = malloc(size)) != NULL)
573355b4669Sjacobs 				(void) snprintf((char *)dn, size, "%s=%s,%s,%s",
574355b4669Sjacobs 				ATTR_URI, printerName, PCONTAINER, domainDN);
575355b4669Sjacobs 		}
576355b4669Sjacobs 		else
577355b4669Sjacobs 		if (uri != NULL)
578355b4669Sjacobs 		{
579355b4669Sjacobs 			/* use the URI for the RDN */
580355b4669Sjacobs 
581355b4669Sjacobs 			size = strlen(ATTR_URI) +
582355b4669Sjacobs 			    strlen((char *)uri) +
583355b4669Sjacobs 			    strlen((char *)domainDN) +
584355b4669Sjacobs 			    strlen(PCONTAINER) +
585355b4669Sjacobs 			    10; /* plus a few extra */
586355b4669Sjacobs 
587355b4669Sjacobs 			if ((dn = malloc(size)) != NULL)
588355b4669Sjacobs 				(void) snprintf((char *)dn, size, "%s=%s,%s,%s",
589355b4669Sjacobs 				ATTR_URI, uri, PCONTAINER, domainDN);
590355b4669Sjacobs 		}
591355b4669Sjacobs 
592355b4669Sjacobs 		/*
593355b4669Sjacobs 		 * else
594355b4669Sjacobs 		 * {
595355b4669Sjacobs 		 *    printName not given so return null
596355b4669Sjacobs 		 * }
597355b4669Sjacobs 		 */
598355b4669Sjacobs 
599355b4669Sjacobs 	}
600355b4669Sjacobs 
601355b4669Sjacobs 	return (dn);	/* caller must free this memory */
602355b4669Sjacobs } /* _constructPrinterDN */
603355b4669Sjacobs 
604355b4669Sjacobs 
605355b4669Sjacobs 
606355b4669Sjacobs /*
607355b4669Sjacobs  * *****************************************************************************
608355b4669Sjacobs  *
609355b4669Sjacobs  * Function:    _checkPrinterExists()
610355b4669Sjacobs  *
611355b4669Sjacobs  * Description: Check that the printer object for the printerName exists in the
612355b4669Sjacobs  *              directory DIT and then extract the object's DN
613355b4669Sjacobs  *              The function uses an exiting ldap connection and does a
614355b4669Sjacobs  *              search for the printerName in the supplied domain DN.
615355b4669Sjacobs  *
616355b4669Sjacobs  * Parameters:
617355b4669Sjacobs  * Input:       LDAP *ld             - existing ldap connection descriptor
618355b4669Sjacobs  *              uchar_t *printerName - printer name
619355b4669Sjacobs  *              uchar_t *domainDN    - DN of domain to search in
620355b4669Sjacobs  * Output:      uchar_t **printerDN  - DN of the printer - the caller should
621355b4669Sjacobs  *                                     free this memory using free()
622355b4669Sjacobs  *
623355b4669Sjacobs  * Result:      NSL_RESULT - NSL_OK = object exists
624355b4669Sjacobs  *
625355b4669Sjacobs  * *****************************************************************************
626355b4669Sjacobs  */
627355b4669Sjacobs 
628355b4669Sjacobs static NSL_RESULT
629355b4669Sjacobs _checkPrinterExists(LDAP *ld, uchar_t *printerName, uchar_t *domainDN,
630355b4669Sjacobs 			uchar_t **printerDN)
631355b4669Sjacobs 
632355b4669Sjacobs {
633355b4669Sjacobs 	NSL_RESULT result = NSL_ERR_UNKNOWN_PRINTER;
634355b4669Sjacobs 	int sresult = LDAP_NO_SUCH_OBJECT;
635355b4669Sjacobs 	LDAPMessage *ldapMsg = NULL;
636355b4669Sjacobs 	char *requiredAttrs[2] = { ATTR_PNAME, NULL };
637355b4669Sjacobs 	LDAPMessage *ldapEntry = NULL;
638355b4669Sjacobs 	uchar_t *filter = NULL;
639355b4669Sjacobs 	uchar_t *baseDN = NULL;
640355b4669Sjacobs 
641355b4669Sjacobs 	/* ---------- */
642355b4669Sjacobs 
643355b4669Sjacobs 	if ((printerName != NULL) && (domainDN != NULL) && (printerDN != NULL))
644355b4669Sjacobs 	{
645355b4669Sjacobs 		size_t size;
646355b4669Sjacobs 
647355b4669Sjacobs 		if (printerDN != NULL)
648355b4669Sjacobs 		{
649355b4669Sjacobs 			*printerDN = NULL;
650355b4669Sjacobs 		}
651355b4669Sjacobs 
652355b4669Sjacobs 		/* search for this Printer in the directory */
653355b4669Sjacobs 
654355b4669Sjacobs 		size = (3 + strlen((char *)printerName) + strlen(ATTR_PNAME) +
655355b4669Sjacobs 			2);
656355b4669Sjacobs 
657355b4669Sjacobs 		if ((filter = malloc(size)) != NULL)
658355b4669Sjacobs 			(void) snprintf((char *)filter, size, "(%s=%s)",
659355b4669Sjacobs 			    ATTR_PNAME, (char *)printerName);
660355b4669Sjacobs 
661355b4669Sjacobs 		size = (strlen((char *)domainDN) + strlen(PCONTAINER) + 5);
662355b4669Sjacobs 
663355b4669Sjacobs 		if ((baseDN = malloc(size)) != NULL)
664355b4669Sjacobs 			(void) snprintf((char *)baseDN, size, "%s,%s",
665355b4669Sjacobs 			    PCONTAINER, (char *)domainDN);
666355b4669Sjacobs 
667355b4669Sjacobs 		sresult = ldap_search_s(ld, (char *)baseDN, LDAP_SCOPE_SUBTREE,
668355b4669Sjacobs 				(char *)filter, requiredAttrs, 0, &ldapMsg);
669355b4669Sjacobs 		if (sresult == LDAP_SUCCESS)
670355b4669Sjacobs 		{
671355b4669Sjacobs 			/* check that the object exists and extract its DN */
672355b4669Sjacobs 
673355b4669Sjacobs 			ldapEntry = ldap_first_entry(ld, ldapMsg);
674355b4669Sjacobs 			if (ldapEntry != NULL)
675355b4669Sjacobs 			{
676355b4669Sjacobs 				/* object found - there should only be one */
677355b4669Sjacobs 				result = NSL_OK;
678355b4669Sjacobs 
679355b4669Sjacobs 				if (printerDN != NULL)
680355b4669Sjacobs 				{
681355b4669Sjacobs 					*printerDN = (uchar_t *)
682355b4669Sjacobs 						ldap_get_dn(ld, ldapEntry);
683355b4669Sjacobs 				}
684355b4669Sjacobs 			}
685355b4669Sjacobs 
686355b4669Sjacobs 			(void) ldap_msgfree(ldapMsg);
687355b4669Sjacobs 		}
688355b4669Sjacobs 	}
689355b4669Sjacobs 
690355b4669Sjacobs 	else
691355b4669Sjacobs 	{
692355b4669Sjacobs 		result = NSL_ERR_INTERNAL;
693355b4669Sjacobs 	}
694355b4669Sjacobs 
695355b4669Sjacobs 	return (result);
696355b4669Sjacobs } /* _checkPrinterExists */
697355b4669Sjacobs 
698355b4669Sjacobs 
699355b4669Sjacobs 
700355b4669Sjacobs 
701355b4669Sjacobs /*
702355b4669Sjacobs  * *****************************************************************************
703355b4669Sjacobs  *
704355b4669Sjacobs  * Function:    _checkPrinterDNExists()
705355b4669Sjacobs  *
706355b4669Sjacobs  * Description: Check that the printer object for the DN exists in the
707355b4669Sjacobs  *              directory DIT.
708355b4669Sjacobs  *              The function uses an exiting ldap connection and does a
709355b4669Sjacobs  *              search for the DN supplied.
710355b4669Sjacobs  *
711355b4669Sjacobs  * Parameters:  LDAP *ld       - existing ldap connection descriptor
712355b4669Sjacobs  *              char *objectDN - DN to search for
713355b4669Sjacobs  *
714355b4669Sjacobs  * Result:      NSL_RESULT - NSL_OK = object exists
715355b4669Sjacobs  *
716355b4669Sjacobs  * *****************************************************************************
717355b4669Sjacobs  */
718355b4669Sjacobs 
719355b4669Sjacobs static NSL_RESULT
720355b4669Sjacobs _checkPrinterDNExists(LDAP *ld, uchar_t *objectDN)
721355b4669Sjacobs 
722355b4669Sjacobs {
723355b4669Sjacobs 	NSL_RESULT result = NSL_ERR_UNKNOWN_PRINTER;
724355b4669Sjacobs 	int sresult = LDAP_NO_SUCH_OBJECT;
725355b4669Sjacobs 	LDAPMessage *ldapMsg;
726355b4669Sjacobs 	char *requiredAttrs[2] = { ATTR_PNAME, NULL };
727355b4669Sjacobs 	LDAPMessage *ldapEntry;
728355b4669Sjacobs 
729355b4669Sjacobs 	/* ---------- */
730355b4669Sjacobs 
731355b4669Sjacobs 	if ((ld != NULL) && (objectDN != NULL))
732355b4669Sjacobs 	{
733355b4669Sjacobs 		/* search for this Printer in the directory */
734355b4669Sjacobs 
735355b4669Sjacobs 		sresult = ldap_search_s(ld, (char *)objectDN, LDAP_SCOPE_BASE,
736355b4669Sjacobs 				"(objectclass=*)", requiredAttrs, 0, &ldapMsg);
737355b4669Sjacobs 		if (sresult == LDAP_SUCCESS)
738355b4669Sjacobs 		{
739355b4669Sjacobs 			/* check that the object exists */
740355b4669Sjacobs 			ldapEntry = ldap_first_entry(ld, ldapMsg);
741355b4669Sjacobs 			if (ldapEntry != NULL)
742355b4669Sjacobs 			{
743355b4669Sjacobs 				/* object found */
744355b4669Sjacobs 				result = NSL_OK;
745355b4669Sjacobs 			}
746355b4669Sjacobs 
747355b4669Sjacobs 			(void) ldap_msgfree(ldapMsg);
748355b4669Sjacobs 		}
749355b4669Sjacobs 	}
750355b4669Sjacobs 
751355b4669Sjacobs 	else
752355b4669Sjacobs 	{
753355b4669Sjacobs 		result = NSL_ERR_INTERNAL;
754355b4669Sjacobs 	}
755355b4669Sjacobs 
756355b4669Sjacobs 	return (result);
757355b4669Sjacobs } /* _checkPrinterDNExists */
758355b4669Sjacobs 
759355b4669Sjacobs 
760355b4669Sjacobs 
761355b4669Sjacobs 
762355b4669Sjacobs 
763355b4669Sjacobs /*
764355b4669Sjacobs  * *****************************************************************************
765355b4669Sjacobs  *
766355b4669Sjacobs  * Function:    _checkSunPrinter()
767355b4669Sjacobs  *
768355b4669Sjacobs  * Description: Check that the printer object for the printerDN is a sunPrinter
769355b4669Sjacobs  *              ie. it has the required objectclass attribute value.
770355b4669Sjacobs  *
771355b4669Sjacobs  * Parameters:
772355b4669Sjacobs  * Input:       LDAP *ld            - existing ldap connection descriptor
773355b4669Sjacobs  * Output:      uchar_t *printerDN  - DN of the printer
774355b4669Sjacobs  *
775355b4669Sjacobs  * Result:      NSL_RESULT - NSL_OK = object exists and is a sunPrinter
776355b4669Sjacobs  *
777355b4669Sjacobs  * *****************************************************************************
778355b4669Sjacobs  */
779355b4669Sjacobs 
780355b4669Sjacobs static NSL_RESULT
781355b4669Sjacobs _checkSunPrinter(LDAP *ld, uchar_t *printerDN)
782355b4669Sjacobs 
783355b4669Sjacobs {
784355b4669Sjacobs 	NSL_RESULT result = NSL_ERR_UNKNOWN_PRINTER;
785355b4669Sjacobs 	int sresult = LDAP_NO_SUCH_OBJECT;
786355b4669Sjacobs 	char *requiredAttrs[2] = { ATTR_PNAME, NULL };
787355b4669Sjacobs 	LDAPMessage *ldapMsg = NULL;
788355b4669Sjacobs 	LDAPMessage *ldapEntry = NULL;
789355b4669Sjacobs 	char *filter = NULL;
790355b4669Sjacobs 
791355b4669Sjacobs 	/* ---------- */
792355b4669Sjacobs 
793355b4669Sjacobs 	if ((ld != NULL) && (printerDN != NULL))
794355b4669Sjacobs 	{
795355b4669Sjacobs 		size_t size;
796355b4669Sjacobs 
797355b4669Sjacobs 		/* search for this Printer in the directory */
798355b4669Sjacobs 
799355b4669Sjacobs 		size = (3 + strlen(OCV_SUNPRT) + strlen(ATTR_OCLASS) + 2);
800355b4669Sjacobs 		if ((filter = malloc(size)) != NULL)
801355b4669Sjacobs 			(void) snprintf(filter, size, "(%s=%s)",
802355b4669Sjacobs 					ATTR_OCLASS, OCV_SUNPRT);
803355b4669Sjacobs 
804355b4669Sjacobs 		sresult = ldap_search_s(ld, (char *)printerDN,
805355b4669Sjacobs 						LDAP_SCOPE_SUBTREE, filter,
806355b4669Sjacobs 						requiredAttrs, 0, &ldapMsg);
807355b4669Sjacobs 		if (sresult == LDAP_SUCCESS)
808355b4669Sjacobs 		{
809355b4669Sjacobs 			/* check that the printer object exists */
810355b4669Sjacobs 
811355b4669Sjacobs 			ldapEntry = ldap_first_entry(ld, ldapMsg);
812355b4669Sjacobs 			if (ldapEntry != NULL)
813355b4669Sjacobs 			{
814355b4669Sjacobs 				/* object is a sunPrinter */
815355b4669Sjacobs 				result = NSL_OK;
816355b4669Sjacobs 			}
817355b4669Sjacobs 
818355b4669Sjacobs 			(void) ldap_msgfree(ldapMsg);
819355b4669Sjacobs 		}
820355b4669Sjacobs 	}
821355b4669Sjacobs 
822355b4669Sjacobs 	else
823355b4669Sjacobs 	{
824355b4669Sjacobs 		result = NSL_ERR_INTERNAL;
825355b4669Sjacobs 	}
826355b4669Sjacobs 
827355b4669Sjacobs 	return (result);
828355b4669Sjacobs } /* _checkSunPrinter */
829355b4669Sjacobs 
830355b4669Sjacobs 
831355b4669Sjacobs 
832355b4669Sjacobs 
833355b4669Sjacobs 
834355b4669Sjacobs /*
835355b4669Sjacobs  * *****************************************************************************
836355b4669Sjacobs  *
837355b4669Sjacobs  * Function:    _addNewPrinterObject()
838355b4669Sjacobs  *
839355b4669Sjacobs  * Description: For the given printerName add a printer object into the
840355b4669Sjacobs  *              LDAP directory NS domain. The object is created with the
841355b4669Sjacobs  *              supplied attribute values. Note: if the printer's uri is
842355b4669Sjacobs  *              given that is used as the RDN otherwise the printer's
843355b4669Sjacobs  *              name is used as the RDN
844355b4669Sjacobs  *
845355b4669Sjacobs  * Parameters:
846355b4669Sjacobs  * Input:       LDAP    *ld        - existing ldap connection descriptor
847355b4669Sjacobs  *              uchar_t *printerName - Name of printer to be added
848355b4669Sjacobs  *              uchar_t *domainDN    - DN of the domain to add the printer
849355b4669Sjacobs  *              char    **attrList - user specified attribute values list
850355b4669Sjacobs  * Output:      None
851355b4669Sjacobs  *
852355b4669Sjacobs  * Returns:     NSL_RESULT - NSL_OK  = request actioned okay
853355b4669Sjacobs  *                           !NSL_OK = error
854355b4669Sjacobs  *
855355b4669Sjacobs  * *****************************************************************************
856355b4669Sjacobs  */
857355b4669Sjacobs 
858355b4669Sjacobs static NSL_RESULT
859355b4669Sjacobs _addNewPrinterObject(LDAP *ld, uchar_t *printerName,
860355b4669Sjacobs 			uchar_t *domainDN, char **attrList)
861355b4669Sjacobs 
862355b4669Sjacobs {
863355b4669Sjacobs 	NSL_RESULT result = NSL_ERR_ADD_FAILED;
864355b4669Sjacobs 	int lresult = 0;
865355b4669Sjacobs 	uchar_t *printerDN = NULL;
866355b4669Sjacobs 	LDAPMod **attrs = NULL;
867355b4669Sjacobs 
868355b4669Sjacobs 	/* ---------- */
869355b4669Sjacobs 
870355b4669Sjacobs 	if ((ld != NULL) && (printerName != NULL) && (domainDN != NULL) &&
871355b4669Sjacobs 		(attrList != NULL) && (attrList[0] != NULL))
872355b4669Sjacobs 	{
873355b4669Sjacobs 		result = _checkAttributes(attrList);
874355b4669Sjacobs 
875355b4669Sjacobs 		if (result == NSL_OK)
876355b4669Sjacobs 		{
877355b4669Sjacobs 			/*
878355b4669Sjacobs 			 * construct a DN for the printer from the
879355b4669Sjacobs 			 * printerName and printer-uri if given.
880355b4669Sjacobs 			 */
881355b4669Sjacobs 			printerDN = _constructPrinterDN(printerName,
882355b4669Sjacobs 						domainDN, attrList);
883355b4669Sjacobs 			if (printerDN != NULL)
884355b4669Sjacobs 			{
885355b4669Sjacobs 				/*
886355b4669Sjacobs 				 * setup attribute values in an LDAPMod
887355b4669Sjacobs 				 * structure and then add the object
888355b4669Sjacobs 				 */
889355b4669Sjacobs 				result = _constructAddLDAPMod(printerName,
890355b4669Sjacobs 							attrList, &attrs);
891355b4669Sjacobs 				if (result == NSL_OK)
892355b4669Sjacobs 				{
893355b4669Sjacobs 					lresult = ldap_add_s(ld,
894355b4669Sjacobs 						    (char *)printerDN, attrs);
895355b4669Sjacobs 					if (lresult == LDAP_SUCCESS)
896355b4669Sjacobs 					{
897355b4669Sjacobs 						result = NSL_OK;
898355b4669Sjacobs 					}
899355b4669Sjacobs 					else
900355b4669Sjacobs 					{
901355b4669Sjacobs 						result = NSL_ERR_ADD_FAILED;
902355b4669Sjacobs #ifdef DEBUG
903355b4669Sjacobs (void) ldap_perror(ld, "ldap_add_s");
904355b4669Sjacobs #endif
905355b4669Sjacobs 					}
906355b4669Sjacobs 
907355b4669Sjacobs 					(void) ldap_mods_free(attrs, 1);
908355b4669Sjacobs 				}
909355b4669Sjacobs 				free(printerDN);
910355b4669Sjacobs 			}
911355b4669Sjacobs 
912355b4669Sjacobs 			else
913355b4669Sjacobs 			{
914355b4669Sjacobs 				result = NSL_ERR_INTERNAL;
915355b4669Sjacobs 			}
916355b4669Sjacobs 		}
917355b4669Sjacobs 	}
918355b4669Sjacobs 
919355b4669Sjacobs 	else
920355b4669Sjacobs 	{
921355b4669Sjacobs 		result = NSL_ERR_INTERNAL;
922355b4669Sjacobs 	}
923355b4669Sjacobs 
924355b4669Sjacobs 	return (result);
925355b4669Sjacobs } /* _addNewPrinterObject */
926355b4669Sjacobs 
927355b4669Sjacobs 
928355b4669Sjacobs 
929355b4669Sjacobs 
930355b4669Sjacobs 
931355b4669Sjacobs 
932355b4669Sjacobs /*
933355b4669Sjacobs  * *****************************************************************************
934355b4669Sjacobs  *
935355b4669Sjacobs  * Function:    _modifyPrinterObject()
936355b4669Sjacobs  *
937355b4669Sjacobs  * Description: Modify the given LDAP printer object to set the new attributes
938355b4669Sjacobs  *              in the attribute list. If the printer's URI (specified in the
939355b4669Sjacobs  *              attrList) changes the URI of the object the request is rejected.
940355b4669Sjacobs  *
941355b4669Sjacobs  * Parameters:
942355b4669Sjacobs  * Input:       LDAP    *ld        - existing ldap connection descriptor
943355b4669Sjacobs  *              uchar_t *printerDN - DN of printer object to modify
944355b4669Sjacobs  *              uchar_t *printerName - Name of printer to be modified
945355b4669Sjacobs  *              uchar_t *domainDN    - DN of the domain the printer is in
946355b4669Sjacobs  *              char    **attrList - user specified attribute values list
947355b4669Sjacobs  * Output:      None
948355b4669Sjacobs  *
949355b4669Sjacobs  * Returns:     NSL_RESULT - NSL_OK = object modified okay
950355b4669Sjacobs  *
951355b4669Sjacobs  * *****************************************************************************
952355b4669Sjacobs  */
953355b4669Sjacobs 
954355b4669Sjacobs static NSL_RESULT
955355b4669Sjacobs _modifyPrinterObject(LDAP *ld, uchar_t *printerDN,
956355b4669Sjacobs 		uchar_t *printerName, uchar_t *domainDN, char **attrList)
957355b4669Sjacobs 
958355b4669Sjacobs {
959355b4669Sjacobs 	NSL_RESULT result = NSL_ERR_INTERNAL;
960355b4669Sjacobs 	int lresult = 0;
961355b4669Sjacobs 	int sunPrinter = 0;
962355b4669Sjacobs 	uchar_t *uriDN = NULL;
963355b4669Sjacobs 	LDAPMod **attrs = NULL;
964355b4669Sjacobs 	char **kvpList = NULL;
965355b4669Sjacobs 
966355b4669Sjacobs 	/* ---------- */
967355b4669Sjacobs 
968355b4669Sjacobs 	if ((ld != NULL) && (printerDN != NULL) && (printerName != NULL) &&
969355b4669Sjacobs 	    (domainDN != NULL) && (attrList != NULL) && (attrList[0] != NULL))
970355b4669Sjacobs 	{
971355b4669Sjacobs 		result = _checkAttributes(attrList);
972355b4669Sjacobs 
973355b4669Sjacobs 		if (result == NSL_OK)
974355b4669Sjacobs 		{
975355b4669Sjacobs 			/*
976355b4669Sjacobs 			 * The user may have requested that the printer object
977355b4669Sjacobs 			 * be given a new URI RDN, so construct a DN for the
978355b4669Sjacobs 			 * printer from the printerName or the printer-uri (if
979355b4669Sjacobs 			 * given).
980355b4669Sjacobs 			 */
981355b4669Sjacobs 			uriDN = _constructPrinterDN(NULL, domainDN, attrList);
982355b4669Sjacobs 
983355b4669Sjacobs 			/*
984355b4669Sjacobs 			 * compare the 2 DNs to see if the URI has changed,
985355b4669Sjacobs 			 * if uriDN is null then the DN hasn't changed
986355b4669Sjacobs 			 */
987355b4669Sjacobs 			if ((uriDN == NULL) || ((uriDN != NULL) &&
988355b4669Sjacobs 			    (_compareURIinDNs(printerDN, uriDN) == NSL_OK)))
989355b4669Sjacobs 			{
990355b4669Sjacobs 				/*
991355b4669Sjacobs 				 * setup the modify object LDAPMod
992355b4669Sjacobs 				 * structure and then do the modify
993355b4669Sjacobs 				 */
994355b4669Sjacobs 
995355b4669Sjacobs 				if (_checkSunPrinter(ld, printerDN) == NSL_OK)
996355b4669Sjacobs 				{
997355b4669Sjacobs 					sunPrinter = 1;
998355b4669Sjacobs 				}
999355b4669Sjacobs 
1000355b4669Sjacobs 				(void) _getCurrentKVPValues(ld,
1001355b4669Sjacobs 							printerDN, &kvpList);
1002355b4669Sjacobs 
1003355b4669Sjacobs 				result = _constructModLDAPMod(printerName,
1004355b4669Sjacobs 							sunPrinter, attrList,
1005355b4669Sjacobs 							&kvpList, &attrs);
1006355b4669Sjacobs 				_freeList(&kvpList);
1007355b4669Sjacobs 
1008355b4669Sjacobs 				if ((result == NSL_OK) && (attrs != NULL))
1009355b4669Sjacobs 				{
1010355b4669Sjacobs 					lresult = ldap_modify_s(
1011355b4669Sjacobs 						ld, (char *)printerDN, attrs);
1012355b4669Sjacobs 					if (lresult == LDAP_SUCCESS)
1013355b4669Sjacobs 					{
1014355b4669Sjacobs 						result = NSL_OK;
1015355b4669Sjacobs 					}
1016355b4669Sjacobs 					else
1017355b4669Sjacobs 					{
1018355b4669Sjacobs 						result = NSL_ERR_MOD_FAILED;
1019355b4669Sjacobs #ifdef DEBUG
1020355b4669Sjacobs (void) ldap_perror(ld, "ldap_modify_s");
1021355b4669Sjacobs #endif
1022355b4669Sjacobs 					}
1023355b4669Sjacobs 
1024355b4669Sjacobs 					(void) ldap_mods_free(attrs, 1);
1025355b4669Sjacobs 				}
1026355b4669Sjacobs 			}
1027355b4669Sjacobs 			else
1028355b4669Sjacobs 			{
1029355b4669Sjacobs 				/*
1030355b4669Sjacobs 				 * printer-uri name change has been requested
1031355b4669Sjacobs 				 * this is NOT allowed as it requires that
1032355b4669Sjacobs 				 * a new printer object is created
1033355b4669Sjacobs 				 */
1034355b4669Sjacobs 				result = NSL_ERR_RENAME;  /* NOT ALLOWED */
1035355b4669Sjacobs 			}
1036355b4669Sjacobs 
1037355b4669Sjacobs 			if (uriDN != NULL)
1038355b4669Sjacobs 			{
1039355b4669Sjacobs 				free(uriDN);
1040355b4669Sjacobs 			}
1041355b4669Sjacobs 		}
1042355b4669Sjacobs 	}
1043355b4669Sjacobs 
1044355b4669Sjacobs 	return (result);
1045355b4669Sjacobs } /* _modifyPrinterObject */
1046355b4669Sjacobs 
1047355b4669Sjacobs 
1048355b4669Sjacobs 
1049355b4669Sjacobs 
1050355b4669Sjacobs /*
1051355b4669Sjacobs  * *****************************************************************************
1052355b4669Sjacobs  *
1053355b4669Sjacobs  * Function:    _checkAttributes()
1054355b4669Sjacobs  *
1055355b4669Sjacobs  * Description: Check that the given attribute lists does not contain any
1056355b4669Sjacobs  *              key words that are not allowed.
1057355b4669Sjacobs  *
1058355b4669Sjacobs  * Parameters:
1059355b4669Sjacobs  * Input:       char **list - attribute list to check
1060355b4669Sjacobs  * Output:      None
1061355b4669Sjacobs  *
1062355b4669Sjacobs  * Returns:     NSL_RESULT - NSL_OK = checked okay
1063355b4669Sjacobs  *
1064355b4669Sjacobs  * *****************************************************************************
1065355b4669Sjacobs  */
1066355b4669Sjacobs 
1067355b4669Sjacobs static NSL_RESULT
1068355b4669Sjacobs _checkAttributes(char **list)
1069355b4669Sjacobs 
1070355b4669Sjacobs {
1071355b4669Sjacobs 	NSL_RESULT result = NSL_OK;
1072355b4669Sjacobs 	int len = 0;
1073355b4669Sjacobs 	char *attr = NULL;
1074355b4669Sjacobs 	char **p = NULL;
1075355b4669Sjacobs 
1076355b4669Sjacobs 	/* ------ */
1077355b4669Sjacobs 
1078355b4669Sjacobs 	for (p = list; (p != NULL) && (*p != NULL) && (result == NSL_OK); p++)
1079355b4669Sjacobs 	{
1080355b4669Sjacobs 		/* get length of this key word */
1081355b4669Sjacobs 
1082355b4669Sjacobs 		for (len = 0; ((*p)[len] != '=') && ((*p)[len] != '\0'); len++);
1083355b4669Sjacobs 
1084355b4669Sjacobs 		/* check if the key word is allowed */
1085355b4669Sjacobs 
1086355b4669Sjacobs 		if (strncasecmp(*p, ATTR_KVP, len) == 0)
1087355b4669Sjacobs 		{
1088355b4669Sjacobs 			/* not supported through this interface */
1089355b4669Sjacobs 			result = NSL_ERR_KVP;
1090355b4669Sjacobs 		}
1091355b4669Sjacobs 		else
1092355b4669Sjacobs 		if (strncasecmp(*p, ATTR_BSDADDR, len) == 0)
1093355b4669Sjacobs 		{
1094355b4669Sjacobs 			/* not supported through this interface */
1095355b4669Sjacobs 			result = NSL_ERR_BSDADDR;
1096355b4669Sjacobs 		}
1097355b4669Sjacobs 		else
1098355b4669Sjacobs 		if (strncasecmp(*p, ATTR_PNAME, len) == 0)
1099355b4669Sjacobs 		{
1100355b4669Sjacobs 			/* not supported through this interface */
1101355b4669Sjacobs 			result = NSL_ERR_PNAME;
1102355b4669Sjacobs 		}
1103355b4669Sjacobs 		else
1104355b4669Sjacobs 		{
1105355b4669Sjacobs 			/* check for any others */
1106355b4669Sjacobs 
1107355b4669Sjacobs 			attr = strdup(*p);
1108355b4669Sjacobs 			attr[len] = '\0'; /* terminate the key */
1109355b4669Sjacobs 
1110355b4669Sjacobs 			if (_attrInList(attr, nsl_attr_notAllowed))
1111355b4669Sjacobs 			{
1112355b4669Sjacobs 				result = NSL_ERR_NOTALLOWED;
1113355b4669Sjacobs 			}
1114355b4669Sjacobs 		}
1115355b4669Sjacobs 
1116355b4669Sjacobs 	}
1117355b4669Sjacobs 
1118355b4669Sjacobs 	return (result);
1119355b4669Sjacobs } /* _checkAttributes */
1120355b4669Sjacobs 
1121355b4669Sjacobs 
1122355b4669Sjacobs 
1123355b4669Sjacobs 
1124355b4669Sjacobs /*
1125355b4669Sjacobs  * *****************************************************************************
1126355b4669Sjacobs  *
1127355b4669Sjacobs  * Function:    _addLDAPmodValue()
1128355b4669Sjacobs  *
1129355b4669Sjacobs  * Description: Add the given attribute and its value to the LDAPMod array.
1130355b4669Sjacobs  *              If this is the first entry in the array then create it.
1131355b4669Sjacobs  *
1132355b4669Sjacobs  * Parameters:
1133355b4669Sjacobs  * Input:       LDAPMod ***attrs  - array to update
1134355b4669Sjacobs  *              char *type        - attribute to add into array
1135355b4669Sjacobs  *              char *value       - attribute value
1136355b4669Sjacobs  * Output:      None
1137355b4669Sjacobs  *
1138355b4669Sjacobs  * Returns:     NSL_RESULT - NSL_OK = added okay
1139355b4669Sjacobs  *
1140355b4669Sjacobs  * *****************************************************************************
1141355b4669Sjacobs  */
1142355b4669Sjacobs 
1143355b4669Sjacobs static NSL_RESULT
1144355b4669Sjacobs _addLDAPmodValue(LDAPMod ***attrs, char *type, char *value)
1145355b4669Sjacobs 
1146355b4669Sjacobs {
1147355b4669Sjacobs 	int i = 0;
1148355b4669Sjacobs 	int j = 0;
1149355b4669Sjacobs 	NSL_RESULT result = NSL_OK;
1150355b4669Sjacobs 
1151355b4669Sjacobs 	/* ---------- */
1152355b4669Sjacobs 
1153355b4669Sjacobs 	if ((attrs != NULL) && (type != NULL) && (value != NULL))
1154355b4669Sjacobs 	{
1155355b4669Sjacobs #ifdef DEBUG
1156355b4669Sjacobs printf("_addLDAPmodValue() type='%s', value='%s'\n", type, value);
1157355b4669Sjacobs #endif
1158355b4669Sjacobs 		/* search the existing LDAPMod array for the attribute */
1159355b4669Sjacobs 
1160355b4669Sjacobs 		for (i = 0; *attrs != NULL && (*attrs)[i] != NULL; i++)
1161355b4669Sjacobs 		{
1162355b4669Sjacobs 			if (strcasecmp((*attrs)[i]->mod_type, type) == 0)
1163355b4669Sjacobs 			{
1164355b4669Sjacobs 				break;
1165355b4669Sjacobs 			}
1166355b4669Sjacobs 		}
1167355b4669Sjacobs 
1168355b4669Sjacobs 		if (*attrs == NULL)
1169355b4669Sjacobs 		{
1170355b4669Sjacobs 			/* array empty so create it */
1171355b4669Sjacobs 
1172355b4669Sjacobs 			*attrs = (LDAPMod **)calloc(1, 2 * sizeof (LDAPMod *));
1173355b4669Sjacobs 			if (*attrs != NULL)
1174355b4669Sjacobs 			{
1175355b4669Sjacobs 				i = 0;
1176355b4669Sjacobs 			}
1177355b4669Sjacobs 			else
1178355b4669Sjacobs 			{
1179355b4669Sjacobs 				result = NSL_ERR_MEMORY;
1180355b4669Sjacobs 			}
1181355b4669Sjacobs 
1182355b4669Sjacobs 		}
1183355b4669Sjacobs 		else
1184355b4669Sjacobs 		if ((*attrs)[i] == NULL)
1185355b4669Sjacobs 		{
1186355b4669Sjacobs 			*attrs = (LDAPMod **)
1187355b4669Sjacobs 				realloc(*attrs, (i+2) * sizeof (LDAPMod *));
1188355b4669Sjacobs 			if (*attrs == NULL)
1189355b4669Sjacobs 			{
1190355b4669Sjacobs 				result = NSL_ERR_MEMORY;
1191355b4669Sjacobs 			}
1192355b4669Sjacobs 		}
1193355b4669Sjacobs 	}
1194355b4669Sjacobs 	else
1195355b4669Sjacobs 	{
1196355b4669Sjacobs 		result = NSL_ERR_INTERNAL;
1197355b4669Sjacobs 	}
1198355b4669Sjacobs 
1199355b4669Sjacobs 	if (result == NSL_OK)
1200355b4669Sjacobs 	{
1201355b4669Sjacobs 		if ((*attrs)[i] == NULL)
1202355b4669Sjacobs 		{
1203355b4669Sjacobs 			/* We've got a new slot. Create the new mod. */
1204355b4669Sjacobs 
1205355b4669Sjacobs 			(*attrs)[i] = (LDAPMod *) malloc(sizeof (LDAPMod));
1206355b4669Sjacobs 			if ((*attrs)[i] != NULL)
1207355b4669Sjacobs 			{
1208355b4669Sjacobs 				(*attrs)[i]->mod_op = LDAP_MOD_ADD;
1209355b4669Sjacobs 				(*attrs)[i]->mod_type = strdup(type);
1210355b4669Sjacobs 				(*attrs)[i]->mod_values = (char **)
1211355b4669Sjacobs 						malloc(2 * sizeof (char *));
1212355b4669Sjacobs 				if ((*attrs)[i]->mod_values  != NULL)
1213355b4669Sjacobs 				{
1214355b4669Sjacobs 					(*attrs)[i]->mod_values[0] =
1215355b4669Sjacobs 								strdup(value);
1216355b4669Sjacobs 					(*attrs)[i]->mod_values[1] = NULL;
1217355b4669Sjacobs 					(*attrs)[i+1] = NULL;
1218355b4669Sjacobs 				}
1219355b4669Sjacobs 				else
1220355b4669Sjacobs 				{
1221355b4669Sjacobs 					result = NSL_ERR_MEMORY;
1222355b4669Sjacobs 				}
1223355b4669Sjacobs 			}
1224355b4669Sjacobs 			else
1225355b4669Sjacobs 			{
1226355b4669Sjacobs 				result = NSL_ERR_MEMORY;
1227355b4669Sjacobs 			}
1228355b4669Sjacobs 		}
1229355b4669Sjacobs 
1230355b4669Sjacobs 		else
1231355b4669Sjacobs 		{
1232355b4669Sjacobs 			/* Found an existing entry so add value to it */
1233355b4669Sjacobs 
1234355b4669Sjacobs 			for (j = 0; (*attrs)[i]->mod_values[j] != NULL; j++);
1235355b4669Sjacobs 
1236355b4669Sjacobs 			(*attrs)[i]->mod_values =
1237355b4669Sjacobs 				(char **)realloc((*attrs)[i]->mod_values,
1238355b4669Sjacobs 						(j + 2) * sizeof (char *));
1239355b4669Sjacobs 			if ((*attrs)[i]->mod_values != NULL)
1240355b4669Sjacobs 			{
1241355b4669Sjacobs 				(*attrs)[i]->mod_values[j] = strdup(value);
1242355b4669Sjacobs 				(*attrs)[i]->mod_values[j+1] = NULL;
1243355b4669Sjacobs 			}
1244355b4669Sjacobs 			else
1245355b4669Sjacobs 			{
1246355b4669Sjacobs 				result = NSL_ERR_MEMORY;
1247355b4669Sjacobs 			}
1248355b4669Sjacobs 		}
1249355b4669Sjacobs 	}
1250355b4669Sjacobs 
1251355b4669Sjacobs 	return (result);
1252355b4669Sjacobs } /* _addLDAPmodValue */
1253355b4669Sjacobs 
1254355b4669Sjacobs 
1255355b4669Sjacobs 
1256355b4669Sjacobs 
1257355b4669Sjacobs /*
1258355b4669Sjacobs  * *****************************************************************************
1259355b4669Sjacobs  *
1260355b4669Sjacobs  * Function:    _modLDAPmodValue()
1261355b4669Sjacobs  *
1262355b4669Sjacobs  * Description: Add the given attribute modify operation and its value into
1263355b4669Sjacobs  *              the LDAPMod array. This will either be a "replace" or a
1264355b4669Sjacobs  *              "delete"; value = null implies a "delete".
1265355b4669Sjacobs  *              If this is the first entry in the array then create it.
1266355b4669Sjacobs  *
1267355b4669Sjacobs  * Parameters:
1268355b4669Sjacobs  * Input:       LDAPMod ***attrs  - array to update
1269355b4669Sjacobs  *              char *type        - attribute to modify
1270355b4669Sjacobs  *              char *value       - attribute value, null implies "delete"
1271355b4669Sjacobs  * Output:      None
1272355b4669Sjacobs  *
1273355b4669Sjacobs  * Returns:     NSL_RESULT - NSL_OK = added okay
1274355b4669Sjacobs  *
1275355b4669Sjacobs  * *****************************************************************************
1276355b4669Sjacobs  */
1277355b4669Sjacobs 
1278355b4669Sjacobs static NSL_RESULT
1279355b4669Sjacobs _modLDAPmodValue(LDAPMod ***attrs, char *type, char *value)
1280355b4669Sjacobs 
1281355b4669Sjacobs {
1282355b4669Sjacobs 	int i = 0;
1283355b4669Sjacobs 	int j = 0;
1284355b4669Sjacobs 	NSL_RESULT result = NSL_OK;
1285355b4669Sjacobs 
1286355b4669Sjacobs 	/* ---------- */
1287355b4669Sjacobs 
1288355b4669Sjacobs 	if ((attrs != NULL) && (type != NULL))
1289355b4669Sjacobs 	{
1290355b4669Sjacobs #ifdef DEBUG
1291355b4669Sjacobs if (value != NULL)
1292355b4669Sjacobs printf("_modLDAPmodValue() REPLACE type='%s', value='%s'\n", type, value);
1293355b4669Sjacobs else
1294355b4669Sjacobs printf("_modLDAPmodValue() DELETE type='%s'\n", type);
1295355b4669Sjacobs #endif
1296355b4669Sjacobs 		/* search the existing LDAPMod array for the attribute */
1297355b4669Sjacobs 
1298355b4669Sjacobs 		for (i = 0; *attrs != NULL && (*attrs)[i] != NULL; i++)
1299355b4669Sjacobs 		{
1300355b4669Sjacobs 			if (strcasecmp((*attrs)[i]->mod_type, type) == 0)
1301355b4669Sjacobs 			{
1302355b4669Sjacobs 				break;
1303355b4669Sjacobs 			}
1304355b4669Sjacobs 		}
1305355b4669Sjacobs 
1306355b4669Sjacobs 		if (*attrs == NULL)
1307355b4669Sjacobs 		{
1308355b4669Sjacobs 			/* array empty so create it */
1309355b4669Sjacobs 
1310355b4669Sjacobs 			*attrs = (LDAPMod **)calloc(1, 2 * sizeof (LDAPMod *));
1311355b4669Sjacobs 			if (*attrs != NULL)
1312355b4669Sjacobs 			{
1313355b4669Sjacobs 				i = 0;
1314355b4669Sjacobs 			}
1315355b4669Sjacobs 			else
1316355b4669Sjacobs 			{
1317355b4669Sjacobs 				result = NSL_ERR_MEMORY;
1318355b4669Sjacobs 			}
1319355b4669Sjacobs 
1320355b4669Sjacobs 		}
1321355b4669Sjacobs 		else
1322355b4669Sjacobs 		if ((*attrs)[i] == NULL)
1323355b4669Sjacobs 		{
1324355b4669Sjacobs 			/* attribute not found in array so add slot for it */
1325355b4669Sjacobs 
1326355b4669Sjacobs 			*attrs = (LDAPMod **)
1327355b4669Sjacobs 				realloc(*attrs, (i+2) * sizeof (LDAPMod *));
1328355b4669Sjacobs 			if (*attrs == NULL)
1329355b4669Sjacobs 			{
1330355b4669Sjacobs 				result = NSL_ERR_MEMORY;
1331355b4669Sjacobs 			}
1332355b4669Sjacobs 		}
1333355b4669Sjacobs 	}
1334355b4669Sjacobs 	else
1335355b4669Sjacobs 	{
1336355b4669Sjacobs 		result = NSL_ERR_INTERNAL;
1337355b4669Sjacobs 	}
1338355b4669Sjacobs 
1339355b4669Sjacobs 	if (result == NSL_OK)
1340355b4669Sjacobs 	{
1341355b4669Sjacobs 		if ((*attrs)[i] == NULL)
1342355b4669Sjacobs 		{
1343355b4669Sjacobs 			/* We've got a new slot. Create the new mod entry */
1344355b4669Sjacobs 
1345355b4669Sjacobs 			(*attrs)[i] = (LDAPMod *) malloc(sizeof (LDAPMod));
1346355b4669Sjacobs 			if (((*attrs)[i] != NULL) && (value != NULL))
1347355b4669Sjacobs 			{
1348355b4669Sjacobs 				/* Do an attribute replace */
1349355b4669Sjacobs 
1350355b4669Sjacobs 				(*attrs)[i]->mod_op = LDAP_MOD_REPLACE;
1351355b4669Sjacobs 				(*attrs)[i]->mod_type = strdup(type);
1352355b4669Sjacobs 				(*attrs)[i]->mod_values = (char **)
1353355b4669Sjacobs 						malloc(2 * sizeof (char *));
1354355b4669Sjacobs 				if ((*attrs)[i]->mod_values  != NULL)
1355355b4669Sjacobs 				{
1356355b4669Sjacobs 					(*attrs)[i]->mod_values[0] =
1357355b4669Sjacobs 								strdup(value);
1358355b4669Sjacobs 					(*attrs)[i]->mod_values[1] = NULL;
1359355b4669Sjacobs 					(*attrs)[i+1] = NULL;
1360355b4669Sjacobs 				}
1361355b4669Sjacobs 				else
1362355b4669Sjacobs 				{
1363355b4669Sjacobs 					result = NSL_ERR_MEMORY;
1364355b4669Sjacobs 				}
1365355b4669Sjacobs 			}
1366355b4669Sjacobs 			else
1367355b4669Sjacobs 			if ((*attrs)[i] != NULL)
1368355b4669Sjacobs 			{
1369355b4669Sjacobs 				/* value is null so do an attribute delete */
1370355b4669Sjacobs 
1371355b4669Sjacobs 				(*attrs)[i]->mod_op = LDAP_MOD_DELETE;
1372355b4669Sjacobs 				(*attrs)[i]->mod_type = strdup(type);
1373355b4669Sjacobs 				(*attrs)[i]->mod_values = NULL;
1374355b4669Sjacobs 				(*attrs)[i+1] = NULL;
1375355b4669Sjacobs 			}
1376355b4669Sjacobs 			else
1377355b4669Sjacobs 			{
1378355b4669Sjacobs 				result = NSL_ERR_MEMORY; /* malloc failed */
1379355b4669Sjacobs 			}
1380355b4669Sjacobs 		}
1381355b4669Sjacobs 
1382355b4669Sjacobs 		else
1383355b4669Sjacobs 		{
1384355b4669Sjacobs 			/* Found an existing entry so add value to it */
1385355b4669Sjacobs 
1386355b4669Sjacobs 			if (value != NULL)
1387355b4669Sjacobs 			{
1388355b4669Sjacobs 			    /* add value to attribute's replace list */
1389355b4669Sjacobs 
1390355b4669Sjacobs 			    if ((*attrs)[i]->mod_op == LDAP_MOD_REPLACE)
1391355b4669Sjacobs 			    {
1392355b4669Sjacobs 				for (j = 0;
1393355b4669Sjacobs 				    (*attrs)[i]->mod_values[j] != NULL; j++);
1394355b4669Sjacobs 
1395355b4669Sjacobs 				(*attrs)[i]->mod_values =
1396355b4669Sjacobs 				(char **)realloc((*attrs)[i]->mod_values,
1397355b4669Sjacobs 						(j + 2) * sizeof (char *));
1398355b4669Sjacobs 				if ((*attrs)[i]->mod_values != NULL)
1399355b4669Sjacobs 				{
1400355b4669Sjacobs 					(*attrs)[i]->mod_values[j] =
1401355b4669Sjacobs 								strdup(value);
1402355b4669Sjacobs 					(*attrs)[i]->mod_values[j+1] = NULL;
1403355b4669Sjacobs 				}
1404355b4669Sjacobs 				else
1405355b4669Sjacobs 				{
1406355b4669Sjacobs 					result = NSL_ERR_MEMORY;
1407355b4669Sjacobs 				}
1408355b4669Sjacobs 			    }
1409355b4669Sjacobs 			    else
1410355b4669Sjacobs 			    {
1411355b4669Sjacobs 				/* Delete and replace not allowed */
1412355b4669Sjacobs 				result = NSL_ERR_MULTIOP;
1413355b4669Sjacobs 			    }
1414355b4669Sjacobs 			}
1415355b4669Sjacobs 
1416355b4669Sjacobs 			else
1417355b4669Sjacobs 			{
1418355b4669Sjacobs 				/*
1419355b4669Sjacobs 				 * attribute delete - so free any existing
1420355b4669Sjacobs 				 * entries in the value array
1421355b4669Sjacobs 				 */
1422355b4669Sjacobs 
1423355b4669Sjacobs 				(*attrs)[i]->mod_op = LDAP_MOD_DELETE;
1424355b4669Sjacobs 
1425355b4669Sjacobs 				if ((*attrs)[i]->mod_values != NULL)
1426355b4669Sjacobs 				{
1427355b4669Sjacobs 					for (j = 0;
1428355b4669Sjacobs 					    (*attrs)[i]->mod_values[j] != NULL;
1429355b4669Sjacobs 					    j++)
1430355b4669Sjacobs 					{
1431355b4669Sjacobs 					    free((*attrs)[i]->mod_values[j]);
1432355b4669Sjacobs 					}
1433355b4669Sjacobs 
1434355b4669Sjacobs 					free((*attrs)[i]->mod_values);
1435355b4669Sjacobs 					(*attrs)[i]->mod_values = NULL;
1436355b4669Sjacobs 				}
1437355b4669Sjacobs 			}
1438355b4669Sjacobs 		}
1439355b4669Sjacobs 	}
1440355b4669Sjacobs 
1441355b4669Sjacobs 	return (result);
1442355b4669Sjacobs } /* _modLDAPmodValue */
1443355b4669Sjacobs 
1444355b4669Sjacobs 
1445355b4669Sjacobs 
1446355b4669Sjacobs 
1447355b4669Sjacobs 
1448355b4669Sjacobs /*
1449355b4669Sjacobs  * *****************************************************************************
1450355b4669Sjacobs  *
1451355b4669Sjacobs  * Function:    _constructAddLDAPMod()
1452355b4669Sjacobs  *
1453355b4669Sjacobs  * Description: For the given attribute list construct an
1454355b4669Sjacobs  *              LDAPMod array for the printer object to be added. Default
1455355b4669Sjacobs  *              attribute values are included.
1456355b4669Sjacobs  *
1457355b4669Sjacobs  * Parameters:
1458355b4669Sjacobs  * Input:
1459355b4669Sjacobs  *              uchar_t *printerName - Name of printer to be added
1460355b4669Sjacobs  *              char    **attrList - user specified attribute values list
1461355b4669Sjacobs  * Output:      LDAPMod ***attrs  - pointer to the constructed array
1462355b4669Sjacobs  *
1463355b4669Sjacobs  * Returns:     NSL_RESULT - NSL_OK = constructed okay
1464355b4669Sjacobs  *
1465355b4669Sjacobs  * *****************************************************************************
1466355b4669Sjacobs  */
1467355b4669Sjacobs 
1468355b4669Sjacobs static NSL_RESULT
1469355b4669Sjacobs _constructAddLDAPMod(uchar_t *printerName, char **attrList,  LDAPMod ***attrs)
1470355b4669Sjacobs 
1471355b4669Sjacobs {
1472355b4669Sjacobs 	NSL_RESULT result = NSL_ERROR;
1473355b4669Sjacobs 	int len = 0;
1474355b4669Sjacobs 	char **p = NULL;
1475355b4669Sjacobs 	char *value = NULL;
1476355b4669Sjacobs 	char *attr = NULL;
1477355b4669Sjacobs 
1478355b4669Sjacobs 	/* ---------- */
1479355b4669Sjacobs 
1480355b4669Sjacobs 	if ((printerName != NULL) &&
1481355b4669Sjacobs 	    ((attrList != NULL) && (attrList[0] != NULL)) && (attrs != NULL))
1482355b4669Sjacobs 	{
1483355b4669Sjacobs 		*attrs = NULL;
1484355b4669Sjacobs 
1485355b4669Sjacobs 		/*
1486355b4669Sjacobs 		 * setup printer object attribute values in an LDAPMod structure
1487355b4669Sjacobs 		 */
1488355b4669Sjacobs 		result = _addLDAPmodValue(attrs, ATTR_OCLASS, OCV_TOP);
1489355b4669Sjacobs 		if (result == NSL_OK)
1490355b4669Sjacobs 		{
1491355b4669Sjacobs 			/* Structural Objectclass */
1492355b4669Sjacobs 			result =
1493355b4669Sjacobs 			    _addLDAPmodValue(attrs, ATTR_OCLASS, OCV_PSERVICE);
1494355b4669Sjacobs 		}
1495355b4669Sjacobs 		if (result == NSL_OK)
1496355b4669Sjacobs 		{
1497355b4669Sjacobs 			result = _addLDAPmodValue(attrs,
1498355b4669Sjacobs 						ATTR_OCLASS, OCV_PABSTRACT);
1499355b4669Sjacobs 		}
1500355b4669Sjacobs 		if (result == NSL_OK)
1501355b4669Sjacobs 		{
1502355b4669Sjacobs 			result = _addLDAPmodValue(attrs,
1503355b4669Sjacobs 						ATTR_OCLASS, OCV_SUNPRT);
1504355b4669Sjacobs 		}
1505355b4669Sjacobs 		if (result == NSL_OK)
1506355b4669Sjacobs 		{
1507355b4669Sjacobs 			result = _addLDAPmodValue(attrs,
1508355b4669Sjacobs 					ATTR_PNAME, (char *)printerName);
1509355b4669Sjacobs 		}
1510355b4669Sjacobs 
1511355b4669Sjacobs 		/*
1512355b4669Sjacobs 		 * Now work through the user supplied attribute
1513355b4669Sjacobs 		 * values list and add them into the LDAPMod array
1514355b4669Sjacobs 		 */
1515355b4669Sjacobs 
1516355b4669Sjacobs 		for (p = attrList;
1517355b4669Sjacobs 			(p != NULL) && (*p != NULL) && (result == NSL_OK); p++)
1518355b4669Sjacobs 		{
1519355b4669Sjacobs 			/* get length of this key word */
1520355b4669Sjacobs 
1521355b4669Sjacobs 			for (len = 0;
1522355b4669Sjacobs 			    ((*p)[len] != '=') && ((*p)[len] != '\0'); len++);
1523355b4669Sjacobs 
1524355b4669Sjacobs 			if ((strlen(*p) > len+1))
1525355b4669Sjacobs 			{
1526355b4669Sjacobs 				attr = strdup(*p);
1527355b4669Sjacobs 				attr[len] = '\0';
1528355b4669Sjacobs 				value = strdup(&attr[len+1]);
1529355b4669Sjacobs 
1530355b4669Sjacobs 				/* handle specific Key Value Pairs (KVP) */
1531355b4669Sjacobs 
1532355b4669Sjacobs 				if (strcasecmp(attr, NS_KEY_BSDADDR) == 0)
1533355b4669Sjacobs 				{
1534355b4669Sjacobs 					/* use LDAP attribute name */
1535355b4669Sjacobs 					free(attr);
1536355b4669Sjacobs 					attr = strdup(ATTR_BSDADDR);
1537355b4669Sjacobs 				}
1538355b4669Sjacobs 				else
1539355b4669Sjacobs 				if (_attrInLDAPList(attr) == 0)
1540355b4669Sjacobs 				{
1541355b4669Sjacobs 					/*
1542355b4669Sjacobs 					 * Non-LDAP attribute so use LDAP
1543355b4669Sjacobs 					 * KVP attribute and the given KVP
1544355b4669Sjacobs 					 * as the value, ie.
1545355b4669Sjacobs 					 * sun-printer-kvp=description=printer
1546355b4669Sjacobs 					 */
1547355b4669Sjacobs 					free(attr);
1548355b4669Sjacobs 					attr = strdup(ATTR_KVP);
1549355b4669Sjacobs 					value = strdup(*p);
1550355b4669Sjacobs 				}
1551355b4669Sjacobs 
1552355b4669Sjacobs 				/* add it into the LDAPMod array */
1553355b4669Sjacobs 
1554355b4669Sjacobs 				result = _addLDAPmodValue(attrs, attr, value);
1555355b4669Sjacobs 
1556355b4669Sjacobs 				free(attr);
1557355b4669Sjacobs 				free(value);
1558355b4669Sjacobs 			}
1559355b4669Sjacobs 		} /* for */
1560355b4669Sjacobs 
1561355b4669Sjacobs 		if ((result != NSL_OK) && (*attrs != NULL))
1562355b4669Sjacobs 		{
1563355b4669Sjacobs 			(void) ldap_mods_free(*attrs, 1);
1564355b4669Sjacobs 			attrs = NULL;
1565355b4669Sjacobs 		}
1566355b4669Sjacobs 	}
1567355b4669Sjacobs 	else
1568355b4669Sjacobs 	{
1569355b4669Sjacobs 		result = NSL_ERR_INTERNAL;
1570355b4669Sjacobs 	}
1571355b4669Sjacobs 
1572355b4669Sjacobs 	return (result);
1573355b4669Sjacobs } /* _constructAddLDAPMod */
1574355b4669Sjacobs 
1575355b4669Sjacobs 
1576355b4669Sjacobs 
1577355b4669Sjacobs 
1578355b4669Sjacobs 
1579355b4669Sjacobs 
1580355b4669Sjacobs 
1581355b4669Sjacobs /*
1582355b4669Sjacobs  * *****************************************************************************
1583355b4669Sjacobs  *
1584355b4669Sjacobs  * Function:    _constructModLDAPMod()
1585355b4669Sjacobs  *
1586355b4669Sjacobs  * Description: For the given modify attribute list, construct an
1587355b4669Sjacobs  *              LDAPMod array for the printer object to be modified
1588355b4669Sjacobs  *
1589355b4669Sjacobs  * Parameters:
1590355b4669Sjacobs  * Input:       uchar_t *printerName - name of printer to be modified
1591355b4669Sjacobs  *              int     sunPrinter - Boolean; object is a sunPrinter
1592355b4669Sjacobs  *              char    **attrList - user specified attribute values list
1593355b4669Sjacobs  *              char    ***oldKVPList - current list of KVP values on object
1594355b4669Sjacobs  * Output:      LDAPMod ***attrs  - pointer to the constructed array
1595355b4669Sjacobs  *
1596355b4669Sjacobs  * Returns:     NSL_RESULT - NSL_OK = constructed okay
1597355b4669Sjacobs  *
1598355b4669Sjacobs  * *****************************************************************************
1599355b4669Sjacobs  */
1600355b4669Sjacobs 
1601355b4669Sjacobs static NSL_RESULT
1602355b4669Sjacobs _constructModLDAPMod(uchar_t *printerName, int sunPrinter, char **attrList,
1603355b4669Sjacobs 			char ***oldKVPList, LDAPMod ***attrs)
1604355b4669Sjacobs 
1605355b4669Sjacobs {
1606355b4669Sjacobs 	NSL_RESULT result = NSL_OK;
1607355b4669Sjacobs 	int len = 0;
1608355b4669Sjacobs 	int kvpUpdated = 0;
1609355b4669Sjacobs 	int kvpExists = 0;
1610355b4669Sjacobs 	char **p = NULL;
1611355b4669Sjacobs 	char *value = NULL;
1612355b4669Sjacobs 	char *attr = NULL;
1613355b4669Sjacobs 
1614355b4669Sjacobs 	/* ---------- */
1615355b4669Sjacobs 
1616355b4669Sjacobs 	if ((printerName != NULL) &&
1617355b4669Sjacobs 	    ((attrList != NULL) && (attrList[0] != NULL)) && (attrs != NULL))
1618355b4669Sjacobs 	{
1619355b4669Sjacobs 		*attrs = NULL;
1620355b4669Sjacobs 
1621355b4669Sjacobs 		if ((oldKVPList != NULL) && (*oldKVPList != NULL))
1622355b4669Sjacobs 		{
1623355b4669Sjacobs 			kvpExists = 1;
1624355b4669Sjacobs 		}
1625355b4669Sjacobs 
1626355b4669Sjacobs 		if (!sunPrinter)
1627355b4669Sjacobs 		{
1628355b4669Sjacobs 			/*
1629355b4669Sjacobs 			 * The object was previously not a sunPrinter, so
1630355b4669Sjacobs 			 * add the required objectclass attribute value, and
1631355b4669Sjacobs 			 * ensure it has the printername attribute.
1632355b4669Sjacobs 			 */
1633355b4669Sjacobs 			result = _addLDAPmodValue(attrs,
1634355b4669Sjacobs 						ATTR_OCLASS, OCV_SUNPRT);
1635355b4669Sjacobs 			if (result == NSL_OK)
1636355b4669Sjacobs 			{
1637355b4669Sjacobs 				result = _modLDAPmodValue(attrs,
1638355b4669Sjacobs 					    ATTR_PNAME, (char *)printerName);
1639355b4669Sjacobs 			}
1640355b4669Sjacobs 		}
1641355b4669Sjacobs 
1642355b4669Sjacobs 		/*
1643355b4669Sjacobs 		 * work through the user supplied attribute
1644355b4669Sjacobs 		 * values list and add them into the LDAPMod array depending
1645355b4669Sjacobs 		 * on if they are a replace or delete attribute operation,
1646355b4669Sjacobs 		 * a "null value" means delete.
1647355b4669Sjacobs 		 */
1648355b4669Sjacobs 
1649355b4669Sjacobs 		for (p = attrList;
1650355b4669Sjacobs 			(p != NULL) && (*p != NULL) && (result == NSL_OK); p++)
1651355b4669Sjacobs 		{
1652355b4669Sjacobs 			/* get length of this key word */
1653355b4669Sjacobs 
1654355b4669Sjacobs 			for (len = 0;
1655355b4669Sjacobs 			    ((*p)[len] != '=') && ((*p)[len] != '\0'); len++);
1656355b4669Sjacobs 
1657355b4669Sjacobs 			if ((strlen(*p) > len+1))
1658355b4669Sjacobs 			{
1659355b4669Sjacobs 				attr = strdup(*p);
1660355b4669Sjacobs 				attr[len] = '\0';
1661355b4669Sjacobs 				value = strdup(&attr[len+1]);
1662355b4669Sjacobs 
1663355b4669Sjacobs 				/* handle specific Key Value Pairs (KVP) */
1664355b4669Sjacobs 
1665355b4669Sjacobs 				if ((_attrInLDAPList(attr) == 0) &&
1666355b4669Sjacobs 					(strcasecmp(attr, NS_KEY_BSDADDR) != 0))
1667355b4669Sjacobs 				{
1668355b4669Sjacobs 					/*
1669355b4669Sjacobs 					 * Non-LDAP attribute so use LDAP
1670355b4669Sjacobs 					 * KVP attribute and the given KVP as
1671355b4669Sjacobs 					 * the value, ie.
1672355b4669Sjacobs 					 * sun-printer-kvp=description=printer
1673355b4669Sjacobs 					 */
1674355b4669Sjacobs 					result = _modAttrKVP(*p, oldKVPList);
1675355b4669Sjacobs 					kvpUpdated = 1;
1676355b4669Sjacobs 				}
1677355b4669Sjacobs 
1678355b4669Sjacobs 				else
1679355b4669Sjacobs 				{
1680355b4669Sjacobs 					if (strcasecmp(attr, NS_KEY_BSDADDR) ==
1681355b4669Sjacobs 									0)
1682355b4669Sjacobs 					{
1683355b4669Sjacobs 						/*
1684355b4669Sjacobs 						 * use LDAP bsdaddr attribute
1685355b4669Sjacobs 						 * name
1686355b4669Sjacobs 						 */
1687355b4669Sjacobs 						free(attr);
1688355b4669Sjacobs 						attr = strdup(ATTR_BSDADDR);
1689355b4669Sjacobs 					}
1690355b4669Sjacobs 
1691355b4669Sjacobs 					/*
1692355b4669Sjacobs 					 * else
1693355b4669Sjacobs 					 *   use the supplied attribute name
1694355b4669Sjacobs 					 */
1695355b4669Sjacobs 
1696355b4669Sjacobs 					/* add it into the LDAPMod array */
1697355b4669Sjacobs 
1698355b4669Sjacobs 					result = _modLDAPmodValue(attrs,
1699355b4669Sjacobs 								attr, value);
1700355b4669Sjacobs 				}
1701355b4669Sjacobs 
1702355b4669Sjacobs 				free(attr);
1703355b4669Sjacobs 				free(value);
1704355b4669Sjacobs 			}
1705355b4669Sjacobs 
1706355b4669Sjacobs 			else
1707355b4669Sjacobs 			if (strlen(*p) >= 1)
1708355b4669Sjacobs 			{
1709355b4669Sjacobs 				/* handle attribute DELETE request */
1710355b4669Sjacobs 
1711355b4669Sjacobs 				attr = strdup(*p);
1712355b4669Sjacobs 				if (attr[len] == '=')
1713355b4669Sjacobs 				{
1714355b4669Sjacobs 					/* terminate "attribute=" */
1715355b4669Sjacobs 					attr[len] = '\0';
1716355b4669Sjacobs 				}
1717355b4669Sjacobs 
1718355b4669Sjacobs 				/* handle specific Key Value Pairs (KVP) */
1719355b4669Sjacobs 
1720355b4669Sjacobs 				if (strcasecmp(attr, NS_KEY_BSDADDR) == 0)
1721355b4669Sjacobs 				{
1722355b4669Sjacobs 					/* use LDAP bsdaddr attribute name */
1723355b4669Sjacobs 					result = _modLDAPmodValue(attrs,
1724355b4669Sjacobs 							ATTR_BSDADDR, NULL);
1725355b4669Sjacobs 				}
1726355b4669Sjacobs 				else
1727355b4669Sjacobs 				if (_attrInLDAPList(attr) == 0)
1728355b4669Sjacobs 				{
1729355b4669Sjacobs 					/*
1730355b4669Sjacobs 					 * Non-LDAP kvp, so sort items
1731355b4669Sjacobs 					 * in the kvp list
1732355b4669Sjacobs 					 */
1733355b4669Sjacobs 					result = _modAttrKVP(*p, oldKVPList);
1734355b4669Sjacobs 					kvpUpdated = 1;
1735355b4669Sjacobs 				}
1736355b4669Sjacobs 				else
1737355b4669Sjacobs 				{
1738355b4669Sjacobs 					result = _modLDAPmodValue(attrs,
1739355b4669Sjacobs 							attr, NULL);
1740355b4669Sjacobs 				}
1741355b4669Sjacobs 
1742355b4669Sjacobs 				free(attr);
1743355b4669Sjacobs 			}
1744355b4669Sjacobs 		} /* for */
1745355b4669Sjacobs 
1746355b4669Sjacobs 		if ((result == NSL_OK) && (kvpUpdated))
1747355b4669Sjacobs 		{
1748355b4669Sjacobs 			result = _attrAddKVP(attrs, *oldKVPList, kvpExists);
1749355b4669Sjacobs 		}
1750355b4669Sjacobs 
1751355b4669Sjacobs 		if ((result != NSL_OK) && (*attrs != NULL))
1752355b4669Sjacobs 		{
1753355b4669Sjacobs 			(void) ldap_mods_free(*attrs, 1);
1754355b4669Sjacobs 			*attrs = NULL;
1755355b4669Sjacobs 		}
1756355b4669Sjacobs 	}
1757355b4669Sjacobs 	else
1758355b4669Sjacobs 	{
1759355b4669Sjacobs 		result = NSL_ERR_INTERNAL;
1760355b4669Sjacobs 	}
1761355b4669Sjacobs 
1762355b4669Sjacobs 	return (result);
1763355b4669Sjacobs } /* _constructModLDAPMod */
1764355b4669Sjacobs 
1765355b4669Sjacobs 
1766355b4669Sjacobs 
1767355b4669Sjacobs 
1768355b4669Sjacobs 
1769355b4669Sjacobs 
1770355b4669Sjacobs /*
1771355b4669Sjacobs  * *****************************************************************************
1772355b4669Sjacobs  *
1773355b4669Sjacobs  * Function:    _compareURIinDNs()
1774355b4669Sjacobs  *
1775355b4669Sjacobs  * Description: For the 2 given printer object DNs compare the naming part
1776355b4669Sjacobs  *              part of the DN (printer-uri) to see if they are the same.
1777355b4669Sjacobs  *
1778355b4669Sjacobs  * Note:        This function only returns "compare failed" if their URI don't
1779355b4669Sjacobs  *              compare. Problems with the dn etc., return a good compare
1780355b4669Sjacobs  *              because I don't want us to create a new object for these
1781355b4669Sjacobs  *
1782355b4669Sjacobs  * Parameters:
1783355b4669Sjacobs  * Input:       uchar_t *dn1
1784355b4669Sjacobs  *              uchar_t *dn2
1785355b4669Sjacobs  * Output:      None
1786355b4669Sjacobs  *
1787355b4669Sjacobs  * Returns:     NSL_RESULT - NSL_OK = URIs are the same
1788355b4669Sjacobs  *
1789355b4669Sjacobs  * *****************************************************************************
1790355b4669Sjacobs  */
1791355b4669Sjacobs 
1792355b4669Sjacobs static NSL_RESULT
1793355b4669Sjacobs _compareURIinDNs(uchar_t *dn1, uchar_t *dn2)
1794355b4669Sjacobs 
1795355b4669Sjacobs {
1796355b4669Sjacobs 	NSL_RESULT result = NSL_OK;
1797355b4669Sjacobs 	uchar_t *DN1 = NULL;
1798355b4669Sjacobs 	uchar_t *DN2 = NULL;
1799355b4669Sjacobs 	char *p1 = NULL;
1800355b4669Sjacobs 	char *p2 = NULL;
1801355b4669Sjacobs 
1802355b4669Sjacobs 	/* --------- */
1803355b4669Sjacobs 
1804355b4669Sjacobs 	if ((dn1 != NULL) && (dn2 != NULL))
1805355b4669Sjacobs 	{
1806355b4669Sjacobs 		DN1 = (uchar_t *)strdup((char *)dn1);
1807355b4669Sjacobs 		DN2 = (uchar_t *)strdup((char *)dn2);
1808355b4669Sjacobs 
1809355b4669Sjacobs 		/* terminate each string after the printer-uri */
1810355b4669Sjacobs 
1811355b4669Sjacobs 		p1 = strstr((char *)DN1, PCONTAINER);
1812355b4669Sjacobs 		/* move back to the comma */
1813355b4669Sjacobs 		while ((p1 != NULL) && (*p1 != ',') && (p1 >= (char *)DN1))
1814355b4669Sjacobs 		{
1815355b4669Sjacobs 			p1--;
1816355b4669Sjacobs 		}
1817355b4669Sjacobs 
1818355b4669Sjacobs 		p2 = strstr((char *)DN2, PCONTAINER);
1819355b4669Sjacobs 		/* move back to the comma */
1820355b4669Sjacobs 		while ((p2 != NULL) && (*p2 != ',') && (p2 >= (char *)DN2))
1821355b4669Sjacobs 		{
1822355b4669Sjacobs 			p2--;
1823355b4669Sjacobs 		}
1824355b4669Sjacobs 
1825355b4669Sjacobs 		if ((*p1 == ',') && (*p2 == ','))
1826355b4669Sjacobs 		{
1827355b4669Sjacobs 			*p1 = '\0';	/* re-terminate it */
1828355b4669Sjacobs 			*p2 = '\0';	/* re-terminate it */
1829355b4669Sjacobs 
1830355b4669Sjacobs 			/* do the compare */
1831355b4669Sjacobs 
1832355b4669Sjacobs 			/*
1833355b4669Sjacobs 			 * Note: SHOULD really normalise the 2 DNs before
1834355b4669Sjacobs 			 * doing the compare
1835355b4669Sjacobs 			 */
1836355b4669Sjacobs #ifdef DEBUG
1837355b4669Sjacobs printf("_compareURIinDNs() @1 (%s) (%s)\n", DN1, DN2);
1838355b4669Sjacobs #endif
1839355b4669Sjacobs 			if (strcasecmp((char *)DN1, (char *)DN2) != 0)
1840355b4669Sjacobs 			{
1841355b4669Sjacobs 				result = NSL_ERROR;
1842355b4669Sjacobs 			}
1843355b4669Sjacobs 
1844355b4669Sjacobs 		}
1845355b4669Sjacobs 
1846355b4669Sjacobs 		free(DN1);
1847355b4669Sjacobs 		free(DN2);
1848355b4669Sjacobs 	}
1849355b4669Sjacobs 
1850355b4669Sjacobs 	return (result);
1851355b4669Sjacobs } /* _compareURIinDNs */
1852355b4669Sjacobs 
1853355b4669Sjacobs 
1854355b4669Sjacobs 
1855355b4669Sjacobs 
1856355b4669Sjacobs 
1857355b4669Sjacobs 
1858355b4669Sjacobs 
1859355b4669Sjacobs /*
1860355b4669Sjacobs  * *****************************************************************************
1861355b4669Sjacobs  *
1862355b4669Sjacobs  * Function:    _getThisNSDomainDN()
1863355b4669Sjacobs  *
1864355b4669Sjacobs  * Description: Get the current Name Service Domain DN
1865355b4669Sjacobs  *              This is extracted from the result of executing ldaplist.
1866355b4669Sjacobs  *
1867355b4669Sjacobs  * Note:        Do it this way until the NS LDAP library interface is
1868355b4669Sjacobs  *              made public.
1869355b4669Sjacobs  *
1870355b4669Sjacobs  * Parameters:
1871355b4669Sjacobs  * Input:       None
1872355b4669Sjacobs  * Output:      None
1873355b4669Sjacobs  *
1874355b4669Sjacobs  * Returns:     uchar_t*  - pointer to NS Domain DN (The caller should free this
1875355b4669Sjacobs  *                          returned memory).
1876355b4669Sjacobs  *
1877355b4669Sjacobs  * *****************************************************************************
1878355b4669Sjacobs  */
1879355b4669Sjacobs 
1880355b4669Sjacobs #define	LDAPLIST_D	"/usr/bin/ldaplist -d 2>&1"
1881355b4669Sjacobs #define	DNID		"dn: "
1882355b4669Sjacobs 
1883355b4669Sjacobs static uchar_t *
1884355b4669Sjacobs _getThisNSDomainDN(void)
1885355b4669Sjacobs 
1886355b4669Sjacobs {
1887355b4669Sjacobs 	uchar_t *domainDN = NULL;
1888355b4669Sjacobs 	char *cp = NULL;
1889355b4669Sjacobs 	char buf[BUFSIZ] = "";
1890355b4669Sjacobs 
1891355b4669Sjacobs 	/* --------- */
1892355b4669Sjacobs 
1893355b4669Sjacobs 	if (_popen(LDAPLIST_D, buf, sizeof (buf)) == 0)
1894355b4669Sjacobs 	{
1895355b4669Sjacobs 		if ((cp = strstr(buf, DNID)) != NULL)
1896355b4669Sjacobs 		{
1897355b4669Sjacobs 			cp += strlen(DNID);  /* increment past "dn: " label */
1898355b4669Sjacobs 			domainDN = (uchar_t *)strdup(cp);
1899355b4669Sjacobs 
1900355b4669Sjacobs 			if ((cp = strchr((char *)domainDN, '\n')) != NULL)
1901355b4669Sjacobs 			{
1902355b4669Sjacobs 				*cp = '\0'; /* terminate it */
1903355b4669Sjacobs 			}
1904355b4669Sjacobs 		}
1905355b4669Sjacobs 	}
1906355b4669Sjacobs 
1907355b4669Sjacobs 	return (domainDN);
1908355b4669Sjacobs } /* _getThisNSDomainDN */
1909355b4669Sjacobs 
1910355b4669Sjacobs 
1911355b4669Sjacobs 
1912355b4669Sjacobs 
1913355b4669Sjacobs 
1914355b4669Sjacobs /*
1915355b4669Sjacobs  * *****************************************************************************
1916355b4669Sjacobs  *
1917355b4669Sjacobs  * Function:    _popen()
1918355b4669Sjacobs  *
1919355b4669Sjacobs  * Description: General popen function. The caller should always use a full
1920355b4669Sjacobs  *              path cmd.
1921355b4669Sjacobs  *
1922355b4669Sjacobs  * Parameters:
1923355b4669Sjacobs  * Input:       char *cmd - command line to execute
1924355b4669Sjacobs  *              char *buffer - ptr to buffer to put result in
1925355b4669Sjacobs  *              int  size - size of result buffer
1926355b4669Sjacobs  * Output:      None
1927355b4669Sjacobs  *
1928355b4669Sjacobs  * Returns:     int - 0 = opened okay
1929355b4669Sjacobs  *
1930355b4669Sjacobs  * *****************************************************************************
1931355b4669Sjacobs  */
1932355b4669Sjacobs 
1933355b4669Sjacobs static int
1934355b4669Sjacobs _popen(char *cmd, char *buffer, int size)
1935355b4669Sjacobs 
1936355b4669Sjacobs {
1937355b4669Sjacobs 	int result = -1;
1938355b4669Sjacobs 	int rsize = 0;
1939355b4669Sjacobs 	FILE *fptr;
1940355b4669Sjacobs 	char safe_cmd[BUFSIZ];
1941355b4669Sjacobs 	char linebuf[BUFSIZ];
1942355b4669Sjacobs 
1943355b4669Sjacobs 	/* -------- */
1944355b4669Sjacobs 
1945355b4669Sjacobs 	if ((cmd != NULL) && (buffer != NULL) && (size != 0))
1946355b4669Sjacobs 	{
1947355b4669Sjacobs 		(void) strcpy(buffer, "");
1948355b4669Sjacobs 		(void) strcpy(linebuf, "");
1949355b4669Sjacobs 		(void) snprintf(safe_cmd, BUFSIZ, "IFS=' \t'; %s", cmd);
1950355b4669Sjacobs 
1951355b4669Sjacobs 		if ((fptr = popen(safe_cmd, "r")) != NULL)
1952355b4669Sjacobs 		{
1953355b4669Sjacobs 			while ((fgets(linebuf, BUFSIZ, fptr) != NULL) &&
1954355b4669Sjacobs 							(rsize  < size))
1955355b4669Sjacobs 			{
1956355b4669Sjacobs 				rsize = strlcat(buffer, linebuf, size);
1957355b4669Sjacobs 				if (rsize >= size)
1958355b4669Sjacobs 				{
1959355b4669Sjacobs 					/* result is too long */
1960355b4669Sjacobs 					(void) memset(buffer, '\0', size);
1961355b4669Sjacobs 				}
1962355b4669Sjacobs 			}
1963355b4669Sjacobs 
1964355b4669Sjacobs 			if (strlen(buffer) > 0)
1965355b4669Sjacobs 			{
1966355b4669Sjacobs 				result = 0;
1967355b4669Sjacobs 			}
1968355b4669Sjacobs 
1969355b4669Sjacobs 			(void) pclose(fptr);
1970355b4669Sjacobs 		}
1971355b4669Sjacobs 	}
1972355b4669Sjacobs 
1973355b4669Sjacobs 	return (result);
1974355b4669Sjacobs } /* popen */
1975355b4669Sjacobs 
1976355b4669Sjacobs 
1977355b4669Sjacobs /*
1978355b4669Sjacobs  * *****************************************************************************
1979355b4669Sjacobs  *
1980355b4669Sjacobs  * Function:    _attrInList()
1981355b4669Sjacobs  *
1982355b4669Sjacobs  * Description: For the given list check if the attribute is it
1983355b4669Sjacobs  *
1984355b4669Sjacobs  * Parameters:
1985355b4669Sjacobs  * Input:       char *attr   - attribute to check
1986355b4669Sjacobs  *              char **list  - list of attributes to check against
1987355b4669Sjacobs  * Output:      None
1988355b4669Sjacobs  *
1989355b4669Sjacobs  * Returns:     int - TRUE = attr found in list
1990355b4669Sjacobs  *
1991355b4669Sjacobs  * *****************************************************************************
1992355b4669Sjacobs  */
1993355b4669Sjacobs 
1994355b4669Sjacobs static int
1995355b4669Sjacobs _attrInList(char *attr, const char **list)
1996355b4669Sjacobs 
1997355b4669Sjacobs {
1998355b4669Sjacobs 	int result = 0;
1999355b4669Sjacobs 	int j;
2000355b4669Sjacobs 
2001355b4669Sjacobs 	/* ------- */
2002355b4669Sjacobs 
2003355b4669Sjacobs 	if ((attr != NULL) && (list != NULL))
2004355b4669Sjacobs 	{
2005355b4669Sjacobs 		for (j = 0; (list[j] != NULL) && (result != 1); j++)
2006355b4669Sjacobs 		{
2007355b4669Sjacobs 			if (strcasecmp(list[j], attr) == 0)
2008355b4669Sjacobs 			{
2009355b4669Sjacobs 				result = 1; /* found */
2010355b4669Sjacobs 			}
2011355b4669Sjacobs 		}
2012355b4669Sjacobs 	}
2013355b4669Sjacobs 
2014355b4669Sjacobs 	return (result);
2015355b4669Sjacobs } /* _attrInList */
2016355b4669Sjacobs 
2017355b4669Sjacobs 
2018355b4669Sjacobs 
2019355b4669Sjacobs 
2020355b4669Sjacobs /*
2021355b4669Sjacobs  * *****************************************************************************
2022355b4669Sjacobs  *
2023355b4669Sjacobs  * Function:    _attrInLDAPList()
2024355b4669Sjacobs  *
2025355b4669Sjacobs  * Description: Checks to see if the given attribute is an LDAP printing
2026355b4669Sjacobs  *              attribute, ie. is either in an IPP objectclass or the
2027355b4669Sjacobs  *              sun printer objectclass. Note: some attributes are handled
2028355b4669Sjacobs  *              specifically outside this function, so are excluded from
2029355b4669Sjacobs  *              the lists that are checked.
2030355b4669Sjacobs  *
2031355b4669Sjacobs  * Parameters:
2032355b4669Sjacobs  * Input:       char *attr    - attribute to check
2033355b4669Sjacobs  * Output:      None
2034355b4669Sjacobs  *
2035355b4669Sjacobs  * Returns:     int - TRUE = attr found in list
2036355b4669Sjacobs  *
2037355b4669Sjacobs  * *****************************************************************************
2038355b4669Sjacobs  */
2039355b4669Sjacobs 
2040355b4669Sjacobs static int
2041355b4669Sjacobs _attrInLDAPList(char *attr)
2042355b4669Sjacobs 
2043355b4669Sjacobs {
2044355b4669Sjacobs 	int result = 0;
2045355b4669Sjacobs 
2046355b4669Sjacobs 	/* ------- */
2047355b4669Sjacobs 
2048355b4669Sjacobs 	if (_attrInList(attr, nsl_attr_printerService))
2049355b4669Sjacobs 	{
2050355b4669Sjacobs 		result = 1;	/* in list */
2051355b4669Sjacobs 	}
2052355b4669Sjacobs 	else
2053355b4669Sjacobs 	if (_attrInList(attr, nsl_attr_printerIPP))
2054355b4669Sjacobs 	{
2055355b4669Sjacobs 		result = 1;	/* in list */
2056355b4669Sjacobs 	}
2057355b4669Sjacobs 	else
2058355b4669Sjacobs 	if (_attrInList(attr, nsl_attr_sunPrinter))
2059355b4669Sjacobs 	{
2060355b4669Sjacobs 		result = 1;	/* in list */
2061355b4669Sjacobs 	}
2062355b4669Sjacobs 
2063355b4669Sjacobs 	return (result);
2064355b4669Sjacobs } /* _attrInLDAPList */
2065355b4669Sjacobs 
2066355b4669Sjacobs 
2067355b4669Sjacobs 
2068355b4669Sjacobs 
2069355b4669Sjacobs /*
2070355b4669Sjacobs  * *****************************************************************************
2071355b4669Sjacobs  *
2072355b4669Sjacobs  * Function:    _getCurrentKVPValues()
2073355b4669Sjacobs  *
2074355b4669Sjacobs  * Description: For the given printer object read the current set of values
2075355b4669Sjacobs  *              the object has for the sun-printer-kvp (Key Value pair)
2076355b4669Sjacobs  *
2077355b4669Sjacobs  * Parameters:
2078355b4669Sjacobs  * Input:       LDAP *ld       - existing ldap connection descriptor
2079355b4669Sjacobs  *              char *objectDN - DN to search for
2080355b4669Sjacobs  * Output:      char ***list   - returned set of kvp values
2081355b4669Sjacobs  *
2082355b4669Sjacobs  * Result:      NSL_RESULT - NSL_OK = object exists
2083355b4669Sjacobs  *
2084355b4669Sjacobs  * *****************************************************************************
2085355b4669Sjacobs  */
2086355b4669Sjacobs 
2087355b4669Sjacobs static NSL_RESULT
2088355b4669Sjacobs _getCurrentKVPValues(LDAP *ld, uchar_t *objectDN, char ***list)
2089355b4669Sjacobs 
2090355b4669Sjacobs {
2091355b4669Sjacobs 	NSL_RESULT result = NSL_ERR_UNKNOWN_PRINTER;
2092355b4669Sjacobs 	int sresult = LDAP_NO_SUCH_OBJECT;
2093355b4669Sjacobs 	int i = 0;
2094355b4669Sjacobs 	LDAPMessage *ldapMsg;
2095355b4669Sjacobs 	char *requiredAttrs[2] = { ATTR_KVP, NULL };
2096355b4669Sjacobs 	LDAPMessage *ldapEntry = NULL;
2097355b4669Sjacobs 	char *entryAttrib = NULL;
2098355b4669Sjacobs 	char **attribValues = NULL;
2099355b4669Sjacobs 	BerElement *berElement = NULL;
2100355b4669Sjacobs 
2101355b4669Sjacobs 	/* ---------- */
2102355b4669Sjacobs 
2103355b4669Sjacobs 	if ((list != NULL) && (ld != NULL) && (objectDN != NULL))
2104355b4669Sjacobs 	{
2105355b4669Sjacobs 		/* search for this Printer in the directory */
2106355b4669Sjacobs 
2107355b4669Sjacobs 		sresult = ldap_search_s(ld, (char *)objectDN, LDAP_SCOPE_BASE,
2108355b4669Sjacobs 				"(objectclass=*)", requiredAttrs, 0, &ldapMsg);
2109355b4669Sjacobs 		if (sresult == LDAP_SUCCESS)
2110355b4669Sjacobs 		{
2111355b4669Sjacobs 			/*
2112355b4669Sjacobs 			 * check that the object exists and extract its
2113355b4669Sjacobs 			 * KVP attribute values
2114355b4669Sjacobs 			 */
2115355b4669Sjacobs 			ldapEntry = ldap_first_entry(ld, ldapMsg);
2116355b4669Sjacobs 			if (ldapEntry != NULL)
2117355b4669Sjacobs 			{
2118355b4669Sjacobs 				entryAttrib = ldap_first_attribute(ld,
2119355b4669Sjacobs 							ldapEntry, &berElement);
2120355b4669Sjacobs 				if ((entryAttrib != NULL) &&
2121355b4669Sjacobs 				    (strcasecmp(entryAttrib, ATTR_KVP) == 0))
2122355b4669Sjacobs 
2123355b4669Sjacobs 				{
2124355b4669Sjacobs #ifdef DEBUG
2125355b4669Sjacobs printf("Attribute: %s, its values are:\n", entryAttrib);
2126355b4669Sjacobs #endif
2127355b4669Sjacobs 					/*
2128355b4669Sjacobs 					 * add each KVP value to the list
2129355b4669Sjacobs 					 * that we will return
2130355b4669Sjacobs 					 */
2131355b4669Sjacobs 					attribValues = ldap_get_values(
2132355b4669Sjacobs 						ld, ldapEntry, entryAttrib);
2133355b4669Sjacobs 					for (i = 0;
2134355b4669Sjacobs 						attribValues[i] != NULL; i++)
2135355b4669Sjacobs 					{
2136355b4669Sjacobs 					    *list = (char **)
2137355b4669Sjacobs 						list_append((void **)*list,
2138355b4669Sjacobs 						    strdup(attribValues[i]));
2139355b4669Sjacobs #ifdef DEBUG
2140355b4669Sjacobs printf("\t%s\n", attribValues[i]);
2141355b4669Sjacobs #endif
2142355b4669Sjacobs 					}
2143355b4669Sjacobs 					(void) ldap_value_free(attribValues);
2144355b4669Sjacobs 				}
2145355b4669Sjacobs 
2146355b4669Sjacobs 				if ((entryAttrib != NULL) &&
2147355b4669Sjacobs 				    (berElement != NULL))
2148355b4669Sjacobs 				{
2149355b4669Sjacobs 					ber_free(berElement, 0);
2150355b4669Sjacobs 				}
2151355b4669Sjacobs 
2152355b4669Sjacobs 
2153355b4669Sjacobs 				/* object found */
2154355b4669Sjacobs 				result = NSL_OK;
2155355b4669Sjacobs 			}
2156355b4669Sjacobs 
2157355b4669Sjacobs 			(void) ldap_msgfree(ldapMsg);
2158355b4669Sjacobs 		}
2159355b4669Sjacobs 	}
2160355b4669Sjacobs 
2161355b4669Sjacobs 	else
2162355b4669Sjacobs 	{
2163355b4669Sjacobs 		result = NSL_ERR_INTERNAL;
2164355b4669Sjacobs 	}
2165355b4669Sjacobs 
2166355b4669Sjacobs 	return (result);
2167355b4669Sjacobs } /* _getCurrentKVPValues */
2168355b4669Sjacobs 
2169355b4669Sjacobs 
2170355b4669Sjacobs 
2171355b4669Sjacobs /*
2172355b4669Sjacobs  * *****************************************************************************
2173355b4669Sjacobs  *
2174355b4669Sjacobs  * Function:    _freeList()
2175355b4669Sjacobs  *
2176355b4669Sjacobs  * Description: Free the list created by list_append() where the items in
2177355b4669Sjacobs  *              the list have been strdup'ed.
2178355b4669Sjacobs  *
2179355b4669Sjacobs  * Parameters:
2180355b4669Sjacobs  * Input:       char ***list   - returned set of kvp values
2181355b4669Sjacobs  *
2182355b4669Sjacobs  * Result:      void
2183355b4669Sjacobs  *
2184355b4669Sjacobs  * *****************************************************************************
2185355b4669Sjacobs  */
2186355b4669Sjacobs 
2187355b4669Sjacobs static void
2188355b4669Sjacobs _freeList(char ***list)
2189355b4669Sjacobs 
2190355b4669Sjacobs {
2191355b4669Sjacobs 	int i = 0;
2192355b4669Sjacobs 
2193355b4669Sjacobs 	/* ------ */
2194355b4669Sjacobs 
2195355b4669Sjacobs 	if (list != NULL)
2196355b4669Sjacobs 	{
2197355b4669Sjacobs 		if (*list != NULL)
2198355b4669Sjacobs 		{
2199355b4669Sjacobs 			for (i = 0; (*list)[i] != NULL; i++)
2200355b4669Sjacobs 			{
2201355b4669Sjacobs 				free((*list)[i]);
2202355b4669Sjacobs 			}
2203355b4669Sjacobs 			free(*list);
2204355b4669Sjacobs 		}
2205355b4669Sjacobs 
2206355b4669Sjacobs 		*list = NULL;
2207355b4669Sjacobs 	}
2208355b4669Sjacobs } /* _freeList */
2209355b4669Sjacobs 
2210355b4669Sjacobs 
2211355b4669Sjacobs 
2212355b4669Sjacobs /*
2213355b4669Sjacobs  * *****************************************************************************
2214355b4669Sjacobs  *
2215355b4669Sjacobs  * Function:    _modAttrKVP()
2216355b4669Sjacobs  *
2217355b4669Sjacobs  * Description: Sort out the KVP attribute value list, such that this new
2218355b4669Sjacobs  *              value takes precidence over any existing value in the list.
2219355b4669Sjacobs  *              The current list is updated to remove this key, and the new
2220355b4669Sjacobs  *              key "value" is added to the list, eg. for
2221355b4669Sjacobs  *                  value: bbb=ddddd
2222355b4669Sjacobs  *                  and kvpList:
2223355b4669Sjacobs  *                         aaa=yyyy
2224355b4669Sjacobs  *                         bbb=zzzz
2225355b4669Sjacobs  *                         ccc=xxxx
2226355b4669Sjacobs  *                  the resulting kvpList is:
2227355b4669Sjacobs  *                         aaa=yyyy
2228355b4669Sjacobs  *                         ccc=xxxx
2229355b4669Sjacobs  *                         bbb=ddddd
2230355b4669Sjacobs  *
2231355b4669Sjacobs  * Note:        When all new values have been handled the function _attrAddKVP()
2232355b4669Sjacobs  *              must be called to add the "new list" values into the
2233355b4669Sjacobs  *              LDAPMod array.
2234355b4669Sjacobs  *
2235355b4669Sjacobs  * Parameters:
2236355b4669Sjacobs  * Input:       char *value       - Key Value Pair to process,
2237355b4669Sjacobs  *                                  eg. aaaaa=hhhhh, where aaaaa is the key
2238355b4669Sjacobs  *              char ***kvpList   - list of current KVP values
2239355b4669Sjacobs  * Output:      char ***kvpList   - updated list of KVP values
2240355b4669Sjacobs  *
2241355b4669Sjacobs  * Returns:     NSL_RESULT - NSL_OK = done okay
2242355b4669Sjacobs  *
2243355b4669Sjacobs  * *****************************************************************************
2244355b4669Sjacobs  */
2245355b4669Sjacobs 
2246355b4669Sjacobs static NSL_RESULT
2247355b4669Sjacobs _modAttrKVP(char *value, char ***kvpList)
2248355b4669Sjacobs 
2249355b4669Sjacobs {
2250355b4669Sjacobs 	NSL_RESULT result = NSL_ERR_INTERNAL;
2251355b4669Sjacobs 	int i = 0;
2252355b4669Sjacobs 	int inList = 0;
2253355b4669Sjacobs 	int keyDelete = 0;
2254355b4669Sjacobs 	char *key = NULL;
2255355b4669Sjacobs 	char **p = NULL;
2256355b4669Sjacobs 	char **newList = NULL;
2257355b4669Sjacobs 
2258355b4669Sjacobs 	/* ------- */
2259355b4669Sjacobs 
2260355b4669Sjacobs 	if ((value != NULL) && (kvpList != NULL))
2261355b4669Sjacobs 	{
2262355b4669Sjacobs 		result = NSL_OK;
2263355b4669Sjacobs 
2264355b4669Sjacobs 		/* extract "key" from value */
2265355b4669Sjacobs 
2266355b4669Sjacobs 		key = strdup(value);
2267355b4669Sjacobs 
2268355b4669Sjacobs 		for (i = 0; ((key)[i] != '=') && ((key)[i] != '\0'); i++);
2269355b4669Sjacobs 		key[i] = '\0'; /* terminate the key */
2270355b4669Sjacobs 
2271355b4669Sjacobs 		/* Is this a request to delete a "key" value */
2272355b4669Sjacobs 
2273355b4669Sjacobs 		if ((value[i] == '\0') || (value[i+1] == '\0'))
2274355b4669Sjacobs 		{
2275355b4669Sjacobs 			/* this is a request to delete the key */
2276355b4669Sjacobs 			keyDelete = 1;
2277355b4669Sjacobs 		}
2278355b4669Sjacobs 
2279355b4669Sjacobs 		if ((*kvpList != NULL) && (**kvpList != NULL))
2280355b4669Sjacobs 		{
2281355b4669Sjacobs 			/*
2282355b4669Sjacobs 			 * for each item in the list remove it if the keys match
2283355b4669Sjacobs 			 */
2284355b4669Sjacobs 			for (p = *kvpList; *p != NULL; p++)
2285355b4669Sjacobs 			{
2286355b4669Sjacobs 				for (i = 0;
2287355b4669Sjacobs 				    ((*p)[i] != '=') && ((*p)[i] != '\0'); i++);
2288355b4669Sjacobs 
2289355b4669Sjacobs 				if ((strlen(key) == i) &&
2290355b4669Sjacobs 					(strncasecmp(*p, key, i) == 0))
2291355b4669Sjacobs 				{
2292355b4669Sjacobs 					inList = 1;
2293355b4669Sjacobs 				}
2294355b4669Sjacobs 				else
2295355b4669Sjacobs 				{
2296355b4669Sjacobs 					/* no match so add value to new list */
2297355b4669Sjacobs 					newList = (char **)list_append(
2298355b4669Sjacobs 							(void **)newList,
2299355b4669Sjacobs 							strdup(*p));
2300355b4669Sjacobs 				}
2301355b4669Sjacobs 			}
2302355b4669Sjacobs 		}
2303355b4669Sjacobs 
2304355b4669Sjacobs 		/*
2305355b4669Sjacobs 		 * if it was not a DELETE request add the new key value into
2306355b4669Sjacobs 		 * the newList, otherwise we have already removed the key
2307355b4669Sjacobs 		 */
2308355b4669Sjacobs 
2309355b4669Sjacobs 		if (!keyDelete)
2310355b4669Sjacobs 		{
2311355b4669Sjacobs 			newList = (char **)list_append((void **)newList,
2312355b4669Sjacobs 							strdup(value));
2313355b4669Sjacobs 		}
2314355b4669Sjacobs 
2315355b4669Sjacobs 		if ((newList != NULL) || (inList))
2316355b4669Sjacobs 		{
2317355b4669Sjacobs 			/* replace old list with the newList */
2318355b4669Sjacobs 			_freeList(kvpList);
2319355b4669Sjacobs 			*kvpList = newList;
2320355b4669Sjacobs 		}
2321355b4669Sjacobs 
2322355b4669Sjacobs 		free(key);
2323355b4669Sjacobs 	}
2324355b4669Sjacobs 
2325355b4669Sjacobs 	return (result);
2326355b4669Sjacobs } /* modAttrKVP */
2327355b4669Sjacobs 
2328355b4669Sjacobs 
2329355b4669Sjacobs 
2330355b4669Sjacobs 
2331355b4669Sjacobs /*
2332355b4669Sjacobs  * *****************************************************************************
2333355b4669Sjacobs  *
2334355b4669Sjacobs  * Function:    _attrAddKVP()
2335355b4669Sjacobs  *
2336355b4669Sjacobs  * Description: Process KVP items in the kvpList adding them to the
2337355b4669Sjacobs  *              LDAPMod modify array. If the list is empty but there were
2338355b4669Sjacobs  *              previously LDAP KVP values delete them.
2339355b4669Sjacobs  *
2340355b4669Sjacobs  * Note:        This function should only be called when all the new KVP
2341355b4669Sjacobs  *              items have been processed by _modAttrKVP()
2342355b4669Sjacobs  *
2343355b4669Sjacobs  * Parameters:
2344355b4669Sjacobs  * Input:       LDAPMod ***attrs - array to update
2345355b4669Sjacobs  *              char **kvpList   - list KVP values
2346355b4669Sjacobs  *              int  kvpExists   - object currently has LDAP KVP values
2347355b4669Sjacobs  * Output:      None
2348355b4669Sjacobs  *
2349355b4669Sjacobs  * Returns:     NSL_RESULT - NSL_OK = done okay
2350355b4669Sjacobs  *
2351355b4669Sjacobs  * *****************************************************************************
2352355b4669Sjacobs  */
2353355b4669Sjacobs 
2354355b4669Sjacobs static NSL_RESULT
2355355b4669Sjacobs _attrAddKVP(LDAPMod ***attrs, char **kvpList, int kvpExists)
2356355b4669Sjacobs 
2357355b4669Sjacobs {
2358355b4669Sjacobs 	NSL_RESULT result = NSL_OK;
2359355b4669Sjacobs 
2360355b4669Sjacobs 	/* ------- */
2361355b4669Sjacobs 
2362355b4669Sjacobs 	if (attrs != NULL)
2363355b4669Sjacobs 	{
2364355b4669Sjacobs 		if (kvpList != NULL)
2365355b4669Sjacobs 		{
2366355b4669Sjacobs 			while ((kvpList != NULL) && (*kvpList != NULL))
2367355b4669Sjacobs 			{
2368355b4669Sjacobs 				/* add item to LDAPMod array */
2369355b4669Sjacobs 
2370355b4669Sjacobs 				result =
2371355b4669Sjacobs 				    _modLDAPmodValue(attrs, ATTR_KVP, *kvpList);
2372355b4669Sjacobs 
2373355b4669Sjacobs 				kvpList++;
2374355b4669Sjacobs 			}
2375355b4669Sjacobs 		}
2376355b4669Sjacobs 		else
2377355b4669Sjacobs 		if (kvpExists)
2378355b4669Sjacobs 		{
2379355b4669Sjacobs 			/*
2380355b4669Sjacobs 			 * We now have no LDAP KVP values but there were
2381355b4669Sjacobs 			 * some previously, so delete them
2382355b4669Sjacobs 			 */
2383355b4669Sjacobs 			result = _modLDAPmodValue(attrs, ATTR_KVP, NULL);
2384355b4669Sjacobs 		}
2385355b4669Sjacobs 	}
2386355b4669Sjacobs 
2387355b4669Sjacobs 	else
2388355b4669Sjacobs 	{
2389355b4669Sjacobs 		result = NSL_ERR_INTERNAL;
2390355b4669Sjacobs 	}
2391355b4669Sjacobs 
2392355b4669Sjacobs 	return (result);
2393355b4669Sjacobs } /* _attrAddKVP */
2394355b4669Sjacobs 
2395355b4669Sjacobs 
2396355b4669Sjacobs 
2397355b4669Sjacobs 
2398355b4669Sjacobs /*
2399355b4669Sjacobs  * *****************************************************************************
2400355b4669Sjacobs  *
2401355b4669Sjacobs  * Function:    _manageReferralCredentials()
2402355b4669Sjacobs  *
2403355b4669Sjacobs  * Description: This function is called if a referral request is returned by
2404355b4669Sjacobs  *              the origonal LDAP server during the ldap update request call,
2405355b4669Sjacobs  *              eg. ldap_add_s(), ldap_modify_s() or ldap_delete_s().
2406355b4669Sjacobs  * Parameters:
2407355b4669Sjacobs  * Input:       LDAP *ld      - LDAP descriptor
2408355b4669Sjacobs  *              int freeit    - 0 = first call to get details
2409355b4669Sjacobs  *                            - 1 = second call to free details
2410355b4669Sjacobs  *                            - -1 = initial store of authentication details
2411355b4669Sjacobs  * Input/Output: char **dn    - returns DN to bind to on master
2412355b4669Sjacobs  *               char **credp - returns password for DN
2413355b4669Sjacobs  *               int *methodp - returns authentication type, eg. simple
2414355b4669Sjacobs  *
2415355b4669Sjacobs  * Returns:     int - 0 = okay
2416355b4669Sjacobs  *
2417355b4669Sjacobs  * *****************************************************************************
2418355b4669Sjacobs  */
2419355b4669Sjacobs static int _manageReferralCredentials(LDAP *ld, char **dn, char **credp,
2420355b4669Sjacobs 					int *methodp, int freeit)
2421355b4669Sjacobs 
2422355b4669Sjacobs {
2423355b4669Sjacobs 	int result = 0;
2424355b4669Sjacobs 	static char *sDN = NULL;
2425355b4669Sjacobs 	static char *sPasswd = NULL;
2426355b4669Sjacobs 	static int  sMethod = LDAP_AUTH_SIMPLE;
2427355b4669Sjacobs 
2428355b4669Sjacobs 	/* -------- */
2429355b4669Sjacobs 
2430355b4669Sjacobs 	if (freeit == 1)
2431355b4669Sjacobs 	{
2432355b4669Sjacobs 		/* second call - free memory */
2433355b4669Sjacobs 
2434355b4669Sjacobs 		if ((dn != NULL) && (*dn != NULL))
2435355b4669Sjacobs 		{
2436355b4669Sjacobs 			free(*dn);
2437355b4669Sjacobs 		}
2438355b4669Sjacobs 
2439355b4669Sjacobs 		if ((credp != NULL) && (*credp != NULL))
2440355b4669Sjacobs 		{
2441355b4669Sjacobs 			free(*credp);
2442355b4669Sjacobs 		}
2443355b4669Sjacobs 	}
2444355b4669Sjacobs 
2445355b4669Sjacobs 	else
2446355b4669Sjacobs 	if ((ld != NULL) &&
2447355b4669Sjacobs 	    (dn != NULL) && (credp != NULL) && (methodp != NULL))
2448355b4669Sjacobs 	{
2449355b4669Sjacobs 		if ((freeit == 0) && (sDN != NULL) && (sPasswd != NULL))
2450355b4669Sjacobs 		{
2451355b4669Sjacobs 			/* first call - get the saved bind credentials */
2452355b4669Sjacobs 
2453355b4669Sjacobs 			*dn = strdup(sDN);
2454355b4669Sjacobs 			*credp = strdup(sPasswd);
2455355b4669Sjacobs 			*methodp = sMethod;
2456355b4669Sjacobs 		}
2457355b4669Sjacobs 		else
2458355b4669Sjacobs 		if (freeit == -1)
2459355b4669Sjacobs 		{
2460355b4669Sjacobs 			/* initial call - save the saved bind credentials */
2461355b4669Sjacobs 
2462355b4669Sjacobs 			sDN = *dn;
2463355b4669Sjacobs 			sPasswd = *credp;
2464355b4669Sjacobs 			sMethod = *methodp;
2465355b4669Sjacobs 		}
2466355b4669Sjacobs 		else
2467355b4669Sjacobs 		{
2468355b4669Sjacobs 			result = 1;	/* error */
2469355b4669Sjacobs 		}
2470355b4669Sjacobs 	}
2471355b4669Sjacobs 	else
2472355b4669Sjacobs 	{
2473355b4669Sjacobs 		result = 1;	/* error */
2474355b4669Sjacobs 	}
2475355b4669Sjacobs 
2476355b4669Sjacobs 	return (result);
2477355b4669Sjacobs } /* _manageReferralCredentials */
2478