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 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 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 * 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 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 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 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 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 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 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 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 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 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 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 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 * 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 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 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 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 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 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 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 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 */ 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