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