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.
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.
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]
23 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2012 Milan Jurik. All rights reserved.
28 #include <sys/types.h>
44 #include "ns_internal.h"
45 #include "ns_connmgmt.h"
46 #include "ns_cache_door.h"
48 /* Additional headers for addTypedEntry Conversion routines */
53 #include <netinet/in.h>
54 #include <arpa/inet.h>
56 #include <rpc/rpcent.h>
57 #include <auth_attr.h>
58 #include <exec_attr.h>
59 #include <prof_attr.h>
60 #include <user_attr.h>
61 #include <bsm/libbsm.h>
63 static int send_to_cachemgr(const char *,
64 ns_ldap_attr_t
**, ns_ldap_error_t
**);
66 static int escape_str(char *, char *);
69 * If the rdn is a mapped attr:
70 * return NS_LDAP_SUCCESS and a new_dn.
71 * If no mapped attr is found in the rdn:
72 * return NS_LDAP_SUCCESS and *new_dn == NULL
75 * dn = cn=foo,dc=bar,dc=com
76 * attributeMapping: abc:cn=sn
78 * new_dn = sn=foo,dc=bar,dc=com
82 replace_mapped_attr_in_dn(
83 const char *service
, const char *dn
, char **new_dn
)
86 char **dnArray
= NULL
;
89 int len
= 0, orig_len
= 0, mapped_len
= 0;
95 * separate dn into individual componets
97 * "automountKey=user_01" , "automountMapName_test=auto_home", ...
99 dnArray
= ldap_explode_dn(dn
, 0);
100 if (!dnArray
|| !*dnArray
)
101 return (NS_LDAP_INVALID_PARAM
);
103 cur
= strchr(dnArray
[0], '=');
105 __s_api_free2dArray(dnArray
);
106 return (NS_LDAP_INVALID_PARAM
);
110 /* we only check schema mapping for automount, not for auto_* */
111 if (strncasecmp(service
, NS_LDAP_TYPE_AUTOMOUNT
,
112 sizeof (NS_LDAP_TYPE_AUTOMOUNT
) - 1) == 0)
113 rservice
= "automount";
115 rservice
= (char *)service
;
117 mappedattr
= __ns_ldap_getMappedAttributes(rservice
, dnArray
[0]);
118 if (!mappedattr
|| !mappedattr
[0]) {
119 __s_api_free2dArray(dnArray
);
121 __s_api_free2dArray(mappedattr
);
122 return (NS_LDAP_SUCCESS
);
124 orig_len
= strlen(dnArray
[0]);
127 * The new length is *dn length + (difference between
128 * orig attr and mapped attr) + 1 ;
130 * automountKey=aa,automountMapName=auto_home,dc=foo,dc=com
132 * cn=aa,automountMapName=auto_home,dc=foo,dc=com
134 mapped_len
= strlen(mappedattr
[0]);
136 len
= dn_len
- orig_len
+ mapped_len
+ 1;
137 *new_dn
= (char *)calloc(1, len
);
138 if (*new_dn
== NULL
) {
139 __s_api_free2dArray(dnArray
);
140 __s_api_free2dArray(mappedattr
);
141 return (NS_LDAP_MEMORY
);
144 (void) snprintf(*new_dn
, len
, "%s=%s", mappedattr
[0], dn
+ orig_len
+1);
145 __s_api_free2dArray(dnArray
);
146 __s_api_free2dArray(mappedattr
);
148 return (NS_LDAP_SUCCESS
);
153 * The following function is only used by the
154 * "gecos" 1 to N attribute mapping code. It expects
155 * and handle only one data/length pair.
166 struct berval
**bmodval
;
168 /* dup attribute name */
169 mod
->mod_type
= strdup(mtype
);
170 if (mod
->mod_type
== NULL
)
174 * assume single value,
175 * since only one value/length pair passed in
177 bmodval
= (struct berval
**)calloc(2, sizeof (struct berval
*));
178 if (bmodval
== NULL
) {
180 mod
->mod_type
= NULL
;
183 bmodval
[0] = (struct berval
*)calloc(1, sizeof (struct berval
));
184 if (bmodval
[0] == NULL
) {
186 mod
->mod_type
= NULL
;
191 /* set pointer to data */
192 bmodval
[0]->bv_val
= mvptr
;
195 bmodval
[0]->bv_len
= mvlen
;
198 * turn on the BVALUE bit to indicate
199 * that the length of data is supplied
201 mod
->mod_op
= mop
| LDAP_MOD_BVALUES
;
203 mod
->mod_bvalues
= bmodval
;
209 freeModList(LDAPMod
**mods
)
217 for (i
= 0; mods
[i
]; i
++) {
219 /* free attribute name */
221 if (mods
[i
]->mod_type
) {
222 if (strcasecmp(mods
[i
]->mod_type
, "objectclass") == 0)
224 free(mods
[i
]->mod_type
);
227 if (mods
[i
]->mod_bvalues
== NULL
)
230 * LDAP_MOD_BVALUES is only set by
231 * the "gecos" 1 to N attribute mapping
232 * code, and the attribute is single valued.
234 if (mods
[i
]->mod_op
& LDAP_MOD_BVALUES
) {
235 free(mods
[i
]->mod_bvalues
[0]);
239 * only values for the "objectclass"
240 * were dupped using strdup.
241 * other attribute values were
242 * not dupped, but via pointer
243 * assignment. So here the
244 * values for "objectclass"
245 * is freed one by one,
246 * but the values for other
247 * attributes need not be freed.
249 for (j
= 0; mods
[i
]->mod_values
[j
]; j
++)
250 free(mods
[i
]->mod_values
[j
]);
254 free(mods
[i
]->mod_bvalues
);
258 free((char *)(mods
[0]));
263 __s_api_makeModListCount(
265 const ns_ldap_attr_t
* const *attr
,
270 LDAPMod
**mods
, *modlist
;
276 char *c
, *comma1
= NULL
, *comma2
= NULL
;
277 int schema_mapping_existed
= FALSE
;
278 int auto_service
= FALSE
;
282 * add 2 for "gecos" 1 to up to 3 attribute mapping
284 mods
= (LDAPMod
**)calloc((count
+ 3), sizeof (LDAPMod
*));
289 * add 2 for "gecos" 1 to up to 3 attribute mapping
291 modlist
= (LDAPMod
*)calloc(count
+ 2, sizeof (LDAPMod
));
292 if (modlist
== NULL
) {
297 if (service
!= NULL
&& strncasecmp(service
, NS_LDAP_TYPE_AUTOMOUNT
,
298 sizeof (NS_LDAP_TYPE_AUTOMOUNT
) - 1) == 0)
302 * see if schema mapping existed for the given service
304 mapping
= __ns_ldap_getOrigAttribute(service
,
305 NS_HASH_SCHEMA_MAPPING_EXISTED
);
307 schema_mapping_existed
= TRUE
;
308 __s_api_free2dArray(mapping
);
312 for (i
= 0, k
= 0; k
< count
&& attr
[k
] != NULL
; i
++, k
++) {
313 mods
[i
] = &modlist
[i
];
314 mods
[i
]->mod_op
= mod_op
;
316 * Perform attribute mapping if necessary.
318 if (schema_mapping_existed
&& (flags
& NS_LDAP_NOMAP
) == 0) {
319 mapping
= __ns_ldap_getMappedAttributes(service
,
324 if (mapping
== NULL
&& auto_service
&&
325 (flags
& NS_LDAP_NOMAP
) == 0) {
327 * if service == auto_xxx and
328 * no mapped attribute is found
329 * and NS_LDAP_NOMAP is not set
330 * then try automount's mapped attribute
332 mapping
= __ns_ldap_getMappedAttributes("automount",
336 if (mapping
== NULL
) {
337 mods
[i
]->mod_type
= strdup(attr
[k
]->attrname
);
338 if (mods
[i
]->mod_type
== NULL
)
342 * 1 to N attribute mapping is only done for "gecos",
343 * and only 1 to 3 mapping.
346 * A. attrMap=passwd:gecos=a
347 * 1. gecos="xx,yy,zz" -> a="xx,yy,zz"
348 * 2. gecos="xx,yy" -> a="xx,yy"
349 * 3. gecos="xx" -> a="xx"
351 * B. attrMap=passwd:gecos=a b
352 * 4. gecos="xx,yy,zz" -> a="xx" b="yy,zz"
353 * 5. gecos="xx,yy" -> a="xx" b="yy"
354 * 6. gecos="xx" -> a="xx"
356 * C. attrMap=passwd:gecos=a b c
357 * 7. gecos="xx,yy,zz" -> a="xx" b="yy" c="zz"
358 * 8. gecos="xx,yy" -> a="xx" b="yy"
359 * 9. gecos="xx" -> a="xx"
361 * This can be grouped as:
363 * c1 cases: 1,2,3,6,9
364 * if ((attrMap=passwd:gecos=a) ||
365 * (no "," in gecos value))
366 * same as other no-mapping attributes,
367 * no special processing needed
371 * if ((attrMap=passwd:gecos=a b) ||
372 * (only one "," in gecos value))
379 * notes: in case c2 and c3, ... could still contain ","
381 if (strcasecmp(service
, "passwd") == 0 &&
382 strcasecmp(attr
[k
]->attrname
, "gecos") == 0 &&
383 mapping
[1] && attr
[k
]->attrvalue
[0] &&
384 (comma1
= strchr(attr
[k
]->attrvalue
[0],
385 COMMATOK
)) != NULL
) {
387 /* is there a second comma? */
388 if (*(comma1
+ 1) != '\0')
389 comma2
= strchr(comma1
+ 1, COMMATOK
);
392 * Process case c2 or c3.
393 * case c2: mapped to two attributes or just
396 if (mapping
[2] == NULL
|| comma2
== NULL
) {
400 * int mod structure for the first attribute
402 vlen
= comma1
- attr
[k
]->attrvalue
[0];
403 c
= attr
[k
]->attrvalue
[0];
406 rc
= init_bval_mod(mods
[i
], mod_op
,
407 mapping
[0], c
, vlen
);
411 /* don't leave a hole in mods array */
418 * init mod structure for the 2nd attribute
420 if (*(comma1
+ 1) == '\0') {
421 __s_api_free2dArray(mapping
);
427 mods
[i
] = &modlist
[i
];
430 * get pointer to data.
431 * Skip leading spaces.
433 for (c
= comma1
+ 1; *c
== SPACETOK
; c
++) {
437 /* get data length */
438 vlen
= strlen(attr
[k
]->attrvalue
[0]) -
439 (c
- attr
[k
]->attrvalue
[0]);
442 rc
= init_bval_mod(mods
[i
], mod_op
,
443 mapping
[1], c
, vlen
);
447 /* don't leave a hole in mods array */
452 /* done with the mapping array */
453 __s_api_free2dArray(mapping
);
461 * int mod structure for the first attribute
463 vlen
= comma1
- attr
[k
]->attrvalue
[0];
464 c
= attr
[k
]->attrvalue
[0];
467 rc
= init_bval_mod(mods
[i
], mod_op
,
468 mapping
[0], c
, vlen
);
472 /* don't leave a hole in mods array */
478 * init mod structure for the 2nd attribute
481 mods
[i
] = &modlist
[i
];
484 * get pointer to data.
485 * Skip leading spaces.
487 for (c
= comma1
+ 1; *c
== SPACETOK
; c
++) {
491 /* get data length */
495 rc
= init_bval_mod(mods
[i
], mod_op
,
496 mapping
[1], c
, vlen
);
500 /* don't leave a hole in mods array */
506 * init mod structure for the 3rd attribute
508 if (*(comma2
+ 1) == '\0') {
509 __s_api_free2dArray(mapping
);
515 mods
[i
] = &modlist
[i
];
517 * get pointer to data.
518 * Skip leading spaces.
520 for (c
= comma2
+ 1; *c
== SPACETOK
; c
++) {
524 /* get data length */
525 vlen
= strlen(attr
[k
]->attrvalue
[0]) -
526 (c
- attr
[k
]->attrvalue
[0]);
529 rc
= init_bval_mod(mods
[i
], mod_op
,
530 mapping
[2], c
, vlen
);
534 /* don't leave a hole in mods array */
539 /* done with the mapping array */
540 __s_api_free2dArray(mapping
);
548 mods
[i
]->mod_type
= strdup(mapping
[0]);
549 if (mods
[i
]->mod_type
== NULL
) {
552 __s_api_free2dArray(mapping
);
556 modval
= (char **)calloc(attr
[k
]->value_count
+1,
561 * Perform objectclass mapping.
562 * Note that the values for the "objectclass" attribute
563 * will be dupped using strdup. Values for other
564 * attributes will be referenced via pointer
567 if (strcasecmp(mods
[i
]->mod_type
, "objectclass") == 0) {
568 for (j
= 0; j
< attr
[k
]->value_count
; j
++) {
569 if (schema_mapping_existed
&&
570 (flags
& NS_LDAP_NOMAP
) == 0)
572 __ns_ldap_getMappedObjectClass(
573 service
, attr
[k
]->attrvalue
[j
]);
577 if (mapping
== NULL
&& auto_service
&&
578 (flags
& NS_LDAP_NOMAP
) == 0)
580 * if service == auto_xxx and
581 * no mapped objectclass is found
585 __ns_ldap_getMappedObjectClass(
586 "automount", attr
[k
]->attrvalue
[j
]);
588 if (mapping
&& mapping
[0]) {
589 /* assume single mapping */
590 modval
[j
] = strdup(mapping
[0]);
592 modval
[j
] = strdup(attr
[k
]->
595 if (modval
[j
] == NULL
)
599 for (j
= 0; j
< attr
[k
]->value_count
; j
++) {
600 /* ASSIGN NOT COPY */
601 modval
[j
] = attr
[k
]->attrvalue
[j
];
604 mods
[i
]->mod_values
= modval
;
612 __s_api_free2dArray(mapping
);
621 const ns_ldap_attr_t
* const *attr
,
625 ns_ldap_attr_t
**aptr
= (ns_ldap_attr_t
**)attr
;
631 /* count number of attributes */
635 return (__s_api_makeModListCount(service
, attr
, mod_op
, count
, flags
));
639 __s_cvt_freeEntryRdn(ns_ldap_entry_t
**entry
, char **rdn
)
641 if (*entry
!= NULL
) {
642 __ns_ldap_freeEntry(*entry
);
652 * This state machine performs one or more LDAP add/delete/modify
653 * operations to configured LDAP servers.
660 const ns_cred_t
*cred
,
662 ns_ldap_error_t
** errorp
)
664 ConnectionID connectionId
= -1;
665 Connection
*conp
= NULL
;
667 char *target_dn
= NULL
;
668 char errstr
[MAXERROR
];
669 int rc
= NS_LDAP_SUCCESS
;
670 int return_rc
= NS_LDAP_SUCCESS
;
671 int followRef
= FALSE
;
672 int target_dn_allocated
= FALSE
;
676 boolean_t from_get_lderrno
= B_FALSE
;
678 char *err
, *errmsg
= NULL
;
679 /* referrals returned by the LDAP operation */
680 char **referrals
= NULL
;
682 * list of referrals used by the state machine, built from
683 * the referrals variable above
685 ns_referral_info_t
*ref_list
= NULL
;
686 /* current referral */
687 ns_referral_info_t
*current_ref
= NULL
;
688 ns_write_state_t state
= W_INIT
, new_state
, err_state
= W_INIT
;
689 int do_not_fail_if_new_pwd_reqd
= 0;
690 ns_ldap_passwd_status_t pwd_status
= NS_PASSWD_GOOD
;
694 int nopasswd_acct_mgmt
= 0;
695 ns_conn_user_t
*conn_user
= NULL
;
700 /* return the MT connection and free the conn user */
701 if (conn_user
!= NULL
) {
702 if (conn_user
->use_mt_conn
== B_TRUE
) {
703 if (conn_user
->ns_error
!= NULL
) {
704 *errorp
= conn_user
->ns_error
;
705 conn_user
->ns_error
= NULL
;
706 return_rc
= conn_user
->ns_rc
;
708 if (conn_user
->conn_mt
!= NULL
)
709 __s_api_conn_mt_return(
712 __s_api_conn_user_free(conn_user
);
715 if (connectionId
> -1)
716 DropConnection(connectionId
, NS_LDAP_NEW_CONN
);
718 __s_api_deleteRefInfo(ref_list
);
719 if (target_dn
&& target_dn_allocated
)
723 /* see if need to follow referrals */
724 rc
= __s_api_toFollowReferrals(flags
,
726 if (rc
!= NS_LDAP_SUCCESS
) {
732 if (dn
[len
-1] == COMMATOK
)
733 rc
= __s_api_append_default_basedn(
734 dn
, &target_dn
, &target_dn_allocated
,
738 if (rc
!= NS_LDAP_SUCCESS
) {
743 new_state
= GET_CONNECTION
;
746 /* identify self as a write user */
747 conn_user
= __s_api_conn_user_init(NS_CONN_USER_WRITE
,
749 rc
= __s_api_getConnection(NULL
,
750 flags
, cred
, &connectionId
, &conp
, errorp
,
751 do_not_fail_if_new_pwd_reqd
, nopasswd_acct_mgmt
,
755 * If password control attached
757 * e.g. rc == NS_LDAP_SUCCESS_WITH_INFO,
758 * free the error structure (we do not need
759 * the password management info).
760 * Reset rc to NS_LDAP_SUCCESS.
762 if (rc
== NS_LDAP_SUCCESS_WITH_INFO
) {
763 (void) __ns_ldap_freeError(errorp
);
765 rc
= NS_LDAP_SUCCESS
;
768 if (rc
!= NS_LDAP_SUCCESS
) {
774 new_state
= SELECT_OPERATION_ASYNC
;
776 new_state
= SELECT_OPERATION_SYNC
;
778 case SELECT_OPERATION_SYNC
:
779 if (ldap_op
== LDAP_REQ_ADD
)
780 new_state
= DO_ADD_SYNC
;
781 else if (ldap_op
== LDAP_REQ_DELETE
)
782 new_state
= DO_DELETE_SYNC
;
783 else if (ldap_op
== LDAP_REQ_MODIFY
)
784 new_state
= DO_MODIFY_SYNC
;
786 case SELECT_OPERATION_ASYNC
:
787 if (ldap_op
== LDAP_REQ_ADD
)
788 new_state
= DO_ADD_ASYNC
;
789 else if (ldap_op
== LDAP_REQ_DELETE
)
790 new_state
= DO_DELETE_ASYNC
;
791 else if (ldap_op
== LDAP_REQ_MODIFY
)
792 new_state
= DO_MODIFY_ASYNC
;
795 rc
= ldap_add_ext_s(conp
->ld
, target_dn
,
797 new_state
= GET_RESULT_SYNC
;
800 rc
= ldap_delete_ext_s(conp
->ld
, target_dn
,
802 new_state
= GET_RESULT_SYNC
;
805 rc
= ldap_modify_ext_s(conp
->ld
, target_dn
,
807 new_state
= GET_RESULT_SYNC
;
810 rc
= ldap_add_ext(conp
->ld
, target_dn
,
811 mods
, NULL
, NULL
, &msgid
);
812 new_state
= GET_RESULT_ASYNC
;
814 case DO_DELETE_ASYNC
:
815 rc
= ldap_delete_ext(conp
->ld
, target_dn
,
817 new_state
= GET_RESULT_ASYNC
;
819 case DO_MODIFY_ASYNC
:
820 rc
= ldap_modify_ext(conp
->ld
, target_dn
,
821 mods
, NULL
, NULL
, &msgid
);
822 new_state
= GET_RESULT_ASYNC
;
824 case GET_RESULT_SYNC
:
825 if (rc
!= LDAP_SUCCESS
) {
827 (void) ldap_get_lderrno(conp
->ld
,
831 * No need to deal with the error message if
832 * it's an empty string.
834 if (errmsg
!= NULL
&& *errmsg
== '\0')
837 if (errmsg
!= NULL
) {
839 * ldap_get_lderrno does not expect
840 * errmsg to be freed after use, while
841 * ldap_parse_result below does, so set
842 * a flag to indicate source.
844 from_get_lderrno
= B_TRUE
;
847 new_state
= W_LDAP_ERROR
;
849 return_rc
= NS_LDAP_SUCCESS
;
853 case GET_RESULT_ASYNC
:
854 rc
= ldap_result(conp
->ld
, msgid
, 1,
856 /* if no server response, set Errno */
858 (void) ldap_get_option(conp
->ld
,
859 LDAP_OPT_ERROR_NUMBER
, &Errno
);
860 new_state
= W_LDAP_ERROR
;
863 if (rc
== LDAP_RES_ADD
|| rc
== LDAP_RES_MODIFY
||
864 rc
== LDAP_RES_DELETE
) {
865 new_state
= PARSE_RESULT
;
874 * need Errno, referrals, error msg,
875 * and the last "1" is to free
878 rc
= ldap_parse_result(conp
->ld
, res
, &Errno
,
879 NULL
, &errmsg
, &referrals
, NULL
, 1);
881 * free errmsg if it is an empty string
883 if (errmsg
&& *errmsg
== '\0') {
884 ldap_memfree(errmsg
);
888 * If we received referral data, process
890 * - we are configured to follow referrals
891 * - and not already in referral mode (to keep
892 * consistency with search_state_machine()
893 * which follows 1 level of referrals only;
894 * see proc_result_referrals() and
895 * proc_search_references().
897 if (Errno
== LDAP_REFERRAL
&& followRef
&& !ref_list
) {
898 for (i
= 0; referrals
[i
] != NULL
; i
++) {
899 /* add to referral list */
900 rc
= __s_api_addRefInfo(&ref_list
,
901 referrals
[i
], NULL
, NULL
, NULL
,
903 if (rc
!= NS_LDAP_SUCCESS
) {
904 __s_api_deleteRefInfo(ref_list
);
909 ldap_value_free(referrals
);
910 if (ref_list
== NULL
) {
911 if (rc
!= NS_LDAP_MEMORY
)
912 rc
= NS_LDAP_INTERNAL
;
916 new_state
= GET_REFERRAL_CONNECTION
;
917 current_ref
= ref_list
;
920 ldap_memfree(errmsg
);
925 if (Errno
!= LDAP_SUCCESS
) {
926 new_state
= W_LDAP_ERROR
;
928 return_rc
= NS_LDAP_SUCCESS
;
932 case GET_REFERRAL_CONNECTION
:
934 * since we are starting over,
935 * discard the old error info
937 return_rc
= NS_LDAP_SUCCESS
;
939 (void) __ns_ldap_freeError(errorp
);
940 if (connectionId
> -1)
941 DropConnection(connectionId
, NS_LDAP_NEW_CONN
);
943 /* set it up to use a referral connection */
944 if (conn_user
!= NULL
) {
946 * If an MT connection is being used,
947 * return it to the pool.
949 if (conn_user
->conn_mt
!= NULL
)
950 __s_api_conn_mt_return(conn_user
);
952 conn_user
->referral
= B_TRUE
;
954 rc
= __s_api_getConnection(current_ref
->refHost
,
955 0, cred
, &connectionId
, &conp
, errorp
,
956 do_not_fail_if_new_pwd_reqd
,
957 nopasswd_acct_mgmt
, conn_user
);
960 * If password control attached
962 * e.g. rc == NS_LDAP_SUCCESS_WITH_INFO,
963 * free the error structure (we do not need
964 * the password management info).
965 * Reset rc to NS_LDAP_SUCCESS.
967 if (rc
== NS_LDAP_SUCCESS_WITH_INFO
) {
968 (void) __ns_ldap_freeError(errorp
);
970 rc
= NS_LDAP_SUCCESS
;
973 if (rc
!= NS_LDAP_SUCCESS
) {
976 * If current referral is not
977 * available for some reason,
978 * try next referral in the list.
979 * Get LDAP error code from errorp.
981 if (*errorp
!= NULL
) {
982 ns_write_state_t get_ref
=
983 GET_REFERRAL_CONNECTION
;
985 ldap_error
= (*errorp
)->status
;
986 if (ldap_error
== LDAP_BUSY
||
987 ldap_error
== LDAP_UNAVAILABLE
||
989 LDAP_UNWILLING_TO_PERFORM
||
990 ldap_error
== LDAP_CONNECT_ERROR
||
991 ldap_error
== LDAP_SERVER_DOWN
) {
992 current_ref
= current_ref
->next
;
993 if (current_ref
== NULL
) {
994 /* no more referral to follow */
999 * free errorp before going to
1002 (void) __ns_ldap_freeError(
1008 * free errorp before going to W_ERROR
1010 (void) __ns_ldap_freeError(errorp
);
1014 __s_api_deleteRefInfo(ref_list
);
1016 new_state
= W_ERROR
;
1017 if (conn_user
!= NULL
)
1018 conn_user
->referral
= B_FALSE
;
1021 /* target DN may changed due to referrals */
1022 if (current_ref
->refDN
) {
1023 if (target_dn
&& target_dn_allocated
) {
1026 target_dn_allocated
= FALSE
;
1028 target_dn
= current_ref
->refDN
;
1030 new_state
= SELECT_OPERATION_SYNC
;
1034 * map error code and error message
1035 * to password status if necessary.
1036 * This is to see if password updates
1037 * failed due to password policy or
1038 * password syntax checking.
1042 * check if server supports
1043 * password management
1046 __s_api_contain_passwd_control_oid(
1050 __s_api_set_passwd_status(
1053 * free only if not returned by ldap_get_lderrno
1055 if (!from_get_lderrno
)
1056 ldap_memfree(errmsg
);
1058 from_get_lderrno
= B_FALSE
;
1061 (void) snprintf(errstr
, sizeof (errstr
),
1062 "%s", ldap_err2string(Errno
));
1063 err
= strdup(errstr
);
1064 if (pwd_status
!= NS_PASSWD_GOOD
) {
1065 MKERROR_PWD_MGMT(*errorp
, Errno
, err
,
1068 MKERROR(LOG_INFO
, *errorp
, Errno
, err
, 0);
1070 if (conn_user
!= NULL
&&
1071 (Errno
== LDAP_SERVER_DOWN
||
1072 Errno
== LDAP_CONNECT_ERROR
)) {
1073 __s_api_conn_mt_close(conn_user
, Errno
, errorp
);
1075 return_rc
= NS_LDAP_INTERNAL
;
1080 (void) sprintf(errstr
,
1081 gettext("Internal write State machine exit"
1082 " (state = %d, rc = %d)."),
1083 err_state
, return_rc
);
1084 err
= strdup(errstr
);
1085 MKERROR(LOG_WARNING
, *errorp
, return_rc
, err
, 0);
1090 if (new_state
== W_ERROR
)
1093 if (conn_user
!= NULL
&& conn_user
->bad_mt_conn
== B_TRUE
) {
1094 __s_api_conn_mt_close(conn_user
, 0, NULL
);
1102 * should never be here, the next line is to eliminating
1105 return (NS_LDAP_INTERNAL
);
1112 const char *service
,
1114 const ns_ldap_attr_t
* const *attr
,
1115 const ns_cred_t
*cred
,
1117 ns_ldap_error_t
** errorp
)
1123 (void) fprintf(stderr
, "__ns_ldap_addAttr START\n");
1128 if ((attr
== NULL
) || (*attr
== NULL
) ||
1129 (dn
== NULL
) || (cred
== NULL
))
1130 return (NS_LDAP_INVALID_PARAM
);
1132 mods
= __s_api_makeModList(service
, attr
, LDAP_MOD_ADD
, flags
);
1134 return (NS_LDAP_MEMORY
);
1137 rc
= write_state_machine(LDAP_REQ_MODIFY
,
1138 (char *)dn
, mods
, cred
, flags
, errorp
);
1148 const char *service
,
1150 const ns_ldap_attr_t
* const *attr
,
1151 const ns_cred_t
*cred
,
1153 ns_ldap_error_t
** errorp
)
1159 (void) fprintf(stderr
, "__ns_ldap_delAttr START\n");
1164 if ((attr
== NULL
) || (*attr
== NULL
) ||
1165 (dn
== NULL
) || (cred
== NULL
))
1166 return (NS_LDAP_INVALID_PARAM
);
1168 mods
= __s_api_makeModList(service
, attr
, LDAP_MOD_DELETE
, flags
);
1170 return (NS_LDAP_MEMORY
);
1173 rc
= write_state_machine(LDAP_REQ_MODIFY
,
1174 (char *)dn
, mods
, cred
, flags
, errorp
);
1180 /* Retrieve the admin bind password from the configuration, if allowed. */
1182 get_admin_passwd(ns_cred_t
*cred
, ns_ldap_error_t
**errorp
)
1184 void **paramVal
= NULL
;
1186 char *modparamVal
= NULL
;
1189 * For GSSAPI/Kerberos, host credential is used, no need to get
1190 * admin bind password
1192 if (cred
->auth
.saslmech
== NS_LDAP_SASL_GSSAPI
)
1193 return (NS_LDAP_SUCCESS
);
1196 * Retrieve admin bind password.
1197 * The admin bind password is available
1198 * only in the ldap_cachemgr process as
1199 * they are not exposed outside of that
1203 if ((ldaprc
= __ns_ldap_getParam(NS_LDAP_ADMIN_BINDPASSWD_P
,
1204 ¶mVal
, errorp
)) != NS_LDAP_SUCCESS
)
1206 if (paramVal
== NULL
|| *paramVal
== NULL
) {
1207 rc
= NS_LDAP_CONFIG
;
1208 *errorp
= __s_api_make_error(NS_CONFIG_NODEFAULT
,
1209 gettext("Admin bind password not configured"));
1210 if (*errorp
== NULL
)
1211 rc
= NS_LDAP_MEMORY
;
1214 modparamVal
= dvalue((char *)*paramVal
);
1215 (void) memset(*paramVal
, 0, strlen((char *)*paramVal
));
1216 (void) __ns_ldap_freeParam(¶mVal
);
1217 if (modparamVal
== NULL
|| *((char *)modparamVal
) == '\0') {
1219 rc
= NS_LDAP_CONFIG
;
1220 *errorp
= __s_api_make_error(NS_CONFIG_SYNTAX
,
1221 gettext("bind password not valid"));
1222 if (*errorp
== NULL
)
1223 rc
= NS_LDAP_MEMORY
;
1227 cred
->cred
.unix_cred
.passwd
= modparamVal
;
1228 return (NS_LDAP_SUCCESS
);
1232 __ns_ldap_is_shadow_update_enabled(void)
1234 int **enable_shadow
= NULL
;
1235 ns_ldap_error_t
*errorp
= NULL
;
1237 if (__ns_ldap_getParam(NS_LDAP_ENABLE_SHADOW_UPDATE_P
,
1238 (void ***)&enable_shadow
, &errorp
) != NS_LDAP_SUCCESS
) {
1240 (void) __ns_ldap_freeError(&errorp
);
1243 if ((enable_shadow
!= NULL
&& *enable_shadow
!= NULL
) &&
1244 (*enable_shadow
[0] == NS_LDAP_ENABLE_SHADOW_UPDATE_TRUE
)) {
1245 (void) __ns_ldap_freeParam((void ***)&enable_shadow
);
1248 if (enable_shadow
!= NULL
)
1249 (void) __ns_ldap_freeParam((void ***)&enable_shadow
);
1254 * __ns_ldap_repAttr modifies ldap attributes of the 'dn' entry stored
1255 * on the LDAP server. 'service' indicates the type of database entries
1256 * to modify. When the Native LDAP client is configured with 'shadow update
1257 * enabled', Shadowshadow(4) entries can only be modified by privileged users.
1258 * Such users use the NS_LDAP_UPDATE_SHADOW flag to indicate the call is
1259 * for such a shadow(4) update, which would be forwarded to ldap_cachemgr
1260 * for performing the LDAP modify operation. ldap_cachemgr would call
1261 * this function again and use the special service NS_ADMIN_SHADOW_UPDATE
1262 * to identify itself, so that admin credential would be obtained and
1263 * the actual LDAP modify operation be done.
1268 const char *service
,
1270 const ns_ldap_attr_t
* const *attr
,
1271 const ns_cred_t
*cred
,
1273 ns_ldap_error_t
** errorp
)
1278 boolean_t shadow_update_enabled
= B_FALSE
;
1281 (void) fprintf(stderr
, "__ns_ldap_repAttr START\n");
1286 if (attr
== NULL
|| *attr
== NULL
|| dn
== NULL
)
1287 return (NS_LDAP_INVALID_PARAM
);
1289 /* Privileged shadow modify? */
1290 if ((flags
& NS_LDAP_UPDATE_SHADOW
) != 0 &&
1291 strcmp(service
, "shadow") == 0) {
1293 /* Shadow update enabled ? If not, error out */
1294 shadow_update_enabled
= __ns_ldap_is_shadow_update_enabled();
1295 if (!shadow_update_enabled
) {
1296 *errorp
= __s_api_make_error(NS_CONFIG_NOTALLOW
,
1297 gettext("Shadow Update is not enabled"));
1298 return (NS_LDAP_CONFIG
);
1301 /* privileged shadow modify requires euid 0 or all zone privs */
1302 priv
= (geteuid() == 0);
1304 priv_set_t
*ps
= priv_allocset(); /* caller */
1305 priv_set_t
*zs
; /* zone */
1307 (void) getppriv(PRIV_EFFECTIVE
, ps
);
1308 zs
= priv_str_to_set("zone", ",", NULL
);
1309 priv
= priv_isequalset(ps
, zs
);
1314 return (NS_LDAP_OP_FAILED
);
1316 rc
= send_to_cachemgr(dn
, (ns_ldap_attr_t
**)attr
, errorp
);
1321 return (NS_LDAP_INVALID_PARAM
);
1324 * If service is NS_ADMIN_SHADOW_UPDATE, the caller should be
1325 * ldap_cachemgr. We need to get the admin cred to do work.
1326 * If the caller is not ldap_cachemgr, but use the service
1327 * NS_ADMIN_SHADOW_UPDATE, get_admin_passwd() will fail,
1328 * as the admin cred is not available to the caller.
1330 if (strcmp(service
, NS_ADMIN_SHADOW_UPDATE
) == 0) {
1331 if ((rc
= get_admin_passwd((ns_cred_t
*)cred
, errorp
)) !=
1336 mods
= __s_api_makeModList(service
, attr
, LDAP_MOD_REPLACE
, flags
);
1338 return (NS_LDAP_MEMORY
);
1340 rc
= write_state_machine(LDAP_REQ_MODIFY
,
1341 (char *)dn
, mods
, cred
, flags
, errorp
);
1350 const char *service
,
1352 const ns_ldap_entry_t
*entry
,
1353 const ns_cred_t
*cred
,
1355 ns_ldap_error_t
** errorp
)
1357 char *new_dn
= NULL
;
1358 LDAPMod
**mods
= NULL
;
1359 const ns_ldap_attr_t
* const *attr
;
1364 (void) fprintf(stderr
, "__ns_ldap_addEntry START\n");
1367 if ((entry
== NULL
) || (dn
== NULL
) || (cred
== NULL
))
1368 return (NS_LDAP_INVALID_PARAM
);
1371 /* Construct array of LDAPMod representing attributes of new entry. */
1373 nAttr
= entry
->attr_count
;
1374 attr
= (const ns_ldap_attr_t
* const *)(entry
->attr_pair
);
1375 mods
= __s_api_makeModListCount(service
, attr
, LDAP_MOD_ADD
,
1378 return (NS_LDAP_MEMORY
);
1381 rc
= replace_mapped_attr_in_dn(service
, dn
, &new_dn
);
1382 if (rc
!= NS_LDAP_SUCCESS
) {
1387 rc
= write_state_machine(LDAP_REQ_ADD
,
1388 new_dn
? new_dn
: (char *)dn
, mods
, cred
, flags
, errorp
);
1399 const char *service
,
1401 const ns_cred_t
*cred
,
1403 ns_ldap_error_t
** errorp
)
1408 (void) fprintf(stderr
, "__ns_ldap_delEntry START\n");
1410 if ((dn
== NULL
) || (cred
== NULL
))
1411 return (NS_LDAP_INVALID_PARAM
);
1415 rc
= write_state_machine(LDAP_REQ_DELETE
,
1416 (char *)dn
, NULL
, cred
, flags
, errorp
);
1422 * Add Typed Entry Helper routines
1426 * Add Typed Entry Conversion routines
1430 __s_add_attr(ns_ldap_entry_t
*e
, char *attrname
, char *value
)
1435 a
= (ns_ldap_attr_t
*)calloc(1, sizeof (ns_ldap_attr_t
));
1437 return (NS_LDAP_MEMORY
);
1438 a
->attrname
= strdup(attrname
);
1439 if (a
->attrname
== NULL
)
1440 return (NS_LDAP_MEMORY
);
1441 a
->attrvalue
= (char **)calloc(1, sizeof (char **));
1442 if (a
->attrvalue
== NULL
)
1443 return (NS_LDAP_MEMORY
);
1445 a
->attrvalue
[0] = NULL
;
1448 return (NS_LDAP_MEMORY
);
1449 a
->attrvalue
[0] = v
;
1450 e
->attr_pair
[e
->attr_count
] = a
;
1452 return (NS_LDAP_SUCCESS
);
1456 __s_add_attrlist(ns_ldap_entry_t
*e
, char *attrname
, char **argv
)
1463 a
= (ns_ldap_attr_t
*)calloc(1, sizeof (ns_ldap_attr_t
));
1465 return (NS_LDAP_MEMORY
);
1466 a
->attrname
= strdup(attrname
);
1467 if (a
->attrname
== NULL
)
1468 return (NS_LDAP_MEMORY
);
1470 for (i
= 0, av
= argv
; *av
!= NULL
; av
++, i
++)
1473 a
->attrvalue
= (char **)calloc(i
, sizeof (char *));
1475 if (a
->attrvalue
== NULL
)
1476 return (NS_LDAP_MEMORY
);
1479 for (j
= 0; j
< i
; j
++) {
1480 v
= strdup(argv
[j
]);
1482 return (NS_LDAP_MEMORY
);
1483 a
->attrvalue
[j
] = v
;
1485 e
->attr_pair
[e
->attr_count
] = a
;
1487 return (NS_LDAP_SUCCESS
);
1490 static ns_ldap_entry_t
*
1491 __s_mk_entry(char **objclass
, int max_attr
)
1494 e
= (ns_ldap_entry_t
*)calloc(1, sizeof (ns_ldap_entry_t
));
1497 /* allocate attributes, +1 for objectclass, +1 for NULL terminator */
1498 e
->attr_pair
= (ns_ldap_attr_t
**)
1499 calloc(max_attr
+ 2, sizeof (ns_ldap_attr_t
*));
1500 if (e
->attr_pair
== NULL
) {
1505 if (__s_add_attrlist(e
, "objectClass", objclass
) != NS_LDAP_SUCCESS
) {
1515 * Conversion: passwd
1516 * Input format: struct passwd
1517 * Exported objectclass: posixAccount
1520 __s_cvt_passwd(const void *data
, char **rdn
,
1521 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
1526 /* routine specific */
1530 static char *oclist
[] = {
1538 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
1539 return (NS_LDAP_OP_FAILED
);
1540 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
1542 return (NS_LDAP_MEMORY
);
1544 /* Convert the structure */
1545 ptr
= (struct passwd
*)data
;
1547 if (ptr
->pw_name
== NULL
|| ptr
->pw_uid
> MAXUID
||
1548 ptr
->pw_gid
> MAXUID
|| ptr
->pw_dir
== NULL
) {
1549 __ns_ldap_freeEntry(e
);
1551 return (NS_LDAP_INVALID_PARAM
);
1554 /* Create an appropriate rdn */
1555 (void) snprintf(trdn
, RDNSIZE
, "uid=%s", ptr
->pw_name
);
1556 *rdn
= strdup(trdn
);
1558 __ns_ldap_freeEntry(e
);
1560 return (NS_LDAP_MEMORY
);
1563 /* Error check the data and add the attributes */
1564 rc
= __s_add_attr(e
, "uid", ptr
->pw_name
);
1565 if (rc
!= NS_LDAP_SUCCESS
) {
1566 __s_cvt_freeEntryRdn(entry
, rdn
);
1569 rc
= __s_add_attr(e
, "cn", ptr
->pw_name
);
1570 if (rc
!= NS_LDAP_SUCCESS
) {
1571 __s_cvt_freeEntryRdn(entry
, rdn
);
1575 if (ptr
->pw_passwd
!= NULL
&&
1576 ptr
->pw_passwd
[0] != '\0') {
1577 rc
= __s_add_attr(e
, "userPassword", ptr
->pw_passwd
);
1578 if (rc
!= NS_LDAP_SUCCESS
) {
1579 __s_cvt_freeEntryRdn(entry
, rdn
);
1584 (void) sprintf(ibuf
, "%u", ptr
->pw_uid
);
1585 rc
= __s_add_attr(e
, "uidNumber", ibuf
);
1586 if (rc
!= NS_LDAP_SUCCESS
) {
1587 __s_cvt_freeEntryRdn(entry
, rdn
);
1591 (void) sprintf(ibuf
, "%u", ptr
->pw_gid
);
1592 rc
= __s_add_attr(e
, "gidNumber", ibuf
);
1593 if (rc
!= NS_LDAP_SUCCESS
) {
1594 __s_cvt_freeEntryRdn(entry
, rdn
);
1597 if (ptr
->pw_gecos
!= NULL
&&
1598 ptr
->pw_gecos
[0] != '\0') {
1599 rc
= __s_add_attr(e
, "gecos", ptr
->pw_gecos
);
1600 if (rc
!= NS_LDAP_SUCCESS
) {
1601 __s_cvt_freeEntryRdn(entry
, rdn
);
1606 rc
= __s_add_attr(e
, "homeDirectory", ptr
->pw_dir
);
1607 if (rc
!= NS_LDAP_SUCCESS
) {
1608 __s_cvt_freeEntryRdn(entry
, rdn
);
1611 if (ptr
->pw_shell
!= NULL
&&
1612 ptr
->pw_shell
[0] != '\0') {
1613 rc
= __s_add_attr(e
, "loginShell", ptr
->pw_shell
);
1614 if (rc
!= NS_LDAP_SUCCESS
) {
1615 __s_cvt_freeEntryRdn(entry
, rdn
);
1620 return (NS_LDAP_SUCCESS
);
1624 * escape_str function escapes special characters in str and
1625 * copies to escstr string.
1627 * return 0 for successful
1630 static int escape_str(char *escstr
, char *str
)
1634 while ((*str
!= '\0') && (index
< (RDNSIZE
- 1))) {
1635 if (*str
== '+' || *str
== ';' || *str
== '>' ||
1636 *str
== '<' || *str
== ',' || *str
== '"' ||
1637 *str
== '\\' || *str
== '=' ||
1638 (*str
== '#' && index
== 0)) {
1657 * Conversion: project
1658 * Input format: struct project
1659 * Exported objectclass: SolarisProject
1662 __s_cvt_project(const void *data
, char **rdn
,
1663 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
1669 /* routine specific */
1670 struct project
*ptr
;
1673 static char *oclist
[] = {
1679 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
1680 return (NS_LDAP_OP_FAILED
);
1682 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
1684 return (NS_LDAP_MEMORY
);
1686 /* Convert the structure */
1687 ptr
= (struct project
*)data
;
1689 if (ptr
->pj_name
== NULL
|| ptr
->pj_projid
> MAXUID
) {
1690 __ns_ldap_freeEntry(e
);
1692 return (NS_LDAP_INVALID_PARAM
);
1695 /* Create an appropriate rdn */
1696 (void) snprintf(trdn
, RDNSIZE
, "SolarisProjectName=%s", ptr
->pj_name
);
1697 *rdn
= strdup(trdn
);
1699 __ns_ldap_freeEntry(e
);
1701 return (NS_LDAP_MEMORY
);
1704 /* Error check the data and add the attributes */
1707 rc
= __s_add_attr(e
, "SolarisProjectName", ptr
->pj_name
);
1708 if (rc
!= NS_LDAP_SUCCESS
) {
1709 __s_cvt_freeEntryRdn(entry
, rdn
);
1715 * ibuf is 11 chars big, which should be enough for string
1716 * representation of 32bit number + nul-car
1718 if (snprintf(ibuf
, sizeof (ibuf
), "%u", ptr
->pj_projid
) < 0) {
1719 __s_cvt_freeEntryRdn(entry
, rdn
);
1720 return (NS_LDAP_INVALID_PARAM
);
1722 rc
= __s_add_attr(e
, "SolarisProjectID", ibuf
);
1723 if (rc
!= NS_LDAP_SUCCESS
) {
1724 __s_cvt_freeEntryRdn(entry
, rdn
);
1728 /* Comment/Description */
1729 if (ptr
->pj_comment
!= NULL
&& ptr
->pj_comment
[0] != '\0') {
1730 rc
= __s_add_attr(e
, "description", ptr
->pj_comment
);
1731 if (rc
!= NS_LDAP_SUCCESS
) {
1732 __s_cvt_freeEntryRdn(entry
, rdn
);
1738 if (ptr
->pj_attr
!= NULL
&& ptr
->pj_attr
[0] != '\0') {
1739 rc
= __s_add_attr(e
, "SolarisProjectAttr", ptr
->pj_attr
);
1740 if (rc
!= NS_LDAP_SUCCESS
) {
1741 __s_cvt_freeEntryRdn(entry
, rdn
);
1747 if (ptr
->pj_users
!= NULL
) {
1748 rc
= __s_add_attrlist(e
, "memberUid", ptr
->pj_users
);
1749 if (rc
!= NS_LDAP_SUCCESS
) {
1750 __s_cvt_freeEntryRdn(entry
, rdn
);
1756 if (ptr
->pj_groups
!= NULL
) {
1757 rc
= __s_add_attrlist(e
, "memberGid", ptr
->pj_groups
);
1758 if (rc
!= NS_LDAP_SUCCESS
) {
1759 __s_cvt_freeEntryRdn(entry
, rdn
);
1766 return (NS_LDAP_SUCCESS
);
1769 * Conversion: shadow
1770 * Input format: struct shadow
1771 * Exported objectclass: shadowAccount
1774 __s_cvt_shadow(const void *data
, char **rdn
,
1775 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
1780 /* routine specific */
1784 static char *oclist
[] = {
1792 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
1793 return (NS_LDAP_OP_FAILED
);
1794 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
1796 return (NS_LDAP_MEMORY
);
1798 /* Convert the structure */
1799 ptr
= (struct spwd
*)data
;
1801 if (ptr
->sp_namp
== NULL
) {
1802 __ns_ldap_freeEntry(e
);
1804 return (NS_LDAP_INVALID_PARAM
);
1807 /* Create an appropriate rdn */
1808 (void) snprintf(trdn
, RDNSIZE
, "uid=%s", ptr
->sp_namp
);
1809 *rdn
= strdup(trdn
);
1811 __ns_ldap_freeEntry(e
);
1813 return (NS_LDAP_MEMORY
);
1816 /* Error check the data and add the attributes */
1817 rc
= __s_add_attr(e
, "uid", ptr
->sp_namp
);
1818 if (rc
!= NS_LDAP_SUCCESS
) {
1819 __s_cvt_freeEntryRdn(entry
, rdn
);
1823 if (ptr
->sp_pwdp
== NULL
) {
1824 __s_cvt_freeEntryRdn(entry
, rdn
);
1825 return (NS_LDAP_INVALID_PARAM
);
1827 rc
= __s_add_attr(e
, "userPassword", ptr
->sp_pwdp
);
1828 if (rc
!= NS_LDAP_SUCCESS
) {
1829 __s_cvt_freeEntryRdn(entry
, rdn
);
1833 if (ptr
->sp_lstchg
>= 0) {
1834 (void) sprintf(ibuf
, "%d", ptr
->sp_lstchg
);
1835 rc
= __s_add_attr(e
, "shadowLastChange", ibuf
);
1836 if (rc
!= NS_LDAP_SUCCESS
) {
1837 __s_cvt_freeEntryRdn(entry
, rdn
);
1841 if (ptr
->sp_min
>= 0) {
1842 (void) sprintf(ibuf
, "%d", ptr
->sp_min
);
1843 rc
= __s_add_attr(e
, "shadowMin", ibuf
);
1844 if (rc
!= NS_LDAP_SUCCESS
) {
1845 __s_cvt_freeEntryRdn(entry
, rdn
);
1849 if (ptr
->sp_max
>= 0) {
1850 (void) sprintf(ibuf
, "%d", ptr
->sp_max
);
1851 rc
= __s_add_attr(e
, "shadowMax", ibuf
);
1852 if (rc
!= NS_LDAP_SUCCESS
) {
1853 __s_cvt_freeEntryRdn(entry
, rdn
);
1857 if (ptr
->sp_warn
>= 0) {
1858 (void) sprintf(ibuf
, "%d", ptr
->sp_warn
);
1859 rc
= __s_add_attr(e
, "shadowWarning", ibuf
);
1860 if (rc
!= NS_LDAP_SUCCESS
) {
1861 __s_cvt_freeEntryRdn(entry
, rdn
);
1865 if (ptr
->sp_inact
>= 0) {
1866 (void) sprintf(ibuf
, "%d", ptr
->sp_inact
);
1867 rc
= __s_add_attr(e
, "shadowInactive", ibuf
);
1868 if (rc
!= NS_LDAP_SUCCESS
) {
1869 __s_cvt_freeEntryRdn(entry
, rdn
);
1873 if (ptr
->sp_expire
>= 0) {
1874 (void) sprintf(ibuf
, "%d", ptr
->sp_expire
);
1875 rc
= __s_add_attr(e
, "shadowExpire", ibuf
);
1876 if (rc
!= NS_LDAP_SUCCESS
) {
1877 __s_cvt_freeEntryRdn(entry
, rdn
);
1881 (void) sprintf(ibuf
, "%d", ptr
->sp_flag
);
1882 rc
= __s_add_attr(e
, "shadowFlag", ibuf
);
1883 if (rc
!= NS_LDAP_SUCCESS
) {
1884 __s_cvt_freeEntryRdn(entry
, rdn
);
1888 return (NS_LDAP_SUCCESS
);
1894 * Input format: struct group
1895 * Exported objectclass: posixGroup
1898 __s_cvt_group(const void *data
, char **rdn
,
1899 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
1904 /* routine specific */
1910 static char *oclist
[] = {
1916 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
1917 return (NS_LDAP_OP_FAILED
);
1918 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
1920 return (NS_LDAP_MEMORY
);
1922 /* Convert the structure */
1923 ptr
= (struct group
*)data
;
1925 if (ptr
->gr_name
== NULL
|| ptr
->gr_gid
> MAXUID
) {
1926 __ns_ldap_freeEntry(e
);
1928 return (NS_LDAP_INVALID_PARAM
);
1931 /* Create an appropriate rdn */
1932 (void) snprintf(trdn
, RDNSIZE
, "cn=%s", ptr
->gr_name
);
1933 *rdn
= strdup(trdn
);
1935 __ns_ldap_freeEntry(e
);
1937 return (NS_LDAP_MEMORY
);
1940 /* Error check the data and add the attributes */
1941 rc
= __s_add_attr(e
, "cn", ptr
->gr_name
);
1942 if (rc
!= NS_LDAP_SUCCESS
) {
1943 __s_cvt_freeEntryRdn(entry
, rdn
);
1947 (void) sprintf(ibuf
, "%u", ptr
->gr_gid
);
1948 rc
= __s_add_attr(e
, "gidNumber", ibuf
);
1949 if (rc
!= NS_LDAP_SUCCESS
) {
1950 __s_cvt_freeEntryRdn(entry
, rdn
);
1953 if (ptr
->gr_passwd
&& ptr
->gr_passwd
[0] != '\0') {
1954 rc
= __s_add_attr(e
, "userPassword", ptr
->gr_passwd
);
1955 if (rc
!= NS_LDAP_SUCCESS
) {
1956 __s_cvt_freeEntryRdn(entry
, rdn
);
1961 if (ptr
->gr_mem
&& ptr
->gr_mem
[0]) {
1963 for (i
= 0; *lm
; i
++, lm
++)
1966 nm
= (char **)calloc(i
+2, sizeof (char *));
1968 __s_cvt_freeEntryRdn(entry
, rdn
);
1969 return (NS_LDAP_MEMORY
);
1971 for (j
= 0; j
< i
; j
++) {
1972 nm
[j
] = strdup(lm
[j
]);
1973 if (nm
[j
] == NULL
) {
1974 for (k
= 0; k
< j
; k
++)
1977 __s_cvt_freeEntryRdn(entry
, rdn
);
1978 return (NS_LDAP_MEMORY
);
1981 rc
= __s_add_attrlist(e
, "memberUid", nm
);
1982 for (j
= 0; j
< i
; j
++) {
1987 if (rc
!= NS_LDAP_SUCCESS
) {
1988 __s_cvt_freeEntryRdn(entry
, rdn
);
1993 return (NS_LDAP_SUCCESS
);
1998 * Input format: struct hostent
1999 * Exported objectclass: ipHost
2002 __s_cvt_hosts(const void *data
, char **rdn
,
2003 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2008 /* routine specific */
2009 struct hostent
*ptr
;
2013 static char *oclist
[] = {
2020 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
2021 return (NS_LDAP_OP_FAILED
);
2022 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
2024 return (NS_LDAP_MEMORY
);
2026 /* Convert the structure */
2027 ptr
= (struct hostent
*)data
;
2029 if (ptr
->h_name
== NULL
||
2030 ptr
->h_addr_list
== NULL
|| ptr
->h_addr_list
[0] == '\0') {
2031 __ns_ldap_freeEntry(e
);
2033 return (NS_LDAP_INVALID_PARAM
);
2036 /* Create an appropriate rdn */
2037 (void) snprintf(trdn
, RDNSIZE
, "cn=%s+ipHostNumber=%s",
2038 ptr
->h_name
, ptr
->h_addr_list
[0]);
2039 *rdn
= strdup(trdn
);
2041 __ns_ldap_freeEntry(e
);
2043 return (NS_LDAP_MEMORY
);
2046 /* Error check the data and add the attributes */
2047 if (ptr
->h_aliases
&& ptr
->h_aliases
[0]) {
2048 lm
= ptr
->h_aliases
;
2050 * If there is a description, 'i' will contain
2051 * the index of the description in the aliases list
2053 for (i
= 0; *lm
&& (*lm
)[0] != '#'; i
++, lm
++)
2055 lm
= ptr
->h_aliases
;
2056 nm
= (char **)calloc(i
+2, sizeof (char *));
2058 __s_cvt_freeEntryRdn(entry
, rdn
);
2059 return (NS_LDAP_MEMORY
);
2061 nm
[0] = ptr
->h_name
;
2062 for (j
= 0; j
< i
; j
++)
2063 nm
[j
+1] = ptr
->h_aliases
[j
];
2065 rc
= __s_add_attrlist(e
, "cn", nm
);
2067 if (rc
!= NS_LDAP_SUCCESS
) {
2068 __s_cvt_freeEntryRdn(entry
, rdn
);
2073 if (lm
[i
] && lm
[i
][0] == '#') {
2074 nm
[0] = &(lm
[i
][1]);
2076 rc
= __s_add_attrlist(e
, "description", nm
);
2080 if (rc
!= NS_LDAP_SUCCESS
) {
2081 __s_cvt_freeEntryRdn(entry
, rdn
);
2085 rc
= __s_add_attr(e
, "cn", ptr
->h_name
);
2086 if (rc
!= NS_LDAP_SUCCESS
) {
2087 __s_cvt_freeEntryRdn(entry
, rdn
);
2092 if (ptr
->h_addr_list
&& ptr
->h_addr_list
[0]) {
2093 lm
= ptr
->h_addr_list
;
2094 for (i
= 0; *lm
; i
++, lm
++)
2096 lm
= ptr
->h_addr_list
;
2097 nm
= (char **)calloc(i
+2, sizeof (char *));
2099 __s_cvt_freeEntryRdn(entry
, rdn
);
2100 return (NS_LDAP_MEMORY
);
2102 for (j
= 0; j
< i
; j
++) {
2103 nm
[j
] = strdup(lm
[j
]);
2104 if (nm
[j
] == NULL
) {
2105 for (k
= 0; k
< j
; k
++)
2108 __s_cvt_freeEntryRdn(entry
, rdn
);
2109 return (NS_LDAP_MEMORY
);
2112 rc
= __s_add_attrlist(e
, "ipHostNumber", nm
);
2113 for (j
= 0; j
< i
; j
++) {
2118 if (rc
!= NS_LDAP_SUCCESS
) {
2119 __s_cvt_freeEntryRdn(entry
, rdn
);
2123 __s_cvt_freeEntryRdn(entry
, rdn
);
2124 return (NS_LDAP_INVALID_PARAM
);
2127 return (NS_LDAP_SUCCESS
);
2132 * Input format: struct rpcent
2133 * Exported objectclass: oncRpc
2136 __s_cvt_rpc(const void *data
, char **rdn
,
2137 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2142 /* routine specific */
2148 static char *oclist
[] = {
2154 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
2155 return (NS_LDAP_OP_FAILED
);
2156 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
2158 return (NS_LDAP_MEMORY
);
2160 /* Convert the structure */
2161 ptr
= (struct rpcent
*)data
;
2163 if (ptr
->r_name
== NULL
|| ptr
->r_number
< 0) {
2164 __ns_ldap_freeEntry(e
);
2166 return (NS_LDAP_INVALID_PARAM
);
2169 /* Create an appropriate rdn */
2170 (void) snprintf(trdn
, RDNSIZE
, "cn=%s", ptr
->r_name
);
2171 *rdn
= strdup(trdn
);
2173 __ns_ldap_freeEntry(e
);
2175 return (NS_LDAP_MEMORY
);
2178 /* Error check the data and add the attributes */
2179 if (ptr
->r_aliases
&& ptr
->r_aliases
[0]) {
2180 nm
= ptr
->r_aliases
;
2181 for (i
= 0; *nm
; i
++, nm
++)
2183 nm
= (char **)calloc(i
+2, sizeof (char *));
2185 __s_cvt_freeEntryRdn(entry
, rdn
);
2186 return (NS_LDAP_MEMORY
);
2188 nm
[0] = ptr
->r_name
;
2189 for (j
= 0; j
< i
; j
++)
2190 nm
[j
+1] = ptr
->r_aliases
[j
];
2192 rc
= __s_add_attrlist(e
, "cn", nm
);
2195 if (rc
!= NS_LDAP_SUCCESS
) {
2196 __s_cvt_freeEntryRdn(entry
, rdn
);
2200 rc
= __s_add_attr(e
, "cn", ptr
->r_name
);
2201 if (rc
!= NS_LDAP_SUCCESS
) {
2202 __s_cvt_freeEntryRdn(entry
, rdn
);
2207 if (ptr
->r_number
>= 0) {
2208 (void) sprintf(ibuf
, "%d", ptr
->r_number
);
2209 rc
= __s_add_attr(e
, "oncRpcNumber", ibuf
);
2210 if (rc
!= NS_LDAP_SUCCESS
) {
2211 __s_cvt_freeEntryRdn(entry
, rdn
);
2216 return (NS_LDAP_SUCCESS
);
2221 * Conversion: protocols
2222 * Input format: struct protoent
2223 * Exported objectclass: ipProtocol
2226 __s_cvt_protocols(const void *data
, char **rdn
,
2227 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2232 /* routine specific */
2233 struct protoent
*ptr
;
2238 static char *oclist
[] = {
2244 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
2245 return (NS_LDAP_OP_FAILED
);
2246 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
2248 return (NS_LDAP_MEMORY
);
2250 /* Convert the structure */
2251 ptr
= (struct protoent
*)data
;
2253 if (ptr
->p_name
== NULL
|| ptr
->p_proto
< 0) {
2254 __ns_ldap_freeEntry(e
);
2256 return (NS_LDAP_INVALID_PARAM
);
2259 /* Create an appropriate rdn */
2260 (void) snprintf(trdn
, RDNSIZE
, "cn=%s", ptr
->p_name
);
2261 *rdn
= strdup(trdn
);
2263 __ns_ldap_freeEntry(e
);
2265 return (NS_LDAP_MEMORY
);
2268 /* Error check the data and add the attributes */
2269 if (ptr
->p_aliases
&& ptr
->p_aliases
[0]) {
2270 nm
= ptr
->p_aliases
;
2271 for (i
= 0; *nm
; i
++, nm
++)
2273 nm
= (char **)calloc(i
+2, sizeof (char *));
2275 __s_cvt_freeEntryRdn(entry
, rdn
);
2276 return (NS_LDAP_MEMORY
);
2278 nm
[0] = ptr
->p_name
;
2279 for (j
= 0; j
< i
; j
++)
2280 nm
[j
+1] = ptr
->p_aliases
[j
];
2282 rc
= __s_add_attrlist(e
, "cn", nm
);
2285 if (rc
!= NS_LDAP_SUCCESS
) {
2286 __s_cvt_freeEntryRdn(entry
, rdn
);
2290 rc
= __s_add_attr(e
, "cn", ptr
->p_name
);
2291 if (rc
!= NS_LDAP_SUCCESS
) {
2292 __s_cvt_freeEntryRdn(entry
, rdn
);
2297 (void) sprintf(ibuf
, "%d", ptr
->p_proto
);
2298 rc
= __s_add_attr(e
, "ipProtocolNumber", ibuf
);
2299 if (rc
!= NS_LDAP_SUCCESS
) {
2300 __s_cvt_freeEntryRdn(entry
, rdn
);
2304 return (NS_LDAP_SUCCESS
);
2309 * Conversion: services
2310 * Input format: struct servent
2311 * Exported objectclass: ipService
2314 __s_cvt_services(const void *data
, char **rdn
,
2315 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2320 char esc_str
[RDNSIZE
];
2321 /* routine specific */
2322 struct servent
*ptr
;
2327 static char *oclist
[] = {
2333 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
2334 return (NS_LDAP_OP_FAILED
);
2335 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
2337 return (NS_LDAP_MEMORY
);
2339 /* Convert the structure */
2340 ptr
= (struct servent
*)data
;
2342 if (ptr
->s_name
== NULL
|| ptr
->s_port
< 0 || ptr
->s_proto
== '\0') {
2343 __ns_ldap_freeEntry(e
);
2345 return (NS_LDAP_INVALID_PARAM
);
2349 * Escape special characters in service name.
2351 if (escape_str(esc_str
, ptr
->s_name
) != 0) {
2352 __ns_ldap_freeEntry(e
);
2354 return (NS_LDAP_INVALID_PARAM
);
2357 /* Create an appropriate rdn */
2358 (void) snprintf(trdn
, RDNSIZE
, "cn=%s+ipServiceProtocol=%s",
2359 esc_str
, ptr
->s_proto
);
2361 *rdn
= strdup(trdn
);
2363 __ns_ldap_freeEntry(e
);
2365 return (NS_LDAP_MEMORY
);
2368 /* Error check the data and add the attributes */
2369 if (ptr
->s_aliases
&& ptr
->s_aliases
[0]) {
2370 nm
= ptr
->s_aliases
;
2371 for (i
= 0; *nm
; i
++, nm
++)
2373 nm
= (char **)calloc(i
+2, sizeof (char *));
2375 __s_cvt_freeEntryRdn(entry
, rdn
);
2376 return (NS_LDAP_MEMORY
);
2378 nm
[0] = ptr
->s_name
;
2379 for (j
= 0; j
< i
; j
++)
2380 nm
[j
+1] = ptr
->s_aliases
[j
];
2382 rc
= __s_add_attrlist(e
, "cn", nm
);
2385 if (rc
!= NS_LDAP_SUCCESS
) {
2386 __s_cvt_freeEntryRdn(entry
, rdn
);
2390 rc
= __s_add_attr(e
, "cn", ptr
->s_name
);
2391 if (rc
!= NS_LDAP_SUCCESS
) {
2392 __s_cvt_freeEntryRdn(entry
, rdn
);
2397 (void) sprintf(ibuf
, "%d", ptr
->s_port
);
2398 rc
= __s_add_attr(e
, "ipServicePort", ibuf
);
2399 if (rc
!= NS_LDAP_SUCCESS
) {
2400 __s_cvt_freeEntryRdn(entry
, rdn
);
2403 rc
= __s_add_attr(e
, "ipServiceProtocol", ptr
->s_proto
);
2404 if (rc
!= NS_LDAP_SUCCESS
) {
2405 __s_cvt_freeEntryRdn(entry
, rdn
);
2409 return (NS_LDAP_SUCCESS
);
2413 * Conversion: networks
2414 * Input format: struct netent
2415 * Exported objectclass: ipNetwork
2418 __s_cvt_networks(const void *data
, char **rdn
,
2419 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2424 /* routine specific */
2430 static char *oclist
[] = {
2436 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
2437 return (NS_LDAP_OP_FAILED
);
2438 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
2440 return (NS_LDAP_MEMORY
);
2442 /* Convert the structure */
2443 ptr
= (struct netent
*)data
;
2445 if (ptr
->n_name
== NULL
|| ptr
->n_net
== 0) {
2446 __ns_ldap_freeEntry(e
);
2448 return (NS_LDAP_INVALID_PARAM
);
2451 (void) snprintf(cp
, sizeof (cp
), "%d.%d.%d.%d",
2452 (ptr
->n_net
& 0xFF000000) >> 24,
2453 (ptr
->n_net
& 0x00FF0000) >> 16,
2454 (ptr
->n_net
& 0x0000FF00) >> 8,
2455 (ptr
->n_net
& 0x000000FF));
2457 /* Create an appropriate rdn */
2458 (void) snprintf(trdn
, RDNSIZE
, "ipNetworkNumber=%s", cp
);
2459 *rdn
= strdup(trdn
);
2461 __ns_ldap_freeEntry(e
);
2463 return (NS_LDAP_MEMORY
);
2466 /* Error check the data and add the attributes */
2467 if (ptr
->n_aliases
&& ptr
->n_aliases
[0]) {
2468 nm
= ptr
->n_aliases
;
2469 for (i
= 0; *nm
; i
++, nm
++)
2471 nm
= (char **)calloc(i
+2, sizeof (char *));
2473 __s_cvt_freeEntryRdn(entry
, rdn
);
2474 return (NS_LDAP_MEMORY
);
2476 nm
[0] = ptr
->n_name
;
2477 for (j
= 0; j
< i
; j
++)
2478 nm
[j
+1] = ptr
->n_aliases
[j
];
2480 rc
= __s_add_attrlist(e
, "cn", nm
);
2483 if (rc
!= NS_LDAP_SUCCESS
) {
2484 __s_cvt_freeEntryRdn(entry
, rdn
);
2488 rc
= __s_add_attr(e
, "cn", ptr
->n_name
);
2489 if (rc
!= NS_LDAP_SUCCESS
) {
2490 __s_cvt_freeEntryRdn(entry
, rdn
);
2495 rc
= __s_add_attr(e
, "ipNetworkNumber", cp
);
2496 if (rc
!= NS_LDAP_SUCCESS
) {
2497 __s_cvt_freeEntryRdn(entry
, rdn
);
2501 return (NS_LDAP_SUCCESS
);
2505 * Conversion: netmasks
2506 * Input format: struct _ns_netmasks
2507 * Exported objectclass: ipNetwork
2510 __s_cvt_netmasks(const void *data
, char **rdn
,
2511 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2516 /* routine specific */
2517 struct _ns_netmasks
*ptr
;
2519 static char *oclist
[] = {
2525 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
2526 return (NS_LDAP_OP_FAILED
);
2527 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
2529 return (NS_LDAP_MEMORY
);
2531 /* Convert the structure */
2532 ptr
= (struct _ns_netmasks
*)data
;
2534 if (ptr
->netnumber
== NULL
) {
2535 __ns_ldap_freeEntry(e
);
2537 return (NS_LDAP_INVALID_PARAM
);
2540 /* Create an appropriate rdn */
2541 (void) snprintf(trdn
, RDNSIZE
, "ipNetworkNumber=%s", ptr
->netnumber
);
2542 *rdn
= strdup(trdn
);
2544 __ns_ldap_freeEntry(e
);
2546 return (NS_LDAP_MEMORY
);
2549 /* Error check the data and add the attributes */
2550 rc
= __s_add_attr(e
, "ipNetworkNumber", ptr
->netnumber
);
2551 if (rc
!= NS_LDAP_SUCCESS
) {
2552 __s_cvt_freeEntryRdn(entry
, rdn
);
2556 if (ptr
->netmask
!= '\0') {
2557 rc
= __s_add_attr(e
, "ipNetmaskNumber", ptr
->netmask
);
2558 if (rc
!= NS_LDAP_SUCCESS
) {
2559 __s_cvt_freeEntryRdn(entry
, rdn
);
2564 return (NS_LDAP_SUCCESS
);
2568 * Conversion: netgroups
2569 * Input format: struct _ns_netgroups
2570 * Exported objectclass: nisNetgroup
2573 __s_cvt_netgroups(const void *data
, char **rdn
,
2574 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2579 /* routine specific */
2580 struct _ns_netgroups
*ptr
;
2584 static char *oclist
[] = {
2590 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
2591 return (NS_LDAP_OP_FAILED
);
2592 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
2594 return (NS_LDAP_MEMORY
);
2596 /* Convert the structure */
2597 ptr
= (struct _ns_netgroups
*)data
;
2599 if (ptr
->name
== NULL
) {
2600 __ns_ldap_freeEntry(e
);
2602 return (NS_LDAP_INVALID_PARAM
);
2605 /* Create an appropriate rdn */
2606 (void) snprintf(trdn
, RDNSIZE
, "cn=%s", ptr
->name
);
2607 *rdn
= strdup(trdn
);
2609 __ns_ldap_freeEntry(e
);
2611 return (NS_LDAP_MEMORY
);
2614 if (ptr
->name
!= '\0') {
2615 rc
= __s_add_attr(e
, "cn", ptr
->name
);
2616 if (rc
!= NS_LDAP_SUCCESS
) {
2617 __s_cvt_freeEntryRdn(entry
, rdn
);
2622 /* Error check the data and add the attributes */
2623 if (ptr
->triplet
&& ptr
->triplet
[0]) {
2625 for (i
= 0; *nm
; i
++, nm
++)
2627 nm
= (char **)calloc(i
+2, sizeof (char *));
2629 __s_cvt_freeEntryRdn(entry
, rdn
);
2630 return (NS_LDAP_MEMORY
);
2632 for (j
= 0; j
< i
; j
++)
2633 nm
[j
] = ptr
->triplet
[j
];
2635 rc
= __s_add_attrlist(e
, "nisNetgroupTriple", nm
);
2638 if (rc
!= NS_LDAP_SUCCESS
) {
2639 __s_cvt_freeEntryRdn(entry
, rdn
);
2643 if (ptr
->netgroup
&& ptr
->netgroup
[0]) {
2645 for (i
= 0; *nm
; i
++, nm
++)
2647 nm
= (char **)calloc(i
+2, sizeof (char *));
2649 __s_cvt_freeEntryRdn(entry
, rdn
);
2650 return (NS_LDAP_MEMORY
);
2652 for (j
= 0; j
< i
; j
++)
2653 nm
[j
] = ptr
->netgroup
[j
];
2655 rc
= __s_add_attrlist(e
, "memberNisNetgroup", nm
);
2658 if (rc
!= NS_LDAP_SUCCESS
) {
2659 __s_cvt_freeEntryRdn(entry
, rdn
);
2663 return (NS_LDAP_SUCCESS
);
2666 * Conversion: bootparams
2667 * Input format: struct _ns_bootp
2668 * Exported objectclass: bootableDevice, device
2671 __s_cvt_bootparams(const void *data
, char **rdn
,
2672 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2677 /* routine specific */
2678 struct _ns_bootp
*ptr
;
2682 static char *oclist
[] = {
2689 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
2690 return (NS_LDAP_OP_FAILED
);
2691 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
2693 return (NS_LDAP_MEMORY
);
2695 /* Convert the structure */
2696 ptr
= (struct _ns_bootp
*)data
;
2698 if (ptr
->name
== NULL
) {
2699 __ns_ldap_freeEntry(e
);
2701 return (NS_LDAP_INVALID_PARAM
);
2704 /* Create an appropriate rdn */
2705 (void) snprintf(trdn
, RDNSIZE
, "cn=%s", ptr
->name
);
2706 *rdn
= strdup(trdn
);
2708 __ns_ldap_freeEntry(e
);
2710 return (NS_LDAP_MEMORY
);
2713 if (ptr
->name
!= '\0') {
2714 rc
= __s_add_attr(e
, "cn", ptr
->name
);
2715 if (rc
!= NS_LDAP_SUCCESS
) {
2716 __s_cvt_freeEntryRdn(entry
, rdn
);
2721 /* Error check the data and add the attributes */
2722 if (ptr
->param
&& ptr
->param
[0]) {
2724 for (i
= 0; *nm
; i
++, nm
++)
2726 nm
= (char **)calloc(i
+2, sizeof (char *));
2728 __s_cvt_freeEntryRdn(entry
, rdn
);
2729 return (NS_LDAP_MEMORY
);
2731 for (j
= 0; j
< i
; j
++)
2732 nm
[j
] = ptr
->param
[j
];
2734 rc
= __s_add_attrlist(e
, "bootParameter", nm
);
2737 if (rc
!= NS_LDAP_SUCCESS
) {
2738 __s_cvt_freeEntryRdn(entry
, rdn
);
2743 return (NS_LDAP_SUCCESS
);
2747 * Conversion: ethers
2748 * Input format: struct _ns_ethers
2749 * Exported objectclass: ieee802Device, device
2752 __s_cvt_ethers(const void *data
, char **rdn
,
2753 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2758 /* routine specific */
2759 struct _ns_ethers
*ptr
;
2761 static char *oclist
[] = {
2768 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
2769 return (NS_LDAP_OP_FAILED
);
2770 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
2772 return (NS_LDAP_MEMORY
);
2774 /* Convert the structure */
2775 ptr
= (struct _ns_ethers
*)data
;
2777 if (ptr
->name
== NULL
|| ptr
->ether
== '\0') {
2778 __ns_ldap_freeEntry(e
);
2780 return (NS_LDAP_INVALID_PARAM
);
2783 /* Create an appropriate rdn */
2784 (void) snprintf(trdn
, RDNSIZE
, "cn=%s", ptr
->name
);
2785 *rdn
= strdup(trdn
);
2787 __ns_ldap_freeEntry(e
);
2789 return (NS_LDAP_MEMORY
);
2792 /* Error check the data and add the attributes */
2793 rc
= __s_add_attr(e
, "cn", ptr
->name
);
2794 if (rc
!= NS_LDAP_SUCCESS
) {
2795 __s_cvt_freeEntryRdn(entry
, rdn
);
2799 rc
= __s_add_attr(e
, "macAddress", ptr
->ether
);
2800 if (rc
!= NS_LDAP_SUCCESS
) {
2801 __s_cvt_freeEntryRdn(entry
, rdn
);
2805 return (NS_LDAP_SUCCESS
);
2808 * This function is used when processing an ethers (objectclass: ieee802Device)
2809 * or a bootparams (objectclass: bootableDevice) entry, and the entry is
2810 * already found in LDAP. Since both ethers and bootparams share the same
2811 * LDAP container, we want to check that the entry found in LDAP is:
2812 * - either the same entry (same cn, same objectclass): we don't do anything
2814 * - or an entry which does not have the objectclass we are interesting in:
2815 * in this case, we modify the existing entry by adding the relevant
2816 * objectclass (ieee802Device or bootableDevice) and the relevant attribute(s)
2817 * from the attribute list previously computing by the relevant conversion
2819 * Note: from conversion functions __s_cvt_ethers() and __s_cvt_bootparams()
2820 * we know that there is only 1 more attribute today to add (macAddress
2823 #define _MAX_ATTR_ETHBOOTP 2
2825 modify_ethers_bootp(
2826 const char *service
,
2829 const ns_ldap_attr_t
* const *attrlist
,
2830 const ns_cred_t
*cred
,
2832 ns_ldap_error_t
**errorp
)
2834 char filter
[BUFSIZ
];
2835 ns_ldap_result_t
*resultp
;
2838 ns_ldap_attr_t
*new_attrlist
[_MAX_ATTR_ETHBOOTP
+1];
2839 ns_ldap_attr_t new_attrlist0
;
2840 char *new_attrvalue0
[1];
2841 const ns_ldap_attr_t
* const *aptr
= attrlist
;
2842 ns_ldap_attr_t
*aptr2
;
2843 ns_ldap_error_t
*new_errorp
= NULL
;
2845 if (rdn
== NULL
|| fulldn
== NULL
|| attrlist
== NULL
||
2846 errorp
== NULL
|| service
== NULL
)
2847 return (NS_LDAP_OP_FAILED
);
2849 bzero(&new_attrlist
, sizeof (new_attrlist
));
2850 bzero(&new_attrlist0
, sizeof (new_attrlist0
));
2851 new_attrlist
[0] = &new_attrlist0
;
2852 new_attrlist
[0]->attrvalue
= new_attrvalue0
;
2854 new_attrlist
[0]->attrname
= "objectclass";
2855 new_attrlist
[0]->value_count
= 1;
2856 if (strcasecmp(service
, "ethers") == 0) {
2857 (void) snprintf(&filter
[0], sizeof (filter
),
2858 "(&(objectClass=ieee802Device)(%s))", rdn
);
2859 new_attrlist
[0]->attrvalue
[0] = "ieee802Device";
2861 (void) snprintf(&filter
[0], sizeof (filter
),
2862 "(&(objectClass=bootableDevice)(%s))", rdn
);
2863 new_attrlist
[0]->attrvalue
[0] = "bootableDevice";
2866 rc
= __ns_ldap_list(service
, filter
, NULL
, (const char **)NULL
,
2867 NULL
, NS_LDAP_SCOPE_SUBTREE
, &resultp
, &new_errorp
,
2871 case NS_LDAP_SUCCESS
:
2873 * entry already exists for this service
2874 * return NS_LDAP_INTERNAL and do not modify the incoming errorp
2876 rc
= NS_LDAP_INTERNAL
;
2878 case NS_LDAP_NOTFOUND
:
2880 * entry not found with the given objectclasss but entry exists
2881 * hence add the relevant attribute (macAddress or bootparams).
2884 while (*aptr
&& (i
< _MAX_ATTR_ETHBOOTP
)) {
2885 /* aptr2 needed here to avoid lint warning */
2886 aptr2
= (ns_ldap_attr_t
*)*aptr
++;
2887 if ((strcasecmp(aptr2
->attrname
, "cn") != 0) &&
2888 (strcasecmp(aptr2
->attrname
,
2889 "objectclass") != 0)) {
2890 new_attrlist
[i
++] = (ns_ldap_attr_t
*)aptr2
;
2894 if (i
!= _MAX_ATTR_ETHBOOTP
) {
2895 /* we haven't found all expected attributes */
2896 rc
= NS_LDAP_OP_FAILED
;
2900 aptr
= (const ns_ldap_attr_t
* const *) new_attrlist
;
2901 /* clean errorp first */
2902 (void) __ns_ldap_freeError(errorp
);
2903 rc
= __ns_ldap_addAttr(service
, fulldn
, aptr
, cred
, flags
,
2908 * unexpected error happenned
2909 * returning relevant error
2911 (void) __ns_ldap_freeError(errorp
);
2912 *errorp
= new_errorp
;
2920 * Conversion: publickey
2921 * Input format: struct _ns_pubkey
2922 * Exported objectclass: NisKeyObject
2925 __s_cvt_publickey(const void *data
, char **rdn
,
2926 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2931 /* routine specific */
2932 struct _ns_pubkey
*ptr
;
2934 static char *oclist
[] = {
2939 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
2940 return (NS_LDAP_OP_FAILED
);
2941 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
2943 return (NS_LDAP_MEMORY
);
2945 /* Convert the structure */
2946 ptr
= (struct _ns_pubkey
*)data
;
2948 if (ptr
->name
== NULL
|| ptr
->pubkey
== '\0' || ptr
->privkey
== '\0') {
2949 __ns_ldap_freeEntry(e
);
2951 return (NS_LDAP_INVALID_PARAM
);
2954 /* Create an appropriate rdn */
2955 if (ptr
->hostcred
== NS_HOSTCRED_FALSE
)
2956 (void) snprintf(trdn
, RDNSIZE
, "uid=%s", ptr
->name
);
2958 (void) snprintf(trdn
, RDNSIZE
, "cn=%s", ptr
->name
);
2959 *rdn
= strdup(trdn
);
2961 __ns_ldap_freeEntry(e
);
2963 return (NS_LDAP_MEMORY
);
2966 /* Error check the data and add the attributes */
2968 rc
= __s_add_attr(e
, "nisPublickey", ptr
->pubkey
);
2969 if (rc
!= NS_LDAP_SUCCESS
) {
2970 __s_cvt_freeEntryRdn(entry
, rdn
);
2974 rc
= __s_add_attr(e
, "nisSecretkey", ptr
->privkey
);
2975 if (rc
!= NS_LDAP_SUCCESS
) {
2976 __s_cvt_freeEntryRdn(entry
, rdn
);
2980 return (NS_LDAP_SUCCESS
);
2983 * Conversion: aliases
2984 * Input format: struct _ns_alias
2985 * Exported objectclass: mailGroup
2988 __s_cvt_aliases(const void *data
, char **rdn
,
2989 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2994 /* routine specific */
2995 struct _ns_alias
*ptr
;
2999 static char *oclist
[] = {
3005 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
3006 return (NS_LDAP_OP_FAILED
);
3007 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
3009 return (NS_LDAP_MEMORY
);
3011 /* Convert the structure */
3012 ptr
= (struct _ns_alias
*)data
;
3014 if (ptr
->alias
== NULL
) {
3015 __ns_ldap_freeEntry(e
);
3017 return (NS_LDAP_INVALID_PARAM
);
3020 /* Create an appropriate rdn */
3021 (void) snprintf(trdn
, RDNSIZE
, "cn=%s", ptr
->alias
);
3022 *rdn
= strdup(trdn
);
3024 __ns_ldap_freeEntry(e
);
3026 return (NS_LDAP_MEMORY
);
3029 if (ptr
->alias
!= '\0') {
3030 rc
= __s_add_attr(e
, "mail", (char *)ptr
->alias
);
3031 if (rc
!= NS_LDAP_SUCCESS
) {
3032 __s_cvt_freeEntryRdn(entry
, rdn
);
3037 /* Error check the data and add the attributes */
3038 if (ptr
->member
&& ptr
->member
[0]) {
3040 for (i
= 0; *nm
; i
++, nm
++)
3042 nm
= (char **)calloc(i
+2, sizeof (char *));
3044 __s_cvt_freeEntryRdn(entry
, rdn
);
3045 return (NS_LDAP_MEMORY
);
3047 for (j
= 0; j
< i
; j
++)
3048 nm
[j
] = ptr
->member
[j
];
3050 rc
= __s_add_attrlist(e
, "mgrpRFC822MailMember", nm
);
3053 if (rc
!= NS_LDAP_SUCCESS
) {
3054 __s_cvt_freeEntryRdn(entry
, rdn
);
3059 return (NS_LDAP_SUCCESS
);
3063 * Conversion: automount
3064 * Input format: struct _ns_automount
3065 * Exported objectclass: automount
3068 __s_cvt_auto_mount(const void *data
, char **rdn
,
3069 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
3074 /* routine specific */
3075 struct _ns_automount
*ptr
;
3077 void **paramVal
= NULL
;
3078 char **mappedschema
= NULL
;
3080 static char *oclist
[] = {
3086 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
3087 return (NS_LDAP_OP_FAILED
);
3089 /* determine profile version number */
3090 rc
= __ns_ldap_getParam(NS_LDAP_FILE_VERSION_P
, ¶mVal
, errorp
);
3091 if (paramVal
&& *paramVal
&&
3092 strcasecmp(*paramVal
, NS_LDAP_VERSION_1
) == 0)
3095 (void) __ns_ldap_freeParam(¶mVal
);
3097 (void) __ns_ldap_freeError(errorp
);
3099 /* use old schema for version 1 profiles */
3101 oclist
[0] = "nisObject";
3103 oclist
[0] = "automount";
3105 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
3107 return (NS_LDAP_MEMORY
);
3109 /* Convert the structure */
3110 ptr
= (struct _ns_automount
*)data
;
3112 if (ptr
->key
== NULL
|| ptr
->value
== '\0' || ptr
->mapname
== '\0') {
3113 __ns_ldap_freeEntry(e
);
3115 return (NS_LDAP_INVALID_PARAM
);
3118 /* Create an appropriate rdn */
3119 (void) snprintf(trdn
, RDNSIZE
, version1
? "cn=%s" : "automountKey=%s",
3121 *rdn
= strdup(trdn
);
3123 __ns_ldap_freeEntry(e
);
3125 return (NS_LDAP_MEMORY
);
3128 if (ptr
->key
!= '\0') {
3129 rc
= __s_add_attr(e
, version1
? "cn" : "automountKey",
3131 if (rc
!= NS_LDAP_SUCCESS
) {
3132 __s_cvt_freeEntryRdn(entry
, rdn
);
3137 rc
= __s_add_attr(e
, version1
? "nisMapEntry" : "automountInformation",
3138 (char *)ptr
->value
);
3139 if (rc
!= NS_LDAP_SUCCESS
) {
3140 __s_cvt_freeEntryRdn(entry
, rdn
);
3145 * even for version 2, if automount is mapped to nisObject we
3146 * still need 'nisMapName' attribute
3148 mappedschema
= __ns_ldap_getMappedObjectClass("automount", "automount");
3149 if (mappedschema
&& mappedschema
[0] &&
3150 strcasecmp(mappedschema
[0], "nisObject") == 0)
3153 __s_api_free2dArray(mappedschema
);
3156 rc
= __s_add_attr(e
, "nisMapName", (char *)ptr
->mapname
);
3157 if (rc
!= NS_LDAP_SUCCESS
) {
3158 __s_cvt_freeEntryRdn(entry
, rdn
);
3163 return (NS_LDAP_SUCCESS
);
3166 * Conversion: auth_attr
3167 * Input format: authstr_t
3168 * Exported objectclass: SolarisAuthAttr
3171 __s_cvt_authattr(const void *data
, char **rdn
,
3172 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
3177 /* routine specific */
3180 static char *oclist
[] = {
3186 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
3187 return (NS_LDAP_OP_FAILED
);
3189 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
3191 return (NS_LDAP_MEMORY
);
3193 /* Convert the structure */
3194 ptr
= (authstr_t
*)data
;
3196 if (ptr
->name
== NULL
|| ptr
->name
[0] == '\0' || ptr
->attr
== NULL
) {
3197 __ns_ldap_freeEntry(e
);
3199 return (NS_LDAP_INVALID_PARAM
);
3202 /* Create an appropriate rdn */
3203 (void) snprintf(trdn
, RDNSIZE
, "cn=%s", ptr
->name
);
3204 *rdn
= strdup(trdn
);
3206 __ns_ldap_freeEntry(e
);
3208 return (NS_LDAP_MEMORY
);
3211 rc
= __s_add_attr(e
, "cn", ptr
->name
);
3212 if (rc
!= NS_LDAP_SUCCESS
) {
3213 __s_cvt_freeEntryRdn(entry
, rdn
);
3217 rc
= __s_add_attr(e
, "SolarisAttrKeyValue", ptr
->attr
);
3218 if (rc
!= NS_LDAP_SUCCESS
) {
3219 __s_cvt_freeEntryRdn(entry
, rdn
);
3223 if (ptr
->res1
!= NULL
) {
3224 rc
= __s_add_attr(e
, "SolarisAttrReserved1", ptr
->res1
);
3225 if (rc
!= NS_LDAP_SUCCESS
) {
3226 __s_cvt_freeEntryRdn(entry
, rdn
);
3231 if (ptr
->res2
!= NULL
) {
3232 rc
= __s_add_attr(e
, "SolarisAttrReserved2", ptr
->res2
);
3233 if (rc
!= NS_LDAP_SUCCESS
) {
3234 __s_cvt_freeEntryRdn(entry
, rdn
);
3239 if (ptr
->short_desc
!= NULL
) {
3240 rc
= __s_add_attr(e
, "SolarisAttrShortDesc", ptr
->short_desc
);
3241 if (rc
!= NS_LDAP_SUCCESS
) {
3242 __s_cvt_freeEntryRdn(entry
, rdn
);
3247 if (ptr
->long_desc
!= NULL
) {
3248 rc
= __s_add_attr(e
, "SolarisAttrLongDesc", ptr
->long_desc
);
3249 if (rc
!= NS_LDAP_SUCCESS
) {
3250 __s_cvt_freeEntryRdn(entry
, rdn
);
3255 return (NS_LDAP_SUCCESS
);
3258 * Conversion: exec_attr
3259 * Input format: execstr_t
3260 * Exported objectclass: SolarisExecAttr
3263 __s_cvt_execattr(const void *data
, char **rdn
,
3264 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
3269 char esc_str
[RDNSIZE
];
3270 /* routine specific */
3273 static char *oclist
[] = {
3280 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
3281 return (NS_LDAP_OP_FAILED
);
3283 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
3285 return (NS_LDAP_MEMORY
);
3287 /* Convert the structure */
3288 ptr
= (execstr_t
*)data
;
3290 if (ptr
->name
== NULL
|| ptr
->name
[0] == '\0' ||
3291 ptr
->policy
== NULL
|| ptr
->policy
[0] == '\0' ||
3292 ptr
->type
== NULL
|| ptr
->type
[0] == '\0' ||
3293 ptr
->id
== NULL
|| ptr
->id
[0] == '\0') {
3294 __ns_ldap_freeEntry(e
);
3296 return (NS_LDAP_INVALID_PARAM
);
3300 * Escape special characters in ProfileID.
3302 if (escape_str(esc_str
, ptr
->id
) != 0) {
3303 __ns_ldap_freeEntry(e
);
3305 return (NS_LDAP_INVALID_PARAM
);
3308 /* Create an appropriate rdn */
3309 (void) snprintf(trdn
, RDNSIZE
, "cn=%s+SolarisKernelSecurityPolicy=%s"
3310 "+SolarisProfileType=%s+SolarisProfileId=%s",
3311 ptr
->name
, ptr
->policy
, ptr
->type
, esc_str
);
3313 *rdn
= strdup(trdn
);
3315 __ns_ldap_freeEntry(e
);
3317 return (NS_LDAP_MEMORY
);
3320 rc
= __s_add_attr(e
, "cn", ptr
->name
);
3321 if (rc
!= NS_LDAP_SUCCESS
) {
3322 __s_cvt_freeEntryRdn(entry
, rdn
);
3326 rc
= __s_add_attr(e
, "SolarisKernelSecurityPolicy", ptr
->policy
);
3327 if (rc
!= NS_LDAP_SUCCESS
) {
3328 __s_cvt_freeEntryRdn(entry
, rdn
);
3332 rc
= __s_add_attr(e
, "SolarisProfileType", ptr
->type
);
3333 if (rc
!= NS_LDAP_SUCCESS
) {
3334 __s_cvt_freeEntryRdn(entry
, rdn
);
3338 rc
= __s_add_attr(e
, "SolarisProfileId", ptr
->id
);
3339 if (rc
!= NS_LDAP_SUCCESS
) {
3340 __s_cvt_freeEntryRdn(entry
, rdn
);
3344 rc
= __s_add_attr(e
, "SolarisAttrKeyValue", ptr
->attr
);
3345 if (rc
!= NS_LDAP_SUCCESS
) {
3346 __s_cvt_freeEntryRdn(entry
, rdn
);
3350 if (ptr
->res1
!= NULL
) {
3351 rc
= __s_add_attr(e
, "SolarisAttrRes1", ptr
->res1
);
3352 if (rc
!= NS_LDAP_SUCCESS
) {
3353 __s_cvt_freeEntryRdn(entry
, rdn
);
3358 if (ptr
->res2
!= NULL
) {
3359 rc
= __s_add_attr(e
, "SolarisAttrRes2", ptr
->res2
);
3360 if (rc
!= NS_LDAP_SUCCESS
) {
3361 __s_cvt_freeEntryRdn(entry
, rdn
);
3366 return (NS_LDAP_SUCCESS
);
3369 * Conversion: prof_attr
3370 * Input format: profstr_t
3371 * Exported objectclass: SolarisProfAttr
3374 __s_cvt_profattr(const void *data
, char **rdn
,
3375 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
3380 /* routine specific */
3383 static char *oclist
[] = {
3389 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
3390 return (NS_LDAP_OP_FAILED
);
3392 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
3394 return (NS_LDAP_MEMORY
);
3396 /* Convert the structure */
3397 ptr
= (profstr_t
*)data
;
3399 if (ptr
->name
== NULL
|| ptr
->name
[0] == '\0' || ptr
->attr
== NULL
) {
3400 __ns_ldap_freeEntry(e
);
3402 return (NS_LDAP_INVALID_PARAM
);
3405 /* Create an appropriate rdn */
3406 (void) snprintf(trdn
, RDNSIZE
, "cn=%s", ptr
->name
);
3407 *rdn
= strdup(trdn
);
3409 __ns_ldap_freeEntry(e
);
3411 return (NS_LDAP_MEMORY
);
3414 rc
= __s_add_attr(e
, "cn", ptr
->name
);
3415 if (rc
!= NS_LDAP_SUCCESS
) {
3416 __s_cvt_freeEntryRdn(entry
, rdn
);
3420 rc
= __s_add_attr(e
, "SolarisAttrKeyValue", ptr
->attr
);
3421 if (rc
!= NS_LDAP_SUCCESS
) {
3422 __s_cvt_freeEntryRdn(entry
, rdn
);
3426 if (ptr
->res1
!= NULL
) {
3427 rc
= __s_add_attr(e
, "SolarisAttrReserved1", ptr
->res1
);
3428 if (rc
!= NS_LDAP_SUCCESS
) {
3429 __s_cvt_freeEntryRdn(entry
, rdn
);
3434 if (ptr
->res2
!= NULL
) {
3435 rc
= __s_add_attr(e
, "SolarisAttrReserved2", ptr
->res2
);
3436 if (rc
!= NS_LDAP_SUCCESS
) {
3437 __s_cvt_freeEntryRdn(entry
, rdn
);
3442 if (ptr
->desc
!= NULL
) {
3443 rc
= __s_add_attr(e
, "SolarisAttrLongDesc", ptr
->desc
);
3444 if (rc
!= NS_LDAP_SUCCESS
) {
3445 __s_cvt_freeEntryRdn(entry
, rdn
);
3450 return (NS_LDAP_SUCCESS
);
3453 * Conversion: user_attr
3454 * Input format: userstr_t
3455 * Exported objectclass: SolarisUserAttr
3458 __s_cvt_userattr(const void *data
, char **rdn
,
3459 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
3464 /* routine specific */
3467 static char *oclist
[] = {
3472 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
3473 return (NS_LDAP_OP_FAILED
);
3475 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
3477 return (NS_LDAP_MEMORY
);
3479 /* Convert the structure */
3480 ptr
= (userstr_t
*)data
;
3482 if (ptr
->name
== NULL
|| ptr
->name
[0] == '\0' ||
3483 ptr
->attr
== NULL
) {
3484 __ns_ldap_freeEntry(e
);
3486 return (NS_LDAP_INVALID_PARAM
);
3489 /* Create an appropriate rdn */
3490 (void) snprintf(trdn
, RDNSIZE
, "uid=%s", ptr
->name
);
3491 *rdn
= strdup(trdn
);
3493 __ns_ldap_freeEntry(e
);
3495 return (NS_LDAP_MEMORY
);
3499 * SolarisUserAttr has no uid attribute
3502 rc
= __s_add_attr(e
, "SolarisAttrKeyValue", ptr
->attr
);
3503 if (rc
!= NS_LDAP_SUCCESS
) {
3504 __s_cvt_freeEntryRdn(entry
, rdn
);
3508 if (ptr
->qualifier
!= NULL
) {
3509 rc
= __s_add_attr(e
, "SolarisUserQualifier", ptr
->qualifier
);
3510 if (rc
!= NS_LDAP_SUCCESS
) {
3511 __s_cvt_freeEntryRdn(entry
, rdn
);
3516 if (ptr
->res1
!= NULL
) {
3517 rc
= __s_add_attr(e
, "SolarisAttrReserved1", ptr
->res1
);
3518 if (rc
!= NS_LDAP_SUCCESS
) {
3519 __s_cvt_freeEntryRdn(entry
, rdn
);
3524 if (ptr
->res2
!= NULL
) {
3525 rc
= __s_add_attr(e
, "SolarisAttrReserved2", ptr
->res2
);
3526 if (rc
!= NS_LDAP_SUCCESS
) {
3527 __s_cvt_freeEntryRdn(entry
, rdn
);
3532 return (NS_LDAP_SUCCESS
);
3535 * Conversion: audit_user
3536 * Input format: au_user_str_t
3537 * Exported objectclass: SolarisAuditUser
3540 __s_cvt_audituser(const void *data
, char **rdn
,
3541 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
3546 /* routine specific */
3549 static char *oclist
[] = {
3554 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
3555 return (NS_LDAP_OP_FAILED
);
3557 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
3559 return (NS_LDAP_MEMORY
);
3561 /* Convert the structure */
3562 ptr
= (au_user_str_t
*)data
;
3564 if (ptr
->au_name
== NULL
|| ptr
->au_name
[0] == '\0') {
3565 __ns_ldap_freeEntry(e
);
3567 return (NS_LDAP_INVALID_PARAM
);
3570 /* Create an appropriate rdn */
3571 (void) snprintf(trdn
, RDNSIZE
, "uid=%s", ptr
->au_name
);
3572 *rdn
= strdup(trdn
);
3574 __ns_ldap_freeEntry(e
);
3576 return (NS_LDAP_MEMORY
);
3580 * Solaris AuditUser has no uid attribute
3583 if (ptr
->au_always
!= NULL
) {
3584 rc
= __s_add_attr(e
, "SolarisAuditAlways", ptr
->au_always
);
3585 if (rc
!= NS_LDAP_SUCCESS
) {
3586 __s_cvt_freeEntryRdn(entry
, rdn
);
3591 if (ptr
->au_never
!= NULL
) {
3592 rc
= __s_add_attr(e
, "SolarisAuditNever", ptr
->au_never
);
3593 if (rc
!= NS_LDAP_SUCCESS
) {
3594 __s_cvt_freeEntryRdn(entry
, rdn
);
3599 return (NS_LDAP_SUCCESS
);
3603 * Add Typed Entry Conversion data structures
3606 typedef struct __ns_cvt_type
{
3607 const char *service
;
3609 #define AE 1 /* alway add entries */
3610 int (*cvt_rtn
)(const void *data
,
3612 ns_ldap_entry_t
**entry
,
3613 ns_ldap_error_t
**errorp
);
3616 static __ns_cvt_type_t __s_cvtlist
[] = {
3617 { NS_LDAP_TYPE_PASSWD
, 0, __s_cvt_passwd
},
3618 { NS_LDAP_TYPE_GROUP
, 0, __s_cvt_group
},
3619 { NS_LDAP_TYPE_HOSTS
, 0, __s_cvt_hosts
},
3620 { NS_LDAP_TYPE_IPNODES
, 0, __s_cvt_hosts
},
3621 { NS_LDAP_TYPE_RPC
, 0, __s_cvt_rpc
},
3622 { NS_LDAP_TYPE_PROTOCOLS
, 0, __s_cvt_protocols
},
3623 { NS_LDAP_TYPE_NETWORKS
, 0, __s_cvt_networks
},
3624 { NS_LDAP_TYPE_NETGROUP
, 0, __s_cvt_netgroups
},
3625 { NS_LDAP_TYPE_ALIASES
, 0, __s_cvt_aliases
},
3626 { NS_LDAP_TYPE_SERVICES
, 0, __s_cvt_services
},
3627 { NS_LDAP_TYPE_ETHERS
, 0, __s_cvt_ethers
},
3628 { NS_LDAP_TYPE_SHADOW
, 0, __s_cvt_shadow
},
3629 { NS_LDAP_TYPE_NETMASKS
, 0, __s_cvt_netmasks
},
3630 { NS_LDAP_TYPE_BOOTPARAMS
, 0, __s_cvt_bootparams
},
3631 { NS_LDAP_TYPE_AUTHATTR
, 0, __s_cvt_authattr
},
3632 { NS_LDAP_TYPE_EXECATTR
, 0, __s_cvt_execattr
},
3633 { NS_LDAP_TYPE_PROFILE
, 0, __s_cvt_profattr
},
3634 { NS_LDAP_TYPE_USERATTR
, AE
, __s_cvt_userattr
},
3635 { NS_LDAP_TYPE_AUTOMOUNT
, 0, __s_cvt_auto_mount
},
3636 { NS_LDAP_TYPE_PUBLICKEY
, AE
, __s_cvt_publickey
},
3637 { NS_LDAP_TYPE_AUUSER
, AE
, __s_cvt_audituser
},
3638 { NS_LDAP_TYPE_PROJECT
, 0, __s_cvt_project
},
3643 * Add Typed Entry Routine
3647 int __ns_ldap_addTypedEntry(
3648 const char *servicetype
,
3652 const ns_cred_t
*cred
,
3654 ns_ldap_error_t
**errorp
)
3656 char *rdn
= NULL
, *fulldn
= NULL
;
3657 void **paramVal
= NULL
;
3658 ns_ldap_entry_t
*entry
= NULL
;
3659 const ns_ldap_attr_t
*const *modattrlist
;
3660 ns_ldap_search_desc_t
**sdlist
;
3663 char service
[BUFSIZE
];
3668 rc
= NS_LDAP_OP_FAILED
;
3669 for (s
= 0; __s_cvtlist
[s
].service
!= NULL
; s
++) {
3670 if (__s_cvtlist
[s
].cvt_rtn
== NULL
)
3672 if (strcasecmp(__s_cvtlist
[s
].service
, servicetype
) == 0)
3674 /* Or, check if the servicetype is auto_ */
3675 if (strcmp(__s_cvtlist
[s
].service
,
3676 NS_LDAP_TYPE_AUTOMOUNT
) == 0 &&
3677 strncasecmp(servicetype
, NS_LDAP_TYPE_AUTOMOUNT
,
3678 sizeof (NS_LDAP_TYPE_AUTOMOUNT
) - 1) == 0) {
3683 if (__s_cvtlist
[s
].service
== NULL
)
3686 /* Convert the data */
3687 rc
= (*__s_cvtlist
[s
].cvt_rtn
)(data
, &rdn
, &entry
, errorp
);
3688 if (rc
!= NS_LDAP_SUCCESS
) {
3689 __s_cvt_freeEntryRdn(&entry
, &rdn
);
3693 __ns_ldap_freeEntry(entry
);
3694 return (NS_LDAP_OP_FAILED
);
3697 if (strcmp(servicetype
, "publickey") == 0) {
3698 struct _ns_pubkey
*ptr
;
3699 ptr
= (struct _ns_pubkey
*)data
;
3700 if (ptr
->hostcred
== NS_HOSTCRED_TRUE
)
3701 (void) strcpy(service
, "hosts");
3703 (void) strcpy(service
, "passwd");
3705 (void) strcpy(service
, servicetype
);
3707 /* Create the Full DN */
3708 if (basedn
== NULL
) {
3709 rc
= __s_api_get_SSD_from_SSDtoUse_service(service
,
3711 if (rc
!= NS_LDAP_SUCCESS
) {
3712 __s_cvt_freeEntryRdn(&entry
, &rdn
);
3716 if (sdlist
== NULL
) {
3717 rc
= __s_api_getDNs(&dns
, service
, errorp
);
3718 if (rc
!= NS_LDAP_SUCCESS
) {
3720 __s_api_free2dArray(dns
);
3723 __s_cvt_freeEntryRdn(&entry
, &rdn
);
3726 (void) snprintf(trdn
, RDNSIZE
, "%s,%s", rdn
, dns
[0]);
3727 __s_api_free2dArray(dns
);
3729 if (sdlist
[0]->basedn
) {
3730 (void) snprintf(trdn
, RDNSIZE
, "%s,%s",
3731 rdn
, sdlist
[0]->basedn
);
3733 __s_cvt_freeEntryRdn(&entry
, &rdn
);
3734 return (NS_LDAP_OP_FAILED
);
3737 i
= strlen(trdn
) - 1;
3738 if (trdn
[i
] == COMMATOK
) {
3739 rc
= __ns_ldap_getParam(NS_LDAP_SEARCH_BASEDN_P
,
3741 if (rc
!= NS_LDAP_SUCCESS
) {
3742 __s_cvt_freeEntryRdn(&entry
, &rdn
);
3745 i
= strlen(trdn
) + strlen((char *)(paramVal
[0])) + 1;
3746 fulldn
= (char *)calloc(i
, 1);
3747 if (fulldn
== NULL
) {
3748 (void) __ns_ldap_freeParam(¶mVal
);
3749 __s_cvt_freeEntryRdn(&entry
, &rdn
);
3750 return (NS_LDAP_MEMORY
);
3752 (void) snprintf(fulldn
, i
, "%s%s", trdn
,
3753 (char *)(paramVal
[0]));
3754 (void) __ns_ldap_freeParam(¶mVal
);
3756 fulldn
= strdup(trdn
);
3757 if (fulldn
== NULL
) {
3758 __s_cvt_freeEntryRdn(&entry
, &rdn
);
3759 return (NS_LDAP_MEMORY
);
3763 i
= strlen(rdn
) + strlen(basedn
) + 2;
3764 fulldn
= (char *)calloc(i
, 1);
3765 if (fulldn
== NULL
) {
3766 __s_cvt_freeEntryRdn(&entry
, &rdn
);
3767 return (NS_LDAP_MEMORY
);
3769 (void) snprintf(fulldn
, i
, "%s,%s", rdn
, basedn
);
3772 modattrlist
= (const ns_ldap_attr_t
* const *)entry
->attr_pair
;
3773 /* Check to see if the entry exists already */
3774 /* May need to delete or update first */
3777 /* Modify the entry */
3779 * To add a shadow-like entry, the addTypedEntry function
3780 * would call __ns_ldap_repAttr first, and if server says
3781 * LDAP_NO_SUCH_OBJECT, then it tries __ns_ldap_addEntry.
3782 * This is to allow a netmask entry to be added even if the
3783 * base network entry is not in the directory. It would work
3784 * because the difference between the schema for the network
3785 * and netmask data contains only MAY attributes.
3787 * But for shadow data, the attributes do not have MUST
3788 * attributes the base entry needs, so if the __ns_ldap_addEntry
3789 * is executed, it would fail. The real reason, however, is that
3790 * the base entry did not exist. So returning
3791 * LDAP_OBJECT_CLASS_VIOLATION would just confused.
3793 if ((__s_cvtlist
[s
].flags
& AE
) != 0)
3794 rc
= __ns_ldap_addAttr(service
, fulldn
, modattrlist
,
3795 cred
, flags
, errorp
);
3797 rc
= __ns_ldap_repAttr(service
, fulldn
, modattrlist
,
3798 cred
, flags
, errorp
);
3799 if (rc
== NS_LDAP_INTERNAL
&& *errorp
&&
3800 (*errorp
)->status
== LDAP_NO_SUCH_OBJECT
) {
3801 (void) __ns_ldap_freeError(errorp
);
3802 rc
= __ns_ldap_addEntry(service
, fulldn
,
3803 entry
, cred
, flags
, errorp
);
3804 if (rc
== NS_LDAP_INTERNAL
&& *errorp
&&
3805 (*errorp
)->status
==
3806 LDAP_OBJECT_CLASS_VIOLATION
)
3807 (*errorp
)->status
= LDAP_NO_SUCH_OBJECT
;
3812 rc
= __ns_ldap_addEntry(service
, fulldn
, entry
,
3813 cred
, flags
, errorp
);
3814 if (rc
== NS_LDAP_INTERNAL
&& *errorp
&&
3815 (*errorp
)->status
== LDAP_ALREADY_EXISTS
&&
3816 ((strcmp(service
, "ethers") == 0) ||
3817 (strcmp(service
, "bootparams") == 0))) {
3818 rc
= modify_ethers_bootp(service
, rdn
, fulldn
,
3819 modattrlist
, cred
, flags
, errorp
);
3823 /* Free up entry created by conversion routine */
3825 __s_cvt_freeEntryRdn(&entry
, &rdn
);
3831 * Append the default base dn to the dn
3832 * when it ends with ','.
3834 * SSD = service:ou=foo,
3837 __s_api_append_default_basedn(
3841 ns_ldap_error_t
**errp
) {
3843 int rc
= NS_LDAP_SUCCESS
, len
= 0;
3844 void **param
= NULL
;
3851 return (NS_LDAP_INVALID_PARAM
);
3853 rc
= __ns_ldap_getParam(NS_LDAP_SEARCH_BASEDN_P
,
3854 (void ***)¶m
, errp
);
3856 if (rc
!= NS_LDAP_SUCCESS
) {
3858 (void) __ns_ldap_freeParam(¶m
);
3863 str
= ((char **)param
)[0];
3864 len
= len
+ strlen(str
) +1;
3865 *new_dn
= (char *)malloc(len
);
3866 if (*new_dn
== NULL
) {
3867 (void) __ns_ldap_freeParam(¶m
);
3868 return (NS_LDAP_MEMORY
);
3872 (void) strcpy(*new_dn
, dn
);
3873 (void) strcat(*new_dn
, str
);
3875 (void) __ns_ldap_freeParam(¶m
);
3876 return (NS_LDAP_SUCCESS
);
3880 * Flatten the input ns_ldap_attr_t list, 'attr', and convert it into an
3881 * ldap_strlist_t structure in buffer 'buf', to be used by ldap_cachemgr.
3882 * The output contains a count, a list of offsets, which show where the
3883 * corresponding copied attribute type and attribute value are located.
3884 * For example, for dn=aaaa, userpassword=bbbb, shadowlastchange=cccc,
3885 * the output is the ldap_strlist_t structure with: ldap_count = 6,
3886 * (buf + ldap_offsets[0]) -> "dn"
3887 * (buf + ldap_offsets[1]) -> "aaaa"
3888 * (buf + ldap_offsets[2]) -> "userPassword"
3889 * (buf + ldap_offsets[3]) -> "bbbb"
3890 * (buf + ldap_offsets[4]) -> "shadowlastchange"
3891 * (buf + ldap_offsets[5]) -> "cccc"
3892 * and all the string data shown above copied into the buffer after
3893 * the offset array. The total length of the data will be the return
3894 * value, or -1 if error.
3897 attr2list(const char *dn
, ns_ldap_attr_t
**attr
,
3898 char *buf
, int bufsize
)
3903 ldap_strlist_t
*al
= (ldap_strlist_t
*)buf
;
3904 ns_ldap_attr_t
*a
= (ns_ldap_attr_t
*)*attr
;
3905 ns_ldap_attr_t
**aptr
= (ns_ldap_attr_t
**)attr
;
3907 /* bufsize > strlen(dn) + strlen("dn") + 1 ('\0') */
3908 if ((strlen(dn
) + 2 + 1) >= bufsize
)
3911 /* count number of attributes */
3914 al
->ldap_count
= 2 + c
* 2;
3915 ao
= sizeof (al
->ldap_count
) + sizeof (al
->ldap_offsets
[0]) *
3919 al
->ldap_offsets
[0] = ao
;
3926 (void) strlcpy(ap
, "dn", bufsize
);
3929 al
->ldap_offsets
[1] = ao
;
3930 ao
+= strlen(dn
) + 1;
3933 (void) strlcpy(ap
, dn
, bufsize
);
3937 for (c
= 2; c
< al
->ldap_count
; c
++, aptr
++) {
3939 if (a
->attrname
== NULL
|| a
->attrvalue
== NULL
||
3940 a
->value_count
!= 1 || a
->attrvalue
[0] == NULL
)
3942 al
->ldap_offsets
[c
] = ao
;
3943 ao
+= strlen(a
->attrname
) + 1;
3946 (void) strlcpy(ap
, a
->attrname
, bufsize
);
3950 al
->ldap_offsets
[c
] = ao
;
3951 ao
+= strlen(a
->attrvalue
[0]) + 1;
3952 (void) strlcpy(ap
, a
->attrvalue
[0], bufsize
);
3960 * Send a modify request to the ldap_cachemgr daemon
3961 * which will use the admin credential to perform the
3968 ns_ldap_attr_t
**attr
,
3969 ns_ldap_error_t
**errorp
)
3973 char s_b
[DOORBUFFERSIZE
];
3981 char errstr
[MAXERROR
];
3982 ldap_admin_mod_result_t
*admin_result
;
3985 (void) memset(space
.s_b
, 0, DOORBUFFERSIZE
);
3986 len
= attr2list(dn
, attr
, (char *)&space
.s_d
.ldap_call
.ldap_u
.strlist
,
3987 sizeof (space
) - offsetof(ldap_return_t
, ldap_u
));
3989 return (NS_LDAP_INVALID_PARAM
);
3991 adata
= sizeof (ldap_call_t
) + len
;
3992 ndata
= sizeof (space
);
3993 space
.s_d
.ldap_call
.ldap_callnumber
= ADMINMODIFY
;
3996 switch (__ns_ldap_trydoorcall(&sptr
, &ndata
, &adata
)) {
3997 case NS_CACHE_SUCCESS
:
3999 case NS_CACHE_NOTFOUND
:
4000 (void) snprintf(errstr
, sizeof (errstr
),
4001 gettext("Door call ADMINMODIFY to "
4002 "ldap_cachemgr failed - error: %d"),
4003 space
.s_d
.ldap_ret
.ldap_errno
);
4004 MKERROR(LOG_WARNING
, *errorp
, NS_CONFIG_CACHEMGR
,
4006 return (NS_LDAP_OP_FAILED
);
4008 return (NS_LDAP_OP_FAILED
);
4011 admin_result
= &sptr
->ldap_ret
.ldap_u
.admin_result
;
4012 if (admin_result
->ns_err
== NS_LDAP_SUCCESS
)
4013 rc
= NS_LDAP_SUCCESS
;
4015 rc
= admin_result
->ns_err
;
4016 if (admin_result
->msg_size
== 0)
4017 *errorp
= __s_api_make_error(admin_result
->status
,
4020 *errorp
= __s_api_make_error(admin_result
->status
,
4024 /* clean up the door call */
4025 if (sptr
!= &space
.s_d
) {
4026 (void) munmap((char *)sptr
, ndata
);