1*2264Sjacobs /* 2*2264Sjacobs * CDDL HEADER START 3*2264Sjacobs * 4*2264Sjacobs * The contents of this file are subject to the terms of the 5*2264Sjacobs * Common Development and Distribution License (the "License"). 6*2264Sjacobs * You may not use this file except in compliance with the License. 7*2264Sjacobs * 8*2264Sjacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*2264Sjacobs * or http://www.opensolaris.org/os/licensing. 10*2264Sjacobs * See the License for the specific language governing permissions 11*2264Sjacobs * and limitations under the License. 12*2264Sjacobs * 13*2264Sjacobs * When distributing Covered Code, include this CDDL HEADER in each 14*2264Sjacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*2264Sjacobs * If applicable, add the following below this CDDL HEADER, with the 16*2264Sjacobs * fields enclosed by brackets "[]" replaced with your own identifying 17*2264Sjacobs * information: Portions Copyright [yyyy] [name of copyright owner] 18*2264Sjacobs * 19*2264Sjacobs * CDDL HEADER END 20*2264Sjacobs */ 21*2264Sjacobs /* 22*2264Sjacobs * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23*2264Sjacobs * Use is subject to license terms. 24*2264Sjacobs */ 25*2264Sjacobs 26*2264Sjacobs #pragma ident "%Z%%M% %I% %E% SMI" 27*2264Sjacobs 28*2264Sjacobs #include <stdio.h> 29*2264Sjacobs #include <stdlib.h> 30*2264Sjacobs #include <unistd.h> 31*2264Sjacobs #include <sys/types.h> 32*2264Sjacobs #include <sys/stat.h> 33*2264Sjacobs #include <string.h> 34*2264Sjacobs #include <stdarg.h> 35*2264Sjacobs #include <fcntl.h> 36*2264Sjacobs #include <syslog.h> 37*2264Sjacobs #include <errno.h> 38*2264Sjacobs #include <pwd.h> 39*2264Sjacobs #include <libintl.h> 40*2264Sjacobs #include <netdb.h> /* for rcmd() */ 41*2264Sjacobs 42*2264Sjacobs #include <ns.h> 43*2264Sjacobs #include <list.h> 44*2264Sjacobs #include <misc.h> 45*2264Sjacobs 46*2264Sjacobs #define LDAP_REFERRALS 47*2264Sjacobs #include <lber.h> 48*2264Sjacobs #include <ldap.h> 49*2264Sjacobs #include <sys/systeminfo.h> 50*2264Sjacobs 51*2264Sjacobs 52*2264Sjacobs /* 53*2264Sjacobs * This modules contains the code required to manipulate printer objects in 54*2264Sjacobs * a LDAP directory for the Naming Service (NS) switch. 55*2264Sjacobs * It can "add", "modify" and "delete" the objects on the given ldap server 56*2264Sjacobs * and in the given NS domain DN, eg. "dc=mkg,dc=sun,dc=com". 57*2264Sjacobs * Note: printers known to the naming service are contained in the RDN 58*2264Sjacobs * "ou=printers" under the NS domain DN 59*2264Sjacobs */ 60*2264Sjacobs 61*2264Sjacobs #define PCONTAINER "ou=printers" 62*2264Sjacobs 63*2264Sjacobs /* attribute keywords */ 64*2264Sjacobs #define ATTR_DN "dn" 65*2264Sjacobs #define ATTR_OCLASS "objectClass" 66*2264Sjacobs #define ATTR_URI "printer-uri" 67*2264Sjacobs #define ATTR_PNAME "printer-name" 68*2264Sjacobs #define ATTR_XRISUP "printer-xri-supported" 69*2264Sjacobs #define ATTR_BSDADDR "sun-printer-bsdaddr" 70*2264Sjacobs #define ATTR_KVP "sun-printer-kvp" 71*2264Sjacobs 72*2264Sjacobs /* objectClass values */ 73*2264Sjacobs #define OCV_TOP "top" 74*2264Sjacobs #define OCV_PSERVICE "printerService" 75*2264Sjacobs #define OCV_SUNPRT "sunPrinter" 76*2264Sjacobs #define OCV_PABSTRACT "printerAbstract" 77*2264Sjacobs 78*2264Sjacobs /* xri-supported attribute value */ 79*2264Sjacobs #define AV_UNKNOWN "unknown" 80*2264Sjacobs 81*2264Sjacobs 82*2264Sjacobs /* 83*2264Sjacobs * LDAP objectclass atributes that the user can explicity change 84*2264Sjacobs */ 85*2264Sjacobs 86*2264Sjacobs static const char *nsl_attr_printerService[] = { 87*2264Sjacobs "printer-uri", 88*2264Sjacobs "printer-xri-supported", 89*2264Sjacobs /* Not allowed "printer-name", */ 90*2264Sjacobs "printer-natural-language-configured", 91*2264Sjacobs "printer-location", 92*2264Sjacobs "printer-info", 93*2264Sjacobs "printer-more-info", 94*2264Sjacobs "printer-make-and-model", 95*2264Sjacobs "printer-charset-configured", 96*2264Sjacobs "printer-charset-supported", 97*2264Sjacobs "printer-generated-natural-language-supported", 98*2264Sjacobs "printer-document-format-supported", 99*2264Sjacobs "printer-color-supported", 100*2264Sjacobs "printer-compression-supported", 101*2264Sjacobs "printer-pages-per-minute", 102*2264Sjacobs "printer-pages-per-minute-color", 103*2264Sjacobs "printer-finishings-supported", 104*2264Sjacobs "printer-number-up-supported", 105*2264Sjacobs "printer-sides-supported", 106*2264Sjacobs "printer-media-supported", 107*2264Sjacobs "printer-media-local-supported", 108*2264Sjacobs "printer-resolution-supported", 109*2264Sjacobs "printer-print-quality-supported", 110*2264Sjacobs "printer-job-priority-supported", 111*2264Sjacobs "printer-copies-supported", 112*2264Sjacobs "printer-job-k-octets-supported", 113*2264Sjacobs "printer-current-operator", 114*2264Sjacobs "printer-service-person", 115*2264Sjacobs "printer-delivery-orientation-supported", 116*2264Sjacobs "printer-stacking-order-supported", 117*2264Sjacobs "printer-output-features-supported", 118*2264Sjacobs (char *)NULL 119*2264Sjacobs }; 120*2264Sjacobs 121*2264Sjacobs 122*2264Sjacobs static const char *nsl_attr_printerIPP[] = { 123*2264Sjacobs "printer-ipp-versions-supported", 124*2264Sjacobs "printer-multiple-document-jobs-supported", 125*2264Sjacobs (char *)NULL 126*2264Sjacobs }; 127*2264Sjacobs 128*2264Sjacobs static const char *nsl_attr_sunPrinter[] = { 129*2264Sjacobs /* Not allowed "sun-printer-bsdaddr", */ 130*2264Sjacobs /* Not allowed "sun-printer-kvp", */ 131*2264Sjacobs (char *)NULL 132*2264Sjacobs }; 133*2264Sjacobs 134*2264Sjacobs 135*2264Sjacobs /* 136*2264Sjacobs * List of LDAP attributes that user is not allowed to explicitly change 137*2264Sjacobs */ 138*2264Sjacobs static const char *nsl_attr_notAllowed[] = { 139*2264Sjacobs ATTR_DN, 140*2264Sjacobs ATTR_OCLASS, /* objectclass */ 141*2264Sjacobs ATTR_PNAME, /* printer-name */ 142*2264Sjacobs ATTR_BSDADDR, 143*2264Sjacobs ATTR_KVP, 144*2264Sjacobs (char *)NULL 145*2264Sjacobs }; 146*2264Sjacobs 147*2264Sjacobs 148*2264Sjacobs static NSL_RESULT _connectToLDAP(ns_cred_t *cred, LDAP **ld); 149*2264Sjacobs static uchar_t *_constructPrinterDN(uchar_t *printerName, 150*2264Sjacobs uchar_t *domainDN, char **attrList); 151*2264Sjacobs static NSL_RESULT _checkPrinterExists(LDAP *ld, uchar_t *printerName, 152*2264Sjacobs uchar_t *domainDN, uchar_t **printerDN); 153*2264Sjacobs static NSL_RESULT _checkPrinterDNExists(LDAP *ld, uchar_t *objectDN); 154*2264Sjacobs static NSL_RESULT _checkSunPrinter(LDAP *ld, uchar_t *printerDN); 155*2264Sjacobs static NSL_RESULT _addNewPrinterObject(LDAP *ld, uchar_t *printerName, 156*2264Sjacobs uchar_t *domainDN, char **attrList); 157*2264Sjacobs static NSL_RESULT _modifyPrinterObject(LDAP *ld, uchar_t *printerDN, 158*2264Sjacobs uchar_t *printerName, uchar_t *domainDN, char **attrList); 159*2264Sjacobs static NSL_RESULT _checkAttributes(char **list); 160*2264Sjacobs static NSL_RESULT _addLDAPmodValue(LDAPMod ***attrs, char *type, char *value); 161*2264Sjacobs static NSL_RESULT _modLDAPmodValue(LDAPMod ***attrs, char *type, char *value); 162*2264Sjacobs static NSL_RESULT _constructAddLDAPMod(uchar_t *printerName, 163*2264Sjacobs char **attrList, LDAPMod ***attrs); 164*2264Sjacobs static NSL_RESULT _constructModLDAPMod(uchar_t *printerName, int sunPrinter, 165*2264Sjacobs char **attrList, char ***oldKVPList, LDAPMod ***attrs); 166*2264Sjacobs static NSL_RESULT _compareURIinDNs(uchar_t *dn1, uchar_t *dn2); 167*2264Sjacobs static uchar_t *_getThisNSDomainDN(void); 168*2264Sjacobs static int _popen(char *cmd, char *results, int size); 169*2264Sjacobs static int _attrInList(char *attr, const char **list); 170*2264Sjacobs static int _attrInLDAPList(char *attr); 171*2264Sjacobs static NSL_RESULT _getCurrentKVPValues(LDAP *ld, 172*2264Sjacobs uchar_t *objectDN, char ***list); 173*2264Sjacobs static void _freeList(char ***list); 174*2264Sjacobs static NSL_RESULT _modAttrKVP(char *value, char ***kvpList); 175*2264Sjacobs static NSL_RESULT _attrAddKVP(LDAPMod ***attrs, char **kvpList, int kvpExists); 176*2264Sjacobs static int _manageReferralCredentials(LDAP *ld, char **dn, char **credp, 177*2264Sjacobs int *methodp, int freeit); 178*2264Sjacobs 179*2264Sjacobs /* 180*2264Sjacobs * ***************************************************************************** 181*2264Sjacobs * 182*2264Sjacobs * Function: ldap_put_printer() 183*2264Sjacobs * 184*2264Sjacobs * Description: Action the request to change a printer object in the LDAP 185*2264Sjacobs * directory DIT. The object is either added, modified or deleted 186*2264Sjacobs * depending on the request's attribute list. A null list indicates 187*2264Sjacobs * the request is a delete. 188*2264Sjacobs * The object's DN is constructed from the supplied domain DN and 189*2264Sjacobs * a check is done to see if the object exists already, if it 190*2264Sjacobs * doesn't exist then this is a request to add a new object 191*2264Sjacobs * If a URI is given in the attribute list and it is different to 192*2264Sjacobs * the existing printing object's DN then the request will be 193*2264Sjacobs * rejected. 194*2264Sjacobs * 195*2264Sjacobs * 196*2264Sjacobs * Parameters: 197*2264Sjacobs * Input: const ns_printer_t *printer 198*2264Sjacobs * - this structure contains the following : 199*2264Sjacobs * char *printerName - name of the printer 200*2264Sjacobs * ns_cred_t *cred - structure containing the ldap host and 201*2264Sjacobs * port, user, password and NS domain DN for the 202*2264Sjacobs * directory server to be updated. 203*2264Sjacobs * char **attrList - pointer to a list of attribute key values 204*2264Sjacobs * for the printer object. If the object does 205*2264Sjacobs * not already exist then this list contains the 206*2264Sjacobs * values for the new object, otherwise this list 207*2264Sjacobs * is a list of attributes to modify. For modify 208*2264Sjacobs * a null attribute value is a attribute delete 209*2264Sjacobs * request. A NULL ptr = delete the object. 210*2264Sjacobs * Output: None 211*2264Sjacobs * 212*2264Sjacobs * Returns: int - 0 = request actioned okay 213*2264Sjacobs * !0 = error - see NSL_RESULT codes 214*2264Sjacobs * 215*2264Sjacobs * ***************************************************************************** 216*2264Sjacobs */ 217*2264Sjacobs 218*2264Sjacobs int 219*2264Sjacobs ldap_put_printer(const ns_printer_t *printer) 220*2264Sjacobs 221*2264Sjacobs { 222*2264Sjacobs NSL_RESULT result = NSL_OK; 223*2264Sjacobs NSL_RESULT printerExists = NSL_ERR_UNKNOWN_PRINTER; 224*2264Sjacobs LDAP *ld = NULL; 225*2264Sjacobs uchar_t *printerDN = NULL; 226*2264Sjacobs uchar_t *domainDN = NULL; 227*2264Sjacobs char *printerName = NULL; 228*2264Sjacobs ns_cred_t *cred = NULL; 229*2264Sjacobs char **attrList = NULL; 230*2264Sjacobs 231*2264Sjacobs /* -------- */ 232*2264Sjacobs 233*2264Sjacobs /* 234*2264Sjacobs * Note: the "attributes" list should be null for ldap as the attribute 235*2264Sjacobs * values are passed in the nsdata field 236*2264Sjacobs */ 237*2264Sjacobs 238*2264Sjacobs if ((printer != NULL) && 239*2264Sjacobs (printer->attributes == NULL) && (printer->name != NULL)) 240*2264Sjacobs { 241*2264Sjacobs /* extract required pointer values from structure */ 242*2264Sjacobs 243*2264Sjacobs printerName = printer->name; 244*2264Sjacobs cred = printer->cred; 245*2264Sjacobs if (printer->nsdata != NULL) 246*2264Sjacobs { 247*2264Sjacobs attrList = ((NS_LDAPDATA *)(printer->nsdata))->attrList; 248*2264Sjacobs } 249*2264Sjacobs 250*2264Sjacobs /* connect and bind to the ldap directory server */ 251*2264Sjacobs 252*2264Sjacobs result = _connectToLDAP(cred, &ld); 253*2264Sjacobs if ((result == NSL_OK) && (ld != NULL)) 254*2264Sjacobs { 255*2264Sjacobs /* 256*2264Sjacobs * check if the NS domain DN was given, if not use the 257*2264Sjacobs * current NS domain 258*2264Sjacobs */ 259*2264Sjacobs 260*2264Sjacobs if (cred->domainDN != NULL) 261*2264Sjacobs { 262*2264Sjacobs domainDN = (uchar_t *) 263*2264Sjacobs strdup((char *)cred->domainDN); 264*2264Sjacobs } 265*2264Sjacobs else 266*2264Sjacobs { 267*2264Sjacobs /* get DN of current domain */ 268*2264Sjacobs domainDN = _getThisNSDomainDN(); 269*2264Sjacobs } 270*2264Sjacobs 271*2264Sjacobs printerExists = 272*2264Sjacobs _checkPrinterExists(ld, (uchar_t *)printerName, 273*2264Sjacobs domainDN, &printerDN); 274*2264Sjacobs if (printerExists != LDAP_SUCCESS) 275*2264Sjacobs { 276*2264Sjacobs /* 277*2264Sjacobs * could not find the printer by printer-name, 278*2264Sjacobs * but there could be a non sunPrinter object 279*2264Sjacobs * so if the printer-uri was given check if 280*2264Sjacobs * an object for that exists 281*2264Sjacobs */ 282*2264Sjacobs printerDN = 283*2264Sjacobs _constructPrinterDN(NULL, 284*2264Sjacobs domainDN, attrList); 285*2264Sjacobs if (printerDN != NULL) 286*2264Sjacobs { 287*2264Sjacobs printerExists = _checkPrinterDNExists( 288*2264Sjacobs ld, printerDN); 289*2264Sjacobs } 290*2264Sjacobs } 291*2264Sjacobs #ifdef DEBUG 292*2264Sjacobs if (printerExists == NSL_OK) 293*2264Sjacobs { 294*2264Sjacobs printf("DN found = '%s' for '%s'\n", printerDN, printerName); 295*2264Sjacobs } 296*2264Sjacobs #endif 297*2264Sjacobs 298*2264Sjacobs if (attrList == NULL) 299*2264Sjacobs { 300*2264Sjacobs /* 301*2264Sjacobs * a null list indicates that this is a DELETE 302*2264Sjacobs * object request, so if object exists delete 303*2264Sjacobs * it, otherwise report an error. 304*2264Sjacobs */ 305*2264Sjacobs if (printerExists == LDAP_SUCCESS) 306*2264Sjacobs { 307*2264Sjacobs result = ldap_delete_s(ld, 308*2264Sjacobs (char *)printerDN); 309*2264Sjacobs if (result != LDAP_SUCCESS) 310*2264Sjacobs { 311*2264Sjacobs result = NSL_ERR_DEL_FAILED; 312*2264Sjacobs #ifdef DEBUG 313*2264Sjacobs ldap_perror(ld, "ldap_delete_s failed"); 314*2264Sjacobs #endif 315*2264Sjacobs } 316*2264Sjacobs } 317*2264Sjacobs else 318*2264Sjacobs { 319*2264Sjacobs result = NSL_ERR_UNKNOWN_PRINTER; 320*2264Sjacobs } 321*2264Sjacobs } 322*2264Sjacobs else 323*2264Sjacobs { 324*2264Sjacobs /* 325*2264Sjacobs * if object exists then this is a 326*2264Sjacobs * modify request otherwise is is an add request 327*2264Sjacobs */ 328*2264Sjacobs 329*2264Sjacobs if (printerExists == LDAP_SUCCESS) 330*2264Sjacobs { 331*2264Sjacobs /* 332*2264Sjacobs * Modify the printer object to 333*2264Sjacobs * give it the new attribute values 334*2264Sjacobs * specified by the user 335*2264Sjacobs */ 336*2264Sjacobs result = 337*2264Sjacobs _modifyPrinterObject(ld, printerDN, 338*2264Sjacobs (uchar_t *)printerName, 339*2264Sjacobs domainDN, attrList); 340*2264Sjacobs } 341*2264Sjacobs else 342*2264Sjacobs { 343*2264Sjacobs /* 344*2264Sjacobs * add new printer object into the 345*2264Sjacobs * ldap directory with the user 346*2264Sjacobs * specified attribute values 347*2264Sjacobs */ 348*2264Sjacobs result = 349*2264Sjacobs _addNewPrinterObject(ld, 350*2264Sjacobs (uchar_t *)printerName, 351*2264Sjacobs domainDN, attrList); 352*2264Sjacobs } 353*2264Sjacobs } 354*2264Sjacobs 355*2264Sjacobs if (printerDN != NULL) 356*2264Sjacobs { 357*2264Sjacobs free(printerDN); 358*2264Sjacobs } 359*2264Sjacobs if (domainDN != NULL) 360*2264Sjacobs { 361*2264Sjacobs free(domainDN); 362*2264Sjacobs } 363*2264Sjacobs 364*2264Sjacobs /* disconnect from LDAP server */ 365*2264Sjacobs 366*2264Sjacobs (void) ldap_unbind(ld); 367*2264Sjacobs } 368*2264Sjacobs } 369*2264Sjacobs 370*2264Sjacobs else 371*2264Sjacobs { 372*2264Sjacobs /* no printerName given */ 373*2264Sjacobs result = NSL_ERR_INTERNAL; 374*2264Sjacobs } 375*2264Sjacobs 376*2264Sjacobs return ((int)result); 377*2264Sjacobs } /* ldap_put_printer */ 378*2264Sjacobs 379*2264Sjacobs 380*2264Sjacobs 381*2264Sjacobs 382*2264Sjacobs /* 383*2264Sjacobs * ***************************************************************************** 384*2264Sjacobs * 385*2264Sjacobs * Function: _connectToLDAP() 386*2264Sjacobs * 387*2264Sjacobs * Description: Setup the connection and bind to the LDAP directory server. 388*2264Sjacobs * The function returns the ldap connection descriptor 389*2264Sjacobs * 390*2264Sjacobs * Note: Currently the native ldap functions do not support secure 391*2264Sjacobs * passwords, when this is supported this function will require 392*2264Sjacobs * updating to allow the type passed in cred->passwdType to 393*2264Sjacobs * be used with the ldap_simple_bind() 394*2264Sjacobs * 395*2264Sjacobs * Parameters: 396*2264Sjacobs * Input: ns_cred_t *cred - structure containing the credentials (host, 397*2264Sjacobs * port, user and password) required to bind 398*2264Sjacobs * to the directory server to be updated. 399*2264Sjacobs * char *printerName - printer name used only for error messages 400*2264Sjacobs * Output: LDAP** - ldap connection descriptor pointer. NULL = failed 401*2264Sjacobs * 402*2264Sjacobs * Returns: NSL_RESULT - NSL_OK = connected okay 403*2264Sjacobs * 404*2264Sjacobs * ***************************************************************************** 405*2264Sjacobs */ 406*2264Sjacobs 407*2264Sjacobs static NSL_RESULT 408*2264Sjacobs _connectToLDAP(ns_cred_t *cred, LDAP **ld) 409*2264Sjacobs 410*2264Sjacobs { 411*2264Sjacobs NSL_RESULT result = NSL_OK; 412*2264Sjacobs int lresult = 0; 413*2264Sjacobs int ldapPort = LDAP_PORT; /* default LDAP port number */ 414*2264Sjacobs int protoVersion = LDAP_VERSION3; 415*2264Sjacobs int derefOption = LDAP_DEREF_NEVER; 416*2264Sjacobs int referrals = 1; 417*2264Sjacobs char hostname[MAXHOSTNAMELEN]; 418*2264Sjacobs int tmpMethod = LDAP_AUTH_SIMPLE; /* temp - until its passed in */ 419*2264Sjacobs 420*2264Sjacobs /* -------- */ 421*2264Sjacobs 422*2264Sjacobs if ((ld == NULL) || (cred == NULL) || 423*2264Sjacobs ((cred->passwd == NULL) || (cred->binddn == NULL))) 424*2264Sjacobs { 425*2264Sjacobs result = NSL_ERR_CREDENTIALS; 426*2264Sjacobs } 427*2264Sjacobs 428*2264Sjacobs else 429*2264Sjacobs { 430*2264Sjacobs *ld = NULL; 431*2264Sjacobs 432*2264Sjacobs /* if host was not given then bind to local host */ 433*2264Sjacobs 434*2264Sjacobs if (cred->host != NULL) 435*2264Sjacobs { 436*2264Sjacobs (void) strlcpy(hostname, cred->host, sizeof (hostname)); 437*2264Sjacobs } 438*2264Sjacobs else 439*2264Sjacobs { 440*2264Sjacobs (void) sysinfo(SI_HOSTNAME, 441*2264Sjacobs hostname, sizeof (hostname)); 442*2264Sjacobs } 443*2264Sjacobs 444*2264Sjacobs /* initialise the connection to the ldap server */ 445*2264Sjacobs 446*2264Sjacobs if (cred->port != 0) 447*2264Sjacobs { 448*2264Sjacobs ldapPort = cred->port; 449*2264Sjacobs } 450*2264Sjacobs *ld = ldap_init(hostname, ldapPort); 451*2264Sjacobs if (*ld == NULL) 452*2264Sjacobs { 453*2264Sjacobs /* connection setup failed */ 454*2264Sjacobs result = NSL_ERR_CONNECT; 455*2264Sjacobs #ifdef DEBUG 456*2264Sjacobs (void) perror("ldap_init"); 457*2264Sjacobs #endif 458*2264Sjacobs } 459*2264Sjacobs else 460*2264Sjacobs { 461*2264Sjacobs /* set ldap options */ 462*2264Sjacobs 463*2264Sjacobs (void) ldap_set_option(*ld, LDAP_OPT_DEREF, 464*2264Sjacobs &derefOption); 465*2264Sjacobs (void) ldap_set_option(*ld, LDAP_OPT_PROTOCOL_VERSION, 466*2264Sjacobs &protoVersion); 467*2264Sjacobs (void) ldap_set_option(*ld, LDAP_OPT_REFERRALS, 468*2264Sjacobs &referrals); 469*2264Sjacobs 470*2264Sjacobs /* bind to the user DN in the directory */ 471*2264Sjacobs 472*2264Sjacobs /* cred->passwdType is currently not supported */ 473*2264Sjacobs 474*2264Sjacobs lresult = ldap_simple_bind_s(*ld, 475*2264Sjacobs cred->binddn, cred->passwd); 476*2264Sjacobs 477*2264Sjacobs /* 478*2264Sjacobs * before doing anything else, set up the function to 479*2264Sjacobs * call to get authentication details if the 480*2264Sjacobs * ldap update function calls (eg. ldap_add_s()) get a 481*2264Sjacobs * "referral" (to another ldap server) from the 482*2264Sjacobs * original ldap server, eg. if we are trying to do 483*2264Sjacobs * a update on a LDAP replica server. 484*2264Sjacobs */ 485*2264Sjacobs (void) _manageReferralCredentials(*ld, 486*2264Sjacobs &(cred->binddn), &(cred->passwd), 487*2264Sjacobs &tmpMethod, -1); 488*2264Sjacobs ldap_set_rebind_proc(*ld, 489*2264Sjacobs (LDAP_REBINDPROC_CALLBACK *) 490*2264Sjacobs _manageReferralCredentials, NULL); 491*2264Sjacobs 492*2264Sjacobs if (lresult != LDAP_SUCCESS) 493*2264Sjacobs { 494*2264Sjacobs result = NSL_ERR_BIND; 495*2264Sjacobs *ld = NULL; 496*2264Sjacobs #ifdef DEBUG 497*2264Sjacobs (void) ldap_perror(*ld, "ldap_simple_bind_s"); 498*2264Sjacobs #endif 499*2264Sjacobs } 500*2264Sjacobs } 501*2264Sjacobs } 502*2264Sjacobs 503*2264Sjacobs return (result); 504*2264Sjacobs } /* _connectToLDAP */ 505*2264Sjacobs 506*2264Sjacobs 507*2264Sjacobs 508*2264Sjacobs 509*2264Sjacobs 510*2264Sjacobs /* 511*2264Sjacobs * ***************************************************************************** 512*2264Sjacobs * 513*2264Sjacobs * Function: _constructPrinterDN() 514*2264Sjacobs * 515*2264Sjacobs * Description: Construct the DN for the printer object from its name and NS 516*2264Sjacobs * domain DN. If the printer-uri is given in the attrList then 517*2264Sjacobs * that is used instead of the printerName. 518*2264Sjacobs * 519*2264Sjacobs * Parameters: 520*2264Sjacobs * Input: uchar_t *printerName 521*2264Sjacobs * uchar_t *domainDN 522*2264Sjacobs * char **attrList - this list is searched for printer-uri 523*2264Sjacobs * Output: None 524*2264Sjacobs * 525*2264Sjacobs * Returns: uchar_t* - pointer to the DN, this memory is malloced so 526*2264Sjacobs * must be freed using free() when finished with. 527*2264Sjacobs * 528*2264Sjacobs * ***************************************************************************** 529*2264Sjacobs */ 530*2264Sjacobs 531*2264Sjacobs static uchar_t * 532*2264Sjacobs _constructPrinterDN(uchar_t *printerName, uchar_t *domainDN, char **attrList) 533*2264Sjacobs 534*2264Sjacobs { 535*2264Sjacobs uchar_t *dn = NULL; 536*2264Sjacobs uchar_t *uri = NULL; 537*2264Sjacobs char **p = NULL; 538*2264Sjacobs int len = 0; 539*2264Sjacobs 540*2264Sjacobs /* ------- */ 541*2264Sjacobs 542*2264Sjacobs /* first search for printer-uri in the attribute list */ 543*2264Sjacobs 544*2264Sjacobs for (p = attrList; (p != NULL) && (*p != NULL) && (uri == NULL); p++) 545*2264Sjacobs { 546*2264Sjacobs /* get length of this key word */ 547*2264Sjacobs 548*2264Sjacobs for (len = 0; ((*p)[len] != '=') && ((*p)[len] != '\0'); len++); 549*2264Sjacobs 550*2264Sjacobs if ((strncasecmp(*p, ATTR_URI, len) == 0) && 551*2264Sjacobs (strlen(*p) > len+1)) 552*2264Sjacobs { 553*2264Sjacobs uri = (uchar_t *)&((*p)[len+1]); 554*2264Sjacobs } 555*2264Sjacobs } 556*2264Sjacobs 557*2264Sjacobs 558*2264Sjacobs if (domainDN != NULL) { 559*2264Sjacobs size_t size; 560*2264Sjacobs 561*2264Sjacobs /* malloc memory for the DN and then construct it */ 562*2264Sjacobs 563*2264Sjacobs if ((uri == NULL) && (printerName != NULL)) 564*2264Sjacobs { 565*2264Sjacobs /* use the printerName for the RDN */ 566*2264Sjacobs 567*2264Sjacobs size = strlen(ATTR_URI) + 568*2264Sjacobs strlen((char *)printerName) + 569*2264Sjacobs strlen((char *)domainDN) + 570*2264Sjacobs strlen(PCONTAINER) + 571*2264Sjacobs 10; /* plus a few extra */ 572*2264Sjacobs 573*2264Sjacobs if ((dn = malloc(size)) != NULL) 574*2264Sjacobs (void) snprintf((char *)dn, size, "%s=%s,%s,%s", 575*2264Sjacobs ATTR_URI, printerName, PCONTAINER, domainDN); 576*2264Sjacobs } 577*2264Sjacobs else 578*2264Sjacobs if (uri != NULL) 579*2264Sjacobs { 580*2264Sjacobs /* use the URI for the RDN */ 581*2264Sjacobs 582*2264Sjacobs size = strlen(ATTR_URI) + 583*2264Sjacobs strlen((char *)uri) + 584*2264Sjacobs strlen((char *)domainDN) + 585*2264Sjacobs strlen(PCONTAINER) + 586*2264Sjacobs 10; /* plus a few extra */ 587*2264Sjacobs 588*2264Sjacobs if ((dn = malloc(size)) != NULL) 589*2264Sjacobs (void) snprintf((char *)dn, size, "%s=%s,%s,%s", 590*2264Sjacobs ATTR_URI, uri, PCONTAINER, domainDN); 591*2264Sjacobs } 592*2264Sjacobs 593*2264Sjacobs /* 594*2264Sjacobs * else 595*2264Sjacobs * { 596*2264Sjacobs * printName not given so return null 597*2264Sjacobs * } 598*2264Sjacobs */ 599*2264Sjacobs 600*2264Sjacobs } 601*2264Sjacobs 602*2264Sjacobs return (dn); /* caller must free this memory */ 603*2264Sjacobs } /* _constructPrinterDN */ 604*2264Sjacobs 605*2264Sjacobs 606*2264Sjacobs 607*2264Sjacobs /* 608*2264Sjacobs * ***************************************************************************** 609*2264Sjacobs * 610*2264Sjacobs * Function: _checkPrinterExists() 611*2264Sjacobs * 612*2264Sjacobs * Description: Check that the printer object for the printerName exists in the 613*2264Sjacobs * directory DIT and then extract the object's DN 614*2264Sjacobs * The function uses an exiting ldap connection and does a 615*2264Sjacobs * search for the printerName in the supplied domain DN. 616*2264Sjacobs * 617*2264Sjacobs * Parameters: 618*2264Sjacobs * Input: LDAP *ld - existing ldap connection descriptor 619*2264Sjacobs * uchar_t *printerName - printer name 620*2264Sjacobs * uchar_t *domainDN - DN of domain to search in 621*2264Sjacobs * Output: uchar_t **printerDN - DN of the printer - the caller should 622*2264Sjacobs * free this memory using free() 623*2264Sjacobs * 624*2264Sjacobs * Result: NSL_RESULT - NSL_OK = object exists 625*2264Sjacobs * 626*2264Sjacobs * ***************************************************************************** 627*2264Sjacobs */ 628*2264Sjacobs 629*2264Sjacobs static NSL_RESULT 630*2264Sjacobs _checkPrinterExists(LDAP *ld, uchar_t *printerName, uchar_t *domainDN, 631*2264Sjacobs uchar_t **printerDN) 632*2264Sjacobs 633*2264Sjacobs { 634*2264Sjacobs NSL_RESULT result = NSL_ERR_UNKNOWN_PRINTER; 635*2264Sjacobs int sresult = LDAP_NO_SUCH_OBJECT; 636*2264Sjacobs LDAPMessage *ldapMsg = NULL; 637*2264Sjacobs char *requiredAttrs[2] = { ATTR_PNAME, NULL }; 638*2264Sjacobs LDAPMessage *ldapEntry = NULL; 639*2264Sjacobs uchar_t *filter = NULL; 640*2264Sjacobs uchar_t *baseDN = NULL; 641*2264Sjacobs 642*2264Sjacobs /* ---------- */ 643*2264Sjacobs 644*2264Sjacobs if ((printerName != NULL) && (domainDN != NULL) && (printerDN != NULL)) 645*2264Sjacobs { 646*2264Sjacobs size_t size; 647*2264Sjacobs 648*2264Sjacobs if (printerDN != NULL) 649*2264Sjacobs { 650*2264Sjacobs *printerDN = NULL; 651*2264Sjacobs } 652*2264Sjacobs 653*2264Sjacobs /* search for this Printer in the directory */ 654*2264Sjacobs 655*2264Sjacobs size = (3 + strlen((char *)printerName) + strlen(ATTR_PNAME) + 656*2264Sjacobs 2); 657*2264Sjacobs 658*2264Sjacobs if ((filter = malloc(size)) != NULL) 659*2264Sjacobs (void) snprintf((char *)filter, size, "(%s=%s)", 660*2264Sjacobs ATTR_PNAME, (char *)printerName); 661*2264Sjacobs 662*2264Sjacobs size = (strlen((char *)domainDN) + strlen(PCONTAINER) + 5); 663*2264Sjacobs 664*2264Sjacobs if ((baseDN = malloc(size)) != NULL) 665*2264Sjacobs (void) snprintf((char *)baseDN, size, "%s,%s", 666*2264Sjacobs PCONTAINER, (char *)domainDN); 667*2264Sjacobs 668*2264Sjacobs sresult = ldap_search_s(ld, (char *)baseDN, LDAP_SCOPE_SUBTREE, 669*2264Sjacobs (char *)filter, requiredAttrs, 0, &ldapMsg); 670*2264Sjacobs if (sresult == LDAP_SUCCESS) 671*2264Sjacobs { 672*2264Sjacobs /* check that the object exists and extract its DN */ 673*2264Sjacobs 674*2264Sjacobs ldapEntry = ldap_first_entry(ld, ldapMsg); 675*2264Sjacobs if (ldapEntry != NULL) 676*2264Sjacobs { 677*2264Sjacobs /* object found - there should only be one */ 678*2264Sjacobs result = NSL_OK; 679*2264Sjacobs 680*2264Sjacobs if (printerDN != NULL) 681*2264Sjacobs { 682*2264Sjacobs *printerDN = (uchar_t *) 683*2264Sjacobs ldap_get_dn(ld, ldapEntry); 684*2264Sjacobs } 685*2264Sjacobs } 686*2264Sjacobs 687*2264Sjacobs (void) ldap_msgfree(ldapMsg); 688*2264Sjacobs } 689*2264Sjacobs } 690*2264Sjacobs 691*2264Sjacobs else 692*2264Sjacobs { 693*2264Sjacobs result = NSL_ERR_INTERNAL; 694*2264Sjacobs } 695*2264Sjacobs 696*2264Sjacobs return (result); 697*2264Sjacobs } /* _checkPrinterExists */ 698*2264Sjacobs 699*2264Sjacobs 700*2264Sjacobs 701*2264Sjacobs 702*2264Sjacobs /* 703*2264Sjacobs * ***************************************************************************** 704*2264Sjacobs * 705*2264Sjacobs * Function: _checkPrinterDNExists() 706*2264Sjacobs * 707*2264Sjacobs * Description: Check that the printer object for the DN exists in the 708*2264Sjacobs * directory DIT. 709*2264Sjacobs * The function uses an exiting ldap connection and does a 710*2264Sjacobs * search for the DN supplied. 711*2264Sjacobs * 712*2264Sjacobs * Parameters: LDAP *ld - existing ldap connection descriptor 713*2264Sjacobs * char *objectDN - DN to search for 714*2264Sjacobs * 715*2264Sjacobs * Result: NSL_RESULT - NSL_OK = object exists 716*2264Sjacobs * 717*2264Sjacobs * ***************************************************************************** 718*2264Sjacobs */ 719*2264Sjacobs 720*2264Sjacobs static NSL_RESULT 721*2264Sjacobs _checkPrinterDNExists(LDAP *ld, uchar_t *objectDN) 722*2264Sjacobs 723*2264Sjacobs { 724*2264Sjacobs NSL_RESULT result = NSL_ERR_UNKNOWN_PRINTER; 725*2264Sjacobs int sresult = LDAP_NO_SUCH_OBJECT; 726*2264Sjacobs LDAPMessage *ldapMsg; 727*2264Sjacobs char *requiredAttrs[2] = { ATTR_PNAME, NULL }; 728*2264Sjacobs LDAPMessage *ldapEntry; 729*2264Sjacobs 730*2264Sjacobs /* ---------- */ 731*2264Sjacobs 732*2264Sjacobs if ((ld != NULL) && (objectDN != NULL)) 733*2264Sjacobs { 734*2264Sjacobs /* search for this Printer in the directory */ 735*2264Sjacobs 736*2264Sjacobs sresult = ldap_search_s(ld, (char *)objectDN, LDAP_SCOPE_BASE, 737*2264Sjacobs "(objectclass=*)", requiredAttrs, 0, &ldapMsg); 738*2264Sjacobs if (sresult == LDAP_SUCCESS) 739*2264Sjacobs { 740*2264Sjacobs /* check that the object exists */ 741*2264Sjacobs ldapEntry = ldap_first_entry(ld, ldapMsg); 742*2264Sjacobs if (ldapEntry != NULL) 743*2264Sjacobs { 744*2264Sjacobs /* object found */ 745*2264Sjacobs result = NSL_OK; 746*2264Sjacobs } 747*2264Sjacobs 748*2264Sjacobs (void) ldap_msgfree(ldapMsg); 749*2264Sjacobs } 750*2264Sjacobs } 751*2264Sjacobs 752*2264Sjacobs else 753*2264Sjacobs { 754*2264Sjacobs result = NSL_ERR_INTERNAL; 755*2264Sjacobs } 756*2264Sjacobs 757*2264Sjacobs return (result); 758*2264Sjacobs } /* _checkPrinterDNExists */ 759*2264Sjacobs 760*2264Sjacobs 761*2264Sjacobs 762*2264Sjacobs 763*2264Sjacobs 764*2264Sjacobs /* 765*2264Sjacobs * ***************************************************************************** 766*2264Sjacobs * 767*2264Sjacobs * Function: _checkSunPrinter() 768*2264Sjacobs * 769*2264Sjacobs * Description: Check that the printer object for the printerDN is a sunPrinter 770*2264Sjacobs * ie. it has the required objectclass attribute value. 771*2264Sjacobs * 772*2264Sjacobs * Parameters: 773*2264Sjacobs * Input: LDAP *ld - existing ldap connection descriptor 774*2264Sjacobs * Output: uchar_t *printerDN - DN of the printer 775*2264Sjacobs * 776*2264Sjacobs * Result: NSL_RESULT - NSL_OK = object exists and is a sunPrinter 777*2264Sjacobs * 778*2264Sjacobs * ***************************************************************************** 779*2264Sjacobs */ 780*2264Sjacobs 781*2264Sjacobs static NSL_RESULT 782*2264Sjacobs _checkSunPrinter(LDAP *ld, uchar_t *printerDN) 783*2264Sjacobs 784*2264Sjacobs { 785*2264Sjacobs NSL_RESULT result = NSL_ERR_UNKNOWN_PRINTER; 786*2264Sjacobs int sresult = LDAP_NO_SUCH_OBJECT; 787*2264Sjacobs char *requiredAttrs[2] = { ATTR_PNAME, NULL }; 788*2264Sjacobs LDAPMessage *ldapMsg = NULL; 789*2264Sjacobs LDAPMessage *ldapEntry = NULL; 790*2264Sjacobs char *filter = NULL; 791*2264Sjacobs 792*2264Sjacobs /* ---------- */ 793*2264Sjacobs 794*2264Sjacobs if ((ld != NULL) && (printerDN != NULL)) 795*2264Sjacobs { 796*2264Sjacobs size_t size; 797*2264Sjacobs 798*2264Sjacobs /* search for this Printer in the directory */ 799*2264Sjacobs 800*2264Sjacobs size = (3 + strlen(OCV_SUNPRT) + strlen(ATTR_OCLASS) + 2); 801*2264Sjacobs if ((filter = malloc(size)) != NULL) 802*2264Sjacobs (void) snprintf(filter, size, "(%s=%s)", 803*2264Sjacobs ATTR_OCLASS, OCV_SUNPRT); 804*2264Sjacobs 805*2264Sjacobs sresult = ldap_search_s(ld, (char *)printerDN, 806*2264Sjacobs LDAP_SCOPE_SUBTREE, filter, 807*2264Sjacobs requiredAttrs, 0, &ldapMsg); 808*2264Sjacobs if (sresult == LDAP_SUCCESS) 809*2264Sjacobs { 810*2264Sjacobs /* check that the printer object exists */ 811*2264Sjacobs 812*2264Sjacobs ldapEntry = ldap_first_entry(ld, ldapMsg); 813*2264Sjacobs if (ldapEntry != NULL) 814*2264Sjacobs { 815*2264Sjacobs /* object is a sunPrinter */ 816*2264Sjacobs result = NSL_OK; 817*2264Sjacobs } 818*2264Sjacobs 819*2264Sjacobs (void) ldap_msgfree(ldapMsg); 820*2264Sjacobs } 821*2264Sjacobs } 822*2264Sjacobs 823*2264Sjacobs else 824*2264Sjacobs { 825*2264Sjacobs result = NSL_ERR_INTERNAL; 826*2264Sjacobs } 827*2264Sjacobs 828*2264Sjacobs return (result); 829*2264Sjacobs } /* _checkSunPrinter */ 830*2264Sjacobs 831*2264Sjacobs 832*2264Sjacobs 833*2264Sjacobs 834*2264Sjacobs 835*2264Sjacobs /* 836*2264Sjacobs * ***************************************************************************** 837*2264Sjacobs * 838*2264Sjacobs * Function: _addNewPrinterObject() 839*2264Sjacobs * 840*2264Sjacobs * Description: For the given printerName add a printer object into the 841*2264Sjacobs * LDAP directory NS domain. The object is created with the 842*2264Sjacobs * supplied attribute values. Note: if the printer's uri is 843*2264Sjacobs * given that is used as the RDN otherwise the printer's 844*2264Sjacobs * name is used as the RDN 845*2264Sjacobs * 846*2264Sjacobs * Parameters: 847*2264Sjacobs * Input: LDAP *ld - existing ldap connection descriptor 848*2264Sjacobs * uchar_t *printerName - Name of printer to be added 849*2264Sjacobs * uchar_t *domainDN - DN of the domain to add the printer 850*2264Sjacobs * char **attrList - user specified attribute values list 851*2264Sjacobs * Output: None 852*2264Sjacobs * 853*2264Sjacobs * Returns: NSL_RESULT - NSL_OK = request actioned okay 854*2264Sjacobs * !NSL_OK = error 855*2264Sjacobs * 856*2264Sjacobs * ***************************************************************************** 857*2264Sjacobs */ 858*2264Sjacobs 859*2264Sjacobs static NSL_RESULT 860*2264Sjacobs _addNewPrinterObject(LDAP *ld, uchar_t *printerName, 861*2264Sjacobs uchar_t *domainDN, char **attrList) 862*2264Sjacobs 863*2264Sjacobs { 864*2264Sjacobs NSL_RESULT result = NSL_ERR_ADD_FAILED; 865*2264Sjacobs int lresult = 0; 866*2264Sjacobs uchar_t *printerDN = NULL; 867*2264Sjacobs LDAPMod **attrs = NULL; 868*2264Sjacobs 869*2264Sjacobs /* ---------- */ 870*2264Sjacobs 871*2264Sjacobs if ((ld != NULL) && (printerName != NULL) && (domainDN != NULL) && 872*2264Sjacobs (attrList != NULL) && (attrList[0] != NULL)) 873*2264Sjacobs { 874*2264Sjacobs result = _checkAttributes(attrList); 875*2264Sjacobs 876*2264Sjacobs if (result == NSL_OK) 877*2264Sjacobs { 878*2264Sjacobs /* 879*2264Sjacobs * construct a DN for the printer from the 880*2264Sjacobs * printerName and printer-uri if given. 881*2264Sjacobs */ 882*2264Sjacobs printerDN = _constructPrinterDN(printerName, 883*2264Sjacobs domainDN, attrList); 884*2264Sjacobs if (printerDN != NULL) 885*2264Sjacobs { 886*2264Sjacobs /* 887*2264Sjacobs * setup attribute values in an LDAPMod 888*2264Sjacobs * structure and then add the object 889*2264Sjacobs */ 890*2264Sjacobs result = _constructAddLDAPMod(printerName, 891*2264Sjacobs attrList, &attrs); 892*2264Sjacobs if (result == NSL_OK) 893*2264Sjacobs { 894*2264Sjacobs lresult = ldap_add_s(ld, 895*2264Sjacobs (char *)printerDN, attrs); 896*2264Sjacobs if (lresult == LDAP_SUCCESS) 897*2264Sjacobs { 898*2264Sjacobs result = NSL_OK; 899*2264Sjacobs } 900*2264Sjacobs else 901*2264Sjacobs { 902*2264Sjacobs result = NSL_ERR_ADD_FAILED; 903*2264Sjacobs #ifdef DEBUG 904*2264Sjacobs (void) ldap_perror(ld, "ldap_add_s"); 905*2264Sjacobs #endif 906*2264Sjacobs } 907*2264Sjacobs 908*2264Sjacobs (void) ldap_mods_free(attrs, 1); 909*2264Sjacobs } 910*2264Sjacobs free(printerDN); 911*2264Sjacobs } 912*2264Sjacobs 913*2264Sjacobs else 914*2264Sjacobs { 915*2264Sjacobs result = NSL_ERR_INTERNAL; 916*2264Sjacobs } 917*2264Sjacobs } 918*2264Sjacobs } 919*2264Sjacobs 920*2264Sjacobs else 921*2264Sjacobs { 922*2264Sjacobs result = NSL_ERR_INTERNAL; 923*2264Sjacobs } 924*2264Sjacobs 925*2264Sjacobs return (result); 926*2264Sjacobs } /* _addNewPrinterObject */ 927*2264Sjacobs 928*2264Sjacobs 929*2264Sjacobs 930*2264Sjacobs 931*2264Sjacobs 932*2264Sjacobs 933*2264Sjacobs /* 934*2264Sjacobs * ***************************************************************************** 935*2264Sjacobs * 936*2264Sjacobs * Function: _modifyPrinterObject() 937*2264Sjacobs * 938*2264Sjacobs * Description: Modify the given LDAP printer object to set the new attributes 939*2264Sjacobs * in the attribute list. If the printer's URI (specified in the 940*2264Sjacobs * attrList) changes the URI of the object the request is rejected. 941*2264Sjacobs * 942*2264Sjacobs * Parameters: 943*2264Sjacobs * Input: LDAP *ld - existing ldap connection descriptor 944*2264Sjacobs * uchar_t *printerDN - DN of printer object to modify 945*2264Sjacobs * uchar_t *printerName - Name of printer to be modified 946*2264Sjacobs * uchar_t *domainDN - DN of the domain the printer is in 947*2264Sjacobs * char **attrList - user specified attribute values list 948*2264Sjacobs * Output: None 949*2264Sjacobs * 950*2264Sjacobs * Returns: NSL_RESULT - NSL_OK = object modified okay 951*2264Sjacobs * 952*2264Sjacobs * ***************************************************************************** 953*2264Sjacobs */ 954*2264Sjacobs 955*2264Sjacobs static NSL_RESULT 956*2264Sjacobs _modifyPrinterObject(LDAP *ld, uchar_t *printerDN, 957*2264Sjacobs uchar_t *printerName, uchar_t *domainDN, char **attrList) 958*2264Sjacobs 959*2264Sjacobs { 960*2264Sjacobs NSL_RESULT result = NSL_ERR_INTERNAL; 961*2264Sjacobs int lresult = 0; 962*2264Sjacobs int sunPrinter = 0; 963*2264Sjacobs uchar_t *uriDN = NULL; 964*2264Sjacobs LDAPMod **attrs = NULL; 965*2264Sjacobs char **kvpList = NULL; 966*2264Sjacobs 967*2264Sjacobs /* ---------- */ 968*2264Sjacobs 969*2264Sjacobs if ((ld != NULL) && (printerDN != NULL) && (printerName != NULL) && 970*2264Sjacobs (domainDN != NULL) && (attrList != NULL) && (attrList[0] != NULL)) 971*2264Sjacobs { 972*2264Sjacobs result = _checkAttributes(attrList); 973*2264Sjacobs 974*2264Sjacobs if (result == NSL_OK) 975*2264Sjacobs { 976*2264Sjacobs /* 977*2264Sjacobs * The user may have requested that the printer object 978*2264Sjacobs * be given a new URI RDN, so construct a DN for the 979*2264Sjacobs * printer from the printerName or the printer-uri (if 980*2264Sjacobs * given). 981*2264Sjacobs */ 982*2264Sjacobs uriDN = _constructPrinterDN(NULL, domainDN, attrList); 983*2264Sjacobs 984*2264Sjacobs /* 985*2264Sjacobs * compare the 2 DNs to see if the URI has changed, 986*2264Sjacobs * if uriDN is null then the DN hasn't changed 987*2264Sjacobs */ 988*2264Sjacobs if ((uriDN == NULL) || ((uriDN != NULL) && 989*2264Sjacobs (_compareURIinDNs(printerDN, uriDN) == NSL_OK))) 990*2264Sjacobs { 991*2264Sjacobs /* 992*2264Sjacobs * setup the modify object LDAPMod 993*2264Sjacobs * structure and then do the modify 994*2264Sjacobs */ 995*2264Sjacobs 996*2264Sjacobs if (_checkSunPrinter(ld, printerDN) == NSL_OK) 997*2264Sjacobs { 998*2264Sjacobs sunPrinter = 1; 999*2264Sjacobs } 1000*2264Sjacobs 1001*2264Sjacobs (void) _getCurrentKVPValues(ld, 1002*2264Sjacobs printerDN, &kvpList); 1003*2264Sjacobs 1004*2264Sjacobs result = _constructModLDAPMod(printerName, 1005*2264Sjacobs sunPrinter, attrList, 1006*2264Sjacobs &kvpList, &attrs); 1007*2264Sjacobs _freeList(&kvpList); 1008*2264Sjacobs 1009*2264Sjacobs if ((result == NSL_OK) && (attrs != NULL)) 1010*2264Sjacobs { 1011*2264Sjacobs lresult = ldap_modify_s( 1012*2264Sjacobs ld, (char *)printerDN, attrs); 1013*2264Sjacobs if (lresult == LDAP_SUCCESS) 1014*2264Sjacobs { 1015*2264Sjacobs result = NSL_OK; 1016*2264Sjacobs } 1017*2264Sjacobs else 1018*2264Sjacobs { 1019*2264Sjacobs result = NSL_ERR_MOD_FAILED; 1020*2264Sjacobs #ifdef DEBUG 1021*2264Sjacobs (void) ldap_perror(ld, "ldap_modify_s"); 1022*2264Sjacobs #endif 1023*2264Sjacobs } 1024*2264Sjacobs 1025*2264Sjacobs (void) ldap_mods_free(attrs, 1); 1026*2264Sjacobs } 1027*2264Sjacobs } 1028*2264Sjacobs else 1029*2264Sjacobs { 1030*2264Sjacobs /* 1031*2264Sjacobs * printer-uri name change has been requested 1032*2264Sjacobs * this is NOT allowed as it requires that 1033*2264Sjacobs * a new printer object is created 1034*2264Sjacobs */ 1035*2264Sjacobs result = NSL_ERR_RENAME; /* NOT ALLOWED */ 1036*2264Sjacobs } 1037*2264Sjacobs 1038*2264Sjacobs if (uriDN != NULL) 1039*2264Sjacobs { 1040*2264Sjacobs free(uriDN); 1041*2264Sjacobs } 1042*2264Sjacobs } 1043*2264Sjacobs } 1044*2264Sjacobs 1045*2264Sjacobs return (result); 1046*2264Sjacobs } /* _modifyPrinterObject */ 1047*2264Sjacobs 1048*2264Sjacobs 1049*2264Sjacobs 1050*2264Sjacobs 1051*2264Sjacobs /* 1052*2264Sjacobs * ***************************************************************************** 1053*2264Sjacobs * 1054*2264Sjacobs * Function: _checkAttributes() 1055*2264Sjacobs * 1056*2264Sjacobs * Description: Check that the given attribute lists does not contain any 1057*2264Sjacobs * key words that are not allowed. 1058*2264Sjacobs * 1059*2264Sjacobs * Parameters: 1060*2264Sjacobs * Input: char **list - attribute list to check 1061*2264Sjacobs * Output: None 1062*2264Sjacobs * 1063*2264Sjacobs * Returns: NSL_RESULT - NSL_OK = checked okay 1064*2264Sjacobs * 1065*2264Sjacobs * ***************************************************************************** 1066*2264Sjacobs */ 1067*2264Sjacobs 1068*2264Sjacobs static NSL_RESULT 1069*2264Sjacobs _checkAttributes(char **list) 1070*2264Sjacobs 1071*2264Sjacobs { 1072*2264Sjacobs NSL_RESULT result = NSL_OK; 1073*2264Sjacobs int len = 0; 1074*2264Sjacobs char *attr = NULL; 1075*2264Sjacobs char **p = NULL; 1076*2264Sjacobs 1077*2264Sjacobs /* ------ */ 1078*2264Sjacobs 1079*2264Sjacobs for (p = list; (p != NULL) && (*p != NULL) && (result == NSL_OK); p++) 1080*2264Sjacobs { 1081*2264Sjacobs /* get length of this key word */ 1082*2264Sjacobs 1083*2264Sjacobs for (len = 0; ((*p)[len] != '=') && ((*p)[len] != '\0'); len++); 1084*2264Sjacobs 1085*2264Sjacobs /* check if the key word is allowed */ 1086*2264Sjacobs 1087*2264Sjacobs if (strncasecmp(*p, ATTR_KVP, len) == 0) 1088*2264Sjacobs { 1089*2264Sjacobs /* not supported through this interface */ 1090*2264Sjacobs result = NSL_ERR_KVP; 1091*2264Sjacobs } 1092*2264Sjacobs else 1093*2264Sjacobs if (strncasecmp(*p, ATTR_BSDADDR, len) == 0) 1094*2264Sjacobs { 1095*2264Sjacobs /* not supported through this interface */ 1096*2264Sjacobs result = NSL_ERR_BSDADDR; 1097*2264Sjacobs } 1098*2264Sjacobs else 1099*2264Sjacobs if (strncasecmp(*p, ATTR_PNAME, len) == 0) 1100*2264Sjacobs { 1101*2264Sjacobs /* not supported through this interface */ 1102*2264Sjacobs result = NSL_ERR_PNAME; 1103*2264Sjacobs } 1104*2264Sjacobs else 1105*2264Sjacobs { 1106*2264Sjacobs /* check for any others */ 1107*2264Sjacobs 1108*2264Sjacobs attr = strdup(*p); 1109*2264Sjacobs attr[len] = '\0'; /* terminate the key */ 1110*2264Sjacobs 1111*2264Sjacobs if (_attrInList(attr, nsl_attr_notAllowed)) 1112*2264Sjacobs { 1113*2264Sjacobs result = NSL_ERR_NOTALLOWED; 1114*2264Sjacobs } 1115*2264Sjacobs } 1116*2264Sjacobs 1117*2264Sjacobs } 1118*2264Sjacobs 1119*2264Sjacobs return (result); 1120*2264Sjacobs } /* _checkAttributes */ 1121*2264Sjacobs 1122*2264Sjacobs 1123*2264Sjacobs 1124*2264Sjacobs 1125*2264Sjacobs /* 1126*2264Sjacobs * ***************************************************************************** 1127*2264Sjacobs * 1128*2264Sjacobs * Function: _addLDAPmodValue() 1129*2264Sjacobs * 1130*2264Sjacobs * Description: Add the given attribute and its value to the LDAPMod array. 1131*2264Sjacobs * If this is the first entry in the array then create it. 1132*2264Sjacobs * 1133*2264Sjacobs * Parameters: 1134*2264Sjacobs * Input: LDAPMod ***attrs - array to update 1135*2264Sjacobs * char *type - attribute to add into array 1136*2264Sjacobs * char *value - attribute value 1137*2264Sjacobs * Output: None 1138*2264Sjacobs * 1139*2264Sjacobs * Returns: NSL_RESULT - NSL_OK = added okay 1140*2264Sjacobs * 1141*2264Sjacobs * ***************************************************************************** 1142*2264Sjacobs */ 1143*2264Sjacobs 1144*2264Sjacobs static NSL_RESULT 1145*2264Sjacobs _addLDAPmodValue(LDAPMod ***attrs, char *type, char *value) 1146*2264Sjacobs 1147*2264Sjacobs { 1148*2264Sjacobs int i = 0; 1149*2264Sjacobs int j = 0; 1150*2264Sjacobs NSL_RESULT result = NSL_OK; 1151*2264Sjacobs 1152*2264Sjacobs /* ---------- */ 1153*2264Sjacobs 1154*2264Sjacobs if ((attrs != NULL) && (type != NULL) && (value != NULL)) 1155*2264Sjacobs { 1156*2264Sjacobs #ifdef DEBUG 1157*2264Sjacobs printf("_addLDAPmodValue() type='%s', value='%s'\n", type, value); 1158*2264Sjacobs #endif 1159*2264Sjacobs /* search the existing LDAPMod array for the attribute */ 1160*2264Sjacobs 1161*2264Sjacobs for (i = 0; *attrs != NULL && (*attrs)[i] != NULL; i++) 1162*2264Sjacobs { 1163*2264Sjacobs if (strcasecmp((*attrs)[i]->mod_type, type) == 0) 1164*2264Sjacobs { 1165*2264Sjacobs break; 1166*2264Sjacobs } 1167*2264Sjacobs } 1168*2264Sjacobs 1169*2264Sjacobs if (*attrs == NULL) 1170*2264Sjacobs { 1171*2264Sjacobs /* array empty so create it */ 1172*2264Sjacobs 1173*2264Sjacobs *attrs = (LDAPMod **)calloc(1, 2 * sizeof (LDAPMod *)); 1174*2264Sjacobs if (*attrs != NULL) 1175*2264Sjacobs { 1176*2264Sjacobs i = 0; 1177*2264Sjacobs } 1178*2264Sjacobs else 1179*2264Sjacobs { 1180*2264Sjacobs result = NSL_ERR_MEMORY; 1181*2264Sjacobs } 1182*2264Sjacobs 1183*2264Sjacobs } 1184*2264Sjacobs else 1185*2264Sjacobs if ((*attrs)[i] == NULL) 1186*2264Sjacobs { 1187*2264Sjacobs *attrs = (LDAPMod **) 1188*2264Sjacobs realloc(*attrs, (i+2) * sizeof (LDAPMod *)); 1189*2264Sjacobs if (*attrs == NULL) 1190*2264Sjacobs { 1191*2264Sjacobs result = NSL_ERR_MEMORY; 1192*2264Sjacobs } 1193*2264Sjacobs } 1194*2264Sjacobs } 1195*2264Sjacobs else 1196*2264Sjacobs { 1197*2264Sjacobs result = NSL_ERR_INTERNAL; 1198*2264Sjacobs } 1199*2264Sjacobs 1200*2264Sjacobs if (result == NSL_OK) 1201*2264Sjacobs { 1202*2264Sjacobs if ((*attrs)[i] == NULL) 1203*2264Sjacobs { 1204*2264Sjacobs /* We've got a new slot. Create the new mod. */ 1205*2264Sjacobs 1206*2264Sjacobs (*attrs)[i] = (LDAPMod *) malloc(sizeof (LDAPMod)); 1207*2264Sjacobs if ((*attrs)[i] != NULL) 1208*2264Sjacobs { 1209*2264Sjacobs (*attrs)[i]->mod_op = LDAP_MOD_ADD; 1210*2264Sjacobs (*attrs)[i]->mod_type = strdup(type); 1211*2264Sjacobs (*attrs)[i]->mod_values = (char **) 1212*2264Sjacobs malloc(2 * sizeof (char *)); 1213*2264Sjacobs if ((*attrs)[i]->mod_values != NULL) 1214*2264Sjacobs { 1215*2264Sjacobs (*attrs)[i]->mod_values[0] = 1216*2264Sjacobs strdup(value); 1217*2264Sjacobs (*attrs)[i]->mod_values[1] = NULL; 1218*2264Sjacobs (*attrs)[i+1] = NULL; 1219*2264Sjacobs } 1220*2264Sjacobs else 1221*2264Sjacobs { 1222*2264Sjacobs result = NSL_ERR_MEMORY; 1223*2264Sjacobs } 1224*2264Sjacobs } 1225*2264Sjacobs else 1226*2264Sjacobs { 1227*2264Sjacobs result = NSL_ERR_MEMORY; 1228*2264Sjacobs } 1229*2264Sjacobs } 1230*2264Sjacobs 1231*2264Sjacobs else 1232*2264Sjacobs { 1233*2264Sjacobs /* Found an existing entry so add value to it */ 1234*2264Sjacobs 1235*2264Sjacobs for (j = 0; (*attrs)[i]->mod_values[j] != NULL; j++); 1236*2264Sjacobs 1237*2264Sjacobs (*attrs)[i]->mod_values = 1238*2264Sjacobs (char **)realloc((*attrs)[i]->mod_values, 1239*2264Sjacobs (j + 2) * sizeof (char *)); 1240*2264Sjacobs if ((*attrs)[i]->mod_values != NULL) 1241*2264Sjacobs { 1242*2264Sjacobs (*attrs)[i]->mod_values[j] = strdup(value); 1243*2264Sjacobs (*attrs)[i]->mod_values[j+1] = NULL; 1244*2264Sjacobs } 1245*2264Sjacobs else 1246*2264Sjacobs { 1247*2264Sjacobs result = NSL_ERR_MEMORY; 1248*2264Sjacobs } 1249*2264Sjacobs } 1250*2264Sjacobs } 1251*2264Sjacobs 1252*2264Sjacobs return (result); 1253*2264Sjacobs } /* _addLDAPmodValue */ 1254*2264Sjacobs 1255*2264Sjacobs 1256*2264Sjacobs 1257*2264Sjacobs 1258*2264Sjacobs /* 1259*2264Sjacobs * ***************************************************************************** 1260*2264Sjacobs * 1261*2264Sjacobs * Function: _modLDAPmodValue() 1262*2264Sjacobs * 1263*2264Sjacobs * Description: Add the given attribute modify operation and its value into 1264*2264Sjacobs * the LDAPMod array. This will either be a "replace" or a 1265*2264Sjacobs * "delete"; value = null implies a "delete". 1266*2264Sjacobs * If this is the first entry in the array then create it. 1267*2264Sjacobs * 1268*2264Sjacobs * Parameters: 1269*2264Sjacobs * Input: LDAPMod ***attrs - array to update 1270*2264Sjacobs * char *type - attribute to modify 1271*2264Sjacobs * char *value - attribute value, null implies "delete" 1272*2264Sjacobs * Output: None 1273*2264Sjacobs * 1274*2264Sjacobs * Returns: NSL_RESULT - NSL_OK = added okay 1275*2264Sjacobs * 1276*2264Sjacobs * ***************************************************************************** 1277*2264Sjacobs */ 1278*2264Sjacobs 1279*2264Sjacobs static NSL_RESULT 1280*2264Sjacobs _modLDAPmodValue(LDAPMod ***attrs, char *type, char *value) 1281*2264Sjacobs 1282*2264Sjacobs { 1283*2264Sjacobs int i = 0; 1284*2264Sjacobs int j = 0; 1285*2264Sjacobs NSL_RESULT result = NSL_OK; 1286*2264Sjacobs 1287*2264Sjacobs /* ---------- */ 1288*2264Sjacobs 1289*2264Sjacobs if ((attrs != NULL) && (type != NULL)) 1290*2264Sjacobs { 1291*2264Sjacobs #ifdef DEBUG 1292*2264Sjacobs if (value != NULL) 1293*2264Sjacobs printf("_modLDAPmodValue() REPLACE type='%s', value='%s'\n", type, value); 1294*2264Sjacobs else 1295*2264Sjacobs printf("_modLDAPmodValue() DELETE type='%s'\n", type); 1296*2264Sjacobs #endif 1297*2264Sjacobs /* search the existing LDAPMod array for the attribute */ 1298*2264Sjacobs 1299*2264Sjacobs for (i = 0; *attrs != NULL && (*attrs)[i] != NULL; i++) 1300*2264Sjacobs { 1301*2264Sjacobs if (strcasecmp((*attrs)[i]->mod_type, type) == 0) 1302*2264Sjacobs { 1303*2264Sjacobs break; 1304*2264Sjacobs } 1305*2264Sjacobs } 1306*2264Sjacobs 1307*2264Sjacobs if (*attrs == NULL) 1308*2264Sjacobs { 1309*2264Sjacobs /* array empty so create it */ 1310*2264Sjacobs 1311*2264Sjacobs *attrs = (LDAPMod **)calloc(1, 2 * sizeof (LDAPMod *)); 1312*2264Sjacobs if (*attrs != NULL) 1313*2264Sjacobs { 1314*2264Sjacobs i = 0; 1315*2264Sjacobs } 1316*2264Sjacobs else 1317*2264Sjacobs { 1318*2264Sjacobs result = NSL_ERR_MEMORY; 1319*2264Sjacobs } 1320*2264Sjacobs 1321*2264Sjacobs } 1322*2264Sjacobs else 1323*2264Sjacobs if ((*attrs)[i] == NULL) 1324*2264Sjacobs { 1325*2264Sjacobs /* attribute not found in array so add slot for it */ 1326*2264Sjacobs 1327*2264Sjacobs *attrs = (LDAPMod **) 1328*2264Sjacobs realloc(*attrs, (i+2) * sizeof (LDAPMod *)); 1329*2264Sjacobs if (*attrs == NULL) 1330*2264Sjacobs { 1331*2264Sjacobs result = NSL_ERR_MEMORY; 1332*2264Sjacobs } 1333*2264Sjacobs } 1334*2264Sjacobs } 1335*2264Sjacobs else 1336*2264Sjacobs { 1337*2264Sjacobs result = NSL_ERR_INTERNAL; 1338*2264Sjacobs } 1339*2264Sjacobs 1340*2264Sjacobs if (result == NSL_OK) 1341*2264Sjacobs { 1342*2264Sjacobs if ((*attrs)[i] == NULL) 1343*2264Sjacobs { 1344*2264Sjacobs /* We've got a new slot. Create the new mod entry */ 1345*2264Sjacobs 1346*2264Sjacobs (*attrs)[i] = (LDAPMod *) malloc(sizeof (LDAPMod)); 1347*2264Sjacobs if (((*attrs)[i] != NULL) && (value != NULL)) 1348*2264Sjacobs { 1349*2264Sjacobs /* Do an attribute replace */ 1350*2264Sjacobs 1351*2264Sjacobs (*attrs)[i]->mod_op = LDAP_MOD_REPLACE; 1352*2264Sjacobs (*attrs)[i]->mod_type = strdup(type); 1353*2264Sjacobs (*attrs)[i]->mod_values = (char **) 1354*2264Sjacobs malloc(2 * sizeof (char *)); 1355*2264Sjacobs if ((*attrs)[i]->mod_values != NULL) 1356*2264Sjacobs { 1357*2264Sjacobs (*attrs)[i]->mod_values[0] = 1358*2264Sjacobs strdup(value); 1359*2264Sjacobs (*attrs)[i]->mod_values[1] = NULL; 1360*2264Sjacobs (*attrs)[i+1] = NULL; 1361*2264Sjacobs } 1362*2264Sjacobs else 1363*2264Sjacobs { 1364*2264Sjacobs result = NSL_ERR_MEMORY; 1365*2264Sjacobs } 1366*2264Sjacobs } 1367*2264Sjacobs else 1368*2264Sjacobs if ((*attrs)[i] != NULL) 1369*2264Sjacobs { 1370*2264Sjacobs /* value is null so do an attribute delete */ 1371*2264Sjacobs 1372*2264Sjacobs (*attrs)[i]->mod_op = LDAP_MOD_DELETE; 1373*2264Sjacobs (*attrs)[i]->mod_type = strdup(type); 1374*2264Sjacobs (*attrs)[i]->mod_values = NULL; 1375*2264Sjacobs (*attrs)[i+1] = NULL; 1376*2264Sjacobs } 1377*2264Sjacobs else 1378*2264Sjacobs { 1379*2264Sjacobs result = NSL_ERR_MEMORY; /* malloc failed */ 1380*2264Sjacobs } 1381*2264Sjacobs } 1382*2264Sjacobs 1383*2264Sjacobs else 1384*2264Sjacobs { 1385*2264Sjacobs /* Found an existing entry so add value to it */ 1386*2264Sjacobs 1387*2264Sjacobs if (value != NULL) 1388*2264Sjacobs { 1389*2264Sjacobs /* add value to attribute's replace list */ 1390*2264Sjacobs 1391*2264Sjacobs if ((*attrs)[i]->mod_op == LDAP_MOD_REPLACE) 1392*2264Sjacobs { 1393*2264Sjacobs for (j = 0; 1394*2264Sjacobs (*attrs)[i]->mod_values[j] != NULL; j++); 1395*2264Sjacobs 1396*2264Sjacobs (*attrs)[i]->mod_values = 1397*2264Sjacobs (char **)realloc((*attrs)[i]->mod_values, 1398*2264Sjacobs (j + 2) * sizeof (char *)); 1399*2264Sjacobs if ((*attrs)[i]->mod_values != NULL) 1400*2264Sjacobs { 1401*2264Sjacobs (*attrs)[i]->mod_values[j] = 1402*2264Sjacobs strdup(value); 1403*2264Sjacobs (*attrs)[i]->mod_values[j+1] = NULL; 1404*2264Sjacobs } 1405*2264Sjacobs else 1406*2264Sjacobs { 1407*2264Sjacobs result = NSL_ERR_MEMORY; 1408*2264Sjacobs } 1409*2264Sjacobs } 1410*2264Sjacobs else 1411*2264Sjacobs { 1412*2264Sjacobs /* Delete and replace not allowed */ 1413*2264Sjacobs result = NSL_ERR_MULTIOP; 1414*2264Sjacobs } 1415*2264Sjacobs } 1416*2264Sjacobs 1417*2264Sjacobs else 1418*2264Sjacobs { 1419*2264Sjacobs /* 1420*2264Sjacobs * attribute delete - so free any existing 1421*2264Sjacobs * entries in the value array 1422*2264Sjacobs */ 1423*2264Sjacobs 1424*2264Sjacobs (*attrs)[i]->mod_op = LDAP_MOD_DELETE; 1425*2264Sjacobs 1426*2264Sjacobs if ((*attrs)[i]->mod_values != NULL) 1427*2264Sjacobs { 1428*2264Sjacobs for (j = 0; 1429*2264Sjacobs (*attrs)[i]->mod_values[j] != NULL; 1430*2264Sjacobs j++) 1431*2264Sjacobs { 1432*2264Sjacobs free((*attrs)[i]->mod_values[j]); 1433*2264Sjacobs } 1434*2264Sjacobs 1435*2264Sjacobs free((*attrs)[i]->mod_values); 1436*2264Sjacobs (*attrs)[i]->mod_values = NULL; 1437*2264Sjacobs } 1438*2264Sjacobs } 1439*2264Sjacobs } 1440*2264Sjacobs } 1441*2264Sjacobs 1442*2264Sjacobs return (result); 1443*2264Sjacobs } /* _modLDAPmodValue */ 1444*2264Sjacobs 1445*2264Sjacobs 1446*2264Sjacobs 1447*2264Sjacobs 1448*2264Sjacobs 1449*2264Sjacobs /* 1450*2264Sjacobs * ***************************************************************************** 1451*2264Sjacobs * 1452*2264Sjacobs * Function: _constructAddLDAPMod() 1453*2264Sjacobs * 1454*2264Sjacobs * Description: For the given attribute list construct an 1455*2264Sjacobs * LDAPMod array for the printer object to be added. Default 1456*2264Sjacobs * attribute values are included. 1457*2264Sjacobs * 1458*2264Sjacobs * Parameters: 1459*2264Sjacobs * Input: 1460*2264Sjacobs * uchar_t *printerName - Name of printer to be added 1461*2264Sjacobs * char **attrList - user specified attribute values list 1462*2264Sjacobs * Output: LDAPMod ***attrs - pointer to the constructed array 1463*2264Sjacobs * 1464*2264Sjacobs * Returns: NSL_RESULT - NSL_OK = constructed okay 1465*2264Sjacobs * 1466*2264Sjacobs * ***************************************************************************** 1467*2264Sjacobs */ 1468*2264Sjacobs 1469*2264Sjacobs static NSL_RESULT 1470*2264Sjacobs _constructAddLDAPMod(uchar_t *printerName, char **attrList, LDAPMod ***attrs) 1471*2264Sjacobs 1472*2264Sjacobs { 1473*2264Sjacobs NSL_RESULT result = NSL_ERROR; 1474*2264Sjacobs int len = 0; 1475*2264Sjacobs char **p = NULL; 1476*2264Sjacobs char *value = NULL; 1477*2264Sjacobs char *attr = NULL; 1478*2264Sjacobs 1479*2264Sjacobs /* ---------- */ 1480*2264Sjacobs 1481*2264Sjacobs if ((printerName != NULL) && 1482*2264Sjacobs ((attrList != NULL) && (attrList[0] != NULL)) && (attrs != NULL)) 1483*2264Sjacobs { 1484*2264Sjacobs *attrs = NULL; 1485*2264Sjacobs 1486*2264Sjacobs /* 1487*2264Sjacobs * setup printer object attribute values in an LDAPMod structure 1488*2264Sjacobs */ 1489*2264Sjacobs result = _addLDAPmodValue(attrs, ATTR_OCLASS, OCV_TOP); 1490*2264Sjacobs if (result == NSL_OK) 1491*2264Sjacobs { 1492*2264Sjacobs /* Structural Objectclass */ 1493*2264Sjacobs result = 1494*2264Sjacobs _addLDAPmodValue(attrs, ATTR_OCLASS, OCV_PSERVICE); 1495*2264Sjacobs } 1496*2264Sjacobs if (result == NSL_OK) 1497*2264Sjacobs { 1498*2264Sjacobs result = _addLDAPmodValue(attrs, 1499*2264Sjacobs ATTR_OCLASS, OCV_PABSTRACT); 1500*2264Sjacobs } 1501*2264Sjacobs if (result == NSL_OK) 1502*2264Sjacobs { 1503*2264Sjacobs result = _addLDAPmodValue(attrs, 1504*2264Sjacobs ATTR_OCLASS, OCV_SUNPRT); 1505*2264Sjacobs } 1506*2264Sjacobs if (result == NSL_OK) 1507*2264Sjacobs { 1508*2264Sjacobs result = _addLDAPmodValue(attrs, 1509*2264Sjacobs ATTR_PNAME, (char *)printerName); 1510*2264Sjacobs } 1511*2264Sjacobs 1512*2264Sjacobs /* 1513*2264Sjacobs * Now work through the user supplied attribute 1514*2264Sjacobs * values list and add them into the LDAPMod array 1515*2264Sjacobs */ 1516*2264Sjacobs 1517*2264Sjacobs for (p = attrList; 1518*2264Sjacobs (p != NULL) && (*p != NULL) && (result == NSL_OK); p++) 1519*2264Sjacobs { 1520*2264Sjacobs /* get length of this key word */ 1521*2264Sjacobs 1522*2264Sjacobs for (len = 0; 1523*2264Sjacobs ((*p)[len] != '=') && ((*p)[len] != '\0'); len++); 1524*2264Sjacobs 1525*2264Sjacobs if ((strlen(*p) > len+1)) 1526*2264Sjacobs { 1527*2264Sjacobs attr = strdup(*p); 1528*2264Sjacobs attr[len] = '\0'; 1529*2264Sjacobs value = strdup(&attr[len+1]); 1530*2264Sjacobs 1531*2264Sjacobs /* handle specific Key Value Pairs (KVP) */ 1532*2264Sjacobs 1533*2264Sjacobs if (strcasecmp(attr, NS_KEY_BSDADDR) == 0) 1534*2264Sjacobs { 1535*2264Sjacobs /* use LDAP attribute name */ 1536*2264Sjacobs free(attr); 1537*2264Sjacobs attr = strdup(ATTR_BSDADDR); 1538*2264Sjacobs } 1539*2264Sjacobs else 1540*2264Sjacobs if (_attrInLDAPList(attr) == 0) 1541*2264Sjacobs { 1542*2264Sjacobs /* 1543*2264Sjacobs * Non-LDAP attribute so use LDAP 1544*2264Sjacobs * KVP attribute and the given KVP 1545*2264Sjacobs * as the value, ie. 1546*2264Sjacobs * sun-printer-kvp=description=printer 1547*2264Sjacobs */ 1548*2264Sjacobs free(attr); 1549*2264Sjacobs attr = strdup(ATTR_KVP); 1550*2264Sjacobs value = strdup(*p); 1551*2264Sjacobs } 1552*2264Sjacobs 1553*2264Sjacobs /* add it into the LDAPMod array */ 1554*2264Sjacobs 1555*2264Sjacobs result = _addLDAPmodValue(attrs, attr, value); 1556*2264Sjacobs 1557*2264Sjacobs free(attr); 1558*2264Sjacobs free(value); 1559*2264Sjacobs } 1560*2264Sjacobs } /* for */ 1561*2264Sjacobs 1562*2264Sjacobs if ((result != NSL_OK) && (*attrs != NULL)) 1563*2264Sjacobs { 1564*2264Sjacobs (void) ldap_mods_free(*attrs, 1); 1565*2264Sjacobs attrs = NULL; 1566*2264Sjacobs } 1567*2264Sjacobs } 1568*2264Sjacobs else 1569*2264Sjacobs { 1570*2264Sjacobs result = NSL_ERR_INTERNAL; 1571*2264Sjacobs } 1572*2264Sjacobs 1573*2264Sjacobs return (result); 1574*2264Sjacobs } /* _constructAddLDAPMod */ 1575*2264Sjacobs 1576*2264Sjacobs 1577*2264Sjacobs 1578*2264Sjacobs 1579*2264Sjacobs 1580*2264Sjacobs 1581*2264Sjacobs 1582*2264Sjacobs /* 1583*2264Sjacobs * ***************************************************************************** 1584*2264Sjacobs * 1585*2264Sjacobs * Function: _constructModLDAPMod() 1586*2264Sjacobs * 1587*2264Sjacobs * Description: For the given modify attribute list, construct an 1588*2264Sjacobs * LDAPMod array for the printer object to be modified 1589*2264Sjacobs * 1590*2264Sjacobs * Parameters: 1591*2264Sjacobs * Input: uchar_t *printerName - name of printer to be modified 1592*2264Sjacobs * int sunPrinter - Boolean; object is a sunPrinter 1593*2264Sjacobs * char **attrList - user specified attribute values list 1594*2264Sjacobs * char ***oldKVPList - current list of KVP values on object 1595*2264Sjacobs * Output: LDAPMod ***attrs - pointer to the constructed array 1596*2264Sjacobs * 1597*2264Sjacobs * Returns: NSL_RESULT - NSL_OK = constructed okay 1598*2264Sjacobs * 1599*2264Sjacobs * ***************************************************************************** 1600*2264Sjacobs */ 1601*2264Sjacobs 1602*2264Sjacobs static NSL_RESULT 1603*2264Sjacobs _constructModLDAPMod(uchar_t *printerName, int sunPrinter, char **attrList, 1604*2264Sjacobs char ***oldKVPList, LDAPMod ***attrs) 1605*2264Sjacobs 1606*2264Sjacobs { 1607*2264Sjacobs NSL_RESULT result = NSL_OK; 1608*2264Sjacobs int len = 0; 1609*2264Sjacobs int kvpUpdated = 0; 1610*2264Sjacobs int kvpExists = 0; 1611*2264Sjacobs char **p = NULL; 1612*2264Sjacobs char *value = NULL; 1613*2264Sjacobs char *attr = NULL; 1614*2264Sjacobs 1615*2264Sjacobs /* ---------- */ 1616*2264Sjacobs 1617*2264Sjacobs if ((printerName != NULL) && 1618*2264Sjacobs ((attrList != NULL) && (attrList[0] != NULL)) && (attrs != NULL)) 1619*2264Sjacobs { 1620*2264Sjacobs *attrs = NULL; 1621*2264Sjacobs 1622*2264Sjacobs if ((oldKVPList != NULL) && (*oldKVPList != NULL)) 1623*2264Sjacobs { 1624*2264Sjacobs kvpExists = 1; 1625*2264Sjacobs } 1626*2264Sjacobs 1627*2264Sjacobs if (!sunPrinter) 1628*2264Sjacobs { 1629*2264Sjacobs /* 1630*2264Sjacobs * The object was previously not a sunPrinter, so 1631*2264Sjacobs * add the required objectclass attribute value, and 1632*2264Sjacobs * ensure it has the printername attribute. 1633*2264Sjacobs */ 1634*2264Sjacobs result = _addLDAPmodValue(attrs, 1635*2264Sjacobs ATTR_OCLASS, OCV_SUNPRT); 1636*2264Sjacobs if (result == NSL_OK) 1637*2264Sjacobs { 1638*2264Sjacobs result = _modLDAPmodValue(attrs, 1639*2264Sjacobs ATTR_PNAME, (char *)printerName); 1640*2264Sjacobs } 1641*2264Sjacobs } 1642*2264Sjacobs 1643*2264Sjacobs /* 1644*2264Sjacobs * work through the user supplied attribute 1645*2264Sjacobs * values list and add them into the LDAPMod array depending 1646*2264Sjacobs * on if they are a replace or delete attribute operation, 1647*2264Sjacobs * a "null value" means delete. 1648*2264Sjacobs */ 1649*2264Sjacobs 1650*2264Sjacobs for (p = attrList; 1651*2264Sjacobs (p != NULL) && (*p != NULL) && (result == NSL_OK); p++) 1652*2264Sjacobs { 1653*2264Sjacobs /* get length of this key word */ 1654*2264Sjacobs 1655*2264Sjacobs for (len = 0; 1656*2264Sjacobs ((*p)[len] != '=') && ((*p)[len] != '\0'); len++); 1657*2264Sjacobs 1658*2264Sjacobs if ((strlen(*p) > len+1)) 1659*2264Sjacobs { 1660*2264Sjacobs attr = strdup(*p); 1661*2264Sjacobs attr[len] = '\0'; 1662*2264Sjacobs value = strdup(&attr[len+1]); 1663*2264Sjacobs 1664*2264Sjacobs /* handle specific Key Value Pairs (KVP) */ 1665*2264Sjacobs 1666*2264Sjacobs if ((_attrInLDAPList(attr) == 0) && 1667*2264Sjacobs (strcasecmp(attr, NS_KEY_BSDADDR) != 0)) 1668*2264Sjacobs { 1669*2264Sjacobs /* 1670*2264Sjacobs * Non-LDAP attribute so use LDAP 1671*2264Sjacobs * KVP attribute and the given KVP as 1672*2264Sjacobs * the value, ie. 1673*2264Sjacobs * sun-printer-kvp=description=printer 1674*2264Sjacobs */ 1675*2264Sjacobs result = _modAttrKVP(*p, oldKVPList); 1676*2264Sjacobs kvpUpdated = 1; 1677*2264Sjacobs } 1678*2264Sjacobs 1679*2264Sjacobs else 1680*2264Sjacobs { 1681*2264Sjacobs if (strcasecmp(attr, NS_KEY_BSDADDR) == 1682*2264Sjacobs 0) 1683*2264Sjacobs { 1684*2264Sjacobs /* 1685*2264Sjacobs * use LDAP bsdaddr attribute 1686*2264Sjacobs * name 1687*2264Sjacobs */ 1688*2264Sjacobs free(attr); 1689*2264Sjacobs attr = strdup(ATTR_BSDADDR); 1690*2264Sjacobs } 1691*2264Sjacobs 1692*2264Sjacobs /* 1693*2264Sjacobs * else 1694*2264Sjacobs * use the supplied attribute name 1695*2264Sjacobs */ 1696*2264Sjacobs 1697*2264Sjacobs /* add it into the LDAPMod array */ 1698*2264Sjacobs 1699*2264Sjacobs result = _modLDAPmodValue(attrs, 1700*2264Sjacobs attr, value); 1701*2264Sjacobs } 1702*2264Sjacobs 1703*2264Sjacobs free(attr); 1704*2264Sjacobs free(value); 1705*2264Sjacobs } 1706*2264Sjacobs 1707*2264Sjacobs else 1708*2264Sjacobs if (strlen(*p) >= 1) 1709*2264Sjacobs { 1710*2264Sjacobs /* handle attribute DELETE request */ 1711*2264Sjacobs 1712*2264Sjacobs attr = strdup(*p); 1713*2264Sjacobs if (attr[len] == '=') 1714*2264Sjacobs { 1715*2264Sjacobs /* terminate "attribute=" */ 1716*2264Sjacobs attr[len] = '\0'; 1717*2264Sjacobs } 1718*2264Sjacobs 1719*2264Sjacobs /* handle specific Key Value Pairs (KVP) */ 1720*2264Sjacobs 1721*2264Sjacobs if (strcasecmp(attr, NS_KEY_BSDADDR) == 0) 1722*2264Sjacobs { 1723*2264Sjacobs /* use LDAP bsdaddr attribute name */ 1724*2264Sjacobs result = _modLDAPmodValue(attrs, 1725*2264Sjacobs ATTR_BSDADDR, NULL); 1726*2264Sjacobs } 1727*2264Sjacobs else 1728*2264Sjacobs if (_attrInLDAPList(attr) == 0) 1729*2264Sjacobs { 1730*2264Sjacobs /* 1731*2264Sjacobs * Non-LDAP kvp, so sort items 1732*2264Sjacobs * in the kvp list 1733*2264Sjacobs */ 1734*2264Sjacobs result = _modAttrKVP(*p, oldKVPList); 1735*2264Sjacobs kvpUpdated = 1; 1736*2264Sjacobs } 1737*2264Sjacobs else 1738*2264Sjacobs { 1739*2264Sjacobs result = _modLDAPmodValue(attrs, 1740*2264Sjacobs attr, NULL); 1741*2264Sjacobs } 1742*2264Sjacobs 1743*2264Sjacobs free(attr); 1744*2264Sjacobs } 1745*2264Sjacobs } /* for */ 1746*2264Sjacobs 1747*2264Sjacobs if ((result == NSL_OK) && (kvpUpdated)) 1748*2264Sjacobs { 1749*2264Sjacobs result = _attrAddKVP(attrs, *oldKVPList, kvpExists); 1750*2264Sjacobs } 1751*2264Sjacobs 1752*2264Sjacobs if ((result != NSL_OK) && (*attrs != NULL)) 1753*2264Sjacobs { 1754*2264Sjacobs (void) ldap_mods_free(*attrs, 1); 1755*2264Sjacobs *attrs = NULL; 1756*2264Sjacobs } 1757*2264Sjacobs } 1758*2264Sjacobs else 1759*2264Sjacobs { 1760*2264Sjacobs result = NSL_ERR_INTERNAL; 1761*2264Sjacobs } 1762*2264Sjacobs 1763*2264Sjacobs return (result); 1764*2264Sjacobs } /* _constructModLDAPMod */ 1765*2264Sjacobs 1766*2264Sjacobs 1767*2264Sjacobs 1768*2264Sjacobs 1769*2264Sjacobs 1770*2264Sjacobs 1771*2264Sjacobs /* 1772*2264Sjacobs * ***************************************************************************** 1773*2264Sjacobs * 1774*2264Sjacobs * Function: _compareURIinDNs() 1775*2264Sjacobs * 1776*2264Sjacobs * Description: For the 2 given printer object DNs compare the naming part 1777*2264Sjacobs * part of the DN (printer-uri) to see if they are the same. 1778*2264Sjacobs * 1779*2264Sjacobs * Note: This function only returns "compare failed" if their URI don't 1780*2264Sjacobs * compare. Problems with the dn etc., return a good compare 1781*2264Sjacobs * because I don't want us to create a new object for these 1782*2264Sjacobs * 1783*2264Sjacobs * Parameters: 1784*2264Sjacobs * Input: uchar_t *dn1 1785*2264Sjacobs * uchar_t *dn2 1786*2264Sjacobs * Output: None 1787*2264Sjacobs * 1788*2264Sjacobs * Returns: NSL_RESULT - NSL_OK = URIs are the same 1789*2264Sjacobs * 1790*2264Sjacobs * ***************************************************************************** 1791*2264Sjacobs */ 1792*2264Sjacobs 1793*2264Sjacobs static NSL_RESULT 1794*2264Sjacobs _compareURIinDNs(uchar_t *dn1, uchar_t *dn2) 1795*2264Sjacobs 1796*2264Sjacobs { 1797*2264Sjacobs NSL_RESULT result = NSL_OK; 1798*2264Sjacobs uchar_t *DN1 = NULL; 1799*2264Sjacobs uchar_t *DN2 = NULL; 1800*2264Sjacobs char *p1 = NULL; 1801*2264Sjacobs char *p2 = NULL; 1802*2264Sjacobs 1803*2264Sjacobs /* --------- */ 1804*2264Sjacobs 1805*2264Sjacobs if ((dn1 != NULL) && (dn2 != NULL)) 1806*2264Sjacobs { 1807*2264Sjacobs DN1 = (uchar_t *)strdup((char *)dn1); 1808*2264Sjacobs DN2 = (uchar_t *)strdup((char *)dn2); 1809*2264Sjacobs 1810*2264Sjacobs /* terminate each string after the printer-uri */ 1811*2264Sjacobs 1812*2264Sjacobs p1 = strstr((char *)DN1, PCONTAINER); 1813*2264Sjacobs /* move back to the comma */ 1814*2264Sjacobs while ((p1 != NULL) && (*p1 != ',') && (p1 >= (char *)DN1)) 1815*2264Sjacobs { 1816*2264Sjacobs p1--; 1817*2264Sjacobs } 1818*2264Sjacobs 1819*2264Sjacobs p2 = strstr((char *)DN2, PCONTAINER); 1820*2264Sjacobs /* move back to the comma */ 1821*2264Sjacobs while ((p2 != NULL) && (*p2 != ',') && (p2 >= (char *)DN2)) 1822*2264Sjacobs { 1823*2264Sjacobs p2--; 1824*2264Sjacobs } 1825*2264Sjacobs 1826*2264Sjacobs if ((*p1 == ',') && (*p2 == ',')) 1827*2264Sjacobs { 1828*2264Sjacobs *p1 = '\0'; /* re-terminate it */ 1829*2264Sjacobs *p2 = '\0'; /* re-terminate it */ 1830*2264Sjacobs 1831*2264Sjacobs /* do the compare */ 1832*2264Sjacobs 1833*2264Sjacobs /* 1834*2264Sjacobs * Note: SHOULD really normalise the 2 DNs before 1835*2264Sjacobs * doing the compare 1836*2264Sjacobs */ 1837*2264Sjacobs #ifdef DEBUG 1838*2264Sjacobs printf("_compareURIinDNs() @1 (%s) (%s)\n", DN1, DN2); 1839*2264Sjacobs #endif 1840*2264Sjacobs if (strcasecmp((char *)DN1, (char *)DN2) != 0) 1841*2264Sjacobs { 1842*2264Sjacobs result = NSL_ERROR; 1843*2264Sjacobs } 1844*2264Sjacobs 1845*2264Sjacobs } 1846*2264Sjacobs 1847*2264Sjacobs free(DN1); 1848*2264Sjacobs free(DN2); 1849*2264Sjacobs } 1850*2264Sjacobs 1851*2264Sjacobs return (result); 1852*2264Sjacobs } /* _compareURIinDNs */ 1853*2264Sjacobs 1854*2264Sjacobs 1855*2264Sjacobs 1856*2264Sjacobs 1857*2264Sjacobs 1858*2264Sjacobs 1859*2264Sjacobs 1860*2264Sjacobs /* 1861*2264Sjacobs * ***************************************************************************** 1862*2264Sjacobs * 1863*2264Sjacobs * Function: _getThisNSDomainDN() 1864*2264Sjacobs * 1865*2264Sjacobs * Description: Get the current Name Service Domain DN 1866*2264Sjacobs * This is extracted from the result of executing ldaplist. 1867*2264Sjacobs * 1868*2264Sjacobs * Note: Do it this way until the NS LDAP library interface is 1869*2264Sjacobs * made public. 1870*2264Sjacobs * 1871*2264Sjacobs * Parameters: 1872*2264Sjacobs * Input: None 1873*2264Sjacobs * Output: None 1874*2264Sjacobs * 1875*2264Sjacobs * Returns: uchar_t* - pointer to NS Domain DN (The caller should free this 1876*2264Sjacobs * returned memory). 1877*2264Sjacobs * 1878*2264Sjacobs * ***************************************************************************** 1879*2264Sjacobs */ 1880*2264Sjacobs 1881*2264Sjacobs #define LDAPLIST_D "/usr/bin/ldaplist -d 2>&1" 1882*2264Sjacobs #define DNID "dn: " 1883*2264Sjacobs 1884*2264Sjacobs static uchar_t * 1885*2264Sjacobs _getThisNSDomainDN(void) 1886*2264Sjacobs 1887*2264Sjacobs { 1888*2264Sjacobs uchar_t *domainDN = NULL; 1889*2264Sjacobs char *cp = NULL; 1890*2264Sjacobs char buf[BUFSIZ] = ""; 1891*2264Sjacobs 1892*2264Sjacobs /* --------- */ 1893*2264Sjacobs 1894*2264Sjacobs if (_popen(LDAPLIST_D, buf, sizeof (buf)) == 0) 1895*2264Sjacobs { 1896*2264Sjacobs if ((cp = strstr(buf, DNID)) != NULL) 1897*2264Sjacobs { 1898*2264Sjacobs cp += strlen(DNID); /* increment past "dn: " label */ 1899*2264Sjacobs domainDN = (uchar_t *)strdup(cp); 1900*2264Sjacobs 1901*2264Sjacobs if ((cp = strchr((char *)domainDN, '\n')) != NULL) 1902*2264Sjacobs { 1903*2264Sjacobs *cp = '\0'; /* terminate it */ 1904*2264Sjacobs } 1905*2264Sjacobs } 1906*2264Sjacobs } 1907*2264Sjacobs 1908*2264Sjacobs return (domainDN); 1909*2264Sjacobs } /* _getThisNSDomainDN */ 1910*2264Sjacobs 1911*2264Sjacobs 1912*2264Sjacobs 1913*2264Sjacobs 1914*2264Sjacobs 1915*2264Sjacobs /* 1916*2264Sjacobs * ***************************************************************************** 1917*2264Sjacobs * 1918*2264Sjacobs * Function: _popen() 1919*2264Sjacobs * 1920*2264Sjacobs * Description: General popen function. The caller should always use a full 1921*2264Sjacobs * path cmd. 1922*2264Sjacobs * 1923*2264Sjacobs * Parameters: 1924*2264Sjacobs * Input: char *cmd - command line to execute 1925*2264Sjacobs * char *buffer - ptr to buffer to put result in 1926*2264Sjacobs * int size - size of result buffer 1927*2264Sjacobs * Output: None 1928*2264Sjacobs * 1929*2264Sjacobs * Returns: int - 0 = opened okay 1930*2264Sjacobs * 1931*2264Sjacobs * ***************************************************************************** 1932*2264Sjacobs */ 1933*2264Sjacobs 1934*2264Sjacobs static int 1935*2264Sjacobs _popen(char *cmd, char *buffer, int size) 1936*2264Sjacobs 1937*2264Sjacobs { 1938*2264Sjacobs int result = -1; 1939*2264Sjacobs int rsize = 0; 1940*2264Sjacobs FILE *fptr; 1941*2264Sjacobs char safe_cmd[BUFSIZ]; 1942*2264Sjacobs char linebuf[BUFSIZ]; 1943*2264Sjacobs 1944*2264Sjacobs /* -------- */ 1945*2264Sjacobs 1946*2264Sjacobs if ((cmd != NULL) && (buffer != NULL) && (size != 0)) 1947*2264Sjacobs { 1948*2264Sjacobs (void) strcpy(buffer, ""); 1949*2264Sjacobs (void) strcpy(linebuf, ""); 1950*2264Sjacobs (void) snprintf(safe_cmd, BUFSIZ, "IFS=' \t'; %s", cmd); 1951*2264Sjacobs 1952*2264Sjacobs if ((fptr = popen(safe_cmd, "r")) != NULL) 1953*2264Sjacobs { 1954*2264Sjacobs while ((fgets(linebuf, BUFSIZ, fptr) != NULL) && 1955*2264Sjacobs (rsize < size)) 1956*2264Sjacobs { 1957*2264Sjacobs rsize = strlcat(buffer, linebuf, size); 1958*2264Sjacobs if (rsize >= size) 1959*2264Sjacobs { 1960*2264Sjacobs /* result is too long */ 1961*2264Sjacobs (void) memset(buffer, '\0', size); 1962*2264Sjacobs } 1963*2264Sjacobs } 1964*2264Sjacobs 1965*2264Sjacobs if (strlen(buffer) > 0) 1966*2264Sjacobs { 1967*2264Sjacobs result = 0; 1968*2264Sjacobs } 1969*2264Sjacobs 1970*2264Sjacobs (void) pclose(fptr); 1971*2264Sjacobs } 1972*2264Sjacobs } 1973*2264Sjacobs 1974*2264Sjacobs return (result); 1975*2264Sjacobs } /* popen */ 1976*2264Sjacobs 1977*2264Sjacobs 1978*2264Sjacobs /* 1979*2264Sjacobs * ***************************************************************************** 1980*2264Sjacobs * 1981*2264Sjacobs * Function: _attrInList() 1982*2264Sjacobs * 1983*2264Sjacobs * Description: For the given list check if the attribute is it 1984*2264Sjacobs * 1985*2264Sjacobs * Parameters: 1986*2264Sjacobs * Input: char *attr - attribute to check 1987*2264Sjacobs * char **list - list of attributes to check against 1988*2264Sjacobs * Output: None 1989*2264Sjacobs * 1990*2264Sjacobs * Returns: int - TRUE = attr found in list 1991*2264Sjacobs * 1992*2264Sjacobs * ***************************************************************************** 1993*2264Sjacobs */ 1994*2264Sjacobs 1995*2264Sjacobs static int 1996*2264Sjacobs _attrInList(char *attr, const char **list) 1997*2264Sjacobs 1998*2264Sjacobs { 1999*2264Sjacobs int result = 0; 2000*2264Sjacobs int j; 2001*2264Sjacobs 2002*2264Sjacobs /* ------- */ 2003*2264Sjacobs 2004*2264Sjacobs if ((attr != NULL) && (list != NULL)) 2005*2264Sjacobs { 2006*2264Sjacobs for (j = 0; (list[j] != NULL) && (result != 1); j++) 2007*2264Sjacobs { 2008*2264Sjacobs if (strcasecmp(list[j], attr) == 0) 2009*2264Sjacobs { 2010*2264Sjacobs result = 1; /* found */ 2011*2264Sjacobs } 2012*2264Sjacobs } 2013*2264Sjacobs } 2014*2264Sjacobs 2015*2264Sjacobs return (result); 2016*2264Sjacobs } /* _attrInList */ 2017*2264Sjacobs 2018*2264Sjacobs 2019*2264Sjacobs 2020*2264Sjacobs 2021*2264Sjacobs /* 2022*2264Sjacobs * ***************************************************************************** 2023*2264Sjacobs * 2024*2264Sjacobs * Function: _attrInLDAPList() 2025*2264Sjacobs * 2026*2264Sjacobs * Description: Checks to see if the given attribute is an LDAP printing 2027*2264Sjacobs * attribute, ie. is either in an IPP objectclass or the 2028*2264Sjacobs * sun printer objectclass. Note: some attributes are handled 2029*2264Sjacobs * specifically outside this function, so are excluded from 2030*2264Sjacobs * the lists that are checked. 2031*2264Sjacobs * 2032*2264Sjacobs * Parameters: 2033*2264Sjacobs * Input: char *attr - attribute to check 2034*2264Sjacobs * Output: None 2035*2264Sjacobs * 2036*2264Sjacobs * Returns: int - TRUE = attr found in list 2037*2264Sjacobs * 2038*2264Sjacobs * ***************************************************************************** 2039*2264Sjacobs */ 2040*2264Sjacobs 2041*2264Sjacobs static int 2042*2264Sjacobs _attrInLDAPList(char *attr) 2043*2264Sjacobs 2044*2264Sjacobs { 2045*2264Sjacobs int result = 0; 2046*2264Sjacobs 2047*2264Sjacobs /* ------- */ 2048*2264Sjacobs 2049*2264Sjacobs if (_attrInList(attr, nsl_attr_printerService)) 2050*2264Sjacobs { 2051*2264Sjacobs result = 1; /* in list */ 2052*2264Sjacobs } 2053*2264Sjacobs else 2054*2264Sjacobs if (_attrInList(attr, nsl_attr_printerIPP)) 2055*2264Sjacobs { 2056*2264Sjacobs result = 1; /* in list */ 2057*2264Sjacobs } 2058*2264Sjacobs else 2059*2264Sjacobs if (_attrInList(attr, nsl_attr_sunPrinter)) 2060*2264Sjacobs { 2061*2264Sjacobs result = 1; /* in list */ 2062*2264Sjacobs } 2063*2264Sjacobs 2064*2264Sjacobs return (result); 2065*2264Sjacobs } /* _attrInLDAPList */ 2066*2264Sjacobs 2067*2264Sjacobs 2068*2264Sjacobs 2069*2264Sjacobs 2070*2264Sjacobs /* 2071*2264Sjacobs * ***************************************************************************** 2072*2264Sjacobs * 2073*2264Sjacobs * Function: _getCurrentKVPValues() 2074*2264Sjacobs * 2075*2264Sjacobs * Description: For the given printer object read the current set of values 2076*2264Sjacobs * the object has for the sun-printer-kvp (Key Value pair) 2077*2264Sjacobs * 2078*2264Sjacobs * Parameters: 2079*2264Sjacobs * Input: LDAP *ld - existing ldap connection descriptor 2080*2264Sjacobs * char *objectDN - DN to search for 2081*2264Sjacobs * Output: char ***list - returned set of kvp values 2082*2264Sjacobs * 2083*2264Sjacobs * Result: NSL_RESULT - NSL_OK = object exists 2084*2264Sjacobs * 2085*2264Sjacobs * ***************************************************************************** 2086*2264Sjacobs */ 2087*2264Sjacobs 2088*2264Sjacobs static NSL_RESULT 2089*2264Sjacobs _getCurrentKVPValues(LDAP *ld, uchar_t *objectDN, char ***list) 2090*2264Sjacobs 2091*2264Sjacobs { 2092*2264Sjacobs NSL_RESULT result = NSL_ERR_UNKNOWN_PRINTER; 2093*2264Sjacobs int sresult = LDAP_NO_SUCH_OBJECT; 2094*2264Sjacobs int i = 0; 2095*2264Sjacobs LDAPMessage *ldapMsg; 2096*2264Sjacobs char *requiredAttrs[2] = { ATTR_KVP, NULL }; 2097*2264Sjacobs LDAPMessage *ldapEntry = NULL; 2098*2264Sjacobs char *entryAttrib = NULL; 2099*2264Sjacobs char **attribValues = NULL; 2100*2264Sjacobs BerElement *berElement = NULL; 2101*2264Sjacobs 2102*2264Sjacobs /* ---------- */ 2103*2264Sjacobs 2104*2264Sjacobs if ((list != NULL) && (ld != NULL) && (objectDN != NULL)) 2105*2264Sjacobs { 2106*2264Sjacobs /* search for this Printer in the directory */ 2107*2264Sjacobs 2108*2264Sjacobs sresult = ldap_search_s(ld, (char *)objectDN, LDAP_SCOPE_BASE, 2109*2264Sjacobs "(objectclass=*)", requiredAttrs, 0, &ldapMsg); 2110*2264Sjacobs if (sresult == LDAP_SUCCESS) 2111*2264Sjacobs { 2112*2264Sjacobs /* 2113*2264Sjacobs * check that the object exists and extract its 2114*2264Sjacobs * KVP attribute values 2115*2264Sjacobs */ 2116*2264Sjacobs ldapEntry = ldap_first_entry(ld, ldapMsg); 2117*2264Sjacobs if (ldapEntry != NULL) 2118*2264Sjacobs { 2119*2264Sjacobs entryAttrib = ldap_first_attribute(ld, 2120*2264Sjacobs ldapEntry, &berElement); 2121*2264Sjacobs if ((entryAttrib != NULL) && 2122*2264Sjacobs (strcasecmp(entryAttrib, ATTR_KVP) == 0)) 2123*2264Sjacobs 2124*2264Sjacobs { 2125*2264Sjacobs #ifdef DEBUG 2126*2264Sjacobs printf("Attribute: %s, its values are:\n", entryAttrib); 2127*2264Sjacobs #endif 2128*2264Sjacobs /* 2129*2264Sjacobs * add each KVP value to the list 2130*2264Sjacobs * that we will return 2131*2264Sjacobs */ 2132*2264Sjacobs attribValues = ldap_get_values( 2133*2264Sjacobs ld, ldapEntry, entryAttrib); 2134*2264Sjacobs for (i = 0; 2135*2264Sjacobs attribValues[i] != NULL; i++) 2136*2264Sjacobs { 2137*2264Sjacobs *list = (char **) 2138*2264Sjacobs list_append((void **)*list, 2139*2264Sjacobs strdup(attribValues[i])); 2140*2264Sjacobs #ifdef DEBUG 2141*2264Sjacobs printf("\t%s\n", attribValues[i]); 2142*2264Sjacobs #endif 2143*2264Sjacobs } 2144*2264Sjacobs (void) ldap_value_free(attribValues); 2145*2264Sjacobs } 2146*2264Sjacobs 2147*2264Sjacobs if ((entryAttrib != NULL) && 2148*2264Sjacobs (berElement != NULL)) 2149*2264Sjacobs { 2150*2264Sjacobs ber_free(berElement, 0); 2151*2264Sjacobs } 2152*2264Sjacobs 2153*2264Sjacobs 2154*2264Sjacobs /* object found */ 2155*2264Sjacobs result = NSL_OK; 2156*2264Sjacobs } 2157*2264Sjacobs 2158*2264Sjacobs (void) ldap_msgfree(ldapMsg); 2159*2264Sjacobs } 2160*2264Sjacobs } 2161*2264Sjacobs 2162*2264Sjacobs else 2163*2264Sjacobs { 2164*2264Sjacobs result = NSL_ERR_INTERNAL; 2165*2264Sjacobs } 2166*2264Sjacobs 2167*2264Sjacobs return (result); 2168*2264Sjacobs } /* _getCurrentKVPValues */ 2169*2264Sjacobs 2170*2264Sjacobs 2171*2264Sjacobs 2172*2264Sjacobs /* 2173*2264Sjacobs * ***************************************************************************** 2174*2264Sjacobs * 2175*2264Sjacobs * Function: _freeList() 2176*2264Sjacobs * 2177*2264Sjacobs * Description: Free the list created by list_append() where the items in 2178*2264Sjacobs * the list have been strdup'ed. 2179*2264Sjacobs * 2180*2264Sjacobs * Parameters: 2181*2264Sjacobs * Input: char ***list - returned set of kvp values 2182*2264Sjacobs * 2183*2264Sjacobs * Result: void 2184*2264Sjacobs * 2185*2264Sjacobs * ***************************************************************************** 2186*2264Sjacobs */ 2187*2264Sjacobs 2188*2264Sjacobs static void 2189*2264Sjacobs _freeList(char ***list) 2190*2264Sjacobs 2191*2264Sjacobs { 2192*2264Sjacobs int i = 0; 2193*2264Sjacobs 2194*2264Sjacobs /* ------ */ 2195*2264Sjacobs 2196*2264Sjacobs if (list != NULL) 2197*2264Sjacobs { 2198*2264Sjacobs if (*list != NULL) 2199*2264Sjacobs { 2200*2264Sjacobs for (i = 0; (*list)[i] != NULL; i++) 2201*2264Sjacobs { 2202*2264Sjacobs free((*list)[i]); 2203*2264Sjacobs } 2204*2264Sjacobs free(*list); 2205*2264Sjacobs } 2206*2264Sjacobs 2207*2264Sjacobs *list = NULL; 2208*2264Sjacobs } 2209*2264Sjacobs } /* _freeList */ 2210*2264Sjacobs 2211*2264Sjacobs 2212*2264Sjacobs 2213*2264Sjacobs /* 2214*2264Sjacobs * ***************************************************************************** 2215*2264Sjacobs * 2216*2264Sjacobs * Function: _modAttrKVP() 2217*2264Sjacobs * 2218*2264Sjacobs * Description: Sort out the KVP attribute value list, such that this new 2219*2264Sjacobs * value takes precidence over any existing value in the list. 2220*2264Sjacobs * The current list is updated to remove this key, and the new 2221*2264Sjacobs * key "value" is added to the list, eg. for 2222*2264Sjacobs * value: bbb=ddddd 2223*2264Sjacobs * and kvpList: 2224*2264Sjacobs * aaa=yyyy 2225*2264Sjacobs * bbb=zzzz 2226*2264Sjacobs * ccc=xxxx 2227*2264Sjacobs * the resulting kvpList is: 2228*2264Sjacobs * aaa=yyyy 2229*2264Sjacobs * ccc=xxxx 2230*2264Sjacobs * bbb=ddddd 2231*2264Sjacobs * 2232*2264Sjacobs * Note: When all new values have been handled the function _attrAddKVP() 2233*2264Sjacobs * must be called to add the "new list" values into the 2234*2264Sjacobs * LDAPMod array. 2235*2264Sjacobs * 2236*2264Sjacobs * Parameters: 2237*2264Sjacobs * Input: char *value - Key Value Pair to process, 2238*2264Sjacobs * eg. aaaaa=hhhhh, where aaaaa is the key 2239*2264Sjacobs * char ***kvpList - list of current KVP values 2240*2264Sjacobs * Output: char ***kvpList - updated list of KVP values 2241*2264Sjacobs * 2242*2264Sjacobs * Returns: NSL_RESULT - NSL_OK = done okay 2243*2264Sjacobs * 2244*2264Sjacobs * ***************************************************************************** 2245*2264Sjacobs */ 2246*2264Sjacobs 2247*2264Sjacobs static NSL_RESULT 2248*2264Sjacobs _modAttrKVP(char *value, char ***kvpList) 2249*2264Sjacobs 2250*2264Sjacobs { 2251*2264Sjacobs NSL_RESULT result = NSL_ERR_INTERNAL; 2252*2264Sjacobs int i = 0; 2253*2264Sjacobs int inList = 0; 2254*2264Sjacobs int keyDelete = 0; 2255*2264Sjacobs char *key = NULL; 2256*2264Sjacobs char **p = NULL; 2257*2264Sjacobs char **newList = NULL; 2258*2264Sjacobs 2259*2264Sjacobs /* ------- */ 2260*2264Sjacobs 2261*2264Sjacobs if ((value != NULL) && (kvpList != NULL)) 2262*2264Sjacobs { 2263*2264Sjacobs result = NSL_OK; 2264*2264Sjacobs 2265*2264Sjacobs /* extract "key" from value */ 2266*2264Sjacobs 2267*2264Sjacobs key = strdup(value); 2268*2264Sjacobs 2269*2264Sjacobs for (i = 0; ((key)[i] != '=') && ((key)[i] != '\0'); i++); 2270*2264Sjacobs key[i] = '\0'; /* terminate the key */ 2271*2264Sjacobs 2272*2264Sjacobs /* Is this a request to delete a "key" value */ 2273*2264Sjacobs 2274*2264Sjacobs if ((value[i] == '\0') || (value[i+1] == '\0')) 2275*2264Sjacobs { 2276*2264Sjacobs /* this is a request to delete the key */ 2277*2264Sjacobs keyDelete = 1; 2278*2264Sjacobs } 2279*2264Sjacobs 2280*2264Sjacobs if ((*kvpList != NULL) && (**kvpList != NULL)) 2281*2264Sjacobs { 2282*2264Sjacobs /* 2283*2264Sjacobs * for each item in the list remove it if the keys match 2284*2264Sjacobs */ 2285*2264Sjacobs for (p = *kvpList; *p != NULL; p++) 2286*2264Sjacobs { 2287*2264Sjacobs for (i = 0; 2288*2264Sjacobs ((*p)[i] != '=') && ((*p)[i] != '\0'); i++); 2289*2264Sjacobs 2290*2264Sjacobs if ((strlen(key) == i) && 2291*2264Sjacobs (strncasecmp(*p, key, i) == 0)) 2292*2264Sjacobs { 2293*2264Sjacobs inList = 1; 2294*2264Sjacobs } 2295*2264Sjacobs else 2296*2264Sjacobs { 2297*2264Sjacobs /* no match so add value to new list */ 2298*2264Sjacobs newList = (char **)list_append( 2299*2264Sjacobs (void **)newList, 2300*2264Sjacobs strdup(*p)); 2301*2264Sjacobs } 2302*2264Sjacobs } 2303*2264Sjacobs } 2304*2264Sjacobs 2305*2264Sjacobs /* 2306*2264Sjacobs * if it was not a DELETE request add the new key value into 2307*2264Sjacobs * the newList, otherwise we have already removed the key 2308*2264Sjacobs */ 2309*2264Sjacobs 2310*2264Sjacobs if (!keyDelete) 2311*2264Sjacobs { 2312*2264Sjacobs newList = (char **)list_append((void **)newList, 2313*2264Sjacobs strdup(value)); 2314*2264Sjacobs } 2315*2264Sjacobs 2316*2264Sjacobs if ((newList != NULL) || (inList)) 2317*2264Sjacobs { 2318*2264Sjacobs /* replace old list with the newList */ 2319*2264Sjacobs _freeList(kvpList); 2320*2264Sjacobs *kvpList = newList; 2321*2264Sjacobs } 2322*2264Sjacobs 2323*2264Sjacobs free(key); 2324*2264Sjacobs } 2325*2264Sjacobs 2326*2264Sjacobs return (result); 2327*2264Sjacobs } /* modAttrKVP */ 2328*2264Sjacobs 2329*2264Sjacobs 2330*2264Sjacobs 2331*2264Sjacobs 2332*2264Sjacobs /* 2333*2264Sjacobs * ***************************************************************************** 2334*2264Sjacobs * 2335*2264Sjacobs * Function: _attrAddKVP() 2336*2264Sjacobs * 2337*2264Sjacobs * Description: Process KVP items in the kvpList adding them to the 2338*2264Sjacobs * LDAPMod modify array. If the list is empty but there were 2339*2264Sjacobs * previously LDAP KVP values delete them. 2340*2264Sjacobs * 2341*2264Sjacobs * Note: This function should only be called when all the new KVP 2342*2264Sjacobs * items have been processed by _modAttrKVP() 2343*2264Sjacobs * 2344*2264Sjacobs * Parameters: 2345*2264Sjacobs * Input: LDAPMod ***attrs - array to update 2346*2264Sjacobs * char **kvpList - list KVP values 2347*2264Sjacobs * int kvpExists - object currently has LDAP KVP values 2348*2264Sjacobs * Output: None 2349*2264Sjacobs * 2350*2264Sjacobs * Returns: NSL_RESULT - NSL_OK = done okay 2351*2264Sjacobs * 2352*2264Sjacobs * ***************************************************************************** 2353*2264Sjacobs */ 2354*2264Sjacobs 2355*2264Sjacobs static NSL_RESULT 2356*2264Sjacobs _attrAddKVP(LDAPMod ***attrs, char **kvpList, int kvpExists) 2357*2264Sjacobs 2358*2264Sjacobs { 2359*2264Sjacobs NSL_RESULT result = NSL_OK; 2360*2264Sjacobs 2361*2264Sjacobs /* ------- */ 2362*2264Sjacobs 2363*2264Sjacobs if (attrs != NULL) 2364*2264Sjacobs { 2365*2264Sjacobs if (kvpList != NULL) 2366*2264Sjacobs { 2367*2264Sjacobs while ((kvpList != NULL) && (*kvpList != NULL)) 2368*2264Sjacobs { 2369*2264Sjacobs /* add item to LDAPMod array */ 2370*2264Sjacobs 2371*2264Sjacobs result = 2372*2264Sjacobs _modLDAPmodValue(attrs, ATTR_KVP, *kvpList); 2373*2264Sjacobs 2374*2264Sjacobs kvpList++; 2375*2264Sjacobs } 2376*2264Sjacobs } 2377*2264Sjacobs else 2378*2264Sjacobs if (kvpExists) 2379*2264Sjacobs { 2380*2264Sjacobs /* 2381*2264Sjacobs * We now have no LDAP KVP values but there were 2382*2264Sjacobs * some previously, so delete them 2383*2264Sjacobs */ 2384*2264Sjacobs result = _modLDAPmodValue(attrs, ATTR_KVP, NULL); 2385*2264Sjacobs } 2386*2264Sjacobs } 2387*2264Sjacobs 2388*2264Sjacobs else 2389*2264Sjacobs { 2390*2264Sjacobs result = NSL_ERR_INTERNAL; 2391*2264Sjacobs } 2392*2264Sjacobs 2393*2264Sjacobs return (result); 2394*2264Sjacobs } /* _attrAddKVP */ 2395*2264Sjacobs 2396*2264Sjacobs 2397*2264Sjacobs 2398*2264Sjacobs 2399*2264Sjacobs /* 2400*2264Sjacobs * ***************************************************************************** 2401*2264Sjacobs * 2402*2264Sjacobs * Function: _manageReferralCredentials() 2403*2264Sjacobs * 2404*2264Sjacobs * Description: This function is called if a referral request is returned by 2405*2264Sjacobs * the origonal LDAP server during the ldap update request call, 2406*2264Sjacobs * eg. ldap_add_s(), ldap_modify_s() or ldap_delete_s(). 2407*2264Sjacobs * Parameters: 2408*2264Sjacobs * Input: LDAP *ld - LDAP descriptor 2409*2264Sjacobs * int freeit - 0 = first call to get details 2410*2264Sjacobs * - 1 = second call to free details 2411*2264Sjacobs * - -1 = initial store of authentication details 2412*2264Sjacobs * Input/Output: char **dn - returns DN to bind to on master 2413*2264Sjacobs * char **credp - returns password for DN 2414*2264Sjacobs * int *methodp - returns authentication type, eg. simple 2415*2264Sjacobs * 2416*2264Sjacobs * Returns: int - 0 = okay 2417*2264Sjacobs * 2418*2264Sjacobs * ***************************************************************************** 2419*2264Sjacobs */ 2420*2264Sjacobs static int _manageReferralCredentials(LDAP *ld, char **dn, char **credp, 2421*2264Sjacobs int *methodp, int freeit) 2422*2264Sjacobs 2423*2264Sjacobs { 2424*2264Sjacobs int result = 0; 2425*2264Sjacobs static char *sDN = NULL; 2426*2264Sjacobs static char *sPasswd = NULL; 2427*2264Sjacobs static int sMethod = LDAP_AUTH_SIMPLE; 2428*2264Sjacobs 2429*2264Sjacobs /* -------- */ 2430*2264Sjacobs 2431*2264Sjacobs if (freeit == 1) 2432*2264Sjacobs { 2433*2264Sjacobs /* second call - free memory */ 2434*2264Sjacobs 2435*2264Sjacobs if ((dn != NULL) && (*dn != NULL)) 2436*2264Sjacobs { 2437*2264Sjacobs free(*dn); 2438*2264Sjacobs } 2439*2264Sjacobs 2440*2264Sjacobs if ((credp != NULL) && (*credp != NULL)) 2441*2264Sjacobs { 2442*2264Sjacobs free(*credp); 2443*2264Sjacobs } 2444*2264Sjacobs } 2445*2264Sjacobs 2446*2264Sjacobs else 2447*2264Sjacobs if ((ld != NULL) && 2448*2264Sjacobs (dn != NULL) && (credp != NULL) && (methodp != NULL)) 2449*2264Sjacobs { 2450*2264Sjacobs if ((freeit == 0) && (sDN != NULL) && (sPasswd != NULL)) 2451*2264Sjacobs { 2452*2264Sjacobs /* first call - get the saved bind credentials */ 2453*2264Sjacobs 2454*2264Sjacobs *dn = strdup(sDN); 2455*2264Sjacobs *credp = strdup(sPasswd); 2456*2264Sjacobs *methodp = sMethod; 2457*2264Sjacobs } 2458*2264Sjacobs else 2459*2264Sjacobs if (freeit == -1) 2460*2264Sjacobs { 2461*2264Sjacobs /* initial call - save the saved bind credentials */ 2462*2264Sjacobs 2463*2264Sjacobs sDN = *dn; 2464*2264Sjacobs sPasswd = *credp; 2465*2264Sjacobs sMethod = *methodp; 2466*2264Sjacobs } 2467*2264Sjacobs else 2468*2264Sjacobs { 2469*2264Sjacobs result = 1; /* error */ 2470*2264Sjacobs } 2471*2264Sjacobs } 2472*2264Sjacobs else 2473*2264Sjacobs { 2474*2264Sjacobs result = 1; /* error */ 2475*2264Sjacobs } 2476*2264Sjacobs 2477*2264Sjacobs return (result); 2478*2264Sjacobs } /* _manageReferralCredentials */ 2479