12264Sjacobs /*
22264Sjacobs * CDDL HEADER START
32264Sjacobs *
42264Sjacobs * The contents of this file are subject to the terms of the
52264Sjacobs * Common Development and Distribution License (the "License").
62264Sjacobs * You may not use this file except in compliance with the License.
72264Sjacobs *
82264Sjacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
92264Sjacobs * or http://www.opensolaris.org/os/licensing.
102264Sjacobs * See the License for the specific language governing permissions
112264Sjacobs * and limitations under the License.
122264Sjacobs *
132264Sjacobs * When distributing Covered Code, include this CDDL HEADER in each
142264Sjacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152264Sjacobs * If applicable, add the following below this CDDL HEADER, with the
162264Sjacobs * fields enclosed by brackets "[]" replaced with your own identifying
172264Sjacobs * information: Portions Copyright [yyyy] [name of copyright owner]
182264Sjacobs *
192264Sjacobs * CDDL HEADER END
202264Sjacobs */
212264Sjacobs /*
22*7253Sjacobs * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
232264Sjacobs * Use is subject to license terms.
242264Sjacobs */
252264Sjacobs
262264Sjacobs #pragma ident "%Z%%M% %I% %E% SMI"
272264Sjacobs
282264Sjacobs #include <stdio.h>
292264Sjacobs #include <stdlib.h>
302264Sjacobs #include <unistd.h>
312264Sjacobs #include <sys/types.h>
322264Sjacobs #include <sys/stat.h>
332264Sjacobs #include <string.h>
342264Sjacobs #include <stdarg.h>
352264Sjacobs #include <fcntl.h>
362264Sjacobs #include <syslog.h>
372264Sjacobs #include <errno.h>
382264Sjacobs #include <pwd.h>
392264Sjacobs #include <libintl.h>
402264Sjacobs #include <netdb.h> /* for rcmd() */
412264Sjacobs
422264Sjacobs #include <ns.h>
432264Sjacobs #include <list.h>
442264Sjacobs
452264Sjacobs #define LDAP_REFERRALS
462264Sjacobs #include <lber.h>
472264Sjacobs #include <ldap.h>
482264Sjacobs #include <sys/systeminfo.h>
492264Sjacobs
502264Sjacobs
512264Sjacobs /*
522264Sjacobs * This modules contains the code required to manipulate printer objects in
532264Sjacobs * a LDAP directory for the Naming Service (NS) switch.
542264Sjacobs * It can "add", "modify" and "delete" the objects on the given ldap server
552264Sjacobs * and in the given NS domain DN, eg. "dc=mkg,dc=sun,dc=com".
562264Sjacobs * Note: printers known to the naming service are contained in the RDN
572264Sjacobs * "ou=printers" under the NS domain DN
582264Sjacobs */
592264Sjacobs
602264Sjacobs #define PCONTAINER "ou=printers"
612264Sjacobs
622264Sjacobs /* attribute keywords */
632264Sjacobs #define ATTR_DN "dn"
642264Sjacobs #define ATTR_OCLASS "objectClass"
652264Sjacobs #define ATTR_URI "printer-uri"
662264Sjacobs #define ATTR_PNAME "printer-name"
672264Sjacobs #define ATTR_XRISUP "printer-xri-supported"
682264Sjacobs #define ATTR_BSDADDR "sun-printer-bsdaddr"
692264Sjacobs #define ATTR_KVP "sun-printer-kvp"
702264Sjacobs
712264Sjacobs /* objectClass values */
722264Sjacobs #define OCV_TOP "top"
732264Sjacobs #define OCV_PSERVICE "printerService"
742264Sjacobs #define OCV_SUNPRT "sunPrinter"
752264Sjacobs #define OCV_PABSTRACT "printerAbstract"
762264Sjacobs
772264Sjacobs /* xri-supported attribute value */
782264Sjacobs #define AV_UNKNOWN "unknown"
792264Sjacobs
802264Sjacobs
812264Sjacobs /*
822264Sjacobs * LDAP objectclass atributes that the user can explicity change
832264Sjacobs */
842264Sjacobs
852264Sjacobs static const char *nsl_attr_printerService[] = {
862264Sjacobs "printer-uri",
872264Sjacobs "printer-xri-supported",
882264Sjacobs /* Not allowed "printer-name", */
892264Sjacobs "printer-natural-language-configured",
902264Sjacobs "printer-location",
912264Sjacobs "printer-info",
922264Sjacobs "printer-more-info",
932264Sjacobs "printer-make-and-model",
942264Sjacobs "printer-charset-configured",
952264Sjacobs "printer-charset-supported",
962264Sjacobs "printer-generated-natural-language-supported",
972264Sjacobs "printer-document-format-supported",
982264Sjacobs "printer-color-supported",
992264Sjacobs "printer-compression-supported",
1002264Sjacobs "printer-pages-per-minute",
1012264Sjacobs "printer-pages-per-minute-color",
1022264Sjacobs "printer-finishings-supported",
1032264Sjacobs "printer-number-up-supported",
1042264Sjacobs "printer-sides-supported",
1052264Sjacobs "printer-media-supported",
1062264Sjacobs "printer-media-local-supported",
1072264Sjacobs "printer-resolution-supported",
1082264Sjacobs "printer-print-quality-supported",
1092264Sjacobs "printer-job-priority-supported",
1102264Sjacobs "printer-copies-supported",
1112264Sjacobs "printer-job-k-octets-supported",
1122264Sjacobs "printer-current-operator",
1132264Sjacobs "printer-service-person",
1142264Sjacobs "printer-delivery-orientation-supported",
1152264Sjacobs "printer-stacking-order-supported",
1162264Sjacobs "printer-output-features-supported",
1172264Sjacobs (char *)NULL
1182264Sjacobs };
1192264Sjacobs
1202264Sjacobs
1212264Sjacobs static const char *nsl_attr_printerIPP[] = {
1222264Sjacobs "printer-ipp-versions-supported",
1232264Sjacobs "printer-multiple-document-jobs-supported",
1242264Sjacobs (char *)NULL
1252264Sjacobs };
1262264Sjacobs
1272264Sjacobs static const char *nsl_attr_sunPrinter[] = {
1282264Sjacobs /* Not allowed "sun-printer-bsdaddr", */
1292264Sjacobs /* Not allowed "sun-printer-kvp", */
1302264Sjacobs (char *)NULL
1312264Sjacobs };
1322264Sjacobs
1332264Sjacobs
1342264Sjacobs /*
1352264Sjacobs * List of LDAP attributes that user is not allowed to explicitly change
1362264Sjacobs */
1372264Sjacobs static const char *nsl_attr_notAllowed[] = {
1382264Sjacobs ATTR_DN,
1392264Sjacobs ATTR_OCLASS, /* objectclass */
1402264Sjacobs ATTR_PNAME, /* printer-name */
1412264Sjacobs ATTR_BSDADDR,
1422264Sjacobs ATTR_KVP,
1432264Sjacobs (char *)NULL
1442264Sjacobs };
1452264Sjacobs
1462264Sjacobs
1472264Sjacobs static NSL_RESULT _connectToLDAP(ns_cred_t *cred, LDAP **ld);
1482264Sjacobs static uchar_t *_constructPrinterDN(uchar_t *printerName,
1492264Sjacobs uchar_t *domainDN, char **attrList);
1502264Sjacobs static NSL_RESULT _checkPrinterExists(LDAP *ld, uchar_t *printerName,
1512264Sjacobs uchar_t *domainDN, uchar_t **printerDN);
1522264Sjacobs static NSL_RESULT _checkPrinterDNExists(LDAP *ld, uchar_t *objectDN);
1532264Sjacobs static NSL_RESULT _checkSunPrinter(LDAP *ld, uchar_t *printerDN);
1542264Sjacobs static NSL_RESULT _addNewPrinterObject(LDAP *ld, uchar_t *printerName,
1552264Sjacobs uchar_t *domainDN, char **attrList);
1562264Sjacobs static NSL_RESULT _modifyPrinterObject(LDAP *ld, uchar_t *printerDN,
1572264Sjacobs uchar_t *printerName, uchar_t *domainDN, char **attrList);
1582264Sjacobs static NSL_RESULT _checkAttributes(char **list);
1592264Sjacobs static NSL_RESULT _addLDAPmodValue(LDAPMod ***attrs, char *type, char *value);
1602264Sjacobs static NSL_RESULT _modLDAPmodValue(LDAPMod ***attrs, char *type, char *value);
1612264Sjacobs static NSL_RESULT _constructAddLDAPMod(uchar_t *printerName,
1622264Sjacobs char **attrList, LDAPMod ***attrs);
1632264Sjacobs static NSL_RESULT _constructModLDAPMod(uchar_t *printerName, int sunPrinter,
1642264Sjacobs char **attrList, char ***oldKVPList, LDAPMod ***attrs);
1652264Sjacobs static NSL_RESULT _compareURIinDNs(uchar_t *dn1, uchar_t *dn2);
1662264Sjacobs static uchar_t *_getThisNSDomainDN(void);
1672264Sjacobs static int _popen(char *cmd, char *results, int size);
1682264Sjacobs static int _attrInList(char *attr, const char **list);
1692264Sjacobs static int _attrInLDAPList(char *attr);
1702264Sjacobs static NSL_RESULT _getCurrentKVPValues(LDAP *ld,
1712264Sjacobs uchar_t *objectDN, char ***list);
1722264Sjacobs static void _freeList(char ***list);
1732264Sjacobs static NSL_RESULT _modAttrKVP(char *value, char ***kvpList);
1742264Sjacobs static NSL_RESULT _attrAddKVP(LDAPMod ***attrs, char **kvpList, int kvpExists);
1752264Sjacobs static int _manageReferralCredentials(LDAP *ld, char **dn, char **credp,
1762264Sjacobs int *methodp, int freeit);
1772264Sjacobs
1782264Sjacobs /*
1792264Sjacobs * *****************************************************************************
1802264Sjacobs *
1812264Sjacobs * Function: ldap_put_printer()
1822264Sjacobs *
1832264Sjacobs * Description: Action the request to change a printer object in the LDAP
1842264Sjacobs * directory DIT. The object is either added, modified or deleted
1852264Sjacobs * depending on the request's attribute list. A null list indicates
1862264Sjacobs * the request is a delete.
1872264Sjacobs * The object's DN is constructed from the supplied domain DN and
1882264Sjacobs * a check is done to see if the object exists already, if it
1892264Sjacobs * doesn't exist then this is a request to add a new object
1902264Sjacobs * If a URI is given in the attribute list and it is different to
1912264Sjacobs * the existing printing object's DN then the request will be
1922264Sjacobs * rejected.
1932264Sjacobs *
1942264Sjacobs *
1952264Sjacobs * Parameters:
1962264Sjacobs * Input: const ns_printer_t *printer
1972264Sjacobs * - this structure contains the following :
1982264Sjacobs * char *printerName - name of the printer
1992264Sjacobs * ns_cred_t *cred - structure containing the ldap host and
2002264Sjacobs * port, user, password and NS domain DN for the
2012264Sjacobs * directory server to be updated.
2022264Sjacobs * char **attrList - pointer to a list of attribute key values
2032264Sjacobs * for the printer object. If the object does
2042264Sjacobs * not already exist then this list contains the
2052264Sjacobs * values for the new object, otherwise this list
2062264Sjacobs * is a list of attributes to modify. For modify
2072264Sjacobs * a null attribute value is a attribute delete
2082264Sjacobs * request. A NULL ptr = delete the object.
2092264Sjacobs * Output: None
2102264Sjacobs *
2112264Sjacobs * Returns: int - 0 = request actioned okay
2122264Sjacobs * !0 = error - see NSL_RESULT codes
2132264Sjacobs *
2142264Sjacobs * *****************************************************************************
2152264Sjacobs */
2162264Sjacobs
2172264Sjacobs int
ldap_put_printer(const ns_printer_t * printer)2182264Sjacobs ldap_put_printer(const ns_printer_t *printer)
2192264Sjacobs
2202264Sjacobs {
2212264Sjacobs NSL_RESULT result = NSL_OK;
2222264Sjacobs NSL_RESULT printerExists = NSL_ERR_UNKNOWN_PRINTER;
2232264Sjacobs LDAP *ld = NULL;
2242264Sjacobs uchar_t *printerDN = NULL;
2252264Sjacobs uchar_t *domainDN = NULL;
2262264Sjacobs char *printerName = NULL;
2272264Sjacobs ns_cred_t *cred = NULL;
2282264Sjacobs char **attrList = NULL;
2292264Sjacobs
2302264Sjacobs /* -------- */
2312264Sjacobs
2322264Sjacobs /*
2332264Sjacobs * Note: the "attributes" list should be null for ldap as the attribute
2342264Sjacobs * values are passed in the nsdata field
2352264Sjacobs */
2362264Sjacobs
2372264Sjacobs if ((printer != NULL) &&
2382264Sjacobs (printer->attributes == NULL) && (printer->name != NULL))
2392264Sjacobs {
2402264Sjacobs /* extract required pointer values from structure */
2412264Sjacobs
2422264Sjacobs printerName = printer->name;
2432264Sjacobs cred = printer->cred;
2442264Sjacobs if (printer->nsdata != NULL)
2452264Sjacobs {
2462264Sjacobs attrList = ((NS_LDAPDATA *)(printer->nsdata))->attrList;
2472264Sjacobs }
2482264Sjacobs
2492264Sjacobs /* connect and bind to the ldap directory server */
2502264Sjacobs
2512264Sjacobs result = _connectToLDAP(cred, &ld);
2522264Sjacobs if ((result == NSL_OK) && (ld != NULL))
2532264Sjacobs {
2542264Sjacobs /*
2552264Sjacobs * check if the NS domain DN was given, if not use the
2562264Sjacobs * current NS domain
2572264Sjacobs */
2582264Sjacobs
2592264Sjacobs if (cred->domainDN != NULL)
2602264Sjacobs {
2612264Sjacobs domainDN = (uchar_t *)
2622264Sjacobs strdup((char *)cred->domainDN);
2632264Sjacobs }
2642264Sjacobs else
2652264Sjacobs {
2662264Sjacobs /* get DN of current domain */
2672264Sjacobs domainDN = _getThisNSDomainDN();
2682264Sjacobs }
2692264Sjacobs
2702264Sjacobs printerExists =
2712264Sjacobs _checkPrinterExists(ld, (uchar_t *)printerName,
2722264Sjacobs domainDN, &printerDN);
2732264Sjacobs if (printerExists != LDAP_SUCCESS)
2742264Sjacobs {
2752264Sjacobs /*
2762264Sjacobs * could not find the printer by printer-name,
2772264Sjacobs * but there could be a non sunPrinter object
2782264Sjacobs * so if the printer-uri was given check if
2792264Sjacobs * an object for that exists
2802264Sjacobs */
2812264Sjacobs printerDN =
2822264Sjacobs _constructPrinterDN(NULL,
2832264Sjacobs domainDN, attrList);
2842264Sjacobs if (printerDN != NULL)
2852264Sjacobs {
2862264Sjacobs printerExists = _checkPrinterDNExists(
2872264Sjacobs ld, printerDN);
2882264Sjacobs }
2892264Sjacobs }
2902264Sjacobs #ifdef DEBUG
2912264Sjacobs if (printerExists == NSL_OK)
2922264Sjacobs {
2932264Sjacobs printf("DN found = '%s' for '%s'\n", printerDN, printerName);
2942264Sjacobs }
2952264Sjacobs #endif
2962264Sjacobs
2972264Sjacobs if (attrList == NULL)
2982264Sjacobs {
2992264Sjacobs /*
3002264Sjacobs * a null list indicates that this is a DELETE
3012264Sjacobs * object request, so if object exists delete
3022264Sjacobs * it, otherwise report an error.
3032264Sjacobs */
3042264Sjacobs if (printerExists == LDAP_SUCCESS)
3052264Sjacobs {
3062264Sjacobs result = ldap_delete_s(ld,
3072264Sjacobs (char *)printerDN);
3082264Sjacobs if (result != LDAP_SUCCESS)
3092264Sjacobs {
3102264Sjacobs result = NSL_ERR_DEL_FAILED;
3112264Sjacobs #ifdef DEBUG
3122264Sjacobs ldap_perror(ld, "ldap_delete_s failed");
3132264Sjacobs #endif
3142264Sjacobs }
3152264Sjacobs }
3162264Sjacobs else
3172264Sjacobs {
3182264Sjacobs result = NSL_ERR_UNKNOWN_PRINTER;
3192264Sjacobs }
3202264Sjacobs }
3212264Sjacobs else
3222264Sjacobs {
3232264Sjacobs /*
3242264Sjacobs * if object exists then this is a
3252264Sjacobs * modify request otherwise is is an add request
3262264Sjacobs */
3272264Sjacobs
3282264Sjacobs if (printerExists == LDAP_SUCCESS)
3292264Sjacobs {
3302264Sjacobs /*
3312264Sjacobs * Modify the printer object to
3322264Sjacobs * give it the new attribute values
3332264Sjacobs * specified by the user
3342264Sjacobs */
3352264Sjacobs result =
3362264Sjacobs _modifyPrinterObject(ld, printerDN,
3372264Sjacobs (uchar_t *)printerName,
3382264Sjacobs domainDN, attrList);
3392264Sjacobs }
3402264Sjacobs else
3412264Sjacobs {
3422264Sjacobs /*
3432264Sjacobs * add new printer object into the
3442264Sjacobs * ldap directory with the user
3452264Sjacobs * specified attribute values
3462264Sjacobs */
3472264Sjacobs result =
3482264Sjacobs _addNewPrinterObject(ld,
3492264Sjacobs (uchar_t *)printerName,
3502264Sjacobs domainDN, attrList);
3512264Sjacobs }
3522264Sjacobs }
3532264Sjacobs
3542264Sjacobs if (printerDN != NULL)
3552264Sjacobs {
3562264Sjacobs free(printerDN);
3572264Sjacobs }
3582264Sjacobs if (domainDN != NULL)
3592264Sjacobs {
3602264Sjacobs free(domainDN);
3612264Sjacobs }
3622264Sjacobs
3632264Sjacobs /* disconnect from LDAP server */
3642264Sjacobs
3652264Sjacobs (void) ldap_unbind(ld);
3662264Sjacobs }
3672264Sjacobs }
3682264Sjacobs
3692264Sjacobs else
3702264Sjacobs {
3712264Sjacobs /* no printerName given */
3722264Sjacobs result = NSL_ERR_INTERNAL;
3732264Sjacobs }
3742264Sjacobs
3752264Sjacobs return ((int)result);
3762264Sjacobs } /* ldap_put_printer */
3772264Sjacobs
3782264Sjacobs
3792264Sjacobs
3802264Sjacobs
3812264Sjacobs /*
3822264Sjacobs * *****************************************************************************
3832264Sjacobs *
3842264Sjacobs * Function: _connectToLDAP()
3852264Sjacobs *
3862264Sjacobs * Description: Setup the connection and bind to the LDAP directory server.
3872264Sjacobs * The function returns the ldap connection descriptor
3882264Sjacobs *
3892264Sjacobs * Note: Currently the native ldap functions do not support secure
3902264Sjacobs * passwords, when this is supported this function will require
3912264Sjacobs * updating to allow the type passed in cred->passwdType to
3922264Sjacobs * be used with the ldap_simple_bind()
3932264Sjacobs *
3942264Sjacobs * Parameters:
3952264Sjacobs * Input: ns_cred_t *cred - structure containing the credentials (host,
3962264Sjacobs * port, user and password) required to bind
3972264Sjacobs * to the directory server to be updated.
3982264Sjacobs * char *printerName - printer name used only for error messages
3992264Sjacobs * Output: LDAP** - ldap connection descriptor pointer. NULL = failed
4002264Sjacobs *
4012264Sjacobs * Returns: NSL_RESULT - NSL_OK = connected okay
4022264Sjacobs *
4032264Sjacobs * *****************************************************************************
4042264Sjacobs */
4052264Sjacobs
4062264Sjacobs static NSL_RESULT
_connectToLDAP(ns_cred_t * cred,LDAP ** ld)4072264Sjacobs _connectToLDAP(ns_cred_t *cred, LDAP **ld)
4082264Sjacobs
4092264Sjacobs {
4102264Sjacobs NSL_RESULT result = NSL_OK;
4112264Sjacobs int lresult = 0;
4122264Sjacobs int ldapPort = LDAP_PORT; /* default LDAP port number */
4132264Sjacobs int protoVersion = LDAP_VERSION3;
4142264Sjacobs int derefOption = LDAP_DEREF_NEVER;
4152264Sjacobs int referrals = 1;
4162264Sjacobs char hostname[MAXHOSTNAMELEN];
4172264Sjacobs int tmpMethod = LDAP_AUTH_SIMPLE; /* temp - until its passed in */
4182264Sjacobs
4192264Sjacobs /* -------- */
4202264Sjacobs
4212264Sjacobs if ((ld == NULL) || (cred == NULL) ||
4222264Sjacobs ((cred->passwd == NULL) || (cred->binddn == NULL)))
4232264Sjacobs {
4242264Sjacobs result = NSL_ERR_CREDENTIALS;
4252264Sjacobs }
4262264Sjacobs
4272264Sjacobs else
4282264Sjacobs {
4292264Sjacobs *ld = NULL;
4302264Sjacobs
4312264Sjacobs /* if host was not given then bind to local host */
4322264Sjacobs
4332264Sjacobs if (cred->host != NULL)
4342264Sjacobs {
4352264Sjacobs (void) strlcpy(hostname, cred->host, sizeof (hostname));
4362264Sjacobs }
4372264Sjacobs else
4382264Sjacobs {
4392264Sjacobs (void) sysinfo(SI_HOSTNAME,
4402264Sjacobs hostname, sizeof (hostname));
4412264Sjacobs }
4422264Sjacobs
4432264Sjacobs /* initialise the connection to the ldap server */
4442264Sjacobs
4452264Sjacobs if (cred->port != 0)
4462264Sjacobs {
4472264Sjacobs ldapPort = cred->port;
4482264Sjacobs }
4492264Sjacobs *ld = ldap_init(hostname, ldapPort);
4502264Sjacobs if (*ld == NULL)
4512264Sjacobs {
4522264Sjacobs /* connection setup failed */
4532264Sjacobs result = NSL_ERR_CONNECT;
4542264Sjacobs #ifdef DEBUG
4552264Sjacobs (void) perror("ldap_init");
4562264Sjacobs #endif
4572264Sjacobs }
4582264Sjacobs else
4592264Sjacobs {
4602264Sjacobs /* set ldap options */
4612264Sjacobs
4622264Sjacobs (void) ldap_set_option(*ld, LDAP_OPT_DEREF,
4632264Sjacobs &derefOption);
4642264Sjacobs (void) ldap_set_option(*ld, LDAP_OPT_PROTOCOL_VERSION,
4652264Sjacobs &protoVersion);
4662264Sjacobs (void) ldap_set_option(*ld, LDAP_OPT_REFERRALS,
4672264Sjacobs &referrals);
4682264Sjacobs
4692264Sjacobs /* bind to the user DN in the directory */
4702264Sjacobs
4712264Sjacobs /* cred->passwdType is currently not supported */
4722264Sjacobs
4732264Sjacobs lresult = ldap_simple_bind_s(*ld,
4742264Sjacobs cred->binddn, cred->passwd);
4752264Sjacobs
4762264Sjacobs /*
4772264Sjacobs * before doing anything else, set up the function to
4782264Sjacobs * call to get authentication details if the
4792264Sjacobs * ldap update function calls (eg. ldap_add_s()) get a
4802264Sjacobs * "referral" (to another ldap server) from the
4812264Sjacobs * original ldap server, eg. if we are trying to do
4822264Sjacobs * a update on a LDAP replica server.
4832264Sjacobs */
4842264Sjacobs (void) _manageReferralCredentials(*ld,
4852264Sjacobs &(cred->binddn), &(cred->passwd),
4862264Sjacobs &tmpMethod, -1);
4872264Sjacobs ldap_set_rebind_proc(*ld,
4882264Sjacobs (LDAP_REBINDPROC_CALLBACK *)
4892264Sjacobs _manageReferralCredentials, NULL);
4902264Sjacobs
4912264Sjacobs if (lresult != LDAP_SUCCESS)
4922264Sjacobs {
4932264Sjacobs result = NSL_ERR_BIND;
4942264Sjacobs *ld = NULL;
4952264Sjacobs #ifdef DEBUG
4962264Sjacobs (void) ldap_perror(*ld, "ldap_simple_bind_s");
4972264Sjacobs #endif
4982264Sjacobs }
4992264Sjacobs }
5002264Sjacobs }
5012264Sjacobs
5022264Sjacobs return (result);
5032264Sjacobs } /* _connectToLDAP */
5042264Sjacobs
5052264Sjacobs
5062264Sjacobs
5072264Sjacobs
5082264Sjacobs
5092264Sjacobs /*
5102264Sjacobs * *****************************************************************************
5112264Sjacobs *
5122264Sjacobs * Function: _constructPrinterDN()
5132264Sjacobs *
5142264Sjacobs * Description: Construct the DN for the printer object from its name and NS
5152264Sjacobs * domain DN. If the printer-uri is given in the attrList then
5162264Sjacobs * that is used instead of the printerName.
5172264Sjacobs *
5182264Sjacobs * Parameters:
5192264Sjacobs * Input: uchar_t *printerName
5202264Sjacobs * uchar_t *domainDN
5212264Sjacobs * char **attrList - this list is searched for printer-uri
5222264Sjacobs * Output: None
5232264Sjacobs *
5242264Sjacobs * Returns: uchar_t* - pointer to the DN, this memory is malloced so
5252264Sjacobs * must be freed using free() when finished with.
5262264Sjacobs *
5272264Sjacobs * *****************************************************************************
5282264Sjacobs */
5292264Sjacobs
5302264Sjacobs static uchar_t *
_constructPrinterDN(uchar_t * printerName,uchar_t * domainDN,char ** attrList)5312264Sjacobs _constructPrinterDN(uchar_t *printerName, uchar_t *domainDN, char **attrList)
5322264Sjacobs
5332264Sjacobs {
5342264Sjacobs uchar_t *dn = NULL;
5352264Sjacobs uchar_t *uri = NULL;
5362264Sjacobs char **p = NULL;
5372264Sjacobs int len = 0;
5382264Sjacobs
5392264Sjacobs /* ------- */
5402264Sjacobs
5412264Sjacobs /* first search for printer-uri in the attribute list */
5422264Sjacobs
5432264Sjacobs for (p = attrList; (p != NULL) && (*p != NULL) && (uri == NULL); p++)
5442264Sjacobs {
5452264Sjacobs /* get length of this key word */
5462264Sjacobs
5472264Sjacobs for (len = 0; ((*p)[len] != '=') && ((*p)[len] != '\0'); len++);
5482264Sjacobs
5492264Sjacobs if ((strncasecmp(*p, ATTR_URI, len) == 0) &&
5502264Sjacobs (strlen(*p) > len+1))
5512264Sjacobs {
5522264Sjacobs uri = (uchar_t *)&((*p)[len+1]);
5532264Sjacobs }
5542264Sjacobs }
5552264Sjacobs
5562264Sjacobs
5572264Sjacobs if (domainDN != NULL) {
5582264Sjacobs size_t size;
5592264Sjacobs
5602264Sjacobs /* malloc memory for the DN and then construct it */
5612264Sjacobs
5622264Sjacobs if ((uri == NULL) && (printerName != NULL))
5632264Sjacobs {
5642264Sjacobs /* use the printerName for the RDN */
5652264Sjacobs
5662264Sjacobs size = strlen(ATTR_URI) +
5672264Sjacobs strlen((char *)printerName) +
5682264Sjacobs strlen((char *)domainDN) +
5692264Sjacobs strlen(PCONTAINER) +
5702264Sjacobs 10; /* plus a few extra */
5712264Sjacobs
5722264Sjacobs if ((dn = malloc(size)) != NULL)
5732264Sjacobs (void) snprintf((char *)dn, size, "%s=%s,%s,%s",
5742264Sjacobs ATTR_URI, printerName, PCONTAINER, domainDN);
5752264Sjacobs }
5762264Sjacobs else
5772264Sjacobs if (uri != NULL)
5782264Sjacobs {
5792264Sjacobs /* use the URI for the RDN */
5802264Sjacobs
5812264Sjacobs size = strlen(ATTR_URI) +
5822264Sjacobs strlen((char *)uri) +
5832264Sjacobs strlen((char *)domainDN) +
5842264Sjacobs strlen(PCONTAINER) +
5852264Sjacobs 10; /* plus a few extra */
5862264Sjacobs
5872264Sjacobs if ((dn = malloc(size)) != NULL)
5882264Sjacobs (void) snprintf((char *)dn, size, "%s=%s,%s,%s",
5892264Sjacobs ATTR_URI, uri, PCONTAINER, domainDN);
5902264Sjacobs }
5912264Sjacobs
5922264Sjacobs /*
5932264Sjacobs * else
5942264Sjacobs * {
5952264Sjacobs * printName not given so return null
5962264Sjacobs * }
5972264Sjacobs */
5982264Sjacobs
5992264Sjacobs }
6002264Sjacobs
6012264Sjacobs return (dn); /* caller must free this memory */
6022264Sjacobs } /* _constructPrinterDN */
6032264Sjacobs
6042264Sjacobs
6052264Sjacobs
6062264Sjacobs /*
6072264Sjacobs * *****************************************************************************
6082264Sjacobs *
6092264Sjacobs * Function: _checkPrinterExists()
6102264Sjacobs *
6112264Sjacobs * Description: Check that the printer object for the printerName exists in the
6122264Sjacobs * directory DIT and then extract the object's DN
6132264Sjacobs * The function uses an exiting ldap connection and does a
6142264Sjacobs * search for the printerName in the supplied domain DN.
6152264Sjacobs *
6162264Sjacobs * Parameters:
6172264Sjacobs * Input: LDAP *ld - existing ldap connection descriptor
6182264Sjacobs * uchar_t *printerName - printer name
6192264Sjacobs * uchar_t *domainDN - DN of domain to search in
6202264Sjacobs * Output: uchar_t **printerDN - DN of the printer - the caller should
6212264Sjacobs * free this memory using free()
6222264Sjacobs *
6232264Sjacobs * Result: NSL_RESULT - NSL_OK = object exists
6242264Sjacobs *
6252264Sjacobs * *****************************************************************************
6262264Sjacobs */
6272264Sjacobs
6282264Sjacobs static NSL_RESULT
_checkPrinterExists(LDAP * ld,uchar_t * printerName,uchar_t * domainDN,uchar_t ** printerDN)6292264Sjacobs _checkPrinterExists(LDAP *ld, uchar_t *printerName, uchar_t *domainDN,
6302264Sjacobs uchar_t **printerDN)
6312264Sjacobs
6322264Sjacobs {
6332264Sjacobs NSL_RESULT result = NSL_ERR_UNKNOWN_PRINTER;
6342264Sjacobs int sresult = LDAP_NO_SUCH_OBJECT;
6352264Sjacobs LDAPMessage *ldapMsg = NULL;
6362264Sjacobs char *requiredAttrs[2] = { ATTR_PNAME, NULL };
6372264Sjacobs LDAPMessage *ldapEntry = NULL;
6382264Sjacobs uchar_t *filter = NULL;
6392264Sjacobs uchar_t *baseDN = NULL;
6402264Sjacobs
6412264Sjacobs /* ---------- */
6422264Sjacobs
6432264Sjacobs if ((printerName != NULL) && (domainDN != NULL) && (printerDN != NULL))
6442264Sjacobs {
6452264Sjacobs size_t size;
6462264Sjacobs
6472264Sjacobs if (printerDN != NULL)
6482264Sjacobs {
6492264Sjacobs *printerDN = NULL;
6502264Sjacobs }
6512264Sjacobs
6522264Sjacobs /* search for this Printer in the directory */
6532264Sjacobs
6542264Sjacobs size = (3 + strlen((char *)printerName) + strlen(ATTR_PNAME) +
6552264Sjacobs 2);
6562264Sjacobs
6572264Sjacobs if ((filter = malloc(size)) != NULL)
6582264Sjacobs (void) snprintf((char *)filter, size, "(%s=%s)",
6592264Sjacobs ATTR_PNAME, (char *)printerName);
6602264Sjacobs
6612264Sjacobs size = (strlen((char *)domainDN) + strlen(PCONTAINER) + 5);
6622264Sjacobs
6632264Sjacobs if ((baseDN = malloc(size)) != NULL)
6642264Sjacobs (void) snprintf((char *)baseDN, size, "%s,%s",
6652264Sjacobs PCONTAINER, (char *)domainDN);
6662264Sjacobs
6672264Sjacobs sresult = ldap_search_s(ld, (char *)baseDN, LDAP_SCOPE_SUBTREE,
6682264Sjacobs (char *)filter, requiredAttrs, 0, &ldapMsg);
6692264Sjacobs if (sresult == LDAP_SUCCESS)
6702264Sjacobs {
6712264Sjacobs /* check that the object exists and extract its DN */
6722264Sjacobs
6732264Sjacobs ldapEntry = ldap_first_entry(ld, ldapMsg);
6742264Sjacobs if (ldapEntry != NULL)
6752264Sjacobs {
6762264Sjacobs /* object found - there should only be one */
6772264Sjacobs result = NSL_OK;
6782264Sjacobs
6792264Sjacobs if (printerDN != NULL)
6802264Sjacobs {
6812264Sjacobs *printerDN = (uchar_t *)
6822264Sjacobs ldap_get_dn(ld, ldapEntry);
6832264Sjacobs }
6842264Sjacobs }
6852264Sjacobs
6862264Sjacobs (void) ldap_msgfree(ldapMsg);
6872264Sjacobs }
6882264Sjacobs }
6892264Sjacobs
6902264Sjacobs else
6912264Sjacobs {
6922264Sjacobs result = NSL_ERR_INTERNAL;
6932264Sjacobs }
6942264Sjacobs
6952264Sjacobs return (result);
6962264Sjacobs } /* _checkPrinterExists */
6972264Sjacobs
6982264Sjacobs
6992264Sjacobs
7002264Sjacobs
7012264Sjacobs /*
7022264Sjacobs * *****************************************************************************
7032264Sjacobs *
7042264Sjacobs * Function: _checkPrinterDNExists()
7052264Sjacobs *
7062264Sjacobs * Description: Check that the printer object for the DN exists in the
7072264Sjacobs * directory DIT.
7082264Sjacobs * The function uses an exiting ldap connection and does a
7092264Sjacobs * search for the DN supplied.
7102264Sjacobs *
7112264Sjacobs * Parameters: LDAP *ld - existing ldap connection descriptor
7122264Sjacobs * char *objectDN - DN to search for
7132264Sjacobs *
7142264Sjacobs * Result: NSL_RESULT - NSL_OK = object exists
7152264Sjacobs *
7162264Sjacobs * *****************************************************************************
7172264Sjacobs */
7182264Sjacobs
7192264Sjacobs static NSL_RESULT
_checkPrinterDNExists(LDAP * ld,uchar_t * objectDN)7202264Sjacobs _checkPrinterDNExists(LDAP *ld, uchar_t *objectDN)
7212264Sjacobs
7222264Sjacobs {
7232264Sjacobs NSL_RESULT result = NSL_ERR_UNKNOWN_PRINTER;
7242264Sjacobs int sresult = LDAP_NO_SUCH_OBJECT;
7252264Sjacobs LDAPMessage *ldapMsg;
7262264Sjacobs char *requiredAttrs[2] = { ATTR_PNAME, NULL };
7272264Sjacobs LDAPMessage *ldapEntry;
7282264Sjacobs
7292264Sjacobs /* ---------- */
7302264Sjacobs
7312264Sjacobs if ((ld != NULL) && (objectDN != NULL))
7322264Sjacobs {
7332264Sjacobs /* search for this Printer in the directory */
7342264Sjacobs
7352264Sjacobs sresult = ldap_search_s(ld, (char *)objectDN, LDAP_SCOPE_BASE,
7362264Sjacobs "(objectclass=*)", requiredAttrs, 0, &ldapMsg);
7372264Sjacobs if (sresult == LDAP_SUCCESS)
7382264Sjacobs {
7392264Sjacobs /* check that the object exists */
7402264Sjacobs ldapEntry = ldap_first_entry(ld, ldapMsg);
7412264Sjacobs if (ldapEntry != NULL)
7422264Sjacobs {
7432264Sjacobs /* object found */
7442264Sjacobs result = NSL_OK;
7452264Sjacobs }
7462264Sjacobs
7472264Sjacobs (void) ldap_msgfree(ldapMsg);
7482264Sjacobs }
7492264Sjacobs }
7502264Sjacobs
7512264Sjacobs else
7522264Sjacobs {
7532264Sjacobs result = NSL_ERR_INTERNAL;
7542264Sjacobs }
7552264Sjacobs
7562264Sjacobs return (result);
7572264Sjacobs } /* _checkPrinterDNExists */
7582264Sjacobs
7592264Sjacobs
7602264Sjacobs
7612264Sjacobs
7622264Sjacobs
7632264Sjacobs /*
7642264Sjacobs * *****************************************************************************
7652264Sjacobs *
7662264Sjacobs * Function: _checkSunPrinter()
7672264Sjacobs *
7682264Sjacobs * Description: Check that the printer object for the printerDN is a sunPrinter
7692264Sjacobs * ie. it has the required objectclass attribute value.
7702264Sjacobs *
7712264Sjacobs * Parameters:
7722264Sjacobs * Input: LDAP *ld - existing ldap connection descriptor
7732264Sjacobs * Output: uchar_t *printerDN - DN of the printer
7742264Sjacobs *
7752264Sjacobs * Result: NSL_RESULT - NSL_OK = object exists and is a sunPrinter
7762264Sjacobs *
7772264Sjacobs * *****************************************************************************
7782264Sjacobs */
7792264Sjacobs
7802264Sjacobs static NSL_RESULT
_checkSunPrinter(LDAP * ld,uchar_t * printerDN)7812264Sjacobs _checkSunPrinter(LDAP *ld, uchar_t *printerDN)
7822264Sjacobs
7832264Sjacobs {
7842264Sjacobs NSL_RESULT result = NSL_ERR_UNKNOWN_PRINTER;
7852264Sjacobs int sresult = LDAP_NO_SUCH_OBJECT;
7862264Sjacobs char *requiredAttrs[2] = { ATTR_PNAME, NULL };
7872264Sjacobs LDAPMessage *ldapMsg = NULL;
7882264Sjacobs LDAPMessage *ldapEntry = NULL;
7892264Sjacobs char *filter = NULL;
7902264Sjacobs
7912264Sjacobs /* ---------- */
7922264Sjacobs
7932264Sjacobs if ((ld != NULL) && (printerDN != NULL))
7942264Sjacobs {
7952264Sjacobs size_t size;
7962264Sjacobs
7972264Sjacobs /* search for this Printer in the directory */
7982264Sjacobs
7992264Sjacobs size = (3 + strlen(OCV_SUNPRT) + strlen(ATTR_OCLASS) + 2);
8002264Sjacobs if ((filter = malloc(size)) != NULL)
8012264Sjacobs (void) snprintf(filter, size, "(%s=%s)",
8022264Sjacobs ATTR_OCLASS, OCV_SUNPRT);
8032264Sjacobs
8042264Sjacobs sresult = ldap_search_s(ld, (char *)printerDN,
8052264Sjacobs LDAP_SCOPE_SUBTREE, filter,
8062264Sjacobs requiredAttrs, 0, &ldapMsg);
8072264Sjacobs if (sresult == LDAP_SUCCESS)
8082264Sjacobs {
8092264Sjacobs /* check that the printer object exists */
8102264Sjacobs
8112264Sjacobs ldapEntry = ldap_first_entry(ld, ldapMsg);
8122264Sjacobs if (ldapEntry != NULL)
8132264Sjacobs {
8142264Sjacobs /* object is a sunPrinter */
8152264Sjacobs result = NSL_OK;
8162264Sjacobs }
8172264Sjacobs
8182264Sjacobs (void) ldap_msgfree(ldapMsg);
8192264Sjacobs }
8202264Sjacobs }
8212264Sjacobs
8222264Sjacobs else
8232264Sjacobs {
8242264Sjacobs result = NSL_ERR_INTERNAL;
8252264Sjacobs }
8262264Sjacobs
8272264Sjacobs return (result);
8282264Sjacobs } /* _checkSunPrinter */
8292264Sjacobs
8302264Sjacobs
8312264Sjacobs
8322264Sjacobs
8332264Sjacobs
8342264Sjacobs /*
8352264Sjacobs * *****************************************************************************
8362264Sjacobs *
8372264Sjacobs * Function: _addNewPrinterObject()
8382264Sjacobs *
8392264Sjacobs * Description: For the given printerName add a printer object into the
8402264Sjacobs * LDAP directory NS domain. The object is created with the
8412264Sjacobs * supplied attribute values. Note: if the printer's uri is
8422264Sjacobs * given that is used as the RDN otherwise the printer's
8432264Sjacobs * name is used as the RDN
8442264Sjacobs *
8452264Sjacobs * Parameters:
8462264Sjacobs * Input: LDAP *ld - existing ldap connection descriptor
8472264Sjacobs * uchar_t *printerName - Name of printer to be added
8482264Sjacobs * uchar_t *domainDN - DN of the domain to add the printer
8492264Sjacobs * char **attrList - user specified attribute values list
8502264Sjacobs * Output: None
8512264Sjacobs *
8522264Sjacobs * Returns: NSL_RESULT - NSL_OK = request actioned okay
8532264Sjacobs * !NSL_OK = error
8542264Sjacobs *
8552264Sjacobs * *****************************************************************************
8562264Sjacobs */
8572264Sjacobs
8582264Sjacobs static NSL_RESULT
_addNewPrinterObject(LDAP * ld,uchar_t * printerName,uchar_t * domainDN,char ** attrList)8592264Sjacobs _addNewPrinterObject(LDAP *ld, uchar_t *printerName,
8602264Sjacobs uchar_t *domainDN, char **attrList)
8612264Sjacobs
8622264Sjacobs {
8632264Sjacobs NSL_RESULT result = NSL_ERR_ADD_FAILED;
8642264Sjacobs int lresult = 0;
8652264Sjacobs uchar_t *printerDN = NULL;
8662264Sjacobs LDAPMod **attrs = NULL;
8672264Sjacobs
8682264Sjacobs /* ---------- */
8692264Sjacobs
8702264Sjacobs if ((ld != NULL) && (printerName != NULL) && (domainDN != NULL) &&
8712264Sjacobs (attrList != NULL) && (attrList[0] != NULL))
8722264Sjacobs {
8732264Sjacobs result = _checkAttributes(attrList);
8742264Sjacobs
8752264Sjacobs if (result == NSL_OK)
8762264Sjacobs {
8772264Sjacobs /*
8782264Sjacobs * construct a DN for the printer from the
8792264Sjacobs * printerName and printer-uri if given.
8802264Sjacobs */
8812264Sjacobs printerDN = _constructPrinterDN(printerName,
8822264Sjacobs domainDN, attrList);
8832264Sjacobs if (printerDN != NULL)
8842264Sjacobs {
8852264Sjacobs /*
8862264Sjacobs * setup attribute values in an LDAPMod
8872264Sjacobs * structure and then add the object
8882264Sjacobs */
8892264Sjacobs result = _constructAddLDAPMod(printerName,
8902264Sjacobs attrList, &attrs);
8912264Sjacobs if (result == NSL_OK)
8922264Sjacobs {
8932264Sjacobs lresult = ldap_add_s(ld,
8942264Sjacobs (char *)printerDN, attrs);
8952264Sjacobs if (lresult == LDAP_SUCCESS)
8962264Sjacobs {
8972264Sjacobs result = NSL_OK;
8982264Sjacobs }
8992264Sjacobs else
9002264Sjacobs {
9012264Sjacobs result = NSL_ERR_ADD_FAILED;
9022264Sjacobs #ifdef DEBUG
9032264Sjacobs (void) ldap_perror(ld, "ldap_add_s");
9042264Sjacobs #endif
9052264Sjacobs }
9062264Sjacobs
9072264Sjacobs (void) ldap_mods_free(attrs, 1);
9082264Sjacobs }
9092264Sjacobs free(printerDN);
9102264Sjacobs }
9112264Sjacobs
9122264Sjacobs else
9132264Sjacobs {
9142264Sjacobs result = NSL_ERR_INTERNAL;
9152264Sjacobs }
9162264Sjacobs }
9172264Sjacobs }
9182264Sjacobs
9192264Sjacobs else
9202264Sjacobs {
9212264Sjacobs result = NSL_ERR_INTERNAL;
9222264Sjacobs }
9232264Sjacobs
9242264Sjacobs return (result);
9252264Sjacobs } /* _addNewPrinterObject */
9262264Sjacobs
9272264Sjacobs
9282264Sjacobs
9292264Sjacobs
9302264Sjacobs
9312264Sjacobs
9322264Sjacobs /*
9332264Sjacobs * *****************************************************************************
9342264Sjacobs *
9352264Sjacobs * Function: _modifyPrinterObject()
9362264Sjacobs *
9372264Sjacobs * Description: Modify the given LDAP printer object to set the new attributes
9382264Sjacobs * in the attribute list. If the printer's URI (specified in the
9392264Sjacobs * attrList) changes the URI of the object the request is rejected.
9402264Sjacobs *
9412264Sjacobs * Parameters:
9422264Sjacobs * Input: LDAP *ld - existing ldap connection descriptor
9432264Sjacobs * uchar_t *printerDN - DN of printer object to modify
9442264Sjacobs * uchar_t *printerName - Name of printer to be modified
9452264Sjacobs * uchar_t *domainDN - DN of the domain the printer is in
9462264Sjacobs * char **attrList - user specified attribute values list
9472264Sjacobs * Output: None
9482264Sjacobs *
9492264Sjacobs * Returns: NSL_RESULT - NSL_OK = object modified okay
9502264Sjacobs *
9512264Sjacobs * *****************************************************************************
9522264Sjacobs */
9532264Sjacobs
9542264Sjacobs static NSL_RESULT
_modifyPrinterObject(LDAP * ld,uchar_t * printerDN,uchar_t * printerName,uchar_t * domainDN,char ** attrList)9552264Sjacobs _modifyPrinterObject(LDAP *ld, uchar_t *printerDN,
9562264Sjacobs uchar_t *printerName, uchar_t *domainDN, char **attrList)
9572264Sjacobs
9582264Sjacobs {
9592264Sjacobs NSL_RESULT result = NSL_ERR_INTERNAL;
9602264Sjacobs int lresult = 0;
9612264Sjacobs int sunPrinter = 0;
9622264Sjacobs uchar_t *uriDN = NULL;
9632264Sjacobs LDAPMod **attrs = NULL;
9642264Sjacobs char **kvpList = NULL;
9652264Sjacobs
9662264Sjacobs /* ---------- */
9672264Sjacobs
9682264Sjacobs if ((ld != NULL) && (printerDN != NULL) && (printerName != NULL) &&
9692264Sjacobs (domainDN != NULL) && (attrList != NULL) && (attrList[0] != NULL))
9702264Sjacobs {
9712264Sjacobs result = _checkAttributes(attrList);
9722264Sjacobs
9732264Sjacobs if (result == NSL_OK)
9742264Sjacobs {
9752264Sjacobs /*
9762264Sjacobs * The user may have requested that the printer object
9772264Sjacobs * be given a new URI RDN, so construct a DN for the
9782264Sjacobs * printer from the printerName or the printer-uri (if
9792264Sjacobs * given).
9802264Sjacobs */
9812264Sjacobs uriDN = _constructPrinterDN(NULL, domainDN, attrList);
9822264Sjacobs
9832264Sjacobs /*
9842264Sjacobs * compare the 2 DNs to see if the URI has changed,
9852264Sjacobs * if uriDN is null then the DN hasn't changed
9862264Sjacobs */
9872264Sjacobs if ((uriDN == NULL) || ((uriDN != NULL) &&
9882264Sjacobs (_compareURIinDNs(printerDN, uriDN) == NSL_OK)))
9892264Sjacobs {
9902264Sjacobs /*
9912264Sjacobs * setup the modify object LDAPMod
9922264Sjacobs * structure and then do the modify
9932264Sjacobs */
9942264Sjacobs
9952264Sjacobs if (_checkSunPrinter(ld, printerDN) == NSL_OK)
9962264Sjacobs {
9972264Sjacobs sunPrinter = 1;
9982264Sjacobs }
9992264Sjacobs
10002264Sjacobs (void) _getCurrentKVPValues(ld,
10012264Sjacobs printerDN, &kvpList);
10022264Sjacobs
10032264Sjacobs result = _constructModLDAPMod(printerName,
10042264Sjacobs sunPrinter, attrList,
10052264Sjacobs &kvpList, &attrs);
10062264Sjacobs _freeList(&kvpList);
10072264Sjacobs
10082264Sjacobs if ((result == NSL_OK) && (attrs != NULL))
10092264Sjacobs {
10102264Sjacobs lresult = ldap_modify_s(
10112264Sjacobs ld, (char *)printerDN, attrs);
10122264Sjacobs if (lresult == LDAP_SUCCESS)
10132264Sjacobs {
10142264Sjacobs result = NSL_OK;
10152264Sjacobs }
10162264Sjacobs else
10172264Sjacobs {
10182264Sjacobs result = NSL_ERR_MOD_FAILED;
10192264Sjacobs #ifdef DEBUG
10202264Sjacobs (void) ldap_perror(ld, "ldap_modify_s");
10212264Sjacobs #endif
10222264Sjacobs }
10232264Sjacobs
10242264Sjacobs (void) ldap_mods_free(attrs, 1);
10252264Sjacobs }
10262264Sjacobs }
10272264Sjacobs else
10282264Sjacobs {
10292264Sjacobs /*
10302264Sjacobs * printer-uri name change has been requested
10312264Sjacobs * this is NOT allowed as it requires that
10322264Sjacobs * a new printer object is created
10332264Sjacobs */
10342264Sjacobs result = NSL_ERR_RENAME; /* NOT ALLOWED */
10352264Sjacobs }
10362264Sjacobs
10372264Sjacobs if (uriDN != NULL)
10382264Sjacobs {
10392264Sjacobs free(uriDN);
10402264Sjacobs }
10412264Sjacobs }
10422264Sjacobs }
10432264Sjacobs
10442264Sjacobs return (result);
10452264Sjacobs } /* _modifyPrinterObject */
10462264Sjacobs
10472264Sjacobs
10482264Sjacobs
10492264Sjacobs
10502264Sjacobs /*
10512264Sjacobs * *****************************************************************************
10522264Sjacobs *
10532264Sjacobs * Function: _checkAttributes()
10542264Sjacobs *
10552264Sjacobs * Description: Check that the given attribute lists does not contain any
10562264Sjacobs * key words that are not allowed.
10572264Sjacobs *
10582264Sjacobs * Parameters:
10592264Sjacobs * Input: char **list - attribute list to check
10602264Sjacobs * Output: None
10612264Sjacobs *
10622264Sjacobs * Returns: NSL_RESULT - NSL_OK = checked okay
10632264Sjacobs *
10642264Sjacobs * *****************************************************************************
10652264Sjacobs */
10662264Sjacobs
10672264Sjacobs static NSL_RESULT
_checkAttributes(char ** list)10682264Sjacobs _checkAttributes(char **list)
10692264Sjacobs
10702264Sjacobs {
10712264Sjacobs NSL_RESULT result = NSL_OK;
10722264Sjacobs int len = 0;
10732264Sjacobs char *attr = NULL;
10742264Sjacobs char **p = NULL;
10752264Sjacobs
10762264Sjacobs /* ------ */
10772264Sjacobs
10782264Sjacobs for (p = list; (p != NULL) && (*p != NULL) && (result == NSL_OK); p++)
10792264Sjacobs {
10802264Sjacobs /* get length of this key word */
10812264Sjacobs
10822264Sjacobs for (len = 0; ((*p)[len] != '=') && ((*p)[len] != '\0'); len++);
10832264Sjacobs
10842264Sjacobs /* check if the key word is allowed */
10852264Sjacobs
10862264Sjacobs if (strncasecmp(*p, ATTR_KVP, len) == 0)
10872264Sjacobs {
10882264Sjacobs /* not supported through this interface */
10892264Sjacobs result = NSL_ERR_KVP;
10902264Sjacobs }
10912264Sjacobs else
10922264Sjacobs if (strncasecmp(*p, ATTR_BSDADDR, len) == 0)
10932264Sjacobs {
10942264Sjacobs /* not supported through this interface */
10952264Sjacobs result = NSL_ERR_BSDADDR;
10962264Sjacobs }
10972264Sjacobs else
10982264Sjacobs if (strncasecmp(*p, ATTR_PNAME, len) == 0)
10992264Sjacobs {
11002264Sjacobs /* not supported through this interface */
11012264Sjacobs result = NSL_ERR_PNAME;
11022264Sjacobs }
11032264Sjacobs else
11042264Sjacobs {
11052264Sjacobs /* check for any others */
11062264Sjacobs
11072264Sjacobs attr = strdup(*p);
11082264Sjacobs attr[len] = '\0'; /* terminate the key */
11092264Sjacobs
11102264Sjacobs if (_attrInList(attr, nsl_attr_notAllowed))
11112264Sjacobs {
11122264Sjacobs result = NSL_ERR_NOTALLOWED;
11132264Sjacobs }
11142264Sjacobs }
11152264Sjacobs
11162264Sjacobs }
11172264Sjacobs
11182264Sjacobs return (result);
11192264Sjacobs } /* _checkAttributes */
11202264Sjacobs
11212264Sjacobs
11222264Sjacobs
11232264Sjacobs
11242264Sjacobs /*
11252264Sjacobs * *****************************************************************************
11262264Sjacobs *
11272264Sjacobs * Function: _addLDAPmodValue()
11282264Sjacobs *
11292264Sjacobs * Description: Add the given attribute and its value to the LDAPMod array.
11302264Sjacobs * If this is the first entry in the array then create it.
11312264Sjacobs *
11322264Sjacobs * Parameters:
11332264Sjacobs * Input: LDAPMod ***attrs - array to update
11342264Sjacobs * char *type - attribute to add into array
11352264Sjacobs * char *value - attribute value
11362264Sjacobs * Output: None
11372264Sjacobs *
11382264Sjacobs * Returns: NSL_RESULT - NSL_OK = added okay
11392264Sjacobs *
11402264Sjacobs * *****************************************************************************
11412264Sjacobs */
11422264Sjacobs
11432264Sjacobs static NSL_RESULT
_addLDAPmodValue(LDAPMod *** attrs,char * type,char * value)11442264Sjacobs _addLDAPmodValue(LDAPMod ***attrs, char *type, char *value)
11452264Sjacobs
11462264Sjacobs {
11472264Sjacobs int i = 0;
11482264Sjacobs int j = 0;
11492264Sjacobs NSL_RESULT result = NSL_OK;
11502264Sjacobs
11512264Sjacobs /* ---------- */
11522264Sjacobs
11532264Sjacobs if ((attrs != NULL) && (type != NULL) && (value != NULL))
11542264Sjacobs {
11552264Sjacobs #ifdef DEBUG
11562264Sjacobs printf("_addLDAPmodValue() type='%s', value='%s'\n", type, value);
11572264Sjacobs #endif
11582264Sjacobs /* search the existing LDAPMod array for the attribute */
11592264Sjacobs
11602264Sjacobs for (i = 0; *attrs != NULL && (*attrs)[i] != NULL; i++)
11612264Sjacobs {
11622264Sjacobs if (strcasecmp((*attrs)[i]->mod_type, type) == 0)
11632264Sjacobs {
11642264Sjacobs break;
11652264Sjacobs }
11662264Sjacobs }
11672264Sjacobs
11682264Sjacobs if (*attrs == NULL)
11692264Sjacobs {
11702264Sjacobs /* array empty so create it */
11712264Sjacobs
11722264Sjacobs *attrs = (LDAPMod **)calloc(1, 2 * sizeof (LDAPMod *));
11732264Sjacobs if (*attrs != NULL)
11742264Sjacobs {
11752264Sjacobs i = 0;
11762264Sjacobs }
11772264Sjacobs else
11782264Sjacobs {
11792264Sjacobs result = NSL_ERR_MEMORY;
11802264Sjacobs }
11812264Sjacobs
11822264Sjacobs }
11832264Sjacobs else
11842264Sjacobs if ((*attrs)[i] == NULL)
11852264Sjacobs {
11862264Sjacobs *attrs = (LDAPMod **)
11872264Sjacobs realloc(*attrs, (i+2) * sizeof (LDAPMod *));
11882264Sjacobs if (*attrs == NULL)
11892264Sjacobs {
11902264Sjacobs result = NSL_ERR_MEMORY;
11912264Sjacobs }
11922264Sjacobs }
11932264Sjacobs }
11942264Sjacobs else
11952264Sjacobs {
11962264Sjacobs result = NSL_ERR_INTERNAL;
11972264Sjacobs }
11982264Sjacobs
11992264Sjacobs if (result == NSL_OK)
12002264Sjacobs {
12012264Sjacobs if ((*attrs)[i] == NULL)
12022264Sjacobs {
12032264Sjacobs /* We've got a new slot. Create the new mod. */
12042264Sjacobs
12052264Sjacobs (*attrs)[i] = (LDAPMod *) malloc(sizeof (LDAPMod));
12062264Sjacobs if ((*attrs)[i] != NULL)
12072264Sjacobs {
12082264Sjacobs (*attrs)[i]->mod_op = LDAP_MOD_ADD;
12092264Sjacobs (*attrs)[i]->mod_type = strdup(type);
12102264Sjacobs (*attrs)[i]->mod_values = (char **)
12112264Sjacobs malloc(2 * sizeof (char *));
12122264Sjacobs if ((*attrs)[i]->mod_values != NULL)
12132264Sjacobs {
12142264Sjacobs (*attrs)[i]->mod_values[0] =
12152264Sjacobs strdup(value);
12162264Sjacobs (*attrs)[i]->mod_values[1] = NULL;
12172264Sjacobs (*attrs)[i+1] = NULL;
12182264Sjacobs }
12192264Sjacobs else
12202264Sjacobs {
12212264Sjacobs result = NSL_ERR_MEMORY;
12222264Sjacobs }
12232264Sjacobs }
12242264Sjacobs else
12252264Sjacobs {
12262264Sjacobs result = NSL_ERR_MEMORY;
12272264Sjacobs }
12282264Sjacobs }
12292264Sjacobs
12302264Sjacobs else
12312264Sjacobs {
12322264Sjacobs /* Found an existing entry so add value to it */
12332264Sjacobs
12342264Sjacobs for (j = 0; (*attrs)[i]->mod_values[j] != NULL; j++);
12352264Sjacobs
12362264Sjacobs (*attrs)[i]->mod_values =
12372264Sjacobs (char **)realloc((*attrs)[i]->mod_values,
12382264Sjacobs (j + 2) * sizeof (char *));
12392264Sjacobs if ((*attrs)[i]->mod_values != NULL)
12402264Sjacobs {
12412264Sjacobs (*attrs)[i]->mod_values[j] = strdup(value);
12422264Sjacobs (*attrs)[i]->mod_values[j+1] = NULL;
12432264Sjacobs }
12442264Sjacobs else
12452264Sjacobs {
12462264Sjacobs result = NSL_ERR_MEMORY;
12472264Sjacobs }
12482264Sjacobs }
12492264Sjacobs }
12502264Sjacobs
12512264Sjacobs return (result);
12522264Sjacobs } /* _addLDAPmodValue */
12532264Sjacobs
12542264Sjacobs
12552264Sjacobs
12562264Sjacobs
12572264Sjacobs /*
12582264Sjacobs * *****************************************************************************
12592264Sjacobs *
12602264Sjacobs * Function: _modLDAPmodValue()
12612264Sjacobs *
12622264Sjacobs * Description: Add the given attribute modify operation and its value into
12632264Sjacobs * the LDAPMod array. This will either be a "replace" or a
12642264Sjacobs * "delete"; value = null implies a "delete".
12652264Sjacobs * If this is the first entry in the array then create it.
12662264Sjacobs *
12672264Sjacobs * Parameters:
12682264Sjacobs * Input: LDAPMod ***attrs - array to update
12692264Sjacobs * char *type - attribute to modify
12702264Sjacobs * char *value - attribute value, null implies "delete"
12712264Sjacobs * Output: None
12722264Sjacobs *
12732264Sjacobs * Returns: NSL_RESULT - NSL_OK = added okay
12742264Sjacobs *
12752264Sjacobs * *****************************************************************************
12762264Sjacobs */
12772264Sjacobs
12782264Sjacobs static NSL_RESULT
_modLDAPmodValue(LDAPMod *** attrs,char * type,char * value)12792264Sjacobs _modLDAPmodValue(LDAPMod ***attrs, char *type, char *value)
12802264Sjacobs
12812264Sjacobs {
12822264Sjacobs int i = 0;
12832264Sjacobs int j = 0;
12842264Sjacobs NSL_RESULT result = NSL_OK;
12852264Sjacobs
12862264Sjacobs /* ---------- */
12872264Sjacobs
12882264Sjacobs if ((attrs != NULL) && (type != NULL))
12892264Sjacobs {
12902264Sjacobs #ifdef DEBUG
12912264Sjacobs if (value != NULL)
12922264Sjacobs printf("_modLDAPmodValue() REPLACE type='%s', value='%s'\n", type, value);
12932264Sjacobs else
12942264Sjacobs printf("_modLDAPmodValue() DELETE type='%s'\n", type);
12952264Sjacobs #endif
12962264Sjacobs /* search the existing LDAPMod array for the attribute */
12972264Sjacobs
12982264Sjacobs for (i = 0; *attrs != NULL && (*attrs)[i] != NULL; i++)
12992264Sjacobs {
13002264Sjacobs if (strcasecmp((*attrs)[i]->mod_type, type) == 0)
13012264Sjacobs {
13022264Sjacobs break;
13032264Sjacobs }
13042264Sjacobs }
13052264Sjacobs
13062264Sjacobs if (*attrs == NULL)
13072264Sjacobs {
13082264Sjacobs /* array empty so create it */
13092264Sjacobs
13102264Sjacobs *attrs = (LDAPMod **)calloc(1, 2 * sizeof (LDAPMod *));
13112264Sjacobs if (*attrs != NULL)
13122264Sjacobs {
13132264Sjacobs i = 0;
13142264Sjacobs }
13152264Sjacobs else
13162264Sjacobs {
13172264Sjacobs result = NSL_ERR_MEMORY;
13182264Sjacobs }
13192264Sjacobs
13202264Sjacobs }
13212264Sjacobs else
13222264Sjacobs if ((*attrs)[i] == NULL)
13232264Sjacobs {
13242264Sjacobs /* attribute not found in array so add slot for it */
13252264Sjacobs
13262264Sjacobs *attrs = (LDAPMod **)
13272264Sjacobs realloc(*attrs, (i+2) * sizeof (LDAPMod *));
13282264Sjacobs if (*attrs == NULL)
13292264Sjacobs {
13302264Sjacobs result = NSL_ERR_MEMORY;
13312264Sjacobs }
13322264Sjacobs }
13332264Sjacobs }
13342264Sjacobs else
13352264Sjacobs {
13362264Sjacobs result = NSL_ERR_INTERNAL;
13372264Sjacobs }
13382264Sjacobs
13392264Sjacobs if (result == NSL_OK)
13402264Sjacobs {
13412264Sjacobs if ((*attrs)[i] == NULL)
13422264Sjacobs {
13432264Sjacobs /* We've got a new slot. Create the new mod entry */
13442264Sjacobs
13452264Sjacobs (*attrs)[i] = (LDAPMod *) malloc(sizeof (LDAPMod));
13462264Sjacobs if (((*attrs)[i] != NULL) && (value != NULL))
13472264Sjacobs {
13482264Sjacobs /* Do an attribute replace */
13492264Sjacobs
13502264Sjacobs (*attrs)[i]->mod_op = LDAP_MOD_REPLACE;
13512264Sjacobs (*attrs)[i]->mod_type = strdup(type);
13522264Sjacobs (*attrs)[i]->mod_values = (char **)
13532264Sjacobs malloc(2 * sizeof (char *));
13542264Sjacobs if ((*attrs)[i]->mod_values != NULL)
13552264Sjacobs {
13562264Sjacobs (*attrs)[i]->mod_values[0] =
13572264Sjacobs strdup(value);
13582264Sjacobs (*attrs)[i]->mod_values[1] = NULL;
13592264Sjacobs (*attrs)[i+1] = NULL;
13602264Sjacobs }
13612264Sjacobs else
13622264Sjacobs {
13632264Sjacobs result = NSL_ERR_MEMORY;
13642264Sjacobs }
13652264Sjacobs }
13662264Sjacobs else
13672264Sjacobs if ((*attrs)[i] != NULL)
13682264Sjacobs {
13692264Sjacobs /* value is null so do an attribute delete */
13702264Sjacobs
13712264Sjacobs (*attrs)[i]->mod_op = LDAP_MOD_DELETE;
13722264Sjacobs (*attrs)[i]->mod_type = strdup(type);
13732264Sjacobs (*attrs)[i]->mod_values = NULL;
13742264Sjacobs (*attrs)[i+1] = NULL;
13752264Sjacobs }
13762264Sjacobs else
13772264Sjacobs {
13782264Sjacobs result = NSL_ERR_MEMORY; /* malloc failed */
13792264Sjacobs }
13802264Sjacobs }
13812264Sjacobs
13822264Sjacobs else
13832264Sjacobs {
13842264Sjacobs /* Found an existing entry so add value to it */
13852264Sjacobs
13862264Sjacobs if (value != NULL)
13872264Sjacobs {
13882264Sjacobs /* add value to attribute's replace list */
13892264Sjacobs
13902264Sjacobs if ((*attrs)[i]->mod_op == LDAP_MOD_REPLACE)
13912264Sjacobs {
13922264Sjacobs for (j = 0;
13932264Sjacobs (*attrs)[i]->mod_values[j] != NULL; j++);
13942264Sjacobs
13952264Sjacobs (*attrs)[i]->mod_values =
13962264Sjacobs (char **)realloc((*attrs)[i]->mod_values,
13972264Sjacobs (j + 2) * sizeof (char *));
13982264Sjacobs if ((*attrs)[i]->mod_values != NULL)
13992264Sjacobs {
14002264Sjacobs (*attrs)[i]->mod_values[j] =
14012264Sjacobs strdup(value);
14022264Sjacobs (*attrs)[i]->mod_values[j+1] = NULL;
14032264Sjacobs }
14042264Sjacobs else
14052264Sjacobs {
14062264Sjacobs result = NSL_ERR_MEMORY;
14072264Sjacobs }
14082264Sjacobs }
14092264Sjacobs else
14102264Sjacobs {
14112264Sjacobs /* Delete and replace not allowed */
14122264Sjacobs result = NSL_ERR_MULTIOP;
14132264Sjacobs }
14142264Sjacobs }
14152264Sjacobs
14162264Sjacobs else
14172264Sjacobs {
14182264Sjacobs /*
14192264Sjacobs * attribute delete - so free any existing
14202264Sjacobs * entries in the value array
14212264Sjacobs */
14222264Sjacobs
14232264Sjacobs (*attrs)[i]->mod_op = LDAP_MOD_DELETE;
14242264Sjacobs
14252264Sjacobs if ((*attrs)[i]->mod_values != NULL)
14262264Sjacobs {
14272264Sjacobs for (j = 0;
14282264Sjacobs (*attrs)[i]->mod_values[j] != NULL;
14292264Sjacobs j++)
14302264Sjacobs {
14312264Sjacobs free((*attrs)[i]->mod_values[j]);
14322264Sjacobs }
14332264Sjacobs
14342264Sjacobs free((*attrs)[i]->mod_values);
14352264Sjacobs (*attrs)[i]->mod_values = NULL;
14362264Sjacobs }
14372264Sjacobs }
14382264Sjacobs }
14392264Sjacobs }
14402264Sjacobs
14412264Sjacobs return (result);
14422264Sjacobs } /* _modLDAPmodValue */
14432264Sjacobs
14442264Sjacobs
14452264Sjacobs
14462264Sjacobs
14472264Sjacobs
14482264Sjacobs /*
14492264Sjacobs * *****************************************************************************
14502264Sjacobs *
14512264Sjacobs * Function: _constructAddLDAPMod()
14522264Sjacobs *
14532264Sjacobs * Description: For the given attribute list construct an
14542264Sjacobs * LDAPMod array for the printer object to be added. Default
14552264Sjacobs * attribute values are included.
14562264Sjacobs *
14572264Sjacobs * Parameters:
14582264Sjacobs * Input:
14592264Sjacobs * uchar_t *printerName - Name of printer to be added
14602264Sjacobs * char **attrList - user specified attribute values list
14612264Sjacobs * Output: LDAPMod ***attrs - pointer to the constructed array
14622264Sjacobs *
14632264Sjacobs * Returns: NSL_RESULT - NSL_OK = constructed okay
14642264Sjacobs *
14652264Sjacobs * *****************************************************************************
14662264Sjacobs */
14672264Sjacobs
14682264Sjacobs static NSL_RESULT
_constructAddLDAPMod(uchar_t * printerName,char ** attrList,LDAPMod *** attrs)14692264Sjacobs _constructAddLDAPMod(uchar_t *printerName, char **attrList, LDAPMod ***attrs)
14702264Sjacobs
14712264Sjacobs {
14722264Sjacobs NSL_RESULT result = NSL_ERROR;
14732264Sjacobs int len = 0;
14742264Sjacobs char **p = NULL;
14752264Sjacobs char *value = NULL;
14762264Sjacobs char *attr = NULL;
14772264Sjacobs
14782264Sjacobs /* ---------- */
14792264Sjacobs
14802264Sjacobs if ((printerName != NULL) &&
14812264Sjacobs ((attrList != NULL) && (attrList[0] != NULL)) && (attrs != NULL))
14822264Sjacobs {
14832264Sjacobs *attrs = NULL;
14842264Sjacobs
14852264Sjacobs /*
14862264Sjacobs * setup printer object attribute values in an LDAPMod structure
14872264Sjacobs */
14882264Sjacobs result = _addLDAPmodValue(attrs, ATTR_OCLASS, OCV_TOP);
14892264Sjacobs if (result == NSL_OK)
14902264Sjacobs {
14912264Sjacobs /* Structural Objectclass */
14922264Sjacobs result =
14932264Sjacobs _addLDAPmodValue(attrs, ATTR_OCLASS, OCV_PSERVICE);
14942264Sjacobs }
14952264Sjacobs if (result == NSL_OK)
14962264Sjacobs {
14972264Sjacobs result = _addLDAPmodValue(attrs,
14982264Sjacobs ATTR_OCLASS, OCV_PABSTRACT);
14992264Sjacobs }
15002264Sjacobs if (result == NSL_OK)
15012264Sjacobs {
15022264Sjacobs result = _addLDAPmodValue(attrs,
15032264Sjacobs ATTR_OCLASS, OCV_SUNPRT);
15042264Sjacobs }
15052264Sjacobs if (result == NSL_OK)
15062264Sjacobs {
15072264Sjacobs result = _addLDAPmodValue(attrs,
15082264Sjacobs ATTR_PNAME, (char *)printerName);
15092264Sjacobs }
15102264Sjacobs
15112264Sjacobs /*
15122264Sjacobs * Now work through the user supplied attribute
15132264Sjacobs * values list and add them into the LDAPMod array
15142264Sjacobs */
15152264Sjacobs
15162264Sjacobs for (p = attrList;
15172264Sjacobs (p != NULL) && (*p != NULL) && (result == NSL_OK); p++)
15182264Sjacobs {
15192264Sjacobs /* get length of this key word */
15202264Sjacobs
15212264Sjacobs for (len = 0;
15222264Sjacobs ((*p)[len] != '=') && ((*p)[len] != '\0'); len++);
15232264Sjacobs
15242264Sjacobs if ((strlen(*p) > len+1))
15252264Sjacobs {
15262264Sjacobs attr = strdup(*p);
15272264Sjacobs attr[len] = '\0';
15282264Sjacobs value = strdup(&attr[len+1]);
15292264Sjacobs
15302264Sjacobs /* handle specific Key Value Pairs (KVP) */
15312264Sjacobs
15322264Sjacobs if (strcasecmp(attr, NS_KEY_BSDADDR) == 0)
15332264Sjacobs {
15342264Sjacobs /* use LDAP attribute name */
15352264Sjacobs free(attr);
15362264Sjacobs attr = strdup(ATTR_BSDADDR);
15372264Sjacobs }
15382264Sjacobs else
15392264Sjacobs if (_attrInLDAPList(attr) == 0)
15402264Sjacobs {
15412264Sjacobs /*
15422264Sjacobs * Non-LDAP attribute so use LDAP
15432264Sjacobs * KVP attribute and the given KVP
15442264Sjacobs * as the value, ie.
15452264Sjacobs * sun-printer-kvp=description=printer
15462264Sjacobs */
15472264Sjacobs free(attr);
15482264Sjacobs attr = strdup(ATTR_KVP);
15492264Sjacobs value = strdup(*p);
15502264Sjacobs }
15512264Sjacobs
15522264Sjacobs /* add it into the LDAPMod array */
15532264Sjacobs
15542264Sjacobs result = _addLDAPmodValue(attrs, attr, value);
15552264Sjacobs
15562264Sjacobs free(attr);
15572264Sjacobs free(value);
15582264Sjacobs }
15592264Sjacobs } /* for */
15602264Sjacobs
15612264Sjacobs if ((result != NSL_OK) && (*attrs != NULL))
15622264Sjacobs {
15632264Sjacobs (void) ldap_mods_free(*attrs, 1);
15642264Sjacobs attrs = NULL;
15652264Sjacobs }
15662264Sjacobs }
15672264Sjacobs else
15682264Sjacobs {
15692264Sjacobs result = NSL_ERR_INTERNAL;
15702264Sjacobs }
15712264Sjacobs
15722264Sjacobs return (result);
15732264Sjacobs } /* _constructAddLDAPMod */
15742264Sjacobs
15752264Sjacobs
15762264Sjacobs
15772264Sjacobs
15782264Sjacobs
15792264Sjacobs
15802264Sjacobs
15812264Sjacobs /*
15822264Sjacobs * *****************************************************************************
15832264Sjacobs *
15842264Sjacobs * Function: _constructModLDAPMod()
15852264Sjacobs *
15862264Sjacobs * Description: For the given modify attribute list, construct an
15872264Sjacobs * LDAPMod array for the printer object to be modified
15882264Sjacobs *
15892264Sjacobs * Parameters:
15902264Sjacobs * Input: uchar_t *printerName - name of printer to be modified
15912264Sjacobs * int sunPrinter - Boolean; object is a sunPrinter
15922264Sjacobs * char **attrList - user specified attribute values list
15932264Sjacobs * char ***oldKVPList - current list of KVP values on object
15942264Sjacobs * Output: LDAPMod ***attrs - pointer to the constructed array
15952264Sjacobs *
15962264Sjacobs * Returns: NSL_RESULT - NSL_OK = constructed okay
15972264Sjacobs *
15982264Sjacobs * *****************************************************************************
15992264Sjacobs */
16002264Sjacobs
16012264Sjacobs static NSL_RESULT
_constructModLDAPMod(uchar_t * printerName,int sunPrinter,char ** attrList,char *** oldKVPList,LDAPMod *** attrs)16022264Sjacobs _constructModLDAPMod(uchar_t *printerName, int sunPrinter, char **attrList,
16032264Sjacobs char ***oldKVPList, LDAPMod ***attrs)
16042264Sjacobs
16052264Sjacobs {
16062264Sjacobs NSL_RESULT result = NSL_OK;
16072264Sjacobs int len = 0;
16082264Sjacobs int kvpUpdated = 0;
16092264Sjacobs int kvpExists = 0;
16102264Sjacobs char **p = NULL;
16112264Sjacobs char *value = NULL;
16122264Sjacobs char *attr = NULL;
16132264Sjacobs
16142264Sjacobs /* ---------- */
16152264Sjacobs
16162264Sjacobs if ((printerName != NULL) &&
16172264Sjacobs ((attrList != NULL) && (attrList[0] != NULL)) && (attrs != NULL))
16182264Sjacobs {
16192264Sjacobs *attrs = NULL;
16202264Sjacobs
16212264Sjacobs if ((oldKVPList != NULL) && (*oldKVPList != NULL))
16222264Sjacobs {
16232264Sjacobs kvpExists = 1;
16242264Sjacobs }
16252264Sjacobs
16262264Sjacobs if (!sunPrinter)
16272264Sjacobs {
16282264Sjacobs /*
16292264Sjacobs * The object was previously not a sunPrinter, so
16302264Sjacobs * add the required objectclass attribute value, and
16312264Sjacobs * ensure it has the printername attribute.
16322264Sjacobs */
16332264Sjacobs result = _addLDAPmodValue(attrs,
16342264Sjacobs ATTR_OCLASS, OCV_SUNPRT);
16352264Sjacobs if (result == NSL_OK)
16362264Sjacobs {
16372264Sjacobs result = _modLDAPmodValue(attrs,
16382264Sjacobs ATTR_PNAME, (char *)printerName);
16392264Sjacobs }
16402264Sjacobs }
16412264Sjacobs
16422264Sjacobs /*
16432264Sjacobs * work through the user supplied attribute
16442264Sjacobs * values list and add them into the LDAPMod array depending
16452264Sjacobs * on if they are a replace or delete attribute operation,
16462264Sjacobs * a "null value" means delete.
16472264Sjacobs */
16482264Sjacobs
16492264Sjacobs for (p = attrList;
16502264Sjacobs (p != NULL) && (*p != NULL) && (result == NSL_OK); p++)
16512264Sjacobs {
16522264Sjacobs /* get length of this key word */
16532264Sjacobs
16542264Sjacobs for (len = 0;
16552264Sjacobs ((*p)[len] != '=') && ((*p)[len] != '\0'); len++);
16562264Sjacobs
16572264Sjacobs if ((strlen(*p) > len+1))
16582264Sjacobs {
16592264Sjacobs attr = strdup(*p);
16602264Sjacobs attr[len] = '\0';
16612264Sjacobs value = strdup(&attr[len+1]);
16622264Sjacobs
16632264Sjacobs /* handle specific Key Value Pairs (KVP) */
16642264Sjacobs
16652264Sjacobs if ((_attrInLDAPList(attr) == 0) &&
16662264Sjacobs (strcasecmp(attr, NS_KEY_BSDADDR) != 0))
16672264Sjacobs {
16682264Sjacobs /*
16692264Sjacobs * Non-LDAP attribute so use LDAP
16702264Sjacobs * KVP attribute and the given KVP as
16712264Sjacobs * the value, ie.
16722264Sjacobs * sun-printer-kvp=description=printer
16732264Sjacobs */
16742264Sjacobs result = _modAttrKVP(*p, oldKVPList);
16752264Sjacobs kvpUpdated = 1;
16762264Sjacobs }
16772264Sjacobs
16782264Sjacobs else
16792264Sjacobs {
16802264Sjacobs if (strcasecmp(attr, NS_KEY_BSDADDR) ==
16812264Sjacobs 0)
16822264Sjacobs {
16832264Sjacobs /*
16842264Sjacobs * use LDAP bsdaddr attribute
16852264Sjacobs * name
16862264Sjacobs */
16872264Sjacobs free(attr);
16882264Sjacobs attr = strdup(ATTR_BSDADDR);
16892264Sjacobs }
16902264Sjacobs
16912264Sjacobs /*
16922264Sjacobs * else
16932264Sjacobs * use the supplied attribute name
16942264Sjacobs */
16952264Sjacobs
16962264Sjacobs /* add it into the LDAPMod array */
16972264Sjacobs
16982264Sjacobs result = _modLDAPmodValue(attrs,
16992264Sjacobs attr, value);
17002264Sjacobs }
17012264Sjacobs
17022264Sjacobs free(attr);
17032264Sjacobs free(value);
17042264Sjacobs }
17052264Sjacobs
17062264Sjacobs else
17072264Sjacobs if (strlen(*p) >= 1)
17082264Sjacobs {
17092264Sjacobs /* handle attribute DELETE request */
17102264Sjacobs
17112264Sjacobs attr = strdup(*p);
17122264Sjacobs if (attr[len] == '=')
17132264Sjacobs {
17142264Sjacobs /* terminate "attribute=" */
17152264Sjacobs attr[len] = '\0';
17162264Sjacobs }
17172264Sjacobs
17182264Sjacobs /* handle specific Key Value Pairs (KVP) */
17192264Sjacobs
17202264Sjacobs if (strcasecmp(attr, NS_KEY_BSDADDR) == 0)
17212264Sjacobs {
17222264Sjacobs /* use LDAP bsdaddr attribute name */
17232264Sjacobs result = _modLDAPmodValue(attrs,
17242264Sjacobs ATTR_BSDADDR, NULL);
17252264Sjacobs }
17262264Sjacobs else
17272264Sjacobs if (_attrInLDAPList(attr) == 0)
17282264Sjacobs {
17292264Sjacobs /*
17302264Sjacobs * Non-LDAP kvp, so sort items
17312264Sjacobs * in the kvp list
17322264Sjacobs */
17332264Sjacobs result = _modAttrKVP(*p, oldKVPList);
17342264Sjacobs kvpUpdated = 1;
17352264Sjacobs }
17362264Sjacobs else
17372264Sjacobs {
17382264Sjacobs result = _modLDAPmodValue(attrs,
17392264Sjacobs attr, NULL);
17402264Sjacobs }
17412264Sjacobs
17422264Sjacobs free(attr);
17432264Sjacobs }
17442264Sjacobs } /* for */
17452264Sjacobs
17462264Sjacobs if ((result == NSL_OK) && (kvpUpdated))
17472264Sjacobs {
17482264Sjacobs result = _attrAddKVP(attrs, *oldKVPList, kvpExists);
17492264Sjacobs }
17502264Sjacobs
17512264Sjacobs if ((result != NSL_OK) && (*attrs != NULL))
17522264Sjacobs {
17532264Sjacobs (void) ldap_mods_free(*attrs, 1);
17542264Sjacobs *attrs = NULL;
17552264Sjacobs }
17562264Sjacobs }
17572264Sjacobs else
17582264Sjacobs {
17592264Sjacobs result = NSL_ERR_INTERNAL;
17602264Sjacobs }
17612264Sjacobs
17622264Sjacobs return (result);
17632264Sjacobs } /* _constructModLDAPMod */
17642264Sjacobs
17652264Sjacobs
17662264Sjacobs
17672264Sjacobs
17682264Sjacobs
17692264Sjacobs
17702264Sjacobs /*
17712264Sjacobs * *****************************************************************************
17722264Sjacobs *
17732264Sjacobs * Function: _compareURIinDNs()
17742264Sjacobs *
17752264Sjacobs * Description: For the 2 given printer object DNs compare the naming part
17762264Sjacobs * part of the DN (printer-uri) to see if they are the same.
17772264Sjacobs *
17782264Sjacobs * Note: This function only returns "compare failed" if their URI don't
17792264Sjacobs * compare. Problems with the dn etc., return a good compare
17802264Sjacobs * because I don't want us to create a new object for these
17812264Sjacobs *
17822264Sjacobs * Parameters:
17832264Sjacobs * Input: uchar_t *dn1
17842264Sjacobs * uchar_t *dn2
17852264Sjacobs * Output: None
17862264Sjacobs *
17872264Sjacobs * Returns: NSL_RESULT - NSL_OK = URIs are the same
17882264Sjacobs *
17892264Sjacobs * *****************************************************************************
17902264Sjacobs */
17912264Sjacobs
17922264Sjacobs static NSL_RESULT
_compareURIinDNs(uchar_t * dn1,uchar_t * dn2)17932264Sjacobs _compareURIinDNs(uchar_t *dn1, uchar_t *dn2)
17942264Sjacobs
17952264Sjacobs {
17962264Sjacobs NSL_RESULT result = NSL_OK;
17972264Sjacobs uchar_t *DN1 = NULL;
17982264Sjacobs uchar_t *DN2 = NULL;
17992264Sjacobs char *p1 = NULL;
18002264Sjacobs char *p2 = NULL;
18012264Sjacobs
18022264Sjacobs /* --------- */
18032264Sjacobs
18042264Sjacobs if ((dn1 != NULL) && (dn2 != NULL))
18052264Sjacobs {
18062264Sjacobs DN1 = (uchar_t *)strdup((char *)dn1);
18072264Sjacobs DN2 = (uchar_t *)strdup((char *)dn2);
18082264Sjacobs
18092264Sjacobs /* terminate each string after the printer-uri */
18102264Sjacobs
18112264Sjacobs p1 = strstr((char *)DN1, PCONTAINER);
18122264Sjacobs /* move back to the comma */
18132264Sjacobs while ((p1 != NULL) && (*p1 != ',') && (p1 >= (char *)DN1))
18142264Sjacobs {
18152264Sjacobs p1--;
18162264Sjacobs }
18172264Sjacobs
18182264Sjacobs p2 = strstr((char *)DN2, PCONTAINER);
18192264Sjacobs /* move back to the comma */
18202264Sjacobs while ((p2 != NULL) && (*p2 != ',') && (p2 >= (char *)DN2))
18212264Sjacobs {
18222264Sjacobs p2--;
18232264Sjacobs }
18242264Sjacobs
18252264Sjacobs if ((*p1 == ',') && (*p2 == ','))
18262264Sjacobs {
18272264Sjacobs *p1 = '\0'; /* re-terminate it */
18282264Sjacobs *p2 = '\0'; /* re-terminate it */
18292264Sjacobs
18302264Sjacobs /* do the compare */
18312264Sjacobs
18322264Sjacobs /*
18332264Sjacobs * Note: SHOULD really normalise the 2 DNs before
18342264Sjacobs * doing the compare
18352264Sjacobs */
18362264Sjacobs #ifdef DEBUG
18372264Sjacobs printf("_compareURIinDNs() @1 (%s) (%s)\n", DN1, DN2);
18382264Sjacobs #endif
18392264Sjacobs if (strcasecmp((char *)DN1, (char *)DN2) != 0)
18402264Sjacobs {
18412264Sjacobs result = NSL_ERROR;
18422264Sjacobs }
18432264Sjacobs
18442264Sjacobs }
18452264Sjacobs
18462264Sjacobs free(DN1);
18472264Sjacobs free(DN2);
18482264Sjacobs }
18492264Sjacobs
18502264Sjacobs return (result);
18512264Sjacobs } /* _compareURIinDNs */
18522264Sjacobs
18532264Sjacobs
18542264Sjacobs
18552264Sjacobs
18562264Sjacobs
18572264Sjacobs
18582264Sjacobs
18592264Sjacobs /*
18602264Sjacobs * *****************************************************************************
18612264Sjacobs *
18622264Sjacobs * Function: _getThisNSDomainDN()
18632264Sjacobs *
18642264Sjacobs * Description: Get the current Name Service Domain DN
18652264Sjacobs * This is extracted from the result of executing ldaplist.
18662264Sjacobs *
18672264Sjacobs * Note: Do it this way until the NS LDAP library interface is
18682264Sjacobs * made public.
18692264Sjacobs *
18702264Sjacobs * Parameters:
18712264Sjacobs * Input: None
18722264Sjacobs * Output: None
18732264Sjacobs *
18742264Sjacobs * Returns: uchar_t* - pointer to NS Domain DN (The caller should free this
18752264Sjacobs * returned memory).
18762264Sjacobs *
18772264Sjacobs * *****************************************************************************
18782264Sjacobs */
18792264Sjacobs
18802264Sjacobs #define LDAPLIST_D "/usr/bin/ldaplist -d 2>&1"
18812264Sjacobs #define DNID "dn: "
18822264Sjacobs
18832264Sjacobs static uchar_t *
_getThisNSDomainDN(void)18842264Sjacobs _getThisNSDomainDN(void)
18852264Sjacobs
18862264Sjacobs {
18872264Sjacobs uchar_t *domainDN = NULL;
18882264Sjacobs char *cp = NULL;
18892264Sjacobs char buf[BUFSIZ] = "";
18902264Sjacobs
18912264Sjacobs /* --------- */
18922264Sjacobs
18932264Sjacobs if (_popen(LDAPLIST_D, buf, sizeof (buf)) == 0)
18942264Sjacobs {
18952264Sjacobs if ((cp = strstr(buf, DNID)) != NULL)
18962264Sjacobs {
18972264Sjacobs cp += strlen(DNID); /* increment past "dn: " label */
18982264Sjacobs domainDN = (uchar_t *)strdup(cp);
18992264Sjacobs
19002264Sjacobs if ((cp = strchr((char *)domainDN, '\n')) != NULL)
19012264Sjacobs {
19022264Sjacobs *cp = '\0'; /* terminate it */
19032264Sjacobs }
19042264Sjacobs }
19052264Sjacobs }
19062264Sjacobs
19072264Sjacobs return (domainDN);
19082264Sjacobs } /* _getThisNSDomainDN */
19092264Sjacobs
19102264Sjacobs
19112264Sjacobs
19122264Sjacobs
19132264Sjacobs
19142264Sjacobs /*
19152264Sjacobs * *****************************************************************************
19162264Sjacobs *
19172264Sjacobs * Function: _popen()
19182264Sjacobs *
19192264Sjacobs * Description: General popen function. The caller should always use a full
19202264Sjacobs * path cmd.
19212264Sjacobs *
19222264Sjacobs * Parameters:
19232264Sjacobs * Input: char *cmd - command line to execute
19242264Sjacobs * char *buffer - ptr to buffer to put result in
19252264Sjacobs * int size - size of result buffer
19262264Sjacobs * Output: None
19272264Sjacobs *
19282264Sjacobs * Returns: int - 0 = opened okay
19292264Sjacobs *
19302264Sjacobs * *****************************************************************************
19312264Sjacobs */
19322264Sjacobs
19332264Sjacobs static int
_popen(char * cmd,char * buffer,int size)19342264Sjacobs _popen(char *cmd, char *buffer, int size)
19352264Sjacobs
19362264Sjacobs {
19372264Sjacobs int result = -1;
19382264Sjacobs int rsize = 0;
19392264Sjacobs FILE *fptr;
19402264Sjacobs char safe_cmd[BUFSIZ];
19412264Sjacobs char linebuf[BUFSIZ];
19422264Sjacobs
19432264Sjacobs /* -------- */
19442264Sjacobs
19452264Sjacobs if ((cmd != NULL) && (buffer != NULL) && (size != 0))
19462264Sjacobs {
19472264Sjacobs (void) strcpy(buffer, "");
19482264Sjacobs (void) strcpy(linebuf, "");
19492264Sjacobs (void) snprintf(safe_cmd, BUFSIZ, "IFS=' \t'; %s", cmd);
19502264Sjacobs
19512264Sjacobs if ((fptr = popen(safe_cmd, "r")) != NULL)
19522264Sjacobs {
19532264Sjacobs while ((fgets(linebuf, BUFSIZ, fptr) != NULL) &&
19542264Sjacobs (rsize < size))
19552264Sjacobs {
19562264Sjacobs rsize = strlcat(buffer, linebuf, size);
19572264Sjacobs if (rsize >= size)
19582264Sjacobs {
19592264Sjacobs /* result is too long */
19602264Sjacobs (void) memset(buffer, '\0', size);
19612264Sjacobs }
19622264Sjacobs }
19632264Sjacobs
19642264Sjacobs if (strlen(buffer) > 0)
19652264Sjacobs {
19662264Sjacobs result = 0;
19672264Sjacobs }
19682264Sjacobs
19692264Sjacobs (void) pclose(fptr);
19702264Sjacobs }
19712264Sjacobs }
19722264Sjacobs
19732264Sjacobs return (result);
19742264Sjacobs } /* popen */
19752264Sjacobs
19762264Sjacobs
19772264Sjacobs /*
19782264Sjacobs * *****************************************************************************
19792264Sjacobs *
19802264Sjacobs * Function: _attrInList()
19812264Sjacobs *
19822264Sjacobs * Description: For the given list check if the attribute is it
19832264Sjacobs *
19842264Sjacobs * Parameters:
19852264Sjacobs * Input: char *attr - attribute to check
19862264Sjacobs * char **list - list of attributes to check against
19872264Sjacobs * Output: None
19882264Sjacobs *
19892264Sjacobs * Returns: int - TRUE = attr found in list
19902264Sjacobs *
19912264Sjacobs * *****************************************************************************
19922264Sjacobs */
19932264Sjacobs
19942264Sjacobs static int
_attrInList(char * attr,const char ** list)19952264Sjacobs _attrInList(char *attr, const char **list)
19962264Sjacobs
19972264Sjacobs {
19982264Sjacobs int result = 0;
19992264Sjacobs int j;
20002264Sjacobs
20012264Sjacobs /* ------- */
20022264Sjacobs
20032264Sjacobs if ((attr != NULL) && (list != NULL))
20042264Sjacobs {
20052264Sjacobs for (j = 0; (list[j] != NULL) && (result != 1); j++)
20062264Sjacobs {
20072264Sjacobs if (strcasecmp(list[j], attr) == 0)
20082264Sjacobs {
20092264Sjacobs result = 1; /* found */
20102264Sjacobs }
20112264Sjacobs }
20122264Sjacobs }
20132264Sjacobs
20142264Sjacobs return (result);
20152264Sjacobs } /* _attrInList */
20162264Sjacobs
20172264Sjacobs
20182264Sjacobs
20192264Sjacobs
20202264Sjacobs /*
20212264Sjacobs * *****************************************************************************
20222264Sjacobs *
20232264Sjacobs * Function: _attrInLDAPList()
20242264Sjacobs *
20252264Sjacobs * Description: Checks to see if the given attribute is an LDAP printing
20262264Sjacobs * attribute, ie. is either in an IPP objectclass or the
20272264Sjacobs * sun printer objectclass. Note: some attributes are handled
20282264Sjacobs * specifically outside this function, so are excluded from
20292264Sjacobs * the lists that are checked.
20302264Sjacobs *
20312264Sjacobs * Parameters:
20322264Sjacobs * Input: char *attr - attribute to check
20332264Sjacobs * Output: None
20342264Sjacobs *
20352264Sjacobs * Returns: int - TRUE = attr found in list
20362264Sjacobs *
20372264Sjacobs * *****************************************************************************
20382264Sjacobs */
20392264Sjacobs
20402264Sjacobs static int
_attrInLDAPList(char * attr)20412264Sjacobs _attrInLDAPList(char *attr)
20422264Sjacobs
20432264Sjacobs {
20442264Sjacobs int result = 0;
20452264Sjacobs
20462264Sjacobs /* ------- */
20472264Sjacobs
20482264Sjacobs if (_attrInList(attr, nsl_attr_printerService))
20492264Sjacobs {
20502264Sjacobs result = 1; /* in list */
20512264Sjacobs }
20522264Sjacobs else
20532264Sjacobs if (_attrInList(attr, nsl_attr_printerIPP))
20542264Sjacobs {
20552264Sjacobs result = 1; /* in list */
20562264Sjacobs }
20572264Sjacobs else
20582264Sjacobs if (_attrInList(attr, nsl_attr_sunPrinter))
20592264Sjacobs {
20602264Sjacobs result = 1; /* in list */
20612264Sjacobs }
20622264Sjacobs
20632264Sjacobs return (result);
20642264Sjacobs } /* _attrInLDAPList */
20652264Sjacobs
20662264Sjacobs
20672264Sjacobs
20682264Sjacobs
20692264Sjacobs /*
20702264Sjacobs * *****************************************************************************
20712264Sjacobs *
20722264Sjacobs * Function: _getCurrentKVPValues()
20732264Sjacobs *
20742264Sjacobs * Description: For the given printer object read the current set of values
20752264Sjacobs * the object has for the sun-printer-kvp (Key Value pair)
20762264Sjacobs *
20772264Sjacobs * Parameters:
20782264Sjacobs * Input: LDAP *ld - existing ldap connection descriptor
20792264Sjacobs * char *objectDN - DN to search for
20802264Sjacobs * Output: char ***list - returned set of kvp values
20812264Sjacobs *
20822264Sjacobs * Result: NSL_RESULT - NSL_OK = object exists
20832264Sjacobs *
20842264Sjacobs * *****************************************************************************
20852264Sjacobs */
20862264Sjacobs
20872264Sjacobs static NSL_RESULT
_getCurrentKVPValues(LDAP * ld,uchar_t * objectDN,char *** list)20882264Sjacobs _getCurrentKVPValues(LDAP *ld, uchar_t *objectDN, char ***list)
20892264Sjacobs
20902264Sjacobs {
20912264Sjacobs NSL_RESULT result = NSL_ERR_UNKNOWN_PRINTER;
20922264Sjacobs int sresult = LDAP_NO_SUCH_OBJECT;
20932264Sjacobs int i = 0;
20942264Sjacobs LDAPMessage *ldapMsg;
20952264Sjacobs char *requiredAttrs[2] = { ATTR_KVP, NULL };
20962264Sjacobs LDAPMessage *ldapEntry = NULL;
20972264Sjacobs char *entryAttrib = NULL;
20982264Sjacobs char **attribValues = NULL;
20992264Sjacobs BerElement *berElement = NULL;
21002264Sjacobs
21012264Sjacobs /* ---------- */
21022264Sjacobs
21032264Sjacobs if ((list != NULL) && (ld != NULL) && (objectDN != NULL))
21042264Sjacobs {
21052264Sjacobs /* search for this Printer in the directory */
21062264Sjacobs
21072264Sjacobs sresult = ldap_search_s(ld, (char *)objectDN, LDAP_SCOPE_BASE,
21082264Sjacobs "(objectclass=*)", requiredAttrs, 0, &ldapMsg);
21092264Sjacobs if (sresult == LDAP_SUCCESS)
21102264Sjacobs {
21112264Sjacobs /*
21122264Sjacobs * check that the object exists and extract its
21132264Sjacobs * KVP attribute values
21142264Sjacobs */
21152264Sjacobs ldapEntry = ldap_first_entry(ld, ldapMsg);
21162264Sjacobs if (ldapEntry != NULL)
21172264Sjacobs {
21182264Sjacobs entryAttrib = ldap_first_attribute(ld,
21192264Sjacobs ldapEntry, &berElement);
21202264Sjacobs if ((entryAttrib != NULL) &&
21212264Sjacobs (strcasecmp(entryAttrib, ATTR_KVP) == 0))
21222264Sjacobs
21232264Sjacobs {
21242264Sjacobs #ifdef DEBUG
21252264Sjacobs printf("Attribute: %s, its values are:\n", entryAttrib);
21262264Sjacobs #endif
21272264Sjacobs /*
21282264Sjacobs * add each KVP value to the list
21292264Sjacobs * that we will return
21302264Sjacobs */
21312264Sjacobs attribValues = ldap_get_values(
21322264Sjacobs ld, ldapEntry, entryAttrib);
21332264Sjacobs for (i = 0;
21342264Sjacobs attribValues[i] != NULL; i++)
21352264Sjacobs {
21362264Sjacobs *list = (char **)
21372264Sjacobs list_append((void **)*list,
21382264Sjacobs strdup(attribValues[i]));
21392264Sjacobs #ifdef DEBUG
21402264Sjacobs printf("\t%s\n", attribValues[i]);
21412264Sjacobs #endif
21422264Sjacobs }
21432264Sjacobs (void) ldap_value_free(attribValues);
21442264Sjacobs }
21452264Sjacobs
21462264Sjacobs if ((entryAttrib != NULL) &&
21472264Sjacobs (berElement != NULL))
21482264Sjacobs {
21492264Sjacobs ber_free(berElement, 0);
21502264Sjacobs }
21512264Sjacobs
21522264Sjacobs
21532264Sjacobs /* object found */
21542264Sjacobs result = NSL_OK;
21552264Sjacobs }
21562264Sjacobs
21572264Sjacobs (void) ldap_msgfree(ldapMsg);
21582264Sjacobs }
21592264Sjacobs }
21602264Sjacobs
21612264Sjacobs else
21622264Sjacobs {
21632264Sjacobs result = NSL_ERR_INTERNAL;
21642264Sjacobs }
21652264Sjacobs
21662264Sjacobs return (result);
21672264Sjacobs } /* _getCurrentKVPValues */
21682264Sjacobs
21692264Sjacobs
21702264Sjacobs
21712264Sjacobs /*
21722264Sjacobs * *****************************************************************************
21732264Sjacobs *
21742264Sjacobs * Function: _freeList()
21752264Sjacobs *
21762264Sjacobs * Description: Free the list created by list_append() where the items in
21772264Sjacobs * the list have been strdup'ed.
21782264Sjacobs *
21792264Sjacobs * Parameters:
21802264Sjacobs * Input: char ***list - returned set of kvp values
21812264Sjacobs *
21822264Sjacobs * Result: void
21832264Sjacobs *
21842264Sjacobs * *****************************************************************************
21852264Sjacobs */
21862264Sjacobs
21872264Sjacobs static void
_freeList(char *** list)21882264Sjacobs _freeList(char ***list)
21892264Sjacobs
21902264Sjacobs {
21912264Sjacobs int i = 0;
21922264Sjacobs
21932264Sjacobs /* ------ */
21942264Sjacobs
21952264Sjacobs if (list != NULL)
21962264Sjacobs {
21972264Sjacobs if (*list != NULL)
21982264Sjacobs {
21992264Sjacobs for (i = 0; (*list)[i] != NULL; i++)
22002264Sjacobs {
22012264Sjacobs free((*list)[i]);
22022264Sjacobs }
22032264Sjacobs free(*list);
22042264Sjacobs }
22052264Sjacobs
22062264Sjacobs *list = NULL;
22072264Sjacobs }
22082264Sjacobs } /* _freeList */
22092264Sjacobs
22102264Sjacobs
22112264Sjacobs
22122264Sjacobs /*
22132264Sjacobs * *****************************************************************************
22142264Sjacobs *
22152264Sjacobs * Function: _modAttrKVP()
22162264Sjacobs *
22172264Sjacobs * Description: Sort out the KVP attribute value list, such that this new
22182264Sjacobs * value takes precidence over any existing value in the list.
22192264Sjacobs * The current list is updated to remove this key, and the new
22202264Sjacobs * key "value" is added to the list, eg. for
22212264Sjacobs * value: bbb=ddddd
22222264Sjacobs * and kvpList:
22232264Sjacobs * aaa=yyyy
22242264Sjacobs * bbb=zzzz
22252264Sjacobs * ccc=xxxx
22262264Sjacobs * the resulting kvpList is:
22272264Sjacobs * aaa=yyyy
22282264Sjacobs * ccc=xxxx
22292264Sjacobs * bbb=ddddd
22302264Sjacobs *
22312264Sjacobs * Note: When all new values have been handled the function _attrAddKVP()
22322264Sjacobs * must be called to add the "new list" values into the
22332264Sjacobs * LDAPMod array.
22342264Sjacobs *
22352264Sjacobs * Parameters:
22362264Sjacobs * Input: char *value - Key Value Pair to process,
22372264Sjacobs * eg. aaaaa=hhhhh, where aaaaa is the key
22382264Sjacobs * char ***kvpList - list of current KVP values
22392264Sjacobs * Output: char ***kvpList - updated list of KVP values
22402264Sjacobs *
22412264Sjacobs * Returns: NSL_RESULT - NSL_OK = done okay
22422264Sjacobs *
22432264Sjacobs * *****************************************************************************
22442264Sjacobs */
22452264Sjacobs
22462264Sjacobs static NSL_RESULT
_modAttrKVP(char * value,char *** kvpList)22472264Sjacobs _modAttrKVP(char *value, char ***kvpList)
22482264Sjacobs
22492264Sjacobs {
22502264Sjacobs NSL_RESULT result = NSL_ERR_INTERNAL;
22512264Sjacobs int i = 0;
22522264Sjacobs int inList = 0;
22532264Sjacobs int keyDelete = 0;
22542264Sjacobs char *key = NULL;
22552264Sjacobs char **p = NULL;
22562264Sjacobs char **newList = NULL;
22572264Sjacobs
22582264Sjacobs /* ------- */
22592264Sjacobs
22602264Sjacobs if ((value != NULL) && (kvpList != NULL))
22612264Sjacobs {
22622264Sjacobs result = NSL_OK;
22632264Sjacobs
22642264Sjacobs /* extract "key" from value */
22652264Sjacobs
22662264Sjacobs key = strdup(value);
22672264Sjacobs
22682264Sjacobs for (i = 0; ((key)[i] != '=') && ((key)[i] != '\0'); i++);
22692264Sjacobs key[i] = '\0'; /* terminate the key */
22702264Sjacobs
22712264Sjacobs /* Is this a request to delete a "key" value */
22722264Sjacobs
22732264Sjacobs if ((value[i] == '\0') || (value[i+1] == '\0'))
22742264Sjacobs {
22752264Sjacobs /* this is a request to delete the key */
22762264Sjacobs keyDelete = 1;
22772264Sjacobs }
22782264Sjacobs
22792264Sjacobs if ((*kvpList != NULL) && (**kvpList != NULL))
22802264Sjacobs {
22812264Sjacobs /*
22822264Sjacobs * for each item in the list remove it if the keys match
22832264Sjacobs */
22842264Sjacobs for (p = *kvpList; *p != NULL; p++)
22852264Sjacobs {
22862264Sjacobs for (i = 0;
22872264Sjacobs ((*p)[i] != '=') && ((*p)[i] != '\0'); i++);
22882264Sjacobs
22892264Sjacobs if ((strlen(key) == i) &&
22902264Sjacobs (strncasecmp(*p, key, i) == 0))
22912264Sjacobs {
22922264Sjacobs inList = 1;
22932264Sjacobs }
22942264Sjacobs else
22952264Sjacobs {
22962264Sjacobs /* no match so add value to new list */
22972264Sjacobs newList = (char **)list_append(
22982264Sjacobs (void **)newList,
22992264Sjacobs strdup(*p));
23002264Sjacobs }
23012264Sjacobs }
23022264Sjacobs }
23032264Sjacobs
23042264Sjacobs /*
23052264Sjacobs * if it was not a DELETE request add the new key value into
23062264Sjacobs * the newList, otherwise we have already removed the key
23072264Sjacobs */
23082264Sjacobs
23092264Sjacobs if (!keyDelete)
23102264Sjacobs {
23112264Sjacobs newList = (char **)list_append((void **)newList,
23122264Sjacobs strdup(value));
23132264Sjacobs }
23142264Sjacobs
23152264Sjacobs if ((newList != NULL) || (inList))
23162264Sjacobs {
23172264Sjacobs /* replace old list with the newList */
23182264Sjacobs _freeList(kvpList);
23192264Sjacobs *kvpList = newList;
23202264Sjacobs }
23212264Sjacobs
23222264Sjacobs free(key);
23232264Sjacobs }
23242264Sjacobs
23252264Sjacobs return (result);
23262264Sjacobs } /* modAttrKVP */
23272264Sjacobs
23282264Sjacobs
23292264Sjacobs
23302264Sjacobs
23312264Sjacobs /*
23322264Sjacobs * *****************************************************************************
23332264Sjacobs *
23342264Sjacobs * Function: _attrAddKVP()
23352264Sjacobs *
23362264Sjacobs * Description: Process KVP items in the kvpList adding them to the
23372264Sjacobs * LDAPMod modify array. If the list is empty but there were
23382264Sjacobs * previously LDAP KVP values delete them.
23392264Sjacobs *
23402264Sjacobs * Note: This function should only be called when all the new KVP
23412264Sjacobs * items have been processed by _modAttrKVP()
23422264Sjacobs *
23432264Sjacobs * Parameters:
23442264Sjacobs * Input: LDAPMod ***attrs - array to update
23452264Sjacobs * char **kvpList - list KVP values
23462264Sjacobs * int kvpExists - object currently has LDAP KVP values
23472264Sjacobs * Output: None
23482264Sjacobs *
23492264Sjacobs * Returns: NSL_RESULT - NSL_OK = done okay
23502264Sjacobs *
23512264Sjacobs * *****************************************************************************
23522264Sjacobs */
23532264Sjacobs
23542264Sjacobs static NSL_RESULT
_attrAddKVP(LDAPMod *** attrs,char ** kvpList,int kvpExists)23552264Sjacobs _attrAddKVP(LDAPMod ***attrs, char **kvpList, int kvpExists)
23562264Sjacobs
23572264Sjacobs {
23582264Sjacobs NSL_RESULT result = NSL_OK;
23592264Sjacobs
23602264Sjacobs /* ------- */
23612264Sjacobs
23622264Sjacobs if (attrs != NULL)
23632264Sjacobs {
23642264Sjacobs if (kvpList != NULL)
23652264Sjacobs {
23662264Sjacobs while ((kvpList != NULL) && (*kvpList != NULL))
23672264Sjacobs {
23682264Sjacobs /* add item to LDAPMod array */
23692264Sjacobs
23702264Sjacobs result =
23712264Sjacobs _modLDAPmodValue(attrs, ATTR_KVP, *kvpList);
23722264Sjacobs
23732264Sjacobs kvpList++;
23742264Sjacobs }
23752264Sjacobs }
23762264Sjacobs else
23772264Sjacobs if (kvpExists)
23782264Sjacobs {
23792264Sjacobs /*
23802264Sjacobs * We now have no LDAP KVP values but there were
23812264Sjacobs * some previously, so delete them
23822264Sjacobs */
23832264Sjacobs result = _modLDAPmodValue(attrs, ATTR_KVP, NULL);
23842264Sjacobs }
23852264Sjacobs }
23862264Sjacobs
23872264Sjacobs else
23882264Sjacobs {
23892264Sjacobs result = NSL_ERR_INTERNAL;
23902264Sjacobs }
23912264Sjacobs
23922264Sjacobs return (result);
23932264Sjacobs } /* _attrAddKVP */
23942264Sjacobs
23952264Sjacobs
23962264Sjacobs
23972264Sjacobs
23982264Sjacobs /*
23992264Sjacobs * *****************************************************************************
24002264Sjacobs *
24012264Sjacobs * Function: _manageReferralCredentials()
24022264Sjacobs *
24032264Sjacobs * Description: This function is called if a referral request is returned by
24042264Sjacobs * the origonal LDAP server during the ldap update request call,
24052264Sjacobs * eg. ldap_add_s(), ldap_modify_s() or ldap_delete_s().
24062264Sjacobs * Parameters:
24072264Sjacobs * Input: LDAP *ld - LDAP descriptor
24082264Sjacobs * int freeit - 0 = first call to get details
24092264Sjacobs * - 1 = second call to free details
24102264Sjacobs * - -1 = initial store of authentication details
24112264Sjacobs * Input/Output: char **dn - returns DN to bind to on master
24122264Sjacobs * char **credp - returns password for DN
24132264Sjacobs * int *methodp - returns authentication type, eg. simple
24142264Sjacobs *
24152264Sjacobs * Returns: int - 0 = okay
24162264Sjacobs *
24172264Sjacobs * *****************************************************************************
24182264Sjacobs */
_manageReferralCredentials(LDAP * ld,char ** dn,char ** credp,int * methodp,int freeit)24192264Sjacobs static int _manageReferralCredentials(LDAP *ld, char **dn, char **credp,
24202264Sjacobs int *methodp, int freeit)
24212264Sjacobs
24222264Sjacobs {
24232264Sjacobs int result = 0;
24242264Sjacobs static char *sDN = NULL;
24252264Sjacobs static char *sPasswd = NULL;
24262264Sjacobs static int sMethod = LDAP_AUTH_SIMPLE;
24272264Sjacobs
24282264Sjacobs /* -------- */
24292264Sjacobs
24302264Sjacobs if (freeit == 1)
24312264Sjacobs {
24322264Sjacobs /* second call - free memory */
24332264Sjacobs
24342264Sjacobs if ((dn != NULL) && (*dn != NULL))
24352264Sjacobs {
24362264Sjacobs free(*dn);
24372264Sjacobs }
24382264Sjacobs
24392264Sjacobs if ((credp != NULL) && (*credp != NULL))
24402264Sjacobs {
24412264Sjacobs free(*credp);
24422264Sjacobs }
24432264Sjacobs }
24442264Sjacobs
24452264Sjacobs else
24462264Sjacobs if ((ld != NULL) &&
24472264Sjacobs (dn != NULL) && (credp != NULL) && (methodp != NULL))
24482264Sjacobs {
24492264Sjacobs if ((freeit == 0) && (sDN != NULL) && (sPasswd != NULL))
24502264Sjacobs {
24512264Sjacobs /* first call - get the saved bind credentials */
24522264Sjacobs
24532264Sjacobs *dn = strdup(sDN);
24542264Sjacobs *credp = strdup(sPasswd);
24552264Sjacobs *methodp = sMethod;
24562264Sjacobs }
24572264Sjacobs else
24582264Sjacobs if (freeit == -1)
24592264Sjacobs {
24602264Sjacobs /* initial call - save the saved bind credentials */
24612264Sjacobs
24622264Sjacobs sDN = *dn;
24632264Sjacobs sPasswd = *credp;
24642264Sjacobs sMethod = *methodp;
24652264Sjacobs }
24662264Sjacobs else
24672264Sjacobs {
24682264Sjacobs result = 1; /* error */
24692264Sjacobs }
24702264Sjacobs }
24712264Sjacobs else
24722264Sjacobs {
24732264Sjacobs result = 1; /* error */
24742264Sjacobs }
24752264Sjacobs
24762264Sjacobs return (result);
24772264Sjacobs } /* _manageReferralCredentials */
2478